perm filename UNPACK.MAC[SIM,SYS] blob sn#460341 filedate 1979-07-20 generic text, type T, neo UTF8
COMMENT * SIMULA specification;
OPTIONS(/E:CODE,NOCHECK,unpent);
BOOLEAN PROCEDURE unpack;

!*;! MACRO-10 code !*;!

	TITLE	unpack
	SUBTTL	SIMULA utility, UNPACK procedure

;!*** Copyright 1975 by the Swedish Defence Research Institute. ***
;!*** Copying is allowed.					***

;!Author:	Stephan Oldgren, ENEA, Sept 1975
;!Modified by:	Lars Enderin, FOA, Jan 1976
;!Version:	1
;!Purpose:	external procedure to unpack data in a SIMULA program
;!Contents:	PULPV	load packed variable
;!		PUUC	unpack CHARACTER
;!		PUUI	unpack INTEGER and BOOLEAN
;!		PUUL	unpack LONG REAL
;!		PUUR	unpack REAL
;!		PUUT	unpack TEXT
;!		MAINPROGRAM procedure control
SEARCH	SIMMAC,SIMMCR,SIMRPA
ENTRY	UNPENT

;! Offsets in procedure block

result==ZBI%S		;! Function value
PAREA== result+1	;! Parameter (ZFL) for packed area
PBYP==	PAREA+2		;! ZFL for number of bits to bypass in packed area
UAREA==	PBYP+2		;! ZFL for unpacked area (array or variable)
ISIZE==	UAREA+2		;! ZFL for item size (bits)


;! Ac assignments

XIND=	3	;! Offset of current UAREA relative to first UAREA (0,2,4 etc)
XPADR=	4	;! Address (dynamic) of packed area
XPMAX=	5	;! Max offset relative to XPADR or max XPADR value
XPOFF=	6	;! Current bit offset within packed area
XPBYP=	7	;! Number of bits to bypass in current packed word
XUTYP=	XPBYP	;! Type of unpacked area
XUADR=	10	;! Address (dynamic) of unpacked area (UAREA)
XUMAX=	11	;! Max offset or address in UAREA
XUNBY=	XUMAX	;! Number of bytes left in unpacked area
XSIZ=	12	;! Bit size of packed item
XUBYT=	1	;! Number of bytes to skip in unpacked text
XA=	0	;! Work ac
XB=	XUBYT	;! - " -
XC=	2	;! - " -
XD=	XPBYP	;! - " -
XE=	13	;! - " -
XF=	14	;! - " -
XAREA=	16	;! Used to save XUADR, XUMAX in PUUT
XG=	XAREA	;! Work ac, also JSP ac for NEXT and ERROREXIT (simplifies debug)

;! CONSTANTS DEFINITIONS

QWL=	↑D36	;!word length
QHWL=	QWL/2	;!half word length
QQWL=	QWL/4	;!quarter word length
QDWL=	QWL*2	;!double word length
QBYA=	7	;!byte length ASCII
QBYS=	6	;!byte length SIXBIT
QNBA=	5	;!number of bytes in one word ASCII

	OPDEF	ERROREXIT	[JSP	XG,NOGOOD]
	OPDEF	NEXT		[JSP	XG,NEXT]
	OPDEF	LOADPACKED	[PUSHJ	XPDP,PULPV]
SALL
MACINIT

;! ERROR MESSAGES
ERUM1::!	ASCIZ/Parameter missing in UNPACK/
SUBTTL	PULPV
;!Purpose:		load a packed variable from area to unpack data from
;!Entry:		PULPV
;!Input arguments:	XPADR	block instance to area to unpack
;!			data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XSIZ	size of packed field
;!Normal exit:		Skip RETURN
;!Error exit:		RETURN
;!Output arguments:	XPOFF	(see above) now points at first bit
;!				after the now unpacked variable
;!			XA	packed variable left adjusted
;!Call format:		LOADPACKED (EXEC PULPV)
;!Used subroutines:	none


