;-----------------------------------------------;
;	Z80 RESIDENT ASSEMBLER			;
;-----------------------------------------------;
;						;
;	(C) COPYRIGHT 1977			;
;	LEHMAN CONSULTING SERVICES		;
;						;
;	ALL RIGHTS RESERVED			;
;						;
;-----------------------------------------------;
;						;
;	MAIN ASSEMBLER MODULE			;
;						;
;-----------------------------------------------;
;						;
;	REV 0	14-JULY-1977	MGL		;
;	REV 1	20-OCT-77	MGL		;
;						;
;-----------------------------------------------;
;
;
	ORG	100H		;MAIN MODULE
;
	JMP	Z80ASM		;CP/M ENTRY POINT BRANCH
;
;	EJECT
;-----------------------------------------------;
;						;
;	CPMUTIL LINKAGE 			;
;						;
;-----------------------------------------------;
;
	ORG	103H		;JUMP TABLE BASE ADDRESS
;
;
;	FOR AN EXPLANATION OF THESE ROUTINES SEE CPMUTIL ASSEMBLY
;
;
WLINE	DS	3
WMSG	DS	3
DSKSEL	DS	3
OPNFIL	DS	3
CLSFIL	DS	3
DELFIL	DS	3
DREAD	DS	3
DWRITE	DS	3
CREFIL	DS	3
DMASET	DS	3
MOVE	DS	3
CMPCHR	DS	3
CMPHD	DS	3
MUL16	DS	3
GNB	DS	3
WNB	DS	3
GNB2	DS	3
WNB2	DS	3
CNV2HX	DS	3
;
;
;	CPMUTIL DATA AREA - FOR MORE DETAIL SEE CPMUTIL LISTING
;
;
FCB1	DS	33
FCB2	DS	33
IBP	DS	2
IBP2	DS	1
OBP	DS	1
OBP2	DS	1
IBUF	DS	2
OBUF	DS	2
IBUF2	DS	2
OBUF2	DS	2
INBUF	DS	1024
OUTBUF	DS	128
INBUF2	DS	128
OUTBF2	DS	128
;
;	EJECT
;-----------------------------------------------;
;	Z80SUBS LINKAGE AREA			;
;-----------------------------------------------;
;
	ORG	980H
;
;	FOR A MORE DETAILED DESCRIPTION OF THESE FIELDS SEE Z80SUBS LISTING
;
HDRBUF	DS	16
REC	DS	80
PC	DS	2
OBJ	DS	32
OBJCNT	DS	1
LEN	DS	1
VAL	DS	2
INST	DS	80
EOM	DS	1
PTR1	DS	2
PASSNO	DS	1
IDBUF	DS	16
INTBUF	DS	2
CURLNE	DS	1
LEN2	DS	2
LBLADR	DS	2
EQUFLG	DS	1
EQUVAL	DS	2
ENDADR	DS	2
EFLG	DS	1
OPCODE	DS	2
SAVVAL	DS	2
LFLAG	DS	1
HFLAG	DS	1
ERRFLG	DS	1
TEMP	DS	2
MULT	DS	2
SYMPTR	DS	2
SYMPT	DS	2
UFLAG	DS	1
EVFLGS	DS	1	;FLAGS FROM LAST SYMLUK
EVFLAGS	EQU	EVFLGS
;
;
;	Z80SUBS JUMP TABLE
;
EVAL	DS	3
ID	DS	3
INT	DS	3
SETUP	DS	3
SYMENT	DS	3
SYMLUK	DS	3
GNR	DS	3
GNC	DS	3
BACKUP	DS	3
;
;	EJECT
;
;	LOCAL DATA AREA FOR ASSEMBLER
;
	ORG	0E80H
SYMAREA	DS	15	;AREA FOR SYMBOL TABLE BUILD
SYMADR	DS	2	;ADDRESS OF VALUE LOW FIELD FOR LAST SYMENT
OLDADR	DW	-1	;LAST ADDR OF WOBJ
OBJADR	DS	2
PAGENO	DS	1
;
RNAME	EQU	20H	;FLAG BIT - REGISTER NAME
RPNAME	EQU	80H	;FLAG BIT - REGISTER PAIR NAME
;
;
MAXLNE	EQU	55	;LINES PER PAGE
;:::::::::::::::::::::::::::::::::::::::::::::::;
;						;
;	SYMBOL TABLE ADDRESS EQUATES		;
;						;
;:::::::::::::::::::::::::::::::::::::::::::::::;
;
SYMBEG	EQU	1F80H	;POINTER TO FIRST USABLE ENTRY
SYMCND	EQU	SYMBEG+2	;POINTER TO COND CODE TABLE
SYM	EQU	SYMCND+2	;ACTUAL BEGINING ADDRESS FOR SEARCHES
;
;
;
;
;	EJECT
;-----------------------------------------------;
;						;
;	Z 8 0 A S M  - RESIDENT Z80 ASSEMBLER	;
;						;
;	WRITTEN IN 8080 ASSEMBLY LANGUAGE	;
;	TO BE ASSEMBLED BY THE CP/M ASSEMBLER	;
;						;
;	AUTHOR: MICHAEL G. LEHMAN		;
;						;
;-----------------------------------------------;
;
;
Z80ASM	EQU	$
;
;	INIT FIELDS AND SETUP FILES
;
	LXI SP,STACK+128
	JMP STACK+128
VSNMSG	DB	13,10,10,'ZILOG/MOSTEK Z-80 ASSEMBLER   VERSION 2.0'
	DB	13,10,'(C) 1977 LCS',13,10,'$'
STACK	DS	128
	LXI D,VSNMSG ! CALL WMSG	;DISPLAY ON CONSOLE
	LXI H,SYM		;GET ADDRESS OF SYMBOL TABLE
	SHLD SYMPT ! LHLD SYMBEG ! SHLD	SYMPTR ;SET UP POINTERS
	CALL SETUP		;PROCESS FILE NAME, PARAMETERS, ETC.
	MVI A,MAXLNE+1 ! STA CURLNE ;SET UP FOR HEAD OF FORM ON FIRST PRINT
	XRA A !	STA PASSNO ;INDICATE PASS 1
	LXI H,0	! SHLD PC	;SET UP DEFAULT PROGRAM ORIGIN
