	.TITLE	DISM_INSTR Instruction Disassembling Procedure
	.IDENT	/MACRO/
;
;  This procedure is the actual disassembler for the VAX/VMS DISM-32
;  Image Disassembling Program. It is called as an INTEGER*4 function
;  in the form:
;
;	icode = DISM_INSTR(address,flag)
;
;  where the arguments are:
;	address	- current address in the image to disassemble at, relative to
;		  the starting address of the current image file record in
;		  the buffer REC_BUF. passed by reference. this offset is
;		  updated to point to the next instruction.
;
;	flag	- flag word, passed by reference. If LSB = 0, then symbol table
;		  is read/write access and no output is generated. If LSB = 1,
;		  symbol table is read-only, and output is generated by passing
;		  a completely constructed line as a descriptor-passed string
;		  to the procedure WRITE_OUTPUT_TEXT.
;
;	icode will be true if an unconditional jump (JMP), RET, RSB, or REI
;	was not disassembled on this call, and false if it has happened, to
;	allow for exiting disassembly DO WHILE loops when an unconditional
;	transfer of control occurs.
;
;	All currently supported VAX-11 machine instructions are implemented,
;	including privileged instructions and the G-floating and H-floating
;	arithmetic instructions.
;
;	Standard addressing mode format is used for all addressing modes, in
;	full formal format. This means that no plain symbols will occur (they
;	will always have a displacement size code, at least, attached), and
;	the general addressing mode (G^) will appear only for indirect
;	references through the fixup image section, since it is
;	equivalent to the PC-longword-relative and absolute addressing modes.
;
	.PAGE
	.SBTTL	Declarations of External Symbols, Offsets, Etc.
;
	.DISABLE GLOBAL
;
	.EXTRN	WRITE_OUTPUT_TEXT,COPY_BYTE,STR$FREE1_DX,DISM__INVOPCODE
	.EXTRN	STR$APPEND,STR$TRIM,WRITE_SYM_TBL
	.EXTRN	LIB$SIGNAL,DISM__INVIMMTYP,DISM__CORDTSTRUC
	.EXTRN	EXTRACT_SYM_TBL,SYS$FAO,DISM__INVADRMOD,DISM__INVIMMTP2
	.EXTRN	COPY_WORD,COPY_LONG,FOR$CVT_D_TG,FOR$CVT_G_TG,FOR$CVT_H_TG
	.EXTRN	GET_SYMBOL_TYPE,DISM__INDCALJSB
	.EXTRN	SS$_IVMODE
;
; define record buffer common
;
	.PSECT	DSK_BUF,PIC,OVR,REL,GBL,SHR,NOEXE,RD,WRT,LONG
CUR_VBN:	.BLKL	1
REC_BUF:	.BLKB	512
CUR_VA:		.BLKL	1
;
; define current LC common
;
	.PSECT	OUT_LIN,PIC,OVR,REL,GBL,SHR,NOEXE,RD,WRT,LONG
CURR_ADR:	.BLKL	1
;
; define symbol types and operand types
;
REL_VEC		=	^B1010000
COD_REF		=	^B1000000
INV_OPC		=	^B10000
STR_LEN		=	^B100000
SUBR_CALL	=	^B100000
UCOND_TRN	=	^B10000000
PROC_VEC	=	^B10000000
SPEC_INSTR	=	^B1000000
CALLS_SPC	=	^B1000
;
SYM_PROC	=	1
SYM_SUBR	=	2
SYM_JMPE	=	3
;
ISD_BYT		=	1
ISD_WRD		=	2
ISD_LNG		=	3
ISD_QUD		=	4
ISD_FLT		=	5
ISD_DFL		=	6
ISD_GFL		=	7
ISD_HFL		=	8
ISD_CHR		=	9
ISD_PDS		=	10
ISD_LSN		=	11
ISD_TNS		=	12
ISD_TBL		=	13
ISD_PTN		=	14
ISD_OCT		=	15
;
SYM_G_FIXUP	=	^X20000000
;
	.PAGE
	.SBTTL	Declaration of Instruction Look-Up Table
;
;  The Instruction Look-Up Table is the data structure that the instruction
;  disassembler uses to find the format and type of instruction from the
;  single opcode byte it is initially supplied with via the contents of REC_BUF
;  and the value of ADDR. Using this byte as an index value, a pointer to a
;  description of the instruction format is found in the table FORMAT_POINTER.
;  The data structure pointed to by this self-relative word pointer will
;  specify the opcode mnemonic (as ASCII text), the number of operands, and the
;  type of each operand.
;
;  declare the PSECT the data structures exist in
;
	.PSECT	DATA_STRUCTURE,NOPIC,NOEXE,RD,NOWRT,CON,REL,SHR,LCL,NOVEC,LONG
DATA_STRUC_BASE:
;
; define constants
;
TAB	=	9		; ASCII horizontal tab
TAB_S:	.ASCID	<TAB>
COMMA_S:	
	.ASCID	/,/
SIMMX_S:
	.ASCID	/S^#/
BDEC_S:	.ASCID	/!UB/
IMM_S:	.ASCID	/I^#/
ABS_S:	.ASCID	/@#/
GEN_S:	.ASCID	/G^/

XBYTE_S:	.ASCID	<9>/.BYTE/<9>/^X!XB/
XWORD_S:	.ASCID	<9>/.WORD/<9>/^X!XW/
;
;  begin the self-relative pointer table
;
FORMAT_POINTER:
	.WORD	I_HALT-.
	.WORD	I_NOP-.
	.WORD	I_REI-.
	.WORD	I_BPT-.
	.WORD	I_RET-.
	.WORD	I_RSB-.
	.WORD	I_LDPCTX-.
	.WORD	I_SVPCTX-.
	.WORD	I_CVTPS-.
	.WORD	I_CVTSP-.
	.WORD	I_INDEX-.
	.WORD	I_CRC-.
	.WORD	I_PROBER-.
	.WORD	I_PROBEW-.
	.WORD	I_INSQUE-.
	.WORD	I_REMQUE-.
	.WORD	I_BSBB-.
	.WORD	I_BRB-.
	.WORD	I_BNEQ-.
	.WORD	I_BEQL-.
	.WORD	I_BGTR-.
	.WORD	I_BLEQ-.
	.WORD	I_JSB-.
	.WORD	I_JMP-.
	.WORD	I_BGEQ-.
	.WORD	I_BLSS-.
	.WORD	I_BGTRU-.
	.WORD	I_BLEQU-.
	.WORD	I_BVC-.
	.WORD	I_BVS-.
	.WORD	I_BGEQU-.
	.WORD	I_BLSSU-.
	.WORD	I_ADDP4-.
	.WORD	I_ADDP6-.
	.WORD	I_SUBP4-.
	.WORD	I_SUBP6-.
	.WORD	I_CVTPT-.
	.WORD	I_MULP-.
	.WORD	I_CVTTP-.
	.WORD	I_DIVP-.
	.WORD	I_MOVC3-.
	.WORD	I_CMPC3-.
	.WORD	I_SCANC-.
	.WORD	I_SPANC-.
	.WORD	I_MOVC5-.
	.WORD	I_CMPC5-.
	.WORD	I_MOVTC-.
	.WORD	I_MOVTUC-.
	.WORD	I_BSBW-.
	.WORD	I_BRW-.
	.WORD	I_CVTWL-.
	.WORD	I_CVTWB-.
	.WORD	I_MOVP-.
	.WORD	I_CMPP3-.
	.WORD	I_CVTPL-.
	.WORD	I_CMPP4-.
	.WORD	I_EDITPC-.
	.WORD	I_MATCHC-.
	.WORD	I_LOCC-.
	.WORD	I_SKPC-.
	.WORD	I_MOVZWL-.
	.WORD	I_ACBW-.
	.WORD	I_MOVAW-.
	.WORD	I_PUSHAW-.
	.WORD	I_ADDF2-.
	.WORD	I_ADDF3-.
	.WORD	I_SUBF2-.
	.WORD	I_SUBF3-.
	.WORD	I_MULF2-.
	.WORD	I_MULF3-.
	.WORD	I_DIVF2-.
	.WORD	I_DIVF3-.
	.WORD	I_CVTFB-.
	.WORD	I_CVTFW-.
	.WORD	I_CVTFL-.
	.WORD	I_CVTRFL-.
	.WORD	I_CVTBF-.
	.WORD	I_CVTWF-.
	.WORD	I_CVTLF-.
	.WORD	I_ACBF-.
	.WORD	I_MOVF-.
	.WORD	I_CMPF-.
	.WORD	I_MNEGF-.
	.WORD	I_TSTF-.
	.WORD	I_EMODF-.
	.WORD	I_POLYF-.
	.WORD	I_CVTFD-.
	.WORD	UNDEF_INSTR-.
	.WORD	I_ADAWI-.
	.WORD	UNDEF_INSTR-.
	.WORD	UNDEF_INSTR-.
	.WORD	UNDEF_INSTR-.
	.WORD	I_INSQHI-.
	.WORD	I_INSQTI-.
	.WORD	I_REMQHI-.
	.WORD	I_REMQTI-.
	.WORD	I_ADDD2-.		; this should be opcode = ^X60
	.WORD	I_ADDD3-.
	.WORD	I_SUBD2-.
	.WORD	I_SUBD3-.
	.WORD	I_MULD2-.
	.WORD	I_MULD3-.
	.WORD	I_DIVD2-.
	.WORD	I_DIVD3-.
	.WORD	I_CVTDB-.
	.WORD	I_CVTDW-.
	.WORD	I_CVTDL-.
	.WORD	I_CVTRDL-.
	.WORD	I_CVTBD-.
	.WORD	I_CVTWD-.
	.WORD	I_CVTLD-.
	.WORD	I_ACBD-.
	.WORD	I_MOVD-.
	.WORD	I_CMPD-.
	.WORD	I_MNEGD-.
	.WORD	I_TSTD-.
	.WORD	I_EMODD-.
	.WORD	I_POLYD-.
	.WORD	I_CVTDF-.
	.WORD	UNDEF_INSTR-.
	.WORD	I_ASHL-.		; should be opcode = ^X78
	.WORD	I_ASHQ-.
	.WORD	I_EMUL-.
	.WORD	I_EDIV-.
	.WORD	I_CLRQ-.
	.WORD	I_MOVQ-.
	.WORD	I_MOVAQ-.
	.WORD	I_PUSHAQ-.
	.WORD	I_ADDB2-.
	.WORD	I_ADDB3-.
	.WORD	I_SUBB2-.
	.WORD	I_SUBB3-.
	.WORD	I_MULB2-.
	.WORD	I_MULB3-.
	.WORD	I_DIVB2-.
	.WORD	I_DIVB3-.
	.WORD	I_BISB2-.
	.WORD	I_BISB3-.
	.WORD	I_BICB2-.
	.WORD	I_BICB3-.
	.WORD	I_XORB2-.
	.WORD	I_XORB3-.
	.WORD	I_MNEGB-.
	.WORD	I_CASEB-.
	.WORD	I_MOVB-.
	.WORD	I_CMPB-.
	.WORD	I_MCOMB-.
	.WORD	I_BITB-.
	.WORD	I_CLRB-.
	.WORD	I_TSTB-.
	.WORD	I_INCB-.
	.WORD	I_DECB-.
	.WORD	I_CVTBL-.
	.WORD	I_CVTBW-.
	.WORD	I_MOVZBL-.
	.WORD	I_MOVZBW-.
	.WORD	I_ROTL-.
	.WORD	I_ACBB-.
	.WORD	I_MOVAB-.
	.WORD	I_PUSHAB-.
	.WORD	I_ADDW2-.
	.WORD	I_ADDW3-.
	.WORD	I_SUBW2-.
	.WORD	I_SUBW3-.
	.WORD	I_MULW2-.
	.WORD	I_MULW3-.
	.WORD	I_DIVW2-.
	.WORD	I_DIVW3-.
	.WORD	I_BISW2-.
	.WORD	I_BISW3-.
	.WORD	I_BICW2-.
	.WORD	I_BICW3-.
	.WORD	I_XORW2-.
	.WORD	I_XORW3-.
	.WORD	I_MNEGW-.
	.WORD	I_CASEW-.
	.WORD	I_MOVW-.
	.WORD	I_CMPW-.
	.WORD	I_MCOMW-.
	.WORD	I_BITW-.
	.WORD	I_CLRW-.
	.WORD	I_TSTW-.
	.WORD	I_INCW-.
	.WORD	I_DECW-.
	.WORD	I_BISPSW-.
	.WORD	I_BICPSW-.
	.WORD	I_POPR-.
	.WORD	I_PUSHR-.
	.WORD	I_CHMK-.
	.WORD	I_CHME-.
	.WORD	I_CHMS-.
	.WORD	I_CHMU-.
	.WORD	I_ADDL2-.
	.WORD	I_ADDL3-.
	.WORD	I_SUBL2-.
	.WORD	I_SUBL3-.
	.WORD	I_MULL2-.
	.WORD	I_MULL3-.
	.WORD	I_DIVL2-.
	.WORD	I_DIVL3-.
	.WORD	I_BISL2-.
	.WORD	I_BISL3-.
	.WORD	I_BICL2-.
	.WORD	I_BICL3-.
	.WORD	I_XORL2-.
	.WORD	I_XORL3-.
	.WORD	I_MNEGL-.
	.WORD	I_CASEL-.
	.WORD	I_MOVL-.
	.WORD	I_CMPL-.
	.WORD	I_MCOML-.
	.WORD	I_BITL-.
	.WORD	I_CLRL-.
	.WORD	I_TSTL-.
	.WORD	I_INCL-.
	.WORD	I_DECL-.
	.WORD	I_ADWC-.
	.WORD	I_SBWC-.
	.WORD	I_MTPR-.
	.WORD	I_MFPR-.
	.WORD	I_MOVPSL-.
	.WORD	I_PUSHL-.
	.WORD	I_MOVAL-.
	.WORD	I_PUSHAL-.
	.WORD	I_BBS-.		; should be opcode = ^XE0
	.WORD	I_BBC-.
	.WORD	I_BBSS-.
	.WORD	I_BBCS-.
	.WORD	I_BBSC-.
	.WORD	I_BBCC-.
	.WORD	I_BBSSI-.
	.WORD	I_BBCCI-.
	.WORD	I_BLBS-.
	.WORD	I_BLBC-.
	.WORD	I_FFS-.
	.WORD	I_FFC-.
	.WORD	I_CMPV-.
	.WORD	I_CMPZV-.
	.WORD	I_EXTV-.
	.WORD	I_EXTZV-.
	.WORD	I_INSV-.
	.WORD	I_ACBL-.
	.WORD	I_AOBLSS-.
	.WORD	I_AOBLEQ-.
	.WORD	I_SOBGEQ-.
	.WORD	I_SOBGTR-.		; should be opcode = ^XF5
	.WORD	I_CVTLB-.
	.WORD	I_CVTLW-.
	.WORD	I_ASHP-.
	.WORD	I_CVTLP-.
	.WORD	I_CALLG-.
	.WORD	I_CALLS-.
	.WORD	I_XFC-.
	.WORD	I_ESCD-.
	.WORD	I_ESCE-.
	.WORD	I_ESCF-.
