mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
420 lines
11 KiB
420 lines
11 KiB
;
|
|
|
|
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
|
|
|