*************************************** * PUT OBJECT IN OBJECT LINE *************************************** PUT$OBJ: PUSH B MOV B,A LDA OPTOBJ ;LOAD OBJECT FILE OPTION CPI 'Z'-'A' ;NO FILE OPTION MOV A,B JZ PUT$OBJ$EX ;NO OPTION,-EXIT. PUSH D PUSH PSW LXI H,OBJ$BYTE$CNT ;GET OBJECT BYTE COUNT MOV A,M ORA A JZ PUT$OBJ$03 CPI 16 ;MAX IS 16 BYTES PER LINE JC PUT$OBJ$01 CALL OBJ$LINE$00 ;OUTPUT LINE TO BUFFER JMP PUT$OBJ$03 ;NOW PUT NEW CHARACTER IN PUT$OBJ$01: LHLD LOC$CTR1 XCHG LHLD OBJ$LINE$LOC MOV C,A ;PUT OFFSET IN C. MVI B,0 DAD B ;ADD OFFSET TO LINE ORG. MOV A,E ;NOW COMPARE LOC COUNTER. CMP L JNZ PUT$OBJ$02 ;IF DIFFERENT, OUTPUT LINE. MOV A,D CMP H JZ PUT$OBJ$04 PUT$OBJ$02: CALL OBJ$LINE$00 ;OUTPUT LINE TO BUFR PUT$OBJ$03: LHLD LOC$CTR1 ;UPDATE LINE LOCATION SHLD OBJ$LINE$LOC PUT$OBJ$04: LXI H,OBJ$BYTE$CNT ;GET OFFSET MOV E,M INR M MVI D,0 LXI H,OBJ$LINE ;ADD TO LINE ORG. DAD D POP PSW MOV M,A ;PUT BYTE IN LINE POP D PUT$OBJ$EX: POP B RET *************************************** * OBJECT BYTE OUTPUT * ADDS CHECKSUM IN REG D *************************************** OBJ$BYTE$OUT: PUSH PSW RRC ; OUTPUT UPPER NIBBLE RRC RRC RRC ANI 0FH CALL OBJ$ASCII$OUT POP PSW PUSH PSW ANI 0FH CALL OBJ$ASCII$OUT ;OUTPUT LOWER NIBBLE POP PSW ADD D MOV D,A RET *************************************** * HEX TO ASCII CONVERSION * WITH OUTPUT TO OBJ. *************************************** OBJ$ASCII$OUT: ADI 90H DAA ACI '@' ;40H DAA JMP OBJ$OUT$00 *************************************** * OUTPUT OBJECT LINE * OUTPUTS TO OBJ$BUFR *************************************** OBJ$LINE$00: MVI A,':' CALL OBJ$OUT$00 ;START NEW LINE LXI H,OBJ$BYTE$CNT MOV E,M XRA A MOV D,A MOV M,A LHLD OBJ$LINE$LOC ;SET LINE LOCATION MOV A,E CALL OBJ$BYTE$OUT ;WRITE BYTE COUNT MOV A,H CALL OBJ$BYTE$OUT ;WRITE LOCATION MOV A,L CALL OBJ$BYTE$OUT ;WRITE LOCATION XRA A CALL OBJ$BYTE$OUT MOV A,E ;GET COUNT ORA A JZ OBJ$LINE$03 ;EXIT IF ZERO LXI H,OBJ$LINE ;POINT TO LINE DATA OBJ$LINE$01: MOV A,M INX H CALL OBJ$BYTE$OUT ;OUTPUT A BYTE DCR E ;DECR BYTE COUNT JNZ OBJ$LINE$01 ;DO ANOTHER IF NOT DONE. OBJ$LINE$03: ;DONE XRA A SUB D CALL OBJ$BYTE$OUT MVI A,CR CALL OBJ$OUT$00 MVI A,LF CALL OBJ$OUT$00 RET *************************************** * READ CHARACTER AND PLACE ONTO PRINT *************************************** L0747: DB 0 ; PRIOR CHARACTER CUR$CHR: DB 0 ; CURRENT (NEXT) RADIX$CHR: DB 0 ; RADIX CHARACTER *************************************** RDCHAR: CALL DSK$IN ; GET CHAR FROM DISK. PUSH PSW CPI CR ;EXIT IF CR JZ RDCHAR$EX CPI LF ; OR LF JZ RDCHAR$EX CPI EOF ; OR EOF JZ RDCHAR$EX LDA PRN$CHR$CT CPI 78H ; MAX LINE LENGTH.(78H=120D) JNC RDCHAR$EX MOV E,A MVI D,0 INR A STA PRN$CHR$CT ;GET LINE OFFSET LXI H,PRN$LINE ;ADD TO ORG,(GETS LOC) DAD D POP PSW MOV M,A ;PUT CHAR RET RDCHAR$EX: POP PSW RET *************************************** * END PRINT LINE IN PRN BUFR. *************************************** PRN$END$LINE: CALL L0787 STA CUR$CHR ;CLEAR CUR CHAR STA PRN$CHR$CT ; AND PRN COUNTER. MVI A,LF STA L0747 CALL PRN$MSG$00 MVI A,12H ;LABEL STARTS AT 16TH CHAR. STA PRN$CHR$CT RET *************************************** L0787: XRA A STA STR$SIZE STA RADIX$CHR RET L078F: LXI H,STR$SIZE MOV A,M CPI 'A'-1 JC L079D MVI M,0 CALL L0963 L079D: MOV E,M MVI D,0 INR M INX H DAD D LDA CUR$CHR MOV M,A RET L07A8: MOV A,M CPI '$' RNZ XRA A MOV M,A RET NUM$C: ;TEST IF NUMBER LDA CUR$CHR SUI '0' ;30H CPI '9'-'0'+1 RAL ANI 1 RET L07BA: CALL NUM$C RNZ LDA CUR$CHR SUI 'A' ;41H CPI 'F'-'A'+1 RAL ANI 1 RET ALPHA$C: LDA CUR$CHR SUI 'A' ;41H CPI 'Z'-'A'+1 RAL ANI 1 RET L07D4: CALL ALPHA$C RNZ CALL NUM$C RET *************************************** * CONVERT SMALL ALPHA TO CAPS *************************************** CON$ALPH: LDA CUR$CHR CPI 61H RC CPI 7BH ;CONVERT SMALL ALPHA TO CAPS. RNC ANI 5FH STA CUR$CHR RET *************************************** * GET CHAR FROM DISK & PUT IN STRING *************************************** GET$STR$CHR: CALL RDCHAR STA CUR$CHR PUSH PSW LDA STR$TYPE CPI 3 CNZ CON$ALPH POP PSW RET LAST$CHR: CPI CR RZ CPI EOF RZ CPI '!' ;21H RET *************************************** * GET STRING. * picks up a string evaluates it for type * and computes value from radix designated. *************************************** GET$STR: XRA A STA STR$TYPE CALL L0787 GS$00: LDA CUR$CHR CPI TAB JZ GS$03 CPI ';' ;COMMENT JZ GS$01 CPI '*' ;2AH JNZ GS$02 LDA L0747 CPI LF JNZ GS$02 GS$01: CALL GET$STR$CHR CALL LAST$CHR JZ GS$04 JMP GS$01 GS$02: ORI ' ' ;TEST FOR BLANK CPI ' ' ;20H JNZ GS$04 GS$03: CALL GET$STR$CHR JMP GS$00 GS$04: CALL ALPHA$C JZ GS$05 MVI A,1 ;CHARACTER TYPE = ALPHA JMP GS$09 GS$05: CALL NUM$C JZ GS$06 MVI A,2 ;CHARACTER TYPE = NUMBER JMP GS$09 GS$06: LDA CUR$CHR CPI '''' ;27H JNZ GS$07 XRA A STA CUR$CHR MVI A,3 ;CHARACTER TYPE = QUOTE JMP GS$09 GS$07: CPI LF JNZ GS$08 ;BR IF END OF LINE LDA PASS$NM ORA A CNZ PRN$MSG$00 LXI H,PRN$LINE MVI M,' ' ;20H MVI A,10H STA PRN$CHR$CT GS$08: MVI A,4 ;CHAR TYPE= OTHER ?? GS$09: STA STR$TYPE GS$10: LDA CUR$CHR STA L0747 ORA A CNZ L078F CALL GET$STR$CHR LDA STR$TYPE CPI 4 RZ CPI 3 CNZ CON$ALPH LXI H,CUR$CHR LDA STR$TYPE CPI 1 JNZ GS$11 CALL L07A8 JZ GS$10 CALL L07D4 RZ JMP GS$10 GS$11: CPI 2 JNZ L0947 CALL L07A8 JZ GS$10 CALL L07BA JNZ GS$10 LDA CUR$CHR CPI 'O' ;RADIX OCTAL 4FH JZ GS$12 CPI 'Q' ;RADIX OCTAL (ALT) 51H JNZ GS$13 GS$12: MVI A,8 JMP GS$14 GS$13: CPI 'H' ;RADIX HEX 48H JNZ GS$15 MVI A,10H GS$14: STA RADIX$CHR XRA A STA CUR$CHR JMP GS$19 GS$15: LDA L0747 CPI 'B' ;RADIX BINARY 42H JNZ GS$16 MVI A,2 JMP GS$17 GS$16: CPI 'D' ;RADIX DECIMAL 44H MVI A,LF JNZ GS$18 GS$17: LXI H,STR$SIZE DCR M GS$18: STA RADIX$CHR GS$19: LXI H,0 SHLD STR$VAL LXI H,STR$SIZE MOV C,M INX H GS$20: MOV A,M ;CONVERT ASCII TO HEX INX H CPI 'A' JNC GS$21 SUI '0' ;30H JMP GS$22 GS$21: SUI '7' ;37H GS$22: ;EVALUATE DIGIT. PUSH H PUSH B MOV C,A LXI H,RADIX$CHR CMP M ;COMPARE RADIX LIMIT CNC L095D MVI B,0 MOV A,M LHLD STR$VAL XCHG LXI H,0 GS$23: ORA A JZ GS$25 RAR JNC GS$24 DAD D GS$24: XCHG DAD H XCHG JMP GS$23 GS$25: DAD B SHLD STR$VAL ;SAVE STRING VALUE 011EH POP B POP H DCR C JNZ GS$20 RET L0947: LDA CUR$CHR CPI CR JZ L0963 CPI '''' ;27H JNZ GS$10 CALL GET$STR$CHR CPI '''' ;27H RNZ JMP GS$10 L095D: PUSH PSW MVI A,'V' ;VALUE ERROR. JMP L0969 L0963: PUSH PSW MVI A,'O' ;OVERFLOW ERROR. JMP L0969 L0969: PUSH B PUSH H CALL ERR$COD POP H POP B POP PSW RET *************************************** * SYMBOL TABLE ROUTINES *************************************** SYM$SUM: NOP CL$SYM$HASH$LST: LXI H,SYM$HASH$LST MVI B,80H XRA A SYM$01: MOV M,A ;CLR 3018 -- 3099 INX H MOV M,A INX H DCR B JNZ SYM$01 LXI H,0 SHLD SYM$HASH$PTR RET *************************************** * COMPUTE SYMBOL CHECKSUM *************************************** CMPUT$SYM$SUM: LXI H,STR$SIZE ;PUT SIZE IN (B) MOV B,M XRA A SYM$03: INX H ADD M ;ADD CHAR VALUE DCR B JNZ SYM$03 ANI 7FH STA SYM$SUM RET *************************************** * UNUSED CODE ???? *************************************** MOV B,A LHLD SYM$HASH$PTR INX H INX H MOV A,M ANI 0F0H ORA B MOV M,A RET *************************************** * START SYMBOL EVALUATION *************************************** SYM$04: LHLD SYM$HASH$PTR INX H INX H MOV A,M ;GET SIZE ANI 0FH INR A RET SYM$05: LHLD SYM$HASH$PTR MOV A,L ORA H RET *************************************** * SEARCH FOR SYMBOL *************************************** SYM$SERCH: CALL CMPUT$SYM$SUM ;COMPUTE ADDRESS KEY LXI H,STR$SIZE MOV A,M CPI 11H JC SYM$07 MVI M,10H SYM$07: LXI H,SYM$SUM ;GET SYM TABLE ADDRESS MOV E,M MVI D,0 LXI H,SYM$HASH$LST DAD D DAD D MOV E,M INX H MOV H,M MOV L,E SYM$08: SHLD SYM$HASH$PTR ;PUT ADDRESS IN POINTER CALL SYM$05 ;IS ADDRESS USED? RZ ; RETURN IF EMPTY CALL SYM$04 ;GET SYM SIZE LXI H,STR$SIZE ;AND COMPARE WITH CURRENT CMP M JNZ SYM$10 ;BR IF NOT EQUAL MOV B,A INX H XCHG LHLD SYM$HASH$PTR INX H INX H INX H SYM$09: LDAX D ;COMPARE SYMBOL TO NEW STRING CMP M JNZ SYM$10 ;NOT MATCHED INX D INX H DCR B JNZ SYM$09 RET ;RETURN IF MATCHED SYM$10: LHLD SYM$HASH$PTR ;SET UP ANOTHER ADDRESS MOV E,M INX H MOV D,M XCHG JMP SYM$08 *************************************** * POST NEW ENTRY TO SYMBOL TABLE *************************************** POST$SYM: LXI H,STR$SIZE ;MOVE SIZE TO (DE) MOV E,M MVI D,0 LHLD SYMTAB$PTR ;CHECK FOR TABLE OVERFLOW. SHLD SYM$HASH$PTR DAD D LXI D,7 DAD D XCHG LHLD CCP$BEGIN ;CHECK FOR END MEM MOV A,E SUB L MOV A,D SBB H SYM$12: XCHG JNC SYM$15 ;EXIT IF OVERFLOW SHLD SYMTAB$PTR ;UPDATE SYM TABLE POINTER LHLD SYM$HASH$PTR ;RESTORE CURRENT LOCATION XCHG LXI H,SYM$SUM MOV C,M ;PUT SYM$SUM IN (BC) MVI B,0 LXI H,SYM$HASH$LST ;COMPUTE AN ADDRESS DAD B DAD B MOV C,M ;GET EXISTING LINK IF ANY INX H MOV B,M MOV M,D ;PUT NEW LINK HERE DCX H MOV M,E XCHG ;RESTORE SYM TABLE ADDR. MOV M,C ;PUT OLD LINK (IF ANY) HERE) INX H MOV M,B LXI D,STR$SIZE ;GET SIZE LDAX D CPI 11H JC SYM$13 MVI A,10H ;TRUNCATE IF OVERSIZE SYM$13: MOV B,A DCR A INX H MOV M,A ;NOW MOVE SIZE TO SYM TABLE SYM$14: INX H ;AND MOVE SYMBOL IN TO TABLE INX D LDAX D MOV M,A DCR B JNZ SYM$14 XRA A ;CLEAR SPACE FOR VALUE INX H MOV M,A INX H MOV M,A INX H MOV M,A INX H MOV M,A RET SYM$15: LXI H,SYM$16 CALL MSGOUT JMP CLOSE$00 SYM$16: DB 'Symbol table overflow',CR SYM$17: RAL RAL RAL RAL ANI 0F0H MOV B,A LHLD SYM$HASH$PTR INX H INX H MOV A,M ANI 0FH ORA B MOV M,A ;WRITE CONTROL TO SYM TABLE RET SYM$18: LHLD SYM$HASH$PTR INX H INX H MOV A,M RAR RAR RAR RAR ANI 0FH RET SYM$19: CALL SYM$04 LHLD SYM$HASH$PTR MOV E,A MVI D,0 DAD D INX H INX H INX H RET *************************************** * SYMBOL TABLE FORMAT * LENGTH OF EACH ENTRY = SYMBOL LENGTH + 5 * FORMAT * W1 - LINK ADDRESS (IF ANY) * W2 - " " " * W3 - TYPE,LENGTH-1 * W4-WN SYMBOL * WN+1 VALUE * WN+2 VALUE * WN+3 LINE # | IN BCD * WN+4 LINE # | 0 - 9999 *************************************** PUT$SYM$VAL: PUSH H CALL SYM$19 POP D MOV M,E INX H MOV M,D * LOAD BCD LINE NUMBER INTO SYMBOL TABLE PUSH H PUSH B INX H LXI B,LINE$NM LDAX B MOV M,A INX H INX B LDAX B MOV M,A POP B POP H RET GET$SYM$VAL: CALL SYM$19 MOV E,M INX H MOV D,M XCHG RET