;
;
;	MAIN LOOP - READ A SOURCE RECORD
;		    PROCESS LABEL AND OPCODE
;		    PRINT LINE (UNLESS OPTION=N)
;		    OUTPUT HEX (IF NECESSARY)
;		    BACK TO MAIN LOOP FOR NEXT RECORD
;
;
NEXT	EQU	$
	XRA A !	STA LEN	! STA EFLG ! STA EQUFLG	! LXI H,0 ! SHLD LEN2 ;INIT LENGTH & FLGS
	MVI A,' ' ! STA	ERRFLG ;FOR THIS RECORD
	CALL GNR ;GET NEXT RECORD
	CPI 1AH	! JZ S321	;BRANCH IF EOF
	LDA REC	;GET COL 1
	CPI 09H	! JZ S12	;BRANCH IF TAB
	CPI 0DH	! JZ ENDSTMT	;IGNORE NULL LINE
	CPI ' '	! JZ S12	;BRANCH IF NO LABEL
	CPI ';'	! JZ ENDSTMT	;IF COMMENT THEN IGNORE
	CALL ID	! CALL GNC ! CPI ':' ! JZ S9 ! CALL BACKUP
S9	EQU	$
	LDA PASSNO ! ORA A ! JNZ S12 ;BRANCH IF PASS 2
;
;	CALCULATE LENGTH OF SYMBOL AND BUILD ENTRY
;
	MVI B,0	;LENGTH + FLAGS ! LXI H,IDBUF
	LXI D,SYMAREA+1
S10	EQU	$
	MOV A,M	! CPI ' ' ! JZ S10A
	STAX D ! INX H ! INX D ! INR B ! JMP S10
S10A	EQU	$	;SYMBOL COLLECTED
	MOV A,B	! CPI 0CH ! JC S10B	;BRANCH IF LEN < 12 (I.E. OK)
	MVI A,'L' ! STA	ERRFLG ! JMP ENDSTMT ;ELSE LABEL ERROR
S10B	EQU	$
	ADI 4 !	STA SYMAREA ;ADD 4 FOR OVERHEAD
	XCHG	;SWITCH REGISTERS
	LDA PC ! MOV M,A ! INX H ;MOVE IN PC AS VALUE
	LDA PC+1 ! MOV M,A ! INX H ! MVI M,0 ;AND SET TYPE =0
	LXI H,IDBUF ! CALL SYMLUK ! JNZ	S11 ;BRANCH IF NOT ALREADY THERE
	MVI A,'M' ! STA	ERRFLG ! JMP ENDSTMT ;ELSE MULTI DEFINED ERROR
S11	EQU	$
	LXI H,SYMAREA !	CALL SYMENT	;ENTER SYMBOL INTO TABLE
	SHLD SYMADR	;SAVE ADDRESS FOR EQU
;
;
;	NOW PROCESS OPCODE
;
;
S12	EQU	$
	CALL	ID
	LDA IDBUF ! CPI	' ' ! JZ ENDSTMT ;BRANCH IF NO OPCODE (COMMENT)
	LXI H,IDBUF ! CALL SYMLUK ! JZ S16 ;BRANCH IF FOUND
	MVI A,'O' ! STA	ERRFLG ! JMP ENDSTMT ;ERROR IF UNDEFINED OPCODE
S16	EQU	$
	MOV A,M	! STA OPCODE ! INX H ! MOV A,M ! STA OPCODE+1 ;SAVE OPCODE
	INX H !	MOV A,M	;GET TYPE BYTE
	DCR A !	ADD A ;-1 AND DOUBLE FOR TABLE INDEX
	MOV E,A	! MVI D,0 ! LXI	H,TYPTBL ! DAD D
	MOV E,M	! INX H	! MOV D,M ! XCHG
	PCHL		;DISPATCH TO PROPER INSTRUCTION TYPE
;
;	EJECT
;-----------------------------------------------;
;						;
;	INSTRUCTION CLASS DISPATCH TABLE	;
;						;
;-----------------------------------------------;
;
TYPTBL	EQU	$
	DW	S18	;CLASS 1 - OPCODE ONLY
	DW	S24	;CLASS 2 - ROTATES
	DW	S42	;CLASS 3 - JUMPS (NON RELATIVE) CALLS
	DW	S62	;CLASS 4 - RELATIVE JUMPS (JR AND DJNZ)
	DW	S73	;CLASS 5 - RST
	DW	S77	;CLASS 6 - ARITHMETIC INSTRUCTIONS
	DW	S97	;CLASS 7 - I/O
	DW	S116	;CLASS 8 - LD INSTRUCTIONS
	DW	S220	;CLASS 9 - PUSH,POP
	DW	S228	;CLASS 10- EXCHANGE (EX)
	DW	S243	;CLASS 11- RETURNS
	DW	S250	;CLASS 12- BIT,SET,RES
	DW	S268	;CLASS 13- INC,DEC
	DW	S301	;CLASS 14- PSEUDO OPERATORS
;
;	EJECT
;
;	CLASS 1 - OPCODE ONLY
;
S18	EQU	$
	MVI A,1	! STA LEN
	LDA OPCODE ! STA INST
	LDA OPCODE+1 ! ORA A ! JZ ENDSTMT ;BRANCH IF ONLY 1 BYTE
	MVI A,2	! STA LEN
	LDA OPCODE+1 ! STA INST+1
	JMP ENDSTMT
;
;	EJECT
;
;	CLASS 2 - ROTATES
;
S24	EQU	$
	CALL GNC ! CPI '(' ! JZ	S30 ;BRANCH IF () FORM
	CALL BACKUP ! CALL ID !	LXI H,IDBUF ! CALL SYMLUK ! JZ S27
	MVI A,'U' ! STA	ERRFLG ! JMP ENDSTMT ;BRANCH IF UNDEFINED OPERAND
S27	EQU	$
	LDA IDBUF ! CPI	'A' ! JZ S41 ;BRANCH IF A REGISTER
	MVI A,0CBH ! STA INST
	LDA OPCODE ! MOV B,A ! MOV A,M ! ORA B ! STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