;
	.PAGE
	.SBTTL	Instruction Format Descriptions
;
;  Format of instruction format description:
;	bytes 0-5	: ASCII blank-padded mnemonic string
;	byte  6		: operand count (bit 7 flags unconditional transfer
;				instruction, bit 6 flags special instruction,
;				bit 5 flags subroutine/procedure call, bit 4
;				flags illegal opcode, bit 3 flags potentially
;				CALLS-related instructions)
;	byte  7		: operand 1 type
;	byte  8		: operand 2 type
;	etc.
;	byte  7+N	: next entry
;
;  form of operand type is:
;	bits 0-3	: type code
;	bit 4		: relative branch vector (size given by bits 0-3)
;	bit 5		: set if length parameter of string, reset if address
;	bit 6		: code reference instead of data reference
;	bit 7		: procedure vector
;
;  declare definition macro
;
	.MACRO	DEFI	NAME,OP_NUM=0,OP1,OP2,OP3,OP4,OP5,OP6
	.ASCII	/%EXTRACT(0,6,NAME)/
COUNT	=	6-%LENGTH(NAME)
	.REPEAT	COUNT
	.ASCII	/ /
	.ENDR
	.BYTE	OP_NUM
	.IRP	ARG,<OP1,OP2,OP3,OP4,OP5,OP6>
	.IF	NOT_BLANK,ARG
	.BYTE	ARG
	.ENDC
	.ENDR
	.ENDM
;
; do definitions
;
UNDEF_INSTR:	DEFI	XXXX,INV_OPC
;
I_HALT:		DEFI	HALT,UCOND_TRN
I_NOP:		DEFI	NOP
I_REI:		DEFI	REI,UCOND_TRN+SUBR_CALL
I_BPT:		DEFI	BPT
I_RET:		DEFI	RET,UCOND_TRN+SUBR_CALL
I_RSB:		DEFI	RSB,UCOND_TRN+SUBR_CALL
I_LDPCTX:	DEFI	LDPCTX
I_SVPCTX:	DEFI	SVPCTX
I_CVTPS:	DEFI	CVTPS,4,ISD_PDS+STR_LEN,ISD_PDS,-
				ISD_LSN+STR_LEN,ISD_LSN
I_CVTSP:	DEFI	CVTSP,4,ISD_LSN+STR_LEN,ISD_LSN,-
				ISD_PDS+STR_LEN,ISD_PDS
I_INDEX:	DEFI	INDEX,6,ISD_LNG,ISD_LNG,ISD_LNG,ISD_LNG,ISD_LNG,-
				ISD_LNG
I_CRC:		DEFI	CRC,4,ISD_TBL,ISD_LNG,ISD_CHR+STR_LEN,ISD_CHR
I_PROBER:	DEFI	PROBER,3,ISD_BYT,ISD_WRD,ISD_BYT
I_PROBEW:	DEFI	PROBEW,3,ISD_BYT,ISD_WRD,ISD_BYT
I_INSQUE:	DEFI	INSQUE,2,ISD_QUD,ISD_QUD
I_REMQUE:	DEFI	REMQUE,2,ISD_QUD,ISD_LNG
I_BSBB:		DEFI	BSBB,1+SUBR_CALL,REL_VEC+ISD_BYT
I_BRB:		DEFI	BRB,1+UCOND_TRN,REL_VEC+ISD_BYT
I_BNEQ:		DEFI	BNEQ,1,REL_VEC+ISD_BYT
I_BEQL:		DEFI	BEQL,1,REL_VEC+ISD_BYT
I_BGTR:		DEFI	BGTR,1,REL_VEC+ISD_BYT
I_BLEQ:		DEFI	BLEQ,1,REL_VEC+ISD_BYT
I_JSB:		DEFI	JSB,1+SUBR_CALL,COD_REF+ISD_BYT
I_JMP:		DEFI	JMP,1+UCOND_TRN,COD_REF+ISD_BYT
I_BGEQ:		DEFI	BGEQ,1,REL_VEC+ISD_BYT
I_BLSS:		DEFI	BLSS,1,REL_VEC+ISD_BYT
I_BGTRU:	DEFI	BGTRU,1,REL_VEC+ISD_BYT
I_BLEQU:	DEFI	BLEQU,1,REL_VEC+ISD_BYT
I_BVC:		DEFI	BVC,1,REL_VEC+ISD_BYT
I_BVS:		DEFI	BVS,1,REL_VEC+ISD_BYT
I_BGEQU:	DEFI	BGEQU,1,REL_VEC+ISD_BYT
I_BLSSU:	DEFI	BLSSU,1,REL_VEC+ISD_BYT
I_ADDP4:	DEFI	ADDP4,4,ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS
I_ADDP6:	DEFI	ADDP6,6,ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS
I_SUBP4:	DEFI	SUBP4,4,ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS
I_SUBP6:	DEFI	SUBP6,6,ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_WRD+STR_LEN,ISD_PDS
I_CVTPT:	DEFI	CVTPT,5,ISD_WRD+STR_LEN,ISD_PDS,-
				ISD_TBL,ISD_WRD+STR_LEN,ISD_TNS
I_MULP:		DEFI	MULP,6,ISD_WRD+STR_LEN,ISD_PDS,ISD_WRD+STR_LEN,-
				ISD_PDS,ISD_WRD+STR_LEN,ISD_PDS
I_CVTTP:	DEFI	CVTTP,5,ISD_WRD+STR_LEN,ISD_TNS,ISD_TBL,-
				ISD_WRD+STR_LEN,ISD_PDS
I_DIVP:		DEFI	DIVP,6,ISD_WRD+STR_LEN,ISD_PDS,ISD_WRD+STR_LEN,-
				ISD_PDS,ISD_WRD+STR_LEN,ISD_PDS
I_MOVC3:	DEFI	MOVC3,3,ISD_WRD+STR_LEN,ISD_CHR,ISD_CHR
I_CMPC3:	DEFI	CMPC3,3,ISD_WRD+STR_LEN,ISD_CHR,ISD_CHR
I_SCANC:	DEFI	SCANC,4,ISD_WRD+STR_LEN,ISD_CHR,ISD_TBL,ISD_BYT
I_SPANC:	DEFI	SPANC,4,ISD_WRD+STR_LEN,ISD_CHR,ISD_TBL,ISD_BYT
I_MOVC5:	DEFI	MOVC5,5,ISD_WRD+STR_LEN,ISD_CHR,ISD_BYT,-
				ISD_WRD+STR_LEN,ISD_CHR
I_CMPC5:	DEFI	CMPC5,5,ISD_WRD+STR_LEN,ISD_CHR,ISD_BYT,-
				ISD_WRD+STR_LEN,ISD_CHR
I_MOVTC:	DEFI	MOVTC,6,ISD_WRD+STR_LEN,ISD_CHR,ISD_BYT,ISD_TBL,-
				ISD_WRD+STR_LEN,ISD_CHR
I_MOVTUC:	DEFI	MOVTUC,6,ISD_WRD+STR_LEN,ISD_CHR,ISD_BYT,ISD_TBL,-
				ISD_WRD+STR_LEN,ISD_CHR
I_BSBW:		DEFI	BSBW,1+SUBR_CALL,REL_VEC+ISD_WRD
I_BRW:		DEFI	BRW,1+UCOND_TRN,REL_VEC+ISD_WRD
I_CVTWL:	DEFI	CVTWL,2,ISD_WRD,ISD_LNG
I_CVTWB:	DEFI	CVTWB,2,ISD_WRD,ISD_BYT
I_MOVP:		DEFI	MOVP,3,ISD_WRD+STR_LEN,ISD_PDS,ISD_PDS
I_CMPP3:	DEFI	CMPP3,3,ISD_WRD+STR_LEN,ISD_PDS,ISD_PDS
I_CVTPL:	DEFI	CVTPL,3,ISD_WRD+STR_LEN,ISD_PDS,ISD_LNG
I_CMPP4:	DEFI	CMPP4,4,ISD_WRD+STR_LEN,ISD_PDS,ISD_WRD+STR_LEN,ISD_PDS
I_EDITPC:	DEFI	EDITPC,4,ISD_WRD+STR_LEN,ISD_PDS,ISD_PTN,ISD_LSN
I_MATCHC:	DEFI	MATCHC,4,ISD_WRD+STR_LEN,ISD_CHR,-
				ISD_WRD+STR_LEN,ISD_CHR
