;----------------------------------------------------------
;Option ROM Header must be ORGed at 0 by the assembler
;or linked at 0 by the linker.
;----------------------------------------------------------

;Routine to turn on the Option ROM

OPON:	EQU	0FAA4H

;Globals on the Telcom Back Page to temporarily hold HL and
;DE registers during a CALL to Standard ROM, or during an
;Interrupt.

HOLDH:	EQU	0FCC0H
HOLDD:	EQU	0FCC2H
INTH:	EQU	0FCC4H
INTD:	EQU	0FCC6H


;Entry point arrived at by CALL 63012

RST0?:
	INX	SP
	INX	SP
	JMP	PROGRAM
	DB	0,0,0

RST1?:				;Not used
	RET
	DB	0,0,0,0,0,0,0

RST2?:				;Not used
	RET
	DB	0,0,0,0,0,0,0

RST3?:				;Not Used
	RET
	DB	0,0,0,0,0,0,0

RST4?:				;Not Used
	RET
	DB	0,0,0

TRAP?:
	DI
	JMP	INTRAP

RST5?:				;Not Used
	RET
	DB	0,0,0

RST55?:
	DI
	JMP	INT55

;RST 6 used as short call to a Standard ROM routine.

RST6?:
	JMP	STDCALL
	DB	0

;Replaces the 6.5 interrupt and sets up a call to 6.5 in
;Standard ROM

RST65?:
	DI
	JMP	INT65

RST7?:				;Not Used
	RET
	DB	0,0,0

;Replaces the 7.5 interrupt and sets up a call to 7.5 in
;Standard ROM

RST75?:
	DI
	JMP	INT75

;An image of the OPON routine copied to FAA4H by the
;Model 100 power up logic.

OPONIMG:
	PUSH	PSW
	MVI	A,1
	OUT	0E0H
	POP	PSW
	RET
	DB	0

;---------------------------------------------------------
;The STDCALL routine allows a program running in the
;the Option ROM to call and return to an address in the
;Option ROM.
;Syntax is to use a RST 6 plus the address to be called.
;
;	RST	6
;	DW	04B44H
;---------------------------------------------------------

STDCALL:
	DI
	SHLD	HOLDH		;Caller's HL
	XCHG
	SHLD	HOLDD		;Caller's DE
	POP	H		;(HL)=Routine to Call
	MOV	E,M
	INX	H
	MOV	D,M		;DE=Routine to Call
	INX	H		;HL=Return Address
	PUSH	H
	LXI	H,OPON		;return through OPON
	PUSH	H
	PUSH	D		;Return Address
	LHLD	HOLDD		;Caller's DE
	XCHG
	LHLD	HOLDH		;Caller's HL
	EI
	JMP	STDON


;Routines for each of the hardware traps.
INTRAP:
	CALL	INTCALL
	DW	0024H
	RET

INT55:
	CALL	INTCALL
	DW	002CH
	RET

INT65:
	CALL	INTCALL
	DW	0034H
	RET

INT75:
	CALL	INTCALL
	DW	003CH
	RET

OPX:
;Turns off the Option ROM (or turns on Standard ROM)
;Depending on your viewpoint.
;This routine must be ORGed at 85H. Ensure the the previous
;Code does not overlap into 85H

	ORG	85H
STDON:
	PUSH	PSW
	PUSH	H
	LXI	H,26C8H
	XTHL
	XRA	A
OPEXIT:
	OUT	0E0H
	RET

;---------------------------------------------------------
;The INTCALL routine allows a program running in the Option
;ROM to call an interrupt routine.
;Syntax: CALL INTCALL plus the address to be called.
;
;	CALL	INTCALL
;	DW	24H
;---------------------------------------------------------
INTCALL:
	SHLD	INTH		;Caller's HL
	XCHG
	SHLD	INTD		;Caller's DE
	POP	H		;(HL)=Routine to Call
	MOV	E,M
	INX	H
	MOV	D,M		;DE=Routine to Call
	INX	H		;HL=Return Address
	PUSH	H
	LXI	H,OPON		;return through OPON
	PUSH	H
	PUSH	D		;Return Address
	LHLD	INTD		;Caller's DE
	XCHG
	LHLD	INTH		;Caller's HL
	JMP	STDON