S30	EQU	$
	CALL GNC ! CALL	GNC ! CPI 'L' !	JZ S40 ;BRANCH IF (HL)
	CPI 'Y'	! JZ S38 ;BRANCH IF (IY)
	MVI A,0DDH ! STA INST
S33	EQU	$
	MVI A,0CBH ! STA INST+1
	LDA OPCODE ! ADI 6 ! STA INST+3
	CALL GNC ;BYPASS +
	CALL EVAL
	LDA VAL	! STA INST+2
	MVI A,4	! STA LEN
	JMP ENDSTMT
S38	EQU	$
	MVI A,0FDH ! STA INST !	JMP S33	;DO IX AND IY SIMILARLY
;
S40	EQU	$
	MVI A,0CBH ! STA INST !	LDA OPCODE ! ADI 6 ! STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
S41	EQU	$	;COMPATIBILITY WITH RRA, ETC
	LDA OPCODE ! ORI 7 ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
;
;	EJECT
;
;	CLASS 3 - JUMPS - CALLS
;
S42	EQU	$
	CALL	GNC
	CPI '('	! JZ S53 ;BRANCH IF () FORM
	LHLD PTR1 ! MOV	A,M ! CPI ',' !	JZ S49 ;BRANCH IF CONDITIONAL TYPE
	INX H !	MOV A,M	! CPI ',' ! JZ S49
	LDA OPCODE ! STA INST !	MVI A,3	! STA LEN
	CALL BACKUP
S46	EQU	$
	CALL EVAL
	LHLD VAL ! SHLD	INST+1 ! JMP ENDSTMT
;
S49	EQU	$	;PROCESS CONDITIONAL JUMPS, CALLS
	LDA OPCODE ! ANI 0C6H !	STA INST ! MVI A,3 ! STA LEN
	LHLD SYMCND ! SHLD SYMPT ;SO NO CONFLICTS WITH REGISTER NAMES
	CALL BACKUP ! CALL EVAL	! LDA VAL ! RLC	! RLC !	RLC ! ANI 38H
	LXI H,SYM ! SHLD SYMPT ;PUT IT BACK THE WAY IT WAS
	MOV B,A	! LDA INST ! ORA B ! STA INST
	MVI A,3	! STA LEN
	JMP S46	;NOW GO PROCESS LIKE NON CONDITIONAL
;
S53	EQU	$	;PROCESS () FORM
	CALL GNC ! CALL	GNC ;GET REGISTER TYPE
	CPI 'L'	! JZ S58 ;BRANCH IF (HL)
	CPI 'Y'	! JZ S60
	MVI A,0DDH ! STA INST
S56	EQU	$
	MVI A,0E9H ! STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
S58	EQU	$
	MVI A,0E9H ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S60	EQU	$
	MVI A,0FDH ! STA INST !	JMP S56
;
;	EJECT
;
;	CLASS 4 - RELATIVE JUMPS (JR AND DJNZ)
;
;
S62	EQU	$
	CALL GNC
	LHLD PTR1 ! MOV	A,M ! CPI ',' !	JZ S68
	INX H !	MOV A,M	! CPI ',' ! JZ S68 ;BRANCH IF CONDITIONAL
	LDA OPCODE ! STA INST !	MVI A,2	! STA LEN
	CALL BACKUP ! CALL EVAL	! LDA VAL ! DCR	A ! DCR	A ! STA	INST+1
	JMP ENDSTMT
;
S68	EQU	$
	LHLD SYMCND ! SHLD SYMPT ;SO NOT CONFLICT WITH REG NAMES
	CALL BACKUP ! CALL EVAL	! LDA VAL ! RLC	! RLC !	RLC ! ANI 38H
	LXI H,SYM ! SHLD SYMPT ;PUT IT BACK
	ADI 20H	! STA INST ! MVI A,2 ! STA LEN
	CALL EVAL ! LDA	VAL ! DCR A ! DCR A ! STA INST+1 ! JMP ENDSTMT
;
;	EJECT
;
;
;	CLASS 5 - RESTARTS
;
;
S73	EQU	$
	CALL EVAL ! LDA	VAL ! ANI 38H !	ORI 0C7H ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
;	EJECT
;
;
;	CLASS 6 - ARITHMETIC OPCODES
;
;	ADD,SUB,ADC,SBC,AND,OR,XOR,CP
;
;
S77	EQU	$
	CALL GNC ! CPI '(' ! JZ	S85 ;BRANCH IF () FORM
	LHLD PTR1 ! INX	H ! MOV	A,M ! CPI ',' !	JZ S96A	;BR IF REG PAIR
	CALL BACKUP ! CALL EVAL	! LDA EVFLGS ! ANI RNAME ! JNZ S84
	LDA OPCODE ! ADI 0C6H !	STA INST ! LDA VAL ! STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
;	PROCESS REGISTER NAME
;
S84	EQU	$
	LDA OPCODE ! ADI 80H ! MOV B,A ! LDA VAL ! ADD B ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S85	EQU	$
	CALL GNC ! CALL	GNC ! CPI 'L' !	JZ S95
	CPI 'Y'	! JZ S93
	MVI A,0DDH ! STA INST
S88	EQU	$
	LDA OPCODE ! ADI 86H ! STA INST+1
	MVI A,3	! STA LEN
	CALL GNC
	CALL EVAL ! LDA	VAL ! STA INST+2 ! JMP ENDSTMT
;
S93	EQU	$
	MVI A,0FDH ! STA INST !	JMP S88
;
S95	EQU	$
	LDA OPCODE ! ADI 86H ! STA INST	! MVI A,1 ! STA	LEN ! JMP ENDSTMT
;
;
;	PROCESS REGISTER PAIR ADD,SUB,ADC,SBC
;
S96A	EQU	$
	CALL BACKUP ! CALL EVAL
	LDA VAL	! CPI 0FFH ;IX ! JZ S96H ! CPI 0FEH ;IY ! JZ S96J
	LDA OPCODE+1 ! CPI 9 ! JZ S96F
	MVI A,0EDH ! STA INST !	MVI A,2	! STA LEN
	CALL EVAL
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE+1 ! ADD B
	STA INST+1 ! JMP ENDSTMT
;
S96F	EQU	$
	CALL EVAL
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE+1 ! ADD B
	STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S96H	EQU	$
	MVI A,0DDH ! STA INST
	JMP S96K
