CPM EQU 00H BDOS EQU 05H TFCB EQU 5CH L0064 EQU 64H FCB2 EQU 6CH TBUFF EQU 80H LC013 EQU 0C013H LC217 EQU 0C217H ; BDOS EQUATES RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CSTAT EQU 11 SELDSK EQU 14 OPEN EQU 15 CLOSE EQU 16 SRCHF EQU 17 SRCHN EQU 18 DELETE EQU 19 READ EQU 20 WRITE EQU 21 MAKE EQU 22 RTCUDSK EQU 25 STDMA EQU 26 ; GENERAL EQUATES CR EQU 0DH LF EQU 0AH TAB EQU 09H EOF EQU 1AH LIN$PAG$CT: DB 55 STITLE: DB 'LASM-TDL Nov-85 ',0 PAGE$BUF: DB ' PAGE-000 ' TIT$BUF: DB ' ',CR PAS$MSG: DB 'Pass-1 ',0 ; CHARACTER TYPE ; 1 = ALPHA ; 2 = NUMBER ; 3 = QUOTE " ; 4 = OTHER PRN$CHR$CT: DB 0 STR$TYPE: DB 0 STR$VAL: DW 0 STR$SIZE: DB 0 STRING: DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0 L0161: DW 0 SYMTAB$PTR: DW SYM$TABLE XREF$PTR: DW 0 PASS$NM: DB 0 LOC$CTR1: DW 0 LOC$CTR2: DW 0 CCP$BEGIN DW 0 SYM$TAB$BASE: DW SYM$TABLE SYM$HASH$PTR: DW 0 OBJ$LINE$LOC: DW 0 OBJ$BYTE$CNT: DB 0 OBJ$LINE: DW 0,0,0,0,0,0,0,0 DFALDRV: DB 0 OPTSRC: DB 0 OPTPRN: DB 0 OPTOBJ: DB 0 SRCFCB: DB 0 SRCNAME: DB 0,0,0,0,0,0,0,0,'ASM' SRC$EXT: DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0 SRC$CR: DB 0 PRNFCB: DB 0,0,0,0,0,0,0,0,0 DB 'PRN' L01B2: DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0 L01C6: DB 0 OBJFCB: DB 0,0,0,0,0,0,0,0,0,'HEX',0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0 SYM$EXT DB 'SYM' IBUF$CTR: DW 1000H PRN$BUF$PTR: DW 0 OBJ$BUF$PTR: DW 0 FLAG$BYT: DB 0 XREFF EQU 1 SYMF EQU 2 CCP$SP DW 0 ; CPM CCP STACK SEL$DRV: LXI H,DFALDRV CMP M RZ MOV M,A MOV E,A MVI C,SELDSK CALL BDOS RET OPT$TRAN: INX H MOV A,M CPI ' ' JZ L0205 SBI 'A' RET L0205: LDA DFALDRV RET MSGOUT: MOV A,M CALL CO MOV A,M INX H ORA A JZ MSG$01 CPI CR JNZ MSGOUT MSG$00: MVI A,LF CALL CO RET MSG$01: MVI A,CR CALL CO JMP MSG$00 MOVNAM: LXI D,TFCB MVI B,9 L021F: LDAX D CPI '?' JZ ER04 ;'SOURCE NAME ERROR' MOV M,A INX H INX D DCR B JNZ L021F RET OPENFIL: MVI C,OPEN CALL BDOS CPI 0FFH RNZ LXI H,ERMSG1 CALL MSGOUT JMP SYSTEM CLOSFIL: MVI C,CLOSE CALL BDOS CPI 0FFH RNZ LXI H,CANT$CLOS$M CALL MSGOUT JMP SYSTEM DEL$FIL: MVI C,DELETE JMP BDOS MAKEFIL: MVI C,MAKE CALL BDOS CPI 0FFH RNZ LXI H,ERMSG3 CALL MSGOUT JMP SYSTEM SEL$SRC$DRV: LDA OPTSRC CALL SEL$DRV RET L026C: LDA OPTPRN CPI 'Z'-'A' ;NO FILE OPTION RZ CPI 'X'-'A' ;LIST AT CONSOL OPT RET SEL$PRN: LDA OPTPRN CALL SEL$DRV RET SEL$OBJ: LDA OPTOBJ CALL SEL$DRV RET ********************************** * ASSEMBLY PROCESSING ********************************** ASSEMBLE: LXI H,0 DAD SP SHLD CCP$SP LXI SP,IBUFR LXI H,STITLE CALL MSGOUT ;WRITE ASM VERSION TO CONS. LDA TFCB+1 CPI ' ' ;FILENAME THERE? JZ ER04 ;NO, SOURCE NAME ERROR MVI C,RTCUDSK CALL BDOS STA DFALDRV ;SAVE DEFAULT DRIVE OPTION LXI H,L0064 ;POINT TO SOURCE DRIVE OPTION CALL OPT$TRAN ;TRANSLATE SOURCE OPTION STA OPTSRC ;SAVE SOURCE OPTION CALL OPT$TRAN ;TRANSLATE OBJECT OPTION STA OPTOBJ ;SAVE OBJECT OPTION CALL OPT$TRAN ;TRANSLATE PRINT OPTION STA OPTPRN ;SAVE PRINT OPTION LXI H,SRCFCB CALL MOVNAM ;SET UP SOURCE FCB LXI H,PRNFCB CALL MOVNAM ;SET UP PRN FCB CALL L026C JZ L02D5 ;BR IF NO PRN FILE OPTION CALL SEL$PRN ;SELECT PRN FILE DISK LXI D,PRNFCB ;POINT TO FCB CALL DEL$FIL ;DELETE OLD PRN FILE LXI D,PRNFCB CALL MAKEFIL ;OPEN NEW PRN FILE. L02D5: LDA OPTOBJ CPI 'Z'-'A' JZ MAIN ;BR IF NO FILE OPTION LXI H,OBJFCB PUSH H PUSH H CALL MOVNAM CALL SEL$OBJ ;SELECT OBJ DISK POP D CALL DEL$FIL ;KILL OLD OBJECT POP D CALL MAKEFIL ;OPEN NEW OBJECT JMP MAIN ;JUMP TO PASS 1. RESET$SRC: LXI H,01000H ;RESET IBUF POINTER SHLD IBUF$CTR XRA A STA SRC$EXT ;RESET EXTENT STA SRC$CR ;RESET CURRENT RECORD # CALL SEL$SRC$DRV ;SELECT DRIVE LXI D,SRCFCB CALL OPENFIL ;OPEN FILE RET ER04: ; SOURCE NAME ERROR LXI H,ERMSG4 CALL MSGOUT JMP SYSTEM SYSTEM: ;RETURN TO CCP LHLD CCP$SP SPHL RET CMP$LIM: MOV A,D CMP H RNZ MOV A,E CMP L RET *************************************** * GET INPUT CHARACTER FROM DISK *************************************** DSK$IN: PUSH B PUSH D PUSH H LHLD IBUF$CTR ;HAVE WE FINISHED THIS BUFFER LXI D,01000H CALL CMP$LIM JNZ DSK$IN$05 ;BR IF NOT. CALL SEL$SRC$DRV ;YES, SELECT DSK LXI H,0 SHLD IBUF$CTR MVI B,32 ;RESET BUF PTR (32 SECTORS) LXI H,IBUFR DSK$IN$01: PUSH B PUSH H MVI C,READ LXI D,SRCFCB ;READ A SECTOR CALL BDOS POP H POP B ORA A MVI C,80H JNZ DSK$IN$03 ;BR IF EOF LXI D,TBUFF MVI C,80H ;SET CHAR COUNT DSK$IN$02: LDAX D ;MOVE DATA FROM TBUFF TO IBUFR MOV M,A INX D INX H DCR C ;DECR CHAR CTR JNZ DSK$IN$02 DCR B ;DECR SECTOR CTR JNZ DSK$IN$01 JMP DSK$IN$05 DSK$IN$03: CPI 3 ; ETX CHAR? JNC ER05 DSK$IN$04: MVI M,EOF ;WRITE EOFS SECTOR FILL INX H DCR C JNZ DSK$IN$04 DSK$IN$05: LXI D,IBUFR LHLD IBUF$CTR PUSH H INX H SHLD IBUF$CTR POP H DAD D MOV A,M ;THIS IS THE CHARACTER..... PUSH PSW CPI LF ; IS IT A LF? CZ INC$LINE$NM ;YES, INCR LINE NUMBER. POP PSW POP H POP D POP B RET ER05: LXI H,ERMSG5 ;SOURCE FILE READ ERROR CALL MSGOUT JMP SYSTEM *************************************** * PRINT * The following routines handle the listing * operations. *************************************** PRINT$00: PUSH B MOV B,A LDA OPTPRN CPI 'Z'-'A' ;NO FILE OPTION JZ PRINT$03 CPI 'X'-'A' ;LIST AT CONSOL OPT MOV A,B JNZ PRINT$02 CALL CO JMP PRINT$03 PRINT$01: PUSH B PRINT$02: PUSH D PUSH H CALL PRINT$04 POP H POP D PRINT$03: POP B RET PRINT$04: LHLD PRN$BUF$PTR XCHG LXI H,PRN$BUFR DAD D MOV M,A XCHG INX H SHLD PRN$BUF$PTR XCHG LXI H,0400H CALL CMP$LIM RNZ CALL SEL$PRN LXI H,0 SHLD PRN$BUF$PTR LXI H,PRN$BUFR LXI D,PRNFCB MVI B,8 PRINT$05: MOV A,M CPI EOF RZ PUSH B PUSH D MVI C,80H LXI D,TBUFF PRINT$06: MOV A,M STAX D INX H INX D DCR C JNZ PRINT$06 POP D PUSH D PUSH H MVI C,WRITE CALL BDOS POP H POP D POP B ORA A JNZ OUT$FIL$ERR DCR B RZ JMP PRINT$05 OUT$FIL$ERR: LXI H,ERMSG6 CALL MSGOUT JMP CLOSE$04 *************************************** * OBJECT OUT *************************************** OBJ$OUT$00: PUSH B PUSH D PUSH H CALL OBJ$OUT$02 POP H POP D POP B RET OBJ$OUT$02: LHLD OBJ$BUF$PTR XCHG LXI H,OBJ$BUFR DAD D MOV M,A XCHG INX H SHLD OBJ$BUF$PTR XCHG LXI H,0400H CALL CMP$LIM RNZ CALL SEL$OBJ LXI H,0 SHLD OBJ$BUF$PTR LXI H,OBJ$BUFR LXI D,OBJFCB MVI B,8 JMP PRINT$05 *************************************** * CONSOL OUT *************************************** CO: PUSH B PUSH D PUSH H MVI C,WRCON MOV E,A CALL BDOS POP H POP D POP B RET *************************************** * SEND PRN CHARACTER TO LIST DEVICE *************************************** PRN$CHR: MOV C,A CALL PRINT$00 LDA PRN$LINE CPI ' ' RZ LDA OPTPRN CPI 'X'-'A' ;LIST AT CONSOLE OPT RZ MOV A,C CALL CO RET *************************************** * PRINT MESSAGE TO LIST DEVICE *************************************** PRN$MSG$00: LDA PRN$CHR$CT LXI H,PRN$LINE PRN$MSG$01: ORA A JZ PRN$MSG$02 ;IF CTR 0, OUTPUT CRLF MOV B,A PUSH B MVI B,8 ;OUTPUT LINE NUMBER LXI H,LINE$NUM PRN$MSG$01A: MOV A,M CALL PRN$CHR INX H DCR B JNZ PRN$MSG$01A LXI H,PRN$LINE POP B PRN$MSG$01B: MOV A,M ; ELSE OUTPUT MSG CHAR. CALL PRN$CHR INX H DCR B JNZ PRN$MSG$01B XRA A PRN$MSG$02: STA PRN$CHR$CT CALL HEADER ;PRINT HEADER IF REQ. LXI H,PRN$LINE MVI A,78H PRN$MSG$03: MVI M,' ' ;NOW SETUP BLANK LINE. INX H DCR A JNZ PRN$MSG$03 RET ERR$COD: MOV B,A LXI H,PRN$LINE MOV A,M CPI ' ' RNZ MOV M,B RET *************************************** * HEADER OUTPUT *************************************** HEADER: MVI A,CR CALL PRN$CHR MVI A,LF ;OUTPUT LINE FEED CALL PRN$CHR LDA PASS$NM ORA A RZ LXI H,LIN$PAG$CT ;INCREMENT LINES-PAGE COUNTER MOV A,M INR M CPI 55 ;LIMIT IS 55 LINES RC MVI M,0 ;RESET COUNTER IF OVER LXI H,PAGE$BUF+8 HEADER$00: MOV A,M ;INCREMENT PAGE COUNTER ORI '0' INR A MOV M,A CPI ':' JC HEADER$02 ;NOW PRINT HEADER MVI M,'0' DCX H JMP HEADER$00 HEADER$01: MVI A,LF ;OUTPUT LINE FEED CALL PRN$CHR RET ;EXIT HEADER$02: MVI A,12 ;SEND FORM FEED CALL PRN$CHR LXI H,STITLE ;NOW PRINT HEADER HEADER$03: MOV A,M ;GET CHAR ORA A ;SKIP IF 0 JZ HEADER$04 PUSH H CALL PRN$CHR ;OUTPUT CHARACTER POP H MOV A,M HEADER$04: INX H CPI CR ;WAS THAT A CR. JNZ HEADER$03 MVI A,LF CALL PRN$CHR JMP HEADER$01 *************************************** * CLOSING OPERATIONS *************************************** CLOSE$00: CALL SORT$SYM LDA OPTPRN CPI 'Z'-'A' JZ CLOSE$02 ;NOT PRINTING ANYWHERE CALL PRN$REFS CALL L026C JZ CLOSE$02 ;NOT PRINTING TO FILE CLOSE$01: LHLD PRN$BUF$PTR ;RUN OUT PRN. MOV A,L ORA H JZ CLOSE$02 MVI A,EOF CALL PRINT$00 JMP CLOSE$01 CLOSE$02: LDA OPTOBJ CPI 'Z'-'A' ;NO FILE OPTION JZ CLOSE$04 LDA OBJ$BYTE$CNT ORA A CNZ OBJ$LINE$00 LHLD LOC$CTR1 SHLD OBJ$LINE$LOC CALL OBJ$LINE$00 CLOSE$03: LHLD OBJ$BUF$PTR ;RUN OUT OBJ. MOV A,L ORA H JZ CLOSE$04 MVI A,EOF CALL OBJ$OUT$00 JMP CLOSE$03 CLOSE$04: ;CLOSE PRN FILE. CALL L026C JZ CLOSE$05 CALL SEL$PRN LXI D,PRNFCB CALL CLOSFIL CLOSE$05: LDA OPTOBJ CPI 'Z'-'A' ;NO FILE OPTION JZ END$MSG$OUT CALL SEL$OBJ LXI D,OBJFCB CALL CLOSFIL ;CLOSE OBJ FILE. CLOSE$06: ;BUILD SYMBOL FILE LDA FLAG$BYT ANI SYMF ;SYM FILE? JZ END$MSG$OUT ;BR IF NOT LXI H,PRNFCB+9 LXI D,SYM$EXT ;COPY SYM EXTENSION TO MVI B,3 ;PRN FCB CALL L021F LDA OPTOBJ STA OPTPRN ;SET PRN FILE TO OBJ FILE LDA OBJFCB STA PRNFCB ;AND DRIVE XRA A STA PRNFCB+12 STA PRNFCB+32 CALL SEL$PRN LXI D,PRNFCB PUSH D CALL DEL$FIL ;DEL OLD SYM FILE POP D CALL MAKEFIL ;MAKE NEW SYM FILE LXI H,0 SHLD PRN$BUF$PTR LXI H,SYM$MSG CALL MSGOUT CALL L0585 JMP END$MSG$OUT *************************************** END$MSG$OUT: LXI H,END$ASSY$MSG CALL MSGOUT JMP SYSTEM *************************************** * SET UP SYMBOL TABLE FOR PRINTING * SORT ON FIRST CHAR BY FORMING LINKED * LIST. *************************************** SORT$SYM: LDA FLAG$BYT ANI XREFF+SYMF ;NEED SORT? RZ ;RET IF NOT MVI B,'A' LXI D,SYM$LINK$ORG ;INIT LINK POINTER SORT$S$00: CALL SORT$S$01 INR B MOV A,B CPI 'Z'+1 JNZ SORT$S$00 XRA A ;DONE, CLEAR END LINK. STAX D INX D STAX D RET SORT$S$01: LXI H,SYM$TAB SORT$S$02: CALL SORT$S$03 ;TRY FOR MATCH CHAR. RC ;LIST PASS DONE CZ SORT$S$04 ;FOUND A MATCH CALL SORT$S$06 ;BUMP TO NEXT JMP SORT$S$02 ;GO AGAIN SORT$S$03: LDA SYMTAB$PTR SUB L LDA SYMTAB$PTR+1 SBB H RC MOV A,M ANI 0FH MOV C,A ;SYMBOL SIZE SAVED INX H MOV A,M ;1ST CHAR OF SYMBOL SUB B ;SUBTRACT PASS CHARACTER ORA A RET SORT$S$04: MOV A,D ORA E JZ SORT$S$05 ;DONT UNDERSTAND WHY THIS??? DCX H MOV A,L STAX D ;WRITE LINK. INX D MOV A,H STAX D INX H SORT$S$05: PUSH H CALL SORT$S$07 MOV D,H ;UPDATE LINK POINTER MOV E,L POP H RET SORT$S$06: CALL SORT$S$07 INX H ;SKIP W1,W2 SYM RECORD (POINTER) INX H RET SORT$S$07: MOV A,B ;SAVE B. MVI B,0 DAD B ;ADD SIZE MOV B,A INX H ;AND BUMP TO NEXT RECORD. INX H INX H INX H INX H RET *************************************** * BUILD SYMBOL TABLE FILE *************************************** L0585: LHLD SYM$LINK$ORG LXI B,0 L0588: MOV A,H ORA L JZ CLOS$SYM$PRN ;EXIT IF DONE MOV A,M ANI 0FH MOV E,A ;GET SYMBOL SIZE MVI D,0 INX H PUSH H DAD D ;ADD SIZE INX H MOV C,M ;GET SYMBOL VALUE INX H MOV A,M CALL PRN$HEX ;PRINT UPPER MOV A,C CALL PRN$HEX ;PRINT LOWER CALL PRN$SPACE ;PRINT SPACE POP H ;RESTORE SYM ADDR INR E ;INCR SIZE PUSH D ;SAVE SIZE L05A6: MOV A,M CALL PRINT$01 ;PRINT THE SYMBOL INX H DCR E JNZ L05A6 POP D ;RESTORE SIZE MOV A,B CPI 4 JNC PT1 ;END LINE ; LESS THAN 5 ITEMS INR B MVI A,TAB CALL PRINT$01 MOV A,E CPI 3 JNC PT3 MVI A,TAB CALL PRINT$01 PT3: MOV A,E CPI 11 ;IF SYMBOL TOO LARGE,TABOUT. JC PT2 INR B MVI A,TAB CALL PRINT$01 ; PT2: INX H INX H INX H INX H MOV A,M INX H MOV H,M MOV L,A JMP L0588 ; PT1: MVI B,0 MVI A,CR CALL PRINT$01 MVI A,LF CALL PRINT$01 JMP PT2 *************************************** * PRINT SPACE *************************************** PRN$SPACE: MVI A,' ' JMP PRINT$01 *************************************** * CLOSE SYMBOL FILE *************************************** CLOS$SYM$PRN: LHLD PRN$BUF$PTR MOV A,L ORA H JZ CLOS$SYM$01 MVI A,EOF CALL PRINT$01 JMP CLOS$SYM$PRN CLOS$SYM$01: CALL SEL$PRN LXI D,PRNFCB CALL CLOSFIL RET *************************************** * PRINT TWO HEX CHARACTERS *************************************** PRN$HEX: PUSH PSW RAR RAR RAR RAR CALL PRN$HEX$01 POP PSW PRN$HEX$01: ANI 0FH ADI 90H DAA ACI '@' DAA JMP PRINT$01 PRINT$HEX: PUSH PSW RAR RAR RAR RAR CALL PRINT$HEX$01 POP PSW PRINT$HEX$01: ANI 0FH ADI 90H DAA ACI '@' DAA JMP PRINT$00 SYM$LINK$ORG: DW 0 *************************************** * PRINT CROSS REFERENCES *************************************** SYM$LST$PTR: DW 0 SYM$LINE: DW 0 PRN$REFS: LDA FLAG$BYT ANI XREFF ;XREF? RZ ;RET IF NOT CALL HEADER$02 ;PRINT HEADER LXI H,XREF$MSG CALL HEADER$03 LHLD SYM$LINK$ORG ;INIT LIST POINTER SHLD SYM$LST$PTR LXI H,LIN$PAG$CT MVI A,2 MOV M,A CALL HEADER PREF$00: CALL PREF$10 ;GET SYMBOL AND PRINT IT. RZ ;NONE FOUND CALL PREF$30 ;PRINT XREFS CALL HEADER JMP PREF$00 *************************************** * SYMBOL PRINT *************************************** PREF$10: LHLD SYM$LST$PTR ;LOAD SYMBOL LIST POINTER MOV A,H ORA L RZ MOV A,M ;LOAD SIZE ANI 0FH INR A MOV B,A PUSH B ;SAVE SIZE PREF$11: INX H MOV A,M ;PRINT SYMBOL CALL PRINT$00 DCR B JNZ PREF$11 INX H POP B ;RESTORE SIZE MOV A,B CPI 8 JNC PREF$12 MVI A,TAB CALL PRINT$00 ;TAB TO 8TH POSITION PREF$12: MVI A,TAB CALL PRINT$00 ;TAB TO 16TH POSITION INX H ;SKIP VALUE INX H MOV A,M ;OUTPUT LINE # MOV D,A CALL PRINT$HEX INX H MOV A,M MOV E,A CALL PRINT$HEX XCHG SHLD SYM$LINE ;LOAD LINE XCHG INX H MOV A,M INX H MOV H,M MOV L,A SHLD SYM$LST$PTR MVI A,TAB CALL PRINT$00 XRA A INR A RET *************************************** * PRINT XREFS *************************************** PREF$30: LHLD XREF$PTR LXI D,4 DAD D MVI B,7 ;SET ITEMS PER LINE PREF$31: CALL PREF$34 ;ARE WE DONE RC CALL PREF$32 ;TRY FOR MATCH JNZ PREF$31 ;BR IF NO MATCH CALL PREF$33 ;PRINT FOUND REF. JMP PREF$31 PREF$32: LDA SYM$LINE+1 CMP M JNZ PREF$320 INX H LDA SYM$LINE CMP M DCX H RZ PREF$320: INX H INX H INX H INX H RET *************************************** * PRINT FOUND REFERENCE *************************************** PREF$33: INX H INX H MOV A,M CALL PRINT$HEX INX H MOV A,M CALL PRINT$HEX INX H MVI A,TAB CALL PRINT$00 DCR B RNZ ; #################### PUSH H CALL HEADER POP H ; #################### MVI B,7 ; RESTORE XREF / LINE MVI A,TAB CALL PRINT$00 MVI A,TAB CALL PRINT$00 MVI A,TAB CALL PRINT$00 RET PREF$34: XCHG LHLD CCP$BEGIN DCX H DCX H DCX H DCX H DCX H MOV A,L SUB E MOV A,H SBB D XCHG RET *************************************** * MISCELLANEOUS MESSAGES *************************************** XREF$MSG: DB 'Cross Referenced Symbol List',CR SYM$MSG: DB 'Symbols',CR ERMSG1: DB 'No source' ERMSG2: DB ' file present',CR ERMSG3: DB 'No directory space',CR ERMSG4: DB 'Source file name error',CR ERMSG5: DB 'Source file read error',CR ERMSG6: DB 'Output file write error',CR CANT$CLOS$M: DB 'Cannot close files',CR END$ASSY$MSG: DB 'End of assembly',CR