PULPV:	PROC
	SAVE	<XC>
	N==1	;! Number of ac's saved
	;!error return if overflow in area to unpack data from
	L	XC,XPOFF
	ADD	XC,XSIZ
	CAMLE	XC,XPMAX
	GOTO	L9

	;!make a word offset of the bit offset

	IDIVI	XPOFF,QWL

	;!now XPOFF contains offset in words and
	;!XPOFF+1=XPBYP contains number of  bits to be bypassed
	;!at the beginning of area to unpack data from
	;!compute address to area to unpack from and store it in XPOFF

	ADD	XPOFF,XPADR

	;!make bit mask with zeroes in place for packed variable and
	;!ones in the rest of a word
	SETZ	XF,
	SETO	XE,
	MOVN	XSIZ,XSIZ
	ROTC	XE,(XSIZ)
	MOVN	XSIZ,XSIZ
	SETO	XF,
	MOVN	XPBYP,XPBYP
	ROTC	XE,(XPBYP)
	MOVN	XPBYP,XPBYP
	;!read first word of area to unpack data from and use  the bit mask
	;!to remove unwanted parts of the vord
	L	XA,(XPOFF)
	ANDCM	XA,XE

	L	XC,XPBYP
	ADD	XC,XSIZ
	IF	;! The packed variable straddles a word boundary
		CAIG	XC,QWL
		GOTO	FALSE
	THEN	;!increment offset and
		;!read the next word of area  to unpack data from
		;!use the bit mask to remove unwanted parts,left justify
		;!the variable and compute new number of bits to be bypassed
		ADDI	XPOFF,1
		L	XB,(XPOFF)
		ANDCM 	XB,XF
		ROTC	XA,(XPBYP)
		SUBI	XPBYP,QWL
	ELSE	;! left justify variable and 
		;!compute new number of bits to be bypassed
		ROT	XA,(XPBYP)
	FI
	ADD	XPBYP,XSIZ
	;!reset bit offset
	SUB	XPOFF,XPADR
	IMULI	XPOFF,QWL
	ADD	XPOFF,XPBYP
	AOS	-N(XPDP)	;! Ok, skip return
L9():!	 
	RETURN
	EPROC
SUBTTL	PUUC
;!Purpose:		unpack routine for variable of type character
;!			unpacking is done by returning previously
;!			deleted bits as zeroes
;!Entry:		PUUC
;!Input arguments:	XPADR	block instance to area to unpack
;!				data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XUADR	address of unpacked area
;!			XUMAX	max address of  unpacked area
;!			XSIZ	size of packed  field
;!Normal exit:		NEXT
;!Error exit:		ERROREXIT
;!Output arguments:	XPOFF	(see above) now points at first bit after
;!				the now unpacked variable
;!CALL FORMAT:		EXEC PUUC
;!Used subroutine:	PULPV


PUUC:	PROC
	;!compute number of previously deleted bits, negated
	LI	XC,(XSIZ)
	SUBI	XC,QWL
	;!unpack every element of the variable
	WHILE
		CAMLE	XUADR,XUMAX
		GOTO	FALSE
	DO
		;!load element of packed variable
		;!error return if error in pulpv
		;!shift right and move in zeroes in
		;!place of the previously deleted bits
		;!store the unpacked variable
		LOADPACKED
		ERROREXIT
		LSH	XA,(XC)
		ST	XA,(XUADR)
		ADDI	XUADR,1
	OD
	NEXT
	EPROC
SUBTTL	PUUI
;!Purpose:		unpack routine  for variable of type integer
;!			or boolean
;!Entry:		PUUI
;!Input arguments:	XPADR	block instance to area to unpack
;!				data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XUADR	address of unpacked area
;!			XUMAX	max address of  unpacked area
;!			XSIZ	size of packed  field
;!Normal exit:		NEXT
;!Error exit:		ERROREXIT
;!Output arguments:	XPOFF	(see above) now points at first bit after
;!				the now unpacked variable
;!Call format:		EXEC PUUI
;!Used subroutine:	PULPV

PUUI:	PROC
	;!compute number of previously deleted bits and negate
	LI	XC,(XSIZ)
	SUBI	XC,QWL
	;!unpack every element of the variable
	WHILE
		CAMLE	XUADR,XUMAX
		GOTO	FALSE
	DO
		;!load element of packed variable
		;!error return if error in PULPV
		;!copy the sign bit into the previously
		;!deleted bits,and store the variable
		LOADPACKED
		ERROREXIT
		ASH	XA,(XC)
		ST	XA,(XUADR)
		ADDI	XUADR,1
	OD
	NEXT
	EPROC
