;
;****************************************************************
;*								*
;*								*
;*		DRIVER UTILITY FOR SD SYSTEMS			*
;*		  PROM-100 EPROM PROGRAMMER			*
;*		2758  -  2716  -  2732	VERSION			*
;*								*
;*								*
;****************************************************************
;
;
;	Modified by :	Bill Bolton
;			Software Tools
;			P.O. Box 80
;			Newport Beach
;			NSW, 2106
;
;	Dec 29, 1979	Initial bugs removed
;		
;	Jan  3, 1980	Comments added and minor improvements
;
;	Jan  4, 1980	2716 file created from 2708 file
;
;	Jan 16,	1980	First PROM address not programmed debug
;
;	Jan 22, 1982	8080 version created and SPEED equate added
;			plus other minor internal changes
;
WBOOT	EQU	0
BDOS	EQU	00005H		;BDOS ENTRY ADDRESS
FCB	EQU	0005CH		;DEFAULT FILE CONTROL BLOCK
OPEN	EQU	15
SETDMA	EQU	26
ATTRIB	EQU	471BH		;ADM VIDEO ATTRIBUTE LEAD-IN
DATA	EQU	068H		;PROM-100 DATA PORT
LADD	EQU	069H		;PROM-100 LOW ADDRESS PORT
HACTL	EQU	06AH		;PROM-100 CONTROL PORT
SPEED	EQU	6		;PROCESSOR SPEED IN MHZ
ACR	EQU	0DH		;ASCII CARRAIGE RETURN
ALF	EQU	0AH		;ASCII LINE FEED
;
	TITLE	'PROM16 - 8080 VERSION FOR CP/M'
;
	MACLIB	MACRO3		;Use Software Tools special macros
;
	ORG	0100H
;
;
	LXI	SP,SPVAL
	LXI	H,MESG1		;SIGN ON MESSAGE
	CALL	PTXT		;PRINT IT
	MVI	A,080H		;INIT BUFFER COUNT TO FULL
	STA	BUFCNT		;STORE IT
	XRA	A		;RESET A TO 0
	STA	OPENFL		;RESET FILE OPEN FLAG
INITIAL:
	LXI	SP,SPVAL
	XRA	A
	OUT	HACTL		;INIT PROM-100 BOARD
	CALL	CRLF
	LXI	H,MESG2		;READY TO LOAD MESSAGE
	CALL	PTXT
	LXI	H,0		;RESET HL
	SHLD	COUNT		;RESET COUNT
	CALL	YORN		;YES OR NO?
	JNC 	READ2		;NO, GO ASK IF A PROM
				;IS TO BE READ
;
FILEOPN:
	CALL	CRLF			
	LDA	OPENFL		;GET FILE OPEN FLAG
	ORA	A		;IS FILE OPEN?
	JNZ	FILER		;YES, CONTINUE TO READ IT
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,OPEN		;OPEN FILE
	LXI	D,FCB		;FCB ADDRESS
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	CPI	0FFH		;SUCESSFUL OPEN?
	JNZ	FILER		;YES, GO READ IT
	LXI	H,MESG7		;NO, FILE NOT FOUND
	CALL	PTXT
	JMP	EXIT 		;BACK TO CP/M
;
FILER:
	PUSH	D
	PUSH	B
	MVI	C,SETDMA	;SET DISK BUFFER
	LXI	D,00080H	;BUFFER ADDRESS
	CALL	BDOS
	POP	B
	POP	D
	LXI	H,MESG3		;LOAD & BYTES MESSAGE
	CALL	PTXT
	CALL	SCAN$OP		;GET OPERANDS FROM KEYBOARD
	LDA	NXCHAR		;GET FINAL CHARACTER
	CPI	'.'		;IS IT ENTRY ABORT CHAR?
	JZ 	FILEOPN		;YES, REPROCESS THE LOOP
	LXI	H,MESG9		;NO, LOAD START MESSAGE
	CALL	PTXT
	LHLD	OPR1		;POINT TO FIRST OPERAND
	CALL	PADDR		;PRINT IT IN HEX
	CALL	CRLF
	CALL	HXREC		;GET START OF NEXT HEX RECORD
	PUSH	H
	LDED	OPR1		;GET MEM START ADDRESS
	LDA	OPCNT		;GET NUMBER OF OPS ENTERED
	ANA	A		;DETERMINE IF ZERO?
	JZ 	FILER1		;YES, LOAD FILE AT OWN ADDRESS
	DSUB			;FORM LOAD OFFSET INTO MEMORY
	PUSH	H		;COPY OFFSET
	POP	D		; INTO DE