I_LOCC:		DEFI	LOCC,3,ISD_BYT,ISD_WRD+STR_LEN,ISD_CHR
I_SKPC:		DEFI	SKPC,3,ISD_BYT,ISD_WRD+STR_LEN,ISD_CHR
I_MOVZWL:	DEFI	MOVZWL,2,ISD_WRD,ISD_LNG
I_ACBW:		DEFI	ACBW,4,ISD_WRD,ISD_WRD,ISD_WRD,REL_VEC+ISD_WRD
I_MOVAW:	DEFI	MOVAW,2,ISD_WRD,ISD_LNG
I_PUSHAW:	DEFI	PUSHAW,1,ISD_WRD
I_ADDF2:	DEFI	ADDF2,2,ISD_FLT,ISD_FLT
I_ADDF3:	DEFI	ADDF3,3,ISD_FLT,ISD_FLT,ISD_FLT
I_SUBF2:	DEFI	SUBF2,2,ISD_FLT,ISD_FLT
I_SUBF3:	DEFI	SUBF3,3,ISD_FLT,ISD_FLT,ISD_FLT
I_MULF2:	DEFI	MULF2,2,ISD_FLT,ISD_FLT
I_MULF3:	DEFI	MULF3,3,ISD_FLT,ISD_FLT,ISD_FLT
I_DIVF2:	DEFI	DIVF2,2,ISD_FLT,ISD_FLT
I_DIVF3:	DEFI	DIVF3,3,ISD_FLT,ISD_FLT,ISD_FLT
I_CVTFB:	DEFI	CVTFB,2,ISD_FLT,ISD_BYT
I_CVTFW:	DEFI	CVTFW,2,ISD_FLT,ISD_WRD
I_CVTFL:	DEFI	CVTFL,2,ISD_FLT,ISD_LNG
I_CVTRFL:	DEFI	CVTRFL,2,ISD_FLT,ISD_LNG
I_CVTBF:	DEFI	CVTBF,2,ISD_BYT,ISD_FLT
I_CVTWF:	DEFI	CVTWF,2,ISD_WRD,ISD_FLT
I_CVTLF:	DEFI	CVTLF,2,ISD_LNG,ISD_FLT
I_ACBF:		DEFI	ACBF,4,ISD_FLT,ISD_FLT,ISD_FLT,REL_VEC+ISD_WRD
I_MOVF:		DEFI	MOVF,2,ISD_FLT,ISD_FLT
I_CMPF:		DEFI	CMPF,2,ISD_FLT,ISD_FLT
I_MNEGF:	DEFI	MNEGF,2,ISD_FLT,ISD_FLT
I_TSTF:		DEFI	TSTF,1,ISD_FLT
I_EMODF:	DEFI	EMODF,5,ISD_FLT,ISD_BYT,ISD_FLT,ISD_LNG,ISD_FLT
I_POLYF:	DEFI	POLYF,3,ISD_FLT,ISD_WRD,ISD_TBL
I_CVTFD:	DEFI	CVTFD,2,ISD_FLT,ISD_DFL
I_ADAWI:	DEFI	ADAWI,2,ISD_WRD,ISD_WRD
I_INSQHI:	DEFI	INSQHI,2,ISD_QUD,ISD_QUD
I_INSQTI:	DEFI	INSQTI,2,ISD_QUD,ISD_QUD
I_REMQHI:	DEFI	REMQHI,2,ISD_QUD,ISD_LNG
I_REMQTI:	DEFI	REMQTI,2,ISD_QUD,ISD_LNG
I_ADDD2:	DEFI	ADDD2,2,ISD_DFL,ISD_DFL
I_ADDD3:	DEFI	ADDD3,3,ISD_DFL,ISD_DFL,ISD_DFL
I_SUBD2:	DEFI	SUBD2,2,ISD_DFL,ISD_DFL
I_SUBD3:	DEFI	SUBD3,3,ISD_DFL,ISD_DFL,ISD_DFL
I_MULD2:	DEFI	MULD2,2,ISD_DFL,ISD_DFL
I_MULD3:	DEFI	MULD3,3,ISD_DFL,ISD_DFL,ISD_DFL
I_DIVD2:	DEFI	DIVD2,2,ISD_DFL,ISD_DFL
I_DIVD3:	DEFI	DIVD3,3,ISD_DFL,ISD_DFL,ISD_DFL
I_CVTDB:	DEFI	CVTDB,2,ISD_DFL,ISD_BYT
I_CVTDW:	DEFI	CVTDW,2,ISD_DFL,ISD_WRD
I_CVTDL:	DEFI	CVTDL,2,ISD_DFL,ISD_LNG
I_CVTRDL:	DEFI	CVTRDL,2,ISD_DFL,ISD_LNG
I_CVTBD:	DEFI	CVTBD,2,ISD_BYT,ISD_DFL
I_CVTWD:	DEFI	CVTWD,2,ISD_WRD,ISD_DFL
I_CVTLD:	DEFI	CVTLD,2,ISD_LNG,ISD_DFL
I_ACBD:		DEFI	ACBD,4,ISD_DFL,ISD_DFL,ISD_DFL,REL_VEC+ISD_WRD
I_MOVD:		DEFI	MOVD,2,ISD_DFL,ISD_DFL
I_CMPD:		DEFI	CMPD,2,ISD_DFL,ISD_DFL
I_MNEGD:	DEFI	MNEGD,2,ISD_DFL,ISD_DFL
I_TSTD:		DEFI	TSTD,1,ISD_DFL
I_EMODD:	DEFI	EMODD,5,ISD_DFL,ISD_BYT,ISD_DFL,ISD_LNG,ISD_DFL
I_POLYD:	DEFI	POLYD,3,ISD_DFL,ISD_WRD,ISD_TBL
I_CVTDF:	DEFI	CVTDF,2,ISD_DFL,ISD_FLT
I_ASHL:		DEFI	ASHL,3,ISD_BYT,ISD_LNG,ISD_LNG
I_ASHQ:		DEFI	ASHQ,3,ISD_BYT,ISD_QUD,ISD_QUD
I_EMUL:		DEFI	EMUL,4,ISD_LNG,ISD_LNG,ISD_LNG,ISD_QUD
I_EDIV:		DEFI	EDIV,4,ISD_LNG,ISD_QUD,ISD_LNG,ISD_LNG
I_CLRQ:		DEFI	CLRQ,1,ISD_QUD
I_MOVQ:		DEFI	MOVQ,2,ISD_QUD,ISD_QUD
I_MOVAQ:	DEFI	MOVAQ,2,ISD_QUD,ISD_LNG
I_PUSHAQ:	DEFI	PUSHAQ,1,ISD_QUD
I_ADDB2:	DEFI	ADDB2,2,ISD_BYT,ISD_BYT
I_ADDB3:	DEFI	ADDB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_SUBB2:	DEFI	SUBB2,2,ISD_BYT,ISD_BYT
I_SUBB3:	DEFI	SUBB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_MULB2:	DEFI	MULB2,2,ISD_BYT,ISD_BYT
I_MULB3:	DEFI	MULB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_DIVB2:	DEFI	DIVB2,2,ISD_BYT,ISD_BYT
I_DIVB3:	DEFI	DIVB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_BISB2:	DEFI	BISB2,2,ISD_BYT,ISD_BYT
I_BISB3:	DEFI	BISB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_BICB2:	DEFI	BICB2,2,ISD_BYT,ISD_BYT
I_BICB3:	DEFI	BICB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_XORB2:	DEFI	XORB2,2,ISD_BYT,ISD_BYT
I_XORB3:	DEFI	XORB3,3,ISD_BYT,ISD_BYT,ISD_BYT
I_MNEGB:	DEFI	MNEGB,2,ISD_BYT,ISD_BYT
I_CASEB:	DEFI	CASEB,4,ISD_BYT,ISD_BYT,ISD_BYT,ISD_TBL
I_MOVB:		DEFI	MOVB,2,ISD_BYT,ISD_BYT
I_CMPB:		DEFI	CMPB,2,ISD_BYT,ISD_BYT
I_MCOMB:	DEFI	MCOMB,2,ISD_BYT,ISD_BYT
I_BITB:		DEFI	BITB,2,ISD_BYT,ISD_BYT
I_CLRB:		DEFI	CLRB,1,ISD_BYT
I_TSTB:		DEFI	TSTB,1,ISD_BYT
I_INCB:		DEFI	INCB,1,ISD_BYT
I_DECB:		DEFI	DECB,1,ISD_BYT
I_CVTBL:	DEFI	CVTBL,2,ISD_BYT,ISD_LNG
I_CVTBW:	DEFI	CVTBW,2,ISD_BYT,ISD_WRD
I_MOVZBL:	DEFI	MOVZBL,2,ISD_BYT,ISD_LNG
I_MOVZBW:	DEFI	MOVZBW,2,ISD_BYT,ISD_WRD
I_ROTL:		DEFI	ROTL,3,ISD_BYT,ISD_LNG,ISD_LNG
I_ACBB:		DEFI	ACBB,4,ISD_BYT,ISD_BYT,ISD_BYT,REL_VEC+ISD_WRD
I_MOVAB:	DEFI	MOVAB,2,ISD_BYT,ISD_LNG
I_PUSHAB:	DEFI	PUSHAB,1,ISD_BYT
I_ADDW2:	DEFI	ADDW2,2,ISD_WRD,ISD_WRD
I_ADDW3:	DEFI	ADDW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_SUBW2:	DEFI	SUBW2,2,ISD_WRD,ISD_WRD
I_SUBW3:	DEFI	SUBW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_MULW2:	DEFI	MULW2,2,ISD_WRD,ISD_WRD
I_MULW3:	DEFI	MULW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_DIVW2:	DEFI	DIVW2,2,ISD_WRD,ISD_WRD
I_DIVW3:	DEFI	DIVW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_BISW2:	DEFI	BISW2,2,ISD_WRD,ISD_WRD
I_BISW3:	DEFI	BISW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_BICW2:	DEFI	BICW2,2,ISD_WRD,ISD_WRD
I_BICW3:	DEFI	BICW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_XORW2:	DEFI	XORW2,2,ISD_WRD,ISD_WRD
I_XORW3:	DEFI	XORW3,3,ISD_WRD,ISD_WRD,ISD_WRD
I_MNEGW:	DEFI	MNEGW,2,ISD_WRD,ISD_WRD
I_CASEW:	DEFI	CASEW,4,ISD_WRD,ISD_WRD,ISD_WRD,ISD_TBL
I_MOVW:		DEFI	MOVW,2,ISD_WRD,ISD_WRD
I_CMPW:		DEFI	CMPW,2,ISD_WRD,ISD_WRD
I_MCOMW:	DEFI	MCOMW,2,ISD_WRD,ISD_WRD
I_BITW:		DEFI	BITW,2,ISD_WRD,ISD_WRD
I_CLRW:		DEFI	CLRW,1,ISD_WRD
I_TSTW:		DEFI	TSTW,1,ISD_WRD
I_INCW:		DEFI	INCW,1,ISD_WRD
I_DECW:		DEFI	DECW,1,ISD_WRD
I_BICPSW:	DEFI	BICPSW,1,ISD_WRD
I_BISPSW:	DEFI	BISPSW,1,ISD_WRD
I_POPR:		DEFI	POPR,1,ISD_WRD
I_PUSHR:	DEFI	PUSHR,1,ISD_WRD
I_CHMK:		DEFI	CHMK,1,ISD_WRD
I_CHME:		DEFI	CHME,1,ISD_WRD
I_CHMS:		DEFI	CHMS,1,ISD_WRD
I_CHMU:		DEFI	CHMU,1,ISD_WRD
I_ADDL2:	DEFI	ADDL2,2,ISD_LNG,ISD_LNG
I_ADDL3:	DEFI	ADDL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_SUBL2:	DEFI	SUBL2,2,ISD_LNG,ISD_LNG
I_SUBL3:	DEFI	SUBL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_MULL2:	DEFI	MULL2,2,ISD_LNG,ISD_LNG
I_MULL3:	DEFI	MULL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_DIVL2:	DEFI	DIVL2,2,ISD_LNG,ISD_LNG
I_DIVL3:	DEFI	DIVL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_BISL2:	DEFI	BISL2,2,ISD_LNG,ISD_LNG
I_BISL3:	DEFI	BISL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_BICL2:	DEFI	BICL2,2,ISD_LNG,ISD_LNG
I_BICL3:	DEFI	BICL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_XORL2:	DEFI	XORL2,2,ISD_LNG,ISD_LNG
I_XORL3:	DEFI	XORL3,3,ISD_LNG,ISD_LNG,ISD_LNG
I_MNEGL:	DEFI	MNEGL,2,ISD_LNG,ISD_LNG
I_CASEL:	DEFI	CASEL,4,ISD_LNG,ISD_LNG,ISD_LNG,ISD_TBL
I_MOVL:		DEFI	MOVL,2,ISD_LNG,ISD_LNG
I_CMPL:		DEFI	CMPL,2,ISD_LNG,ISD_LNG
I_MCOML:	DEFI	MCOML,2,ISD_LNG,ISD_LNG
I_BITL:		DEFI	BITL,2,ISD_LNG,ISD_LNG
I_CLRL:		DEFI	CLRL,1,ISD_LNG
I_TSTL:		DEFI	TSTL,1,ISD_LNG
I_INCL:		DEFI	INCL,1,ISD_LNG
I_DECL:		DEFI	DECL,1,ISD_LNG
I_ADWC:		DEFI	ADWC,2,ISD_LNG,ISD_LNG
I_SBWC:		DEFI	SBWC,2,ISD_LNG,ISD_LNG
I_MTPR:		DEFI	MTPR,2,ISD_LNG,ISD_LNG
I_MFPR:		DEFI	MFPR,2,ISD_LNG,ISD_LNG
I_MOVPSL:	DEFI	MOVPSL,1,ISD_LNG
I_PUSHL:	DEFI	PUSHL,1,ISD_LNG
I_MOVAL:	DEFI	MOVAL,2,ISD_LNG,ISD_LNG
I_PUSHAL:	DEFI	PUSHAL,1,ISD_LNG
I_BBS:		DEFI	BBS,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBC:		DEFI	BBC,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBSS:		DEFI	BBSS,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBCS:		DEFI	BBCS,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBSC:		DEFI	BBSC,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBCC:		DEFI	BBCC,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBSSI:	DEFI	BBSSI,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BBCCI:	DEFI	BBCCI,3,ISD_LNG,ISD_BYT,REL_VEC+ISD_BYT
I_BLBS:		DEFI	BLBS,2,ISD_LNG,REL_VEC+ISD_BYT
I_BLBC:		DEFI	BLBC,2,ISD_LNG,REL_VEC+ISD_BYT
I_FFS:		DEFI	FFS,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_FFC:		DEFI	FFC,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_CMPV:		DEFI	CMPV,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_CMPZV:	DEFI	CMPZV,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_EXTV:		DEFI	EXTV,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_EXTZV:	DEFI	EXTZV,4,ISD_LNG,ISD_BYT,ISD_BYT,ISD_LNG
I_INSV:		DEFI	INSV,4,ISD_LNG,ISD_LNG,ISD_BYT,ISD_BYT
I_ACBL:		DEFI	ACBL,4,ISD_LNG,ISD_LNG,ISD_LNG,REL_VEC+ISD_WRD
I_AOBLSS:	DEFI	AOBLSS,3,ISD_LNG,ISD_LNG,REL_VEC+ISD_BYT
I_AOBLEQ:	DEFI	AOBLEQ,3,ISD_LNG,ISD_LNG,REL_VEC+ISD_BYT
I_SOBGEQ:	DEFI	SOBGEQ,2,ISD_LNG,REL_VEC+ISD_BYT
I_SOBGTR:	DEFI	SOBGTR,2,ISD_LNG,REL_VEC+ISD_BYT
I_CVTLB:	DEFI	CVTLB,2,ISD_LNG,ISD_BYT
I_CVTLW:	DEFI	CVTLW,2,ISD_LNG,ISD_WRD
I_ASHP:		DEFI	ASHP,6,ISD_BYT,ISD_WRD+STR_LEN,ISD_PDS,ISD_BYT,-
				ISD_WRD+STR_LEN,ISD_PDS