SUBTTL	PUUL
;!Purpose:		unpack routine for variable of type long real
;!			unpacking is done by filling up with zeroes at
;!			the end of each element after the packed part
;!Entry:		PUUL
;!Input arguments:	XPADR	block instance to area to unpack
;!				data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XUADR	address of unpacked area
;!			XUMAX	max address of  unpacked area
;!			XSIZ	size of packed  field
;!Normal exit:		NEXT
;!Error exit:		ERROREXIT
;!Output arguments:	XPOFF	(see above) now points at first bit after
;!				the now unpacked variable
;!Call format:		EXEC PUUL
;!Used subroutine:	PULPV

PUUL:	PROC
	IF	;! Packed field fits in one word
		CAILE	XSIZ,QWL
		GOTO	FALSE
	THEN	;!unpack first word of every element
		;!and zero the second word
		WHILE	;! There is more to unpack
			CAMLE	XUADR,XUMAX
			GOTO	FALSE
		DO	;!load element of packed variable, store the
			;!first word into area to unpack into
			;!increment address to unpacked variable and
			;!zero the second word of the variable
			;!error return if anything wrong in pulpv or
			;!if second word is missing
			LOADPACKED
			ERROREXIT
			ST	XA,(XUADR)
			ADDI	XUADR,2
			CAILE	XUADR,1(XUMAX)
			ERROREXIT
			SETZM	-1(XUADR)
		OD
	ELSE	;!load one word of the packed element,
		;!and store it
		;!then load the rest of the packed element and store it
		;!while there are elements in the variable
		L	XC,XSIZ
		SUBI	XC,QWL
		WHILE
			CAMLE	XUADR,XUMAX
			GOTO	FALSE
		DO
			;!save size of packed variable, set size to word
			;!length,load one word of element and store it
			;!error return if something wrong in PULPV
			LI	XSIZ,QWL
			LOADPACKED
			ERROREXIT
			ST	XA,(XUADR)
			;!increment address,error return if second word
			;!of element is missing
			ADDI	XUADR,2
			CAILE	XUADR,1(XUMAX)
			ERROREXIT
			;!set  size to size of packed element minus
			;!word length,then load the rest of the packed
			;!element and store it in unpacked area
			L	XSIZ,XC
			LOADPACKED
			ERROREXIT
			ST	XA,-1(XUADR)
		OD
	FI
	NEXT
	EPROC
SUBTTL	PUUR
;!Purpose:		unpack routine for variable of type real
;!			unpacking is done by filling up with zeroes at
;!			the end of each element after the packed part
;!Entry:		PUUR
;!Input arguments:	XPADR	block instance to area to unpack
;!				data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XUADR	address of unpacked area
;!			XUMAX	max address of  unpacked area
;!			XSIZ	size of packed  field
;!Normal exit:		NEXT
;!Error exit:		ERROREXIT
;!Output arguments:	XPOFF	(see above) now points at first bit after
;!				the now unpacked variable
;!Call format:		EXEC PUUR
;!Used subroutine:	PULPV


PUUR:	PROC
	WHILE	;! More remains to be unpacked
		CAMLE	XUADR,XUMAX
		GOTO	FALSE
	DO	;!load element of packed variable and just store it into
		;!area to unpack into
		;!error return if something wrong in PULPV
		;!increment address of unpacked variable
		LOADPACKED
		ERROREXIT
		ST	XA,(XUADR)
		ADDI	XUADR,1
	OD
	NEXT
	EPROC
SUBTTL	PUUT
;!Purpose:		unpack routine for variable of  type text
;!			unpacking is done by converting characters from
;!			SIXBIT to ASCII
;!Entry:		PUUT
;!Input arguments:	XPADR	block instance to area to unpack
;!				data from
;!			XPMAX	max offset to area to unpack data from
;!			XPOFF	start offset to area to unpack data from
;!			XUADR	address of text specification
;!			XUMAX	max address of text specification
;!			XSIZ	size of packed  field 
;!Normal exit:		NEXT
;!Error exit:		ERROREXIT
;!Output arguments:	XPOFF	(see above) now points at first bit after
;!				the now unpacked variable
;!Call format:		EXEC PUUT
;!Used subroutine:	PULPV