FILER1:
	POP	H		;GET FILE START ADDRESS
	SDED	OFFSET		;(OFFSET = 0 IF NO OPERAND)
	JMP	FILER3
;
FILER2:
	CALL	HXREC
FILER3:
	LDED	OFFSET		;GET LOAD OFFSET
	ORA	A
	DSUB			;FORM LOAD ADDRESS
LOADLP:
	CALL	HEXBIN		;GET A BYTE
	MOV	M,A		;PUT INTO MEMORY
	SHLD	LDPOINT		;SAVE LOAD ADDRESS POINTER
	INX	H		;BUMP THE LOAD ADDRESS
	PUSH	H
	LHLD	COUNT
	INX	H		;BUMP THE LOAD COUNT
	SHLD	COUNT
	POP	H
	DCX	B		;BC < NUMBER OF BYTES IN HEX RECORD
	MOV	A,B
	ORA	C
	JNZ	LOADLP
	CALL	HEXBIN		;FETCH HEX RECORD CHECKSUM
	XRA	A		;RESET A
	ADD	C		;CHECKSUM ERROR?
	JZ 	ENDCHK		;NO, CHECK FOR END
	PUSH	H		;YES, SAVE THE ADDRESS
	LXI	H,MESG10	;CHECKSUM ERROR MESSAGE
	CALL	PTXT
	POP	H		;RESTORE THE ADDRESS
	CALL	PADDR		;PRINT ERROR ADDRESS
ENDCHK:
	LHLD	COUNT		;COUNT OF BYTES LOADED
	LBCD	OPR2		;NUMBER OF BYTES REQUIRED
	DCX	H
	DCX	B
	ANA	A
	BSUB			;MORE BYTES TO LOAD?
	JC 	FILER2		;YES, GET THEM
;
LDEND:
	LXI	H,MESG11	;LOAD END ADDR MESSAGE
	CALL	PTXT
	LHLD	LDPOINT		;GET LOAD END ADDRESS
	CALL	PADDR		;PRINT HEX ADDRESS
;
PPG10A:
	CALL	CRLF
	LXI	H,MESG4		;READY TO PROG MESSAGE
	CALL	PTXT
	CALL	YORN		;YES OR NO?
	JNC 	EXIT		;NO, EXIT
;
PPG11:
	CALL	CRLF
	LXI	H,MESG5		;YES, MEM START ETC. MESSAGE
	CALL	PTXT
	CALL	SCAN$OP		;GET OPERANDS
	LDA	NXCHAR
	CPI	'.'		;ENTRY ABORT CHARACTER?
	JZ 	PPG11		;YES, REPROCESS LOOP
	JMP	PROG 		;NO, GO PROGRAM EPROM
;
;
; LOOKS FOR START OF A HEX RECORD AND RETURNS
; FIRST DATA BYTE IN A, BYTE COUNT IN B &
; RECORD LOAD ADDRESS IN HL
;
;
HXREC:
	CALL	BUFFR		;GET AN ASCII BYTE
	CPI	':'		;IS IT HEX RECORD START?
	JNZ	HXREC		;NO, KEEP LOOKING
	XRA	A		;RESET A
	MOV	C,A		;RESET C
	CALL	HEXBIN		;GET A 'HEX' BYTE
	ANA	A		;IS IT 0?
	JZ 	HXREC1		;YES, MUST BE AT END
	MOV	B,A		;NO, # BYTES IN HEX RECORD
	CALL	HEXBIN		
	MOV	H,A		;HI BYTE OF LOAD
	CALL	HEXBIN
	MOV	L,A		;LO BYTE OF LOAD
	CALL	HEXBIN		;GET FIRST DATA BYTE
	RET	
;
HXREC1:
	POP	PSW
	JMP	LDEND 
;
;
; DETERMINE IF Y, N OR ABORT ANSWER
;
;
YORN:
	CALL	ECHO
	CPI	'.'
	JZ 	EXIT
	ORA	A
	CPI	'N'
	RZ	
	CPI	'Y'
	JNZ	YORN
	STC 
	RET	
