home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.whtech.com
/
ftp.whtech.com.tar
/
ftp.whtech.com
/
club100
/
ref
/
sandr.asm
< prev
next >
Wrap
Assembly Source File
|
2006-10-19
|
22KB
|
1,280 lines
;----------------------------------------------------------
;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