;END OF ROM HEADER PORTION OF CODE



;================Model 100 Routines===============
;Poll the keyboard and return with or without key
;Entry:	None
;Exit:	Z if no key. Carry set if afunction key pressed
KYREAD:		EQU	07242H
;------

;Clear The Screen
CLS:		EQU	04231H
;------

;Output a character to LCD
;Entry Character in A Reg
CHROUT:		EQU	04B44H
;------

;Retrieve next directory entry of an active file
;Entry:	HL should point to one directory entry less than the
;	point at which to begin the search. The search routine
;	starts by incrementing to the next entry
;Exit:	Z set = no more entries
;		else
;	HL points to the next directory entry with an
;		active file.
NXTDIR: 	EQU      020D5H
;------

;Locate an empty directory slot.
;Entry:	none
;Exit:	HL points to a free slot
FREDIR: EQU      020ECH
;------

;Position the cursor
;Entry:	H=Column	1-40
;	L=Row		1-8
;Exit:	None
CURPOS:		EQU	0427CH
;------

;Erase to end of the current line
ERAEOL:		EQU	0425DH
;------

;Turn Cursor On
CURSON:		EQU	04249H
;------

;Turn Cursor Off
CUROFF:		EQU	0424EH
;------

;Position the cursor to 1 of 24 bar cursor positions
;Entry	HL = position 0-23
BARPOS:		EQU	059C9H
;------

;Toggle bar cursor to opposite state at poisition
;Specified in HL
;Entry:	HL = Position 0-23
BARCUR:		EQU	059E5H
;------

;Convert Model 100 directory name 'FILE  DO' to 
;Displayable name 'FILE.DO'
;Entry:	DE points to Directory name
;	HL points to buffer for formatted output
MKPNAM:		EQU	059ADH
;------

;Sound the beeper
BEEP:		EQU	04229H
;------

;Make a hole (space) in RAM file
;Entry:	HL = where to make the hole
;	BC = Size of the hole
MAKHOL:		EQU	06B6DH
;------

;Delete bytes in a file
;Entry:	HL= where to delete
;	BC= number of bytes to delete
MASDEL:		EQU	06B9FH
;------

;Reorganize directory pointers
DIROK:		EQU	02146H
;------

;=============Model 100 Addresses===============

;Beginning of the User Directory Area
USRDIR:		EQU	0F9BAH
;------

;Beginning of free space
MOAT:		EQU	0FBB6H
;------


;=====Globals Allocated to TELCOM back page====

;Pointer to the start of the search string.
;And its length
SEARCH:		EQU	0FCCAH
SEARCHLEN:	EQU	0FCCCH
;------

;Pointer to the Replace String and its length
REPLACE:	EQU	0FCCEH
REPLACELEN:	EQU	0FCD0H
;------

;Current location in the TEXT file
LOC:		EQU	0FCD2H
;------


;==============================================
;MAIN PROGRAM BEGINS HERE
;==============================================

;------
PROGRAM:
;------
;Check Stack, Install the ROM name and call the search
;and replace routine.

;1.	Check that at least 512 bytes of free space
;	Exists.

	LXI	H,0
	DAD	SP
	XCHG
	LHLD	MOAT

;2.	Subtract High bytes of Moat from Stack. Result
;	Must be at least 2 (0200H = 512)

	MOV	A,D
	SUB	H
	JC	OMEM
	CPI	2
	JC	OMEM
	
;3.	Install The ROM name
	LXI	H,ROMNAME	;Name to appear on Menu
	CALL	TRGINS		;Install it

;4.	Execute the main program
	CALL	SANDR

;5.	Return
	JMP	STDON

ROMNAME:	DB	'SandR',0


;------
OMEM:
;------
;Print insufficient Memory message and exit

	LXI	H,NOMEM
	CALL	DSPMSG
	CALL	GETCH
	JMP	STDON