PUUT:	PROC
	WHILE
		CAMLE	XUADR,XUMAX
		GOTO	FALSE
	DO
		;!save address
		L	XAREA,XUADR
		HRL	XAREA,XUMAX
		LD	XUADR,(XUADR)
		JUMPE	XUADR,NOGOOD	;! If NOTEXT
		HLRZ	XA,XUADR
		HLLI	XUADR,
		HLRZ	XUNBY,XUNBY
		;!compute start address
		IDIVI	XA,QNBA
		ADDI	XA,2
		ADD	XUADR,XA
		;!Note that XB=XUBYT now contains number of bytes to be
		;!bypassed before start of text in the word(XUADR)
		;!construct byte pointer to byte where unpacked text should be stored
		L	XC,[POINT	QBYA,(XUADR)]
		IF	JUMPLE	XUBYT,FALSE
		THEN
			LOOP
				IBP	XC
			AS	SOJG	XUBYT,TRUE
			SA
		FI
		IF	;! Bytes remain in text variable
			JUMPLE	XUNBY,FALSE
		THEN
			LOOP	;!load one sixbit character,error return if 
				;!something wrong in PULPV ,convert to ASCII and
				;!store byte in unpacked area
				LOADPACKED
				ERROREXIT
				IF
					CAIE	XSIZ,6
					GOTO	FALSE
				THEN
					ROT	XA,QBYS
					ADDI	XA,40
				ELSE
					ROT	XA,QBYA
				FI
				IDPB	XA,XC
			AS	SOJG	XUNBY,TRUE
			SA
		FI
		;!reinitialize address to text specification and increment it to 
		;!point at the next text element if any
		HRRI	XUADR,2(XAREA)
		HLR	XUMAX,XAREA
	OD
	NEXT
	EPROC
SUBTTL	MAINPROGRAM
;!Purpose:		to unpack a number of variables defined by a 
;!			SIMULA program from another variable
;!			also defined by the SIMULA program
;!Entry:		UNPENT
;!Used subroutines:	PUUC	unpack character
;!			PUUI	unpack integer and boolean
;!			PUUL	unpack long real
;!			PUUR	unpack real
;!			PUUT	unpack text

UNPENT:;!	Execution starts here for UNPACK routine
	SETOM	result(XCB)	;! Assume true result as a start
	SETZ	XIND,
	IF	;! ISIZE was not given
		SKIPE	ISIZE(XCB)
		GOTO	FALSE
	THEN	;! Error, not enough parameters
		OUTSTR	ERUM1
		RTSERR	QDSCON,214
		ERROREXIT
	FI
	SETZB	XE,XB
	;!read parameters for area to unpack data from and number of bits
	;!to be bypassed at the beginning of that area
	;!ie the first two parameters
	BEGIN
	;!error exit if area to unpack data from is a constant or an
	;!expression
	LF	XA,ZFLDTP(XCB,PAREA)
	CAIL	XA,QDTCON
	ERROREXIT
	;!check type of area
	;!error exit if not REAL,LONG REAL,INTEGER,BOOLEAN 
;!**	GETTYPE	XD,PAREA
	LF	XD,ZFLATP(XCB,PAREA)
	CAIG	XD,QBOOLEAN
	CAIN	XD,QCHARACTER
	ERROREXIT
	;!check kind of area,error exit if not ARRAY or SIMPLE
;!**	GETKIND	XE,PAREA
	LF	XE,ZFLAKD(XCB,PAREA)
	IF	;! NOT array
		CAIN	XE,QARRAY
		GOTO	FALSE
	THEN	;! Must be simple variable
		CAIE	XE,QSIMPLE
		ERROREXIT
		;!treat simple variable
		;!load dynamic address and compute max bit offset and bit offset
		;!to first bit in variable
;!**		GETADD	PAREA,<XPADR-XWAC1>
		IF	;! No thunk
			SKIPL	PAREA(XCB)
			GOTO	FALSE
		THEN	;! Get address the easy way
			LF	XPADR,ZFLZBI(XCB,PAREA)
			HRL	XPADR,PAREA+1(XCB)
		ELSE	;! Use PHFA
			LI	XPADR,(XCB)
			HRLI	XPADR,PAREA
			EXEC	PHFA
			XWD	XPADR-XWAC1,[0]
		FI
		HLRZ	XPMAX,XPADR
		CAIN	XD,QLREAL
		ADDI	XPMAX,1
		IMULI	XPMAX,QWL
		ADDI	XPMAX,QWL
		HLRZ	XPOFF,XPADR
		IMULI	XPOFF,QWL
		HLLI	XPADR,
	ELSE	;!treat array variables
		;!load dynamic address and compute number of bits in array