;
S96J	EQU	$
	MVI A,0FDH ! STA INST
S96K	EQU	$
	CALL EVAL
	LDA VAL	! CPI 0FFH ! JNZ S96L !	CPI 0FEH ! JNZ S96L ! MVI A,4 !	STA VAL
S96L	EQU	$
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE+1 ! ADD B
	STA INST+1 ! MVI A,2 ! STA LEN ! JMP ENDSTMT
;
;	EJECT
;
;	CLASS 7 - I/O INSTRUCTIONS
;
;
S97	EQU	$
	LDA OPCODE ! CPI 0D3H !	JZ S107	;BRANCH IF OUT OPCODE
	CALL GNC ! CPI 'A' ! JNZ S104 ;BRANCH IF  8080 TYPE I/O
	CALL GNC ! CALL	GNC ! CALL EVAL	;GET PORT ADDRESS
	MVI A,0DBH ! STA INST !	LDA VAL	! STA INST+1 ! MVI A,2 ! STA LEN
	JMP ENDSTMT
;
S104	EQU	$
	CALL BACKUP ! CALL EVAL	;GET REGISTER NAME
	MVI A,0EDH ! STA INST
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 40H !	STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
S107	EQU	$	;PROCESS OUT INSTRUCTION
	CALL GNC ! CALL	GNC ! CPI 'C'  ! JNZ S109
	LHLD PTR1 ! MOV	A,M ! CPI ')' !	JZ S112
S109	EQU	$
	CALL BACKUP ! CALL EVAL	;GET PORT NUMBER
	MVI A,0D3H ! STA INST !	LDA VAL	! STA INST+1 ! MVI A,2 ! STA LEN
	JMP ENDSTMT
;
S112	EQU	$
	CALL GNC ! CALL	GNC
	CALL EVAL
	MVI A,0EDH ! STA INST
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 41H !	STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
;	EJECT
;
;	CLASS 8 - LD INSTRUCTIONS
;
;
;	THE FOLLOWING ARE STRINGS WHICH ARE SPECIAL OPERAND FORMS
;
LD1	DB	'A,I'
LD2	DB	'A,R'
LD3	DB	'I,A'
LD4	DB	'R,A'
LD5	DB	'SP,HL'
LD6	DB	'SP,IX'
LD7	DB	'SP,IY'
;
S116	EQU	$
	CALL GNC ! CALL	BACKUP ;POINT TO OPERAND FIELD
	LHLD PTR1 ;SET UP POINTER TO OPERAND FIELD
	LXI D,LD1 ! MVI	B,3 ! CALL CMPCHR ! JZ S171
	LXI D,LD2 ! MVI	B,3 ! CALL CMPCHR ! JZ S173
	LXI D,LD3 ! MVI	B,3 ! CALL CMPCHR ! JZ S175
	LXI D,LD4 ! MVI	B,3 ! CALL CMPCHR ! JZ S177
	LXI D,LD5 ! MVI	B,5 ! CALL CMPCHR ! JZ S179
	LXI D,LD6 ! MVI	B,5 ! CALL CMPCHR ! JZ S181
	LXI D,LD7 ! MVI	B,5 ! CALL CMPCHR ! JZ S183 ;PROCESS SPECIAL OPRNDS
;
	CALL GNC
	CPI '('	! JZ S185 ;BRANCH IF () FORM
	CALL BACKUP ! CALL EVAL
	LDA EVFLGS ! ANI RPNAME	! JNZ S147	;BRANCH IF RPAIR NAME
	CALL GNC ! CPI '(' ! JZ	S130 ;BRANCH IF () OPERAND
	LHLD VAL ! SHLD	SAVVAL
	CALL BACKUP ! CALL EVAL	! LDA EVFLAGS !	ANI RNAME ! JNZ	S128 ;> RNAME
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 6 ! STA INST
	LDA VAL	! STA INST+1 ! MVI A,2 ! STA LEN ! JMP ENDSTMT ;IMMED OPERAND
;
S128	EQU	$	;PROCESS RNAME
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA VAL ! ADD B
	ADI 40H	;FOR R-R TYPE INST
	STA INST ! MVI A,1 ! STA LEN ;REG-REG OPERAND
	JMP ENDSTMT
;
S130	EQU	$
	CALL GNC ! CALL	GNC
	CPI 'L'	! JZ S138
	CPI 'X'	! JZ S140
	CPI 'Y'	! JZ S145
	CALL BACKUP ! CALL BACKUP ! CALL EVAL
	LDA EVFLAGS ! ANI RPNAME ! JNZ S136 ;BRANCH IF REG PAIR
	MVI A,3AH ! STA	INST ! LHLD VAL	! SHLD INST+1
	MVI A,3	! STA LEN ! JMP	ENDSTMT
;
S136	EQU	$
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H
	ADI 0AH	! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S138	EQU	$
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H
	ADI 46H	! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S140	MVI A,0DDH ! STA INST
S140A	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 46H !	STA INST+1
	CALL GNC
	CALL EVAL ! LDA	VAL ! STA INST+2
	MVI A,3	! STA LEN
	JMP ENDSTMT
;
S145	EQU	$
	MVI A,0FDH ! STA INST !	JMP S140A
;
S147	EQU	$
	CALL GNC ! CPI '(' ! JZ	S159
	LHLD VAL ! SHLD	SAVVAL
	CALL BACKUP
	CALL EVAL
	LDA SAVVAL ! CPI 0FFH !	JZ S155	! CPI 0FEH ! JZ	S157
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! INR A ! STA INST
	LHLD VAL ! SHLD	INST+1 ! MVI A,3 ! STA LEN ! JMP ENDSTMT
;
S155	EQU	$
	MVI A,0DDH ! STA INST
S156	EQU	$
	MVI A,21H ! STA	INST+1 ! MVI A,4 ! STA LEN
	LHLD VAL ! SHLD	INST+2
	JMP ENDSTMT
;
S157	EQU	$
	MVI A,0FDH ! STA INST !	JMP S156