NOMEM:		DB	12,'Insufficient Memory',13,10
		DB	'Any Key to Exit',0


;------
TRGINS:
;------
;Installs a 6 OR LESS character name as a ROM trigger file on the
;Model 100 directory.
;Entry: HL points to 6 OR LESS null TERMINATED
;	character string to use for the name.
;Exit:  None

;1.	Test if a Trigger file exists

	PUSH	H		;Save New File name.
	CALL	FOTRG		;Find an old trigger file
	POP	D		;File Name

;2.	If so then install over it

	JNZ	TRGINS1		;If found install over it.

;3.	Otherwise locate a free directory

	PUSH	D		;else
	RST	6		;Call Std ROM to
	DW	FREDIR		;Find an empty Slot.
	POP	D		;and install

;4.	Copy in 0F0H file type and 0FFFFH start

TRGINS1:
	MVI	M,0F0H		;Trigger File type
	INX	H		;Step past start
	MVI	M,0FFH		;Set start to 0FFFFH
	INX	H
	MVI	M,0FFH
	INX	H

;5.	Copy the name to the first null and then
;	nulls to the rest of the name.
	MVI	C,8		;and copy in the name

TRGINS2:
	LDAX	D
	MOV	M,A
	INX	H		;Fill the rest of the
	ORA	A		;name with nulls when we
	JZ	TRGINS3		;hit the null terminator
	INX	D
TRGINS3:
	DCR	C		;directory name with nulls
	JNZ	TRGINS2
	RET

;------
FOTRG:
;------
;Searches the directory for an already existing trigger
;file and returns a pointer to it in HL if found.
;Entry:	None
;Exit:	Z set if none found
;		else
;	HL points to the directory entry


;1.	Starting behind the free directory
	LXI	H,USRDIR-11	;Free dir - 1 entry

;2.	Get the next in use File

FOTRG1:
	RST	6		;Call Std ROM to
	DW	NXTDIR		;get Next Live File
	RZ			;no file found

;3.	Return Pointing to it if it is a ROM
;	trigger file.

	MOV	A,M		;is it a ROM Trigger
	CPI	0F0H		;Type
	JNZ	FOTRG1		;No - Go again
	ANA	A		;Clear Z flag
	RET

;------
SANDR:
;------
;This routine calls a menu display like the Model 100
;System Menu but only including visible .DO files.
;The user may position the bar cursor over a file
;name and press enter to select a file for search
;and replace operations.

;1.	Allocate Stack space for 24 words and
;	save the pointer to the space.
	LXI	H,-48
	DAD	SP
	SPHL
SANDR1:
	PUSH	H

;2.	Set all 48 bytes to 0FFH
	MVI	C,48
SANDR2:
	MVI	M,0FFH
	INX	H
	DCR	C
	JNZ	SANDR2

;3.	Locate all DO files and save pointers to
;	Directory entries for each
	POP	H		;Pointer in HL
	PUSH	H
	CALL	FINDDO

;4.	Display an empty menu
	CALL	DISPEMPTY

;5.	Write any active .DO files over the empty
;	slots.
	POP	H		;Pointer
	PUSH	H
	CALL	DISPDO

;6.	Let user position the cursor and pick
	POP	H		;Pointer
	PUSH	H
	CALL	PICKDO

	POP	D		;Pointer
;7.	If User selected F8 (7 in a reg) then exit
	CPI	7
	JZ	SANDR3

;8.	The only other posibility is ENTER. Check
;	That the cursor was over a valid entry
;	Not 0FFFFH as user could have been looking
;	At a display with no .DO files. Directory user is
;	pointing to is returned in HL

	PUSH	D		;Pointer
	MOV	A,L
	ANA	H
	INR	A

;9.	If it is legal then call the search and
;	Replace routine
	CNZ	SR
	POP	H

;10.	And Redisplay the menu
	JMP	SANDR1

SANDR3:
;7.	Deallocate the stack space.
	LXI	H,48
	DAD	SP
	SPHL
	RET