I_CVTLP:	DEFI	CVTLP,3,ISD_LNG,ISD_WRD+STR_LEN,ISD_PDS
I_CALLG:	DEFI	CALLG,2+SUBR_CALL,ISD_TBL,ISD_BYT+COD_REF+PROC_VEC
I_CALLS:	DEFI	CALLS,2+SUBR_CALL,ISD_LNG,ISD_BYT+COD_REF+PROC_VEC
I_XFC:		DEFI	XFC
I_ESCD:		DEFI	ESCD,SPEC_INSTR
I_ESCE:		DEFI	ESCE,INV_OPC
I_ESCF:		DEFI	ESCF,SPEC_INSTR
;
	.PAGE
	.SBTTL	Auxiliary Tables for ^XFD and ^XFF Prefix Opcodes
;
;  begin the 2nd self-relative table
;
TBL2_PTR:
	.BYTE	^X32
	.WORD	I_CVTDH-.
	.BYTE	^X33
	.WORD	I_CVTGF-.
	.BYTE	^X40
	.WORD	I_ADDG2-.
	.BYTE	^X41
	.WORD	I_ADDG3-.
	.BYTE	^X42
	.WORD	I_SUBG2-.
	.BYTE	^X43
	.WORD	I_SUBG3-.
	.BYTE	^X44
	.WORD	I_MULG2-.
	.BYTE	^X45
	.WORD	I_MULG3-.
	.BYTE	^X46
	.WORD	I_DIVG2-.
	.BYTE	^X47
	.WORD	I_DIVG3-.
	.BYTE	^X48
	.WORD	I_CVTGB-.
	.BYTE	^X49
	.WORD	I_CVTGW-.
	.BYTE	^X4A
	.WORD	I_CVTGL-.
	.BYTE	^X4B
	.WORD	I_CVTRGL-.
	.BYTE	^X4C
	.WORD	I_CVTBG-.
	.BYTE	^X4D
	.WORD	I_CVTWG-.
	.BYTE	^X4E
	.WORD	I_CVTLG-.
	.BYTE	^X4F
	.WORD	I_ACBG-.
	.BYTE	^X50
	.WORD	I_MOVG-.
	.BYTE	^X51
	.WORD	I_CMPG-.
	.BYTE	^X52
	.WORD	I_MNEGG-.
	.BYTE	^X53
	.WORD	I_TSTG-.
	.BYTE	^X54
	.WORD	I_EMODG-.
	.BYTE	^X55
	.WORD	I_POLYG-.
	.BYTE	^X56
	.WORD	I_CVTGH-.
	.BYTE	^X60
	.WORD	I_ADDH2-.
	.BYTE	^X61
	.WORD	I_ADDH3-.
	.BYTE	^X62
	.WORD	I_SUBH2-.
	.BYTE	^X63
	.WORD	I_SUBH3-.
	.BYTE	^X66
	.WORD	I_MULH2-.
	.BYTE	^X65
	.WORD	I_MULH3-.
	.BYTE	^X66
	.WORD	I_DIVH2-.
	.BYTE	^X67
	.WORD	I_DIVH3-.
	.BYTE	^X68
	.WORD	I_CVTHB-.
	.BYTE	^X69
	.WORD	I_CVTHW-.
	.BYTE	^X6A
	.WORD	I_CVTHL-.
	.BYTE	^X6B
	.WORD	I_CVTRHL-.
	.BYTE	^X6C
	.WORD	I_CVTBH-.
	.BYTE	^X6D
	.WORD	I_CVTWH-.
	.BYTE	^X6E
	.WORD	I_CVTLH-.
	.BYTE	^X6F
	.WORD	I_ACBH-.
	.BYTE	^X70
	.WORD	I_MOVH-.
	.BYTE	^X71
	.WORD	I_CMPH-.
	.BYTE	^X72
	.WORD	I_MNEGH-.
	.BYTE	^X73
	.WORD	I_TSTH-.
	.BYTE	^X74
	.WORD	I_EMODH-.
	.BYTE	^X75
	.WORD	I_POLYH-.
	.BYTE	^X76
	.WORD	I_CVTHG-.
	.BYTE	^X78
	.WORD	I_CLRH-.
MAX_2_ENTRIES	=	. - TBL2_PTR
;
;  begin the 3rd self-relative table
;
TBL3_PTR:
	.BYTE	^XFD
	.WORD	I_BUGL-.
	.BYTE	^XFE
	.WORD	I_BUGW-.
MAX_3_ENTRIES	=	. - TBL3_PTR
;
;  do definitions
;
I_CVTDH:	DEFI	CVTDH,2,ISD_DFL,ISD_HFL
I_CVTGF:	DEFI	CVTGF,2,ISD_GFL,ISD_FLT
I_ADDG2:	DEFI	ADDG2,2,ISD_GFL,ISD_GFL
I_ADDG3:	DEFI	ADDG3,3,ISD_GFL,ISD_GFL,ISD_GFL
I_SUBG2:	DEFI	SUBG2,2,ISD_GFL,ISD_GFL
I_SUBG3:	DEFI	SUBG3,3,ISD_GFL,ISD_GFL,ISD_GFL
I_MULG2:	DEFI	MULG2,2,ISD_GFL,ISD_GFL
I_MULG3:	DEFI	MULG3,3,ISD_GFL,ISD_GFL,ISD_GFL
I_DIVG2:	DEFI	DIVG2,2,ISD_GFL,ISD_GFL
I_DIVG3:	DEFI	DIVG3,3,ISD_GFL,ISD_GFL,ISD_GFL
I_CVTGB:	DEFI	CVTGB,2,ISD_GFL,ISD_BYT
I_CVTGW:	DEFI	CVTGW,2,ISD_GFL,ISD_WRD
I_CVTGL:	DEFI	CVTGL,2,ISD_GFL,ISD_LNG
I_CVTRGL:	DEFI	CVTRGL,2,ISD_GFL,ISD_LNG
I_CVTBG:	DEFI	CVTBG,2,ISD_BYT,ISD_GFL
I_CVTWG:	DEFI	CVTWG,2,ISD_WRD,ISD_GFL
I_CVTLG:	DEFI	CVTLG,2,ISD_LNG,ISD_GFL
I_ACBG:		DEFI	ACBG,4,ISD_GFL,ISD_GFL,ISD_GFL,REL_VEC+ISD_WRD
I_MOVG:		DEFI	MOVG,2,ISD_GFL,ISD_GFL
I_CMPG:		DEFI	CMPG,2,ISD_GFL,ISD_GFL
I_MNEGG:	DEFI	MNEGG,2,ISD_GFL,ISD_GFL
I_TSTG:		DEFI	TSTG,1,ISD_GFL
I_EMODG:	DEFI	EMODG,5,ISD_GFL,ISD_WRD,ISD_GFL,ISD_LNG,ISD_GFL
I_POLYG:	DEFI	POLYG,3,ISD_GFL,ISD_WRD,ISD_TBL
I_CVTGH:	DEFI	CVTGH,2,ISD_GFL,ISD_HFL
I_ADDH2:	DEFI	ADDH2,2,ISD_HFL,ISD_HFL
I_ADDH3:	DEFI	ADDH3,3,ISD_HFL,ISD_HFL,ISD_HFL
I_SUBH2:	DEFI	SUBH2,2,ISD_HFL,ISD_HFL
I_SUBH3:	DEFI	SUBH3,3,ISD_HFL,ISD_HFL,ISD_HFL
I_MULH2:	DEFI	MULH2,2,ISD_HFL,ISD_HFL
I_MULH3:	DEFI	MULH3,3,ISD_HFL,ISD_HFL,ISD_HFL
I_DIVH2:	DEFI	DIVH2,2,ISD_HFL,ISD_HFL
I_DIVH3:	DEFI	DIVH3,3,ISD_HFL,ISD_HFL,ISD_HFL
I_CVTHB:	DEFI	CVTHB,2,ISD_HFL,ISD_BYT
I_CVTHW:	DEFI	CVTHW,2,ISD_HFL,ISD_WRD
I_CVTHL:	DEFI	CVTHL,2,ISD_HFL,ISD_LNG
I_CVTRHL:	DEFI	CVTRHL,2,ISD_HFL,ISD_LNG
I_CVTBH:	DEFI	CVTBH,2,ISD_BYT,ISD_HFL
I_CVTWH:	DEFI	CVTWH,2,ISD_WRD,ISD_HFL
I_CVTLH:	DEFI	CVTLH,2,ISD_LNG,ISD_HFL
I_ACBH:		DEFI	ACBH,4,ISD_HFL,ISD_HFL,ISD_HFL,REL_VEC+ISD_WRD
I_MOVH:		DEFI	MOVH,2,ISD_HFL,ISD_HFL
I_CMPH:		DEFI	CMPH,2,ISD_HFL,ISD_HFL
I_MNEGH:	DEFI	MNEGH,2,ISD_HFL,ISD_HFL
I_TSTH:		DEFI	TSTH,1,ISD_HFL
I_EMODH:	DEFI	EMODH,5,ISD_HFL,ISD_WRD,ISD_HFL,ISD_LNG,ISD_HFL
I_POLYH:	DEFI	POLYH,3,ISD_HFL,ISD_WRD,ISD_TBL
I_CVTHG:	DEFI	CVTHG,2,ISD_HFL,ISD_GFL
I_CLRH:		DEFI	CLRH,1,ISD_HFL
;
I_BUGL:		DEFI	BUGL,1,ISD_LNG
I_BUGW:		DEFI	BUGW,1,ISD_WRD
;
	.PAGE
	.SBTTL	Operand Types