;!**		GETAADD	PAREA,3
		IF	;! No thunk
			SKIPL	PAREA(XCB)
			GOTO	FALSE
		THEN	;! Get address the easy way
			LF	XPADR,ZFLZBI(XCB,PAREA)
			ADD	XPADR,PAREA+1(XCB)
			L	XPADR,(XPADR)
		ELSE	;! Use PHFM
			LI	XPADR,(XCB)
			HRLI	XPADR,PAREA
			EXEC	PHFM
			XWD	XPADR-XWAC1,[0]
		FI
		LF	XPMAX,ZARLEN(XPADR)
		IMULI	XPMAX,QWL
		;!compute offset to first element
		LF	XPOFF,ZARSUB(XPADR)
		IMULI	XPOFF,3*QWL
		ADDI	XPOFF,3*QWL
	FI
	;!read parameter for number of bits to be bypassed
	;!at the beginning of area to unpack data from
	;!error exit if not simple integer
;!**	GETTYPE	XC,PBYP
	LF	XA,ZFLAKD(XCB,PBYP)
	LF	XC,ZFLATP(XCB,PBYP)
	CAIN	XA,QSIMPLE
	CAIE	XC,QINTEGER
	NOGOODEXIT
;!**	GETVAL	PBYP,6,<XPADR>
	IF	;! No thunk
		SKIPL	PBYP(XCB)
		GOTO	FALSE
	THEN	;! Simple value access
		LF	XPBYP,ZFLZBI(XCB,PBYP)
		ADD	XPBYP,PBYP+1(XCB)
		L	XPBYP,(XPBYP)
	ELSE	;! Do it the hard way
		LI	XPBYP,(XCB)
		HRLI	XPBYP,PBYP
		EXEC	PHFV
		XWD	XPBYP-XWAC1,[1B<XPADR-XWAC1>]
	FI
	;!error exit if negative value
	JUMPL	XPBYP,NOGOOD
	;!add number of bits to bypass to offset
	ADD	XPOFF,XPBYP
	;!
	;!now the contents of the registers are as follows
	;!	XPADR	block instance of area to unpack from
	;!	XPMAX	max bit offset
	;!	XPOFF	bit offset to first bit in area to unpack from
	;!
	ENDD
GETNXT:	;!read parameters for area to unpack into and size of packed variable
	;!ie the next two parameters
	;!XIND contains index to parameter table
	BEGIN
	;!check type of area,
	;!error exit if not REAL,LONG REAL,INTEGER,BOOLEAN,
	;!CHARACTER or TEXT
;!**	GETTYPE	XUTYP,UAREA,XIND
	LI	XUADR,UAREA(XIND)
	ADDI	XUADR,(XCB)
	LF	XUTYP,ZFLATP(XUADR)
	CAILE	XUTYP,QTEXT
	ERROREXIT
	;!check kind of area,error exit if not ARRAY or SIMPLE
;!**	GETKIND	XE,UAREA,XIND
	LF	XE,ZFLAKD(XUADR)
	IF	;! Not array
		CAIN	XE,QARRAY
		GOTO	FALSE
	THEN	;! Must be simple
		CAIE	XE,QSIMPLE
		ERROREXIT
		;!treat simple variable
		;! Get dynamic address and compute max offset
;!**		GETADD	UAREA(XIND),7,<XPADR>
		IF	;! No thunk
			SKIPL	(XUADR)
			GOTO	FALSE
		THEN	;! Get dynamic address
			HRL	XUADR,1(XUADR)
			HRR	XUADR,(XUADR)
		ELSE	;! Use PHFA or PHFT
			HRLI	XUADR,UAREA(XIND)
			HRRI	XUADR,(XCB)
			LI	XB,PHFA
			CAIN	XUTYP,QTEXT
			LI	XB,PHFT
			EXEC	0(XB)
			XWD	XUADR-XWAC1,[1B<XPADR-XWAC1>]
		FI
		HLRZ	XUMAX,XUADR
		CAIE	XUTYP,QTEXT
		CAIN	XUTYP,QLREAL
		ADDI	XUMAX,1
	ELSE	;!treat array variables
		;!load dynamic address and compute max offset and start offset