;
S159	EQU	$
	LHLD VAL ! SHLD	SAVVAL
	CALL EVAL
	LDA SAVVAL ! CPI 4 ! JZ	S165
	CPI 0FFH ! JZ S167
	CPI 0FEH ! JZ S169
	MVI A,0EDH ! STA INST
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 4BH ! STA INST+1
	LHLD VAL ! SHLD	INST+2 ! MVI A,4 ! STA LEN
	JMP ENDSTMT
;
S165	EQU	$
	MVI A,2AH ! STA	INST ! LHLD VAL	! SHLD INST+1 !	MVI A,3	! STA LEN
	JMP ENDSTMT
;
S167	EQU	$
	MVI A,0DDH ! STA INST
S168	MVI A,2AH ! STA	INST+1 ! LHLD VAL ! SHLD INST+2	! MVI A,4 ! STA	LEN
	JMP ENDSTMT
;
S169	EQU	$
	MVI A,0FDH ! STA INST !	JMP S168
;
S171	LXI H,57EDH
S171A	SHLD INST ! MVI	A,2 ! STA LEN !	JMP ENDSTMT
;
S173	LXI H,5FEDH ! JMP S171A
;
S175	LXI H,47EDH ! JMP S171A
;
S177	LXI H,4FEDH ! JMP S171A
;
S179	MVI A,0F9H ! STA INST !	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S181	LXI H,0F9DDH ! JMP S171A
;
S183	LXI H,0F9FDH ! JMP S171A
;
S185	JMP	S186
;
LD01	DB	'HL)'
LD02	DB	'IX+'
LD03	DB	'IY+'
;
S186	LHLD PTR1
	LXI D,LD01 ! MVI B,3 ! CALL CMPCHR ! JZ	S204
	LXI D,LD02 ! MVI B,3 ! CALL CMPCHR ! JZ	S210A
	LXI D,LD03 ! MVI B,3 ! CALL CMPCHR ! JZ	S210B
	CALL EVAL ! LHLD VAL ! SHLD SAVVAL
	LDA EVFLAGS ! ANI RPNAME ! JNZ S202
	CALL GNC	;BYPASS COMMA
	CALL EVAL ! LDA	EVFLAGS	! ANI RPNAME ! JNZ S193
	MVI A,32H ! STA	INST ! LHLD SAVVAL ! SHLD INST+1
	MVI A,3	! STA LEN ! JMP	ENDSTMT
;
S193	EQU	$
	LDA VAL
	CPI 4 !	JZ S196
	CPI 0FFH ! JZ S198
	CPI 0FEH ! JZ S200
;
	MVI A,0EDH ! STA INST
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 43H !	STA INST+1
	LHLD SAVVAL ! SHLD INST+2
	MVI A,4	! STA LEN ! JMP	ENDSTMT
;
S196	EQU	$
	MVI A,22H ! STA	INST
	LHLD SAVVAL ! SHLD INST+1 ! MVI	A,3 ! STA LEN !	JMP ENDSTMT
;
S198	EQU	$
	MVI A,0DDH ! STA INST
S199	EQU	$
	MVI A,22H ! STA	INST+1 ! LHLD SAVVAL ! SHLD INST+2
	MVI A,4	! STA LEN ! JMP	ENDSTMT
;
S200	EQU	$
	MVI A,0FDH ! STA INST !	JMP S199
;
S202	EQU	$
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 2 ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S204	EQU	$
	CALL GNC ! CALL	GNC ! CALL GNC ! CALL GNC
	CALL EVAL
	LDA EVFLAGS ! ANI RNAME	! JNZ S209
	MVI A,36H ! STA	INST ! LDA VAL ! STA INST+1 ! MVI A,2 !	STA LEN
	JMP ENDSTMT
;
S209	EQU	$
	LDA VAL	! ADI 70H ! STA	INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S210A	MVI A,0DDH ! STA INST !	JMP S211
S210B	MVI A,0FDH ! STA INST
S211	EQU	$
	CALL GNC ! CALL	GNC ! CALL GNC ! CALL EVAL
	LHLD VAL ! SHLD	SAVVAL
	CALL GNC	;BYPASS COMMA
	CALL EVAL
	LDA EVFLAGS ! ANI RNAME	! JNZ S218
	MVI A,36H ! STA	INST+1
	LDA SAVVAL ! STA INST+2	! LDA VAL ! STA	INST+3
	MVI A,4	! STA LEN ! JMP	ENDSTMT
;
S218	EQU	$
	LDA VAL	! ADI 70H ! STA	INST+1 ! LDA SAVVAL ! STA INST+2
	MVI A,3	! STA LEN ! JMP	ENDSTMT
;
;	EJECT		;END OF LD PROCESSING
;
;	CLASS 9 - PUSH POP
;
;
S220	EQU	$
	CALL EVAL
	LDA VAL	! CPI 0FFH ! JZ	S224 ! CPI 0FEH	! JZ S226
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE ! ADD B
	STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S224	EQU	$
	MVI A,0DDH ! STA INST
S225	EQU	$
	LDA OPCODE ! ADI 20H ! STA INST+1 ! MVI	A,2 ! STA LEN
	JMP ENDSTMT
;
S226	MVI A,0FDH ! STA INST !	JMP S225
;
;	EJECT
;
;
;	CLASS 10 - EXCHANGE (EX)
;
;
S228	EQU	$
	CALL GNC ! CPI '(' ! JZ	S235 ;BRANCH IF () FORM
	CPI 'A'	! JZ S233 ; BRANCH IF EX AF,AF'
	MVI A,0EBH ! STA INST !	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S233	EQU	$
	MVI A,8	! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S235	EQU	$
	LHLD PTR1 ! LXI	D,5 ! DAD D ! SHLD PTR1
	CALL GNC
	CPI 'L'	! JZ S239
	CPI 'Y'	! JZ S241
;
	MVI A,0DDH ! STA INST
S238	EQU	$
	MVI A,0E3H ! STA INST+1	! MVI A,2 ! STA	LEN ! JMP ENDSTMT
;
S239	EQU	$
	MVI A,0E3H ! STA INST !	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S241	EQU	$
	MVI A,0FDH ! STA INST !	JMP S238