;
;  define operand sizes
;
OP_SIZ:	.BYTE	1		; byte
	.BYTE	2		; word
	.BYTE	4		; longword
	.BYTE	8		; quadword
	.BYTE	4		; F_floating
	.BYTE	8		; D_floating
	.BYTE	8		; G_floating
	.BYTE	16		; H_floating
	.BYTE	1		; character string
	.BYTE	1		; packed decimal string
	.BYTE	-1		; leading separate string
	.BYTE	-1		; trailing numeric string
	.BYTE	-1		; table structure
	.BYTE	1		; edit pattern string
	.BYTE	16		; octaword
;
;  define table element types and table sizes for all instructions that use
;    tables
;  format: bytes 0 & 1	= opcode
;	   byte 2	= element type
;	   bytes 3 & 4	= number of table entries (-1=specified by previous
;				operand, -2=specified by first element, -3=
;				CASEx instruction vector list, in-line code,
;				-4=CALLG argument list)
;
TBL_TYPES:
	.WORD	^X55	; POLYF
	.BYTE	ISD_FLT
	.WORD	-1
	.WORD	^X75	; POLYD
	.BYTE	ISD_DFL
	.WORD	-1
	.WORD	^X8F	; CASEB
	.BYTE	ISD_WRD
	.WORD	-3
	.WORD	^XAF	; CASEW
	.BYTE	ISD_WRD
	.WORD	-3
	.WORD	^XCF	; CASEL
	.BYTE	ISD_WRD
	.WORD	-3
	.WORD	^XFA	; CALLG
	.BYTE	ISD_LNG
	.WORD	-4
	.WORD	^X2E	; MOVTC
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X2F	; MOVTUC
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X2A	; SCANC
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X2B	; SPANC
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X0B	; CRC
	.BYTE	ISD_LNG
	.WORD	16
	.WORD	^X24	; CVTPT
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X26	; CVTTP
	.BYTE	ISD_BYT
	.WORD	256
	.WORD	^X55FD	; POLYG
	.BYTE	ISD_GFL
	.WORD	-1
	.WORD	^X75FD	; POLYH
	.BYTE	ISD_HFL
	.WORD	-1
	.WORD	0		; end of table
;
	.PAGE
	.SBTTL	Additional Strings for Output
;
DISPL_TBL:
	.WORD	BYT_STR - DISPL_TBL
	.WORD	BYT_DEF_STR - DISPL_TBL
	.WORD	WRD_STR - DISPL_TBL
	.WORD	WRD_DEF_STR - DISPL_TBL
	.WORD	LNG_STR - DISPL_TBL
	.WORD	LNG_DEF_STR - DISPL_TBL
;
BYT_STR:
	.ASCID	/B^/
BYT_DEF_STR:
	.ASCID	/@B^/
WRD_STR:
	.ASCID	/W^/
WRD_DEF_STR:
	.ASCID	/@W^/
LNG_STR:
	.ASCID	/L^/
LNG_DEF_STR:
	.ASCID	/@L^/
;
	.PAGE
	.SBTTL	Local Static Storage
;
	.PSECT	$LOCAL,PIC,CON,REL,RD,WRT,NOEXE,LCL,NOSHR,LONG
;
CASE_NUM:
	.LONG	19999		; local symbol counter for CASEx instructions
;
	.PAGE
	.SBTTL	DISM_INSTR Procedure
;
;  declare stack-resident local storage
;
	.PSECT	ABS_OFS,ABS,NOEXE,NORD,NOWRT
SCR:	.BLKO	1		; scratch octaword
DESCR:	.BLKQ	1		; dynamic string descriptor
DESCR2:	.BLKQ	1		; alternate descriptor
OFFSET:	.BLKL	1		; relative branch offset
OPCODE:	.BLKL	1		; opcode (maintaining stack alignment)
CASEVEC:
	.BLKL	1		; number of CASE vectors in current instr
SAVOPR:	.BLKQ	1		; saved operand data for later context handling
LENSTR:	.BLKW	1		; length of trimmed ASCII string
INDEX:	.BLKB	1		; index register code
BASEREG:
	.BLKB	1		; base register code
TXTBUF:	.BLKB	40		; scratch text buffer
END_LOCAL_STORAGE=.
;
;  declare instruction scrollback pointer array
;
	.PSECT	$LOCAL,NOEXE,WRT,RD,LCL,NOSHR,PIC,CON,REL,LONG
ILV_PTR:
	.BLKL			; index to next buffer slot
ILV_SIZE:
	.BLKL			; number of slots in buffer
ILV_QUEUE:
	.BLKL	32		; array of buffer slots
;
	.PSECT	$CODE,EXE,NOWRT,RD,LCL,SHR,PIC,CON,REL,LONG
;
	.ENTRY	DISM_INSTR,^M<R2,R3,R4,R5,R6,R7,R9,R10,R11>
;
;  this is the actual disassembly procedure.
;
	MOVAL	DATA_STRUC_BASE,R11	; get base address of data structures,
	MOVAL	@4(AP),R10		; get address of "address",
	SUBL2	#END_LOCAL_STORAGE,SP	; create local storage area,
	MOVAL	(SP),R9			; save address in R9,
	MOVC5	#0,(SP),#0,#END_LOCAL_STORAGE,(R9) ; clear local storage area,
	CASEB	@8(AP),#0,#2		; vector to set-up code.
3000$:	.WORD	3001$ - 3000$		; 0 - normal pass 1
	.WORD	3004$ - 3000$		; 1 - normal pass 2
	.WORD	3003$ - 3000$		; 2 - pass 1, init address pointers
	MOVZWL	#SS$_IVMODE,R0		; invalid mode code, error exit.
	RET
3003$:	MNEGL	#1,ILV_PTR		; initialize queue pointer,
	CLRL	ILV_SIZE		; initialize queue count,
	CLRB	@8(AP)			; change to normal pass 1.
3001$:	ADDL3	#1,ILV_PTR,R0		; increment queue pointer,
	BICL2	#^C^X1F,R0		; cause wrap-around at 32,
	ADDL3	#1,ILV_SIZE,R1		; increment size counter,
	CMPL	R1,#32			; test if queue full,
	BGEQ	3002$			; skip if so,
	MOVL	R1,ILV_SIZE		; else store updated size,
3002$:	MOVL	(R10),ILV_QUEUE[R0]	; store opcode address in queue,
	MOVL	R0,ILV_PTR		; store updated index,
3004$:	PUSHAB	OPCODE(R9)		; store address of opcode buffer,
	PUSHAL	(R10)			; store address of "address",
	CALLS	#2,G^COPY_BYTE		; get byte from file,
	INCL	(R10)			; update "address",
	MOVZBL	OPCODE(R9),R2		; get result,
	MOVAW	B^FORMAT_POINTER-DATA_STRUC_BASE(R11)[R2],R3
					; get address of offset word,
	CVTWL	(R3),R4			; get word,
	ADDL2	R4,R3			; get address of description,
	CMPZV	#6,#1,6(R3),#1		; test if a two-byte opcode,
	BNEQ	5$			; no, stay with what we have.
	PUSHAB	OPCODE+1(R9)		; yes, get a new byte from file,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE
	INCL	(R10)			; update "address" again,
	CLRL	R4			; zero table index,
	CMPB	R2,#^XFD		; is it 1st aux. table of opcodes?
	BNEQ	3$			; no, use table 3.
6$:	CMPB	TBL2_PTR-DATA_STRUC_BASE(R11)[R4],OPCODE+1(R9)
					; compare entry against opcode byte,
	BEQL	8$			; jump if match,
	ACBL	#MAX_2_ENTRIES,#3,R4,6$	; else try next entry,
	MOVL	#DISM__INVOPCODE,R0	; end of entries, return error.
	RET
8$:	MOVAB	TBL2_PTR+1-DATA_STRUC_BASE(R11)[R4],R3
					; get address of offset word,
	CVTWL	(R3),R4
	ADDL2	R4,R3			; get address of description,
	BRB	5$			; proceed as usual.
3$:	CMPB	TBL3_PTR-DATA_STRUC_BASE(R11)[R4],OPCODE+1(R9)
					; compare entry agains opcode byte,
	BEQL	9$			; jump if match,
	ACBL	#MAX_3_ENTRIES,#3,R4,3$	; else try next entry,
	MOVL	#DISM__INVOPCODE,R0	; end of entries, return error.
	RET
9$:	MOVAB	TBL3_PTR+1-DATA_STRUC_BASE(R11)[R4],R3
					; get address of offset word,
	CVTWL	(R3),R4
	ADDL2	R4,R3			; get address of description,
5$:	BLBC	@8(AP),10$		; if pass 1, skip this.
	CLRQ	DESCR(R9)		; else create a dynamic string descriptor,
	MOVB	#2,DESCR+3(R9)		; fill it in,
	PUSHAQ	B^TAB_S-DATA_STRUC_BASE(R11)
					; copy tab to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVAB	(R3),DESCR2+4(R9)	; build descriptor of opcode,
	LOCC	#^A/ /,#6,(R3)		; find length of string,
	SUBL3	R0,#6,DESCR2(R9)
	PUSHAQ	DESCR2(R9)		; push address of descriptor,
	PUSHAQ	DESCR(R9)		; append opcode name to line,
	CALLS	#2,G^STR$APPEND
10$:	MOVZBL	6(R3),R5		; get operand count,
	BICB2	#^XF8,R5		; check only operand count field,
	TSTL	R5
	BNEQ	11$			; operands, skip branch.
	BRW	END_INSTR		; no operands, end processing.
11$:	BLBC	@8(AP),12$		; if pass 1, skip text work.
	PUSHAQ	B^TAB_S-DATA_STRUC_BASE(R11)
					; if pass 2, append another tab,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
12$:	MOVL	#1,R6			; set up R6 as index thru operands,
OPRND_LP:
	MOVZBL	6(R3)[R6],R0		; get operand type byte,
	CMPZV	#4,#1,R0,#1		; test if relative branch vector,
	BNEQ	NOT_RELVEC		; not, try as conventional operand.
	EXTZV	#0,#4,R0,R1		; yes, extract size code,
	PUSHL	R1			; save R1,
	PUSHAB	OFFSET(R9)		; get first byte of offset,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE
	INCL	(R10)			; update "address",
	MOVL	(SP)+,R1		; restore R1 from stack,
	CMPB	R1,#ISD_BYT		; check if byte offset,
	BEQL	20$			; yes, use as is.
	PUSHAB	OFFSET+1(R9)		; no, get next byte,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE
	INCL	(R10)			; point to next byte,
	CVTWL	OFFSET(R9),OFFSET(R9)	; sign-extend word,
	BRB	21$