;------
FINDDO:
;------
;Entry:	HL points to a memory area for the storage of up to
;	24 pointers.
;Exit:	The memory area has been loaded with pointers to
;	Directory entries if any of .DO files in the
;	system.

	PUSH	H		;Save Pointer

;1.	Starting from one behind the first free
;	user directory slot.

	LXI	H,USRDIR-11	;Start back one

;2.	Find the next active file and return if none found

FINDDO1:
	RST	6		;Call Std ROM
	DW	NXTDIR		;To locate next active file
	POP	D		;Pointer
	RZ			;No more files

;3.	Test the type byte for C0H = .DO file

	MOV	A,M		;Get File Type
	CPI	0C0H		;Is it .DO type
	JNZ	FINDDO2		;Skip if not

;4.	And save it if it is

	XCHG			;else save pointer
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	XCHG
FINDDO2:
	PUSH	D
	JMP	FINDDO1


;------
DISPEMPTY:
;------
;Display a menu and screen of .DO Files

;1.	Clear Screen

	RST	6		;Call Std ROM to
	DW	CLS		;Clear The Screen

;2.	Display the Logo

	LXI	H,LOGO		;Display MSG
	CALL	DSPMSG

;3.	Position to the last line

	CALL	ROW8

;4.	Display a mini-menu (Exit Option Only)

	LXI	H,MINIMENU
	CALL	DSPMSG

;5.	Display 24 empty slots

	CALL	SLOTS
	RET

			;1234567890123456789012345678901234567890
LOGO:		DB	'   Search and Replace (c)1988 KCSI',0
MINIMENU:	DB	' --   --   --   --   --   --   --  Exit',0

;------
SLOTS:
;------
;Display 24 Empty slot positions on the bar cursor
;style screen

;1.	From 0 to 23

	XRA	A		;Starting from 0
SLOTS1:
	CPI	24		;Stop when A passes 23
	RZ

;2.	Position to that slot

	MVI	H,0
	MOV	L,A
	PUSH	PSW		;Save slot count
	RST	6		;Call Std ROM
	DW	BARPOS		;to move to bar position

;3.	And print the '-.-' empty entry

	LXI	H,EMPTY		;and print an empty
	CALL	DSPMSG

;4.	Next Slot

	POP	PSW		;Slot count
	INR	A
	JMP	SLOTS1

EMPTY:		DB	'-.-',0


;------
DISPDO:
;------
;Display .DO files at bar cursor positions.
;Entry	HL points to memory holding up to 24
;	pointers to directory entries of .DO files

;1.	Save pointer and Allocate 10 bytes for formatted name

	XCHG
	LXI	H,-10
	DAD	SP
	SPHL
	XCHG

;2.	For 0 to 23 entries

	MVI	C,0
DISPDO1:
	MOV	A,C
	CPI	24
	JZ	DISPDO2

;3.	Or until the pointer points to 0FFFFH

	MOV	A,M
	INX	H
	ANA	M
	INR	A
	JZ	DISPDO2

;4.	Get the Directory Entry

	PUSH	H		;Pointer to Pointers
	MOV	A,M
	DCX	H
	MOV	L,M
	MOV	H,A

;5.	Step to the file name portion

	INX	H
	INX	H
	INX	H

;6.	Format	The Name

	PUSH	D		;Buffer
	PUSH	B		;Slot Number
	XCHG
	RST	6		;Call Std ROM
	DW	MKPNAM		;to Format the name
	POP	H		;Slot Number
	PUSH	H

;7.	Position the cursor

	RST	6		;Call Std ROM
	DW	BARPOS		;for bar position
	POP	B		;Position
	POP	H		;Pointer to Buffer
	PUSH	H
	PUSH	B

;8.	Display the formatted name

	CALL	DSPMSG		;Display The Name

;9.	Square up and go again

	POP	B		;Bar Position
	POP	D		;Buffer Again
	POP	H		;Pointer to Pointers
	INX	H		;Adjusted
	INR	C
	JMP	DISPDO1
DISPDO2:

;10.	Clean up the stack

	LXI	H,10
	DAD	SP
	SPHL
	RET
	
