* TITLE - DISASSEMBLER FOR 8080 ; ; NOTE: This program is to be used in conjunction ; with BECK.ASM ; ; ORIGIN EQU 0F000H ORG ORIGIN+400H ; SUBROUTINE TO DISASSEMBLE ONE INSTRUCTION ; SETS CY IF DE=ADDR FIELD OF 3 BYTE INSTR ; BC -> OUTPUT BUFFER (ADVANCES) ; HL -> INSTRUCTION (ADVANCES) FUDGE EQU 0E0H ; ; DISL: CALL HXSYM ; BACK HL AS SYMBOL DISNL: ; DISASSMBLE W/O LABEL PUSH B CALL GTPTR ; GET DE ->OP FMT BLK POP B CALL BLANK ; BUILD OP FIELD LDAX D ;OFB (0) ANI 1FH ; 1ST LETTER CODE ADI 'A'-1 ; MAKE ASCII STAX B ; TO OUTPUT BUFFER INX B INX D LDAX D ; OFB(1) ANI 1FH ; IF ZERO, OR DONE EXCEPT COND OF C,J,R JZ BACK1 ADI 'A'-1 STAX B INX B INX D LDAX D ;OFP(2) ANI 1FH JNZ OPCH3 MVI A,FUDGE ; FUDGE BLANK OPCH3: ADI 'A'-1 STAX B INX B LDAX D ; OFP(2) ANI 0E0H ; HI 3 BITS RLC! RLC! RLC! ; LOOK UP 4TH OP LETTER PUSH B LXI B,OL4TB ; TABLE START ADD C MOV C,A MVI A,0 ; W/O CHANGING CARRY Š ADC B MOV B,A ; BC->BYTE IN TABLE LDAX B ; 4TH OP LETTER ASCII POP B STAX B INX B DCX D BACK1: DCX D ; BUILD OF BYTE DEPENDENT VARIABLE FIELDS ; HL->OP. DE->OFB(0), BC->OUT BFFR LDAX D ANI 0F0H ; FMT CODES IN 5-7 ; FORMAT CODES NAMED FOR VARIABLES ; 1-RP(SP),2=RP(PSW),3=S,4=D,5=DS,6=N,7=COND PUSH PSW CPI 0E0H CNZ BLANK ; IF NOT FMT 7 (COND) POP PSW JZ CKLNG ; IF NO FIELD FROM OP PUSH D CPI 60H ; TYPE 3? PUSH PSW JZ FS2 ; REMAINING FMTS NEED BITS 3-5 OF OP BYTE MOV A,M ; OP BYTE RRC! RRC! RRC! ANI 7 MOV D,A POP PSW PUSH PSW ; A=FMT CODE. PSW SET ; HL->OP BYTE, D=OP BITS 3-5, BC-> OUT BFFR JNC CKN ; IF FMT>3 ; RP FMTS MOV A,D ANI 6 ; RP IS 2 BITS MOV D,A CPI 6 JNZ FD2 ; IF D HAS REG CODE ; BUILD SP OR PSW POP PSW ; A=FMT PUSH PSW CPI FRPP JZ RPPSW MVI A,'S' STAX B INX B MVI A,'P' JMP LSTOV ; LAST OP VAR RPPSW: MVI A,'P' STAX B INX B MVI A,'S' Š STAX B INX B MVI A,'W' JMP LSTOV ; A=FMT, HL->OP BYTE, D=OP BITS 3-5, ; BC->OUT BFFR, (D,PSW PUSHED) CKN: CPI 0C0H ; FMT 6? JNZ CKCND ; FMT N (RST) MOV A,D ADI '0' ; ASCII JMP LSTOV CKCND: CPI 0E0H ; FMT 7? JNZ FD2 ; IF FD OR FDS ; CONDITION PART OF OP FOR J,C,R MOV A,D RLC ; DOUBLE FOR 2 BYTE LOOKUP LXI D,CNDTB ; TABLE START ADD E MOV E,A MVI A,0 ADC D MOV D,A LDAX D ; 1ST LETTER STAX B INX B INX D LDAX D STAX B INX B MVI A,' ' ; END OF FIELD STAX B INX B JMP LSTOV FD2: ; FD, FDS OR PREPROCESSED MOV A,D ; REG CALL REGDE ; DE->REG LETTER POP PSW ; A=FMT PUSH PSW CPI 0A0H LDAX D ; LETTER JNZ LSTOV ; IF NOT FDS ; FDS STAX B INX B CALL COMMA FS2: MOV A,M ; OP BYTE ANI 7 ; S FIELD CALL REGDE ; DE->REG LETTER LDAX D ; LETTER LSTOV: Š ; LAST VAR FIELD FROM OP STAX B ; TO BUFFER INX B POP PSW ; A=FMT POP D CKLNG: INX H INX D ; *FMT, DE->OBK(1), HL->AFTER OP ; BC->OUT BUFFER PUSH PSW LDAX D ; OFP(1) POP D ; D=FMT RLC! RLC! RLC! ANI 3 ; INSTR LNGTH - 1 JZ CRL ; IF DONE MOV E,A ; FORMATS 0,7 NEED NO COMMA MOV A,D ; FMT ORA A JZ BYT2 CPI 0E0H ; FMT 7? CNZ COMMA BYT2: MOV A,E ; LNGTH-1 MOV E,M ; NEXT BYTE INX H CPI 2 JM LNG2 ; IF 2 BYTE INSTR ; 3 BYTE INSTR MOV D,M ; 3RD BYTE INX H XCHG ; DE->HL CALL HXSYM XCHG STC ; CARRY MEANS 3 BYTE INSTR ; DE=ADDR VALUE FROM INSTR JMP CR2 LNG2: MVI A,'0' STAX B ; TENTATIVE 1ST CHAR MOV A,E ; 2ND INSTR BYTE RRC ANI 7FH CPI 50H MOV A,E ; DATA BYTE AGAIN JM PRFXD ; IF 1ST HEX IS 0-9 INX B ; USE 0 PREFIX PRFXD: CALL HXBYT MVI A,'H' STAX B INX B CRL: XRA A Š; CY=0 MEANS NOT A 3 BYTE INSTRUCTION CR2: MVI A,0DH JMP LOUT BLANK: MVI A,' ' LOUT: STAX B INX B RET COMMA: MVI A,',' JMP LOUT REGDE: LXI D,REGTB ADD E MOV E,A MVI A,0 ADC D MOV D,A RET ; DE->REG LETTER ; CONVERT HL TO SYMBOL. USES A,PSW AND BC HXSYM: MVI A,'H' ; MAKES IT A SYMB STAX B INX B MOV A,H CALL HXBYT MOV A,L HXBYT: PUSH PSW RRC! RRC! RRC! RRC! CALL HXNBL POP PSW HXNBL: ANI 0FH ADI '0' CPI '9'+1 JC LOUT ; IF <=9 ADI 'A'-'9'-1 ; MAKE A-F JMP LOUT ; ; SUBR. GETS PTR TO OP FORMAT BLOCK ; GROUP IS BITS 7-6 OF OP BYTE ; HL->OP BYTE (PRESERVED) ; DE->OP BLOCK ON EXIT ; USES C. PRESERVES B. GTPTR: MOV A,M ; OP BYTE CPI 40H JNC CKG1 ; IF NOT GROUP 0 ; GROUP 0 LXI D,GRPOX ; ->GROUP 0 INDEX TABLE JMP LKUPX ; LOOP UP INDEX CKG1: Š CPI 80H JNC CKG2 ; GROUP 1 CPI 76H MVI A,8 ; INDEX FOR HALT JZ GOTX ; IF HALT INR A ; INDEX FOR MOV JMP GOTX CKG2: CPI 0C0H JNC GRP3 ; GROUP 2 RRC! RRC! RRC! ANI 7 ; INDEX I BITS 5-3 OF OP JMP GOTX GRP3: LXI D,GRP3X ; ->GROUP 3 INDEX TABLE LKUPX: ANI 3FH ; BITS 5-0 OF OP ADD E MOV E,A MVI A,0 ADC D MOV D,A LDAX D ; GET INDEX GOTX: ; A=INDEX OF OP BLOCK ; HL->OP BYTE LXI D,OPTAB ; ->OP FORMAT BLOCK TABLE ; TRIBLE INDEX (3 BYTES PER OP BLOCK) MOV C,A ADD C ADD C ; 3*INDEX (CAN'T CARRY) ADD E MOV E,A MVI A,0 ADC D MOV D,A ; DE->BLOCK FOR THIS OP RET OL4TB: ; 4TH LETTER OF OPS DW 'D ' DW 'HG' DW 'XL' CNDTB: ; COND CODES FOR B,C,J DW 'ZN' DW ' Z' DW 'CN' DW ' C' DW 'OP' DW 'EP' DW ' P' DW ' M' REGTB: Š DW 'CB' DW 'ED' DW 'LH' DW 'AM' ; OPERATION CODE FORMAT AND MNEMONIC TABLE ; INDEX IS DERIVED ELSEWHERE AND USED *3. ; SYMBOLS FOR DEBIASED LETTERS ; AA EQU 1 BB EQU 2 CD EQU 3 DD EQU 4 EE EQU 5 HH EQU 8 II EQU 9 JJ EQU 10 LL EQU 12 MM EQU 13 NN EQU 14 OO EQU 15 PP EQU 16 RR EQU 18 SS EQU 19 TT EQU 20 UU EQU 21 VV EQU 22 XX EQU 24 ; LENGTH CODES L2 EQU 20H L3 EQU 40H ; CODES FOR 4TH OP LETTER OL4D EQU 32 OL4G EQU 64 OL4H EQU 96 OL4L EQU 128 OL4X EQU 160 ; FORMAT TYPES FRPS EQU 32 ; RP(SP)=1 FRPP EQU 64 ; RP(PSW)=2 FS EQU 96 ; S=3 FD EQU 128 ; D=4 FDS EQU 160 ; DS=5 FN EQU 192 ; NUMERAL=6 FC EQU 224 ; C=7 ; OPTAB: ; 3 BYTE BLOCK PER CODE FORMAT ; RIGHT 5 BITS OF BYTE IS CODED OP LETTER ; LEFT 3 BITS OF BYTE 1 IS FORMAT CODE ; BITS 5-6 OF BYTE 2 IS INSTR LENGTH (1,2,3) ; LEFT 3 BITS OF BYTE 3 IS CODED OP LETTER 4 ; ; GROUP 2 INDEX=THIS+BITS 5-3 OF INSTR. ; DB AA+FS ; ADD=0 Š DB DD DB DD DB AA+FS ; ADC=1 DB DD DB CD DB SS+FS ; SUB=2 DB UU DB BB DB SS+FS ; SBB=3 DB BB DB BB DB AA+FS ; ANA=4 DB NN DB AA DB XX+FS ; XRA=5 DB RR DB AA DB OO+FS ; ORA=6 DB BB DB AA DB CD+FS ; CMP=7 DB MM DB PP ; GROUP 1 DB HH ; HLT=8 DB LL DB TT DB MM+FDS ; MOV=9 DB OO DB VV ; GROUPS 0 AND 3 ; INDEXES FOR GRPOX AND GRP3X TABLES DB MM+FD ; MVI=10 DB VV+L2 DB II DB DD+FD ; DCR=11 DB CD DB RR DB II+FD ; INR=12 DB NN DB RR DB LL+FRPS ; LXI=13 DB XX+L3 DB II DB LL ; LDA=14 DB DD+L3 DB AA DB SS ; STA=15 DB TT+L3 DB AA DB LL ; LHLD=16 DB HH+L3 DB LL+OL4D DB SS ; SHLD=17 DB H+L3 Š DB LL+OL4D DB LL+FRPS ; LDAX=18 DB DD DB AA+OL4X DB SS+FRPS ; STAX=19 DB TT DB AA+OL4X DB XX ; XCHG=20 DB CD DB HH+OL4G DB AA ; ADI=21 DB DD+L2 DB II DB AA ; ACI=22 DB CD+L2 DB II DB SS ; SUI=23 DB UU+L2 DB II DB SS ; SBI=24 DB BB+L2 DB II DB II+FRPS ; INX=25 DB NN DB XX DB DD+FRPS ; DCX=26 DB CD DB XX DB DD+FRPS ; DAD=27 DB AA DB DD DB DD ; DAA=28 DB AA DB AA DB AA ; ANI=29 DB NN+L2 DB II DB XX ; XRI=30 DB RR+L2 DB II DB OO ; ORI=31 DB RR+L2 DB II DB CD ; CPI=32 DB PP+L2 DB II DB RR ; RLC=33 DB LL DB CD DB RR ; RRC=34 DB RR DB CD DB RR ; RAL=35 DB AA DB LL Š DB RR ; RAR=36 DB AA DB RR DB CD ; CMA=37 DB MM DB AA DB CD ; CMC=38 DB MM DB CD DB SS ; STC=39 DB TT DB CD DB JJ ; JMP=40 DB MM+L3 DB PP DB JJ+FC ; J(COND)=41 DB L3 DB 0 DB CD ; CALL=42 DB AA+L3 DB LL+OL4L DB CD+FC ; C(COND)=43 DB L3 DB 0 DB RR ; RET=44 DB EE DB TT DB RR+FC ; R(COND)=45 DB 0 DB 0 DB RR+FN ; RST=46 DB SS DB TT DB PP ; PCHL=47 DB CD DB HH+OL4L DB PP+FRPP ; PUSH=48 DB UU DB SS+OL4H DB PP+FRPP ; POP=49 DB OO DB PP DB XX ; XTHL=50 DB TT DB HH+OL4L DB SS ; SPHL=51 DB PP DB HH+OL4L DB II ; IN=52 DB NN+L2 DB 0 DB OO ; OUT=53 DB UU+L2 DB TT DB EE ; EI=54 Š DB II DB 0 DB DD ; DI=55 DB II DB 0 DB NN ; NOP=56 DB OO DB PP DB UU ; UND=57 (UNDEFINED) DB NN DB DD ; THE FOLLOWING TABLES CONVERT THE REMAINING ; 6 (LOW) BITS OF INSTRS IN GROUPS 0 AND 3 ; TO INDEXES TO OP BLOCKS GRPOX: DB 56 ; NOP DB 13 ; LXI DB 19 ; STAX DB 25 ; INX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 33 ; RLC DB 57 ; UNDEF DB 27 ; DAD DB 18 ; LDAX DB 26 ; DCX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 34 ; RRC DB 57 ; UNDEF DB 13 ; LXI DB 19 ; STAX DB 25 ; INX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 35 ; RAL DB 57 ; UNDEF DB 27 ; DAD DB 18 ; LDAX DB 26 ; DCX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 36 ; RAR DB 57 ; UNDEF DB 13 ; LXI DB 17 ; SHLD DB 25 ; INX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 28 ; DAA Š DB 57 ; UNDEF DB 27 ; DAD DB 16 ; LHLD DB 26 ; DCX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 37 ; CMA DB 57 ; UNDEF DB 13 ; LXI DB 15 ; STA DB 25 ; INX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 39 ; STC DB 57 ; UNDEF DB 27 ; DAD DB 14 ; LDA DB 26 ; DCX DB 12 ; INR DB 11 ; DCR DB 10 ; MVI DB 38 ; CMC GRP3X: DB 45 ; P DB 49 ; POP DB 41 ; J DB 40 ; JMP DB 43 ; C DB 48 ; PUSH DB 21 ; ADI DB 46 ; RST DB 45 ; R DB 44 ; RET DB 41 ; J DB 57 ; UNDEF DB 43 ; C DB 42 ; CALL DB 22 ; ACI DB 46 ; RST DB 45 ; R DB 49 ; POP DB 41 ; J DB 53 ; OUT DB 43 ; C DB 48 ; PUSH DB 23 ; SUI DB 46 ; RST DB 45 ; R DB 57 ; UNDEF DB 41 ; J DB 52 ; IN DB 43 ; C DB 57 ; UNDEF Š DB 24 ; SBI DB 46 ; RST DB 45 ; R DB 49 ; POP DB 41 ; J DB 50 ; XTHL DB 43 ; C DB 48 ; PUSH DB 29 ; ANI DB 46 ; RST DB 45 ; R DB 47 ; PCHL DB 41 ; J DB 20 ; XCHG DB 43 ; C DB 57 ; UNDEF DB 30 ; XRI DB 46 ; RST DB 45 ; R DB 49 ; POP DB 41 ; J DB 55 ; DI DB 43 ; C DB 48 ; PUSH DB 31 ; ORI DB 46 ; RST DB 45 ; R DB 51 ; SPHL DB 41 ; J DB 54 ; EI DB 43 ; C DB 57 ; UNDEF DB 32 ; CPI DB 46 ; RST DELAY: ORG 0F700H PUSH H! PUSH B! PUSH D! PUSH PSW! MVI B,80H DEL1: MVI C,0FFH DEL2: DCR C JNZ DEL2 DCR B JNZ DEL1 POP PSW! POP D! POP B! POP H! RET END