; Digital Research ASM assembler ; disassembled by Larry A. Greene ; got any comments or suggestions? ; send to greenela@clear.lakes.com ; using command ASM TEST.ABC will assemble TEST.ASM with drive designations ; following period. A=ASM file drive, B=HEX file drive, C=SYM file drive ORG 0100H H0000 EQU 0000H ; Cold re-entry to system H0005 EQU 0005H ; BDOS H005C EQU 005CH ; FCB H0080 EQU 0080H ; DMA LXI SP,H0200 ; Set stack LHLD H0005+1 SHLD H01CD ; Set end of memory = BDOS base JMP H0200 H010C: DB ' ' ; 120 byte line buffer for PRN output H010D: DB 'C' ; If H010C is non-space then contains error code: ; B = unknown ; C = comma missing ; D = not an 8 bit value for DB label expression ; E = bad register syntax ; L = bad mnemonic ; N = function not supported ; O = unknown (some form of syntax error) ; P = duplicate label or phase error ; R = wrong register ; S = syntax error ; U = unclained label ; V = bad value H010E: DB 'OPY' H0111: DB 'R' H0112: DB 'IGHT(C) 1978, DIGITAL RESEARCH ' DS 53H H0184: DS 01H ; Index into H010C PRN buffer H0185: DS 01H ; Char type. 4=EOL 3=literal 2=digit 1=alpha H0186: DS 02H ; Holds value of numeric expression from H1106 call H0188: DS 01H ; Index into H0189 ASM buffer H0189: DS 01H ; 64 byte ASM line buffer H018A: DS 01H H018B: DS 3EH H01C9: DS 02H H01CB: DW H20F0 ; Contains end of symbol table H01CD: DS 02H ; Contains BDOS base (end of memory space) H01CF: DS 01H ; Assembly pass count 0=build symbol table 1=table done H01D0: DS 02H ; Address counter (for HEX file also) H01D2: DS 02H ; Address printed at start of line in PRN file H01D4: DW H20F0 ; Start of symbol table (fixed) H01D6: DS 2AH ; Stack space below H0200 H0200: JMP H0CE0 ; Cold start H0203: JMP H0DA1 ; Open ASM file H0206: JMP H0DCA ; Get char from H029D ASM file buffer. ; Reads disk as needed. JMP H0E34 ; Write byte in ACC reg to PRN file. all regs preserved JMP H0EAA ; Write ACC reg to HEX file (direct - after processed) JMP H0EDE ; Write ACC reg to console H0212: JMP H0CBC ; Print string at (HL). terminates with cr H0215: JMP H0F00 ; Print H010C line buffer to PRN file w/echo to console H0218: JMP H0F2F ; Put error code from ACC reg into H010C flag H021B: JMP H104C ; Write byte in ACC reg to HEX file in ASCII form H021E: JMP H0F39 ; Close files and exit H0221: DS 02H ; HEX file pointer (base address of line) H0223: DS 01H ; Index into line of H0224 H0224: DS 10H ; Obj code line buffer for PRN and HEX use H0234: DS 01H ; Current disk H0235: DS 01H ; ASM file drive designation H0236: DS 01H ; PRN file drive designation H0237: DS 01H ; HEX file drive designation H0238: DS 9 ; ASM filename DB 'ASM' H0244: DS 14H H0258: DS 01H ; PRN filename H0259: DS 9 DB 'PRN' DS 15H H027A: DS 9 ; HEX filename DB 'HEX' DS 15H H029B: DS 02H ; Index into H029D buffer H029D: DS 400H ; Buffer for ASM file read H069D: DS 02H ; Index into H069F buffer H069F: DS 300H ; Buffer for PRN file write H099F: DS 02H ; Index into H09A1 buffer H09A1: DS 300H ; Buffer for HEX file write H0CA1: LXI H,H0234 ; Select drive in ACC reg and make it the current drive CMP M RZ MOV M,A MOV E,A MVI C,0EH CALL H0005 RET H0CAE: INX H MOV A,M CPI 20H JZ H0CB8 SBI 41H RET H0CB8: LDA H0234 RET H0CBC: MOV A,M ; Print string at (HL). terminate w/cr CALL H0EDE MOV A,M INX H CPI 0DH JNZ H0CBC MVI A,0AH CALL H0EDE RET H0CCD: LXI D,H005C ; Move 9 bytes from FCB to (HL) MVI B,09H ; Error exit if '?' found H0CD2: LDAX D CPI 3FH JZ H0DBB MOV M,A INX H INX D DCR B JNZ H0CD2 RET H0CE0: LXI H,H0FA0 ; Cold start CALL H0CBC ; Print title JMP H0D3F H0CE9: MVI C,0FH ; Open file CALL H0005 CPI 0FFH RNZ LXI H,H0FB9 CALL H0CBC JMP H0000 H0CFA: MVI C,10H ; Close file CALL H0005 CPI 0FFH RNZ LXI H,H1029 CALL H0CBC JMP H0000 H0D0B: MVI C,13H ; Delete file. (DE) = FCB JMP H0005 H0D10: MVI C,16H ; Make file. (DE) = FCB CALL H0005 ; Error exit if disk full CPI 0FFH RNZ LXI H,H0FD0 CALL H0CBC JMP H0000 H0D21: LDA H0235 ; Select ASM file drive CALL H0CA1 RET H0D28: LDA H0236 CPI 19H RZ CPI 17H RET H0D31: LDA H0236 ; Select PRN file drive CALL H0CA1 RET H0D38: LDA H0237 ; Select HEX file drive CALL H0CA1 RET H0D3F: LDA H005C ; Drive designation CPI 20H JZ H0DBB ; Error exit MVI C,19H CALL H0005 ; Get current disk STA H0234 LXI H,0064H ; Get optional drive designations following '.' CALL H0CAE ; After filename else use current drive STA H0235 CALL H0CAE STA H0237 CALL H0CAE STA H0236 LXI H,H0238 ; ASM filename CALL H0CCD ; Move filename CALL H0D28 JZ H0D83 LXI H,H0259 PUSH H PUSH H CALL H0CCD CALL H0D31 ; Select PRN file drive POP D CALL H0D0B ; Delete old PRN file POP D CALL H0D10 ; Make new PRN file H0D83: LDA H0237 CPI 19H JZ H0D9E LXI H,H027A PUSH H PUSH H CALL H0CCD CALL H0D38 ; Select HEX file drive POP D CALL H0D0B ; Delete old HEX file POP D CALL H0D10 ; Make new HEX file H0D9E: JMP H1100 ; Enter assembler with HEX and PRN files open H0DA1: LXI H,0400H ; Open ASM file. force reading of first byte SHLD H029B ; Of ASM file by setting index to EOF XRA A STA H0244 STA H0258 STA H0223 CALL H0D21 LXI D,H0238 CALL H0CE9 RET H0DBB: LXI H,H0FE3 ; 'source filename error' exit CALL H0CBC JMP H0000 H0DC4: MOV A,D CMP H RNZ MOV A,E CMP L RET H0DCA: PUSH B ; Get char from ASM file PUSH D PUSH H LHLD H029B LXI D,0400H CALL H0DC4 JNZ H0E19 CALL H0D21 LXI H,0000H SHLD H029B MVI B,08H LXI H,H029D H0DE7: PUSH B PUSH H MVI C,14H LXI D,H0238 CALL H0005 POP H POP B ORA A MVI C,80H JNZ H0E0D LXI D,H0080 MVI C,80H ; Extra code not needed (see 3 lines previous) H0DFE: LDAX D MOV M,A INX D INX H DCR C JNZ H0DFE DCR B JNZ H0DE7 JMP H0E19 H0E0D: CPI 03H JNC H0E2B H0E12: MVI M,1AH INX H DCR C JNZ H0E12 H0E19: LXI D,H029D LHLD H029B PUSH H INX H SHLD H029B POP H DAD D MOV A,M POP H POP D POP B RET H0E2B: LXI H,H0FFA ; 'source file read error' exit CALL H0CBC JMP H0000 H0E34: PUSH B ; Output char in ACC reg to PRN designation: MOV B,A ; Z = null, X = console, else to H069F buffer LDA H0236 ; And write to disk as needed CPI 19H ; 'Z' JZ H0E51 CPI 17H ; 'X' MOV A,B JNZ H0E4A CALL H0EDE ; Write to console JMP H0E51 H0E4A: PUSH D PUSH H CALL H0E53 POP H POP D H0E51: POP B RET H0E53: LHLD H069D ; Write byte to PRN file XCHG LXI H,H069F DAD D MOV M,A XCHG INX H SHLD H069D XCHG LXI H,0300H CALL H0DC4 RNZ CALL H0D31 LXI H,0000H SHLD H069D LXI H,H069F LXI D,H0259 MVI B,06H ; 6 times 80H = 300H H0E7A: MOV A,M ; Write HEX file comes here CPI 1AH RZ PUSH B PUSH D MVI C,80H LXI D,H0080 H0E85: MOV A,M STAX D INX H INX D DCR C JNZ H0E85 POP D PUSH D PUSH H MVI C,15H ; Write sequential CALL H0005 POP H POP D POP B ORA A JNZ H0EA1 DCR B RZ JMP H0E7A H0EA1: LXI H,H1011 CALL H0CBC JMP H0F77 H0EAA: PUSH B ; Write ACC to HEX file with disk buffering PUSH D PUSH H CALL H0EB4 POP H POP D POP B RET H0EB4: LHLD H099F XCHG LXI H,H09A1 DAD D MOV M,A XCHG INX H SHLD H099F XCHG LXI H,0300H CALL H0DC4 ; Compare DE and HL - buffer full? RNZ ; No CALL H0D38 ; Select HEX file drive LXI H,0000H SHLD H099F LXI H,H09A1 LXI D,H027A MVI B,06H JMP H0E7A H0EDE: PUSH B ; Write ACC reg to console PUSH D PUSH H MVI C,02H MOV E,A CALL H0005 POP H POP D POP B RET H0EEB: MOV C,A ; Write ACC reg to PRN designation. echo error CALL H0E34 ; To console if H010C is non-space LDA H010C CPI 20H RZ LDA H0236 CPI 17H RZ MOV A,C CALL H0EDE ; Echo to console RET H0F00: LDA H0184 ; Print H010C line buffer to PRN file with LXI H,H010C ; Echo to console. H0184 = # of chars in line H0F06: ORA A JZ H0F15 MOV B,A MOV A,M CALL H0EEB ; Write byte w/echo INX H MOV A,B DCR A JMP H0F06 H0F15: STA H0184 ; Write CR to PRN file then clear line buffer MVI A,0DH CALL H0EEB MVI A,0AH CALL H0EEB LXI H,H010C MVI A,78H H0F27: MVI M,20H INX H DCR A JNZ H0F27 RET H0F2F: MOV B,A LXI H,H010C MOV A,M CPI 20H RNZ MOV M,B RET H0F39: CALL H0D28 ; Close files and exit JZ H0F4F ; Taken if no PRN file designated H0F3F: LHLD H069D MOV A,L ORA H JZ H0F4F MVI A,1AH ; Fill to end of buffer with ctrl-Z CALL H0E34 JMP H0F3F H0F4F: LDA H0237 CPI 19H JZ H0F77 ; Taken if no HEX file designated LDA H0223 ; Index ORA A CNZ H10B8 ; Write final line to HEX file LHLD H01D0 SHLD H0221 CALL H10B8 ; Write EOF address as data H0F67: LHLD H099F MOV A,L ORA H JZ H0F77 MVI A,1AH CALL H0EAA JMP H0F67 H0F77: CALL H0D28 ; Error in writing PRN or HEX file comes here JZ H0F86 ; Taken if no PRN file designation CALL H0D31 ; Select PRN file drive LXI D,H0259 CALL H0CFA ; Close PRN file H0F86: LDA H0237 ; Check HEX designation CPI 19H JZ H0F97 ; Taken if no HEX file designation CALL H0D38 ; Select HEX file drive LXI D,H027A CALL H0CFA ; Close HEX file H0F97: LXI H,H103C CALL H0CBC JMP H0000 H0FA0: DB 'CP/M ASSEMBLER - VER 2.0' DB 0DH H0FB9: DB 'NO SOURCE FILE PRESENT' DB 0DH H0FD0: DB 'NO DIRECTORY SPACE' DB 0DH H0FE3: DB 'SOURCE FILE NAME ERROR' DB 0DH H0FFA: DB 'SOURCE FILE READ ERROR' DB 0DH H1011: DB 'OUTPUT FILE WRITE ERROR' DB 0DH H1029: DB 'CANNOT CLOSE FILES' DB 0DH H103C: DB 'END OF ASSEMBLY' DB 0DH H104C: PUSH B ; Write ACC reg to HEX file MOV B,A LDA H0237 CPI 19H MOV A,B JZ H1098 PUSH D PUSH PSW LXI H,H0223 MOV A,M ORA A JZ H1084 CPI 10H JC H106C CALL H10B8 ; Write complete line to HEX file. H0221 = addr JMP H1084 H106C: LHLD H01D0 XCHG LHLD H0221 ; If (H0221) + ACC = (H01D0) then jump to H108A MOV C,A ; Else H1081 MVI B,00H DAD B MOV A,E CMP L JNZ H1081 MOV A,D CMP H JZ H108A H1081: CALL H10B8 ; Write complete line to HEX file H1084: LHLD H01D0 SHLD H0221 H108A: LXI H,H0223 ; Write ACC reg to H0224 obj buffer and MOV E,M ; Increment H0223 index INR M MVI D,00H LXI H,H0224 DAD D POP PSW MOV M,A POP D H1098: POP B RET H109A: PUSH PSW ; Write ACC reg to HEX file in HEX ASCII form RRC RRC RRC RRC ANI 0FH CALL H10AF POP PSW PUSH PSW ANI 0FH CALL H10AF POP PSW ADD D MOV D,A ; Keep running checksum for Intel HEX form RET H10AF: ADI 90H DAA ACI 40H DAA JMP H0EAA H10B8: MVI A,3AH ; Write complete line to HEX file CALL H0EAA ; Write ACC reg to HEX file LXI H,H0223 MOV E,M ; # of bytes to write XRA A MOV D,A MOV M,A ; Reset index to 0 LHLD H0221 ; Address of line in HEX file MOV A,E CALL H109A MOV A,H ; Write line address CALL H109A MOV A,L CALL H109A XRA A CALL H109A MOV A,E ORA A JZ H10E8 LXI H,H0224 H10DF: MOV A,M INX H CALL H109A DCR E JNZ H10DF H10E8: XRA A SUB D ; Checksum CALL H109A ; Write checksum to HEX file MVI A,0DH CALL H0EAA MVI A,0AH CALL H0EAA RET DB 0,0,0,0,0,0,0,0 H1100: JMP H1340 ; Enter assembler with PRN and HEX files open H1103: JMP H1132 ; Output cr/lf to PRN file (clears line buffer) H1106: JMP H11C0 ; Parse line up to non-alphanumeric char (EOL) ; Reading from ASM file as necessary. if char is ; Numeric then return value in H0186. if LF (0Ah ; Found, will print line to PRN file with echo ; To console on 2nd pass. H1109: NOP ; Previous char from H110A H110A: NOP ; Last char read from ASM file H110B: NOP ; Base 2,8,10 or 16 for numeric value H110C: CALL H0206 ; Get char from ASM file and store in PUSH PSW ; H010C PRN line buffer CPI 0DH JZ H1130 CPI 0AH JZ H1130 LDA H0184 CPI 78H JNC H1130 MOV E,A MVI D,00H INR A STA H0184 LXI H,H010C DAD D POP PSW ; Restore char MOV M,A ; Store in PRN line buffer RET H1130: POP PSW ; Restore char RET H1132: CALL H1149 ; Print CR/LF to PRN file STA H110A STA H0184 MVI A,0AH STA H1109 CALL H0215 ; Print PRN line buffer MVI A,10H STA H0184 ; Index to label field RET H1149: XRA A STA H0188 STA H110B RET H1151: LXI H,H0188 ; Store char in H0189 buffer MOV A,M CPI 40H JC H115F MVI M,00H CALL H131E H115F: MOV E,M MVI D,00H INR M INX H DAD D LDA H110A MOV M,A RET H116A: MOV A,M ; Null out '$' at (HL) CPI 24H RNZ XRA A MOV M,A RET H1171: LDA H110A ; Return z clear if '0-9' digit SUI 30H CPI 0AH RAL ANI 01H RET H117C: CALL H1171 ; Return z clear if '0-9' or 'A-F' hex digit RNZ LDA H110A SUI 41H CPI 06H ; A-F = 0-5. carry set if A-F RAL ; Carry to bit 0 ANI 01H ; =1 if A-F RET H118B: LDA H110A ; Return z clear if 'A-Z' alpha SUI 41H CPI 1AH RAL ANI 01H RET H1196: CALL H118B ; Return z clear if 'A-Z' or '0-9' alphanumeric RNZ CALL H1171 RET H119E: LDA H110A CPI 61H RC CPI 7BH RNC ANI 5FH STA H110A RET H11AD: CALL H110C ; Get char and store in PRN line buffer STA H110A ; Save in last char JMP H132D ; Go convert lower/upper conditionally RET ; Bogus H11B7: CPI 0DH RZ CPI 1AH RZ CPI 21H RET H11C0: XRA A ; Parse line STA H0185 ; Clear char mode CALL H1149 H11C7: LDA H110A ; Each char loops here CPI 09H JZ H11F4 CPI 3BH JZ H11E1 CPI 2AH JNZ H11ED LDA H1109 CPI 0AH JNZ H11ED H11E1: CALL H11AD ; Search ahead to EOL CALL H11B7 JZ H11FA JMP H11E1 H11ED: ORI 20H CPI 20H JNZ H11FA H11F4: CALL H11AD ; Get next char JMP H11C7 ; Loop for next char H11FA: CALL H118B JZ H1205 ; If not alpha MVI A,01H JMP H1239 H1205: CALL H1171 JZ H1210 ; If not digit MVI A,02H JMP H1239 H1210: LDA H110A CPI 27H ; Single quote JNZ H1221 XRA A STA H110A MVI A,03H JMP H1239 H1221: CPI 0AH JNZ H1237 LDA H01CF ; Assembly pass count ORA A CNZ H0215 ; On 2nd pass print line to PRN file LXI H,H010C MVI M,20H ; Clear error char MVI A,10H STA H0184 ; Index to label field for PRN file H1237: MVI A,04H H1239: STA H0185 H123C: LDA H110A ; Last char STA H1109 ; Previous char ORA A CNZ H1151 ; Store char in ASM buffer CALL H11AD ; Get char and store in PRN line buffer LDA H0185 ; Char mode CPI 04H ; EOL ? RZ CPI 03H ; Literal? CNZ H119E ; Convert lower to upper case if not in quotes LXI H,H110A LDA H0185 ; Char mode CPI 01H ; Alpha? JNZ H126C CALL H116A ; Null out '$' from last char JZ H123C ; Taken if last char was '$' CALL H1196 RZ ; Taken if not alphanumeric JMP H123C H126C: CPI 02H JNZ H1302 CALL H116A JZ H123C ; Taken if '$' CALL H117C JNZ H123C ; Taken if hex digit LDA H110A CPI 4FH ; 'O' octal JZ H128A CPI 51H ; 'Q' octal JNZ H128F H128A: MVI A,08H ; Base 8 for octal JMP H1296 H128F: CPI 48H ; 'H' JNZ H12A0 MVI A,10H ; Base 16 hex for 'H' H1296: STA H110B XRA A STA H110A JMP H12BB H12A0: LDA H1109 CPI 42H ; 'B' binary JNZ H12AD MVI A,02H ; Base 2 for binary JMP H12B4 H12AD: CPI 44H ; 'D' decimal MVI A,0AH ; base 10 decimal (default) JNZ H12B8 H12B4: LXI H,H0188 ; Index DCR M ; Ignore trailing char H12B8: STA H110B ; Set base H12BB: LXI H,0000H SHLD H0186 LXI H,H0188 MOV C,M INX H H12C6: MOV A,M INX H CPI 41H JNC H12D2 SUI 30H JMP H12D4 H12D2: SUI 37H H12D4: PUSH H PUSH B MOV C,A LXI H,H110B CMP M CNC H1318 MVI B,00H MOV A,M LHLD H0186 XCHG LXI H,0000H H12E8: ORA A JZ H12F7 RAR JNC H12F1 DAD D H12F1: XCHG DAD H XCHG JMP H12E8 H12F7: DAD B SHLD H0186 POP B POP H DCR C JNZ H12C6 RET H1302: LDA H110A CPI 0DH JZ H131E CPI 27H JNZ H123C CALL H11AD CPI 27H RNZ JMP H123C H1318: PUSH PSW ; 'V' bad value error. all regs preserved MVI A,56H JMP H1324 H131E: PUSH PSW ; 'O' error. all regs preserved MVI A,4FH JMP H1324 H1324: PUSH B PUSH H CALL H0218 POP H POP B POP PSW RET H132D: PUSH PSW ; Convert lower to upper case if not in quotes LDA H0185 ; Char mode CPI 03H ; Literal? CNZ H119E ; Convert if not literal POP PSW RET DB 0,0,0,0,0,0,0,0 H1340: JMP H15A0 ; Enter assembler with PRN and HEX files open H1343: JMP H145C ; Clear H135B buffer H1346: JMP H149E ; Using label in H0188 buffer, search for ; Duplicate label. return H01D6=0 if no duplicat ; Else H01D6 holds address of link field of dup. H1349: JMP H1498 ; Ret dup label addr in HL. z-set if no dup H134C: JMP H14EB ; Add symbol. see H14EB for more description H134F: JMP H1560 ; Set nibble in symbol table at (H01D6) from ;ACC reg low nibble. when nibble designated by X is set then symbol has been ;assigned value. (H01D6): 00 00 X3 BDOS DW 0005 H1352: JMP H1572 ; Get nibble from symbol table H1355: JMP H158D ; Set value field of symbol at (H01D6) from HL H1358: JMP H1596 ; Get value of symbol at (H01D6) into HL H135B: DS 100H ; Buffer table holds 16 bit values. offset into ; Table based on checksum of chars in label H145B: DS 01H H145C: LXI H,H135B MVI B,80H XRA A H1462: MOV M,A INX H MOV M,A INX H DCR B JNZ H1462 LXI H,0000H SHLD H01D6 RET H1471: LXI H,H0188 ; Add all chars of label then mask bit 7 MOV B,M XRA A H1476: INX H ADD M DCR B JNZ H1476 ANI 7FH STA H145B RET MOV B,A ; Bogus code until H148E. image from addr 1566h LHLD H01D6 INX H INX H MOV A,M ANI 0F0H ORA B MOV M,A RET H148E: LHLD H01D6 ; Get length of symbol table INX H INX H MOV A,M ANI 0FH INR A RET H1498: LHLD H01D6 MOV A,L ORA H RET H149E: CALL H1471 ; Search for duplicate label. return H01D6=0 if LXI H,H0188 ; No duplicate or pointing to link field before MOV A,M ; Duplicate CPI 11H JC H14AC MVI M,10H ; 16 chars max length of label H14AC: LXI H,H145B MOV E,M MVI D,00H LXI H,H135B DAD D DAD D MOV E,M INX H MOV H,M MOV L,E H14BB: SHLD H01D6 CALL H1498 RZ CALL H148E LXI H,H0188 CMP M JNZ H14E1 MOV B,A INX H XCHG LHLD H01D6 INX H INX H INX H H14D5: LDAX D CMP M JNZ H14E1 INX D INX H DCR B JNZ H14D5 RET H14E1: LHLD H01D6 MOV E,M INX H MOV D,M XCHG JMP H14BB H14EB: LXI H,H0188 ; Add symbol from H0188 buffer to end of symbol MOV E,M ; Table at (H01CB) and zero value field MVI D,00H LHLD H01CB SHLD H01D6 DAD D LXI D,0005H DAD D XCHG LHLD H01CD MOV A,E SUB L MOV A,D SBB H XCHG JNC H1541 ; Taken if end of symbol space SHLD H01CB LHLD H01D6 XCHG LXI H,H145B MOV C,M MVI B,00H LXI H,H135B DAD B DAD B MOV C,M INX H MOV B,M MOV M,D DCX H MOV M,E XCHG MOV M,C INX H MOV M,B LXI D,H0188 LDAX D CPI 11H JC H152F MVI A,10H ; Max length of label = 16 chars H152F: MOV B,A DCR A INX H MOV M,A ; Store length-1 H1533: INX H ; Store label name INX D LDAX D MOV M,A DCR B JNZ H1533 XRA A ; Zero value field INX H MOV M,A INX H MOV M,A RET H1541: LXI H,H154A CALL H0212 JMP H021E H154A: DB 'SYMBOL TABLE OVERFLOW' DB 0DH H1560: RAL RAL RAL RAL ANI 0F0H MOV B,A LHLD H01D6 INX H INX H MOV A,M ANI 0FH ORA B MOV M,A RET H1572: LHLD H01D6 INX H INX H MOV A,M RAR RAR RAR RAR ANI 0FH RET H157F: CALL H148E ; Return HL pointing to value field of LHLD H01D6 ; Symbol at (H01D6) MOV E,A MVI D,00H DAD D INX H INX H INX H RET H158D: PUSH H CALL H157F POP D MOV M,E INX H MOV M,D RET H1596: CALL H157F MOV E,M INX H MOV D,M XCHG RET DB 0,0 H15A0: JMP H1860 ; Enter assembler with PRN and HEX files open JMP H1783 H15A6: JMP H1810 ; Check word for match. return z-set for match ; And regs ACC=parm1, B=parm2 H15A9: DW H15C4 ; Mnem length = 1 (as in reg designation char) DW H15D4 ; Mnem length = 2 DW H15E6 ; Mnem length = 3 DW H1682 ; Mnem length = 4 DW H16AE ; Mnem length = 5 DW H16BD ; Bogus? H15B5: DB 10H ; # of 1 char words in H15C4 table DB 09H ; # of 2 char words in H15D4 table DB 34H ; # of 3 char words in H15E6 table DB 0BH ; # of 4 char words in H1682 table DB 03H ; # of 5 char words in H16AE table H15BA: DW H16BD ; Length = 1 DW H16DD ; Length = 2 DW H16EF ; Length = 3 DW H1757 ; Length = 4 DW H176D ; Length = 5 H15C4: DB 0DH ; the following tables must have at least two words in table and words must be ; in alphabetical order DB '()*+,-/ABCDEHLM' H15D4: DB 'DBDIDSDWEIIFINORSP' H15E6: DB 'ACIADCADDADIANAANDANICMACMCCMPCPIDAADADDCRDCXENDEQUHLTINRINXJMPL' DB 'DALXIMODMOVMVINOPNOTORAORGORIOUTPOPPSWRALRARRETRLCRRCRSTSBBSBISE' DB 'TSHLSHRSTASTCSUBSUIXORXRAXRI' H1682: DB 'CALLENDMLDAXLHLDPCHLPUSHSHLDSPHLSTAXXCHGXTHL' H16AE: DB 'ENDIFMACROTITLE' ; the following are 2 byte parameters corresponding to each word. ; they are referenced in source comments as parm1 and parm2. ; for first pair at H16BD: parm1 = 0FH, parm2 = 0AH ; if parm1 = 10H then parm2 represents a register as follows: ; B=0 C=1 D=2 E=3 H=4 L=5 M,SP,PSW=6 H16BD: DB 0FH,0AH DB 0CH,14H,0DH,1EH,00H,50H DB 05H,46H,0EH,0AH,06H,46H,01H,50H DB 10H,07H,10H,00H,10H,01H,10H,02H DB 10H,03H,10H,04H,10H,05H,10H,06H H16DD: DB 11H,01H,13H,0F3H,11H,02H,11H,03H DB 13H,0FBH,11H,08H,21H,0DBH,0AH,28H DB 10H,06H H16EF: DB 1AH,0CEH,1DH,88H,1DH,80H,1AH,0C6H DB 1DH,0A0H,09H,32H,1AH,0E6H,13H,2FH DB 13H,3FH,1DH,0B8H,1AH,0FEH,13H,27H DB 15H,09H,1EH,05H,1FH,0BH,11H,04H DB 11H,07H,13H,76H,1EH,04H,1FH,03H DB 17H,0C3H,1CH,3AH,14H,01H,02H,50H DB 18H,40H,19H,06H,13H,00H,08H,3CH DB 1DH,0B0H,11H,0AH,1AH,0F6H,21H,0D3H DB 16H,0C1H,10H,06H,13H,17H,13H,1FH DB 13H,0C9H,13H,07H,13H,0FH,20H,0C7H DB 1DH,98H,1AH,0DEH,11H,0BH,03H,50H DB 04H,50H,1CH,32H,13H,37H,1DH,90H DB 1AH,0D6H,0BH,28H,1DH,0A8H,1AH,0EEH H1757: DB 17H,0CDH,11H,06H,1BH,0AH,1CH,2AH DB 13H,0E9H,16H,0C5H,1CH,22H,13H,0F9H DB 1BH,02H,13H,0EBH,13H,0E3H H176D: DB 11H,05H,11H,09H,11H,0CH H1773: DB 'NZZ NCC POPEP M ' H1783: MVI E,0FFH INR B MVI C,00H H1788: XRA A MOV A,B ADD C RAR CMP E JZ H17C4 MOV E,A PUSH H PUSH D PUSH B PUSH H MOV B,D MOV C,B MVI D,00H LXI H,0000H H179C: DAD D DCR B JNZ H179C POP D DAD D LXI D,H0189 H17A6: LDAX D CMP M INX D INX H JNZ H17B6 DCR C JNZ H17A6 POP B POP D POP H MOV A,E RET H17B6: POP B POP D POP H JC H17C0 MOV C,E JMP H1788 H17C0: MOV B,E JMP H1788 H17C4: XRA A INR A RET H17C7: LDA H0189 LXI B,0C217H CPI 4AH RZ MVI B,0C4H CPI 43H RZ LXI B,0C013H CPI 52H RET H17DB: LDA H0188 CPI 04H JNC H180D CPI 03H JZ H17F2 CPI 02H JNZ H180D LXI H,H018B MVI M,20H H17F2: LXI B,0008H LXI D,H1773 H17F8: LXI H,H018A LDAX D CMP M INX D JNZ H1805 LDAX D INX H CMP M RZ H1805: INX D INR B DCR C JNZ H17F8 INR C RET H180D: XRA A INR A RET H1810: LDA H0188 MOV C,A DCR A MOV E,A MVI D,00H PUSH D CPI 05H ; Max length of mnem JNC H185A LXI H,H15B5 DAD D MOV B,M LXI H,H15A9 DAD D DAD D MOV D,M INX H MOV H,M MOV L,D MOV D,C CALL H1783 JNZ H1845 ; ACC now = nth pair of whichever 2 byte table POP D LXI H,H15BA DAD D DAD D MOV E,M INX H MOV D,M MOV L,A MVI H,00H DAD H DAD D MOV A,M INX H MOV B,M RET H1845: POP D CALL H17C7 RNZ PUSH B CALL H17DB MOV A,B POP B RNZ ORA A RAL RAL RAL ORA B MOV B,A MOV A,C CMP A RET H185A: POP D XRA A INR A RET DB 0,0 H1860: JMP H1BA0 ; Enter assembler with PRN and HEX files open H1863: JMP H1A19 ; Return addr of symbol in H01C9 and (HL) reg JMP H196E H1869: JMP H1938 ; Return 'USE FACTOR' value in DE reg H186C: DS 01H ; Flag 0 or FFh H186D: DS 0AH ; Buffer for parm1 values H1877: DS 0AH ; Buffer for parm2 values H1881: DS 10H H1891: DS 01H ; Index into H186D or H1877 buffers H1892: DS 01H ; Index into H1881 buffer H1893: XCHG ; Store HL reg pair in H1881 buffer and incremen LXI H,H1892 ; H1892 index by 2 MOV A,M CPI 10H JC H18A2 CALL H1B85 MVI M,00H H18A2: MOV A,M INR M INR M MOV C,A MVI B,00H LXI H,H1881 DAD B MOV M,E INX H MOV M,D RET H18B0: PUSH PSW ; Store parm1,parm2 in H186D and H1877 buffers LXI H,H1891 ; And increment H1891 index MOV A,M CPI 0AH JC H18BF MVI M,00H CALL H1B85 ; 'E' error H18BF: MOV E,M MVI D,00H INR M POP PSW LXI H,H186D DAD D MOV M,A LXI H,H1877 DAD D MOV M,B RET H18CF: LXI H,H1892 ; Get previous pair to HL reg from H1881 buffer MOV A,M ORA A JNZ H18DE CALL H1B85 LXI H,0000H RET H18DE: DCR M DCR M MOV C,M MVI B,00H LXI H,H1881 DAD B MOV C,M INX H MOV H,M MOV L,C RET H18EC: CALL H18CF ; Get 2 pairs from H1881 buffer to HL and DE reg XCHG CALL H18CF RET H18F4: MOV L,A ; Call subroutine from H1901 table based on MVI H,00H ; Parm1 value from H186D table DAD H LXI D,H1901 DAD D MOV E,M INX H MOV H,M MOV L,E PCHL H1901: DW H1989 DW H1992 DW H1999 DW H199F DW H19AB DW H19BF DW H19C6 DW H19D0 DW H19D9 DW H19E0 DW H19EC DW H19F8 DW H1B85 H191B: CALL H18EC MOV A,D ORA A JNZ H1927 MOV A,E CPI 11H RC H1927: CALL H1B85 ; Call 'E' error MVI A,10H RET H192D: XRA A SUB L MOV L,A MVI A,00H SBB H MOV H,A RET H1935: CALL H18EC H1938: XCHG SHLD H196B LXI H,H196D MVI M,11H LXI B,0000H PUSH B XRA A H1946: MOV A,E RAL MOV E,A MOV A,D RAL MOV D,A DCR M POP H RZ MVI A,00H ACI 00H DAD H MOV B,H ADD L LHLD H196B SUB L MOV C,A MOV A,B SBB H MOV B,A PUSH B JNC H1964 DAD B XTHL H1964: LXI H,H196D CMC JMP H1946 H196B: NOP NOP H196D: NOP H196E: MOV B,H MOV C,L LXI H,0000H H1973: XRA A MOV A,B RAR MOV B,A MOV A,C RAR MOV C,A JC H1982 ORA B RZ JMP H1983 H1982: DAD D H1983: XCHG DAD H XCHG JMP H1973 H1989: CALL H18EC CALL H196E JMP H1A01 H1992: CALL H1935 XCHG JMP H1A01 H1999: CALL H1935 JMP H1A01 H199F: CALL H191B H19A2: ORA A JZ H1A01 DAD H DCR A JMP H19A2 H19AB: CALL H191B H19AE: ORA A JZ H1A01 PUSH PSW XRA A MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A POP PSW DCR A JMP H19AE H19BF: CALL H18EC H19C2: DAD D JMP H1A01 H19C6: CALL H18EC XCHG CALL H192D JMP H19C2 H19D0: CALL H18CF H19D3: CALL H192D JMP H1A01 H19D9: CALL H18CF INX H JMP H19D3 H19E0: CALL H18EC MOV A,D ANA H MOV H,A MOV A,E ANA L MOV L,A JMP H1A01 H19EC: CALL H18EC MOV A,D ORA H MOV H,A MOV A,E ORA L MOV L,A JMP H1A01 H19F8: CALL H18EC MOV A,D XRA H MOV H,A MOV A,E XRA L MOV L,A H1A01: JMP H1893 H1A04: LDA H0185 CPI 04H RNZ LDA H0189 CPI 0DH RZ CPI 3BH RZ CPI 2CH RZ CPI 21H RET H1A19: XRA A STA H1891 STA H1892 DCR A STA H186C LXI H,0000H SHLD H01C9 H1A2A: CALL H1A04 JNZ H1A5D H1A30: LXI H,H1891 MOV A,M ORA A JZ H1A48 DCR M MOV E,A DCR E MVI D,00H LXI H,H186D DAD D MOV A,M CALL H18F4 ; Call subroutine from table JMP H1A30 H1A48: LDA H1892 CPI 02H CNZ H1B85 ; Call 'E' error LDA H010C CPI 20H RNZ LHLD H1881 SHLD H01C9 RET H1A5D: LDA H010C CPI 20H JNZ H1B7F LDA H0185 ; Char type CPI 03H JNZ H1A89 LDA H0188 ORA A CZ H1B85 CPI 03H CNC H1B85 MVI D,00H LXI H,H0189 MOV E,M INX H DCR A JZ H1A85 MOV D,M H1A85: XCHG JMP H1B71 H1A89: CPI 02H ; Char type = numeric JNZ H1A94 LHLD H0186 ; Numeric value JMP H1B71 ; non-alphanumeric chars encountered in label being evaluated come here to ; evaluate possible expression (math) H1A94: CALL H15A6 ; Scan for match. if match then ACC=parm1 B=parm JNZ H1B31 ; Taken if no match CPI 10H JNC H1B26 CPI 0CH MOV C,A LDA H186C JNZ H1AB5 ORA A CZ H1B85 ; 'E' error MVI A,0FFH STA H186C MOV A,C JMP H1B03 H1AB5: ORA A JNZ H1B0E H1AB9: PUSH B LDA H1891 ORA A JZ H1ADE MOV E,A DCR E MVI D,00H LXI H,H1877 DAD D MOV A,M CMP B JC H1ADE LXI H,H1891 MOV M,E LXI H,H186D DAD D MOV A,M CALL H18F4 ; Call subroutine from table POP B JMP H1AB9 H1ADE: POP B MOV A,C CPI 0DH JNZ H1B03 LXI H,H1891 MOV A,M ORA A JZ H1AFC DCR A MOV M,A MOV E,A MVI D,00H LXI H,H186D DAD D MOV A,M CPI 0CH JZ H1AFF H1AFC: CALL H1B85 H1AFF: XRA A JMP H1B08 H1B03: CALL H18B0 MVI A,0FFH H1B08: STA H186C JMP H1B7F H1B0E: MOV A,C ; Parm1 CPI 05H JZ H1B7F CPI 06H JNZ H1B1E INR A ; F(-) MOV C,A JMP H1AB9 H1B1E: CPI 08H ; F(NOT) = 8 CNZ H1B85 JMP H1AB9 H1B26: CPI 11H CZ H1B85 MOV L,B MVI H,00H JMP H1B71 H1B31: LDA H0185 CPI 04H JNZ H1B50 LDA H0189 CPI 24H ; '$' JZ H1B4A CALL H1B85 LXI H,0000H JMP H1B71 H1B4A: LHLD H01D2 JMP H1B71 H1B50: CALL H1346 ; Check for duplicate label CALL H1349 ; Test results JNZ H1B64 ; Taken if no duplicate MVI A,50H ; 'P' CALL H0218 ; Error CALL H134C ; Add symbol JMP H1B6E H1B64: CALL H1352 ; Test nibble ANI 07H MVI A,55H ; 'U' CZ H0218 ; Error H1B6E: CALL H1358 ; Get symbol value into HL H1B71: LDA H186C ORA A CZ H1B85 XRA A STA H186C CALL H1893 H1B7F: CALL H1106 ; F(+) JMP H1A2A H1B85: PUSH H ; 'E' error MVI A,45H CALL H0218 POP H RET H1B8D: CALL H1352 ORA A JZ H1DB5 RET DB 0,0,0,0,0,0,0,0,0,0,0 H1BA0: XRA A ; Entry to assembler with PRN and HEX files open STA H01CF ; Reset pass count to 0 CALL H1343 ; Clear buffer ; 2nd pass loops here H1BA7: CALL H1103 ; New line (send CR/LF to PRN file) CALL H0203 ; Open ASM file LXI H,0000H SHLD H20EB SHLD H01D0 SHLD H01D2 SHLD H20ED H1BBC: CALL H1106 ; Parse word into H0189 and H010C buffers and H1BBF: LDA H0185 ; Set char type in H0185 CPI 02H JZ H1BBC ; Handle digit CPI 04H JNZ H1BDD LDA H0189 CPI 2AH ; '*' JNZ H1F31 CALL H2000 JNZ H1F7C ; 'S' error JMP H1F52 H1BDD: CPI 01H JNZ H1F7C ; Not alpha CALL H15A6 ; Check word for match JZ H1C30 CALL H1346 ; Check for duplicate label CALL H1349 ; Test results JNZ H1BFE ; If no duplicate CALL H134C ; Add symbol to table LDA H01CF ; Assembler pass# ORA A CNZ H20D7 ; 'P' error if duplicate symbol on 1st pass JMP H1C0C H1BFE: CALL H1352 ; Get symbol assignment nibble CPI 06H JNZ H1C0C ; If label assigned value CALL H20E3 ; 'N' error JMP H1F52 H1C0C: LHLD H20EB MOV A,L ORA H CNZ H20DD ; 'L' error LHLD H01D6 SHLD H20EB CALL H1106 LDA H0185 CPI 04H JNZ H1BBF LDA H0189 CPI 3AH JNZ H1BBF JMP H1BBC H1C30: CPI 11H JNZ H1DD7 MOV E,B MVI D,00H DCX D LXI H,H1C43 DAD D DAD D MOV E,M INX H MOV H,M MOV L,E PCHL ;table for parm1 = 11h. parm2 referenced in () H1C43: DW H1C5B ; (01h) DB DW H1CA9 ; (02h) DS DW H1CC0 ; (03h) DW DW H1CDE ; (04h) END DW H1D15 ; (05h) ENDIF DW H1D18 ; (06h) ENDM (function not supported. gives 'N' error) DW H1D1E ; (07h) EQU DW H1D40 ; (08h) IF DW H1D87 ; (09h) MACRO (function not supported. gives 'N' error) DW H1D8D ; (0Ah) ORG DW H1DA7 ; (0Bh) SET DW H1DCE ; (0Ch) TITLE H1C5B: CALL H200A H1C5E: CALL H1106 LDA H0185 CPI 03H JNZ H1C8C LDA H0188 DCR A JZ H1C8C MOV B,A INR B INR B LXI H,H0189 H1C76: DCR B JZ H1C86 PUSH B MOV B,M INX H PUSH H CALL H2048 POP H POP B JMP H1C76 H1C86: CALL H1106 JMP H1C9B H1C8C: CALL H1863 LHLD H01C9 MOV A,H ORA A CNZ H20D1 ; 'D' error if DB label not 8-bit value MOV B,L CALL H2048 H1C9B: CALL H1FF9 CALL H1EBA CPI 2CH JZ H1C5E JMP H1F31 H1CA9: CALL H200A ; F(DS) CALL H20A6 CALL H1ED1 ; Get 16 bit value/address into HL XCHG LHLD H01D2 DAD D SHLD H01D2 SHLD H01D0 ; Address PC counter JMP H1F31 H1CC0: CALL H200A ; F(DW) H1CC3: CALL H1ED1 PUSH H MOV B,L CALL H2048 POP H MOV B,H CALL H2048 CALL H1FF9 CALL H1EBA CPI 2CH JZ H1CC3 JMP H1F31 H1CDE: CALL H200A ; F(END) CALL H20A6 ; Print final PRN line addr to buffer LDA H010C CPI 20H JNZ H1F31 CALL H1ED1 ; Get addr to HL of symbol following END (if any LDA H010C ; END w/o symbol gives 'E' error (both passes) CPI 20H JNZ H1CFA SHLD H20ED ; Value of symbol after END. possibly EOF addr? H1CFA: MVI A,20H STA H010C CALL H1106 LDA H0185 CPI 04H JNZ H1F7C LDA H0189 CPI 0AH JNZ H1F7C JMP H1F8B H1D15: JMP H1DD1 ; F(ENDIF) H1D18: CALL H20E3 ; F(ENDM) gives 'N' error (not supported) JMP H1DD1 H1D1E: CALL H2000 ; F(EQU) JZ H1F7C LHLD H01D2 PUSH H CALL H1ED1 SHLD H01D2 CALL H200A CALL H20A9 LXI H,H0112 MVI M,3DH POP H SHLD H01D2 JMP H1F31 H1D40: CALL H200A ; F(IF) CALL H1ED1 LDA H010C CPI 20H JNZ H1F31 MOV A,L RAR JC H1F31 H1D53: CALL H1106 LDA H0185 CPI 04H JNZ H1D6E LDA H0189 CPI 1AH MVI A,42H CZ H0218 JZ H1F8B JMP H1D53 H1D6E: CPI 01H JNZ H1D53 CALL H15A6 JNZ H1D53 CPI 11H JNZ H1D53 MOV A,B CPI 05H JNZ H1D53 JMP H1DD1 H1D87: CALL H20E3 ; F(MACRO) gives 'N' error (not supported) JMP H1F31 H1D8D: CALL H1ED1 ; F(ORG) LDA H010C CPI 20H JNZ H1F31 SHLD H01D2 ; ORG address for PC counters SHLD H01D0 CALL H200A CALL H20A6 JMP H1F31 H1DA7: CALL H2000 ; F(SET) JZ H1F7C CALL H1B8D CPI 05H CNZ H20DD H1DB5: MVI A,05H CALL H134F CALL H1ED1 PUSH H CALL H2000 POP H CALL H1355 LXI H,0000H SHLD H20EB JMP H1F31 H1DCE: CALL H20E3 H1DD1: CALL H1106 JMP H1F31 H1DD7: SUI 13H ; ACC = parm1 value from H15A6 call CPI 21H ; Bug here. should have been 0Fh JNC H1F7C ; Taken for parm1<13h or >=34h (should be >=22h) MOV E,A ; See table following. range only 13h to 21h MVI D,00H LXI H,H1DEB DAD D DAD D MOV E,M INX H MOV H,M MOV L,E PCHL ;table for parm1 = 13h to 21h. parm1 value in () H1DEB: DW H1E09 ; (13h) DI EI CMA CMC DAA HLT NOP RAL RAR RET RLC RRC ST ; PCHL SPHL XTHL XCHG DW H1E12 ; (14h) LXI DW H1E1E ; (15h) DAD DW H1E24 ; (16h) POP PUSH DW H1E38 ; (17h) JMP CALL DW H1E41 ; (18h) MOV DW H1E50 ; (19h) MVI DW H1E60 ; (1Ah) ACI ADI ANI CPI ORI XRI SUI SBI DW H1E69 ; (1Bh) LDAX STAX DW H1E78 ; (1Ch) LDA STA LHLD SHLD DW H1E81 ; (1Dh) ADC ADD ANA CMP ORA XRA SUB SBB DW H1E88 ; (1Eh) DCR INR DW H1E8F ; (1Fh) DCX INX DW H1E9E ; (20h) RST DW H1EA5 ; (21h) IN OUT H1E09: CALL H2048 CALL H1106 JMP H1EB1 H1E12: CALL H1EFC ; Process reg char following LXI instruction CALL H1F17 ; Check for comma CALL H1F11 JMP H1EB1 H1E1E: CALL H1EFC ; Process reg char following DAD instruction JMP H1EB1 H1E24: CALL H1EF2 CPI 38H JZ H1E31 ANI 08H CNZ H20BD H1E31: MOV A,C ANI 30H ORA B JMP H1EAE H1E38: CALL H2048 CALL H1F11 JMP H1EB1 H1E41: CALL H1EF2 ; F(MOV) ORA B MOV B,A CALL H1F17 CALL H1EE7 ; Parse reg value ORA B JMP H1EAE H1E50: CALL H1EF2 ; Get reg mask following MVI instruction ORA B CALL H2047 ; Store opcode CALL H1F17 ; Check for comma CALL H1F0B ; Parse and store 8 bit label/value after comma JMP H1EB1 H1E60: CALL H2048 ; Store opcode in HEX file CALL H1F0B ; Parse operand JMP H1EB1 H1E69: CALL H1EF2 ANI 28H CNZ H20BD MOV A,C ANI 10H ORA B JMP H1EAE H1E78: CALL H2048 CALL H1F11 JMP H1EB1 H1E81: CALL H1EE7 ORA B JMP H1EAE H1E88: CALL H1EF2 ORA B JMP H1EAE H1E8F: CALL H1EF2 ANI 08H CNZ H20BD MOV A,C ANI 30H ORA B JMP H1EAE H1E9E: CALL H1EF2 ORA B JMP H1EAE H1EA5: CALL H2048 CALL H1F0B JMP H1EB1 H1EAE: CALL H2047 H1EB1: CALL H200A ; Each instruction line comes here to close CALL H1FF9 ; Update PRN file PC counter (H01D2) for next line JMP H1F31 H1EBA: LDA H0185 CPI 04H CNZ H20D1 LDA H0189 CPI 2CH RZ CPI 3BH RZ CPI 0DH CNZ H20D1 RET H1ED1: PUSH B ; Get 16 bit reg value or label address into HL reg. CALL H1106 ; Parse word CALL H1863 ; Process word LHLD H01C9 ; Holds value (example: C reg value = 0001) POP B RET H1EDD: CALL H1ED1 ; Get 8 bit reg value or label address into ACC reg. MOV A,H ORA A CNZ H20C7 MOV A,L RET H1EE7: CALL H1EDD ; Parse 8 bit reg char value into ACC (0 to 7 = ACC to M CPI 08H CNC H20C7 ; 'V' error (bad register designation) ANI 07H RET H1EF2: CALL H1EE7 ; Get 8 bit reg char value (0-7) into bits 3,4,5 of ACC RAL RAL RAL ANI 38H MOV C,A RET H1EFC: CALL H1EF2 ; Store 16 bit regs (even# B,D or H) ORA'd with B(=parm2 ANI 08H ; Bit 3 set if odd# reg (ACC,C,E or L) CNZ H20BD ; 'R' error MOV A,C ANI 30H ORA B JMP H2047 H1F0B: CALL H1EDD ; Parse and store 8 bit label/address (operand) JMP H2047 H1F11: CALL H1ED1 ; Parse and store 16 bit label/address (operand) JMP H2074 H1F17: PUSH PSW ; Check for comma PUSH B LDA H0185 CPI 04H JNZ H1F29 LDA H0189 CPI 2CH JZ H1F2E H1F29: MVI A,43H CALL H0218 H1F2E: POP B POP PSW RET H1F31: CALL H200A LDA H0185 CPI 04H JNZ H1F7C LDA H0189 CPI 0DH JNZ H1F4A CALL H1106 JMP H1BBC H1F4A: CPI 3BH ; ';' JNZ H1F72 CALL H200A H1F52: CALL H1106 LDA H0185 CPI 04H JNZ H1F52 LDA H0189 CPI 0AH JZ H1BBC CPI 1AH JZ H1F8B CPI 21H JZ H1BBC JMP H1F52 H1F72: CPI 21H JZ H1BBC CPI 1AH JZ H1F8B H1F7C: MVI A,53H CALL H0218 JMP H1F52 H1F84: MOV A,E ; HL=DE-HL SUB L MOV L,A MOV A,D SBB H MOV H,A RET H1F8B: LXI H,H01CF ; Assembler pass count MOV A,M INR M ; Increment 1st to 2nd pass ORA A JZ H1BA7 ; If 2nd pass CALL H1106 ; Here after 2nd pass CALL H20A6 LXI H,H0111 MVI M,0DH LXI H,H010D CALL H0212 LHLD H01CB XCHG LHLD H01D4 CALL H1F84 PUSH H LHLD H01CD XCHG LHLD H01D4 CALL H1F84 MOV E,H MVI D,00H POP H CALL H1869 XCHG CALL H20A9 ; Put HL in PRN buffer just before 'USE FACTOR' LXI H,H0111 LXI D,H1FD6 H1FCB: LDAX D ; Put 'USE FACTOR' in PRN buffer ORA A JZ H1FE4 MOV M,A INX H INX D JMP H1FCB H1FD6: DB 'H USE FACTOR' DB 0DH,00H H1FE4: LXI H,H010E CALL H0212 LHLD H20ED SHLD H01D0 JMP H021E ; Go close files and exit H1FF3: MOV A,D CMP H RNZ MOV A,E CMP L RET H1FF9: LHLD H01D0 SHLD H01D2 RET H2000: LHLD H20EB ; Test H20EB for 0. move to H01D6 and ret in HL SHLD H01D6 CALL H1349 RET ; on 1st pass if H20EB non-zero then set PC counter to value of symbol operand ; at (H20EB). clear up unevaluated label, if any. on 2nd pass make sure label ; value is set and matches current PC else 'P' phase error H200A: CALL H2000 RZ LXI H,0000H SHLD H20EB LDA H01CF ; Pass count ORA A JNZ H2031 ; If 2nd pass CALL H1352 ; Test nibble (see H134F notes) PUSH PSW ANI 07H CNZ H20DD ; 'L' error POP PSW ORI 01H CALL H134F ; Set nibble flag LHLD H01D2 CALL H1355 ; Set value of symbol to HL RET H2031: CALL H1352 ; Test nibble ANI 07H CZ H20D7 ; 'P' error CALL H1358 ; Get symbol value XCHG LHLD H01D2 CALL H1FF3 CNZ H20D7 RET ;on 2nd pass store byte from ACC in hex ascii form to H010C PRN line buffer ;and HEX file. also write PC address in hex ascii if at beginning of line. H2047: MOV B,A H2048: LDA H01CF ; Store byte in B reg ORA A ; Pass count MOV A,B JZ H206C ; If 1st pass, only advance PC counter PUSH B CALL H021B ; Write byte to HEX file LDA H010D CPI 20H LHLD H01D2 ; PC counter of PRN line CZ H20A9 ; Print PC at start of PRN line (if no error) LDA H20EF ; PRN file line index CPI 10H ; 10h = start of label field POP B JNC H206C MOV A,B CALL H2096 ; Print byte in hex to PRN file H206C: LHLD H01D0 ; Advance PC counter INX H SHLD H01D0 RET H2074: PUSH H ; Write HL to PRN buffer and HEX file MOV B,L CALL H2048 POP H MOV B,H JMP H2048 H207E: ADI 30H CPI 3AH RC ADI 07H RET H2086: CALL H207E LXI H,H20EF MOV E,M MVI D,00H INR M LXI H,H010C DAD D MOV M,A RET H2096: PUSH PSW ; Print byte to PRN buffer RAR RAR RAR RAR ANI 0FH CALL H2086 POP PSW ANI 0FH JMP H2086 H20A6: LHLD H01D2 ; Print PC addr in ascii to PRN buffer H20A9: XCHG LXI H,H20EF PUSH H MVI M,01H MOV A,D PUSH D CALL H2096 POP D MOV A,E CALL H2096 POP H INR M RET H20BD: PUSH PSW ; 'R' error PUSH B MVI A,52H CALL H0218 POP B POP PSW RET H20C7: PUSH PSW ; 'V' error PUSH H MVI A,56H CALL H0218 POP H POP PSW RET H20D1: PUSH PSW ; 'D' error MVI A,44H JMP H20E6 H20D7: PUSH PSW ; 'P' error MVI A,50H JMP H20E6 H20DD: PUSH PSW ; 'L' error MVI A,4CH JMP H20E6 H20E3: PUSH PSW ; 'N' error MVI A,4EH H20E6: CALL H0218 POP PSW RET H20EB: DS 02H ; Last H01D6 value from H1346 call H20ED: DS 02H ; EOF addr after 'END' (value of symbol) H20EF: DS 1 ; Char index into H010C PRN line buffer H20F0: DS 1 ; Label table begins here END