home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
bye5
/
ffor.aqm
/
FFOR.ASM
Wrap
Assembly Source File
|
1986-07-13
|
12KB
|
534 lines
; FFOR.ASM - Displays the FFOR text file, describing old files - 12/10/85
;
; This program has been copyrighted (c) by Irvin M. Hoff
;
; FOR.ASM
; by
; Irvin M. Hoff
; (17 July 1985)
;
ASEG ; For M80 and RMAC, ignore if using MAC
;
;
; This program displays the FFOR text file, showing the description of
; recently uploaded files. It should go on A0: area, giving full secur-
; ity, and allowing it to be called from any drive/user area. ^S pauses
; and the following characters will terminate at the end of the current
; line:
;
; ^C C c ^K K k ^X X x
;
; It can also show the entire description of any file area that contains
; a string of characters typed after the FFOR name, in a similar (but
; more simple) manner to FIND52, etc. Example:
;
; A>FFOR ? (displays a help guide)
; A>FFOR IBM (types all files with IBM somewhere)
; A>FFOR .A?M (accepts ? for a wildcard)
;
;-----------------------------------------------------------------------
;
; 12/10/85 Rewritten (slightly) for FFOR - Irv Hoff
; 08/20/85 Redated for KMD04 - Irv Hoff
; 07/17/85 Initial version - Irv Hoff
;
;-----------------------------------------------------------------------
;
; User choices
;
DRIVE EQU 'A' ; FFOR text file location in your system
USER EQU 5 ; FFOR text file location in your system
;
;
; Equates
;
CR EQU 0DH ; Carriage return
LF EQU 0AH ; Line feed
EOF EQU 1AH ; End of file character
EOT EQU 04H ; End of transmission
ETX EQU 03H ; End of text
;
;
ORG 0100H
;
;
JMP START
;
;
STDRIV: DB DRIVE ; Location of FFOR text file
STUSER: DB USER ; Location of FFOR text file
;
;
;=======================================================================
;
; PROGRAM STARTS HERE
;
;=======================================================================
;
; Save stack, print sign-on, look for file specification
;
START: LXI H,0
DAD SP ; Get 'CCP' stack
SHLD STACK ; Save it for exit
LXI SP,STACK ; Set stack pointer
;
LDA 0004H ; Get current drive/user
STA DRUSER ; Store
;
;
; Set drive/user to the FFOR text file area listed above
;
LDA STUSER ; Set user to FFOR text file area
MOV E,A
MVI C,SETUSR
CALL BDOS
LDA STDRIV ; Set drive to FFOR text file area
SUI 41H
MOV E,A
MVI C,SELDSK
CALL BDOS
;
;
; Open source file
;
LXI D,FILE
MVI C,OPEN
CALL BDOS
INR A ; Check for no open
JZ NONE ; No file, exit
;
CALL ILPRT
DB CR,LF
DB 'FFOR - copyright 1985 by Irvin M. Hoff - 12/10/85'
DB CR,LF,'[type ^S to pause, ^C, ^X or ^K to abort, ? for '
DB 'help]',CR,LF
DB 'wait a moment...'
DB 0
;
LDA TBUF ; Any search string requested?
ORA A
STA SHOWAL ; If no strings to find, show everything
JNZ CHECK
CALL ILPRT ; Will overwrite "wait" message
DB CR,' ',CR,LF,0
JMP READLP ; If no strings, exit
;
;
; Want the help guide?
;
CHECK: LDA TBUF+2
CPI '?' ; First chararter typed a '?' for help?
JNZ LOOP ; If not, continue
LDA TBUF+3 ; Check next character after '?'
ORA A ; If a zero, they want some help
JZ HELP
;
;
; Store the search string in STRING
;
LOOP: LXI H,TBUF
MOV B,M ; Get number of characters in string
LXI D,STRING ; Get and store the requested string(s)
INX H
;
LOOP1: INX H
MOV A,M
STAX D
INX D
DCR B
JNZ LOOP1
;
;
; Address the main buffer, now
;
LXI D,BUFFER ; Put in buffer
;
;
; Read record from source file
;
READLP: PUSH D ; Save the line address
MVI C,SETDMA
LXI D,TBUF
CALL BDOS
;
MVI C,READ
LXI D,FILE
CALL BDOS
;
POP D
ORA A ; Read ok?
JNZ RERROR ; If not, display an error
;
LXI H,TBUF ; Read buffer address
;
WRDLOP: LDA LFEED ; Last character a line feed?
ORA A
JZ WRDL1 ; If not, keep going
;
XRA A
STA LFEED ; Clear the flag
MOV A,M
ANI 7FH ; Remove any parity
CPI '-' ; Is this a separator line?
JNZ WRDL1 ; If not, keep going
MVI A,03H ; If yes, store an "end of text" char.
STAX D
JMP COMPAR ; Handle the string
;
WRDL1: MOV A,M ; Get byte from read buffer
ANI 7FH ; Strip parity bit
CPI 7FH ; DEL (rubout) ?
JZ NEXT ; Yes, ignore it
CPI EOF ; End of file marker ?
JZ TDONE ; Transfer done, close, exit
;
MOV B,A ; Store the character temporarily
LDA SHOWAL ; Going to show everything?
ORA A
MOV A,B ; Get the character back
JNZ WRDL2
CALL TYPE
JMP WRDL3
;
;
; Store the character in the buffer
;
WRDL2: STAX D ; Store the character in the buffer
INX D ; Next buffer position
;
WRDL3: CPI LF ; See if finished with this line
JNZ NEXT ; If not get next character
LDA SHOWAL
STA LFEED ; Show we just had a line feed character
CALL ABORT ; Ready to quit?
;
NEXT: INR L ; Done with sector?
JZ READLP ; If yes get another sector
JMP WRDLOP ; No, get another byte
;.....
;
;
;=======================================================================
;
; SUBROUTINES
;
;=======================================================================
;
;
; Aborts the display when requested, but only at end of line
;
ABORT: PUSH H ; Save the TBUF address
PUSH D
MVI C,CONST ; Check to see if key pressed
CALL BDOS
ORA A
JZ ABORT3 ; If no key pressed, then continue
MVI C,RDCON ; If key pressed, then check for abort
ANI 5FH ; Remove parity, insure upper-case
CALL BDOS
CPI 'S'-40H
JNZ ABORT1
MVI C,RDCON
CALL BDOS
ANI 5FH
;
ABORT1: CPI 'C'-40H ; Is it CTL-C?
JZ ABORT2
CPI 'K'-40H ; Is it CTL-K?
JZ ABORT2 ; If no, then continue
CPI 'X'-40H ; Is it CTL-X?
JZ ABORT2
ANI 5FH ; Cnvert to upper-case
CPI 'C'
JZ ABORT2
CPI 'K'
JZ ABORT2
CPI 'X'
JNZ ABORT3
;
ABORT2: CALL EXIT ; If yes, then print abort message
DB CR,LF,'++ ABORTED ++','$'
;
ABORT3: POP D
POP H
RET
;.....
;
;
; Print message then exit to CP/M
;
EXIT: POP D ; Get message address
MVI C,PRINT ; Print message
CALL BDOS
;
EXIT1: CALL ILPRT ; Print CRLF before quitting
DB CR,LF,0
LDA DRUSER ; Get original drive/user area back
RAR
RAR
RAR
RAR
ANI 0FH ; Just look at the user area
MOV E,A
MVI C,SETUSR ; Restore original user area
CALL BDOS
LDA DRUSER ; Get the original drive/user back
ANI 0FH ; Just look at the drive for now
MOV E,A
MVI C,SELDSK ; Restore original drive
CALL BDOS
;
LHLD STACK
XRA A
SPHL
RET
;.....
;
;
; Help guide if no search string is included
;
HELP: CALL EXIT
DB CR,' Examples of how to use:',CR,LF
DB CR,LF,' B>FFOR MOD'
DB CR,LF,' B>FFOR MOD|BYE'
DB CR,LF,' B>FFOR M7'
DB CR,LF,' B>FFOR \M7'
DB CR,LF,' B>FFOR SPHL'
DB CR,LF,' B>FFOR .A?M'
DB CR,LF,CR,LF,' If no string is included, all the file '
DB 'is shown. A ''|'' allows',CR,LF,' numerous '
DB 'strings to be used at the same time. ''?'' is used '
DB 'for',CR,LF,' "any character at this position". A '
DB '''\'' fakes a line feed and',CR,LF,' looks only at '
DB 'the start of the filename line.',CR,LF,'$'
;.....
;
;
; Inline print routine - prints string pointed to by stack until a zero
; is found. Returns to caller at the next address after the zero ter-
; minator.
;
ILPRT: XTHL ; Save HL, get message address
;
ILPLP: MOV A,M ; Get chararacter
CALL TYPE ; Show on CRT
INX H ; Next character location
MOV A,M ; Get the character
ORA A ; If zero, all done
JNZ ILPLP ; Else keep going
XTHL ; Restore HL, ret address
RET ; Return past the end of the message
;.....
;
;
NONE: CALL EXIT
DB CR,LF,'++ No current FFOR text file available ++','$'
;.....
;
;
; Scan for the string
;
COMPAR: PUSH H ; Save the TBUF address
LXI H,STRING
;
ORLINE: SHLD STRPTR
LXI H,BUFFER
;
NXTSTR: XCHG ; Buffer location into DE for now
LHLD STRPTR
XCHG ; DE=string ponter, HL=buffer address
PUSH H ; Save current buffer position
;
;
; Replace '\' with a line feed character
;
CLOOP: LDAX D ; Get character from the string
CPI '\'
JNZ $+5
MVI A,LF ; Call it a line feed
;
;
; Compare the string with characters in the buffer
;
INX D
ORA A ; End of string?
JZ MATCHED
;
CPI '|'
JZ MATCHED ; First part
;
MOV B,A ; Store the string character for now
MOV A,M ; Get the buffer character
CPI 'a' ; Test for lower case
JC NOTLWR
CPI 'z'+1
JNC NOTLWR
ANI 5FH
;
NOTLWR: MOV C,A ; Store temporarily
INX H
MOV A,B ; Get the string character back again
CPI '?' ; If wild card, accept any character
JZ CLOOP ; Match so far, keep going
CMP C ; String char. match buffer char?
JZ CLOOP ; Matched, so keep going
;
;
; Not equal
;
POP H ; Restore the buffer address
INX H ; Next buffer position
MVI B,0 ; Zero out temporary "end of file" flag
MOV A,M ; Get the character
CPI ETX ; At end of buffer?
JZ NOTEQL ; If yes, exit
;
CPI EOT
JNZ NXTSTR ; If not, keep going
INR B
;
NOTEQL: LHLD STRPTR ; Reload the string pointer
;
;
; If an 'OR' (|) is in the line, scan for it
;
FINDOR: MOV A,M ; Get the character from the string
INX H ; Next position in string
CPI '|' ; Divisor between strings
JZ ORLINE ; Was a divisor, so check next string
ORA A ; End of string?
JNZ FINDOR ; If neither, keep checking
;
;
; Start the buffer over again
;
MOV A,B ; Get our temporary "all done" flag
ORA A
JNZ TDONE1 ; If not zero, all finished
LXI D,BUFFER+1 ; Keep the one '-' from very first line
POP H ; Restore the TBUF address
JMP NEXT ; Get the next character and continue
;
;
; Now print the line itself
;
MATCHED:POP H ; Restore the stack from inner loop
LDA FIRSTM
ORA A
JNZ MATCH0
INR A
STA FIRSTM
CALL ILPRT
DB CR,' ',CR,LF,0
;
MATCH0: LXI H,BUFFER ; Start at beginning of buffer
;
MATCH1: MOV A,M ; Get the character
CPI ETX ; End of Text?
JZ MATCH2 ; If yes, start next group
CPI EOT ; End of transmission?
JZ TDONE1 ; If yes, all finished now
CALL TYPE ; Show on CRT
INX H ; Next character in buffer
JMP MATCH1
;
MATCH2: POP H ; Restore the TBUF address
LXI D,BUFFER+1 ; Keep the original '-' to balance line
JMP NEXT ; Get the next group
;.....
;
;
RERROR: CPI 1 ; File finished?
JZ TDONE ; Exit, then
CALL EXIT
DB '++ SOURCE FILE READ ERROR ++$'
;.....
;
;
; Transfer is done - close destination file
;
TDONE: LDA SHOWAL ; Showing all text?
ORA A
JZ TDONE1 ; If yes, exit
MVI A,EOT ; Store ad "end of transmission" char.
STAX D
JMP COMPAR ; Make a final comparison
;
TDONE1: MVI C,CLOSE
LXI D,FILE
CALL BDOS
CALL EXIT
DB CR,'----'
DB CR,LF,'[End of listing]','$'
JMP EXIT1
;.....
;
;
; Send character in A register to console
;
TYPE: PUSH B
PUSH D
PUSH H
PUSH PSW
MOV E,A ; Character to 'E' for CP/M
MVI C,WRCON ; Write to console
CALL BDOS
POP PSW
POP H
POP D
POP B
RET
;.....
;
;
;***********************************************************************
;
; Data area
;
;***********************************************************************
;
;
FILE: DB 0,'FFOR '
DB 0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0
;
DRUSER: DB 0 ; Store original drive/user area
FIRSTM: DB 0 ; To clear "wait a momemnt....."
LFEED: DB 0 ; Checks the character after a line feed
SHOWAL: DB 0 ; Flag to show all text if no strings
STRPTR: DW 0 ; Pointer for "|" scan
;
STRING: DS 128 ; What to search for
DS 40 ; Room for 20-level stack
;
;
; Set write buffer to even page boundry
;
ORG ($+255)/256*256
;
BUFFER EQU $ ; Write buffer starts here
STACK EQU BUFFER-2
;
;
; BDOS equates
;
RDCON EQU 1 ; Read console
WRCON EQU 2 ; Write to console
PRINT EQU 9 ; Print string
CONST EQU 11 ; Get console status
SELDSK EQU 14 ; Select requested disk drive
OPEN EQU 15 ; Open a file
CLOSE EQU 16 ; Close a file
READ EQU 20 ; Read sequential file
SETDMA EQU 26 ; Set dma address
SETUSR EQU 32 ; Set requested user area
;
BDOS EQU 0005H
TBUF EQU 0080H
;.....
;
;
END