;------
PICKDO:
;------
;Allows bar cursor to be moved with left and right
;Arrows only
;Entry:	HL Contains base of array of pointers to 
;	to directory entries
;Exit:	HL Points to the Directory Entry the Bar Cursor
;	Was Over.

	XCHG			;Pointer to DE

;1.	Turn the cursor on at 0

	LXI	H,0		;Starting from 0
	PUSH	D
PICKDO1:
	CALL	BARTOG
	JMP	PICKDO3

;This entry is used to ring the beeper if the
;Key stroke is an error.

PICKDO2:
	PUSH	H
	RST	6		;Call Std ROM
	DW	BEEP		;to BEEP
	POP	H

;2.	Get User Key stroke and dispatch accordingly

PICKDO3:
	PUSH	H
	CALL	GETCH

;3.	Carry set indicates a function Key
;	If it is F8 (A=7) then bail out

	JNC	PICKDO4
	POP	H
	CPI	7
	JNZ	PICKDO2		;Beep and try again
	POP	D		;Else clear the stack
	RET

;3.	Left Arrow can move only if not at position zero.

PICKDO4:
	CPI	29		;Left Arrow
	JNZ	PICKDO5
	POP	H
	MOV	A,H
	ORA	L
	JZ	PICKDO2		;Can't move
	CALL	BARTOG		;else current position off
	DCX	H
	JMP	PICKDO1

;4.	Right Arrow can move if new pointer is valid
;	If not valid, the cursor wraps to position 0

PICKDO5:
	CPI	28		;Right Arrow
	JNZ	PICKDO7
	POP	H		;Can always move
	CALL	BARTOG		;SO toggle off
	POP	D		;Now Where do we go
	INX	H		;Up one
	PUSH	H
	DAD	H		;Double it
	DAD	D		;Offset into table
	MOV	A,M		;If not FFFFH
	INX	H		;Then Move is legal
	ANA	M
	INR	A
	POP	H
	JNZ	PICKDO6		;Legal
	LXI	H,0		;Not legal, wrap to zero
PICKDO6:
	PUSH	D		;Restore the pointer
	JMP	PICKDO1

;5.	Last chance is for an ENTER key. If it is enter
;	Then return what is being pointed to.

PICKDO7:
	CPI	13
	POP	H
	JNZ	PICKDO2		;Invalid Key
	POP	D
	DAD	H		;Position times 2
	DAD	D		;Plus Table base
	MOV	A,M		;and load the value
	INX	H
	MOV	H,M
	MOV	L,A
	RET

;------
BARTOG:
;------
;Toggles the bar cursor at the position specified in HL
;Hl is preserved and restored.

	PUSH	H
	RST	6		;Call Std ROM
	DW	BARCUR		;to toggle BAR
	POP	H
	RET	

;------
GETCH:
;------
;Poll the keyboard until a key is hit.
;Return the value in A register.
;C set if its a function key and A will =
;0=F1, 1=F2 ... 7=F8,8=LABEL,9=PRINT,10=SHIFT-PRINT,11=PASTE

	RST	6		;Call Std ROM to
	DW	KYREAD		;Poll the keyboard
	JZ	GETCH		;Keep at it til something
	RET			;gotten


;------
DSPMSG:
;------
;Display a NULL terminated message on the LCD
;Entry HL points to the message
;Exit HL points to the NULL at the end of the message

;1.	Until the Character is null

	MOV	A,M		;Get char
	ORA	A
	RZ			;Return if NULL

;2.	Send it to the screen

	PUSH	H		;Save pointer
	RST	6		;Call Std ROM to
	DW	CHROUT		;Display it
	POP	H		;Restore Pointer

;3.	Point to the next character

	INX	H		;Next char
	JMP	DSPMSG

;------
ROW8
;------
;Position Cursor to Column 1, Row 8

	LXI	H,(256*1)+8	;Col 1 Row 8
	RST	6		;Call Std ROM
	DW	CURPOS		;to position cursor
	RET

;------------------------------------------------------
;Search and Replace Routine.
;------------------------------------------------------

;------
SR:
;------
;Ask User for Search and Replace strings and execute.
;Entry:	HL Points to a directory Entry for a TEXT
;File to be processed.

