; ; FIND.A86 - Fast File Finder ; ; To Assemble: ASM86 FIND $PZSZ ; GENCMD FIND ; ; This program will search all user areas of the specified drive for any files ; matching the request on the command line. It then displays those files to ; the screen. ; ; Originally written by R. Rodman. Translated to CP/M-86 by Alex Soya. ; Totally revamped by Kirk Lawrence ; ;======================================================================= ; ; ; DEFINE TRUE AND FALSE ; YES EQU 0FFH NO EQU 0 ;..... ; ; ; SET THE FOLLOWING AS DESIRED: ; SHOWSYS EQU YES ;'YES' if want to show system files MINDRV db 0 MAXDRV db 0 ;number of drives to search through MAXCOL EQU 4 ;max number of columns desired in display MINUSR EQU 0 ;min user Number MAXUSR EQU 15 ;max user # to be checked (0-15 possible) ;..... ; ; ; DEFINE SOME MISCELLANEOUS VALUES: ; BASE EQU 0 ;set to base address of your cp/m BDOS EQU 224 ;CP/M BDOS entry point CR EQU 13 ;ASCII return FCB EQU BASE+5Ch ;CP/M file control block address LF EQU 10 ;ASCII linefeed TBUF EQU BASE+128 ;DMA buffer address ;..... ; ; ; DEFINE SOME BDOS FUNCTIONS: ; CONIN EQU 1 ;console input function CONOUT EQU 2 ;console output function PRINT EQU 9 ;print string at console function CONSTAT EQU 11 ;get console status function RTNVER EQU 12 ;return version number function SELDRV EQU 14 ;select drive SRCHFST EQU 17 ;search for first function SRCHNXT EQU 18 ;search for next function SETIOB EQU 24 ;set I/O byte SETDMA EQU 26 ;set DMA address function SETUSR EQU 32 ;set/get user code function ;..... ; ; CSEG ; START: pushf ! pop bx cli ; No interrupt during stack messing mov ax,ds mov ss,ax mov sp, offset STACK push bx ! popf ; ; see if user has specified a drive other than the default drive ; mov al,byte ptr .FCB ;get the driver specifier from FCB cmp al,0 ;is it a zero? je default ;yes, so assume default drive dec al ;convert to drive number (A=0, etc.) mov mindrv,al ;save drive # in variable mov maxdrv,al ; ...and again jmp proceed ;go do it ; ; handle the default drive ; default: mov cl,25 ;function 25 - return current disk int 224 ;call BDOS mov mindrv,al ;save drive # in variable mov maxdrv,al ; ...and again inc al ;convert to useable drive number mov byte ptr .FCB,al ;stuff it into the FCB ; proceed: CALL ILPRT ;print sign-on message DB CR,LF,' FIND Version 0.0 - Fast Filer Finder' db cr,lf,' Freeware from Kirk Lawrence',cr,lf,lf,0 MOV AL,Byte Ptr .FCB+1 ;check for filename on command line CMP AL,' ' JNZ $+5 JMP NONAME CALL ILPRT DB ' Searching (CTRL-X aborts)...',0 ; SETUP: mov cl,SETUSR ; Get User Number mov dl,0ffh int bdos MOV UDNUM,AL ; Save it MOV CUN,AL ;save current user # MOV CH,AL ; MOV AL,MAXUSR ; CMP AL,CH JNC INSIDE JMP OUTSIDE INSIDE: MOV AL,MINUSR MOV CTU,AL ;set current try user to 0: MOV ORIGCTU,AL ;set original 'CTU' to same ; MOV AL,MAXUSR ; MOV MAXTEMP,AL ;set maximum user number to 'maxusr' ; SBOOT: MOV DX,OFFSET TBUF MOV CL,SETDMA INT BDOS ;set DMA address MOV AL,MINDRV ;start looking on current drive MOV TRYDRV,AL ; ; TRY: MOV AL,TRYDRV ;try to select drive MOV DL,AL MOV CL,SELDRV INT BDOS MOV AL,TRYDRV INC AL MOV TRYDRV,AL ;get ready for next drive, too MOV Byte Ptr .FCB,AL ;store 1+drive# in FCB (1=A, 2=B, etc.) ; NXTUSR: MOV AL,CTU ;set user to 'CTU' via a BDOS call MOV DL,AL MOV CL,SETUSR INT BDOS ; AVAIL: MOV CL,CONSTAT ;check to see if key pressed INT BDOS OR AL,AL JNZ $+5 JMP NOPRESS ;if no key pressed, then continue MOV CL,CONIN ;if key pressed, then check for abort INT BDOS CMP AL,'X'-40H ;is it CTL-x? ; AVAIL1: JNZ NOPRESS ;if no, then continue CALL ILPRT ;if yes, then print abort message DB CR,LF,LF,' = Search aborted at user request.',0 JMP DONE1 ;..... ; ; NOPRESS: MOV DX,OFFSET FCB MOV CL,SRCHFST INT BDOS ;check for directory match with 'FCB' CMP AL,0FFH ;a-reg. has 0-3 if file found else 0FFH JZ NXT ;do next drive if no more matches found CALL SHOFIL ;if match found, display the filename ; SNEXT: MOV CL,SRCHNXT INT BDOS ;check for next match with FCB CMP AL,0FFH JZ NXT ;no more matches? then do next drive CALL SHOFIL ;if match found, display the filename JMP SNEXT ;continue until no more matches found ; NXT: MOV AL,CTU ;increment current try user number INC AL MOV CTU,AL MOV CH,AL MOV AL,MAXTEMP CMP AL,CH JC $+5 JMP NXTUSR ;do next user number if all not done MOV AL,ORIGCTU ;else reset user # and do next drive MOV CTU,AL ; MOV cl,MAXDRV ; FOUR: MOV AL,TRYDRV CMP AL,CL JNC DONE JMP TRY ;continue until all drives checked... ; ; ; ALL DONE NOW, RETURN TO CP/M ; DONE: MOV AL,MFLAG ;see if any files found OR AL,AL JNZ DONE1 ;if yes, then done, so exit CALL ILPRT ;if no, then say none found first DB CR,LF,LF,' = No files matching your filespec were found.',0 ; DONE1: CALL ILPRT DB CR,LF,0 ;turn up a line ; EXIT: MOV DL,UDNUM ;put it in 'DL' register MOV CL,SETUSR ;set user area INT BDOS ; EXITSPCL: MOV CL,0 INT BDOS ; All Done ;..... ; ; NONAME: CALL ILPRT ;else, print help message and exit DB CR DB ' Syntax: FIND [d:]filespec',CR,LF,LF DB ' The drive letter [d:] is optional.',CR,LF db ' (If omitted, the default drive is assumed.)',cr,lf,lf db ' Wildcards ("*" and "?") in the filespec are fully supported.',CR,LF,LF db ' CTRL-X aborts the search at any time.',cr,lf,lf,0 ; DB ' Examples: FIND MODEM9.DOC finds all occurences on the default drive',CR,LF ; DB ' of the file name "MODEM9.DOC."',cr,lf,lf ; DB ' FIND MOD*.* A: finds all occurences on drive A: of files',CR,LF ; db ' whose name begins with the letters "M-O-D."',cr,lf,lf ; DB ' FIND *.A86 finds all occurences on the default drive',CR,LF ; db ' of files whose extension is "A86."',cr,lf,lf ; DB ' FIND *.* M: prints all filenames in all user areas',CR,LF ; db ' of drive M: to the screen.',cr,lf,lf,0 JMP EXIT ;return to CP/M ; OUTSIDE: MOV AL,CUN MOV CTU,AL ;set current try user to current user # MOV ORIGCTU,AL ;set original 'CTU' to same MOV MAXTEMP,AL ;set maximum user number to current JMP SBOOT ;and continue... ; SHOFIL: MOV BL,AL ;get filename to display from directory MOV BH,0 ;which CP/M puts at DMA address mov cl,5 shl bx,cl ;multiply 'A' by 32 to point to start of MOV DX,OFFSET TBUF ;filename ADD BX,DX ;now point to filename XCHG BX,DX ;save filename pointer in 'DE' ; IF NOT SHOWSYS ;then ignore 'SYS' files MOV BX,OFFSET 10 ADD BX,DX ;point to 'SYS' file attribute MOV AL,[BX] AND AL,80H ;check for 'SYS' type file JZ NOSYS RET ;don't display if 'SYS' attribute is set ENDIF ;NOT SHOWSYS ; NOSYS: XCHG BX,DX MOV AL,[BX] XCHG BX,DX ;get user number INC DX LAHF PUSH AX ;save the user number CMP AL,9+1 ;is user number = 0 thru 9? JC $+5 JMP SHOFIL1 ;if not, exit MOV AL,' ' CALL AOUT ;print the extra space ; SHOFIL1: MOV AL,TRYDRV ;get the disk drive ADD AL,'A'-1 ;convert binary to ASCII CALL AOUT ;display drive (a-p) POP AX SAHF ;save the user number CMP AL,9+1 ;0-9 ? JC USRL ;if yes, exit ; SUB AL,10 ;user number = 10 thru 15 LAHF PUSH AX ;remainder is <10 MOV AL,'1' CALL AOUT2 ;print a leading '1' POP AX SAHF ;get the remainder back ; USRL: ADD AL,'0' ;convert from binary to ASCII # CALL AOUT2 ;print digit ; NOUSR: MOV AL,':' ;fence character CALL AOUT2 ;display a ':' to look nice MOV CH,8 ;(8 characters or less in filename) ; PFN: XCHG BX,DX MOV AL,[BX] XCHG BX,DX ;now print the filename.. INC DX CALL AOUT2 ;..one character at a time DEC CH JNZ PFN ;continue for all 8 characters MOV AL,'.' CALL AOUT2 ;display the '.' before the filetype MOV CH,3 ;now do the same for the filetype ; PXT: XCHG BX,DX MOV AL,[BX] XCHG BX,DX INC DX CALL AOUT2 DEC CH JNZ PXT MOV AL,COLUMN ;print MAXCOL columns across the screen DEC AL JZ DOCRLF MOV COLUMN,AL CALL TWOSPC ;print two spaces to make it neat MOV AL,0FFH ;show that a file was found MOV MFLAG,AL ;suppresses 'not found' message RET ;..... ; ; DOCRLF: MOV AL,MAXCOL ;reset column number after last column MOV COLUMN,AL MOV AL,CR CALL AOUT2 MOV AL,LF CALL AOUT2 RET ;..... ; ; TWOSPC: MOV AL,' ' CALL AOUT2 MOV AL,' ' JMP AOUT2 ; AOUT: MOV CH,AL ;save the character for now MOV AL,FIRST OR AL,AL JNZ AOUT1 CALL ILPRT DB CR,LF,CR,LF,0 MOV AL,1 MOV FIRST,AL ; AOUT1: MOV AL,CH ; AOUT2: PUSH CX ;send a character to the console PUSH DX PUSH BX ;save registers in case bdos eats them AND AL,7FH ;strip parity bit MOV DL,AL MOV CL,2 INT BDOS ;print the char. in 'A' on the console POP BX POP DX POP CX ;restore the registers RET ;..... ; ; ; INLINE PRINT ROUTINE ; ILPRT: POP SI ; ILPLP: LODS CS:BYTE PTR [SI] ;get a character from message OR AL,AL ; End of Message ? JZ ILPRET CALL AOUT2 ;output it JMPS ILPLP ILPRET: PUSH SI ; Put Return Address on Stack RET ; then return to caller ;..... DSEG org 100h ; COLUMN DB MAXCOL ;column counter CTU DB 0 ;current try user number CUN DB 0 ;currently logged-in user number FIRST DB 0 ;first time use of 'AOUT' (for CR/LF) MAXTEMP DB 0 ;maximum try user number MFLAG DB 0 ;flag set to non-zero if file is found ORIGCTU DB 0 ;original current try user number TRYDRV DB 0 ;number of drive being tried UDNUM DB 0 ;user/drive number is saved here ; ;..... ; ; RS 128 ;64 level stack should be enough room STACK dw 0 ;..... ; ; END