;
;
; CONSOLE STATUS, INPUT AND OUTPUT
;
;
CONSTAT:
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,11
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	ORA	A
	RET	
;
CONIN:
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,1
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	MOV	C,A		;NEED A & C TO RETURN CHAR
	RET	
;
CONOUT:
	PUSH	H
	PUSH	D
	PUSH	B
	MOV	E,C
	MVI	C,2
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	MOV	C,E		;NEED C TO RETURN CHAR
				;SENT
	RET	
;
;
; CLOSE FILE AND EXIT BACK TO CP/M
;
;
EXIT:
	XRA	A
	OUT	HACTL
	CALL	CRLF
	LDA	OPENFL
	ORA	A
	JZ 	WBOOT
	MVI	C,16
	LXI	D,FCB
	CALL	BDOS
	JMP	WBOOT 
;
;
; PRINT VALUE IN ACCUMULATOR AS AN ASCII 'HEX' VALUE
;
;
PADDR:
	MOV	A,H		;HI BYTE OF ADDRESS
	CALL	PACC		;PRINT A AS HEX VALUE
	MOV	A,L		;LO BYTE OF ADDRESS
	JMP	PASP 		;PRINT<A, ' ' CRLF
;
;
MESG1:
	DB	ACR,ALF
	DB	'Software Tools PROM-100 Driver utility for 2758/2716/2732 EPROMs'
	DB	ACR,ALF
	DB	'Version 1.13 for '
	DB	SPEED + '0',' MHz Z80/8080, January 1982'
	DB	ACR,ALF
	DB	'$'
;
MESG2:
	DB	'Ready to load a hex file (Y/N)? '
	DB	'$'
;
MESG3:
	DB	'Load address, Number of bytes to load : '
	DB	'$'
;
MESG4:
	DB	'Ready to program a PROM  (Y/N)? '
	DB	'$'
;
MESG5:
	DB	'Memory start, Memory end, PROM start  : '
	DB	'$'
;
MESG6:
	DB	'Ready  to  read  a  PROM (Y/N)? '
	DB	'$'
;
MESG7:
	DB	ACR,ALF
	DW	ATTRIB
	DB	'4'
	DB	' FILE NOT FOUND '
	DW	ATTRIB
	DB	'0'
	DB	'$'
;
MESG8:
	DB	ACR,ALF
	DW	ATTRIB
	DB	'4'
	DB	' Attempting to read past end of disk file '
	DW	ATTRIB
	DB	'0'
	DB	'$'
;
MESG9:
	DB	ACR,ALF
	DB	'Load start address = '
	DB	'$'
;
MESG10:
	DW	ATTRIB
	DB	'4'
	DB	'Checksum error at location : '
	DW	ATTRIB
	DB	'0'
	DB	'$'
;
MESG11:
	DB	'Load end address   = '
	DB	'$'
;
;
; PROM READ SEQUENCE
;
;
READ2:
	CALL	CRLF
	LXI	H,MESG6		;READY TO READ MESSAGE
	CALL	PTXT
	CALL	YORN
	JNC 	PPG10A		;NO, THEN PROGRAM
READ0:
	CALL	CRLF
	LXI	H,MESG5		;MEM START ETC. MESSAGE
	CALL	PTXT
	CALL	SCAN$OP		;INPUT PARAMETERS
	LDA	NXCHAR
	CPI	'.'
	JZ 	READ0
	MVI	A,040H		;TURN ON PROM VOLTAGE
	OUT	HACTL	
	LHLD	OPR1		;MEM START ADDRESS
	LDED	OPR3		;PROM START ADDRESS
READ1:
	CALL	PREAD		;READ A BYTE OF PROM
	MOV	M,A		;SAVE BYTE IN MEMORY
	CALL	ADCMP		;INC ADDRESS AND COMPARE
	JNZ	READ1		;IF NOT END, READ NEXT BYTE
	XRA	A		;TURN OFF PROM
	OUT	HACTL
	JMP	PPG10A 		;PROGRAM SEQUENCE
;
;
; INC HL & DE THEN COMPARE WITH (IX)
; EXIT WITH ZERO FLAG SET IF EQUAL
;
;
ADCMP:
	INX	D		;INC PROM ADDRESS
	MOV	A,D
	ANI	00FH		;MAX PROM ADDR =00FFFH
	MOV	D,A
	INX	H
	PUSH	D
	PUSH	H		;SAVE HL & DE
	LDED	OPR2		;GET RAM END ADDRESS
	INX	D
	ANA	A
	CPHL			;COMPARE
	POP	H
	POP	D
	RET	