;
;	EJECT
;
;
;	CLASS 11 - RETURNS
;
;
S243	EQU	$
	CALL GNC
	CPI 0AH	! JZ S248	;BRANCH IF NO OPERAND
	CPI 0DH	! JZ S248 ! CPI	';' ! JZ S248 ;BRANCH IF NO OPERAND
	LHLD SYMCND ! SHLD SYMPT ;FOR ELIMINATING REG NAME CONFLICTS
	CALL BACKUP ! CALL EVAL
	LXI H,SYM ! SHLD SYMPT ;PUT IT BACK
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! ADI 0C0H ! STA INST
	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
S248	EQU	$
	LDA OPCODE ! STA INST !	MVI A,1	! STA LEN ! JMP	ENDSTMT
;
;	EJECT
;
;	CLASS 12 - BIT,SET,RES
;
;
S250	EQU	$
	CALL EVAL ! LHLD VAL ! SHLD SAVVAL ;SAVE BIT NUMBER
	CALL GNC ! CPI '(' ! JZ	S257
	CALL BACKUP ! CALL EVAL
	MVI A,0CBH ! STA INST
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE !	ADD B
	MOV B,A	! LDA VAL ! ADD	B ! STA	INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
S257	EQU	$
	CALL GNC ! CALL	GNC ! CPI 'L' !	JZ S266
	CPI 'Y'	! JZ S264
;
	MVI A,0DDH ! STA INST
S260	CALL GNC
	CALL EVAL
	MVI A,0CBH ! STA INST+1	! LDA VAL ! STA	INST+2
	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 6 ! MOV B,A
	LDA OPCODE ! ADD B ! STA INST+3
	MVI A,4	! STA LEN ! JMP	ENDSTMT
;
S264	EQU	$
	MVI A,0FDH ! STA INST !	JMP S260
;
S266	EQU	$
	MVI A,0CBH ! STA INST !	LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H
	ADI 6 !	MOV B,A	! LDA OPCODE ! ADD B ! STA INST+1
	MVI A,2	! STA LEN ! JMP	ENDSTMT
;
;	EJECT
;
;	CLASS 13 - INC,DEC
;
;
S268	EQU	$
	CALL GNC ! CPI '(' ! JZ	S290
	CALL BACKUP ! CALL EVAL
	LDA EVFLAGS ! ANI RNAME	! JNZ S280
	LDA VAL	! CPI 0FFH ! JZ	S275 ! CPI 0FEH	! JZ S278
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE+1 ! ADD B
	STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S275	MVI A,0DDH ! STA INST
S276	LDA OPCODE+1 ! ADI 20H ! STA INST+1 ! MVI A,2 !	STA LEN
	JMP ENDSTMT
;
S278	EQU	$
	MVI A,0FDH ! STA INST !	JMP S276
;
S280	EQU	$
	LDA VAL	! RLC !	RLC ! RLC ! ANI	38H ! MOV B,A !	LDA OPCODE ! ADD B
	STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT
;
S290	EQU	$
	CALL GNC ! CALL	GNC
	CPI 'L'	! JZ S299
	CPI 'Y'	! JZ S297
	MVI A,0DDH ! STA INST
S293	CALL GNC ! CALL	EVAL
	LDA OPCODE ! ADI 30H ! STA INST+1 ! LDA	VAL ! STA INST+2
	MVI A,3	! STA LEN ! JMP	ENDSTMT
;
S297	EQU	$
	MVI A,0FDH ! STA INST !	JMP S293
;
S299	EQU	$
	LDA OPCODE ! ADI 30H ! STA INST	! MVI A,1 ! STA	LEN ! JMP ENDSTMT
;
;	EJECT
;
;	CLASS 14 - PSEUDO OPERATORS
;
;
S301	EQU	$
	LDA OPCODE ! DCR A ! ADD A
	MOV E,A	! MVI D,0 ! LXI	H,PSDTAB ! DAD D
	MOV E,M	! INX H	! MOV D,M
	XCHG
	PCHL
;
PSDTAB	EQU	$
	DW	S302	;EQU
	DW	S305	;DEFS
	DW	S308	;DEFB
	DW	S317	;DEFW
	DW	S320	;END
	DW	S323	;ORG
	DW	S324	;EJECT
	DW	S325	;IBM	FOR FORMATTING 3270 (ICC) SCREENS
;
;
S302	EQU	$	;EQU
	CALL EVAL ! LHLD VAL ! XCHG ! LHLD SYMADR
	MOV M,E	! INX H	! MOV M,D
	LHLD VAL ! SHLD	EQUVAL ! MVI A,1 ! STA EQUFLG
	JMP ENDSTMT
;
S305	EQU	$	;DEFS
	CALL EVAL ! LHLD VAL ! SHLD LEN2 ! JMP ENDSTMT
;
S308	EQU	$	;DEFB
	CALL GNC ! CPI 27H ! JZ	S313 ;BRANCH IF QUOTE
	CALL BACKUP ! CALL EVAL	! MVI A,1 ! STA	LEN
	LDA VAL	! STA INST
	JMP ENDSTMT
;
S313	EQU	$
	LXI D,INST
	LHLD PTR1
S313A	LDA LEN	! INR A	! STA LEN
	MOV A,M	! INX H	! STAX D ! INX D ! MOV A,M
	CPI 0DH	! JZ ENDSTMT ! CPI 27H ! JNZ S313A
	JMP ENDSTMT
;
S317	EQU	$
	CALL EVAL	;DEFW
	LHLD VAL ! SHLD	INST
	MVI A,2	! STA LEN
	JMP ENDSTMT
;
S320	EQU	$	;END
	CALL EVAL ! LHLD VAL ! SHLD ENDADR ! SHLD EQUVAL
S321	MVI A,1
	STA EQUFLG ! STA EFLG
	JMP ENDSTMT
;
S323	EQU	$	;ORG
	CALL EVAL ! LHLD VAL ! SHLD PC
	SHLD EQUVAL ! MVI A,1 !	STA EQUFLG
	JMP ENDSTMT
;
;
S324	EQU	$	;EJECT
	MVI A,MAXLNE-1 ! STA CURLNE ;CAUSE HOF ON RECORD AFTER EJECT
	JMP ENDSTMT	;TREAT THIS LIKE A COMMENT
