; 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