;
;
; PROGRAMMING SEQUENCE
;
;
PROG:
	MVI	A,40
	OUT	HACTL		;TURN ON PROM VOLTAGE
	LHLD	OPR1		;MEM START ADDRESS
	LDED	OPR3		;PROM START ADDRESS
PROG1:
	CALL	PREAD		;READ A BYTE FROM PROM
	CPI	0FFH		;ERASED?
	JNZ	PROG2		;NO, PRINT ERROR
PROG1A:
	CALL	ADCMP		;INC ADDRESS & CHECK FOR END
	JNZ	PROG1
	JMP	PROG3		;ALL OK, PROGRAM PROM
;
PROG2:
	PUSH	H
	LXI	H,MESG13	;NOT ERASED MESSAGE
	CALL	PTXT
	POP	H
	IN	DATA
	CALL	PRTER		;PRINT BAD LOCATION
	CALL	ECHO		;READ CONSOLE
	CPI	'.'		;ABORT?
	JZ 	PROG9
	CPI	'C'		;CONTINUE?
	JZ 	PROG3
	JMP	PROG1A		;CHECK MORE LOCATIONS
;
PROG2A:
	MVI	A,000H
	OUT	HACTL
	JMP	INITIAL 
;
PROG3:
	CALL	CRLF
PROG4:
	LHLD	OPR1		;MEM START ADDRESS
	LDED	OPR3		;PROM START ADRESS
PROG5:
	CALL	PPROG		;PROGRAM ONE BYTE
	CALL	CONSTAT
	JZ 	PROG5A
	CALL	CONIN
	CPI	'.'
	JZ 	PROG9
PROG5A:
	CALL	ADCMP		;INC ADDRESS & CHECK FOR END
	JNZ	PROG5		;FINISH THIS LOOP
;
PROG6:
	MVI	A,0
	OUT	HACTL		;TURN OFF ALL CONTROL LINES
PROG6A:
	LHLD	OPR1		;MEM START ADDRESS
	LDED	OPR3		;PROM START ADDRESS
PROG7:
	CALL	PREAD		;READ PROM DATA
	CMP	M		;COMPARE TO MEMORY DATA
	JNZ	PROG8		;ERROR IF NOT MATCHED
PROG7A:
	CALL	ADCMP		;INC ADDRESS & CHECK FOR END
	JNZ	PROG7
	JMP	PROG2A		;EXIT, COMPLETE
;
PROG8:
	PUSH	PSW
	PUSH	H
	LXI	H,MESG14	;BAD LOCATION MESSAGE
	CALL	PTXT
	POP	H
	CALL	CONSTAT
	JZ 	PROG8A
	CALL	CONIN
	CPI	'.'		;ABORT?
	JZ 	PROG9
PROG8A:
	POP	PSW
	CALL	PRTER		;PRINT THE ERROR MESSAGE
	JMP	PROG7A		;CHECK MORE LOCATIONS
;
PROG9:
	LXI	H,MESG15	;ABORTED MESSAGE
	CALL	PTXT
	JMP	PROG2A
;
;
; PULSE ONE PROM LOCATION
;
;
PPROG:
	CALL	PADD		;LATCH LSB OF ADDRESS
	MOV	A,D
	ANI	00FH		;MAX ROM ADDRESS =00FFFH
	ORI	0C0H
	OUT	HACTL
	MOV	A,M		;FETCH DATA
	OUT	DATA		;OUTPUT TO PROM
	MOV	A,D
	ORI	0E0H		;TURN ON PROGRAMING PULSE
	OUT	HACTL
	MVI	A,50
	CALL	DELAY		;1 MILLISEC DELAY
	MOV	A,D
	ORI	0C0H
	ANI	0C7H		;TURN OFF PROGRAMING PULSE
	OUT	HACTL
	RET	
;
DELAY:
	LXI	B,26 * SPEED	;DELAY COUNT DEPENDS ON PROC SPEED
	PUSH	PSW
DELAY1:
	DCX	B		;ADJUST INNER COUNT
	MOV	A,B
	ORA	C		;DONE?
	JNZ	DELAY1 		;NO
	POP	PSW		;YES
	DCR	A		;ADJUST OUTER COUNT
	JNZ	DELAY
	RET	
