Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 2.X/CPM 2.2/ASM80/ASM.Z80
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

2299 lines
47 KiB
Plaintext

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