;
;
S325	EQU	$	;IBM PSEUDO FOR 3270 (ICC 40+) SCREEN FORMATTING
	LXI H,INST ! SHLD TEMP ;SET UP FOR MULTI-BYTE OUTPUT
S325X	EQU	$
	CALL GNC ! CPI 27H ! JZ	S326 ;BRANCH IF LEADING QUOTE
;
;	DO HEX UNTIL COMMA FOUND
;
S325A	EQU	$
	CALL S325B ;CONVERT TO BINARY AND STORE AWAY
	LDA LEN	! INR A	! STA LEN ;INCREMENT LENGTH
	CALL GNC ;GET NEXT CHARACTER
	CPI ','	! JZ S326 ;IF COMMA THEN SWITCH TO ASCII
	CPI 0DH	! JNZ S325A ;BRANCH IF NOT DONE
	JMP ENDSTMT ;BRANCH IF CARRIAGE RETURN FOUND
;
;	DO ASCII UNTIL COMMA FOUND
;
S326	EQU	$
	LHLD PTR1 ! MOV	A,M ! INX H ! SHLD PTR1	;(GNC SKIPS BLANKS)
	CPI 0DH	! JZ ENDSTMT ;BRANCH IF END
	CPI ','	! JZ S325X ;BRANCH IF END OF ASCII- SWITCH BACK TO HEX
	LHLD TEMP ! MOV	M,A ! INX H ! SHLD TEMP	;PUT CHARACTER AWAY
	LDA LEN	! INR A	! STA LEN ;INCREMENT LENGTH COUNTER
	JMP S326 ;AND CONTINUE
;
;	CONVERT HEX TO BIN FOR 'IBM' PSEUDO (INTERNAL SUBROUTINE)
;
S325B	EQU	$
	LXI B,0	;SET UP FOR POSSIBLE SINGLE CHAR HEX DIG, ZERO B AND C
	CALL CNVDIG ;CONVERT DIGIT WE ALREADY HAVE
	CALL GNC
	CPI ','	! JZ S325D ! CPI 0DH ! JZ S325D	;BRANCH IF ONLY SINGLE DIGIT
	PUSH PSW ;SAVE CHARACTER
	MOV A,B	! RLC !	RLC ! RLC ! RLC	! ANI 0F0H ! MOV C,A ;SET UP
	POP PSW	! CALL CNVDIG ;CONVERT SECOND DIGIT
S325C	EQU	$	;NOW COMBINE THEM
	MOV A,B	! ORA C
	LHLD TEMP ! MOV	M,A ! INX H ! SHLD TEMP	;PUT CHARACTER AWAY
	RET
;
S325D	CALL BACKUP
	JMP S325C
;
CNVDIG	EQU	$	;CONVERT DIGIT TO BINARY (0-9 , A-F)
	CPI 'A'	! JC CNVD2 ;BRANCH IF NUMBER
	ADI 9 ;ADJUST 41 (A) TO 4A TO MAKE IT BINARY EQUIVALENT
CNVD2	ANI 0FH	! MOV B,A
	RET
;
;	EJECT
;
;
;	E N D	O F   S T A T E M E N T   P R O C E S S I N G
;
;
;	ENDSTMT------HERE IT IS!!!!
;
;
ENDSTMT	EQU	$
	LDA PASSNO ! ORA A ! JZ	S417	;DONT PRINT DURING PASS 1
	LDA UFLAG ! ORA	A ! JZ $+8 ! MVI A,'U' ! STA ERRFLG ! XRA A ! STA UFLAG
	LDA ERRFLG ! CPI ' ' ! JNZ S402	;ALWAYS PRINT ERRORS
	LDA LFLAG ! CPI	'N' ! JZ S412 ;DON'T PRINT IF USER ASKED US NOT TO
S402	EQU	$
	LDA ERRFLG ! STA HDRBUF
	MVI A,' ' ! STA	HDRBUF+1
	LXI H,HDRBUF+2 ! LXI D,HDRBUF+1	! LXI B,14 ! CALL MOVE
	LDA EQUFLG ! ORA A ! JNZ S410 ;BRANCH IF TO USE EQUVAL
	LHLD PC	! XCHG ! LXI H,HDRBUF+1
	MOV A,D	! CALL CNV2HX
	MOV A,E	! CALL CNV2HX
	INX H
	LXI D,INST
	MVI C,4	! LDA LEN ! MOV	B,A
	ORA A !	JZ S408	;BRANCH IF LENGTH IF ZERO
S406	EQU	$
	LDAX D ! CALL CNV2HX
	INX D
	DCR B !	JZ S408
	DCR C !	JNZ S406
S408	EQU	$
	LXI H,HDRBUF ! CALL PLINE ;WRITE AND PAGE
	JMP S412
;
S410	EQU	$
	LHLD EQUVAL ! XCHG ! LXI H,HDRBUF+1
	MOV A,D	! CALL CNV2HX
	MOV A,E	! CALL CNV2HX
	LXI H,HDRBUF ! CALL PLINE
;
S412	EQU	$
	LDA LEN	! ORA A	! JZ S417
	MOV B,A
	LXI D,INST
	LHLD PC	! SHLD TEMP
S414	EQU	$
	PUSH B
	LDAX D ! LHLD TEMP ! CALL WOBJ
	POP B
	INX D
	LHLD TEMP ! INX	H ! SHLD TEMP
	DCR B !	JNZ S414
;
S417	EQU	$
	LHLD PC	! LDA LEN ! MOV	C,A ! MVI B,0 !	DAD B
	XCHG ! LHLD LEN2 ! DAD D ! SHLD	PC
	LDA EFLG ! ORA A ! JZ NEXT ;GO PROCESS NEXT RECORD
	LDA PASSNO ! CMA ! STA PASSNO
	CPI 0 !	JZ ENDIT
	LXI H,FCB1+12 !	MVI M,0
	LXI D,FCB1 ! CALL OPNFIL
	LXI H,FCB1+32 !	MVI M,0
	LXI H,INBUF+1024 ! SHLD	IBP
	XRA A !	STA EFLG	;RESET END OF RECORD FLAG
	LXI H,0	! SHLD PC	;RESET PC
	MVI A,1	! STA PAGENO	;SET UP PAGE NUMBER
	MVI A,MAXLNE+1 ! STA CURLNE
	LXI D,-1 ! SHLD	OBJADR
	JMP NEXT
