mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
1070 lines
20 KiB
NASM
1070 lines
20 KiB
NASM
; CP/M DEBUGGER DISASSEMBLER/ASSEMBLER MODULE
|
||
TITLE 'CP/M DEBUGGER (ASMOD) 1/78'
|
||
;
|
||
; COPYRIGHT (C) 1976, 1977, 1978
|
||
; DIGITAL RESEARCH
|
||
; BOX 579 PACIFIC GROVE, CA
|
||
; 93950
|
||
;
|
||
FALSE EQU 0 ;VALUE OF "FALSE"
|
||
TRUE EQU NOT FALSE ;VALUE OF "TRUE"
|
||
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 RELOC
|
||
ORG 0000H ;READY FOR RELOCATION
|
||
ELSE
|
||
ORG 0D000H ;DEBUG IN 64K
|
||
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
|
||
|