home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
norge.freeshell.org (192.94.73.8)
/
192.94.73.8.tar
/
192.94.73.8
/
pub
/
computers
/
cpm
/
alphatronic
/
DRIPAK.ZIP
/
CPM_3-0
/
SOURCES
/
PRS1ASM.ASM
< prev
next >
Wrap
Assembly Source File
|
1982-12-31
|
20KB
|
1,075 lines
; CP/M DEBUGGER DISASSEMBLER/ASSEMBLER MODULE
TITLE 'SYMBOLIC INTERACTIVE DEBUGGER (ASMOD) 12/16/77'
;
; COPYRIGHT (C) 1976, 1977
; DIGITAL RESEARCH
; BOX 579 PACIFIC GROVE, CA
; 93950
;
FALSE EQU 0 ;VALUE OF "FALSE"
TRUE EQU NOT FALSE ;VALUE OF "TRUE"
ISIS2 EQU FALSE ;TRUE IF ASSEMBLING FOR "IS"
DEBUG EQU FALSE ;TRUE IF CHECK-OUT TIME
RELOC EQU TRUE ;TRUE IF GENERATING RELOC IMAGE
;
IF DEBUG
ORG 1000H ;IN LOW MEMORY FOR DEBUG
ELSE
IF ISIS2
ORG 0E500H
ELSE
IF RELOC
ORG 0000H ;READY FOR RELOCATION
ELSE
ORG 0D000H ;DEBUG IN 64K
ENDIF
ENDIF
ENDIF
;
JLOC1 EQU 0005H ;BDOS JUMP LOCATION
;
;
; ENTRY POINTS FOR DEBUGGING MONITOR
DEMON EQU $+680H
BEGIN EQU DEMON+03H ;BEGINNING OF DEBUGGING MONITOR
GETBUFF EQU DEMON+9H ;READ BUFFER
GNC EQU DEMON+0CH
PCHAR EQU DEMON+0FH ;PRINT CHARACTER IN REG A
PBYTE EQU DEMON+12H ;PRINT BYTE
PADDX EQU DEMON+15H ;PRINT ADDRESS IN REG D,E
SCANEXP EQU DEMON+18H ;SCAN 0,1, OR 2 EXPRESSIONS
BREAK EQU DEMON+1EH ;CHECK FOR BREAK AT CONSOLE
PRLABEL EQU DEMON+21H ;PRINT SYMBOLIC LABEL
;
;
CI EQU GNC ;SYNONYM FOR GNC
;
CR EQU 0DH
LF EQU 0AH
TAB EQU 09H
;
MODLOC: ;MODULE LOCATION
JMP BEGIN ;ADDRESS FIELD IS ALTERED AT "BEGIN"
DB 0,0,0 ;FILLER (USED IN SYMBOL TABLE)
JMP DISENT
JMP ASMEN ;ENTRY POINT FOR ASSEMBLER
PC: DS 2 ;CURRENT FAKED PC DURING DISASSEMBLY
MPC: DS 2 ;MAX VALUE FOR PC (STOP ADDRESS)
PAGM: DS 1 ;PAGE MODE IF NON ZERO
TPC: DS 2 ;TEMPORARY PC FOR ASSEMBLER RESTORE ON ERROR
OLDSP: DS 2 ;ENTRY SP VALUE
;
;
CO: ;PRINT CHARACTER IN REGISTER C
PUSH PSW
MOV A,C ;PCHAR EXPECTS VALUE IN C
CALL PCHAR ;TO PRINT THE CHARACTER
POP PSW
RET
;
;
DELIM: ;CHECK FOR DELIMITER
CPI ' '
RZ
CPI TAB
RZ
CPI ','
RZ
CPI CR
RZ
CPI 7FH
JZ ASMEN ;RESTART CURRENT LINE
RET
;
CRLF: ;RETURN AND LINE FEED
MVI C,CR
CALL CO
MVI C,LF
CALL CO
RET
;
SCAN: ;FILL OPCODE WITH CHARACTERS
;
SC1: CALL CI
SCAN0: ;ENTER HERE IF CHARACTER SCANNED
CPI CR
JZ ERR
CALL DELIM
JZ SC1
;
; CLEAR BUFFER
MVI C,4
LXI H,OPCODE
SC0: MVI M,' '
INX H
DCR C
JNZ SC0
;
; GARBAGE REMOVED AT BEGINNING OF SCAN
MVI C,5
LXI H,OPCODE
SC2: MOV M,A ;STORE CHARACTER
CALL CI
CALL DELIM
JZ SC3
INX H
DCR C
JZ ERR ;TOO LONG
JMP SC2
;
SC3: ;END OF CURRENT SCAN, COMPARE FOR EMPTY
LDA OPCODE
CPI ' '
RET
;
HEX: ;CONVERT ACCUMULATOR TO HEXADECIMAL
SUI '0'
CPI 10
RC ;'0' - '9'
ADI ('0'-'A'+10) AND 0FFH
CPI 16
RC
JMP ERR
;
GADDR: ;GET ADDRESS VALUE TO B (HIGH ORDER) AND C (LOW) WITH COPY OF C IN A
CALL SCANEXP ;READ 1 EXPRESSION
DCR A ;GOES TO ZERO
JNZ ERR ;? IF NOT A SINGLE EXPRESSION
XCHG ;ADDRESS OF EXPRESSION TO HL
MOV C,M ;LOW BYTE
INX H
MOV B,M ;HIGH BYTE
MOV A,C ;COPY OF LOW BYTE TO A
DCR B
INR B ;SETS ZERO FLAG IF B IS ZERO
RET
;
GBYTE: ;GET BYTE VALUE TO ACCUMULATOR AND C, CHECK FOR HIGH ORDER ZERO
CALL GADDR
JNZ ERR
RET
;
;
; ************************************************************
; ********* ASSEMBLER MODULE STARTS HERE *********************
; ************************************************************
;
ADJ: ;MOVE REGISTER INDICATOR TO MIDDLE FIELD OF CODE
RAL
RAL
RAL
ANI 111000B
RET
;
ADJ4: ;MOVE TO LEFT BY 4 AND MASK
RAL
RAL
RAL
RAL
ANI 110000B
RET
;
SEAR2: ;SAME AS SEAR, EXCEPT 2 CHARACTER MATCH
; H,L ADDRESS TABLE TO MATCH ON
XCHG
LHLD OPCODE ;2ND BYTE IN D, 1ST BYTE IN E
XCHG ;H,L ADDRESS TABLE
SEA0: MOV A,E ;GET 1ST BYTE
CMP M ;MATCH?
JNZ SEA1 ;TO ADDRESS NEXT ELT
INX H ;NEXT TO MATCH
MOV A,D ;2ND CHAR
CMP M
RZ ;MATCH AT CURRENT ENTRY
DCX H
SEA1: DCX H
DCX H ;ADDRESSES NEXT ELEMENT
DCR C
JNZ SEA0 ;FOR ANOTHER COMPARE
;
; NO MATCH IN TABLE, RETURN WITH NON-ZERO VALUE
DCR C
RET
;
;
SEAR: ;SEARCH FOR MATCH IN OPCODE TABLE, LENGTH OF TABLE IN REG-C
; D,E CONTAINS ADDRESS OF BINARY EQUIVALENT OF OPCODE
; H,L ADDRESS FOUR CHARACTER OPCODE TO MATCH
; OPCODE CONTAINS FOUR BYTE OPCODE TYPED AT CONSOLE
; RETURNS WITH ZERO VALUE IF OPCOE FOUND, WITH D,E
; ADDRESSING PROPER BYTE, NON-ZERO IF NOT FOUND.
MVI B,4 ;4 CHARACTER MATCH
;
PUSH D ;SAVE THE CURRENT BYTE VALUE LOCATION
LXI D,OPCODE ;ADDRESS CHARACTERS TYPED
SE1: LDAX D ;POINT TO FIRST BYTE TO MATCH
CMP M ;SAME CHARACTER AS TABLE?
JNZ SE2 ;NO, SKIP TO NXT TABLE ENTRY
INX H ;YES, LOOK AT NEXT CHARACTER
INX D ;MOVE TO NEXT CHARACTER TYPED
DCR B ;DECREMENT CHARACTER COUNT
JNZ SE1 ;MORE TO MATCH?
;
; COMPLETE MATCH, RETURN WITH D,E ADDRESSING BYTE VALUE
POP D
RET
;
; MISMATCH, FINISH COUNT
SE2: INX H
DCR B
JNZ SE2
;
; H,L AT END OF FOUR BYTE AREA, MOVE BACK 8
LXI D,-8
DAD D ;H,L READY FOR NXT MATCH
;
POP D ;RESTORE BYTE POINTER
INX D ;MOVE TO NEXT IN CASE MATCH OK
DCR C ;MORE OPCODES TO MATCH?
JNZ SEAR ;LOOK FOR MORE
;
; NO MATCH FOUND IN TABLE, SET NON-ZERO VALUE AND RETURN
DCR C
RET
;
;
GETREG: ;SCAN FOR SIMPLE REGISTER REFERENCE
PUSH B
CALL SCAN
JZ ERR
MVI C,8 ;8 REGISTERS
LXI H,SREG ;SIMPLE REGISTERS
CALL SEAR2 ;LOOK FOR 2 CHAR MATCH
JNZ ERR
DCR C
MOV A,C
POP B
RET
;
GETD: ;GET DOUBLE PRECISION REGISTER
PUSH B
CALL SCAN
JZ ERR
MVI C,5
LXI H,DREG
CALL SEAR
JNZ ERR
DCR C
MOV A,C
POP B
RET
;
GETDR: ;GET DOUBLE REGISTER (BDHSP)
CALL GETD
CPI 4 ;PSW?
JZ ERR
RET
;
GETPR: ;GET PUSH/POP REGISTER (BDH OR PSW)
CALL GETD
CPI 3
JZ ERR
CPI 4
RNZ
DCR A ;PSW MUST BE ADJUSTED
RET
;
GCON: ;GET CONDITION CODE
; BUFFER IS SCANNED, MOVE LEFT BEFORE COMPARE
LXI H,OPCODE
LXI D,OPCODE+1
MVI C,2 ;MOVE TWO CHARACTERS
MOP: LDAX D ;LOAD CHARACTER TO MOVE
MOV M,A ;MOVE LEFT
INX H ;NEXT DESTINATION
INX D ;NEXT SOURCE
DCR C
JNZ MOP
;
; MUST BE BLANK AT END
LDAX D
CPI ' '
JNZ ERR
MOV M,A
;
; NOW READY TO DO THE COMPARE
LXI H,CREG
MVI C,8
CALL SEAR2
JNZ ERR
DCR C
MOV A,C
CALL ADJ ;MOVE TO BITS 3,4,5 OF BYTE (LSB = 0)
RET
;
GCONA: ;GET CONDITION CODE TO REGISTER A, DOUBLE ADDRESS TO B,C
CALL GCON ;CONDITION CODE TO A
PUSH PSW
CALL GADDR ;VALUE TO B,C
POP PSW
; INCLUDE HIGH ORDER 11'S FOR J AND C OPCODES
ORI 11000000B
RET
;
SETMD: ;SET MEMORY AT LOCATION PC TO VALUE ADDRESSED BY D
LDAX D ;VALUE TO ACCUM
;
SETM: ;SET MEMORY AT LOCATION PC TO VALUE IN ACCUM, INC PC
LHLD TPC
MOV M,A ;STORE AT PC
INX H ;PC=PC+1
SHLD TPC
RET
;
;
;
GETOP: ;PROCESS NEXT OPCODE
CALL CI
CPI CR
JZ GOBACK ;RETURN IF SIMPLE INPUT
CPI '.' ;ALTERNATE RETURN IS .
JZ GOBACK
CALL SCAN0
JZ ERR
;
CHK0: ;CHECK FOR OPCODES WITH NO OPERANDS
MVI C,17 ;LENGTH OF GROUP-0
LXI H,ETAB1 ;END OF GROUP-0
LXI D,TABLE ;FIRST BYTE VALUE
CALL SEAR ;LOOK FOR MATCH
JNZ CHK1 ;NO MATCH, CHECK FOR GROUP-1
;
; MATCHED OPCODE, D,E ADDRESS BYTE VALUE
JMP SETMD ;SET MEMORY AT PC AND INC PC
;
; CHECK GROUP-1 VALUES
CHK1: MVI C,10 ;LENGTH OF GROUP-1
LXI H,ETAB2
CALL SEAR ;D,E REMAIN SET
JNZ CHK2 ;NO MATCH, CHECK NEXT GROUP
;
; MATCH FOUND, SET BYTE AND GET BYTE OPERAND
CALL SETMD
CALL GBYTE ;GETS BYTE VALUE TO ACCUMULATOR
JMP SETM ;PUTS BYTE VALUE TO MEMORY AT PC
;
; CHECK GROUP-2 OPCODES, REQUIRE DOUBLE BYTE OPERAND
CHK2: MVI C,6
LXI H,ETAB3
CALL SEAR
JNZ CHK3 ;NO MATCH
;
; FOUND MATCH, GET OPCODE BIT PATTERN AND STORE
CALL SETMD
OP2: ;ENTER HERE FOR DOUBLE BYTE OPERANDS
CALL GADDR ;VALUE IN B,A
CALL SETM
MOV A,B
JMP SETM
;
CHK3: ;CHECK FOR MOV INSTRUCTION
MVI C,1
LXI H,PMOV
CALL SEAR
JNZ CHK4
;
; MOV INSTRUCTION GET DESTINATION OPERAND
CALL GETREG ;VALUE TO ACCUMULATOR
CALL ADJ
MOV B,A ;SAVE IN B
MVI C,01000000B ;BIT PATTERN FOR MOV
;
OP1: ;GET NEXT OPERAND FOR MOV, FIRST OPERAND FOR ACCUM/REG OPERATOR
CALL GETREG
ORA C ;SETS HIGH ORDER TWO BITS
ORA B ;SETS DESTINATION/OPERATOR
JMP SETM
;
CHK4: ;CHECK FOR GROUP-5 (ACCUM/REG OPERATOR)
MVI C,8
LXI H,ETAB5
CALL SEAR
JNZ CHK5
;
; ACCUM/REG INSTRUCTION, C COUNTS OPERATORS AS SEARCH PROCEEDS
DCR C
MOV A,C
CALL ADJ
MOV B,A
; OPERATOR NUMBER (SHIFTED) SAVED FOR LATER MASK
MVI C,10000000B ;ACCUM/REG OPERATOR INDICATOR
JMP OP1 ;GETS OPERAND AND SAVES BYTE IN MEMORY
;
CHK5: ;MAY BE INR/DCR
MVI C,2
LXI H,PDCR
CALL SEAR
JNZ CHK6
;
; C=2 IF DCR, =1 IF INR
INR C ;+1
INR C ;+2
INR C ;+3
CALL GETREG ;VALUE TO ACCUM
CALL ADJ
ORA C ;FILL PROPER INSTRUCTION INDICATOR
JMP SETM
;
CHK6: ;MAY BE A MVI INSTRUCTION
MVI C,1
LXI H,PMVI
CALL SEAR
JNZ CHK7
;
; MVI INSTRUCTION, GET REGISTER
CALL GETREG ;VALUE GOES TO ACCUMULATOR
CALL ADJ
ORI 110B
CALL SETM
CALL GBYTE
JMP SETM
;
CHK7: ;CHECK FOR GROUP-7
MVI C,6
LXI H,ETAB7
CALL SEAR
JNZ CHK8
;
; LXI,STAX,INX,DAD,LDA, OR DCX
MOV A,C ;A=1...6
CPI 4
JC IN0
;
; MUST BE DAD,LDA, OR DCX
ADI 5 ;CHANGES ACCUM TO 9,10, OR 11
IN0: ;ACCUMULATOR CONTAINS CODE, SAVE IT
MOV B,A
CALL GETDR ;DOUBLE REGISTER VALUE TO ACCUM
CALL ADJ4 ;ADJUST VALUE TO MIDDLE FIELD
ORA B ;FILLS REMAINING BITS
CALL SETM
; MAY BE LXI
ANI 11001111B
CPI 1
RNZ ;NOT LXI
JMP OP2 ;PICK UP OPERAND
;
;
;
CHK8: ;RST?
MVI C,1
LXI H,PRST
CALL SEAR
JNZ CHK9
;
; RST, GET OPERAND
CALL GBYTE
CPI 8
JNC ERR
CALL ADJ
ORI 11000111B
JMP SETM
;
CHK9: ;POP/PUSH?
MVI C,2
LXI H,PPOP+4
CALL SEAR
JNZ CHK10
;
; C=2 IF PUSH, 1 IF POP
DCR C
JNZ PP0
;
; POP, SET BIT PATTERN
MVI C,11000001B
JMP PP1
;
PP0: ;PUSH
MVI C,11000101B
PP1: CALL GETPR ;DOUBLE PUSH/POP REGISTER TO PROPER FIELD
CALL ADJ4 ;MOVE TO FIELD
ORA C
JMP SETM
;
CHK10: ;J/C/R?
LDA OPCODE
CPI 'J'
JNZ CHK11
CALL GCONA
; CONDITION CODE TO FIELD IN ACCUM, ADDRESS TO B,C
ORI 010B
JMP FADDR ;FILL ADDRESS
;
CHK11: CPI 'C'
JNZ CHK12
CALL GCONA
ORI 100B
;
FADDR: CALL SETM
MOV A,C
CALL SETM
MOV A,B
JMP SETM
;
CHK12: CPI 'R'
JNZ ERR
CALL GCON
ORI 11000000B
JMP SETM
;
; ************************************************************
; *********** END OF ASSEMBLER MODULE, START DISASSEMBLER ****
; ************************************************************
;
RDBYTE: LHLD MPC
PUSH D ;SAVE DE
XCHG ;MAX PC TO D,E
LHLD PC ;CURRENT PC
; SUBTRACT PC FROM MPC, STOP IF CARRY GENERATED
MOV A,E
SUB L
MOV A,D
SBB H
JNC RD0
;
; PC EXCEEDS MPC, RETURN
LHLD OLDSP
SPHL ;RESTORE ORIGINAL STACK POINTER
RET
;
RD0: POP D ;RESTORE D,E
MOV A,M
INX H
SHLD PC
RET
RGPRNT: INR A
ANI 07
CPI 06
JC RGP1
ADI 03
RGP1: CPI 05
JC RGP2
ADI 02
RGP2: ADI 41H
MOV C,A
JMP CO
DECODE: MOV B,A
ANI 0F0H
RRC
RRC
RRC
RRC
ADI 90H
DAA
ACI 40H
DAA
MOV C,A
CALL CO
MOV A,B
ANI 0FH
ADI 90H
DAA
ACI 40H
DAA
MOV C,A
JMP CO
PRINT: MVI B,4
P1: MOV C,M
CALL CO
INX H
DCR B
JNZ P1
MVI C,' '
JMP CO
;
; EXTRACT THE REGISTER FIELD FROM THE OPCODE
XTRACT: MOV A,D
ANI 0011$1000B
RRC
RRC
RRC
RET
;
; PRINT CONDITION CODE
CCPRNT: CALL XTRACT
ADD A
MOV C,A
LXI H,CCODE
DAD B
MOV C,M
CALL CO
INX H
MOV C,M
CALL CO
MVI C,' '
CALL CO
JMP CO
; PRINT REGISTER REFERENCE
RPPRNT: CALL XTRACT
ANI 06
CPI 06
JNZ RGPRNT
MVI C,'S'
CALL CO
MVI C,'P'
JMP CO
;
;
PRPC: ;PRINT CRLF FOLLOWED BY PC VALUE
CALL CRLF
; (ENTER HERE FROM DISASSEMBLER)
PRPC0: LHLD PC
MOV A,H
CALL DECODE
MOV A,L
CALL DECODE
MVI C,' '
CALL CO
CALL CO
RET
;
DISENT: ;ENTER HERE FROM DEBUGGER
LXI H,0
DAD SP
SHLD OLDSP ;SP SAVED FOR LATER RETURN
;
; CHECK FOR PAGE MODE DISPLAY
LDA PAGM ;GET PAGE MODE (NUMBER OF LINES TO PRINT)
ORA A ;SET FLAGS
JZ DISASM ;NOT PAGE MODE
;
; SET MPC TO 0FFFFH
LXI H,0FFFFH
SHLD MPC
; 255 IMPLIES TRACE MODE
INR A
JNZ DISASM ;NOT TRACE MODE IF BR
; TRACE MODE, SET TO 1 AND IGNORE ADDRESS FIELD
INR A ;1 IN ACC
STA PAGM
LHLD PC ;RECOVER PC
JMP DIS1
;
;
DISASM:
; CHECK FOR BREAK AT CONSOLE
CALL BREAK
JNZ GOBACK
;
; CHECK TO SEE IF ENOUGH LINES PRINTED IN PAGE MODE
LXI H,PAGM
MOV A,M
ORA A ;ZERO?
JZ DIS0 ;JMP IF NOT PAGE MODE
;
; PAGE MODE, DECREMENT AND CHECK FOR ZERO
DCR M
JZ GOBACK
;
DIS0: LHLD PC ;CURRENT PC
CALL PRLABEL ;OPTIONAL LABEL
CALL CRLF ;NEW LINE
MVI C,' '
CALL CO
CALL CO ;TWO LEADING BLANKS
CALL PRPC0 ;PRINT THE VALUE
DIS1: CALL RDBYTE
; SAVE THE OPCODE IN THE D REGISTER
MOV D,A
; SEARCH THE FIRST 17 ITEMS FOR SIMPLE OPCODES
; EI (FB) THROUGH NOP (00). NOTE THAT THE SEARCH PROCEEDS
; THROUGH "TABLE" STARTING AT THE BEGINNING, BUT THE OPCODES
; ARE ACTUALLY STORED IN SYMBOLIC FORM IN REVERSE ORDER.
;
LXI H,TABLE
LXI B,17 ;FIRST 17 SIMPLE OPCODES
GROUP1: CMP M ;TABLE VALUE = OPCODE?
JZ TYPE1 ;SKIP TO PRINT IF SO
INX H ;MOVE TO THE NEXT TABLE ELEMENT
DCR C ;COUNT THE SIMPLE OPCODES DOWN
JNZ GROUP1 ;TRY FOR ANOTHER
;
; NOT A SIMPLE OPERATION CODE, CHECK FOR IMMEDIATE OP
; ADI, ACI, OUT, SUI, IN, SBI, ANI, XRI, ORI, CPI
MVI C,10
GROUP2: CMP M
JZ TYPE2
INX H
DCR C
JNZ GROUP2
;
; NOT AN IMMEDIATE OPERATION, CHECK FOR
; SHLD LHLD STA LDA JMP OR CALL
MVI C,6
GROUP3: CMP M
JZ TYPE3
INX H
DCR C
JNZ GROUP3
;
; NOT TYPE3 OPERATION CODE, CHECK FOR MOV
; BY MASKING THE HIGH ORDER TWO FIBITS -
; XX00 0000 IS PRODUCED IN THE ACCUMULATOR
ANI 0C0H
; MOV IS GIVEN BY 01 DDD SSS (DDD IS DEST, SSS IS SOURCE)
CPI 40H
JZ MOVOP
;
; NOT A MOV INSTRUCTION, CHECK FOR ACCUMLATOR-REGISTER OPS
; BIT PATTERN 10 CCC RRR CORRESPONDS TO
; ADD (0), ADC (1), SUB (2), SBB (3), ANA (4),
; XRA (5), ORA (6), CMP (7)
CPI 80H
JZ ACCREG
;
; NOT ACCUM-REGISTER, RESTORE OPCODE FOR FURTHER CHECKS
MOV A,D
;
; LOOK FOR INR, DCR, AND MVI OPERATIONS
; INR = 00 RRR 100, DCR = 00 RRR 101, MVI = 00 RRR 110
; OR, INR = 00 RRR 4, DCR = 00 RRR 5, MVI = 00 RRR 6
ANI 1100$0111B
SUI 04
; INR GOES TO ZERO
JZ INRREG
; NOT INR, MAY BE DCR
DCR A
JZ DCRREG
DCR A
; NOT DCR, MAY BE MVI
JZ MVIREG
; NOT INR, DCR, OR MVI INSTRUCTION
;
; RESTORE THE OPCODE
MOV A,D
; LOOK FOR LXI STAX INX DAD LDAX DCX OPCODES
; LXI = 00 RR 0001,
; STAX= 00 RR 0010,
; INX = 00 RR 0011,
; DAD = 00 RR 1001,
; LDAX= 00 RR 1010
; DCX = 00 RR 1011
ANI 0C0H
JZ LXILST ;TO PROCESS FURTHER
;
; NOT ONE OF THE ABOVE, CHECK FURTHER
; MUST BE OF THE FORM - 11 XXX XXX
MOV A,D
ANI 0000$0111B ;TO EXTRACT THE RIGHTMOST BITS
; RETURN CONDITIONALS TAKE THE FORM 11 XXX 000
JZ RETCON ;RETURN CONDITIONALLY
; JUMP CONDITIONALS TAKE THE FORM 11 XXX 010 = 2
SUI 02
JZ JMPCON
; CALL CONDITIONALS TAKE THE FORM 11 XXX 100 = 4 - 2 = 2
SUI 02
JZ CALLCON
; RST'S TAKE THE FORM 11 XXX 111 = 7 - 4 = 3
SUI 03
JZ RSTOP
;
; NONE OF THE ABOVE, PUSHES AND POP'S REMAIN
MOV A,D ;RESTORE OPCODE
; FIRST CAPTURE REMAINING OPCODES CB, D9, DD, ED, FD
ANI 0000$1000B ;THIS BIT RESET FOR POP,PUSH
JNZ N8080 ;NOT 8080 OPCODE IF SET
MOV A,D ;RESTORE IT
; PUSH = 11 XX0 101 = 5, POP = 11 XX0 001 = 1
ANI 07
; USE THE RESULTING VALUE TO INDEX TO REGISTER TABLE
MOV C,A
DCR A ;POP GOES TO 00
LXI H,PPOP-1
DAD B
CALL PRINT
; GET THE RELEVANT REGISTER
CALL XTRACT
; CHECK FOR PSW OPERATION CODE
CPI 06
JNZ D6
LXI H,PPSW
CALL PRINT
JMP DISASM
;
; PRINT RST XXX INSTRUCTION
RSTOP: LXI H,PRST
CALL PRINT
CALL XTRACT
CALL DECODE
JMP DISASM
;
; CALL CONDITIONAL 'C'
CALLCON:
MVI C,'C'
CALL CO
CALL CCPRNT
JMP PREXT ;TO PRINT THE ADDRESS
;
; JUMP CONDITIONAL 'J'
JMPCON:
MVI C,'J'
CALL CO
CALL CCPRNT
JMP PREXT ;TO PRINT THE ADDRESS
;
; RETURN CONDITIONAL 'R'
RETCON:
MVI C,'R'
CALL CO
CALL CCPRNT
JMP DISASM
;
;
; PROCESS ONE OF LXI STAX INX DAD LDAX DCX
LXILST: LXI H,PLXI
; CAPTURE 08, 10, 18, 20, 28, 30, AND 38
MOV A,D ;GET OPCODE
ANI 111B ;RIGHTMOST BITS ZERO?
JZ N8080 ;NOT 8080 IF SO
; RECALL OPCODE TO DETERMINE WHICH ONE
MOV A,D
; FIND THE PARTICULAR OPCODE
ANI 0FH
; LXI HAS LEAST SIGNIFICANT FOUR BITS = 0001
DCR A
JZ LXIREG
; STAX 0010 BECOMES 0001 = 1
; INX 0011 BECOMES 0010 = 2
; DAD 1001 BECOMES 1000 = 8
; LDAX 1010 BECOMES 1001 = 9
; DCX 1011 BECOMES 1010 = 10
CPI 03
JC D4
; MUST BE DAD, LDAX OR DCX
SUI 05
; DAD 8 BECOMES 3
; LDAX9 BECOMES 4
; DCX10 BECOMES 5
; ACCUMULATOR NORMALIZED
D4: ADD A
ADD A
; VALUE IN ACCUM MULTIPLIED BY FOUR
MOV C,A
DAD B
CALL PRINT
; STAX, INX, DAD, LDAX, OR DC X PRINTED, PRINT REGISTER
CALL RPPRNT
JMP DISASM
;
; PRINT REGISTER ADDRESSED BY HL (E.G., IN LXI)
LXIREG: CALL PRINT
CALL RPPRNT
MVI C,','
CALL CO
JMP PREXT ;TO PRINT THE EXTENDED INSTRUCTION
;
;
MVIREG: LXI H,PMVI
CALL PRINT
CALL XTRACT
CALL RGPRNT
MVI C,','
CALL CO
JMP DATA8
;
DCRREG: LXI H,PDCR
JMP D5
;
INRREG: LXI H,PINR
;
; PRINT THE INSTRUCTION GIVEN BY HL, FOLLOWED BY REGISTER
D5: CALL PRINT
CALL XTRACT
D6: CALL RGPRNT
JMP DISASM
;
; FOUND ACCUM REGISTER OPERATION - MIDDLE BITS GIVE PCODE
ACCREG: MOV A,D
ANI 38H ;SELECT OPCODE BITS
RRC ;OPCODE * 4 FOR LENGTH FOUR STRING
MOV C,A
LXI H,PADD ;ADDRESS THE ACCUM-REGISTER LIST
DAD B
CALL PRINT
JMP D9
;
; MOV OPERATION FOUND
MOVOP: LXI H,PMOV
CALL PRINT
CALL XTRACT
CALL RGPRNT
MVI C,',' ;REGISTER DELIMITER
CALL CO
D9: MOV A,D
ANI 07
CALL RGPRNT
JMP DISASM
;
; TYPE GROUP3: CALL JMP LDA STA LHLD SHLD
TYPE3:
MOV A,C ;*4 FOR LENGTH 4
ADD A
ADD A
MOV C,A
LXI H,TAB3-4
DAD B
CALL PRINT
;
; ARRIVE HERE TO PRINT THE ADDRESS FIELD
PREXT: CALL RDBYTE ;LOW ADDRESS TO A
PUSH PSW ;SAVE IT
CALL RDBYTE
MOV D,A ;SET HIGH ADDRESS
POP PSW ;RECALL LOW ADDRESS
MOV E,A ;DE IS THE ADDRESS TO PRINT
CALL PADDX
JMP DISASM
;
; TYPE THE IMMEDIATE OPCODES (INCLUDING IN/OUT)
TYPE2: MOV A,C ;TYPE IMMEDIATE OPERATION CODE
ADD A ;*2
ADD A ;*4 FOR LENGTH FOUR CHAR STRING
MOV C,A ;BC = INDEX * 4 FOR OPCODE
LXI H,TAB2-4
DAD B
CALL PRINT
;
; ARRIVE HERE TO PRINT THE IMMEDIATE VALUE
DATA8: CALL RDBYTE
CALL PBYTE ;BYTE VALUE PRINTED
JMP DISASM
;
; FOUND OPCODE IN TABLE, POSITION GIVEN
; BY COUNT IN BC (NOTE THAT C IS COUNTED DOWN, WHILE
; INDEX WAS MOVING UP THE TABLE DURING THE SEARCH)
TYPE1: MOV A,C ;TYPE SIMPLE OPCODES FROM GROUP 1
ADD A ;POSITION * 2
ADD A ;POSITION * 4 (FOUR CHAR CODES)
MOV C,A ;BC IS INDEX * 4 OF OPCODE
LXI H,TAB1-4
DAD B ;HL NOW HOLDS ADDRESS OF CODE TO PRINT
CALL PRINT
JMP DISASM
;
N8080: ;NOT AN 8080 OPERATION CODE
LXI H,DBOP
CALL PRINT ;PRINT THE '??='
MOV A,D ;GET THE OPCODE
CALL PBYTE ;AND PRINT IT
JMP DISASM
;
ERR: ;ENTER HERE FOR ERROR REPORTING
CALL CRLF
MVI C,'?'
CALL CO
;
LHLD OLDSP
SPHL
; PC REMAINS UNCHANGED
;
;
ASMEN: ;ENTER HERE FROM DEBUGGER
LXI H,0
DAD SP
SHLD OLDSP
;
ASM0: CALL PRPC ;PRINT PC VALUE
SHLD TPC ;SAVE PC VALUE
CALL GETBUFF ;FILL INPUT BUFFER
CALL GETOP ;GET OPERATION
; UPDATE PC, MUST BE CORRECT INPUT
LHLD TPC
SHLD PC
JMP ASM0
;
GOBACK: LHLD OLDSP
SPHL
RET
;
; THE FIRST 17 ITEMS CORRESPOND TO SIMPLE OPCODES
; (NOP BACKWARD THROUGH EI)
TABLE: DB 000H,007H,00FH,017H ;NOP RLC RRC RAL
DB 01FH,027H,02FH,037H ;RAR DAA CMA STC
DB 03FH,076H,0C9H,0E3H ;CMC HLT RET XTHL
DB 0E9H,0EBH,0F3H,0F9H ;PCHL XCHG DI SPHL
DB 0FBH ;EI
;
; THE NEXT 10 ITEMS CORRESPOND TO THE IMMEDIATE OPCODES
DB 0C6H,0CEH,0D3H ;ADI ACI OUT
DB 0D6H,0DBH,0DEH,0E6H ;SUI IN SBI ANI
DB 0EEH,0F6H,0FEH ;XRI ORI
DB 022H ;SHLD
DB 02AH,032H,03AH,0C3H
DB 0CDH
TAB1: DB 'EI ','SPHL','DI ','XCHG'
DB 'PCHL','XTHL','RET ','HLT '
DB 'CMC ','STC ','CMA ','DAA '
DB 'RAR ','RAL ','RRC ','RLC '
ETAB1: DB 'NOP '
TAB2: DB 'CPI ','ORI ','XRI ','ANI '
DB 'SBI ','IN ','SUI ','OUT '
DB 'ACI '
ETAB2: DB 'ADI '
;
TAB3: DB 'CALL','JMP ','LDA ','STA '
DB 'LHLD'
ETAB3: DB 'SHLD'
;
PMOV: DB 'MOV '
PADD: DB 'ADD ','ADC ','SUB ','SBB '
DB 'ANA ','XRA ','ORA '
ETAB5: DB 'CMP '
PINR: DB 'INR '
PDCR: DB 'DCR '
PMVI: DB 'MVI '
PLXI: DB 'LXI ','STAX','INX ','DAD '
DB 'LDAX'
ETAB7: DB 'DCX '
;
PRST: DB 'RST '
PPSW: DB 'PSW '
PPOP: DB 'POP ','PUSH'
CCODE: DB 'NZ','Z ','NC','C '
DB 'PO','PE','P '
CREG: DB 'M '
DB 'B ','C ','D ','E '
DB 'H ','L ','M '
SREG: DB 'A '
;
DB 'B ','D ','H ','SP '
DREG: DB 'PSW '
;
DBOP: DB '??= '
OPCODE: DS 4
END