home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
UTILITYS
/
FML.ARC
/
LOOKUP.Z80
< prev
Wrap
Text File
|
1990-07-21
|
7KB
|
320 lines
; ****** LOOKUP.ASM *******
;
; by Jim Schenkel (415) 928-4445 - reads a data file and tries to match
; match an input string
;
; rev. 8/15/86 - Paul Foote, to protect CCP and start buffer on even page
; rev. 9/1/82 - Jim Schenkel
.Z80 ; Needed for M80 assembler, else ignore
ASEG ; Needed for M80 assembler, else ignore
ORG 100H ; CP/M operating system
JP START
BDOS EQU 0005H ; DOS entry point
FCB EQU 005CH ; File control block
TYPEF EQU 2 ; Type character to console
PRINTF EQU 9 ; Print string terminated by '$'
RDBUFF EQU 10 ; Read console buffer
OPENF EQU 15 ; Open file
READF EQU 20 ; Sequential read
DMAF EQU 26 ; Set DMA
CR EQU 0DH ; Carriage return
LF EQU 0AH ; Line feed
TAB EQU 9 ; Tab character
; File name must be exactly 11 bytes (FILENAME.TYP) - placed here so it
; can be easily changed to default to your favorite program.
FILNAM: DEFB 'MAST LST' ; Name of default file
; Initialize local stack
START: LD HL,0 ; Clear HL
ADD HL,SP ; Add in old stack
LD (OLDSP),HL ; Save it
LD SP,STACK ; Set up new stack
CALL CLEAR ; Clear screen
; Check for command line file name
LD A,(FCB+1) ; Get first character
CP ' ' ; If it's not a space
JR NZ,OPEN ; Then use that name
LD DE,HOWDY ; Sign on
CALL PRINT
; Move the default file name into the FCB
LD HL,FILNAM ; Point to file name
LD DE,FCB+1 ; Point to FCB filename
LD BC,11 ; Counter
LDIR ; Move it
; Open the file
OPEN: LD DE,FCB ; Point to FCB
LD C,OPENF ; Open the file
CALL BDOS
LD DE,NOFILE ; Error message
INC A ; FF-->0 if no file
JP Z,ERROR ; So bail out
; Calculate the top of memory
LD HL,(0006) ; Get BDOS location
LD DE,900H ; Leave enough room
SBC HL,DE ; To avoid trouble
LD (TOP),HL ; Store upper bound
; Initialize the pointer to the DMA
LD DE,BUFFER ; Point to data area
LD (BDMA),DE ; Store current pointer
LD C,DMAF ; Set the DMA
CALL BDOS
XOR A ; Zero a
LD (FCB+32),A ; Clear CR in DMA
; Read data into memory
READ: LD DE,FCB ; Get record
LD C,READF
CALL BDOS
OR A ; Zero if read ok
JR NZ,BUFSIZ ; Else entire file was read
; Increment the buffer pointer
LD HL,(BDMA) ; Get the current pointer
LD DE,80H ; Add 128 bytes
ADD HL,DE ; As offset
LD (BDMA),HL ; Store new pointer
PUSH HL ; Save pointer
LD DE,(TOP) ; Get upper bound
SBC HL,DE ; Subtract from pointer
JR C,XBF ; DE>HL, so proceed
LD DE,OVRFLW ; HL>DE, so give
CALL PRINT ; Message and
JR BUFSIZ ; Don't read any more
XBF: POP DE ; Pick up pointer in DE
LD C,DMAF ; Update the DMA
CALL BDOS
JR READ ; Do it again
; Calculate size of data buffer
BUFSIZ: LD HL,(BDMA) ; Get last DMA
LD DE,80H ; Add another block
ADD HL,DE ; To get to end of buffer
LD DE,BUFFER ; Get start of buffer
OR A ; Clear carry
SBC HL,DE ; Subtract start from end
LD (BUFLEN),HL ; Store buffer length
; Get the input string
GETSTR: CALL CLSTR ; Clear the search string
LD DE,PROMPT ; Ready the prompt
LD C,PRINTF ; Print it
CALL BDOS
LD DE,MX ; Point to input buffer
LD C,RDBUFF ; Read a buffer
CALL BDOS
LD A,(MX+1) ; Get string length
OR A ; Test for zero
JR NZ,CONT
LD DE,CRLF
JR ERROR ; 0 = aborted
; Convert to upper-case
CONT: LD BC,(MX) ; Get CX in B
LD HL,STRING ; Point to string
UP: LD A,(HL) ; Get a character
CP 'a' ; Check for lower case
JR C,NOLO ; Jump if ok
SUB 20H ; Else convert to lower
LD (HL),A ; And store it
NOLO: INC HL ; Bump pointer
DJNZ UP ; And loop
; Search for the string
SEARCH: LD HL,BUFFER ; Point to buffer
LD BC,(BUFLEN) ; Counter for length
LOOK: LD DE,STRING ; Point to search string
LD A,(DE) ; Get first character
CPIR ; Look for a match
JR Z,GOT1 ; Found a match
JP PO,GETSTR ; Counter has reached zero
; So ask for another string
JR LOOK ; Do entire buffer
; Found match for first character, check the rest of the search string
GOT1: PUSH BC ; Save BUFLEN counter
LD BC,(MX) ; Get CX in B
DEC B ; Allow for first character
JR Z,SHOW ; Print if only 1
GOT2: INC DE ; Bump pointer to string
LD A,(DE) ; Get a character
CP '?' ; Wild card?
JR Z,WILD ; Yes, so ignore match
CP (HL) ; Does it match?
JR NZ,NOPE ; No, try again
WILD: INC HL ; Bump pointer to buffer
DJNZ GOT2 ; Loop for all characters
JR SHOW ; All characters match
NOPE: POP BC ; Restore BUFLEN counter
JR LOOK ; And keep looking
; Print the record and update the data pointer and counter to the end of
; the record
SHOW: POP BC ; Restore BUFLEN counter
SHOW1: DEC HL ; Back up a character
PUSH HL ; Save pointer to buffer
LD DE,BUFFER ; Beginning of buffer
OR A ; Clear the carry
SBC HL,DE ; Are we at the beginning?
POP HL ; (restore the pointer)
JR Z,NEXTCH ; Yes, so print 1st record
INC BC ; Else increment counter
LD A,(HL) ; What's that character?
CP CR ; Is it a carriage return?
JR NZ,SHOW1 ; No, so go back further
NEXTCH: LD E,A ; Ready to print character
CALL PRCHR ; Start printing the record
INC HL ; Byte by byte
DEC BC ; Keeping track of length
LD A,B ; If bc goes to zero
OR C ; Then at the end of the data buffer
JR Z,LOOK
LD A,(HL) ; Get another character
CP 1AH ; End of file?
JR Z,GETSTR ; Then get another string
CP CR ; End of record?
JR NZ,NEXTCH ; No, get another character
JR LOOK ; Yes, so go look some more
; Wrap it up and bail out
ERROR: CALL PRINT ; Print message
LD HL,(OLDSP) ; Get old stack pointer
LD SP,HL ; Put it in place
RET ; Return to CCP
;-----------------------------------------------------------------------
; subroutines
; Clear the screen
CLEAR: LD E,26 ; Clear screen character
; Print a character
PRCHR: PUSH AF ; Save everything
PUSH BC
PUSH DE
PUSH HL
LD C,TYPEF ; Type character function
CALL BDOS ; Do it, then
POP HL ; Restore everything
POP DE
POP BC
POP AF
RET
; Clear the input string
CLSTR: LD B,80 ; Counter for 128 bytes
LD HL,STRING ; Point to string storage
XOR A ; Clear a
CLR2: LD (HL),A ; Zero a byte
INC HL ; Bump pointer
DJNZ CLR2 ; And loop
RET
; Print a string terminated by '$'
PRINT: PUSH AF ; Save the registers
PUSH BC
PUSH DE
PUSH HL
LD C,PRINTF ; Print function
CALL BDOS
POP HL ; Restore the registers
POP DE
POP BC
POP AF
RET
; Messages
CRLF DEFB CR,LF,'$'
HOWDY: DEFB CR,LF,TAB,'*** SELECT STRING TO FIND ***',CR,LF,LF,'$'
NOFILE: DEFB CR,LF,'++ Cannot find the data file ++',CR,LF,'$'
OVRFLW: DEFB CR,LF,LF,'++ File is longer than available space, '
DEFB 'excess is unavailable ++',CR,LF,'$'
PROMPT: DEFB CR,LF,LF,'==>','$'
; Storage
DEFS 64 ; Stack area
STACK EQU $ ; Reserved
OLDSP: DEFW 0 ; Old stack pointer
TOP: DEFW 0 ; Top of memory
BUFLEN: DEFW 0 ; Length of data buffer
BDMA: DEFW 0 ; Current DMA pointer
; Read buffer - MX, CX and string must be in this order
MX: DEFB 80H ; Max length of search string
CX: DEFB 0 ; Reserved for actual length
STRING: DEFS 80H ; Space for search string
ORG ($+255)/256*256
BUFFER EQU $ ; Begin data buffer here
END