Listing of file='DISASM.MAC;01' on disk='vmedia/disassembler-sector.ccvf'
;^RED>DISASM.SRC;8 1980/09/14 1200 ; ; KNOWN BUGS: ; DOES NOT ALLOW INITIAL VALUE ; FOR LABELS ; ; ; ; COPYRIGHT 1977 NORDIN ENTERPRISES ; P.O. BOX 1277 ; CUPERTINO, CA 95014 ; ; ; TITLE 'AUTOMATIC DIS-ASSEMBLER PROGRAM' ; ; ; COMPUCOLOR II 32K SYSTEM ; ; ENTER A 'START ADDR','FINISH ADDR','OFFSET'&'PARAM' ; FROM CONSOLE. PRINT TO THE LIST DEVICE IN ; ASSEMBLER LANGUAGE FORMAT THE FOLLOWING: ; HEX ADDR---OBJECT CODE---MNEMONIC---OPERAND ; PRINT LABELS WHERE FOUND ; LOAD EQU 0E400H ;64K MACHINE ; ORG LOAD ; ; JMP FIRST ;FIRST DO COMPUCOLOR THINGS CI: JMP CIX ;CONSOLE INPUT CO: JMP COX ;CONSOLE OUTPUT (DATA IN A REG) LO: JMP LOX ;LIST (PRINT) OUTPUT MNTR: JMP EXIT ;RETURN TO MONITOR WRTV: JMP PUNCH ;PUNCH OUTPUT UPDAT: JMP MNTR STACK: DW THESTK ;LOCATION OF THE STACK SZTBL EQU 3 ;TABLE SIZE IN KILOBYTES TBLSZ: DB SZTBL ;TABLE SIZE IN KILOBYTES TABLOC EQU LOAD-SZTBL*1024 TABLE: DW TABLOC ;START LOCATION OF SYMBOL TABLE ; ; START: DW 0 ;START ADDRESS FINSH: DW 0 ;FINISH ADDRESS OFSET: DW 0 ;OFFSET VALUE HERE: DW 0 ;PRESENT ADDRESS VALUE TINL: DW 0 ;ADDRESS OF SYMBOL TABLE INSERT TMPST: DW 0 ;SEARCH ADDRESS FOLLOWING JMP , CALL PSTAT: DB 0 ;PRINT LABEL STATUS LABV: DW 0 ;LABEL VALUE -- UP TO 12K LABELS TABL3: DW 0 ;STARTING ADDRESS OF SYMBOL TABLE COUNT: DB 0 ;PRINT OUT FORMAT CONTROL ; ; CR EQU 0DH ;CARRIAGE RETURN ; ; ; BEGIN: LHLD TABLE SHLD TABL3 ;SET UP SYMBOL TABLE START LXI H,MSG1 CALL MESAG ;PRINT--PUNCH THE SOURCE ? CALL TI CPI 'Y' ;YES? JZ BEG0 ;JUMP IF YES LXI H,0C900H;NO SHLD WRTV ;PATCH PUNCH WITH RET IF SO JMP BEG1 ;SKIP DISK FILE SETUP BEG0: CALL CRLF CALL SETUP ;SETUP DISK FILE BEG1: CALL CRLF LXI H,MSG2 CALL MESAG ;PRINT--PRINT ASCII DUMP ? CALL TI CPI 'Y' JZ PASCI ;GO PRINT ASCII FIRST CALL CRLF CALL STFIN ;GET THE START-FINISH PARAMETERS ; ; CLEAR THE SYMBOL TABLE ; BEG2: LHLD TABL3 LDA TBLSZ RLC RLC MOV C,A XRA A STA PSTAT MOV B,A DCX H CLEAR: MOV M,A INX H INR B JNZ CLEAR DCR C JNZ CLEAR MVI A,0FFH MVI B,4 CLR1: MOV M,A DCX H DCR B JNZ CLR1 LHLD START SHLD HERE ; ; FIRST PASS--BUILD A SYMBOL TABLE ( 3 BYTES PER SYMBOL ) ; SEARCH CODE DELIMITED BY 'START' & 'FINISH' FOR ; ALL JMP'S & CALL'S. IF THE ADDRESS WHICH FOLLOWS ; ISN'T FOUND IN THE TABLE AND IS IN THE RANGE ; OF 'START & FINISH'--- ; THEN INSERT IT IN A NUMERICALLY ASCENDING ORDER. ; IF IT IS FOUND IN THE TABLE--- ; INCREMENT THAT LABELS 'NUMBER OF CALLS' ; COUNTER (UP TO 254 POSSIBLE). ; FORMAT OF TABL3: ; CNTR0,MS ADDRESS,LS ADDRESS,CNTR1,MS ADDRESS,LS ADDRESS ; LAST TABLE POSITION IS 0FFH ; PASS: LHLD HERE ;GET PRESENT CODE POINTER LDA FINSH+1 CMP H ;ARE WE FINISHED? JZ PASS1 ;MAYBE JC PASSE ;YES JMP PASS2 PASS1: LDA FINSH CMP L ;FINISHED? JC PASSE ;YES PASS2: MOV A,M ;NO - GET OPCODE BYTE INX H SHLD HERE ;SAVE POINTER TO NEXT BYTE LXI H,TABL1 ADD L MOV L,A MVI A,0 ADC H MOV H,A MOV A,M ;GET NUMBER OF BYTES/OPCODE COUNTER CPI 1 ;ONE BYTE OPCODE? JZ PASS ;YES CPI 2 JZ PASS3 ;TWO BYTE OPCODE CPI 3 JZ PASS4 ;THREE BYTES OTHER THAN JMP , CALL LHLD HERE ;THIS IS A JMP OR CALL OPCODE MOV E,M ;GET LS ADDRESS INX H MOV D,M ;GET MS ADDRESS INX H SHLD HERE ;READY FOR NEXT OPCODE XCHG SHLD TMPST ;SAVE DE IN RAM LHLD START XCHG LHLD OFSET DAD D ;ADD OFFSET TO START ADDRESS XCHG LHLD TMPST ;NOW RETRIEVE COMPARE ADDRESS MOV A,H CMP D ;IF COMPARE ADDRESS < START ADDRESS JC PASS ;THEN GO ON TO NEXT OPCODE JNZ PASS0 MOV A,L CMP E JC PASS PASS0: LHLD FINSH XCHG LHLD OFSET DAD D ;ADD OFFSET TO FINISH ADDRESS XCHG LHLD TMPST XCHG MOV A,H CMP D ;IF COMPARE ADDRESS > FINISH ADDRESS JC PASS ;THEN GO ON TO NEXT OPCODE JNZ SERCH MOV A,L CMP E JC PASS JMP SERCH ;COMPARE ADDRESS WAS WITHIN RANGE PASS3: LHLD HERE INX H SHLD HERE JMP PASS PASS4: LHLD HERE INX H INX H SHLD HERE JMP PASS ; ; TABLE SEARCH FOR COMPARE ADDRESS CONTAINED IN DE ; SERCH: LHLD TABL3 SER1: MOV A,M ;GET NUMBER OF CALLS COUNTER CPI 0FFH ;END OF TABLE? JZ PASS ;YES ORA A JZ INSRT ;THAT WAS END OF TABLE ENTRIES INX H MOV A,D ;GET MS SEARCH VALUE CMP M ;COMPARE TO SYMBOL TABLE VALUE JC SER5 ;MS TABLE > MS SEARCH VALUE JNZ SER2 ;NOT EQUAL INX H MOV A,E ;GET LS SEARCH VALUE CMP M JC SER4 ;LS TABLE > LS SEARCH VALUE JNZ SER3 ;NOT EQUAL DCX H ;AHA--THEY ARE EQUAL DCX H MOV A,M ;GET COUNTER INR A MOV M,A CPI 0FFH ;REACHED 255 CALLS? JNZ PASS ;NO DCR A ;YES--ONLY ALLOW 254 MOV M,A JMP PASS SER2: INX H ;GO TO NEXT TABLE LOCATION SER3: INX H JMP SER1 ;AND CONTINUE SEARCH SER4: DCX H ;TABLE VALUE WAS > SEARCH VALUE SER5: DCX H ;SO INSERT SEARCH VALUE IN TABLE ; ; INSERT SEARCH VALUE CONTAINED IN DE INTO SYMBOL TABLE ; INSRT: SHLD TINL ;SAVE PRESENT POSITION IN SYMBOL TABLE INSR1: XRA A ORA M ;END OF TABLE YET? JZ INSR2 ;YES CPI 0FFH ;MAX END YET? JZ PASS ;YES INX H INX H INX H JMP INSR1 ;GO TO NEXT SYMBOL TABLE LOCATION INSR2: PUSH D ;IT IS OK TO INSERT INX H INX H XCHG LXI H,3 DAD D ;BOTH POINTERS READY INSR3: LDAX D ;GET CHARACTER MOV M,A ;PUT IT IN LOCATION+3 LOCATION DCX H DCX D LDA TINL+1 ;HAVE WE REACHED STARTING CMP D ;PLACE IN TABLE? JNZ INSR3 ;NO LDA TINL CMP E JNZ INSR3 LDAX D MOV M,A XCHG MVI M,1 ;INITIAL COUNT = 1 INX H POP D MOV M,D ;STORE MS ADDRESS VALUE INX H MOV M,E ;STORE LS JMP PASS ;BACK TO NEXT CODE SEARCH ; ; THIS IS BEGINNING OF SECOND PASS ; WE NOW PRINT OUT THE ASSEMBLY LANGUAGE EQUIVALENT ; OF THE OPCODES FOUND AND THEIR ARGUMENTS. ; ALL 3-BYTE CODES FOUND MAKE A SEARCH OF THE ; SYMBOL TABLE AND COMPARE. IF THE VALUE IS FOUND ; IN THE TABLE THEN IT IS REPLACED BY A MANUFACTURED ; LABEL WHICH RELATES TO ITS POSITION IN THE TABLE. ; PASSE: LHLD START SHLD HERE AGAIN: LHLD HERE LDA FINSH+1 CMP H ;EQUAL? JZ AGN1 ;YES JC FOUR ;WHOOPS GREATER THAN JMP AGN2 AGN1: LDA FINSH CMP L ;GREATER THAN? JC FOUR ;YES AGN2: MVI B,4 ;INDENT CALL SPACE ;LISTING FOR 3 HOLE PUNCH XCHG LHLD OFSET DAD D ;ADD OFFSET CALL DADR ;PRINT ADDRESS IN HL MVI B,2 CALL SPACE XCHG CALL FIND ;SEARCH SYMBOL TABLE LHLD HERE MOV A,M ;GET OPCODE BYTE PUSH PSW ;SAVE A COPY INX H SHLD HERE ;SAVE NEXT BYTE ADDRESS LXI H,TABL1 ;FORM TABL1 POINTER ADD L MOV L,A MVI A,0 ADC H MOV H,A MOV A,M ;GET NUMBER OF BYTES PER OPCODE DCR A JZ ONE ;THAT IS A ONE-BYTE OPCODE CPI 1 JZ TWO ;THAT IS A TWO-BYTE OPCODE ; THREE: POP PSW ;THIS IS A THREE-BYTE OPCODE MOV E,A ;SAVE OPCODE IN "E" CALL DBYTE ;PRINT IT LHLD HERE MOV A,M ;GET 1ST DATA/ADDRESS BYTE PUSH PSW ;SAVE TO STACK CALL DBYTE ;PRINT IT INX H MOV A,M ;GET 2ND DATA/ADDRESS BYTE PUSH PSW CALL DBYTE INX H SHLD HERE ;SAVE NEXT OPCODE ADDRESS MVI B,2 CALL SPACE CALL LABEL ;PRINT LABEL IF APPROPRIATE CALL PRINT POP PSW MOV D,A ;GET MS POP PSW MOV E,A ;GET LS CALL FIND ;IS IT IN SYMBOL TABLE? JNC THRE1 ;NO--JUST PRINT THE NUMBER CALL PLAB ;YES--PRINT A LABEL JMP THRE2 THRE1: XCHG CALL FADR THRE2: CALL FCRLF JMP AGAIN ; ; PRINT THE SYMBOL TABLE WITH NUMBER OF CALLS PER LABEL ; FORMAT: SMxxx YY ADDR ; WHERE xxx=LABEL NUMBER & YY=NUMBER OF CALLS ; FOUR: MVI B,4 FOUR1: MVI A,0AH ;PRINT 4 LINE FEEDS CALL LO DCR B JNZ FOUR1 LHLD TABL3 LXI D,0 FOUR2: MVI A,4 STA COUNT FOUR3: XRA A ;GET COUNTER VALUE ORA M ;END OF TABLE ENTRIES? JZ FLOPY ;YES CPI 0FFH ;END OF TABLE? JZ FLOPY ;YES MOV A,D ;GET POSITION COUNTER STA LABV+1 ;INITIALIZE FOR PRINTING LABEL MOV A,E STA LABV CALL XLAB MVI B,1 CALL SPACE MOV A,M ;GET NUMBER OF CALLS COUNTER CALL DBYTE ;PRINT IT MVI B,1 CALL SPACE INX H MOV A,M ;GET MS ADDRESS VALUE CALL DBYTE ;PRINT IT INX H MOV A,M ;GET LS ADDRESS VALUE CALL DBYTE ;PRINT IT INX H MVI B,4 CALL SPACE INX D ;NO--ADVANCE TABLE POSITION LDA COUNT DCR A STA COUNT JNZ FOUR3 ;PRINT 4 GROUPS PER LINE CALL LCRLF ;END OF A LINE JMP FOUR2 ; FLOPY: MVI B,8 FLOP1: CALL LCRLF DCR B JNZ FLOP1 MVI A,FF ;FORM FEED CALL LO MVI A,FF CALL LO JMP UPDAT ; ; ONE BYTE OPCODE PROGRAM PATH ; ONE: POP PSW ;GET OPCODE MOV E,A ;SAVE CALL DBYTE ;PRINT IT MVI B,6 CALL SPACE ;PRINT SPACES CALL LABEL CALL PRINT ;PRINT OPCODE MNEMONIC JMP THRE2 ; ; TWO BYTE OPCODE PROGRAM PATH ; TWO: POP PSW ;GET OPCODE MOV E,A ;SAVE CALL DBYTE ;PRINT LHLD HERE MOV A,M ;GET DATA BYTE PUSH PSW ;SAVE INX H SHLD HERE ;SAVE NEXT OPCODE ADDRESS CALL DBYTE ;PRINT DATA BYTE MVI B,4 CALL SPACE CALL LABEL CALL PRINT POP PSW CALL FBYTE ;GET AND PRINT DATA BYTE JMP THRE2 ; ; PRINT A MESSAGE ; ENTER WITH HL POINTING AT FIRST ; ASCII DIGIT--WILL PRINT UNTIL A ; "EOT" (04H) CHARACTER IS FOUND. ; MESAG: MOV A,M ;GET THE CHARACTER CPI 4H ;IS IT EOT? RZ ;ALL FINISHED CALL CO INX H ;ADVANCE POINTER JMP MESAG ; FESAG: MOV A,M CPI 4H RZ CALL LO CALL WRTV INX H JMP FESAG ; ; ENTER START, FINISH AND OFFSET ; PRINTS CR-LF & MESSAGE: ; "START ADDRESS, FINISH ADDRESS, OFFSET= " ; ENTRY OF UP TO 4 HEX DIGITS PER VALUE IS ; EXPECTED. OFFSET IS SAME VALUE USED IF ; LOADING A PROGRAM FROM PAPER TAPE OR ; FLOPPY WITH OFFSET. ; STFIN: CALL CRLF LXI H,MSGST CALL MESAG ;PRINT MESSAGE TO CONSOLE MVI C,3 CALL EXPR ;GET 3 PARAMETERS POP H ;GET OFFSET XRA A SUB L ;DO A 2'S COMPLEMENT MOV L,A MVI A,0 SBB H MOV H,A SHLD OFSET ;SAVE IT POP H SHLD FINSH POP H SHLD START CALL CRLF RET ; ; PRINT NUMBER OF SPACES SPECIFIED IN "B" ; TO THE LIST DEVICE ; SPACE: MVI A,' ' CALL LO ;TO LIST DEVICE DCR B JNZ SPACE RET ; FPACE: MVI A,' ' CALL LO DCR B JNZ FPACE MVI A,9H ;TAB CHARACTER TO FLOPPY CALL WRTV RET ; ; PRINT OPCODE MNEMONIC MESSAGE ; ENTER WITH OPCODE BYTE IN "E" ; PRINT: MVI D,0 LXI H,TABL2 XCHG DAD H ;DOUBLE OPCODE VALUE DAD D ;NOW ADD TO TABL2 ADDRESS MOV A,M ;GET LS BYTE FROM TABLE2 INX H MOV H,M ;GET MS BYTE FROM TABLE MOV L,A CALL FESAG ;NOW PRINT APPROPRIATE MESSAGE RET ; ; SEARCH SYMBOL TABLE FOR AN EQUAL COMPARISON ; WITH THE VALUE IN DE. ; EXIT WITH: IF FOUND AN EQUAL ; CY=1,TABLE POSITION IN "LABV" ; IF NOT FOUND----CY=0 ; A,B,H,L,FLAGS USED ; FIND: LHLD TABL3 LXI B,0 FIND1: XRA A ORA M ;GET TABLE COUNTER VALUE JZ FIND2 ;WHOOPS-FOUND END OF ENTRIES CPI 0FFH ;AT END OF TABLE? JZ FIND2 ;YES-ALL FINISHED INX H MOV A,D ;GET MS TABLE VALUE CMP M JC FIND2 ;D > TABLE VALUE JNZ FIND3 ;D < TABLE VALUE INX H MOV A,E ;GET LS CMP M JC FIND2 ;E > TABLE VALUE JNZ FIND4 ;E < TABLE VALUE MOV A,B STA LABV+1 ;FOUND EQUAL SO SAVE POSITION COUNT MOV A,C STA LABV MVI A,0FFH STA PSTAT ;SET FOUND STATUS STC RET FIND2: XRA A STA PSTAT ;NOT FOUND EXIT RET FIND3: INX H FIND4: INX H ;ADJUST POINTER INX B ;KEEP TRACK OF TABLE POSITION JMP FIND1 ; ; PRINT A LABEL WHOSE VALUE IS FOUND IN "LABV" ; XLAB: MVI A,'S' CALL LO MVI A,'M' CALL LO LDA LABV+1 CALL CONV CALL LO LDA LABV CALL DBYTE RET ; ; PLAB: MVI A,'S' CALL LO CALL WRTV MVI A,'M' CALL LO CALL WRTV LDA LABV+1 CALL CONV CALL LO CALL WRTV LDA LABV RRC RRC RRC RRC CALL CONV CALL LO CALL WRTV LDA LABV CALL CONV CALL LO CALL WRTV RET ; ; PRINT LABEL PRECEEDING CODE IF PRINT STAT IS ON. ; OTHERWISE PRINT SPACES. ; LABEL: LDA PSTAT ORA A JZ LAB1 CALL PLAB MVI A,':' CALL LO CALL WRTV MVI B,2 CALL FPACE RET LAB1: MVI B,8 CALL FPACE RET ; ; PRINT A CR-LF AND SEND TO PUNCH ; FCRLF: MVI A,CR CALL LO CALL WRTV MVI A,LF CALL LO CALL WRTV RET ; CRLF: MVI A,CR CALL CO MVI A,LF CALL CO RET ; ; PRINT HEX VALUE IN "A" AND SEND TO PUNCH ; INSERT A LEADING 0 AND APPEND AN "H" ; FBYTE: PUSH PSW PUSH PSW MVI A,'0' CALL LO CALL WRTV POP PSW RRC RRC RRC RRC CALL CONV CALL LO CALL WRTV POP PSW CALL CONV CALL LO CALL WRTV MVI A,'H' CALL LO CALL WRTV RET ; ; PRINT AN ADDRESS IN HL AND SEND TO PUNCH ; INSERT A LEADING 0 AND APPEND AN "H" ; FADR: MVI A,'0' CALL LO CALL WRTV MOV A,H RRC RRC RRC RRC CALL CONV CALL LO CALL WRTV MOV A,H CALL CONV CALL LO CALL WRTV MOV A,L RRC RRC RRC RRC CALL CONV CALL LO CALL WRTV MOV A,L CALL CONV CALL LO CALL WRTV MVI A,'H' CALL LO CALL WRTV RET ; ; GOMON: CALL LCRLF JMP MNTR ; ; TI: PUSH B CALL CI CALL UC POP B RET ; ; UC: CPI 'A'+20H RM CPI 'Z'+21H RP ANI 0DFH ;FORCE UPPER CASE RET ; ; LCRLF: MVI A,CR CALL LO MVI A,LF CALL LO RET ; ; DADR: MOV A,H CALL DBYTE MOV A,L CALL DBYTE RET ; ; DBYTE: PUSH PSW RRC RRC RRC RRC CALL CONV CALL LO POP PSW CALL CONV CALL LO RET ; ; CONV: ANI 0FH ADI 90H DAA ACI 40H DAA RET ; ; NIBBL: SUI '0' RC ADI 0E9H RC ADI 6 JP NIBB1 ADI 7 RC NIBB1: ADI 10 ORA A RET ; ; HILO: INX H MOV A,H ORA L STC RZ MOV A,E SUB L MOV A,D SBB H ;RETURN WITH CY=1 IF HL > DE RET ; ; EXPR: CALL PARAM XTHL PUSH H DCR C JNC EXPR1 JNZ GOMON RET EXPR1: JNZ EXPR JMP GOMON PARAM: CALL PCHK JZ GOMON LXI H,0 PAR1: MOV B,A CALL NIBBL JC PAR2 DAD H DAD H DAD H DAD H ORA L MOV L,A CALL TI JMP PAR1 PAR2: MOV A,B CALL PCHK1 JNZ GOMON RET PCHK: CALL TI PCHK1: CPI ' ' RZ CPI ',' RZ CPI CR STC RZ CMC RET ; ; ; PRINT MEMORY AND LOOK FOR ASCII CHARACTERS ; PASCI: LHLD STACK SPHL CALL STFIN CALL LCRLF LHLD FINSH XCHG LHLD START PASC1: MVI B,64 CALL DADR MVI A,' ' CALL LO PASC2: MOV A,M CPI 20H JC PASC4 CPI 5FH JNC PASC4 MOV A,M PASC3: CALL LO CALL HILO JC PASC5 DCR B JNZ PASC2 CALL LCRLF JMP PASC1 PASC4: MVI A,'.' JMP PASC3 PASC5: MVI B,8 PASC6: CALL LCRLF DCR B JNZ PASC6 JMP BEG2 ; ; ; MSG1: DB 'PUNCH THE SOURCE ? ( Y OR ANY CHARACTER ) ',4 MSG2: DB 'PRINT ASCII DUMP ? ( Y OR ANY CHARACTER ) ',4 MSGST: DB 'START ADDRESS , FINISH ADDRESS , OFFSET = ',4 ; ; LF EQU 10 ;LINE FEED FF EQU 12 ;FORM FEED BS EQU 26 ;LEFT CURSOR (BACKSPACE) ESC EQU 27 ;ESCAPE RATE EQU 0A0H ;PRINTER BAUD RATE 0A0H = 4800 BAUD ; END