;1.	Retrieve the start pointer from the directory
;	and save it

	INX	H
	LXI	D,LOC
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D

;2.	Allocate two 21 byte buffers on the stack to hold
;	The search and Replace Strings and save pointers

	LXI	H,-42
	DAD	SP
	SPHL
	SHLD	SEARCH
	LXI	D,21
	DAD	D
	SHLD	REPLACE

;3.	At ROw 8 Ask user for a search string and erase
;	the rest of Row 8

	CALL	ROW8

	LXI	H,SPROMPT
	CALL	DSPMSG
	RST	6		;Call Std ROM
	DW	ERAEOL		;To clear to EOL

;4.	Point to the search buffer and allow the user to
;	enter up to 20 bytes

	LXI	D,20
	LHLD	SEARCH
	CALL	GETSTR


;5.	The GETSTR routine returns the length of the
;	entered string in HL so save it

	SHLD	SEARCHLEN

;6.	If the length is 0 (no search string) then
;	exit

	MOV	A,L
	ORA	H
	JZ	SR1

;7.	At Row 8 ask the user for a replace string
;	and erase to end of line.

	CALL	ROW8

	LXI	H,RPROMPT
	CALL	DSPMSG
	RST	6		;Call Std ROM
	DW	ERAEOL		;To clear to EOL

;8.	Point to the replace buffer and allow 20
;	characters of replace text

	LXI	D,20
	LHLD	REPLACE
	CALL	GETSTR

;9.	Save the length

	SHLD	REPLACELEN

;10.	And do the search and replace

	CALL	SANDRPL

;11.	Square up stack for the exit.

SR1:
	LXI	H,42
	DAD	SP
	SPHL
	RET

SPROMPT:	DB	'Search for :',0
RPROMPT:	DB	'Replace with :',0

;------
SANDRPL:
;------

;1.	Retrieve start of the file.

	LHLD	LOC

;2.	If it is CTRLZ then we're all done.

	MOV	A,M
	CPI	26
	JZ	SANDRPL1

;3.	Load file into HL and search string to DE

	XCHG
	LHLD	SEARCH
	XCHG

;4.	And look for it

	CALL	CMPSTR

;5.	Replace it there's a match

	CZ	RPL

;6.	Step forward one in the file and try again

	LHLD	LOC
	INX	H
	SHLD	LOC
	JMP	SANDRPL

;7.	On exit reorganize the directory before returning.

SANDRPL1:
	RST	6		;Call Std ROM
	DW	DIROK		;to re-organize

	RET
;------
RPL:
;------
;Replace routine.
;Entry:	LOC = Where to replace.
;This routine could probably be improved since
;MASDEL and MAKHOL supposedly preserve the HL
;Register. It wouldn't be necessary to keep
;reloading.

;1.	Delete the length of the search string from the
;	The file

	LHLD	SEARCHLEN
	PUSH	H
	POP	B
	LHLD	LOC
	RST	6		;Call Std ROM
	DW	MASDEL		;To Delete bytes

;2.	Make a hole the length of the replace string

	LHLD	REPLACELEN
	PUSH	H
	POP	B
	LHLD	LOC
	RST	6		;Call Std ROM
	DW	MAKHOL		;to make the hole

;3.	Copy the replacement string to the hole

	LHLD	REPLACELEN
	PUSH	H
	POP	B
	LHLD	LOC
	XCHG
	LHLD	REPLACE
	CALL	MEMCPY

;4.	Increment the LOC pointer by Length - 1
;	So that we don't end up with recursive
;	Replacement

	LHLD	REPLACELEN
	XCHG
	LHLD	LOC
	DAD	D
	DCX	H
	SHLD	LOC
	RET

;------
GETSTR
;------
;Allows entry of a string of the specified length (1-255)
;Entry:	HL points to the receiving buffer
;	DE contains the maximum length allowed
;Exit:	HL contains actual length entered.

	PUSH	H		;Buffer