;!**		GETAADD	UAREA(XIND),7,<XPADR>
		IF	;! No thunk
			SKIPL	(XUADR)
			GOTO	FALSE
		THEN	;! Simple computation of array address
			LF	XB,ZFLZBI(XUADR)
			ADD	XB,1(XUADR)
			L	XUADR,(XB)
		ELSE	;! Use PHFM
			LI	XUADR,(XCB)
			HRLI	XUADR,UAREA(XIND)
			EXEC	PHFM
			XWD	XUADR-XWAC1,[1B<XPADR-XWAC1>]
		FI
		LF	XUMAX,ZARLEN(XUADR)
		SUBI	XUMAX,1
		LF	XE,ZARSUB(XUADR)
		IMULI	XE,3
		ADDI	XE,3
		HRL	XUADR,XE
	FI
	;!read argument for size of packed variable
	;!error exit if not of type integer and of kind simple or
	;!if size greater than double word length for long real variables or
	;! greater than word length for other variables
;!**	GETTYPE	XE,ISIZE,XIND
	LI	XSIZ,ISIZE(XIND)
	ADDI	XSIZ,(XCB)
	LF	XB,ZFLAKD(XSIZ)
	LF	XE,ZFLATP(XSIZ)
	CAIN	XE,QINTEGER
	CAIE	XB,QSIMPLE
	ERROREXIT
;!**	GETVAL	ISIZE(XIND),11,<XPADR,XUADR>
	IF	;! No thunk
		SKIPL	(XSIZ)
		GOTO	FALSE
	THEN	;! Simple evaluation
		LF	XB,ZFLZBI(XSIZ)
		ADD	XB,1(XSIZ)
		L	XSIZ,(XB)
	ELSE	;! Use PHFV
		LI	XSIZ,(XCB)
		HRLI	XSIZ,ISIZE(XIND)
		EXEC	PHFV
		XWD	XSIZ-XWAC1,[1B<XPADR-XWAC1>+1B<XUADR-XWAC1>]
	FI
	;!error exit if size is as follows:
	;!type of var	greater than		less than
	;!INTEGER	WORD LENGTH		2
	;!REAL	 	- " -			10
	;!CHARACTER	 - " -			7
	;!BOOLEAN	 - " -			1
	;!LONG REAL	DOUBLE WORD LENGTH	10
	;!TEXT		  7			6
	L	XB,SIZTAB-1(XUTYP)
	HLRZ	XB
	CAIL	XSIZ,(XB)
	CAMGE	XSIZ
	ERROREXIT
	;!change dynamic address to real address and max offset to max address
	HLRZ	XE,XUADR
	HLLI	XUADR,
	ADD	XUMAX,XUADR
	ADD	XUADR,XE
	;!now the contents of the ac's are as follows
	;!	XUTYP	type of area to unpack
	;!	XUADR	address of first word of area to unpack
	;!		or if text, address to first text specification
	;!	XUMAX	max address of area to unpack (not if text)
	;!		or if text, max address of text specifications
	;!	XSIZ	size of packed variable
	;!
	ENDD
	;!select correct subroutine for each type of variable
	XCT	ROUTAB-1(XUTYP)
NEXT:	;!Check for more arguments
	ADDI	XIND,2*2	;! Step to next UAREA, ISIZE pair
	LI	XB,(XCB)
	ADDI	XB,(XIND)
	SKIPN	UAREA(XB)
	GOTO	FINISH

	IF	;! There is room for both UAREA and ISIZE parameters
		Q==2*<<↑D31/2>*2-4>
		CAILE	XIND,Q
		GOTO	FALSE
	THEN	;! Handle next pair if ISIZE is given
		SKIPE	ISIZE(XB)
		GOTO	GETNXT
	FI

	;! *** ERROR, wrong number of parameters *** ;!

	OUTSTR	ERUM1
	RTSERR	QDSCON,214
NOGOOD:	SETZM	result(XCB)
	GOTO	FINISH
FINISH=CSEP

SIZTAB:	XWD	QWL,2		;! INTEGER
	XWD	QWL,10		;! REAL
	XWD	2*QWL,10	;! LONG REAL
	XWD	QWL,7		;! CHARACTER
	XWD	QWL,1		;! BOOLEAN
	XWD	7,6		;! TEXT

ROUTAB:	BRANCH	PUUI
	BRANCH	PUUR
	BRANCH	PUUL
	BRANCH	PUUI
	BRANCH	PUUI
	BRANCH	PUUT

	LIT
	END;