;
ENDIT	EQU	$
	LDA HFLAG ! CPI	'N' ! JZ ENDITX	;BRANCH IF NO HEX FILE
	LDA OBJCNT ! ORA A ! JZ	ENDIT1 ;BRANCH IF NO OBJ TO WRITE
	CALL WREC	;ELSE WRITE FINAL RECORD
ENDIT1	LXI H,EOFREC ! MVI B,13
ENDIT2	MOV A,M	! CALL WNB2 ! INX H ! DCR B ! JNZ ENDIT2
	MVI B,255	;FLUSH BUFFER
ENDIT3	MVI A,1AH ! CALL WNB2 !	DCR B !	JNZ ENDIT3
	LXI D,FCB2 ! CALL CLSFIL
ENDITX	EQU	$
	LHLD PC	! XCHG ! LXI H,PCMSGA
	MOV A,D	! CALL CNV2HX !	MOV A,E	! CALL CNV2HX
	LXI D,PCMSG ! CALL WMSG
	LHLD SYMPTR ! XCHG ! LXI H,SYMSGA
	MOV A,D	! CALL CNV2HX !	MOV A,E	! CALL CNV2HX
	LXI D,SYMSG ! CALL WMSG
	LXI D,ENDMSG ! CALL WMSG
	JMP	0000H
PCMSG	DB	13,10,'LAST ADDRESS USED IN THIS ASSEMBLY IS: '
PCMSGA	DB	'XXXX','$'
;
SYMSG	DB	13,10,'NEXT SYMBOL ADDRESS IS: '
SYMSGA	DB	'XXXX$'
;
ENDMSG	DB	13,10,10,'Z-80 ASSEMBLY COMPLETE',13,10,10,'$'
;
EOFREC	DB	':00000001FF',13,10
;
;	EJECT
;
;	WOBJ - WRITE OBJECT BYTE ROUTINE
;
;	INPUT BYTE IN A REGISTER
;
WOBJ	EQU	$
	MOV B,A	;SAVE INPUT
	LDA HFLAG ! CPI	'N' ! RZ ;RETURN IF NO HEX FILE
	MOV A,B	;GET INPUT CHARACTER BACK
	PUSH D ! PUSH PSW
	PUSH H ! LHLD OBJADR ! LXI D,-1
	CALL CMPHD ! POP H ! JZ	WOBJ0 ;BRANCH IF FIRST TIME THROUGH
	XCHG ! LHLD OLDADR ! INX H ! CALL CMPHD	! JZ WOBJ1 ;BRA IF NEXT SEQ BYT
	CALL WREC
WOBJ0	EQU	$
	XCHG ! SHLD OBJADR ! XCHG
	XRA A !	STA OBJCNT
WOBJ1	EQU	$
	XCHG ! SHLD OLDADR
	LDA OBJCNT ! CPI 10H ! JC WOBJ2	;BRANCH IF NOT TIME TO WRITE
	CALL WREC
	LHLD OBJADR ! LXI D,16 ! DAD D ! SHLD OBJADR ;ADVANCE ADDR
	XRA A !	STA OBJCNT
WOBJ2	EQU	$
	INR A !	STA OBJCNT	;UPDATE COUNT
	DCR A !	MOV E,A	! MVI D,0 ! LXI	H,OBJ !	DAD D
WOBJ3	POP PSW	! MOV M,A
	POP D
	RET
;
;	WREC - FORMAT AND WRITE HEX RECORD
;
;
WREC	EQU	$
	PUSH H ! PUSH D
	LHLD OLDADR ! LXI D,-1 ! CALL CMPHD ! JZ WREC3 ;BRANCH IF FIRST TIME
	LDA OBJCNT ! MOV C,A ! MOV B,A ;SET CHKSUM AND COUNT
	LXI H,REC ! MVI	M,':' !	INX H
	MOV A,B	! CALL CNV2HX
	LDA OBJADR+1 ! ADD C ! MOV C,A ! LDA OBJADR+1 !	CALL CNV2HX
	LDA OBJADR   ! ADD C ! MOV C,A ! LDA OBJADR ! CALL CNV2HX
	XRA A !	CALL CNV2HX
	LXI D,OBJ
WREC1	EQU	$
	LDAX D ! ADD C ! MOV C,A ! LDAX	D ! CALL CNV2HX
	INX D !	DCR B !	JNZ WREC1
	MOV A,C	! CMA !	INR A !	CALL CNV2HX
	MVI M,0DH ! INX	H ! MVI	M,0AH	;PUT CRLF ON END
	LXI H,REC	;WRITE OUT RECORD
WREC2	EQU	$
	MOV A,M	! CALL WNB2
	MOV A,M	! CPI 0AH ! INX	H ! JNZ	WREC2 ;GO UNTIL LF
WREC3	EQU	$
	POP D !	POP H
	RET
;
;	EJECT
;
;
;	PLINE ROUTINE - WRITE AND PAGE
;
;
PLINE	EQU	$
	LDA CURLNE ! CPI MAXLNE	! JC PLINE1 ;BRANCH IF LESS
	LXI D,FCB1+1 ! LXI H,HOFNAM ! LXI B,8 !	CALL MOVE ;GET FILE NAME
	LXI H,HOFPG ! LDA PAGENO ! CALL	CNV2HX
	LDA HOFPG ! CPI	'0' ! JNZ $+8 !	MVI A,' ' ! STA	HOFPG
	LDA PAGENO ! ADI 1 ! DAA ! STA PAGENO
	LXI H,HOFMSG ! CALL WLINE ! XRA	A
PLINE1	EQU	$
	INR A !	STA CURLNE
	LXI H,HDRBUF ! CALL WLINE
	RET
;
HOFMSG	EQU	$
	DB 0DH,8AH,0DH,8AH,0CH
	DB 'Z80ASM-2.0A (C) 1977 LCS'
	DB 0DH,8AH,0DH,8AH
	DB 'SOURCE FILE NAME: '
HOFNAM	DB 'XXXXXXXX           PAGE # '
HOFPG	DB	'XX'
	DB 8AH,0DH,8AH,0DH,0AH
;
;
;	EJECT
;
;