20$:	CVTBL	OFFSET(R9),OFFSET(R9)	; sign-extend byte,
21$:	CLRB	BASEREG(R9)		; mark register codes as unused,
	BRW	BUILD_OPREF		; handle deciphered operand.
;
NOT_RELVEC:
	MOVB	#1,BASEREG(R9)		; mark registers flag,
	MNEGB	#1,INDEX(R9)		; mark index register flag as unused,
NOT_RELVEC_2:
	CMPZV	#0,#4,R0,#ISD_TBL	; test if table type operand,
	BEQL	1$
	BRW	NOT_TBL			; no, try ordinary operands.
1$:	MOVAB	TBL_TYPES-DATA_STRUC_BASE(R11),R1
					; yes, get address of table type table,
10$:	TSTW	(R1)			; check if end of table,
	BEQL	20$			; yes, report error.
	CMPW	(R1),OPCODE(R9)		; no, compare opcode against table,
	BEQL	30$			; match, process it.
	MOVAB	5(R1),R1		; no match, skip to next entry.
	BRB	10$
20$:	PUSHL	#DISM__CORDTSTRUC	; report fatal "data structures
	CALLS	#1,G^LIB$SIGNAL		; corrupted" error.
	RET
30$:	CMPW	3(R1),#-3		; test if CASEx instruction,
	BEQL	31$
	BRW	NOT_TBL			; no, addressed normally.
31$:	MOVL	CASEVEC(R9),R2		; yes, get immediate vector count,
40$:	MOVL	(R10),R4		; get current address,
	BLBC	@8(AP),41$		; if pass 2,
	MOVZWL	DESCR(R9),R0		; find end of text line,
	DECL	R0
	ADDL3	DESCR+4(R9),R0,R0
	MOVB	#^A/ /,(R0)		; remove trailing comma,
	PUSHAQ	DESCR(R9)		; write out current line,
	CALLS	#1,G^WRITE_OUTPUT_TEXT
	PUSHAQ	DESCR(R9)		; deassign string,
	CALLS	#1,G^STR$FREE1_DX
	MOVL	#16,DESCR2(R9)		; build local symbol text in scratch buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	INCL	CASE_NUM		; using a unique symbol each time,
	PUSHL	CASE_NUM
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	LCLSYM_S
	CALLS	#4,G^SYS$FAO
	PUSHAQ	DESCR2(R9)		; append symbol text to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#16,DESCR2(R9)		; rebuild descriptor,
	PUSHL	CASE_NUM		; build suffixing text,
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	LCLSYM2_S
	CALLS	#4,G^SYS$FAO
41$:	CLRL	R7			; set up loop index,
42$:	PUSHAB	SCR(R9)			; get displacement word,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_WORD
	MOVL	(R10),CURR_ADR		; save current address for output,
	ADDL2	#2,(R10)		; step to next byte,
	CVTWL	SCR(R9),R5		; sign-extend result,
	ADDL2	R4,R5			; add base address to this displacement,
	BLBS	@8(AP),50$		; select pass # code.
	CLRQ	-(SP)
	PUSHL	#<1@<SYM_JMPE-1>>	; pass 1: add entry to symbol table
	PUSHL	R5			; as a jump entry point,
	CALLS	#4,G^WRITE_SYM_TBL
	BRB	60$
50$:	PUSHAQ	WORD_S			; append '.WORD' to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	PUSHL	R5
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^EXTRACT_SYM_TBL
	PUSHAQ	DESCR2(R9)		; append suffix text to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	PUSHAQ	DESCR(R9)		; write line to output file,
	CALLS	#1,G^WRITE_OUTPUT_TEXT
	PUSHAQ	DESCR(R9)		; deallocate string,
	CALLS	#1,G^STR$FREE1_DX
60$:	ACBL	R2,#1,R7,42$		; loop around until all choices done,
	BRW	END_INSTR_1		; then exit.
;
NOT_TBL:
	PUSHAB	SCR(R9)			; set up call,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE		; fetch a new byte from record buffer,
	INCL	(R10)			; update "address",
	MOVZBL	SCR(R9),R0		; get byte from stack,
	CMPZV	#6,#2,R0,#0		; check for short immediate operand,
	BNEQ	NOT_SHORT_IMM		; no, try other modes.
	EXTZV	#0,#6,R0,R1		; yes, get short immediate value,
	MOVZBL	R1,CASEVEC(R9)		; store it,
	BRW	BUILD_OPREF		; then handle it.
;
NOT_SHORT_IMM:
	EXTZV	#0,#4,R0,R1		; extract and save register,
	EXTZV	#4,#4,R0,R0		; select appropriate addressing mode
	CASEL	R0,#4,#11		; handler,
1$:	.WORD	A_IDXD - 1$
	.WORD	A_REG - 1$
	.WORD	A_REG_DEF - 1$
	.WORD	A_AUTODEC - 1$
	.WORD	A_AUTOINC - 1$
	.WORD	A_AUTOINC_DEF - 1$
	.WORD	A_BYTE - 1$
	.WORD	A_BYTE_DEF - 1$
	.WORD	A_WORD - 1$
	.WORD	A_WORD_DEF - 1$
	.WORD	A_LONG - 1$
	.WORD	A_LONG_DEF - 1$
;
A_IDXD:	MOVB	R1,INDEX(R9)		; save index register,
	BRW	NOT_RELVEC_2		; get rest of operand.
;
A_REG:	BISB3	#^X10,R1,BASEREG(R9)	; save register,
	BRW	BUILD_OPREF		; build operand text.
;
A_REG_DEF:
	BISB3	#^X20,R1,BASEREG(R9)	; mark register as deferred,
	BRW	BUILD_OPREF
;
A_AUTODEC:
	BISB3	#^X40,R1,BASEREG(R9)	; mark register as autodecrement,
	BRW	BUILD_OPREF
;
A_AUTOINC:
	BISB3	#^X60,R1,BASEREG(R9)	; mark reg. as autoincrement,
	BRW	BUILD_OPREF
;
A_AUTOINC_DEF:
	BISB3	#^X70,R1,BASEREG(R9)	; mark reg. as autoincrement deferred,
	BRW	BUILD_OPREF
;
A_BYTE:	BISB3	#^XA0,R1,BASEREG(R9)	; mark as byte,
B_BYTE:	PUSHAB	SCR(R9)			; get a new byte from file,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE
	INCL	(R10)			; increment pointer,
	CVTBL	SCR(R9),SCR(R9)		; sign-extend byte,
	BRB	BUILD_OPREF
;
A_BYTE_DEF:
	BISB3	#^XB0,R1,BASEREG(R9)	; mark as byte deferred,
	BRB	B_BYTE			; let previous code finish it.
;
A_WORD:	BISB3	#^XC0,R1,BASEREG(R9)	; mark as word,
B_WORD:	PUSHAW	SCR(R9)			; get new word from file,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_WORD
	ADDL2	#2,(R10)
	CVTWL	SCR(R9),SCR(R9)		; sign-extend word,
	BRB	BUILD_OPREF
;
A_WORD_DEF:
	BISB3	#^XD0,R1,BASEREG(R9)	; mark reg. as word deferred,
	BRB	B_WORD
;
A_LONG:	BISB3	#^XE0,R1,BASEREG(R9)	; mark as longword,
B_LONG:	PUSHAL	SCR(R9)			; get new longword,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_LONG
	ADDL2	#4,(R10)
	BRB	BUILD_OPREF
;
A_LONG_DEF:
	BISB3	#^XF0,R1,BASEREG(R9)	; mark as longword deferred,
	BRB	B_LONG
;
BUILD_OPREF:
	BLBC	@8(AP),100$
	BRW	BUILD_P2		; if pass 2, build text.
100$:	TSTB	BASEREG(R9)		; if pass 1, check operand mode,
	BNEQ	10$			; modified, analyze it.
	CLRQ	-(SP)			; add dummy arguments to stack,
	ADDL3	(R10),OFFSET(R9),R0	; add displacement to current address,
	BITB	#SUBR_CALL,6(R3)	; test if a subroutine call,
	BNEQ	1$			; yes, skip next instruction.
	PUSHL	#<1@<SYM_JMPE-1>>
	BRB	2$
1$:	PUSHL	#<1@<SYM_SUBR-1>>
2$:	PUSHL	R0			; push symbol value,
	CALLS	#4,G^WRITE_SYM_TBL	; write entry to symbol table,
	BRW	NEXT_OPRND		; go for next operand.
10$:	MOVB	BASEREG(R9),R0		; get register number,
	CMPB	R0,#^X10		; test if any register used,
	BLSSU	8$			; no, do nothing (short immediate).
	BICL2	#^XFFFFFFF0,R0		; clean out extraneous stuff,
	CMPB	R0,#15			; is the register the PC?
	BEQL	9$			; yes, analyze it.
8$:	BRW	NEXT_OPRND		; no, no more pass 1 work.
9$:	EXTZV	#4,#4,BASEREG(R9),R0	; extract the mode code,
	CASEL	R0,#6,#9		; vecter to appropriate handler.
11$:	.WORD	C_IMMED - 11$
	.WORD	C_ABS - 11$
	.WORD	0,0			; unused codes
	.WORD	C_DISP - 11$
	.WORD	C_DDISP - 11$
	.WORD	C_DISP - 11$
	.WORD	C_DDISP - 11$
	.WORD	C_DISP - 11$
	.WORD	C_DDISP - 11$
;
C_IMMED:
	MOVZBL	6(R3)[R6],R0		; get operand type byte again,
	BICB2	#^XF0,R0
	MOVZBL	OP_SIZ-1-DATA_STRUC_BASE(R11)[R0],R2
					; get size of operand,
	CMPB	R2,#^XFF		; test for invalid value,
	BNEQ	1$			; OK, handle it.
	PUSHL	(R10)			; not OK, signal it.
	PUSHL	#1
	PUSHL	#DISM__INVIMMTYP
	CALLS	#3,G^LIB$SIGNAL
	MOVL	#DISM__INVIMMTYP,R0	; exit prematurely as end instruction.
	RET
1$:	CLRL	R4			; initialize loop index,
	CLRQ	SCR(R9)			; clear scratch buffer,
2$:	PUSHAB	SCR(R9)[R4]		; get the next byte in the instruction,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_BYTE
	INCL	(R10)			; update the address,
	AOBLSS	R2,R4,2$		; go again until all bytes found,
	MOVL	SCR(R9),CASEVEC(R9)	; save immediate value in case this
					; is a CASEx instruction,
	BRW	NEXT_OPRND		; go to next operand.
;
C_ABS:	PUSHAL	SCR(R9)			; get longword from file,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_LONG
	ADDL2	#4,(R10)
ALL_EVAL:
	CLRQ	-(SP)			; push dummy arguments,
	MOVZBL	6(R3)[R6],R0		; get operand type byte again,
	BITB	#COD_REF,R0		; test if code reference,
	BEQL	23$			; no, goto data processing.
	CMPZV	#5,#1,6(R3),#1		; yes, test if subroutine call,
	BEQL	21$			; yes, skip to call processing.
	PUSHL	#<1@<SYM_JMPE-1>>	; no, treat as jump entry.
	BRB	PUSH_ALL_EVAL
21$:	BITB	#PROC_VEC,R0		; test if procedure call,
	BEQL	22$			; no, subroutine jump.
	PUSHL	#<1@<SYM_PROC-1>>	; yes, procedure call.
	BRB	PUSH_ALL_EVAL
22$:	PUSHL	#<1@<SYM_SUBR-1>>
	BRB	PUSH_ALL_EVAL
23$:	EXTZV	#0,#4,R0,R0		; extract type code,
DO_TYP_CODE:
	CMPB	R0,#ISD_TBL		; test if table type,
	BNEQ	35$			; no, use as is.