;
;
; READ ONE LOCATION OF PROM
;
;
PREAD:
	CALL	PADD		;LATCH LSB OF ADDRESS
	MOV	A,D
	ORI	40H
	OUT	HACTL
	IN	DATA
	RET	
;
;
; LATCH LOWER 8 BITS OF PROM ADDRESS
;
;
PADD:
	MOV	A,E
	OUT	LADD
	RET	
;
;
; PRINTS ADDRESS, BAD DATA, GOOD DATA
; OF ERROR LOCATION
;
;
PRTER:
	MOV	B,A
	MOV	A,D
	CALL	PACC		;PRINT MSB OF ADDRESS
	MOV	A,E
	CALL	PACC		;PRINT LSB
	MVI	C,' '
	CALL	CONOUT
	MOV	A,B
	CALL	PACC		;PRINT BAD DATA
	MVI	C,' '
	CALL	CONOUT
	MOV	A,M
	CALL	PACC		;PRINT GOOD DATA
	CALL	CRLF
	RET	
;
;
MESG13:
	DW	ATTRIB
	DB	'4'
	DB	'Not Erased'
	DW	ATTRIB
	DB	'0'
	DB	' : '
	DB	'$'
;
MESG14:
	DW	ATTRIB
	DB	'4'
	DB	'Bad location'
	DW	ATTRIB
	DB	'0'
	DB	' : '
	DB	'$'
;
MESG15:
	DW	ATTRIB
	DB	'4'
	DB	' ABORTED '
	DW	ATTRIB
	DB	'0'
	DB	ACR,ALF
	DB	'$'
;
;
; GET A BYTE FROM AN INTEL 'HEX' FORMAT FILE
; AND RETURN WITH IT IN BINARY FORM IN A
;
;
HEXBIN:
	CALL	BUFFR		;GET AN ASCII BYTE
	CALL	ASBIN		;MAKE IT BINARY
	RLC 
	RLC 
	RLC 
	RLC 
	PUSH	B
	MOV	C,A
	CALL	BUFFR
	CALL	ASBIN
	ORA	C
	POP	B
	PUSH	PSW
	ADD	C
	MOV	C,A
	POP	PSW
	RET	
;
;
; ASCII TO BINARY CONVERSION
;
;
ASBIN:
	SUI	'0'
	CPI	10
	RM	
	SUI	007H
	RET	
;
;
; UTILITY PRINT ROUTINES
;
;
PASP:
	PUSH	B
	CALL	PACC
	CALL	SPACE
	CALL	CRLF
	POP	B
	RET	
;
CRLF:
	MVI	C,ACR
	CALL	CONOUT
	MVI	C,ALF
	JMP	CONOUT 
;
SPACE:
	MVI	C,' '
	JMP	CONOUT 
;
PTXT:
	MOV	A,M		;FETCH A BYTE
	CPI	'$'
	RZ	
	MOV	C,A
	CALL	CONOUT
	INX	H
	JMP	PTXT 
;
PACC:
	PUSH	PSW
	RRC 
	RRC 
	RRC 
	RRC 
	CALL	PRVAL
	POP	PSW
PRVAL:
	ANI	00FH
	ADI	090H
	DAA
	ACI	040H
	DAA
	MOV	C,A
	JMP	CONOUT 
;
;
; CHECK FOR VALID ASCII 'HEX' CHARACTER
;
;
AORN:
	CPI	'0'
	JC 	AORN2
	CPI	'9'+1
	JC 	AORN1
	CPI	'A'-1
	JC 	AORN2
	CPI	'F'+1
	JNC 	AORN2
AORN1:
	XRA	A
	RET	
;
AORN2:
	XRA	A
	INR	A
	RET	
;
;
; CHECK FOR ENTRY TERMINATOR:
;
; SPACE, COMMA OR CARRIAGE RETURN
;
;
TERMCHK:
	CPI	' '
	RZ	
	CPI	','
	RZ	
	CPI	'.'
	JZ 	TCHK0
	CPI	00DH
	RNZ	
TCHK0:
	PUSH	B
	CALL	CRLF
	POP	B
	XRA	A
	RET	