;1.	Get the pointer to the end of the string on
;	the stack END = Start + Length and the start
;	over that.

	PUSH	H		;Buffer
	DAD	D		;Limit or end of the buffer
	XTHL


;2.	Turn on the cursor

	PUSH	H
	RST	6		;Call Std ROM
	DW	CURSON		;to turn it on.
	POP	D		;Buffer

;3.	Save the Buffer

	PUSH	D

;4.	Get a character

GETSTR1:
	CALL	GETCH

;5.	Ignore Function keys (Carry Set) Beep and go again

	JC	GETSTR4

;6.	Carriage Return is the end of user input

GETSTR2:
	CPI	13
	JZ	GETSTR6

;7.	A backspace can only be done if
;	The current buffer pointer not =
;	the start of the buffer

	CPI	8
	JNZ	GETSTR3
	POP	D		;Current pointer
	POP	B		;Buffer end
	POP	H		;Buffer Start
	PUSH	H
	PUSH	B
	PUSH	D
	CALL	CMPHLDE		;Compare HL and DE
	JZ	GETSTR4		;Ignore if HL=DE

;8.	If Okay then decrement the current buffer
;	pointer
	POP	D
	DCX	D
	PUSH	D

;9.	And display BS-SPACE-BS to clear the character
;	on the screen and go again.

	LXI	H,RUBOUT
	CALL	DSPMSG
	JMP	GETSTR1
	
;10.	Ignore all other control characters

GETSTR3:
	CPI	' '
	JC	GETSTR4

;11.	And hex 7FH

	CPI	07FH
	JZ	GETSTR4

;12.	So we have a valid ASCII character. Check if the
;	The current pointer is at the end of the buffer.
;	If it is then ignore the input.

	MOV	C,A		;Save The Character
	POP	D		;Current Pointer
	POP	H		;End of Buffer
	PUSH	H
	PUSH	D
	CALL	CMPHLDE		;Compare
	JZ	GETSTR4		;Ignore if equal

;13.	The character is placed in the buffer and the
;	Buffer is incremented.

	MOV	A,C
	POP	D
	STAX	D
	INX	D
	PUSH	D

;14.	Display the character and go again.

	RST	6		;Call Std ROM
	DW	CHROUT		;to Display it
	JMP	GETSTR1

;	Jumping to this address causes a beep and
;	a jump back to the top, used for invalid characters

GETSTR4:
	RST	6		;Call Std ROM
	DW	BEEP		;to beep
	JMP	GETSTR1		;And jump to the top

;15.	This is the exit when CR is pressed. First
;	Turn the cursor off

GETSTR6:
	RST	6		;Call Std ROM
	DW	CUROFF		;to turn it off

;16.	Store a null at the current buffer pointer.

	POP	H		;Buffer pointer
	XRA	A
	MOV	M,A

;17.	Get the length in HL and exit

	POP	D		;Limit or end of buffer
	POP	D		;Start of Buffer
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	MOV	H,A
	RET

RUBOUT:		DB	8,' ',8,0

;------
CMPHLDE
;------
;Compare HL and DE
;Entry:	HL and DE with value to compare
;Exit:	Z flag set if HL=DE
;	Carry Set if DE>HL

	MOV	A,H
	CMP	D
	RNZ
	MOV	A,L
	CMP	E
	RET

;------
CMPSTR:
;------
;Compare strings pointed to by HL and DE
;Comparison stops when (DE)=0 success
;Or (DE)<>(HL) = nomatch
;Entry:	DE points to null terminated string to search for
;	HL points to where in the file to match
;Exit:	NZ if the match fails or Z if successful

;1.	Retrieve a character from the search string.
;	If it is null, then the search is successful

	LDAX	D
	ORA	A
	RZ

;2.	Otherwise compare and return for mismatch

	CMP	M
	INX	H
	INX	D
	RNZ

;3.	Go again

	JMP	CMPSTR

;------
MEMCPY
;------
;Copy (HL) to (DE) for BC bytes

;1.	Exit when BC exhausted

	MOV	A,C
	ORA	B
	RZ

;2.	Otherwise move it and increment

	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCX	B
	JMP	MEMCPY

	END
