.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 not appear, 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 ; ; 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 ; 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 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) ; 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, .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=. ; .PSECT $CODE,EXE,NOWRT,RD,LCL,SHR,PIC,CON,REL,LONG ; .ENTRY DISM_INSTR,^M ; ; 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, 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 #^XF0,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@> ; 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@> BRB 2$ 1$: PUSHL #<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@> ; 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@> ; yes, procedure call. BRB PUSH_ALL_EVAL 22$: PUSHL #<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, BEQL 40$ ; no, finish normal processing. MOVL SCR(R9),SAVOPR(R9) ; yes, save operand address, 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 ; clean stack, PUSHR #^M ; 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 ; 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 ; preserve R1, PUSHL SCR(R9) ; yes, get symbol type field, CALLS #1,G^GET_SYMBOL_TYPE POPR #^M ; 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,#4,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 11$: BRW OPRND_LP ; now process next operand. ; END_INSTR: BLBC @8(AP),END_INSTR_1 ; 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 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 /.WORD/ LCLSYM2_S: .ASCID / - !UL$/ ; .PAGE .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. ; .END