1$:	MOVAB	TBL_TYPES-DATA_STRUC_BASE(R11),R1
					; yes, get address of table type table,
10$:	TSTW	(R1)			; check if end of table,
	BEQL	20$			; yes, report error.
	CMPW	(R1),OPCODE(R9)		; no, compare opcode against table,
	BEQL	30$			; match, process it.
	MOVAB	5(R1),R1		; no match, skip to next entry.
	BRB	10$
20$:	PUSHL	#DISM__CORDTSTRUC	; report fatal "data structures
	CALLS	#1,G^LIB$SIGNAL		; corrupted" error.
	RET
30$:	ASHL	2(R1),#^B100,R0		; get table type entry,
	BISL2	#<^B100@ISD_TBL>,R0	; make a composite mask with TBL bitmask,
	CMPW	3(R1),#-4		; test if argument list type,
	BNEQ	40$			; no, finish normal processing.
	MOVL	SCR(R9),SAVOPR(R9)	; yes, save operand address,
	CLRL	SCR(R9)			; clear it from the scratch buffer,
	BICL2	#<^B100@ISD_TBL>,R0	; clear the table type bit,
	BISL3	#^X00080000,R0,SAVOPR+4(R9) ; save mask longword w/extended bit,
	BRW	NEXT_OPRND		; go to next operand.
35$:	ASHL	R0,#^B100,R0		; shift value into field position,
40$:	PUSHL	R0			; push composite data type code,
PUSH_ALL_EVAL:
	PUSHL	SCR(R9)			; push symbol value,
	CALLS	#4,G^WRITE_SYM_TBL	; write entry to symbol table,
	TSTL	SAVOPR(R9)		; test if any auxiliary data saved,
	BEQL	50$			; skip if not,
	PUSHL	SCR(R9)			; push this symbol's value,
	PUSHL	#18			; assume this is an arglist type,
	MOVQ	SAVOPR(R9),-(SP)	; push mask and value of previous symbol,
	CALLS	#4,G^WRITE_SYM_TBL	; write other entry to symbol table,
50$:	CLRQ	SAVOPR(R9)		; clear context from save area,
	BRW	NEXT_OPRND		; go to next operand.
;
C_DISP:	ADDL2	(R10),SCR(R9)		; add (sign-extended) displacement to
					; current location,
	BRW	ALL_EVAL		; handle storing of symbol.
;
C_DDISP:
	ADDL2	(R10),SCR(R9)		; add (sign-extended) displacement to
					; current location,
	CLRQ	-(SP)			; push dummy arguments,
	PUSHL	#<4@ISD_LNG>		; specify longword data type,
	BRB	PUSH_ALL_EVAL		; store that type symbol.
;
BUILD_P2:
	TSTB	BASEREG(R9)		; test operand type,
	BNEQ	10$			; modified, use elaborate addressing modes,
	ADDL3	(R10),OFFSET(R9),R0	; unmodified, add displacement to current address,
	PUSHL	R0			; push address,
	PUSHAQ	DESCR(R9)		; push dynamic descriptor address,
	CALLS	#2,G^EXTRACT_SYM_TBL	; append symbol name to line,
	BRW	NEXT_OPRND		; continue to next operand.
10$:	MOVZBL	BASEREG(R9),R0		; select register number,
	CMPB	R0,#^X10		; test if any register,
	BGEQU	20$			; yes, analyze addressing mode,
	PUSHAQ	B^SIMMX_S-DATA_STRUC_BASE(R11)
					; no, append short immediate text,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#16,DESCR2(R9)		; make descriptor of scratch buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	MOVZBL	CASEVEC(R9),-(SP)	; push value on stack,
	PUSHAQ	DESCR2(R9)		; push buffer descriptor,
	PUSHAW	DESCR2(R9)		; push length field address,
	PUSHAQ	B^BDEC_S-DATA_STRUC_BASE(R11)
					; push format string,
	CALLS	#4,G^SYS$FAO		; call system service,
	PUSHAQ	DESCR2(R9)		; append result to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	NEXT_OPRND		; continue to next operand.
20$:	BICL3	#^XFFFFFFF0,R0,R1	; check if PC is register in operand,
	CMPL	#15,R1
	BEQL	21$			; yes, handle it.
	BRW	DO_REG_ADR		; no, treat as ordinary register.
21$:	EXTZV	#4,#4,R0,R1		; extract internal addressing mode code,
	CASEL	R1,#6,#9		; vector to handler.
22$:	.WORD	D_IMMED - 22$
	.WORD	D_ABS - 22$
	.WORD	23$ - 22$, 23$ - 22$
	.WORD	D_DISP - 22$
	.WORD	D_DISP - 22$
	.WORD	D_DISP - 22$
	.WORD	D_DISP - 22$
	.WORD	D_DISP - 22$
	.WORD	D_DISP - 22$
;
23$:	PUSHL	(R10)			; push location,
	PUSHL	#1
	PUSHL	#DISM__INVADRMOD	; report error,
	CALLS	#3,G^LIB$SIGNAL
	BRW	NEXT_OPRND		; continue with next operand.
;
D_IMMED:
	PUSHAQ	B^IMM_S-DATA_STRUC_BASE(R11)
					; append immediate addressing text,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVZBL	6(R3)[R6],R0		; get operand size again,
	BICB2	#^XF0,R0
	MOVZBL	OP_SIZ-1-DATA_STRUC_BASE(R11)[R0],R0
					; get operand size,
	CMPB	#-1,R0			; test if minus one (invalid),
	BNEQ	1$			; no, skip.
	PUSHL	(R10)			; yes, report error.
	PUSHL	#1
	PUSHL	#DISM__INVIMMTP2
	CALLS	#3,G^LIB$SIGNAL
1$:	PUSHL	R0			; save length value,
	MOVAB	TXTBUF(R9),R4		; get buffer address,
	MOVL	R0,R5			; get byte count,
	CLRL	R2			; initialize index,
	CLRQ	SCR(R9)			; clear scratch buffer,
3$:	PUSHAB	SCR(R9)[R2]		; push buffer address,
	PUSHAL	(R10)			; push address,
	CALLS	#2,COPY_BYTE		; get a byte,
	INCL	(R10)			; update address,
	AOBLSS	R5,R2,3$		; loop around again,
	MOVL	SCR(R9),CASEVEC(R9)	; save value if CASEx instruction,
	MOVZBL	6(R3)[R6],R1		; get operand type,
	BICL2	#^XFFFFFFF0,R1
	CMPL	R1,#ISD_FLT		; test if floating point type,
	BLSS	10$			; no, too small.
	CMPL	R1,#ISD_HFL
	BGTR	10$			; no, too large.
	BRW	100$			; yes, unscramble it to text.
10$:	PUSHAQ	X_STR			; append hex mark,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#32,DESCR2(R9)		; build output descriptor,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	MOVL	(SP)+,R0		; restore length value,
	CLRL	R1			; initialize loop counter,
11$:	MOVZBL	SCR(R9)[R1],-(SP)	; push byte on stack,
	AOBLSS	R0,R1,11$		; loop until done,
	PUSHL	R0			; push count,
	PUSHAQ	DESCR2(R9)		; push output descriptor,
	PUSHAW	DESCR2(R9)		; push length word,
	PUSHAQ	HEXB_S			; push control string,
	ADDL2	#4,R0			; calculate parameter count,
	CALLS	R0,G^SYS$FAO		; format output,
	PUSHAQ	DESCR2(R9)		; append this to output line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	NEXT_OPRND		; finish operand.
100$:	POPR	#^M<R0>			; clean stack,
	PUSHR	#^M<R1,R3>		; preserve R1,
	PUSHAQ	F_STR			; append the ^F mark,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVC5	#0,(SP),#^A/ /,#40,TXTBUF(R9) ; clear output string buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)	; build output descriptor,
	POPR	#^M<R1,R3>		; restore operand type,
	CASEB	R1,#ISD_FLT,#4		; select the appropriate float format,
101$:	.WORD	102$ - 101$		; F_floating
	.WORD	103$ - 101$		; D_floating
	.WORD	104$ - 101$		; G_floating
	.WORD	105$ - 101$		; H_floating
102$:	MOVL	#13,DESCR2(R9)		; specify length of string,
	CVTFD	SCR(R9),SCR(R9)		; get value in D_floating form,
	PUSHL	#7			; push fraction count,
	PUSHAQ	DESCR2(R9)		; push string descriptor address,
	PUSHAB	SCR(R9)			; push value address,
	CALLS	#3,G^FOR$CVT_D_TG	; convert to ASCII,
	BRB	106$			; finish floating point processing.
103$:	MOVL	#24,DESCR2(R9)		; specify length of string,
	PUSHL	#17			; push fraction count,
	PUSHAQ	DESCR2(R9)		; push string descriptor address,
	PUSHAB	SCR(R9)			; push value address,
	CALLS	#3,G^FOR$CVT_D_TG	; convert to ASCII,
	BRB	106$			; finish floating point processing.
104$:	MOVL	#23,DESCR2(R9)		; specify length of string,
	PUSHL	#16			; push fraction count,
	PUSHAQ	DESCR2(R9)		; push string descriptor address,
	PUSHAB	SCR(R9)			; push value address,
	CALLS	#3,G^FOR$CVT_G_TG	; convert to ASCII,
	BRB	106$			; finish floating point processing.
105$:	MOVL	#40,DESCR2(R9)		; specify length of string,
	PUSHL	#33			; push fraction count,
	PUSHAQ	DESCR2(R9)		; push string descriptor address,
	PUSHAB	SCR(R9)			; push value address,
	CALLS	#3,G^FOR$CVT_H_TG	; convert to ASCII,
106$:	PUSHAW	LENSTR(R9)		; get the actual length of the string,
	PUSHAQ	DESCR2(R9)
	PUSHAQ	DESCR2(R9)
	CALLS	#3,G^STR$TRIM
	MOVW	LENSTR(R9),DESCR2(R9)	; set the length,
	PUSHAQ	DESCR2(R9)		; append format string to text line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	NEXT_OPRND
;
D_ABS:	PUSHAL	SCR(R9)			; get longword from file,
	PUSHAL	(R10)
	CALLS	#2,G^COPY_LONG
	ADDL2	#4,(R10)
	PUSHAQ	B^ABS_S-DATA_STRUC_BASE(R11)
					; append absolute addressing text,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
SYMBOL_EVAL:
	PUSHL	SCR(R9)			; push symbol value,
	PUSHAQ	DESCR(R9)		; push descriptor of line,
	CALLS	#2,G^EXTRACT_SYM_TBL	; read symbol name from symbol table,
	BRW	END_P2			; go to next operand.
;
D_DISP:	ADDL2	(R10),SCR(R9)		; add current address to displacement,
	CMPL	R1,#15			; test if longword-displaced deferred,
	BNEQ	10$			; no, skip special processing.
	PUSHR	#^M<R1>			; preserve R1,
	PUSHL	SCR(R9)			; yes, get symbol type field,
	CALLS	#1,G^GET_SYMBOL_TYPE
	POPR	#^M<R1>			; restore R1,
	BITL	#SYM_G_FIXUP,R0		; test if fixup section flag set,
	BEQL	10$			; no, process normally.
	PUSHAQ	GEN_S			; yes, use general addressing mark,
	PUSHAQ	DESCR(R9)		; prefixed to symbol name.
	CALLS	#2,G^STR$APPEND
	BRB	SYMBOL_EVAL		; finish like normal addressing.
10$:	MOVAW	DISPL_TBL-DATA_STRUC_BASE(R11),R4
					; get address of text descriptor table,
	SUBL2	#^XA,R1			; calculate offset in table,
	CVTWL	(R4)[R1],R1		; get base-relative offset from table,
	ADDL2	R1,R4			; calculate address of descriptor,
	PUSHAQ	(R4)			; push address,
	PUSHAQ	DESCR(R9)		; push address of line,
	CALLS	#2,G^STR$APPEND		; append text,
	BRB	SYMBOL_EVAL		; now evaluate.
