mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 22:43:15 -06:00
420 lines
11 KiB
Z80 Assembly
420 lines
11 KiB
Z80 Assembly
;
|
||
|
||
TITLE ZFORP.Z80 - 09/29/88 - ZMD Public Description Utility
|
||
; Copyrighted (c) 1987, 1988
|
||
; Robert W. Kramer III
|
||
|
||
PAGE
|
||
;- -;
|
||
; Update History ;
|
||
; ;
|
||
; Date Release Comments ;
|
||
; -------- ------- ---------------------------------------------- ;
|
||
; ;
|
||
; 09/29/88 v1.50 - No change(s) made to this file. ;
|
||
; 03/18/88 v1.49 - No change(s) made to this file ;
|
||
; 03/13/88 v1.48 - Redefined buffer table at end of programs. STACK;
|
||
; and filename buffers now EQUated with offsets ;
|
||
; from the last switch/toggle in program instead ;
|
||
; of with DS directive. ;
|
||
; - Some systems which do NOT have an interrupt ;
|
||
; driven keyboard may have noticed problems when ;
|
||
; an invalid key was entered in the ZNEWP, ZFORP ;
|
||
; and ZMDEL programs. In ZNEWP and ZFORP, if a ;
|
||
; CR was entered to pause the output, output was ;
|
||
; limited to one line at a time per key pressed. ;
|
||
; If an invalid key was hit, output would have ;
|
||
; remained in a paused state until one of the ;
|
||
; abort keys were pressed. This was difficult to ;
|
||
; find since my keyboard is interrupt driven and ;
|
||
; I could not duplicate the problem on my own ;
|
||
; system. ;
|
||
; 02/25/88 v1.47 - No change(s) made to this file ;
|
||
; 01/27/88 v1.46 - Some changes were made to ZMDSUBS that are not ;
|
||
; directly related to this file ;
|
||
; - Fixed typo in help guide reflecting '/' as the ;
|
||
; flag to force LF in search routine ;
|
||
; 01/17/88 v1.45 - First public release ;
|
||
; 12/24/87 v1.01 - Some trivial bugs fixed ;
|
||
; 11/10/87 v1.00 - Initial version ;
|
||
;- -;
|
||
|
||
;-------------------------------------------------------------------------;
|
||
; EXTERNAL Declarations: |
|
||
;-------------------------------------------------------------------------;
|
||
|
||
|
||
EXTRN CKABRT,CMDBUF,DBUF,ERXIT,EXIT,ILPRTB,LINCNT,NOFILE
|
||
EXTRN NOFOR,OLDDRV,OLDUSR,PRINTV,RECAR1,RECDR1,RENFCB
|
||
EXTRN RSDMA,SHONM4,STACK,TYPE,UCASE,NOFOR
|
||
|
||
;
|
||
;-------------------------------------------------------------------------;
|
||
; Program Starts Here |
|
||
;-------------------------------------------------------------------------;
|
||
|
||
|
||
.Z80
|
||
ASEG
|
||
ORG 100H ; Program starts
|
||
JP BEGIN ; Jump around configuration table
|
||
INCLUDE ZMDHDR.Z80 ; Include the ZMD header overlay
|
||
.REQUEST ZMDSUBS ; Include the ZMD subroutines
|
||
|
||
;
|
||
;
|
||
; Save CP/M stack, initialize new one for this program
|
||
;
|
||
BEGIN: LD (STACK),SP ; Save return address to CCP
|
||
LD SP,STACK ; Initialize new one for this program
|
||
|
||
;
|
||
; Get current drive/user and save for later
|
||
;
|
||
LD A,255
|
||
CALL RECAR1
|
||
LD (OLDUSR),A ; Save current user area
|
||
LD C,CURDRV
|
||
CALL BDOS
|
||
LD (OLDDRV),A ; Save current drive
|
||
|
||
;
|
||
; Tell em who we are
|
||
;
|
||
LD HL,PUBFOR
|
||
CALL PRINTV
|
||
|
||
;
|
||
; See if descriptions enabled
|
||
;
|
||
LD A,(DESCRIB)
|
||
OR A
|
||
JP NZ,BEGIN1
|
||
LD A,(MSGDESC)
|
||
OR A
|
||
JP Z,NOFOR
|
||
|
||
BEGIN1: CALL ILPRTB
|
||
DB '(S to Pause - C K or X Abort - ? for Help)'
|
||
DB CR,LF,LF,0
|
||
LD A,8
|
||
LD (LINCNT),A
|
||
|
||
;
|
||
; See if user wants file displayed 'nonstop' ($N)
|
||
;
|
||
LD A,(TBUF) ; Number of bytes in command tail
|
||
OR A ; Were there any?
|
||
LD (SHOWALL),A ; Tell rest of program
|
||
JP Z,OPNFIL ; Just go display the file if not
|
||
|
||
LD A,(FCB+1) ; Get first character on command line
|
||
CP '$' ; Must specify '$' first for pause disabling
|
||
JP NZ,CKHLP ; Nope, continue normal
|
||
|
||
LD A,(FCB+2) ; Get second character on command line
|
||
CP 'N' ; 'N' for nonstop display?
|
||
JP NZ,CKHLP ; No
|
||
|
||
XOR A
|
||
LD (SHOWALL),A ; Disable string search
|
||
LD (PAGLEN),A ; Else disable page pauses
|
||
JP OPNFIL
|
||
|
||
;
|
||
; See if requesting help
|
||
;
|
||
CKHLP: LD A,(TBUF+2) ; Get character after space
|
||
CP '?' ; ??
|
||
JP NZ,SAVTAIL ; No, save command tail for comparison
|
||
|
||
LD A,(TBUF+3) ; Any more chracters?
|
||
OR A
|
||
JP Z,HELP ; No, so must want HELP
|
||
|
||
;
|
||
; Move command line buffer to internal buffer
|
||
;
|
||
SAVTAIL:LD HL,TBUF ; Point to command line buffer
|
||
LD B,(HL) ; Character count is first byte into 'B'
|
||
LD DE,CMDBUF ; Destination is internal buffer
|
||
INC HL ; Increment to ' ', next INC gets first chr
|
||
LD A,(HL) ; Get this character
|
||
CP ' ' ; Is it a space?
|
||
JR Z,SVTAIL1 ; Yes, leave things alone
|
||
DEC HL ; No, decrement pointer
|
||
|
||
SVTAIL1:INC HL ; Increment to next character
|
||
LD A,(HL) ; Into A
|
||
LD (DE),A ; Store in internal buffer
|
||
INC DE ; Increment pointer
|
||
DJNZ SVTAIL1 ; One less character on command line
|
||
|
||
;
|
||
; Open FOR file
|
||
;
|
||
OPNFIL: LD A,(USER) ; Get user area to find FOR file
|
||
CALL RECAR1 ; Log into it
|
||
LD A,(DRIVE) ; Get drive to find FOR file
|
||
CALL RECDR1 ; Log into it
|
||
|
||
LD HL,FILE ; Initialize internal FCB1
|
||
LD DE,FORNAM ; With FOR filename
|
||
CALL RENFCB
|
||
|
||
LD DE,FILE ; Internal FCB1 contains filename
|
||
LD C,OPEN ; Now attempt open
|
||
CALL BDOS
|
||
INC A ; Open successful?
|
||
LD HL,FORNAM ; Point to FOR filename for 'not found'
|
||
JP Z,NOFILE ; No, inform user and abort
|
||
|
||
;
|
||
; Read a 128 byte record into DBUF at end of program
|
||
;
|
||
XOR A
|
||
LD (FILE+12),A ; Start with first extent
|
||
LD (FILE+32),A ; And first record
|
||
LD DE,DBUF ; Destination buffer
|
||
|
||
;
|
||
RDRECD: PUSH DE ; Save current data buffer address
|
||
CALL RSDMA ; Reset DMA
|
||
|
||
LD C,READ ; Read next record
|
||
LD DE,FILE ; From FOR file
|
||
CALL BDOS
|
||
POP DE ; Get current DBUF address back
|
||
OR A ; Read successful?
|
||
JP NZ,RERROR ; No, go check EOF
|
||
LD HL,TBUF ; 128 byte buffer in page 0
|
||
|
||
WRDLP: LD A,(LINEND) ; At end of line?
|
||
OR A
|
||
JP Z,WDLP1 ; No
|
||
|
||
XOR A
|
||
LD (LINEND),A ; Else we aren't anymore
|
||
|
||
LD A,(HL) ; Get the character
|
||
AND 7FH ; Strip parity
|
||
CP '-' ; Start of next description?
|
||
JP NZ,WDLP1 ; No
|
||
|
||
LD A,3
|
||
LD (DE),A ; Stuff a break for beginning of last descrip
|
||
JP SEARCH
|
||
|
||
WDLP1: LD A,(HL) ; Get character
|
||
AND 7FH ; Strip high bit
|
||
CP DEL ; Rubout?
|
||
JP Z,NEXT ; Yes, ignore and get next character
|
||
CP EOF ; EOF - End of file marker?
|
||
JP Z,ENDFIL ; Yes, all done
|
||
LD B,A ; Save character for now
|
||
LD A,(SHOWALL) ; Looking for specified string?
|
||
OR A
|
||
LD A,B ; Get our character back now
|
||
JP NZ,WDLP2 ; Yes, just write to memory
|
||
CALL TYPE ; Output to console
|
||
EX AF,AF' ; Save flags (NZ=displaying to console)
|
||
LD A,0 ; A=0 disables pausing while checking abort
|
||
EX AF,AF' ; Save it for now, get character back
|
||
JP WDLP3 ; And see if at end of line
|
||
|
||
WDLP2: LD (DE),A ; Else writing to memory
|
||
INC DE ; Next buffer position
|
||
EX AF,AF' ; Save flags (Z=writing to memory)
|
||
LD A,1 ; A=1 enables puasing while checking abort
|
||
EX AF,AF' ; Save it for now, get character back
|
||
|
||
WDLP3: CP LF ; Are we at end of line?
|
||
JP NZ,NEXT ; No get next character
|
||
|
||
LD A,(SHOWALL) ; Get string search toggle
|
||
LD (LINEND),A ; If set, at end of line, and writng to memory
|
||
EX AF,AF' ; AF'=1 enable pauses, disable if 0
|
||
CALL CKABRT ; Check for user abort (and pauses if A=1)
|
||
|
||
NEXT: INC L ; One more byte
|
||
JP Z,RDRECD ; If no more get next record
|
||
JP WRDLP ; Else get next character
|
||
|
||
;
|
||
; Search for a match with search string
|
||
;
|
||
SEARCH: PUSH HL ; Save HL
|
||
LD HL,CMDBUF ; Point to buffer containing command tail
|
||
|
||
SEARC1: LD (CMDPTR),HL ; Save command tail buffer pointer
|
||
LD HL,DBUF ; Disk buffer with FOR text
|
||
|
||
SEARC2: LD DE,(CMDPTR) ; Get command tail buffer pointer again
|
||
PUSH HL ; Save it (command tail pointer still in DE)
|
||
|
||
SEARC3: LD A,(DE) ; Get a character
|
||
CP '\' ; Force LF?
|
||
JP NZ,SEARC4 ; No
|
||
LD A,LF ; Else LF value in A for comparison
|
||
|
||
SEARC4: INC DE ; Increment to next command tail character
|
||
OR A ; Anything there?
|
||
JP Z,SEARC8 ; No
|
||
CP '|' ; String seperator?
|
||
JP Z,SEARC8 ; Yes
|
||
LD B,A ; Save character for compare
|
||
LD A,(HL) ; Get a FOR text character in A
|
||
CALL UCASE ; Convert it to uppercase
|
||
|
||
SEARC5: LD C,A ; Put FOR text character in C for now
|
||
INC HL ; And increment to next one
|
||
LD A,B ; Get comparison character back (from CMDBUF)
|
||
CP '?' ; Accept any character?
|
||
JP Z,SEARC3 ; Yes, call it a match
|
||
CP C ; Else are they the same?
|
||
JP Z,SEARC3 ; Yes, call it a match
|
||
POP HL ; Else get FOR buffer address back
|
||
INC HL ; Increment to next character
|
||
LD B,0 ; Initialize count to 0
|
||
LD A,(HL) ; Get next character from FOR buffer
|
||
CP CTRLC ; Beginning of description entry?
|
||
JP Z,SEARC6 ; Yes
|
||
CP 4 ; End of file?
|
||
JP NZ,SEARC2 ; No
|
||
INC B ; Else, show we hit end of buffer
|
||
|
||
SEARC6: LD HL,(CMDPTR) ; Get command tail pointer back
|
||
|
||
SEARC7: LD A,(HL) ; Get character from saved command tail
|
||
INC HL ; Point to next one
|
||
CP '|' ; Searching for multiple strings?
|
||
JP Z,SEARC1 ; Yes, go search next one
|
||
OR A ; Else are we all done?
|
||
JP NZ,SEARC7 ; No, keep looking
|
||
LD A,B ; Else see if at end of buffer
|
||
OR A
|
||
JP NZ,ENDFL1 ; Yes
|
||
LD DE,DBUF+1
|
||
POP HL ; Get record count back
|
||
JP NEXT ; Go get next
|
||
|
||
SEARC8: POP HL
|
||
LD A,CR
|
||
CALL TYPE ; Output CR for end of line
|
||
LD HL,DBUF
|
||
|
||
SEARC9: LD A,(HL) ; Get character
|
||
CP CTRLC ; Start of description?
|
||
JP Z,SEARC10 ; Yes, go get next character
|
||
CP 4 ; End of file?
|
||
JP Z,ENDFL1 ; Yes
|
||
CALL TYPE ; Output character to console
|
||
CP LF ; At end of line?
|
||
LD A,0 ; Disable page pauses
|
||
CALL Z,CKABRT ; Check for aborts
|
||
INC HL ; Next character
|
||
JP SEARC9 ; Loop until a ^C or ^D
|
||
|
||
SEARC10:POP HL
|
||
LD DE,DBUF+1
|
||
JP NEXT ; Go get next byte
|
||
|
||
;
|
||
; The following routine displays the help guide to the user
|
||
;
|
||
HELP: CALL PRTABT
|
||
DB CR,LF
|
||
DB 'Usage examples:'
|
||
DB CR,LF
|
||
DB CR,LF,' FOR Show entire file'
|
||
DB CR,LF,' FOR $N Show entire file without paging'
|
||
DB CR,LF,' FOR ZMD All descriptions containing string ''ZMD'''
|
||
DB CR,LF,' FOR ZMD|LU ''|'' seperates multiple strings to search'
|
||
DB CR,LF,' FOR \ZMD ''\'' forces line feed and looks at filenames'
|
||
DB CR,LF,' FOR ZM? ''?'' matches any character in this position'
|
||
DB CR,LF,0
|
||
|
||
LD A,(INCLDU)
|
||
OR A
|
||
JP Z,HELP1
|
||
CALL PRTABT
|
||
DB ' FOR (B0:) Descriptions for files received on B0:',0
|
||
|
||
HELP1: CALL PRTABT
|
||
DB CR,LF,0
|
||
LD A,(DSTAMP)
|
||
OR A
|
||
JP Z,HELP4
|
||
LD A,(EDATE)
|
||
OR A
|
||
JP Z,HELP2
|
||
CALL PRTABT
|
||
DB ' FOR ??/12',0
|
||
JP HELP3
|
||
|
||
HELP2: CALL PRTABT
|
||
DB ' FOR 12/??',0
|
||
|
||
HELP3: CALL PRTABT
|
||
DB ' Show files received in month of December',0
|
||
|
||
HELP4: CALL ERXIT
|
||
DB CR,LF,LF,LF,LF,'$'
|
||
|
||
;
|
||
; Inline print routine checks for user abort on each line feed
|
||
;
|
||
PRTABT: POP HL ; Get address following CALL
|
||
|
||
AM1: LD A,(HL) ; Character in A
|
||
OR A ; Null terminator?
|
||
JP Z,AM2 ; Yes, all done
|
||
CALL TYPE ; Else output to console
|
||
CP LF ; Was it a LF?
|
||
LD A,0 ; Enable page pauses
|
||
CALL Z,CKABRT ; Check for user abort, or pause request
|
||
INC HL ; Point to next character
|
||
JP AM1 ; Loop until a null
|
||
|
||
AM2: PUSH HL ; Current address in HL=return address
|
||
RET
|
||
|
||
;
|
||
;
|
||
RERROR: CP 1
|
||
JP Z,ENDFIL
|
||
CALL ERXIT
|
||
DB '-- Source file read error$'
|
||
;
|
||
ENDFIL: LD A,(SHOWALL)
|
||
OR A
|
||
JP Z,ENDFL1
|
||
LD A,4
|
||
LD (DE),A
|
||
JP SEARCH
|
||
|
||
ENDFL1: LD C,CLOSE
|
||
LD DE,FILE
|
||
CALL BDOS
|
||
CALL ERXIT
|
||
DB CR
|
||
DB '-----'
|
||
DB CR,LF
|
||
DB '-- End of file --$'
|
||
|
||
|
||
;
|
||
; These next are dummy routines to satisfy external ZMDSUBS requests.
|
||
; They do nothing, but leave alone
|
||
;
|
||
DONE:: JP EXIT
|
||
TIME:: RET
|
||
|
||
|
||
LINEND: DB 0
|
||
SHOWALL:DB 0
|
||
CMDPTR: DW 0
|
||
|
||
|
||
END
|
||
|