;
;
; SCAN FOR OPERAND FROM CONSOLE
;
; EXIT WITH DATA IN HL, TERMINATOR
; IN C. IF VALID DATA, RETURN WITH
; ZERO FLAG SET. B CONTAINS NUMBER
; OF CHARACTERS ENTERED
;
;
KEYIN:
	LXI	H,0
	MOV	B,L
KEY1:
	CALL	ECHO
	INR	B		;INC CHARACTER COUNT
	CALL	TERMCHK		;TERMINATOR?
	RZ	
	CALL	AORN		;CHECK FOR VALID DATA
	RNZ	
	MOV	A,C
	CALL	ASBIN		;CONVERT TO BINARY
	DAD	H
	DAD	H
	DAD	H
	DAD	H		;SHIFT 4 BITS
	ADD	L
	MOV	L,A
	JMP	KEY1 
;
ECHO:
	JMP	CONIN 		;CP/M DOES ITS OWN ECHO
;
INVCMD:
	MVI	C,'?'
	CALL	CONOUT
	MVI	A,'.'
	STA	NXCHAR
	RET	
;
SCAN$OP:
	XRA	A		;INITIALISE
	STA	OPCNT
	LXI	H,OPR1		;CLEAR OPERANDS
	SHLD	OP$POINT$
	MOV	M,A		;RESET HL
	LXI	B,9
	LXI	D,OPRS+1
SCLOOP:
	MOV	A,M		;GET A BYTE
	STAX	D		;PUT A BYTE
	INX	H		;BUMP POINTERS
	INX	D
	DCX	B		;ADJUST COUNT
	MOV	A,B
	ORA	C		;DONE?
	JNZ	SCLOOP		;NO
SCAN1:
	CALL	KEYIN		;GET 1 OPERAND FROM CONSOLE
	JNZ 	INVCMD
	MOV	A,C
	STA	NXCHAR
	CPI	' '
	JZ 	SCAN2
	CPI	','
	JZ 	SCAN2
	DCR	B
	RZ			;RETURN IF NO DATA
SCAN2:
	PUSH	D		;PRESERVE CONTENTS OF D
	XCHG			;DE < DATA
	LHLD	OP$POINT	;GET POINTER
	MOV	M,E		;PUT LOW BYTE
	INX	H
	MOV	M,D		;PUT HIGH BYTE
	INX	H
	SHLD	OP$POINT	;STORE POINTER
	POP	D
	LDA	OPCNT
	INR	A		;BUMP OPERAND COUNT
	STA	OPCNT
	MOV	A,C
	CPI	' '
	JZ 	SCAN1
	CPI	','
	JZ 	SCAN1
	RET	
;
BUFFR:
	PUSH	H		;SAVE,
	PUSH	D		;THE,
	PUSH	B		;ENVIRONMENT
	LDA	BUFCNT		;GET POS OF LAST BYTE
				;READ FROM BUFFER
	CPI	080H		;AT END OF THE RECORD?
	JNZ	BUFFR1		;NO, GET NEXT BYTE
	MVI	C,20		;READ NEXT FILE RECORD
	LXI	D,FCB		;FCB ADDRESS
	CALL	BDOS
	ORA	A		;SUCESSFUL READ?
	JNZ	ERROR		;NO, FINALISE THEN EXIT
	XRA	A		;YES, RESET A
BUFFR1:
	LXI	H,00080H	;START OF DISK BUFFER
	MOV	E,A		;GET OFFSET TO LAST BYTE
				;READ FROM BUFFER
	INR	A		;BUMP TO NEXT BYTE
	STA	BUFCNT		;SAVE NEW LOCATION
	MVI	D,0		;RESET DE
	DAD	D		;FORM ACTUAL ADDRESS
	MOV	A,M		;GET BYTE
	POP	B		;RESTORE
	POP	D		; THE
	POP	H		; ENVIRONMENT
	RET	
;
ERROR:
	POP	B
	POP	D
	POP	H
	LXI	H,MESG8		;READ PAST EOF MESSAGE
	CALL	PTXT
	JMP	EXIT 
;
COUNT:	DW	0
OFFSET:	DB	0
OPCNT:	DB	0
NXCHAR:	DB	0
OPENFL:	DB	0
BUFCNT:	DB	0
LDPOINT	DW	0
OP$POINT DW	0
OPRS:	DS	6
OPR1	EQU	OPRS
OPR2	EQU	OPRS+2
OPR3	EQU	OPRS+4
SPVAL	EQU	OPRS+100H
;
	END