;
DO_REG_ADR:
	BITB	#COD_REF,6(R3)[R6]	; test if operand is code type,
	BEQL	0$			; no, skip error report.
	PUSHL	(R10)			; yes, store current address,
	PUSHL	#1
	PUSHL	#DISM__INDCALJSB	; report funny CALL/JMP/JSB mode,
	CALLS	#3,G^LIB$SIGNAL
0$:	EXTZV	#4,#4,R0,R1		; extract addressing mode code,
	EXTZV	#0,#4,R0,R2		; extract register number,
	CASEL	R1,#1,#14		; branch to appropriate handler.
1$:	.WORD	E_REG - 1$
	.WORD	E_REG_D - 1$
	.WORD	0
	.WORD	E_ADEC - 1$
	.WORD	0
	.WORD	E_AINC - 1$
	.WORD	E_AINC_D - 1$
	.WORD	0,0
	.WORD	E_BYT - 1$
	.WORD	E_BYT_D - 1$
	.WORD	E_WRD - 1$
	.WORD	E_WRD_D - 1$
	.WORD	E_LNG - 1$
	.WORD	E_LNG_D - 1$
;
E_REG:	BSBW	PRNT_REG		; add register name,
	BRW	NEXT_OPRND		; do next operand.
;
E_REG_D:
	PUSHAQ	L_PAREN			; add left parenthesis,
E_RPAR:	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BSBW	PRNT_REG		; add register name,
	PUSHAQ	R_PAREN			; add right parenthesis,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	END_P2			; do indexing.
;
E_ADEC:	PUSHAQ	LM_PAREN		; add '-(',
	BRB	E_RPAR			; finish like E_REG_D.
;
E_AINC:	PUSHAQ	L_PAREN			; add '(',
E_RPARPL:
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BSBW	PRNT_REG		; add register name,
	PUSHAQ	RP_PAREN		; add ')+',
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	END_P2			; do indexing.
;
E_AINC_D:
	PUSHAQ	LAT_PAREN		; add '@(',
	BRB	E_RPARPL		; finish like E_AINC.
;
E_BYT:	PUSHAQ	BYT_STR-DATA_STRUC_BASE(R11)
					; append mode identifier,
E_BYTS:	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#16,DESCR2(R9)		; build descriptor of buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	PUSHL	SCR(R9)			; build text of displacement,
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	BSDEC_S
	CALLS	#4,G^SYS$FAO
	PUSHAQ	DESCR2(R9)		; add test to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	E_REG_D			; use deferred reg. to finish.
;
E_BYT_D:
	PUSHAQ	BYT_DEF_STR-DATA_STRUC_BASE(R11)
	BRB	E_BYTS
;
E_WRD:	PUSHAQ	WRD_STR-DATA_STRUC_BASE(R11)
					; append mode identifier,
E_WRDS:	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#16,DESCR2(R9)		; build descriptor of buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	PUSHL	SCR(R9)			; build text of displacement,
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	WSDEC_S
	CALLS	#4,G^SYS$FAO
	PUSHAQ	DESCR2(R9)		; add test to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	E_REG_D			; use deferred reg. to finish.
;
E_WRD_D:
	PUSHAQ	WRD_DEF_STR-DATA_STRUC_BASE(R11)
	BRB	E_WRDS
;
E_LNG:	PUSHAQ	LNG_STR-DATA_STRUC_BASE(R11)
					; append mode identifier,
E_LNGS:	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	MOVL	#16,DESCR2(R9)		; build descriptor of buffer,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	PUSHL	SCR(R9)			; build text of displacement,
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	LSDEC_S
	CALLS	#4,G^SYS$FAO
	PUSHAQ	DESCR2(R9)		; add test to line,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	E_REG_D			; use deferred reg. to finish.
;
E_LNG_D:
	PUSHAQ	LNG_DEF_STR-DATA_STRUC_BASE(R11)
	BRB	E_LNGS
;
END_P2:	CMPB	INDEX(R9),#^XFF		; was an index value written?
	BEQL	NEXT_OPRND		; no, skip.
	MOVZBL	INDEX(R9),R2		; yes, get index register number,
	PUSHAQ	L_BRACKET		; add bracket to text,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BSBW	PRNT_REG		; add register name,
	PUSHAQ	R_BRACKET		; add closing bracket,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND		; fall into end-of-operand code.
;
NEXT_OPRND:
	EXTZV	#0,#3,6(R3),R0		; get operand count again,
	ACBL	R0,#1,R6,10$		; test if the loop is done,
	BRB	END_INSTR		; done, exit.
10$:	BLBC	@8(AP),11$		; not done, check if pass 2.
	PUSHAQ	B^COMMA_S-DATA_STRUC_BASE(R11)
					; pass 2, append a comma after last operandd,
	PUSHAQ	DESCR(R9)
	CALLS	#2,G^STR$APPEND
	BRW	OPRND_LP		; now process next operand.
11$:	TSTL	SAVOPR(R9)		; test if saved auxiliary data unused,
	BEQL	12$			; skip if not,
	PUSHL	SCR(R9)			; push this symbol's value,
	PUSHL	#18			; assume this is an arglist type,
	MOVQ	SAVOPR(R9),-(SP)	; push mask and value of previous symbol,
	CALLS	#4,G^WRITE_SYM_TBL	; write other entry to symbol table,
12$:	BRW	OPRND_LP		; now process next operand.
;
END_INSTR:
	BLBC	@8(AP),END_INSTR_P1	; if pass 1, skip.
	MOVB	6(R3),R0		; pass 2, get opcode type,
	CMPB	R0,#INV_OPC		; was opcode undefined?
	BEQL	5$			; yes, don't write this text.
	PUSHAQ	DESCR(R9)		; no, write output text,
	CALLS	#1,G^WRITE_OUTPUT_TEXT
5$:	PUSHAQ	DESCR(R9)		; deallocate dynamic string,
	CALLS	#1,G^STR$FREE1_DX
	MOVB	6(R3),R0		; get opcode type again,
	CMPB	R0,#INV_OPC		; was opcode undefined?
	BNEQ	END_INSTR_1		; no, continue normally.
	MOVL	#40,DESCR(R9)		; yes, create a string descriptor,
	MOVAB	TXTBUF(R9),DESCR+4(R9)
	PUSHL	OPCODE(R9)		; push value of opcode,
	PUSHAQ	DESCR(R9)		; push descriptor of output buffer,
	PUSHAW	DESCR(R9)		; push descriptor of output length,
	CMPW	OPCODE(R9),#255		; test if two-byte opcode,
	BLEQU	7$			; no, handle as a byte.
	PUSHAQ	B^XWORD_S-DATA_STRUC_BASE(R11)
					; yes, copy .WORD to line,
	BRB	10$
7$:	PUSHAQ	B^XBYTE_S-DATA_STRUC_BASE(R11)
					; copy .BYTE to line,
10$:	CALLS	#4,G^SYS$FAO		; format output text,
	PUSHAQ	DESCR(R9)		; write output text,
	CALLS	#1,G^WRITE_OUTPUT_TEXT
	BRB	END_INSTR_1
END_INSTR_P1:
	CMPB	OPCODE(R9),#^XFB	; was this instruction a CALLS?
	BNEQ	END_INSTR_1		; no, skip special processing.
	BSBW	ANALYZE_CALLS_STK	; yes, try to derive CALLS stack.
END_INSTR_1:
	MOVB	6(R3),R0		; get opcode type,
	CMPB	R0,#INV_OPC		; was opcode undefined?
	BNEQ	2$			; no, skip.
	MOVL	#DISM__INVOPCODE,R0	; yes, report error.
	BRB	99$
2$:	BITB	R0,#UCOND_TRN		; was opcode an unconditional transfer?
	BEQL	3$			; no, skip.
	CLRL	R0			; yes, return zero.
	BRB	99$
3$:	MOVL	#1,R0			; return success.
99$:	RET				; exit.
;
	.PAGE
	.SBTTL	Register Mode Punctuation Strings
;
;  these are data strings used used in formatting operand specifications
;
L_BRACKET:	.ASCID	/[/
R_BRACKET:	.ASCID	/]/
L_PAREN:	.ASCID	/(/
R_PAREN:	.ASCID	/)/
RP_PAREN:	.ASCID	/)+/
LM_PAREN:	.ASCID	/-(/
LAT_PAREN:	.ASCID	/@(/
BSDEC_S:	.ASCID	/!SB/
WSDEC_S:	.ASCID	/!SW/
LSDEC_S:	.ASCID	/!SL/
X_STR:		.ASCID	/^X/
F_STR:		.ASCID	/^F/
HEXB_S:		.ASCID	/!#(XB)/
;
;  format strings for CASEx instructions
;
LCLSYM_S:	.ASCID	/!UL$:/
WORD_S:		.ASCID	<TAB>/.WORD/<TAB>
LCLSYM2_S:	.ASCID	/ - !UL$/
;
	.SBTTL	Register Name Text Generator
;
;  This subroutine converts a general register number into a text string
;    appended to the text line. The registers AP, FP, SP, and PC are returned
;    by these names rather than R12 through R15. The register number is
;    passed in R2.
;
REG_FMT_STR:
	.ASCID	/R!UL/
REG_NAM_LST:
1$:	.WORD	NAM_AP - 1$
	.WORD	NAM_FP - 1$
	.WORD	NAM_SP - 1$
	.WORD	NAM_PC - 1$
NAM_AP:	.ASCID	/AP/
NAM_FP:	.ASCID	/FP/
NAM_SP:	.ASCID	/SP/
NAM_PC:	.ASCID	/PC/
;
PRNT_REG:
	CMPL	R2,#12			; is register AP, FP, SP, or PC?
	BGEQ	10$			; yes, handle it.
	MOVL	#16,DESCR2(R9)		; no, create output descriptor,
	MOVAB	TXTBUF(R9),DESCR2+4(R9)
	PUSHL	R2			; format string of register number,
	PUSHAQ	DESCR2(R9)
	PUSHAW	DESCR2(R9)
	PUSHAQ	REG_FMT_STR
	CALLS	#4,G^SYS$FAO
	PUSHAQ	DESCR2(R9)		; store address of descriptor,
	BRB	20$			; finish somewhere else.
10$:	SUBL3	#12,R2,R0		; calculate offset in table,
	MOVAW	REG_NAM_LST,R1		; get address of table,
	CVTWL	(R1)[R0],R0
	ADDL2	R0,R1			; get address of descriptor,
	PUSHAQ	(R1)			; push descriptor address,
20$:	PUSHAQ	DESCR(R9)		; push descriptor of text line,
	CALLS	#2,G^STR$APPEND		; append register name to line,
	RSB				; exit.
;
	.PAGE
	.SBTTL	CALLS Stack Analyzer
;
;  This subroutine uses the opcode wind-back buffer to try to figure out
;    context of CALLS stack, IF the argument count is specified as a short
;    literal (and is therefore at least partially decipherable). The last
;    few instructions are decoded again to see if they are pushing anything
;    on the stack; the pseudo-symbolic stack context is built as far as it
;    can be (or is needed for the specified argument count), and anything
;    immediate, PC-relative, or absolute is used to build additional symbol
;    table entries.
;
ANALYZE_CALLS_STK:
	MOVL	ILV_PTR,R8		; get last index into buffer,
	ADDL3	#1,ILV_QUEUE[R8],SCR(R9) ; get address of CALLS opcode's
					; 1st operand,
	PUSHAB	OPCODE+1(R9)		; get the 1st operand,
	PUSHAL	SCR(R9)
	CALLS	#2,G^COPY_BYTE
	TSTB	OPCODE+1(R9)		; test if zero arguments,
	BEQL	999$			; exit if so (nothing to do).
	CMPB	OPCODE+1(R9),#63	; test if short literal addressing,
	BGTRU	999$			; exit, can't decipher this CALLS.
	
999$:	RSB				; return.

	.END
