; FILE23.ASM ; ; This program will search all user areas of all drives for any files ; matching the request on the command line. Allowable user areas for ; CP/M are 0-15. Originally written by R. Rodman. ; ; Example: FILE *.COM lists all .COM files on all drives and ; all allowable areas (set by default to ; show through user 15.) ; ; FILE displays short help message ; ; FILE *.COM S Lists all matching file and includes ; all system files as well. read only ; files will be followid by "--ro" in ; all cases. ; ; Please return any updates to technical CBBS Dearborn MI (313) 846-6127 ; so the file will be available to all. ; ;======================================================================= ; ; 01/27/86 Converted program from Z80 mnemonics back to Intel 8080 like ; v21 it was prior to version 22. It may once again be assembled ; with any normal 8080 assembler instead of requiring the M80 ; assembler and L80 linker (or the Z80ASM assembler by SLR.) ; - Irv Hoff ; ; 06/06/85 a. Added a table to enable / disable any combination of ; v22 drives users. See "DTABL:" in code. The table starts ; at 104H. ; b. Start next drive on new line. ; c. Start next user display on new line. ; d. Changed 8080 code to Z80 code. ; e. Added optional display of SYSTEM files. Set SHOSYS="NO" ; If you enter FILE22 FILENAME.TYP, only non-system ; files will be displayed. Read-only files will be dis- ; played as "FILENAME.TYP--RO". FILE22 NAME.EXT S, ; the "S" will enable the system file display and all ; files will be displayed in the following four formats. ; ; FILENAME.TYP = not a system nor read-only file ; FILENAME.TYP--ro = not system file, just read-only ; FILENAME.TYP-s-- = is a system file, but not read-only ; FILENAME.TYP-sro = is a system read-only file ; The -xxx will be in lower case to make it easier to read ; if your CRT has lower case. ; ; f. Added a flag byte at 104H. This byte enables/disables ; the displaying of "USER PROTECTED AREA" message for ; users that are turned off. 00=no message, FFH=display ; message. ; g. Added "S" option to menu after entering "FILE" ; h. Tested on CP/M 2.2 using 512-K ram disk & 85M hard disk. ; i. Tested on CP/M 3.0+ using 96-K ram and 130M hard disk. ; ; *** Only 8080 compatible Z-80 instructions are used. *** ; The code can be assembled using Microsoft M80.COM and ; L80.COM or SLR Systems Z-80 assembler. ; - Ron Lambert Sprague Electric Co. ; (615)-457-4130 ex 226 ; ; 02/27/84 Reformatted, standardized tabs, minor changes, ran through ; v21 FILTX and TABASM, saving 19 sectors of source code length. ; - Irv Hoff ; ; 01/14/84 Fixed bug in user area search limit when USEMAX true. When ; v20 using ZCMD/NZCPR, location 03FH contains Max. user area +1, ; and FILE was using this as absolute limit. ; - Mark Howard ; ;======================================================================= ; ; YES EQU 0FFFFH NO EQU NOT YES ; ; Set the following as desired: ; SHORO EQU YES ; 'YES' to display --ro at all times ; "NO" to just display in "S" mode if ; they are read only. SHOSYS EQU YES ; 'YES' if want to show system files DRVTYP EQU YES ; 'YES' if BIOS has 'ILLEGAL DRIVE SELECT' ; ; ; Trap set 'NO' if no trap in BIOS, then set 'MAXDRV' to the number of ; drives to search through for the requested file. ; MAXDRV EQU 2 ; Number of drives to search (1-16) MAXCOL EQU 4 ; Max number of displayed columns wanted MAXUSR EQU 15 ; Max user # to be checked (0-15) USEMAX EQU NO ; 'YES' for dynamic changes USRMAX EQU 03FH ; Location of MAXUSER byte DRIVMAX EQU 03DH ; Location of MAXDRIV byte ; ; ; Define some miscellaneous values: ; BDOS EQU 0005H ; CP/M BDOS entry point FCB EQU 005CH ; CP/M file control block address TBUF EQU 0080H ; DMA buffer address CR EQU 0DH ; ASCII return LF EQU 0AH ; ASCII linefeed ; ; ; BDOS calls ; 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 ; ; ORG 0100H ; START: JMP START0 ; Stip over table ; ; ; Flag byte for display of "user protected" message ; DPROT: DB YES ; "YES" to display protected user msg ; ; ; This table is used to set up all allowed drives and users. You may ; set the table for any number of drives (maximum is 16) and display ; any combination of drives and users. You must set up the table as ; follows. The first byte should be either the drive #, "DISON", or ; "DISOFF". Here is an example of how one system was set: ; ; A: as ram disk ; B: 8" DSDD floppy ; C: 8" DSDD floppy ; D: 5" floppy (not installed so has "DISOFF" to disable the drive) ; ; This program is also put on a user's area and restricts his viewing of ; certain sections. You might want to rename FILE22.COM to DIR.COM for ; general use. ; ; If the table for drive A: is as follows ; A: 0 1 2 3 4 5 6 7 8 9 A B C D E F ; 80H,FF,FF,FF,00,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF ; display all user areas except 3 ; ; If the table for dirve B: is as follows ; B: 0 1 2 3 4 5 6 7 8 9 A B C D E F ; 80H,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF ; display all users ; ; If the table for Drive C: is as follows ; C: 0 1 2 3 4 5 6 7 8 9 A B C D E F ; DISOFF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF ; Skip this drive completely ; ; If you have three drives, A:, B:, and C:, set the first byte of D: to ; "YES", this will flag that C: is your last drive. ; ; If byte 0 of any of the drives (0-15) is: ; DISON = look at this drive ; DISOFF = drive not in system ; LASTD = last drive + 1 (end of table) ; ; Byte 2-17 ; NO = do not display this user area ; YES = display this user ; LASTD EQU YES ; Flag for last drive + 1 DISON EQU 80H ; Drive is enabled DISOFF EQU NO ; Drive is disabled ; DTABL: DB DISON ; A 512-K ram disk, that looks DB YES,YES,YES,YES ; Just like another floppy DB YES,YES,YES,YES ; So look here also DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; B 8" DS/DD floppy, that is DB YES,YES,YES,YES ; Always on the system because DB YES,YES,YES,YES ; I boot off of it, so look at DB YES,YES,YES,YES ; It DB YES,YES,YES,YES ; DB DISOFF ; C: non existant floppy, skip it DB YES,YES,YES,YES ; This is my second DS/DD 8" DB YES,YES,YES,YES ; Drive, but if no disk is in DB YES,YES,YES,YES ; It, I get "DRIVE NOT READY" DB YES,YES,YES,YES ; So don't look at it. ; DB DISOFF ; D: non existant floppy, skip it DB YES,YES,YES,YES ; This is set up to be a 5 1/4" DB YES,YES,YES,YES ; Drive which is not connected DB YES,YES,YES,YES ; So don't look here either DB YES,YES,YES,YES ; DB DISON ; E: 8 hard disks assigned E:-N: DB YES,YES,YES,YES ; So set O: to LASTD to flag DB YES,YES,YES,YES ; That N: is the last legal DB YES,YES,YES,YES ; Drive. DB YES,YES,YES,YES ; DB DISON ; F DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; G DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; H DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; I DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; J DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; K DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; L DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; M DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; N DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB LASTD ; O:, N: is the last hard disk DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB DISON ; P DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES DB YES,YES,YES,YES ; DB 0FFH ; End of drive table ; START0: LXI H,0 ; Set 'HL' to zero DAD SP ; Get stack pointer into 'HL' SHLD STACK ; Save for exit to 'CCP' stack LXI SP,STACK ; Set up local stack MVI A,MAXCOL ; Reset column number after last column STA COLUMN CALL ILPRT ; Print sign-on message DB CR,LF,'FILE v22 06/06/85 - ^C to abort',CR,LF,0 LDA FCB+1 ; Check for filename on command line CPI ' ' JZ NONAME CALL ILPRT DB 'Searching all drives, and all user areas',CR,LF,00 ; SETUP: LDA 0004H ; Save user & drive # STA UDNUM RRC ; 1st 4 bits give current user # RRC RRC RRC ANI 0FH ; 'and' off the drive bits STA CUN ; Save current user # MOV B,A ; IF USEMAX LDA USRMAX DCR A ENDIF ; IF NOT USEMAX MVI A,MAXUSR ENDIF ; CMP B JC OUTSIDE XRA A STA CTU ; Set current try user to 0: STA ORIGCTU ; Set original 'CTU' to same ; IF USEMAX LDA USRMAX DCR A ENDIF ; IF NOT USEMAX MVI A,MAXUSR ENDIF ; STA MAXTEMP ; Set maximum user number to 'maxusr' ; SBOOT: LXI D,TBUF MVI C,SETDMA CALL BDOS ; Set DMA address MVI A,0 ; Start looking on 0 drive ('A') STA TRYDRV ; Set up to try drive '0' first ; TRY: LDA TRYDRV ; Try to select drive CALL TDRIVE ; See if a legal drive CPI 0FFH ; End of drives to test JNZ TRY02 ; ; ; Last drive + 1, exit ; CALL ILPRT DB CR,LF,00 JMP DONE1 ; Y...exit ; TRY02: LDA TRYDRV ; Get drive ADI 'A' ; N...ASCII it STA DDRIV STA DDRIV0 ; TRY01: CALL ILPRT DB CR,LF,' ---- Drive ' ; DDRIV: DB 00 ; Put drive here DB ': ----',00 ; IF SHOSYS ; LDA 6DH ; See if system display is on ANI 01011111B ; Convert to upper case CPI 'S' ; "S" = y... JNZ NONSYS ; N... CALL ILPRT ; Y... DB ' * * * System File Display Active * * *',00 ENDIF ; NONSYS: CALL ILPRT DB CR,LF,00 ; ; ; Test for allowed drive, 00=n..., FF=y... ; TRY1: LDA TRYDRV ; Try to select drive CALL TDRIVE ; See if a legal drive CPI NO ; Drive allowed JNZ TRY2 ; Y...continue ; CALL ILPRT DB CR,LF,'Drive ' ; DDRIV0: DB 00 ; Put drive here DB ': has been disabled.',CR,LF,LF,00 LDA TRYDRV INR A STA TRYDRV JMP TRY ; Next drive ; TRY2: LDA TRYDRV ; Get legal drive MOV E,A MVI C,SELDRV CALL BDOS LDA TRYDRV INR A STA TRYDRV ; Get ready for next drive, too STA FCB ; Store 1+drive# in FCB (1=A, 2=B, etc.) ; NXTUSR: LDA CTU ; Set user to 'CTU' via a BDOS call CALL TUSER ; See if we display this user JNZ NXT1 LDA CTU ; Get user INR A ; Skip this user STA CTU ; MOV B,A ; Get user in (B) LDA MAXTEMP ; See if done CMP B JNC NXT01 ; Y... JMP NXT2 ; NXT01: LDA DPROT ; Look at protected flag ORA A ; See if display is ON/OFF JZ NXT1 ; Off... CALL ILPRT DB 'Protected user area encountered',CR,LF,00 JMP NXTUSR ; NXT1: LDA CTU ; Resume with next one MOV E,A MVI C,SETUSR CALL BDOS ; AVAIL: MVI C,CONSTAT ; Check to see if key pressed CALL BDOS ORA A JZ NOPRESS ; If no key pressed, then continue MVI C,CONIN ; If key pressed, then check for abort CALL BDOS CPI 'C' AND 1FH ; Is it CTL-x? ; AVAIL1: JNZ NOPRESS ; If no, then continue CALL ILPRT ; If yes, then print abort message DB CR,LF,CR,LF,' + + ABORTED + +',0 JMP DONE1 ; NOPRESS:LXI D,FCB MVI C,SRCHFST CALL BDOS ; Check for directory match with 'FCB' CPI 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 MVI A,-1 STA FNDFIL ; SNEXT: MVI C,SRCHNXT CALL BDOS ; Check for next match with FCB CPI 0FFH JZ NXT ; No more matches? then do next drive CALL SHOFIL ; If match found, display the filename MVI A,-1 STA FNDFIL JMP SNEXT ; Continue until no more matches found ; NXT: LDA FNDFIL ; Get found file falg ORA A ; 0=N... JZ NXT0 LDA COLUMN CPI MAXCOL JZ NXTA CALL CRLF ; NXTA: CALL ILPRT DB CR,LF DB 'Searching Additional Users',CR,LF,00 MVI A,MAXCOL ; Reset column number after last column STA COLUMN XRA A STA FNDFIL ; Clear found file falg ; NXT0: LDA CTU ; Increment current try user number INR A STA CTU MOV B,A LDA MAXTEMP CMP B JNC NXTUSR ; Do next user number if all not done ; NXT2: LDA ORIGCTU ; Else reset user # and do next drive STA CTU MVI C,RTNVER CALL BDOS ; See if CP/M version 1.4 or 2.x MVI C,5 ; (if CP/M 1.4, then BIOS must return an ORA A ; Error if bad drive #, else won't work) JZ FOUR ; If 1.4 then four drives maximum ; IF NOT USEMAX ; If no trap then the maximum drive is MVI C,MAXDRV ; Set manually. ENDIF ; IF USEMAX LDA DRIVMAX INR A MOV C,A ENDIF ; FOUR: LDA TRYDRV CMP C JC TRY ; Continue until all drives checked... ; ; ; Done now, return to CP/M ; DONE: LDA MFLAG ; See if any files found ORA A JNZ DONE1 ; If yes, then done, so exit CALL ILPRT ; If no, then say none found first DB CR,LF,CR,LF,' + + FILE NOT FOUND + +',0 ; DONE1: CALL ILPRT DB CR,LF,0 ; Turn up a line LDA UDNUM ; Restore user/drive number STA 4 ANI 0FH MOV E,A ; Select the default drive MVI C,SELDRV CALL BDOS ; EXIT: LDA UDNUM RLC RLC RLC RLC ; Make it a user area ANI 15 ; Make it between 0 and 15 MOV E,A ; Put it in 'E' register MVI C,SETUSR ; Set user area CALL BDOS ; EXITSPCL: CALL ILPRT DB ' Search Completed',CR,LF,00 LHLD STACK ; Get old stack value SPHL RET ; All done ;..... ; ; NONAME: CALL ILPRT ; Else, print help message and exit DB 1AH ; Clear screen chr. DB CR,LF DB ' You must specify the file(s) you want to find.' DB CR,LF DB ' Wildcards are OK.',CR,LF,LF DB ' Example: FILE MDM7.DOC',CR,LF DB ' FILE MOD*.*',CR,LF DB ' FILE *.ASM',CR,LF,LF DB ' The "S" option will enable the display',CR,LF DB ' of files with the system attribute set',CR,LF,LF DB ' FILE MDM7.DOC S',CR,LF DB ' FILE *.* S',CR,LF DB ' FILE MOD*.* S',CR,LF DB ' FILE *.COM S',CR,LF,LF DB ' The last four will display as follows',CR,LF DB ' FILENAME.TYP = non system read write file' DB CR,LF DB ' FILEMANE.TYP--ro = non system read only file' DB CR,LF DB ' FILENAME.TYP-s-- = read write system file',CR,LF DB ' FILEMANE.TYP-sro = system read only file',CR,LF DB 00 ; ; ; Reset everything and exit ; LDA UDNUM RLC RLC RLC RLC ; Make it a user area ANI 15 ; Make it between 0 and 15 MOV E,A ; Put it in 'E' register MVI C,SETUSR ; Set user area CALL BDOS ; ; ; Restore old stack ; LHLD STACK ; Get old stack value SPHL ; RET ; All done ;..... ; ; OUTSIDE:LDA CUN STA CTU ; Set current try user to current user # STA ORIGCTU ; Set original 'CTU' to same STA MAXTEMP ; Set maximum user number to current JMP SBOOT ; And continue... ; SHOFIL: MOV L,A ; Get filename to display from directory MVI H,0 ; Which CP/M puts at DMA address DAD H ; ('A' register has relative position of DAD H ; Name within directory record) DAD H DAD H DAD H ; Multiply 'A' by 32 for filename start LXI D,TBUF ; Filename DAD D ; Now point to filename XCHG ; Save filename pointer in 'DE' ; IF SHOSYS ; Then ignore 'SYS' files LXI H,10 DAD D ; Point to 'SYS' file attribute MOV A,M ANI 80H ; Check for 'SYS' type file STA SAVSAT ; Save attributes DCX H ; To next test byte MOV A,M ; Get it ANI 80H ; Check for "R/O" type file STA SAVRAT ; Save attribute INX H LDA 6DH ; Get first chr of second FCB ANI 01011111B ; Convert to upper case CPI 'S' ; "S" = yes, display system files JZ ISOPS ; Y...is optional "S" LDA SAVSAT ; Get attribute again ORA A ; Test for 00 RNZ ; Don't display if 'SYS' file ENDIF ; NOT SHOSYS ; ISOPS: LDAX D ; Get user number INX D PUSH PSW ; Save the user number ; ; ; Print "drive user: FILENAME.TYP" ; SHOFIL1:LDA TRYDRV ; Get the disk drive ADI 'A'-1 ; Convert binary to ASCII CALL AOUT ; Display drive (a-p) POP PSW ; Save the user number CPI 9+1 ; 0-9 ? JC USRL ; If yes, exit SUI 10 ; User number = 10 thru 15 PUSH PSW ; Remainder is <10 MVI A,'1' CALL AOUT2 ; Print a leading '1' POP PSW ; Get the remainder back ; USRL: ADI '0' ; Convert from binary to ASCII # CALL AOUT2 ; Print digit ; NOUSR: MVI A,':' ; Fence character CALL AOUT2 ; Display a ':' to look nice ; ; ; FILENAME.TYP ; MVI B,8 ; (8 characters or less in filename) ; PFN: LDAX D ; Now print the filename.. INX D ; CALL AOUT2 ; One character at a time DCR B JNZ PFN ; Continue for all 8 characters MVI A,'.' CALL AOUT2 ; Display the '.' before the filetype MVI B,3 ; Now do the same for the filetype ; PXT: LDAX D INX D CALL AOUT2 DCR B JNZ PXT LDA COLUMN ; Print MAXCOL columns across the screen DCR A JZ TEOL ; Go test end of line STA COLUMN CALL THRESP ; Print two spaces to make it neat MVI A,0FFH ; Show that a file was found STA MFLAG ; Suppresses 'not found' message RET ;..... ; ; ; This is end of line sequence, see if it is a system file ; TEOL: LDA SAVSAT ; Test the attribute flag ORA A ; 00=not sys file JZ TEOL1 CALL ILPRT DB 's',0 ; Is system file LDA SAVRAT ORA A JZ TEOL2 CALL ILPRT DB 'ro',0 ; Sys and read only JMP DOCRLF ; TEOL1: IF SHORO LDA SAVRAT ORA A JZ DOCRLF ; Not sys, not read only, just c/r l/f CALL ILPRT DB '-ro',0 ; Just read only ENDIF ; JMP DOCRLF ; TEOL2: CALL ILPRT ; Not read only, just system DB '--',0 ; ; ; CR/LF ; DOCRLF: MVI A,MAXCOL ; Reset column number after last column STA COLUMN ; CRLF: CALL ILPRT DB CR,LF,0 RET ;..... ; ; THRESP: LDA SAVSAT ; Test the attribute flag ORA A ; 00=not sys file JZ NOTSYS CALL ILPRT DB 's',0 ; Is system file JMP ISSYS ; NOTSYS: IF SHORO LDA SAVRAT ORA A ; Test for read only JZ THRES0 ; Not sys or read only CALL ILPRT DB '-ro ',0 ; Is read only ENDIF ; SHORO ; IF NOT SHORO CALL ILPRT DB ' ',0 ENDIF ; RET ;..... ; ; ISSYS: LDA SAVRAT ORA A ; Test for read only JZ NOTRO0 CALL ILPRT DB 'ro ',0 ; Is read only RET ;..... ; ; ; Not R/O, make it spaces ; NOTRO0: CALL ILPRT DB '-- ',0 RET ;..... ; ; ; Not system, make it 5 spaces ; THRES0: CALL ILPRT DB ' ',0 RET ;..... ; ; AOUT: MOV B,A ; Save the character for now ; AOUT2: PUSH B ; Send a character to the console PUSH D PUSH H ; Save registers in case bdos eats them ANI 7FH ; Strip parity bit MOV E,A MVI C,2 CALL BDOS ; Print the char. in 'A' on the console POP H POP D POP B ; Restore the registers RET ;..... ; ; ; Inline print routine ; ILPRT: XTHL ; Set 'HL' to point to message ; ILPLP: MOV A,M ; Get a character from message CALL AOUT2 ; Output it INX H ; Point to next character MOV A,M ; Check for end of message ORA A ; (00H marks end of message) JNZ ILPLP XTHL ; Get proper return address onto stack RET ; Then return to program ;..... ; ; ; Test for legal drive or end of drives ; TDRIVE: PUSH H PUSH D PUSH B INR A LXI H,DTABL ; Point to table LXI D,17 ; 16 bytes per table plus 1 for drive no ; TDRIV0: DCR A ; Adjust (A) JZ ISD DAD D ; Not correct, index to next drive JMP TDRIV0 ; ISD: MOV A,M ; Get drive no. ORA A ; 00=skip, <> 0 = OK POP B POP D POP H RET ;..... ; ; ; To display or not to display, that is the question! ; TUSER: PUSH H PUSH D PUSH B LDA TRYDRV LXI H,DTABL ; Point to table LXI D,17 ; 16 bytes per table plus 1 for drive ; TUSER0: DCR A ; Adjust (A) JZ ISU DAD D ; Not correct, index to next drive entry JMP TUSER0 ; ISU: INX H LDA CTU ; Get user no. MVI D,00 ; Set up offset MOV E,A DAD D ; Add it to pointer MOV A,M ; Read in user's on/off display byte ORA A ; 00=skip, <> 0 = OK POP B POP D POP H RET ;..... ; ; COLUMN: DB MAXCOL ; Column counter SAVSAT: DB 0 ; Storage for system attribute flag SAVRAT: DB 0 ; Storage for read only attribute flag 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 FNDFIL: DB 0 ; FOUND A FILE = FF ; DS 64 ; 32 level stack should be enough room ; STACK: DS 2 ; ; END ; ; ; ; ; Line numbers containing untranslated opcodes: ; ;