home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************
- ;* *
- ;* < - SUPER DIRECTORY PROGRAM - > *
- ;* SD100 *
- ;************************************************************************
- ;
- MAIN EQU 1 ; Main block number
- VER EQU 00 ; Current version
- ;
- MONTH EQU 7 ; July
- DAY EQU 24 ; Day
- YEAR EQU 85 ; Year
- ;
- ASEG ; Needed for m80, ignore error made with mac
- ;
- ; NOTE: This version can be assembled with ASM, LASM,
- ; MAC, RMAC or M80. The name has been slightly
- ; changed as M80 cannot use names with a dash.
- ;
- ;=======================================================================
- ;
- ; Displays the directory of a CP/M disk, sorted alphabetically, with the
- ; file size in k, rounded to the nearest CP/M block size. Also displays
- ; library files with the file size in k if the '$L' option is used.
- ;
- ;======================================================================
- ;
- ; 07/24/85 Rewrote the TIMEON code to allow use of the existing time-
- ; v100 on-system data contained in BYE5, BYE3, BYE+ or MBYE's RTC
- ; buffer. If TIMEON is YES, SD merely reports "Time on system
- ; is nnn minutes" and makes no attempt to log the user off.
- ; Logoff responsibility is delegated to the (M)BYE(+) program.
- ; TIMEON checks to see if BYE is running and continues without
- ; reporting time-on if not. No installation required to use
- ; this feature if you have clock code installed in your BYE.
- ; All page-1 equates previously used by TIMEON were deleted.
- ;
- ; This update also contains the SD99.FIX code for nested IF'
- ;
- ; - Wayne Masters, Potpourri
- ;======================================================================
- ;
- ; 07/11/85 Added THREBYT equate for systems needing a 3-byte sequence
- ; v99 for reverse video. If THREBYT is YES then the value coded
- ; at TBYTE is added to the reverse video sequence (currently
- ; set for a Kaypro).
- ;
- ; Also added a new "?" option which will display a menu
- ; of the $ options available if HELP is YES.
- ;
- ; - Steve Sanders
- ;======================================================================
- ;
- ; 03/15/85 Fixes obscure display bug which deletes display of 1, 2 or
- ; v98 3 file names in 3 out of 4 cases when the directory has
- ; >255 entries. The fix code was written by Peter Lyman.
- ; (See SD98.NOT).
- ; - Paul Foote ;
- ;=======================================================================
- ;
- ; 01/21/85 Added support for ZRDOS. Although CP/M compatible, ZRDOS
- ; v97 does not allow the SWAPEM technique of poking local values
- ; into the operating system. Instead, a test for ZRDOS is
- ; made and, if present, further calls to CPM: set the Warm
- ; Boot Trap in ZRDOS. On any error detected by ZRDOS the
- ; trap is reset and control is passed to DSKERR: No equates
- ; need be changed for CPM/ZRDOS, testing is dynamic in the
- ; run-time code.
- ; - Joe Wright
- ;
- ;=======================================================================
- ;
- ; 12/28/84 Added CP/M Plus TIMEON logic controlled by tag CPM3. Also
- ; inserted a call to CKABRT in routine TYPE to catch an abort
- ; request (^C) sooner.
- ; - George Peace
- ;
- ;=======================================================================
- ; Current versions of SD automatically adjust for any block size and di-
- ; rectory length under CP/M 1.4 or 2.x or MP/M (any version). They also
- ; automatically adjust for any number of disk drives and work satisfac-
- ; torily even if no disk is in that drive at the moment. Provisions are
- ; made for:
- ;
- ; (1) automatic pauses when the screen fills up
- ; (2) searching individual or multiple drives and/or user areas
- ; (3) unconditional or optional resetting the disk system before
- ; execution begins
- ; (4) directing output to a disk file called SD.DIR and appending
- ; to that file on subsequent runs
- ; (5) summary line output giving drive and user information, num-
- ; ber of files matched and how much space they consume, and
- ; the amount of free space remaining on the disk
- ; (6) displaying or suppressing "system" files
- ; (7) accepting ambiguous filenames with or without a drive name
- ; (8) printer output
- ; (9) optional help menu with $?
- ;
- ;
- ; See SD.DOC for detailed instructions on configuring and running SD.ASM
- ;
- ;=======================================================================
- ;
- ; 11/27/84 Would not assemble with ASM or M80. Now it will. Replaced
- ; v95 22 'PUSH A' and 'POP A' with conventional 'PUSH PSW' and
- ; 'POP PSW'. Found four instances of labels being used more
- ; than once with the same name. MAC didn't mind but ASM and
- ; M80 bombed. Many nested conditionals changed to enable nor-
- ; rmal assembly with ASM or M80 in addition to MAC. Surprised
- ; this has not been done some time ago. Name slightly changed
- ; as M80 doesn't seem to accept names with a dash (like SD-95).
- ; - Irv Hoff
- ;
- ; 11/24/84 Fixed a display bug, also removed a colon from a macro line.
- ; v94 - Steve Sanders
- ;
- ; 11/20/84 In previous versions of SD "SD $L" gave a size of "0K" for
- ; v93 any library member file which was exactly 255 records in
- ; length. This bug is fixed in SD-93, with code supplied by
- ; Gene Head. - Paul Foote
- ;
- ; 07/27/84 Some systems do not have contiguous disk drives. The XEROX
- ; v92 820 hard disk system for example assigns the only floppy
- ; drive as A: and the hard disk as drives E:, F:, G: & H:
- ; Code has been added to skip any drive whose maximum user
- ; area in the 'Drive code/user area lookup table' is set
- ; to a negative value. - Gene Head (N6NN/7)
- ;
- ; 07/25/84 Added routine to allow the command line or MAXCL option for
- ; v91 names per line to function with VCODE. (After several
- ; threats from my friends.) Also fixed a few small bugs in
- ; the display format I found after releasing SD-90. The
- ; state of MAXCL now has no affect on the drive status lines.
- ; They now follow the value of MNPL or MAXCL automatically.
- ; Because of this, the status line appears as it did prior to
- ; SD-90. The NPL equate now sets the default number of names
- ; per line if no command line option for columns is specified
- ; unless MAXCL = YES. - John Ray
- ;
- ;=======================================================================
- ;
- ;
- NO EQU 0
- YES EQU NOT NO ; M80 will not work with 0ffh
- ;
- CR EQU 0DH
- LF EQU 0AH
- ESC EQU 1BH
- ;
- ;***********************************************************************
- ;
- ; USER OPTION SPECIFICATIONS
- ;
- ;***********************************************************************
- ;
- HELP EQU YES ; Yes, allow $? and display options menu
- DIRCON EQU NO ; Yes for direct console output
- LOWCCP EQU NO ; Yes only if you are running with byelow
- BDOSPG EQU 0D4H ; Set properly if lowccp is yes
- CPM3 EQU NO ; Set to yes if running cp/m 3 or above
- ;
- TIMEON EQU NO ; If yes, SD will fetch TIMEON from BYE5, BYE3
- ; Or MBYE and display "Time on system is nnn
- ; Minutes". (or from BYE+nnn). Logoff, if time
- ; Limit is exceeded, is left up to (M)BYE(+).
- ; If (M)BYE(+) is not running it just returns.
- ;
- ; ZCPR options
- ;
- ZCPR2 EQU NO ; Yes if nzcpr/zcpr2 (wheel byte enabled)
- MAXUR EQU NO ; Yes if using maxusr in nzcpr/zcpr2
- MAXDR EQU NO ; Yes if using maxdrv in nzcpr/zcpr2
- MAXCL EQU NO ; Yes if storing mnpl value at maxc
- ;
- WHEEL EQU 3EH ; Set to wheel location if zcpr2 is yes
- ; Use 3eh if using nzcpr or zcmd
- ; Use 3bh if using unmodified zcprhdr file
- MAXU EQU 3FH ; Set to max user location if maxur is yes
- MAXD EQU 3DH ; Set to max drive location for maxdr=yes
- MAXC EQU 3BH ; Set to # of names per line location
- MXZUSR EQU 15 ; Maximum user # allowed whlusr=yes/wheel set
- WHLUSR EQU YES ; Yes to allow search 0-mxzusr if wheel set
- ;
- WHLA EQU NO ; Yes to disallow a option if wheel zero
- WHLC EQU NO ; Yes to disallow c option if wheel zero
- WHLCL EQU NO ; Yes to disallow 4,6 or 8 options if wheel = 0
- WHLD EQU NO ; Yes to disallow d option if wheel zero
- WHLF EQU NO ; Yes to disallow f option if wheel zero
- WHLL EQU NO ; Yes to disallow l option if wheel zero
- WHLP EQU NO ; Yes to disallow p option if wheel zero
- WHLR EQU NO ; Yes to disallow r option if wheel zero
- WHLS EQU NO ; Yes to disallow s option if wheel zero
- WHLU EQU NO ; Yes to disallow u option if wheel zero
- ;
- ;
- ; Command line options
- ;
- AOPT EQU YES ; Yes to allow searching all user areas
- COPT EQU YES ; Yes to allow clear screen
- CLOPT EQU YES ; Yes allows a 40, 64 or 80 column display
- DOPT EQU YES ; Yes to allow searching all drives on-line
- FOPT EQU YES ; Yes to allow file output option
- LOPREV EQU NO ; No to reverse the "L" option and not print
- LOPT EQU YES ; Yes to allow library file member printing
- NOPT EQU YES ; Yes to allow disabling page pause option
- PGPAWS EQU YES ; Yes for pause after each page
- POPT EQU YES ; Yes to allow printer option
- ROPT EQU YES ; Yes to allow reset option
- SOPT EQU YES ; Yes to allow system file option
- UOPT EQU YES ; Yes to allow user number option
- VOPT EQU YES ; Yes to allow version number display
- ;
- ;===========================================================================
- ; Console video equates
- ;
- REVIDEO EQU NO ; Use reverse video sequences
- ; If no, the rest of the equates are disabled
- LEADIN EQU ESC ; Escape lead-in (try a null if not required)
- INTOREV EQU 'B' ; Toggle background (enter your value here)
- OUTAREV EQU 'C' ; Toggle foreground (enter your value here)
- ;
- ; the following equate allows computers like the kaypro with a 3-byte
- ; video sequence to be specified.
- ;
- THREBYT EQU NO ; Yes, a 3-byte video sequence is needed
- ;
- IF THREBYT
- TBYTE EQU '0' ; Third byte if THREBYT is YES
- ENDIF
- ;
- VECTOR EQU NO ; Yes to display attributes on flashwriter ii
- VIDEO EQU 0E009H ; Entry to flashwriter video driver prom
- ;==========================================================================
- ;
- ; Hardware equates
- ;
- IF NOT (ZCPR2 AND MAXCL)
- NPL EQU 4 ; # of names per line max values are:
- ; 2 for 40 x xx, 3 for 64 x 16, & 4 for 80 x 24
- ENDIF
- ;
- LPS EQU 24 ; # of lines per screen max values are:
- ; ? for 40 x xx, 16 for 64 x 16, 24 for 80x24
- LPS1 EQU 16 ; # of lines per screen if names per line = 3
- LPS2 EQU 16 ; # of lines per screen if names per line < 3
- FENCEC EQU ':' ; Use 00h for none
- ;
- ;
- ; Miscellaneous equates
- ;
- KTHREE EQU YES ; Yes limits file size columns to 3 digits to
- ; Gain an additional print colomn. allows
- ; Fence to be used with four files per line.
- PRDI EQU NO ; Yes to print drive # on each line
- PRUS EQU NO ; Yes to print user # on each line
- PRLIBD EQU NO ; If yes and prus & prdi are yes then drive and
- ; User numbers will be displayed on library
- ; Listing lines
- PRBRDR EQU YES ; Yes to print a quasi-border for library files
- DORST EQU YES ; Yes to always reset disks when d option active
- DUOPT EQU YES ; Yes, allow drive/user spec zcpr2 style
- NODISK EQU YES ; Yes if you do not want to specify disk drive
- ; When asking for options and using default drv
- REPERR EQU YES ; Yes to report command line option errors
- REPUSR EQU YES ; Yes to report user numbers
- VCODE EQU YES ; Yes if files are to be alphabetized vertically
- ;
- ;
- IF (MAXUR OR MAXDR OR MAXCL) AND NOT ZCPR2
- ++++ MAXUR, MAXDR, MAXCL CANNOT BE YES UNLESS ZCPR2 IS YES
- ENDIF
- ;
- ;
- ; BDOS equates
- ;
- RDCHR EQU 1 ; Read char from console
- WRCHR EQU 2 ; Write char to console
- PRINTS EQU 9 ; Print string
- CONST EQU 11 ; Check cons stat
- CPMVER EQU 12 ; Return cp/m version
- RESET EQU 13 ; Reset disk system
- SELDSK EQU 14 ; Select disk
- OPEN EQU 15 ; 0ffh=not found
- CLOSE EQU 16 ; " "
- SEARCH EQU 17 ; " "
- NEXT EQU 18 ; " "
- READ EQU 20 ; Not 0 = eof
- WRITE EQU 21 ; Not 0 = disk full
- MAKE EQU 22 ; 0ffh = directory full
- CURDSK EQU 25 ; Get currently logged disk name
- SETDMA EQU 26 ; Set current dma
- GALLOC EQU 27 ; Get address of allocation vector
- CURDPB EQU 31 ; Get current disk parameters
- CURUSR EQU 32 ; Get currently logged user number (2.x only)
- ;
- ZRDVER EQU 48 ; Return ZRDOS version
- SETWBT EQU 50 ; Set warm boot trap (ZRDOS)
- RESWBT EQU 52 ; Reset warm boot trap (ZRDOS)
- ;
- BASE EQU 0 ; Default to 0 (or 100h with mac +r option)
- TPA EQU 100H
- FCB EQU BASE+5CH
- BDOS EQU BASE+5
- ;
- ;
- ORG TPA
- ;
- ;
- ;***********************************************************************
- ;
- ; BEGIN EXECUTABLE PROGRAM CODE *
- ;
- ;***********************************************************************
- ;
- ;
- JMP START
- ;
- ;
- MLEADIN:DB LEADIN ; Leadin char for highlight sequences
- MINTOREV: DB INTOREV ; Code to enter highlight mode
- MOUTAREV: DB OUTAREV ; Code to return to normal mode
- ;
- IF NOT MAXCL
- MNPL: DB NPL ; Names per line (# of columns)
- MLPS: DB LPS ; Lines per screen (between pauses)
- ENDIF ; Not maxcl
- ;
- IF MAXCL
- MNPL: DB 0
- MLPS: DB 0
- ENDIF ; Maxcl
- ;
- FENC: DB FENCEC ; Fence character
- ;
- IF COPT
- DB 'CL SCR CODE->' ; For easy patching via du/ddt
- CLCHR: DB 1AH ; Enter your clear screen code(s) here
- DB '$' ; End with a '$'
- DB 0,0,0,0,0,0 ; Allow further space for custom version
- ENDIF ; Copt
- ;
- ;
- VERNAME:DB CR,LF,'SD',MAIN+'0'
- DB VER/10+'0',VER MOD 10+'0',' - '
- DB MONTH/10+'0',MONTH MOD 10+'0','/'
- DB DAY/10+'0',DAY MOD 10+'0','/'
- DB YEAR/10+'0',YEAR MOD 10+'0'
- DB 0
- ;
- ;
- ; Drive code/user area lookup table
- ;
- ; Note that the LODRV-HIDRV table is included here fully configured.
- ; For your own use, you should change the maximum user areas as appro-
- ; priate for each drive on your system. Note that there are only 32
- ; user areas available under CP/M 2, so the highest legal user area you
- ; can specify is 31 (range 0-31 = 32 areas). The program will convert
- ; anything over 31 into mod 31. The default table below is set for the
- ; usual 16 user areas rather than the full 32 available.
- ;
- DB 'MAXUSR TBL>' ; Label to make finding the table easier
- ;
- LODRV EQU $ ; Mark beginning of drive/user table
- ;
- DB 15 ; Maximum user area for drive a
- DB 15 ; " " " " " b
- DB 15 ; " " " " " c
- DB 15 ; " " " " " d
- DB 15 ; " " " " " e
- DB 15 ; " " " " " f
- DB 15 ; " " " " " g
- DB 15 ; " " " " " h
- DB 15 ; " " " " " i
- DB 15 ; " " " " " j
- DB 15 ; " " " " " k
- DB 15 ; " " " " " l
- DB 15 ; " " " " " m
- DB 15 ; " " " " " n
- DB 15 ; " " " " " o
- DB 15 ; " " " " " p
- ;
- HIDRV EQU $ ; Mark end of drive/user table
- ;
- START: LXI H,0
- DAD SP ; Hl=old stack
- SHLD STACK ; Save it
- LXI SP,STACK ; Get new stack
- ;
- ;
- ; Initialize reverse video code in message area
- ;
- IF REVIDEO
- LHLD MLEADIN
- SHLD REVMS1
- SHLD REVMS2
- SHLD REVMS3
- LDA MOUTAREV
- STA REVMS3+1
- ENDIF ; Revideo
- ;
- ;
- ; Zero out the entire initialization data area
- ;
- LXI H,DATA0 ; Point to beginning of init. data area
- PUSH H ; Save for non-zero filling later
- MVI C,DATA1-DATA0 ; Get length of data area
- XRA A ; Zero accumulator
- ;
- ZFILL: MOV M,A
- INX H
- DCR C
- JNZ ZFILL
- ;
- ;
- ; Now copy non-zero initialization data from the template area
- ;
- POP H ; Reset hl to data0
- LXI D,TMPLT0 ; Set de to beginning of template
- MVI C,TMPLT1-TMPLT0 ; Get length of template area
- ;
- NZFILL: LDAX D ; Get template byte
- MOV M,A ; Move to data area
- INX D
- INX H
- DCR C
- JNZ NZFILL
-
- MVI C,ZRDVER ; Get zrdos version
- CALL BDOS
- MOV A,L
- STA ZRDFLG ; Save it
-
- MVI C,CPMVER ; Get and save the cp/m version #
- CALL BDOS
- MOV A,L
- STA VERFLG
- CPI 20H ; Set carry if cp/m 1.4
- MVI E,0FFH ; Get current user number if using cp/m 2
- MVI C,CURUSR ; Fall through with a=0 if not
- CNC CPM
- STA OLDUSR ; Initialize startup user number
- STA NEWUSR ; And make new user match it
- ;
- IF DOPT ; Save extra copy for multi-disk
- STA BASUSR ; Directories
- ENDIF ; Dopt
- ;
- IF TIMEON
- CALL TIME
- ENDIF ; Timeon
- ;
- IF DUOPT ; Drive/user option?
- LXI H,81H ; Point to command line
- MOV A,M
- INX H
- ORA A
- JNZ CLOK
- MOV M,A
- ;
- CLOK: LXI D,FCB
- CALL FNAME
- MOV A,B
- CPI 0FFH
- JZ CLUS
- STAX D
- ;
- CLUS: MOV A,C
- CPI 0FFH
- JZ CLNON
- STA NEWUSR
- ENDIF ; Duopt
- ;
- IF DOPT AND DUOPT
- STA BASUSR
- ENDIF ; Dopt and duopt
- ;
- CLNON: MVI C,CURDSK
- CALL CPM ; Get current disk nr
- STA OLDDSK ; Save for reset if needed
- ;
- IF FOPT
- INR A
- STA OUTFCB ; Set directory output file drive
- ENDIF ; Fopt
- ;
- LXI H,FCB
- MOV A,M ; Get drive name for directory search
- ORA A ; Any specified?
- JNZ STRT1A ; Yes skip next routine
- LDA OLDDSK ; Otherwise, get default disk
- INR A
- JMP START2
- ;
- STRT1A: PUSH PSW
- MVI A,1
- STA DFLAG
- POP PSW
- ;
- START2: MOV M,A ; Put the absolute drive code in
- ; Directory fcb
- ;
- ;
- ; If at least one option is allowed, scan the command line for the
- ; option field delimiter. The option field delimiter is considered
- ; valid only if it is preceded by at least 1 space (otherwise, it
- ; may be part of the directory filename). Any unrecognized options
- ; or illegal user numbers will be flagged or ignored (see REPERR).
- ; (We scan the command line buffer rather than the 2nd default FCB
- ; because all 8 options plus a 2 digit user number won't fit in
- ; the FCB name field).
- ;
- LXI H,80H ; Set command line buffer pointer
- MOV B,M ; Get length of command line buffer
- ;
- ;
- ; Search for valid command line delimiter. If not found, assume no op-
- ; tions.
- ;
- SCNDOL: INX H
- DCR B
- JM CKREST ; Exit if command line buffer empty
- MOV A,M
- CPI '$'
- JNZ SCNDOL
- DCX H ; '$' found - make sure a space precedes
- MOV A,M
- INX H
- CPI ' '
- JNZ SCNDOL ; No space - ignore "$" and search again
- ;
- ;
- ; Valid delimiter found. Scan the rest of the buffer for options.
- ; Errors past this point will cause an abort if the command line error
- ; option is enabled. Otherwise, the dud option will be ignored and SD
- ; will attempt to continue stumbling through the rest of the field.
- ;
- XCHG ; Get option field pointer to de
- ;
- SCNOPT: INX D ; Bump to next option field character
- DCR B ; Dock characters left in option field
- JM CKREST ; If option field exhausted, exit
- ;
- SCNAGN: LDAX D ; Get the next option character
- CPI ' ' ; Do we have a space?
- JZ SCNOPT ; Ignore it if so
- ;
- IF HELP
- CPI '?' ; User wants help menu
- JZ HELPME ; Show option menu and exit
- ENDIF ; Help
- ;
- IF ZCPR2 AND WHLU
- CPI 'U' ; Disallowing "U" option, treat
- JZ CLERR ; As error if there..
- ENDIF ; Zcpr2 and whlu
- ;
- LXI H,OTBL-1 ; Get base of option lookup table
- MVI C,OEND-OTBL+1 ; Get length of option lookup table
- ;
- NOMACH: INX H ; Bump to next option table character
- DCR C ; Are we out of the table?
- JZ CK4USR ; If so, check for user option
- ;
- IF ZCPR2 ; Nzcpr/zcpr2? (wheel byte?)
- PUSH PSW ; Save accum.
- LDA WHEEL ; Get wheel byte
- ORA A ; Check it
- JZ NOMAC1 ; It's zero, so forget it
- MOV A,M ; Get the table option
- CPI '4' ; If 4 then skip lc con
- JZ UCBP
- CPI '6' ; If 6 then skip lc con
- JZ UCBP
- CPI '8' ; If 8 then skip lc con
- JZ UCBP
- ANI 0DFH ; Make sure is upper case
- ;
- UCBP: MOV M,A ; Stuff back in table
- ;
- NOMAC1: POP PSW ; Restore accum.
- ENDIF ; Zcpr2
- ;
- CMP M ; Compare our character with option table
- JNZ NOMACH ; Exit if no match
- MVI M,0 ; Otherwise, activate the flag
- CPI 'D' ; All disk search?
- CZ NOMAC2 ; Yes, start at a always
- CPI 'A' ; All user search?
- CZ NOMAC4 ; Yes, start at user no. 0 always
- JMP SCNOPT ; And go get the next option character
- ;
- NOMAC2: PUSH PSW
- PUSH H
- LDA DFLAG
- ORA A
- JNZ NOMAC3
- LXI H,FCB ; Set fcb drive byte to drive a
- MVI A,1
- MOV M,A
- POP H
- POP PSW
- RET
- ;...
- ;
- ;
- NOMAC3: POP H
- POP PSW
- RET
- ;...
- ;
- ;
- NOMAC4: LDA AFLAG ; Asking for $u3a or $u4a, etc.?
- ORA A
- RNZ
- MVI A,0 ; Always start at user #0
- STA NEWUSR
- STA BASUSR
- RET
- ;.....
- ;
- ;
- ; If option character doesn't match the table, see if we have a User
- ; option.
- ;
- CK4USR: IF UOPT ; Check for user number option
- CPI 'U'
- JNZ CLERR ; Last option, so bad deal if not it
- ;
- UAGN: INX D ; Bump to user number digit
- DCR B
- JM CLERR ; Error if nothing left
- LDAX D ; Get decimal digit
- CPI ' ' ; Ignore leading spaces
- JZ UAGN
- SUI 30H ; Subtract ascii bias
- JC CLERR ; Error if < 0
- CPI 10
- JNC CLERR ; Error if > 9
- STA NEWUSR ; Save user number, might be only 1 digit
- ENDIF ; Uopt
- ;
- IF DOPT AND UOPT
- STA BASUSR ; Duplicate it if multi-disk mode
- ENDIF ; Dopt and uopt
- ;
- IF UOPT
- MVI A,1
- STA AFLAG ; To allow $u3a, etc.
- INX D ; Bump to possible 2nd digit of user #
- DCR B
- JM CKREST ; No more buffer, exit with user #
- LDAX D ; Else, check for another digit
- SUI 30H
- JC SCNAGN ; If next char not numeric, it is not
- CPI 10 ; Part of user number so go check for
- JNC SCNAGN ; Another option
- MOV L,A ; Save units digit
- LDA NEWUSR ; Get tens digit
- ADD A ; Multiply by 10
- MOV H,A
- ADD A
- ADD A
- ADD H
- ADD L ; Combine with units digit
- STA NEWUSR ; Save the total user number
- ENDIF ; Uopt
- ;
- IF DOPT AND UOPT
- STA BASUSR ; Duplicate it if multi-disk mode
- ENDIF ; Dopt and uopt
- ;
- IF UOPT
- JMP SCNOPT ; Continue scanning
- ENDIF ; Uopt
- ;
- ;
- ; If command line error option enabled, playback the command line up
- ; to the character that we gagged on and exit. If REPERR is not enabled
- ; then continue as if nothing were amiss to avoid acknowledging that
- ; some options are available.
- ;
- CLERR: IF REPERR
- XRA A
- INX D ; Tag end of command line with terminator
- STAX D
- CALL CRLF
- LXI D,ERRMS2
- CALL PRINT
- LXI D,ERRTAG
- CALL PRINT
- LXI H,81H ; Playback bad cmd line to error point
- ;
- CLELP: MOV A,M
- ORA A
- JZ CLEX
- CALL TYPE
- INX H
- JMP CLELP
- ;
- CLEX: MVI A,'?' ; Tag line with a '?' field
- CALL TYPE
- CALL CRLF ; Space down 1 more line
- JMP EXIT ; And return to cp/m
- ENDIF ; Reperr
- ;
- IF (NOT REPERR)
- JMP SCNOPT ; If not reporting errors, ignore the dud
- ENDIF ; (not reperr)
- ;
- ;
- ; Options input or not specified. If reset option specified, reset
- ; the disk system now. Its important that the reset be done OUTSIDE
- ; the multiple drive loop if the file output option is enabled because
- ; CP/M 1.4 clobbers the DMA buffer on reset.
- ;
- CKREST: IF COPT
- LDA COPFLG
- ORA A
- JNZ CLOPN
- LDA CLCHR
- CPI 0C3H ; Op-code for jmp
- JZ CLCAL
- LXI D,CLCHR ; Get it from down under
- MVI C,PRINTS ; Print just to console
- CALL BDOS
- JMP CLOPN
- ;
- CLCAL: LHLD CLCHR+1
- SHLD CLCALL+1
- ;
- CLCALL: CALL 0 ; To be safe
- ENDIF ; Copt
- ;
- ;Check for command line option for 40,64, or 80 column & store value
- ;
- CLOPN: IF CLOPT ; If clopr inabled then
- LDA CL4FLG ; Load a with 40 col flag
- ORA A ; Test it
- JNZ CLOPN1 ; No then skip to 64 col test
- PUSH PSW ; If so the save a
- MVI A,2 ; 2 names per line for 40 column
- ENDIF ; Clopt
- ;
- IF MAXCL AND CLOPT ; If storing value in external location
- STA MAXC ; Do it
- ENDIF ; Maxcl and clopt
- ;
- IF NOT MAXCL AND CLOPT ; If storing value internal to sd
- STA MNPL ; Do it
- ENDIF ; Not maxcl and clopt
- ;
- IF CLOPT
- MVI A,LPS2 ;
- STA MLPS ;
- POP PSW ; Get it back a
- ;
- CLOPN1: LDA CL6FLG ; Load a with 64 col flag
- ORA A ; Test it
- JNZ CLOPN2 ; No then skip to 80 col test
- PUSH PSW ; If so then save a
- MVI A,3 ; 3 names per line for 64 column
- ENDIF ; Clopt
- ;
- IF MAXCL AND CLOPT ; If storing value in external location
- STA MAXC ; Do it
- ENDIF ; Maxcl and clopt
- ;
- IF NOT MAXCL AND CLOPT ; If storing value internal to sd
- STA MNPL ; Do it
- ENDIF ; Not maxcl and clopt
- ;
- IF CLOPT
- MVI A,LPS1 ;
- STA MLPS ;
- POP PSW ; Get back where you belong
- ;
- CLOPN2: LDA CL8FLG ; Load a with 80 col flag
- ORA A ; Test it
- JNZ ROPTN ; No then exit to test for r option
- PUSH PSW ; If so then save a
- MVI A,4 ; 4 names per line for 80 column
- ENDIF ; Clopt
- ;
- IF MAXCL AND CLOPT ; If storing value in external location
- STA MAXC ; Do it
- ENDIF ; Maxcl and clopt
- ;
- IF NOT MAXCL AND CLOPT ; If storing value internal to sd
- STA MNPL ; Do it
- ENDIF ; Not maxcl and clopt
- ;
- IF CLOPT
- MVI A,LPS
- STA MLPS
- POP PSW ; Get it back
- ENDIF ; Clopt
- ;
- ROPTN: IF ROPT
- LDA ROPFLG ; If reset flag set, reset disk system
- ORA A ; Before starting to update allocation
- MVI C,RESET ; Vetors
- CZ CPM
- ENDIF ; Ropt
- ;
- IF DOPT
- LDA DOPFLG ; If multi-disk flag set,
- ORA A ; Need to set error traps
- CZ SWAPEM ; Swap bdos error vector tables
- ENDIF ; Dopt
- ;
- IF DORST AND DOPT
- LDA DOPFLG
- ORA A
- CZ DSET ; Reset disk system if $d only
- ENDIF ; Dorst and dopt
- ;
- ;
- ; Set MNPL and MLPS values if MAXCL
- ;
- IF MAXCL
- LDA MAXC ; Load a reg with value @ maxc
- STA MNPL ; Punch a into mnpl
- ;
- MVI A,LPS ; Load a reg with lps
- STA MLPS ; Assume 4 names across
- LDA MAXC ; Get val @ maxc
- CPI 3 ; 3 columns across?
- JNZ LPCL1 ; If not then jmp to lpcl1
- MVI A,LPS1 ; Load a reg with mnpl for col = 3
- STA MLPS ; Punch it into mpls
- ;
- LPCL1: LDA MAXC ; Get maxc val again
- CPI 2 ; 2 columns across?
- JZ LPCL2 ; If so then jmp to lpcl2 and set mnpl
- CPI 1 ; Not 2 across, how about 1?
- JNZ LPSE ; If not then jmp to exit
- ;
- LPCL2: MVI A,LPS2 ; It was 1 or 2 so set mnpl with lps2
- STA MLPS
- ;
- LPSE: ENDIF ; Maxcl
- ;
- ;
- ; Validate drive code and user area numbers from the drive table.
- ;
- NOOPT: LXI D,DRUMSG ; Get the drive/user error message
- PUSH D
- LDA FCB ; Get directory drive code
- DCR A ; Normalize to range of 0-31
- CPI HIDRV-LODRV ; Compare with maximum drives on-line
- JNC ERXIT ; Take drive error exit if out of range
- ;
- IF MAXDR ; Look for maxd
- LXI H,MAXD ; Adddress to hl
- MOV L,M ; Maxd to l
- INX H ; Add one
- CMP L ; Check it
- JNC ERXIT ; Oops if not bigger
- ENDIF ; Maxdr
- ;
- MOV E,A ; Use drive code as index into table
- MVI D,0
- ;
- IF ZCPR2 AND WHLUSR
- LDA WHEEL ; Get wheel byte
- ORA A ; Check it
- JZ USRCK ; If reset, restrict user
- MVI A,MXZUSR ; If set, max user = mxzusr
- JMP USRCK2
- ENDIF ; Zcpr2 and whlusr
- ;
- USRCK: LXI H,LODRV ; Point to base of drive/user table
- DAD D
- MOV A,M ; Get the maximum user # for this drive
- ;
- IF MAXUR ; Use lomem values if smaller
- MOV H,A ; Current value of maxusr
- LDA MAXU ; Alternate value
- SBI 1 ; Maxusr was really max user + 1
- CMP H ; Compare the two
- JNC USRCK2 ; Jmp if table value smaller or equal
- STA MAXUSR ; Else replace it
- ENDIF ; Maxur
- ;
- USRCK2: MOV B,A ; Save the maxuser for later testing (9.2)
- ANI 1FH ; Make sure its in range 0 - 31
- STA MAXUSR ; Save it for later
- LXI H,NEWUSR ; Point to the directory user area
- CMP M ; Compare it with the maximum
- JC ERXIT ; Take error exit if user number illegal
- POP D ; Destroy error message pointer
-
- MOV A,B ; Check to see if this drive (9.2)
- ORA A ; Has been mapped out (9.2)
- JM NDSK ; If so then skip this drive (9.2)
-
- LXI H,FCB+1 ; Point to name
- MOV A,M ; Any specified?
- ;
- IF NODISK
- CPI '$'
- JZ WCD
- ENDIF ; Nodisk
- ;
- CPI ' '
- JNZ GOTFCB
- ;
- ;
- ; No FCB - make FCB all '?'
- ;
- WCD: MVI B,11 ; Fn+ft count
- ;
- QLOOP: MVI M,'?' ; Store '?' in fcb
- INX H
- DCR B
- JNZ QLOOP
- ;
- GOTFCB: MVI A,'?' ; Force wild extent
- STA FCB+12
- CALL SETSRC ; Set dma for bdos media change check
- LXI H,FCB ; Point to fcb drive code for directory
- MOV E,M ; Get the drive code out of the fcb
- DCR E ; Normalize drive code for select
- MVI C,SELDSK ; Select the directory drive to retrieve
- CALL CPM ; The proper allocation vector
- CALL CKVER ; Check version
- JC V14 ; Pre-2.x...get params the 1.4 way
- MVI C,CURDPB ; It is 2.x or mp/m...request dpb
- CALL BDOS
- INX H
- INX H
- MOV A,M ; Get block shift
- STA BLKSHF
- INX H ; Bump to block mask
- MOV A,M
- STA BLKMSK ; Get it
- INX H
- INX H
- MOV E,M ; Get max block #
- INX H
- MOV D,M
- XCHG
- SHLD BLKMAX ; Save it
- XCHG
- INX H
- MOV E,M ; Get directory size
- INX H
- MOV D,M
- XCHG
- JMP FREE ; Let free save it and setup order table
- ;
- V14: LHLD BDOS+1 ; Get params 1.4 style
- MVI L,3BH ; Point to directory size
- MOV E,M ; Get it
- MVI D,0 ; Force high order to 0
- PUSH D ; Save for later
- INX H ; Point to block shift
- MOV A,M ; Fetch
- STA BLKSHF ; Save
- INX H ; Point to block mask
- MOV A,M ; Fetch it
- STA BLKMSK ; And save it
- INX H
- MOV E,M ; Get max. block no.
- MVI D,0
- XCHG
- SHLD BLKMAX ; Save it
- POP H ; Restore directory size
- JMP FREE20 ; Go figure free space from alloc vector
- ;
- ;
- ; Calculate # of K free on selected drive now so that the FREE figure
- ; will not reflect either the creation or additions to the SD.DIR file
- ; (which we would probably erase or move anyway).
- ;
- FREE: SHLD DIRMAX ; Save max # of entries in directory
- LDA VERFLG ; Check version #
- CPI 30H ; 3.0?
- JC FREE20 ; Use old method if not
- LDA FCB ; Get drive #
- DCR A
- MOV E,A ; Use new compute free space bdos call
- MVI C,46
- CALL CPM
- MVI C,3 ; Answer is a 24-bit integer
- ;
- FRE3L1: LXI H,BASE+82H ; Answer is in 1st 3 bytes of dma adr
- MVI B,3 ; Convert it from sectors to k
- ORA A ; By dividing by 8
- ;
- FRE3L2: MOV A,M
- RAR
- MOV M,A
- DCX H
- DCR B
- JNZ FRE3L2 ; Loop for 3 bytes
- DCR C
- JNZ FRE3L1 ; Shift 3 times
- LHLD BASE+80H ; Now get result in k
- JMP SAVFRE ; Go store it
- ;
- FREE20: MVI C,GALLOC ; Get address of allocation vector
- CALL BDOS
- XCHG
- LHLD BLKMAX ; Get its length
- INX H
- LXI B,0 ; Init block count to 0
- ;
- GSPBYT: PUSH D ; Save alloc address
- LDAX D
- MVI E,8 ; Set to process 8 blocks
- ;
- GSPLUP: RAL ; Test bit
- JC NOTFRE
- INX B
- ;
- NOTFRE: MOV D,A ; Save bits
- DCX H ; Count down blocks
- MOV A,L
- ORA H
- JZ ENDALC ; Quit if out of blocks
- MOV A,D ; Restore bits
- DCR E ; Count down 8 bits
- JNZ GSPLUP ; Do another bit
- POP D ; Bump to next byte..
- INX D ; Of alloc. vector
- JMP GSPBYT ; Process it
- ;
- ENDALC: POP D ; Clear allocation vector pntr from stack
- MOV L,C ; Copy blocks to hl
- MOV H,B
- LDA BLKSHF ; Get block shift factor
- SUI 3 ; Convert from sectors to k
- JZ SAVFRE ; Skip shifts if 1k blocks ret free in hl
- ;
- FREKLP: DAD H ; Multiply blocks by k/blk
- DCR A
- JNZ FREKLP
- ;
- SAVFRE: SHLD FREEBY ; Save the free space for output later
- ;
- ;
- ; Reenter here on subsequent passes while in the all-users mode
- ;
- SETTBL: LHLD DIRMAX ; Get directory maximum again
- INX H ; Directory size is dirmax+1
- DAD H ; Double directory size
- LXI D,ORDER ; To get size of order table
- DAD D ; Allocate order table
- SHLD TBLOC ; Name tbl begins where order tbl ends
- SHLD NEXTT
- XCHG
- LHLD BDOS+1 ; Make sure we have room to continue
- MOV A,E
- SUB L
- MOV A,D
- SBB H
- JNC OUTMEM
- ;
- IF UOPT
- CALL CKVER ; Set carry if pre-cp/m 2
- LDA NEWUSR ; Get user area for directory
- MOV E,A
- MVI C,CURUSR ; Get the user function
- CNC CPM ; And set new user number if cp/m 2
- ENDIF ; Uopt
- ;
- ;
- ; Look up the FCB in the directory
- ;
- MVI A,'?'
- LXI H,FCB+12
- MOV M,A ; Match all extents
- INX H
- MOV M,A ; Match all s1 bytes
- INX H
- MOV M,A ; Match all s2 bytes
- LXI H,0
- SHLD COUNT ; Initialize match counter
- SHLD TOTFIL ; " total file counter
- SHLD TOTSIZ ; " total size counter
- CALL SETSRC ; Set dma for directory search
- MVI C,SEARCH ; Get 'search first' function
- JMP LOOK ; And go search for 1st match
- ;
- ;
- ; Read more directory entries
- ;
- MORDIR: MVI C,NEXT ; Search next
- ;
- LOOK: LXI D,FCB
- CALL CPM ; Read directory entry
- INR A ; Check for end (0ffh)
- JZ SPRINT ; If no more, sort & print what we have
- ;
- ;
- ; Point to directory entry
- ;
- SOME: DCR A ; Undo prev 'inr a'
- ANI 3 ; Make modulus 4
- ADD A ; Multiply
- ADD A ; By 32 because
- ADD A ; Each directory
- ADD A ; Entry is 32
- ADD A ; Bytes long
- LXI H,BASE+81H ; Point to buffer (skip to fn/ft)
- ADD L ; Point to entry
- ADI 9 ; Point to sys byte
- MOV L,A ; Save (can't carry to h)
- ;
- IF SOPT
- LDA SOPFLG ; Did user request sys files?
- ORA A
- JZ SYSFOK
- ENDIF ; Sopt
- ;
- MOV A,M ; Get system byte
- ORA A ; Check bit 7
- JM MORDIR ; Skip that file
- ;
- SYSFOK: MOV A,L ; Go back now
- SUI 10 ; Back to user number (alloc flag)
- MOV L,A ; Hl points to entry now
- LDA NEWUSR ; Get current user
- CMP M
- JNZ MORDIR ; Ignore if different
- INX H
- ;
- ;
- ; Move entry to table
- ;
- XCHG ; Entry to de
- LHLD NEXTT ; Next table entry to hl
- MVI B,11 ; Entry length (name, type, extent)
- ;
- TMOVE: LDAX D ; Get entry character
- ;
- IF NOT (VECTOR OR REVIDEO)
- ANI 7FH ; Remove attributes
- ENDIF ; Not (vector or revideo)
- ;
- MOV M,A ; Store in table
- INX D
- INX H
- DCR B ; More?
- JNZ TMOVE
- INX D ; De->> s1
- INX D ; De->> s2
- LDAX D ; Get s2 byte, overflow=int(extents/32)
- PUSH H ; Save hl
- MOV L,A ; Set up 16-bit multiply
- MVI H,0
- MVI B,5
- CALL SHLL ; Hl is now # of overflow extents
- DCX D ; De->> s1
- DCX D ; De->> extent
- LDAX D ; Get extent
- ADD L
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A ; Hl now has total extents
- MVI B,7
- CALL SHLL ; Hl now has total sectors less last ext
- INX D ; De->> s1
- INX D ; De->> s2
- INX D ; Point to sector count
- LDAX D ; Get it
- ADD L
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A ; Hl now has total sectors
- XTHL ; Do some fancy shuffling
- XCHG
- XTHL
- XCHG
- MOV M,D
- INX H
- MOV M,E
- POP D ; All back to normal...
- INX H
- SHLD NEXTT ; Save updated table address
- XCHG
- LHLD COUNT ; Bump the # of matches made
- INX H
- SHLD COUNT
- LXI H,13 ; Size of next entry
- DAD D
- XCHG ; Future nextt is in de
- LHLD BDOS+1 ; Pick up tpa end
- MOV A,E
- SUB L ; Compare nextt-tpa end
- MOV A,D
- SBB H
- JC MORDIR ; If tpa end > nextt, loop back for more
- ;
- OUTMEM: CALL ERXIT ; Exit if directory too large
- DB 'Memory',0
- ;
- ;
- ; Shift HL left by B bits
- ;
- SHLL: DAD H
- DCR B
- RZ
- JMP SHLL
- ;
- ;
- ; Sort and print
- ;
- SPRINT: IF AOPT OR FOPT OR UOPT
- CALL SETFOP ; Return to file output dma & user #
- ENDIF ; Aopt or fopt or uopt
- ;
- LHLD COUNT ; Get file name count
- MOV A,L
- ORA H ; Any found?
- JZ PRTOTL ; Exit if no files found
- PUSH H ; Save file count
- STA SUPSPC ; Enable leading zero suppression
- ;
- ;
- ; Initialize the order table
- ;
- LHLD TBLOC ; Get start of name table
- XCHG ; Into de
- LXI H,ORDER ; Point to order table
- LXI B,13 ; Entry length
- ;
- BLDORD: MOV M,E ; Save low order address
- INX H
- MOV M,D ; Save high order address
- INX H
- XCHG ; Table addr to hl
- DAD B ; Point to next entry
- XCHG
- XTHL ; Save tbl addr, fetch loop counter
- DCX H ; Count down loop
- MOV A,L
- ORA H ; More?
- XTHL ; (restore tbl addr, save counter)
- JNZ BLDORD ; Yes, go do another one
- POP H ; Clean loop counter off stack
- LHLD COUNT ; Get count
- SHLD SCOUNT ; Save as # to sort
- DCX H ; Only 1 entry?
- MOV A,L
- ORA H
- JZ DONE ; Yes, so skip sort
- ;
- ;
- ; This sort routine is adapted from SOFTWARE TOOLS by Kernigan and
- ; Plaugher.
- ;
- SORT: LHLD SCOUNT ; Number of entries
- ;
- L0: ORA A ; Clear carry
- MOV A,H ; Gap=gap/2
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
- ORA H ; Is it zero?
- JZ DONE ; Then none left
- MOV A,L ; Make gap odd
- ORI 1
- MOV L,A
- SHLD GAP
- INX H ; I=gap+1
- ;
- L2: SHLD I
- XCHG
- LHLD GAP
- MOV A,E ; J=i-gap
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- ;
- L3: SHLD J
- XCHG
- LHLD GAP ; Jg=j+gap
- DAD D
- SHLD JG
- MVI A,13 ; Compare 13 chars {sfk}
- CALL COMPARE ; Compare (j) and (jg)
- JP L5 ; If a(j)<=a(jg)
- LHLD J
- XCHG
- LHLD JG
- CALL SWAP ; Exchange a(j) and a(jg)
- LHLD J ; J=j-gap
- XCHG
- LHLD GAP
- MOV A,E
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- JM L5 ; If j>0 goto l3
- ORA L ; Check for zero
- JZ L5
- JMP L3
- ;
- L5: LHLD SCOUNT ; For later
- XCHG
- LHLD I ; I=i+1
- INX H
- MOV A,E ; If i<=n goto l2
- SUB L
- MOV A,D
- SBB H
- JP L2
- LHLD GAP
- JMP L0
- ;
- ;
- ; Sort is all done - print entries
- ;
- DONE: IF FOPT ; If output option wanted, prepare file
- LDA FOPFLG
- ORA A
- JNZ NOOUT ; If file output, fall through, a=0
- ;
- ;
- ; If all user option enabled, and we're not on the first pass, then the
- ; output file is already open and positioned, so we can skip the open.
- ;
- LXI H,OPNFLG ; Get pointer to output file open flag
- CMP M ; A=0,set z if opnflg=0 also
- JNZ NOOUT ; If opnflg not zero, skip open
- DCR M ; Else, set opnflg for next user #
- ;
- ;
- ; First pass on file append - prepare SD.DIR to receive new or appended
- ; output.
- ;
- LXI D,OUTFCB ; Does output file already exist?
- MVI C,SEARCH
- CALL CPM
- INR A
- JNZ OPENIT ; If it does, then open it for processing
- MVI C,MAKE ; Otherwise, create the output file
- CALL CPM
- INR A
- JNZ NOOUT ; Continue if open successful
- ;
- ;
- ; If make or open fails, declare error
- ;
- OPNERR: CALL ERXIT
- DB 'Open',0
- ;
- WRTERR: CALL ERXIT
- DB 'Write',0
- ;
- ;
- ; Output file already exists - open it and position to the last record
- ; of the last extent.
- ;
- OPENIT: MVI C,OPEN ; Open 1st extent of output file
- CALL CPM
- INR A
- JZ OPNERR ; Bad deal if 1st won't open
- ;
- OPNMOR: LDA OUTFCB+15
- CPI 128
- JC LSTEXT ; If rc<128, this is last extent
- LXI H,OUTFCB+12
- INR M ; Else, bump to next extent
- MVI C,OPEN ; And try to open it
- CALL CPM
- INR A
- JNZ OPNMOR ; Continue opening extents til no more
- DCR M ; Then, reopen preceding extent
- MVI C,OPEN
- CALL CPM
- LDA OUTFCB+15 ; Get rc for the last extent
- ;
- ;
- ; At this point, OUTFCB is opened to the last extent of the file, so
- ; read in the last record in the last extent.
- ;
- LSTEXT: ORA A ; Is this extent empty?
- JZ NOOUT ; If so, then starting a clean slate
- DCR A ; Normalize record count
- STA OUTFCB+32 ; Set record number to read
- MVI C,READ ; And read last record of file
- CALL CPM
- ORA A ; Was read successful?
- JZ RDOK ; If so, proceed to scan for eof mark
- ;
- APERR: CALL ERXIT
- DB 'Append',0
- ;
- ;
- ; We now have the last record in the file in our buffer. Scan the last
- ; record for the EOF mark, indicating where we can start adding data.
- ;
- RDOK: LXI H,OUTBUF ; Point to start of output buffer
- MVI B,128 ; Get length of output buffer
- ;
- SCAN: MOV A,M
- CPI 'Z'-40H ; Have we found end of file?
- JZ RESCR ; If so, save pointers and reset cr
- INX H
- DCR B
- JNZ SCAN ; Otherwise, look until end of buffer
- ;
- ;
- ; If we find an explicit EOF mark in the last buffer (or an implied EOF
- ; if the last record is full), move the FCB record and extent pointers
- ; back to correct for the read operation so that our first write opera-
- ; tion will effectively replace the last record of the SD.DIR file.
- ;
- RESCR: PUSH H ; Save eof buffer pointer
- PUSH B ; Save eof buffer remaining
- LXI H,OUTFCB+32 ; Get current record again
- DCR M ; Dock it
- JP SAMEXT ; If cr >=0, we're still in same extent
- LXI H,OUTFCB+12 ; Else, move to previous extent
- DCR M
- MVI C,OPEN ; Then, reopen the previous extent
- CALL CPM
- INR A
- JZ APERR ; Append position error if can not reopen
- LDA OUTFCB+15 ; Else, position to last record of extent
- DCR A
- STA OUTFCB+32
- ;
- SAMEXT: POP PSW ; Recall where eof is in buffer
- STA BUFCNT ; And set buffer counter
- POP H ; Recall next buffer pointer
- SHLD BUFPNT ; And set pointer for first addition
- ENDIF ; Fopt
- ;
- ; end of IF FOPT routine
- ;-----------------------------------------------------------------------
- ;
- NOOUT: IF VOPT ; If version option, check if first
- LDA FIRSTT ; Time through
- ORA A
- JNZ NOVOPT ; No, we've been here before
- MVI A,0FFH ; Virgin, poke it
- STA FIRSTT
- LDA VOPFLG ; If version display flag set, print it
- ORA A
- JNZ NOVOPT
- LXI D,VERNAME
- CALL PRINT
- CALL CRLF
- ;
- NOVOPT: ENDIF ; Vopt
- ;
- IF LOPT
- LHLD COUNT
- SHLD LCOUNT
- LXI H,0
- SHLD LBTOTL
- SHLD LMTOTL
- LXI H,ORDER ; Initialize order table pointer
- SHLD NEXTL
- ENDIF ; Lopt
- ;
- IF NOT LOPT
- LXI H,ORDER ; Initialize order table pointer
- ENDIF ; Not lopt
- ;
- SHLD NEXTT
- ;
- IF VCODE
- LHLD COUNT ; Code computes end of name
- CALL MULT13 ; Table (or start of second table
- XCHG ; Where files will be stored after
- LHLD TBLOC ; Redundant extents removed.)
- DAD D
- SHLD NEWPTR ; Save it twice
- SHLD XPOINT ; For later
- ENDIF ; Vcode
- ;
- IF NOT VCODE ;
- JMP NEWLIN ; Start new line and output the files
- ENDIF ; Not vcode
- ;
- ;
- ; Output the directory files we've matched.
- ;
- ENTRY: LHLD COUNT
- DCX H ; Dock file count
- SHLD COUNT
- MOV A,H ; Is this the last file?
- ORA L
- JZ OKPRNT ; If count=0, last file so skip compare
- ;
- ;
- ; Compare each entry to make sure that it isn't part of a multiple ex-
- ; tent file. Go only when we have the last extent of the file.
- ;
- PUSH B ; Save npl
- ;
- IF NOT VCODE
- CALL CKABRT ; Check for abort code from keyboard
- ENDIF ; Not vcode
- ;
- LHLD NEXTT
- MVI A,11
- CALL COMPR ; Does this entry match next one?
- POP B ; Recall npl
- JNZ OKPRNT ; No, print it
- INX H
- INX H ; Skip since highest extent last in list
- SHLD NEXTT
- JMP ENTRY ; Loop back for next lowest extent
- ;
- ;
- ; Vcode substitution . If VCODE option chosen, OKPRINT moves unique
- ; filenames and sizes in 'k' to a second table above the first for use
- ; later.
- ;
- OKPRNT: LHLD NEXTT ; Get order table pointer
- MOV E,M ; Get low order address
- INX H
- MOV D,M ; Get high order address
- INX H
- SHLD NEXTT ; Save updated table pointer
- XCHG ; Table entry to hl
- ;
- IF VCODE
- PUSH H ; Save address of byte to be moved
- LHLD NEWPTR ; Get address in new table to put it in
- PUSH H ; Save it
- LXI D,13 ; Update it
- DAD D
- SHLD NEWPTR ; Save for later - will be end of table
- POP H ; Get current move to address
- XCHG ; Put in de
- POP H ; Get current move from address back
- MVI B,11 ; Size of file name, type
- CALL MOVE ; Move it
- PUSH D
- ENDIF ; Vcode
- ;
- IF NOT VCODE
- MVI B,8 ; File name length
- CALL TYPEIT ; Type filename
- MVI A,'.' ; Period after fn
- CALL TYPE
- MVI B,3 ; Display 3 characters of filetype
- CALL TYPEIT
- ENDIF ; Not vcode
- ;
- CALL DOIT
- LHLD TOTSIZ ; De now has rounded size in k
- DAD D ; Add to total used
- SHLD TOTSIZ
- LHLD TOTFIL ; Increment file count
- INX H
- SHLD TOTFIL
- XCHG ; Get back file size
- ;
- IF VCODE
- POP D ; Get back where size is to go
- MOV A,H ; Move size to table two
- STAX D
- INX D
- MOV A,L
- STAX D
- ;
- ;
- ; One file MOVED - test to see if we have to move another one.
- ;
- LHLD COUNT ; Get current file counter and test it
- MOV A,H
- ORA L
- JZ PRTOTL ; If no more files exit to summary output
- JMP ENTRY ; If more, go get them
- ENDIF ; Vcode
- ;
- ;
- ; Output the size of the individual file.
- ;
- IF NOT VCODE
- CALL FDECPRT ; Go print it
- MVI A,'k' ; And follow with k size
- CALL TYPE
- ;
- ;
- ; One file output - test to see if we have to output another one.
- ;
- LHLD COUNT ; Get current file counter and test it
- MOV A,H
- ORA L
- JZ PRTOTL ; If no more files exit to summary output
- ;
- ;
- ; At least one more file to output - can we put it on the current line?
- ;
- DCR C
- PUSH PSW
- CNZ FENCE ; If room left output the fence character
- POP PSW
- JNZ ENTRY ; And go output another file
- ;
- ;
- ; Current line full, start a new one.
- ;
- NEWLIN: LDA MNPL
- MOV C,A ; Reset names per line counter
- CALL CRLF ; Space down to next line
- ENDIF ; Not vcode
- ;
- IF PRDI AND (NOT VCODE)
- LDA FCB ; Precede new line with drive name
- ADI 'A'-1
- CALL TYPE
- ENDIF ; Prdi and (not vcode)
- ;
- IF PRDI AND (NOT VCODE) AND (REPUSR AND PRUS)
- ; If reporting user # and running under
- CALL CKVER ; Cp/m 2, output the user number too
- CNC TYPUSR
- ENDIF ; Prdi and (not vcode) and (repusr and prus)
- ;
- IF PRDI AND (NOT VCODE)
- MVI A,':' ; Tag header with a colon and a space
- CALL FPAD ; And exit back to entry
- ENDIF ; Prdi and (not vcode)
- ;
- IF NOT VCODE
- JMP ENTRY ; Go back and output another file
- ENDIF ; Not vcode
- ;
- ;
- ; Compute the size of the file/library and update our summary datum.
- ; This has been changed into a subroutine so that both the file size
- ; computation and a library size (when printing out library members)
- ; can be computed in K.
- ;
- DOIT: MOV D,M
- INX H
- MOV E,M ; Size in de (sectors)
- LDA BLKMSK
- PUSH PSW
- ADD E
- MOV E,A
- MOV A,D
- ACI 0
- MOV D,A
- POP PSW
- CMA
- ANA E
- MOV E,A
- MVI B,3
- ;
- SHRR: MOV A,D
- ORA A
- RAR
- MOV D,A
- MOV A,E
- RAR
- MOV E,A
- DCR B
- JNZ SHRR
- RET
- ;.....
- ;
- ;
- ; Print HL in decimal with leading zero suppression
- ;
- FDECPRT: IF KTHREE ; Individual file size print
- XRA A ; Clear leading zero flag
- STA LZFLG
- JMP SKTHSD
- ENDIF ; Kthree
- ;
- DECPRT: XRA A ; Clear leading zero flag
- STA LZFLG
- LXI D,-10000
- LDA SUPSPC
- PUSH PSW
- XRA A
- STA SUPSPC
- CALL DIGIT
- POP PSW
- STA SUPSPC
- LXI D,-1000 ; Print 1000's digit
- CALL DIGIT
- ;
- SKTHSD: LXI D,-100 ; Etc.
- CALL DIGIT
- LXI D,-10
- CALL DIGIT
- MVI A,'0' ; Get 1's digit
- ADD L
- JMP TYPE
- ;
- DIGIT: MVI B,'0' ; Start off with ascii 0
- ;
- DIGLP: PUSH H ; Save current remainder
- DAD D ; Subtract
- JNC DIGEX ; Quit on overflow
- POP PSW ; Throw away remainder
- INR B ; Bump digit
- JMP DIGLP ; Loop back
- ;
- DIGEX: POP H ; Restore pointer
- MOV A,B
- CPI '0' ; Zero digit?
- JNZ DIGNZ ; No, type it
- LDA LZFLG ; Leading zero?
- ORA A
- MVI A,'0'
- JNZ TYPE ; Print digit
- LDA SUPSPC ; Get space suppression flag
- ORA A ; See if printing file totals
- RZ ; Yes, don't give leading spaces
- JMP SPACE ; Leading zero...print space
- ;
- DIGNZ: STA LZFLG ; Leading zero flag so next zero prints
- JMP TYPE ; And print digit
- ;.....
- ;
- ;=======================================================================
- ; VCODE subroutines begin here
- ;
- ; Multiply contents of HL register by 13
- ;
- IF VCODE
- MULT13: MOV D,H
- MOV E,L
- DAD H
- DAD D
- DAD H
- DAD H
- DAD D
- RET
- ;.....
- ;
- ;
- ; Main subroutine to print out a filename and column delimiter
- ;
- SUBA: CALL PFILE1 ; Routine to print a filename
- RZ ; If at end of line return with zero set
- ;; CPI 0FFH ; If true past the end of the table;850315
- ;; CNZ FENCE ; Print the column delimiter if more;850315
- CC FENCE ; Print col delimiter if more ;850315
- LHLD JUMPER ; Put the jumper back in de
- XCHG
- ORI 1 ; Insure non zero return ;850315
- RET
-
- ;.....
- ;
- ;
- PFILE1: MOV A,M ; Let's see what we have
- CPI 0FEH
- RNC
- ANI 7FH ; Strip parity bit
- PUSH B ; Save the number of columns
- MVI B,8 ; Print file name and type
- CALL TYPEIT
- MVI A,'.'
- CALL TYPE
- MVI B,3
- CALL TYPEIT
- PUSH H
- CALL CKABRT ; Ctl-c from keyboard?
- POP H
- MOV D,M ; Get it into
- INX H
- MOV E,M
- XCHG ; Hl
- CALL FDECPRT ; And print it out
- MVI A,'k'
- CALL TYPE
- POP B ; Get back number of columns
- LHLD TOTFIL ; Get number of files left
- DCX H ; Reduce it by one
- SHLD TOTFIL ; And resave it
- MOV A,H
- ORA L ; Down to zero yet?
- RZ ; Return if no more files
- DCR C ; Decrement it and
- STC ; Force carry on this return ;850315
- RET
- ENDIF ; Vcode
- ;.....
- ;
- ; end of VCODE routines
- ;=======================================================================
- ;
- ;
- ; Show total space and files used
- ;
- PRTOTL: IF LOPT AND (NOT VCODE)
- LDA LOPFLG
- ORA A
- ENDIF ; Lopt and (not vcode)
- ;
- IF LOPT AND (NOT VCODE) AND LOPREV
- JZ PRTOT1
- ENDIF ; Lopt and (not vcode) and loprev
- ;
- IF LOPT AND (NOT VCODE) AND (NOT LOPREV)
- JNZ PRTOT1
- ENDIF ; Lopt and (not vcode) and (not loprev)
- ;
- IF LOPT AND (NOT VCODE)
- LHLD TOTFIL ; How many files did we match?
- MOV A,H
- ORA L
- CNZ PRTLMEM ; Skip the .lbr check if none found
- ;
- PRTOT1 EQU $
- ENDIF ; Lopt and (not vcode)
- ;
- XRA A ; Get a zero to...
- STA SUPSPC ; Suppress leading spaces in totals
- LHLD TOTFIL ; How many files did we match?
- MOV A,H
- ORA L
- JZ NXTUSR ; Skip the summary if we didn't find any
- PUSH H ; Save totfil
- STA FNDFLG ; Set file found flag
- ;
- IF VCODE ; Leading crlf for vertical output mode
- LDA FIRSTT ; If not first time through
- ORA A
- CNZ CRLF
- ENDIF ; Vcode
- ;
- LXI D,TOTMS1 ; Print [cr,lf] " Drive "
- CALL PRINT
- LDA FCB
- ADI 'A'-1
- CALL TYPE ; Output the drive code
- ;
- IF REPUSR
- CALL CKVER
- JC NOUSER
- CALL TYPUSR ; Output the user number
- ENDIF ; Repusr
- ;
- NOUSER: LXI D,TOTMS6 ; Print " FILES: "
- CALL PRINT
- POP H ; Recall totfil
- CALL DECPRT ; Print number of files matched
- PUSH PSW ; Just in case
- LDA MNPL ; Load a with # of names per line
- CPI 3 ; Is it 3?
- JZ SKDRV ; Yes then skip cr,lf print
- CPI 4 ; Is it 4?
- JZ SKDRV ; Yes then skip cr,lf print
- LXI D,TOTMS3 ; Split drive status line for 40 < display
- CALL PRINT ; Do it
- ;
- SKDRV: POP PSW ; Put it back
- LXI D,TOTMS4 ; No cr,lf needed since display > 40
- CALL PRINT
- LHLD TOTSIZ ; Print total k used by files matched
- CALL DECPRT
- LXI D,TOTMS5 ; Print "K "
- CALL PRINT
- CALL PRTFRE ; Output free space remaining & " FREE."
- ;
- IF NOT VCODE
- CALL CRLF
- ENDIF ; Not vcode
- ;
- ;
- ; Summary line printed, now print the detail files, but first compute
- ; total lines the printout will take.
- ;
- IF VCODE
- NPRNT: PUSH PSW ; Just in case
- LDA MNPL ; Load a with # names per line
- CPI 1 ; Is it 1?
- JNZ MNC1 ; If not test for 2
- LXI D,0-1 ; Minus number of columns
- LXI B,1-1 ; Number of columns minus 1
- ;
- MNC1: CPI 2 ; Wasn't 1, is it 2?
- JNZ MNC2 ; If not then test for 3
- LXI D,0-2 ; Minus number of columns
- LXI B,2-1 ; Number of columns minus 1
- ;
- MNC2: CPI 3 ; Wasn't 2, is it 3?
- JNZ MNC3 ; If not then test for 4
- LXI D,0-3 ; Minus number of columns
- LXI B,3-1 ; Number of columns minus 1
- ;
- MNC3: CPI 4 ; Wasn't 3, is it 4?
- JNZ MNC4 ; If not then fall through
- LXI D,0-4 ; Minus number of columns
- LXI B,4-1 ; Number of columns minus 1
- ;
- MNC4: POP PSW ; Put it back
- LHLD TOTFIL ; Get total number of files
- DAD B ; Round up to a full line
- MVI C,0FFH
- ;
- NPRNT1: INR C ; 'c' will end up holding number
- DAD D ; Of lines to be displayed.
- JC NPRNT1
- MOV A,C
- STA LINES ; Done. save it for later
- STA SUPSPC ; Allow spaces in front of file sizes
- ;
- ;
- ; Number of lines times size of an entry equals the number of bytes to
- ; jump in the second table when outputing files in vertical order.
- ;
- MOV L,A ; Put number of lines into hl
- MVI H,0
- CALL MULT13
- SHLD JUMPER ; Put it away
- ;
- ;
- ; Fill a sector with FF at the end of table 2
- ;
- LHLD NEWPTR ; Now points to end of table 2
- MVI B,128
- MVI A,0FFH
- ;
- NPRNT2: MOV M,A
- INX H
- DCR B
- JNZ NPRNT2
- ;
- ;
- ; Increment the number of files for use later in SUBA. This insures
- ; that a column delimiter will be printed after the last filename, if
- ; the file appears in other than the last column of the display.
- ;
- LXI H,TOTFIL
- INR M
- ;
- ;
- ; Print out a line of files
- ;
- NPRNT3: CALL CRLF ; Start a new line
- PUSH PSW ; Save it just in case
- LDA MNPL ; Load a with # of names per line
- MOV C,A ; Reset number of columns
- POP PSW ; Put it back
- ENDIF ; Vcode
- ;
- IF PRDI AND VCODE
- PUSH B
- LDA FCB ; Show drive letter at beginning of
- ADI 'A'-1 ; Each line
- CALL TYPE
- ENDIF ; Prdi and vcode
- ;
- IF REPUSR AND PRUS AND PRDI AND VCODE ; Also user number, if allowed
- CALL CKVER
- CNC TYPUSR
- ENDIF ; Repusr and prus and prdi and vcode
- ;
- IF PRDI AND VCODE
- MVI A,':'
- CALL FPAD
- POP B
- ENDIF ; Prdi and vcode
- ;
- ;
- ; Print first filename
- ;
- IF VCODE
- LHLD XPOINT ; Xpoint points to start of second table
- CALL SUBA ; At entry. below it is incremented
- ; For additional lines of printout.
- JZ NLINE ; Either out of columns or out of files.
- ;
- ;
- ; Print second filename
- ;
- LHLD XPOINT
- DAD D
- CALL SUBA
- JZ NLINE
- ;
- ;
- ; NOTE: The following conditionals are used only to save some bytes if
- ; running with only two or three columns of files in display.
- ;
- ; Print third filename, if still room on line
- ;
- PUSH PSW ; Just in case
- LDA MNPL ; Load a with # of names per line
- CPI 1 ; Is it 1?
- JZ VCLT2 ; If so then skip name print
- CPI 2 ; Is it 2?
- JZ VCLT2 ; If so then skip name print
- POP PSW ; Put it back where it belongs
- LHLD XPOINT
- DAD D
- DAD D
- CALL SUBA
- JZ NLINE
- JMP VCMT2
- ;
- VCLT2: POP PSW ; Didn't put it back so do it now
- ;
- ;
- ; Print fourth filename
- ;
- VCMT2: PUSH PSW ; Just in case it's loaded bang!
- LDA MNPL ; Load a with # of names per line
- CPI 4 ; Is it 4?
- JNZ VCLT3 ; If not then skip fourth name print
- POP PSW ; Put it back
- LHLD XPOINT
- DAD D
- DAD D
- DAD D
- CALL SUBA
- JMP VCMT3
- ;
- VCLT3: POP PSW ; Didn't put it back yet so do it now
- ;
- VCMT3: DS 0
- ; ; Wasn't 4 so go
- NLINE: LHLD XPOINT ; Increment xpoint to next file
- LXI D,13
- DAD D
- SHLD XPOINT
- LHLD TOTFIL ; Time to see if we're out of files
- MOV A,H
- ORA L
- JZ DOLIB ; Yes we are
- LXI H,LINES ; Nope, just need a new line
- DCR M
- JNZ NPRNT3
- ENDIF ; Vcode
- ;
- DOLIB: IF LOPT AND VCODE
- LDA LOPFLG
- ORA A
- ENDIF ; Lopt and vcode
- ;
- IF LOPREV AND LOPT AND VCODE
- JZ DOLIB1
- ENDIF ; Loprev and lopt and vcode
- ;
- IF NOT LOPREV AND LOPT AND VCODE
- JNZ DOLIB1
- ENDIF ; Not loprev and lopt and vcode
- ;
- IF LOPT AND VCODE
- LHLD TOTFIL ; How many files did we match?
- MOV A,H
- ORA L
- CNZ PRTLMEM ; Skip the library check if none found
- ;
- DOLIB1: ENDIF ; Lopt and vcode
- ;
- ;
- ; Directory for one user area completed. If 'all users' option is se-
- ; lected, then go do another directory on the next user number until we
- ; exceed the maximum user # for the selected drive.
- ;
- NXTUSR: IF AOPT ; If all users option enabled
- LDA AOPFLG ; If not all users mode - skip next
- ORA A
- JNZ GOCLZ
- CALL CKVER ; Are we running cp/m 2?
- JC GOCLZ ; Skip user increment if not
- CALL CKABRT ; Check for user abort first
- LDA MAXUSR ; No abort - get maximum user number
- LXI H,NEWUSR ; Bump directory user number
- INR M
- CMP M ; Does next user # exceed maximum?
- JNC SETTBL ; Continue if more user areas to go
- ENDIF ; Aopt
- ;
- IF DOPT AND AOPT ; If multi-disk option enabled
- LDA BASUSR ; Reset base user number for the
- MOV M,A ; Next directory search
- ENDIF ; Dopt and aopt
- ;
- ;
- ; We've finished all of our outputting. Flush the remainder of the out-
- ; put buffer and close the file before going to exit routine.
- ;
- GOCLZ: IF FOPT
- LXI H,OPNFLG ; Get file open status then reset flag to
- MOV A,M ; Force reopen on next pass
- MVI M,0
- ORA A
- JZ NXTDSK ; Skip closing sd.dir if it wasn't opened
- LXI H,BUFCNT
- MOV A,M ; Retrieve # of unflushed characters in
- MVI M,128 ; Buffer, force bufcnt to empty status
- ORA A ; If bufcnt=128, buffer empty set sign
- JM CLOSE ; Close sd.dir if buffer is empty
- JZ FLUSH ; Write last record to sd.dir if full buf
- LHLD BUFPNT ; Else pad unused buffer with ctl-z
- ;
- PUTAGN: MVI M,'Z'-40H
- INX H
- DCR A
- JNZ PUTAGN ; Keep padding until buffer filled out
- ;
- FLUSH: LXI D,OUTFCB ; Flush the last output buffer
- MVI C,WRITE
- CALL CPM
- ORA A
- JNZ WRTERR
- ;
- CLOZE: LXI D,OUTFCB ; Close the output file
- MVI C,CLOSE
- CALL CPM
- ENDIF ; Fopt
- ;
- ;
- ; Directory for all user areas completed. If the multi-disk option is
- ; enabled and selected, reset to the base user area and repeat the di-
- ; rectory for next drive on-line until we either exceed the drives in
- ; our LODRV-HIDRV table, or the BDOS shuts us down with a select or bad
- ; sector error, which will be intercepted back to the EXIT module.
- ;
- NXTDSK: LXI H,FNDFLG ; Get file found flag
- MOV A,M
- MVI M,0 ; Clear file found flag for next drive
- ORA A
- JNZ NDSK ; Continue if at least 1 file found
- ;
- IF FOPT ; If file output enabled, temp. diasable
- LXI H,FOPFLG
- DCR M
- PUSH H
- ENDIF ; Fopt
- ;
- LXI D,NOFMS1 ; Print first part of no files message
- CALL PRINT ; Print it
- LDA MNPL ; Load a with # of names per line
- CPI 4 ; Is it 4?
- JZ LNOFM ; If so then jump to long message print
- CPI 3 ; Is it 3?
- JZ LNOFM ; If so then jump to long message print
- LXI D,NOFSM ; Isn't 3 or 4 so set up short message
- CALL PRINT ; Print it
- JMP NNOFM ; Skip long message print
- IF MAXCL ; If maxcl then print short message anyway
- LNOFM: LXI D,NOFSM ; Since rcpm's won't want to print the word
- ENDIF ; Maxcl
- ;
- IF NOT MAXCL ; Not maxcl so long message is defined
- LNOFM: LXI D,NOFLM
- ENDIF ; Not maxcl
- ;
- CALL PRINT ; Print message
- ;
- NNOFM: LDA FCB
- ADI 'A'-1
- CALL TYPE ; Output the drive
- ;
- IF REPUSR
- CALL CKVER
- JC NOUSR1
- CALL TYPUSR ; Output the user number
- ENDIF ; Repusr
- ;
- NOUSR1: LXI D,NOFMS2 ; Print divider
- CALL PRINT
- CALL PRTFRE ; Tag with free message
- ;
- IF NOT VCODE
- CALL CRLF ; Need another crlf in horiz. output mode
- ENDIF ; Not vcode
-
- IF FOPT ; Restore original file output mode
- POP H
- INR M
- ENDIF ; Fopt
- ;
- NDSK: IF DOPT ; If multi-disk option enabled
- LDA DOPFLG ; If multi-disk not selected - skip next
- ORA A
- JNZ NPRT
- CALL CKABRT ; Check for user abort first
- MVI A,HIDRV-LODRV ; Get maximum drive code to search
- LXI H,FCB ; Bump directory fcb drive code
- INR M
- CMP M ; Does next disk exceed maximum?
- JC NPRT
- ENDIF ; Dopt
- ;
- IF MAXDR AND DOPT
- LDA MAXD ; Look at another value limit
- INR A
- CMP M ; Is it lower?
- JC NPRT ; Bail out if too low
- JMP NOOPT ; Search next disk
- ENDIF ; Maxdr and dopt
- ;
- IF DOPT
- JNC NOOPT ; Search next disk if maxdr not true
- ENDIF ; Dopt
- ;
- ;
- ; If no printer, fall through to EXIT
- ;
- NPRT: IF POPT ; Check if printer is in use
- LDA POPFLG
- ORA A ; Printer active?
- JNZ EXIT ; No, just exit...
- MVI C,5
- MVI E,CR ; Print a crlf
- CALL CPM
- MVI E,LF ; Line feed
- CALL CPM
- ENDIF ; Popt
- ;
- JMP EXIT ; All done - exit to ccp
- ;.....
- ;
- ;
- ; Print the user number of the directory in decimal
- ;
- TYPUSR: IF REPUSR
- LDA NEWUSR
- CPI 10 ; If user no. < 10, skip tens digit
- JC DUX
- PUSH B
- MVI C,'0'-1
- ;
- DUY: INR C ; Get tens digit
- SUI 10
- JNC DUY ; Loop until we've gone too far
- ADI 10
- MOV B,A ; Save units digit
- MOV A,C ; Print tens digit
- CALL TYPE
- MOV A,B ; Get units back
- POP B
- ;
- DUX: ADI '0'
- JMP TYPE
- ENDIF ; Repusr
- ;
- ;
- ; Force new line on video and check for page pause
- ;
- CRLF: MVI A,CR ; Send cr
- CALL TYPE
- MVI A,LF ; Send lf
- JMP TYPE
- ;.....
- ;
- ;
- ; Separate the directory output on a line with a space, the delimiter,
- ; followed by another space.
- ;
- FENCE: CALL SPACE
- LDA FENC ; Fence character
- ;
- FPAD: CALL TYPE ; Print it, fall into space
- ;
- SPACE: MVI A,' ' ; Fall through to type
- ;
- ;
- ; Output character in A to console, and optionally to printer and/or the
- ; output file.
- ;
- TYPE: PUSH B
- PUSH D
- PUSH H
- PUSH PSW ; Save the character to output
- CALL TYPE1 ; Send it to console
- CALL CKABRT ; Check for user abort request
- POP PSW ; Restore the output character
- ANI 7FH ; Strip parity bit on character
- ;
- ;
- ; Check if reverse video sequence. If so, do not store the
- ; leadin character or entry/exit characters in SD.DIR
- ;
- IF REVIDEO
- CPI LEADIN ; If lead-in for hilite
- JZ NOHLT ; Skip file i/o and printer
- CPI INTOREV ; Reverse start?
- JZ CKREV
- CPI OUTAREV ; Reverse end?
- JNZ TYSKIP ; No, skip
- ;
- CKREV: MOV B,A ; Save character
- LDA HITRAP ; Get previous character
- CPI LEADIN ; Was it a leadin?
- MOV A,B ; Restore char
- JZ NOHLT ; Skip file and printer
- ;
- TYSKIP: STA HITRAP ; Save character for hilite trap
- ENDIF ; Revideo
- ;
- ;
- ; Test file output mode and skip to page pause test if not active.
- ;
- IF FOPT
- MOV B,A ; Save stripped character to b
- LDA FOPFLG ; Is file output active?
- ORA A
- JNZ NOWRIT ; Go check for page pause if not
- ;
- ;
- ; File output mode active - make sure we have room in buffer to add the
- ; next character. If buffer full, write out current record first and
- ; then start a new record with current character.
- ;
- LHLD BUFPNT ; Get current buffer pointer
- LDA BUFCNT ; Get buffer capacity remaining
- ORA A
- JNZ PUTBUF ; Continue if buffer not full
- CALL SETFOP ; Set the dma address
- LXI D,OUTFCB ; Otherwise, write the current buffer out
- MVI C,WRITE
- CALL CPM ; (note call must save character in b)
- ORA A
- JNZ WRTERR ; Write error exit if disk full or r/o
- LXI H,OUTBUF ; Reset buffer pointer
- MVI A,128 ; Reset buffer capacity
- ;
- PUTBUF: MOV M,B ; Shove character to next buffer position
- INX H ; Bump buffer pointer
- SHLD BUFPNT ; And save it
- DCR A ; Dock count of characters left in buffer
- STA BUFCNT ; And save it
- ;
- NOWRIT: MOV A,B ; Recall stripped character
- ENDIF ; Fopt
- ;
- IF POPT ; If printer option
- ANI 7FH ; Strip parity bit on character
- MOV E,A ; Setup list output call
- MVI C,5
- LDA POPFLG ; Test printer flag
- ORA A
- CZ CPM ; Print character if flag true
- MOV A,E ; Recall character
- ENDIF ; Popt
- ;
- IF REVIDEO
- NOHLT: STA HITRAP ; Save character for hilite trap
- ENDIF ; Revideo
- ;
- IF PGPAWS
- CPI LF ; Do we have a lf?
- JNZ TYPRET ; Exit if not
- ENDIF ; Pgpaws
- ;
- IF NOPT AND PGPAWS
- LDA NOPFLG ; Is the page pause function disabled?
- ORA A
- JZ TYPRET ; Exit if so
- ENDIF ; Nopt and pgpaws
- ;
- IF PGPAWS
- LDA LINCNT ; Get line count
- INR A ; Bump it
- LXI H,MLPS
- CMP M ; Are we at the end of the screen?
- JC NOTEOS ; Skip if not
- LXI D,EOSMSG ; Else, display pause message
- MVI C,PRINTS ; Without checking for lfs
- CALL BDOS
- CALL CINPUT ; Wait for character
- CPI 'C'-40H ; Want to abort?
- JZ EXIT1 ; Abort on ctl-c
- LXI D,MORERA ; Wipe the silly '[more]' out
- MVI C,PRINTS
- CALL BDOS
- XRA A ; Reset line count
- ;
- NOTEOS: STA LINCNT ; Save new line count
- ENDIF ; Pbpaws
- ;
- TYPRET: POP H ; Exit from type
- POP D
- POP B
- RET
- ;.....
- ;
- ; Output character
- ;
- TYPE1: IF VECTOR
- ORA A ; Set sign flag if ms bit is on
- JP TYPE2 ; If character is ascii, continue
- MOV B,A ; Else, get character to b
- MVI A,5 ; Video driver function for direct output
- JMP VIDEO ; Display in rev video, exit from video
- ENDIF ; VECTOR
- ;
- TYPE2: IF REVIDEO
- ORA A
- JP TYPE99
- PUSH PSW
- LDA MLEADIN ; Send esc char first
- CALL TYPE99
- LDA MINTOREV
- CALL TYPE99
- ENDIF ; REVIDEO
- ;
- IF THREBYT ; 3-byte video?
- MVI A,TBYTE ; If so, add the third byte
- CALL TYPE99
- ENDIF
- ;
- IF REVIDEO ;
- POP PSW ; Retrieve character
- ANI 7FH
- CALL TYPE99
- LDA MLEADIN ; Send esc first
- CALL TYPE99
- LDA MOUTAREV ; The out of reverse video character
- ENDIF ; REVIDEO
- ;
- IF THREBYT ; 3-byte video?
- CALL TYPE99
- MVI A,TBYTE ; If so, add the third byte
- ENDIF
- ;
- TYPE99: EQU $
- ;
- ;
- IF DIRCON
- MOV C,A ; Get character into bios entry register
- LHLD BASE+1 ; Get page base of bios
- MVI L,12 ; Get entry vector to conout
- JMP GOHL ; Call conout direct through the bios
- ENDIF ; Dircon
- ;
- IF NOT DIRCON
- MOV E,A ; Get character into bdos entry register
- MVI C,WRCHR
- JMP BDOS ; Call conout via the bdos
- ENDIF ; Not dircon
- ;.....
- ;
- ;
- ; Print a string at HL of length B
- ;
- TYPEIT: MOV A,M
- CALL TYPE
- INX H
- DCR B
- JNZ TYPEIT
- RET
- ;.....
- ;
- ;
- ; Print string on the console
- ;
- PRINT: LDAX D ; Get the character from the de string
- ANI 7FH ; Strip off any parity
- ORA A ; See if it is a 0
- RZ ; Terminates with a 0 character
- CALL TYPE ; Show the character on the console
- INX D ; Next string position
- JMP PRINT ; Go do another
- ;.....
- ;
- ;
- ; Fetch character from console (without echo)
- ;
- CINPUT: LHLD BASE+1
- MVI L,9
- CALL GOHL
- ANI 7FH ; Strip off any parity
- RET
- ;.....
- ;
- ;
- ; Check for a CTRL-C or CTRL-S entered from the keyboard. Jump to EXIT
- ; if CTRL-C, pause on CTRL-S.
- ;
- CKABRT: LHLD BASE+1
- MVI L,6 ; Check status of keyboard
- CALL GOHL ; Any key pressed?
- ORA A
- RZ ; No, return to caller
- CALL CINPUT ; Get character
- CPI 'C'-40H ; Ctl-c?
- JZ EX0 ; If ctl-c then quit
- CPI 'S'-40H ; Ctl-s?
- RNZ ; No, return to caller
- CALL CINPUT ; Yes, wait for another char.
- CPI 'C'-40H ; Might be ctl-c
- JZ EX0 ; If ctl-c, else fall thru and continue
- RET
- ;.....
- ;
- ;
- ; Routine to do disk reset if D option entered on command line
- ;
- DSET: MVI C,RESET
- CALL CPM
- RET
- ;.....
- ;
- ;
- ; Kludge to allow call to address in HL
- ;
- GOHL: PCHL
- ;
- ; Entry to BDOS saving all extended registers
- ;
- CPM: PUSH B
- PUSH D
- PUSH H
-
- LDA ZRDFLG ; Zrdos running?
- ORA A
- JNZ ZRD ; Zrdos error trap and dos call
-
- CALL BDOS
- MOV B,A ; Save return code
- LDA VERFLG ; Is this 3.0?
- CPI 30H
- MOV A,B
- JC CPM20 ; No, exit normally
- CPI 0FFH ; It is 3.0 - was return code ff?
- JNZ CPM20 ; No, exit normally
- MOV A,H ; 3.0 and a=ff - check for error code
- ORA A
- JNZ DSKERR ; Trap out if we got a physical error
- MOV A,B ; Else continue normally
- ;
- CPM20: POP H
- POP D
- POP B
- RET
- ;
- ; ZRDOS Error Trap and System Call exits to CPM20
- ;
- ZRD: CALL SETTRAP ; Set the warm boot trap
- CALL BDOS ; Do what we're told
- CALL RESTRAP ; Reset the trap
- JMP CPM20 ; Error free exit.
- ;
- ; Set Warm Boot Trap in ZRDOS
- ;
- SETTRAP:
- PUSH H
- PUSH D
- PUSH B
- MVI C,SETWBT ; Set warm boot trap to come..
- LXI D,WBTRAP ; Here.
- CALL BDOS
- POP B
- POP D
- POP H
- RET
- ;
- ; WBTRAP is where the ZRDOS returns control on warm boot (error)
- ;
- WBTRAP: LXI H,DSKERR ; After re-setting the trap, return here.
- PUSH H ; Save DSKERR on stack.
- ;
- ; Reset Warm Boot Trap in ZRDOS
- ;
- RESTRAP:PUSH H
- PUSH D
- PUSH B
- PUSH PSW
- MVI C,RESWBT ; Reset warm boot trap
- CALL BDOS
- POP PSW
- POP B
- POP D
- POP H
- RET
- ;.....
- ;
- ;
- ; For file output mode, return to old user area and set DMA for the file
- ; output buffer.
- ;
- SETFOP: IF UOPT OR AOPT
- CALL CKVER ; Clear carry if cp/m 2 or later
- LDA OLDUSR ; Get user number at startup
- MOV E,A
- MVI C,CURUSR
- CNC CPM ; Reset the old user number if cp/m 2
- ENDIF ; Upot or aopt
- ;
- IF FOPT
- LXI D,OUTBUF ; Move dma from search buffer into the
- JMP SET2 ; Output buffer
- ENDIF ; Fopt
- ;
- RET
- ;.....
- ;
- ;
- ; Move disk buffer DMA to default buffer for directory search operations
- ; and BDOS media change routines (necessary for pre-CP/M 2 systems while
- ; in file output mode with an active buffer).
- ;
- SETSRC: LXI D,BASE+80H
- ;
- SET2: MVI C,SETDMA
- JMP CPM
- ;.....
- ;
- ;
- ; Print the amount of free space remaining on the selected drive
- ;
- PRTFRE: LXI D,TOTMS7 ; Print " ( "
- CALL PRINT
- LHLD FREEBY
- CALL DECPRT ; Print k free
- LXI D,TOTMS8 ; Print " K FREE) "
- JMP PRINT
- ;.....
- ;
- ;
- ; Compare routine for sort
- ;
- COMPR: PUSH H ; Save table addr
- MOV E,M ; Load low order
- INX H
- MOV D,M ; Load high order
- INX H
- MOV C,M
- INX H
- MOV B,M
- ;
- ;
- ; BC, DE now point to entries to be compared
- ;
- XCHG
- MOV E,A ; Get count
- ;
- CMPLP: MOV A,M
- ANI 7FH
- MOV D,A
- LDAX B
- ANI 7FH
- CMP D
- INX H
- INX B
- JNZ NOTEQL ; Quit on mismatch
- DCR E ; Or end of count
- JNZ CMPLP
- ;
- NOTEQL: POP H
- RET ; Cond code tells all
- ;.....
- ;
- ;
- ; Swap entries in the order table
- ;
- SWAP: LXI B,ORDER-2 ; Table base
- DAD H ; *2
- DAD B ; + base
- XCHG
- DAD H ; *2
- DAD B ; + base
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- INX H
- INX D
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- RET
- ;.....
- ;
- ;
- ; New compare routine
- ;
- COMPARE:LXI B,ORDER-2
- DAD H
- DAD B
- XCHG
- DAD H
- DAD B
- XCHG
- MOV C,M
- INX H
- MOV B,M
- XCHG
- MOV E,M
- INX H
- MOV D,M
- XCHG
- MOV E,A ; Count
- ;
- CMPLPE: MOV A,M
- ANI 7FH
- MOV D,A
- LDAX B
- ANI 7FH
- CMP D
- INX B
- INX H
- RNZ
- DCR E
- JNZ CMPLPE
- RET
- ;.....
- ;
- ;
- ; Error exit
- ;
- ERXIT: IF FOPT
- MVI A,0FFH
- STA FOPFLG ; Disable file output mode on error
- ENDIF ; Fopt
- ;
- CALL CRLF ; Space down
- POP D ; Get pointer to message string
- CALL PRINT ; Print it
- LXI D,ERRMS1 ; Print " Error"
- CALL PRINT
- CALL CRLF ; Space down
- ;
- ;
- ; Exit - all done, restore stack
- ;
- EXIT: IF DOPT ; If multi-disk option enabled
- LDA DOPFLG ; If multi-disk not selected - skip next
- ORA A
- JNZ EX0
- CALL CKABRT ; Check for user abort first
- MVI A,HIDRV-LODRV ; Get maximum drive code to search
- LXI H,FCB ; Bump directory fcb drive code
- INR M
- CMP M ; Does next disk exceed maximum?
- JC EX0
- ENDIF ; Dopt
- ;
- IF MAXDR AND DOPT
- LDA MAXD ; Look at another value limit
- INR A
- CMP M ; Is it lower?
- JC EX0 ; Bail out if too low
- JMP NOOPT ; Search next disk
- ENDIF ; Maxdr and dopt
- ;
- IF DOPT
- JNC NOOPT ; Search next disk if maxdr not true
- ENDIF ; Dopt
- ;
- EX0: IF VCODE
- CALL CRLF ; Turn up a blank line at end
- ENDIF ; Vcode
-
- MVI C,CONST ; Check console status
- CALL CPM
- ORA A ; Character waiting?
- MVI C,RDCHR
- CNZ CPM ; Gobble up character
- ;
- IF DOPT ; Restore bdos intercept vectors
-
- LDA ZRDFLG ; Zrdos running?
- ORA A
- JNZ EXIT1 ; Yes.
-
- LDA VERFLG ; Or error mode, depending on version
- CPI 30H
- JC EXIT0
- MVI C,45
- MVI E,0 ; Set error mode back to default
- CALL CPM
- JMP EXIT1
- ;
- EXIT0: LDA DOPFLG ; If they were swapped
- ORA A
- CZ SWAPEM
- ENDIF ; Dopt
- ;
- EXIT1: IF ROPT
- LDA ROPFLG ; If disk system was reset
- ORA A
- LDA OLDDSK ; Get default disk at startup
- MOV E,A
- MVI C,SELDSK ; Reselect it
- CZ CPM
- ENDIF ; Ropt
- ;
- LHLD STACK ; Get old stack pointer
- SPHL ; Move back to old stack
- RET ; And return to ccp
- ;.....
- ;
- ;
- ; Trap BDOS select and sector error vectors to our own intercept routine
- ; so we can catch a reference to an illegal drive.
-
- IF DOPT
- SWAPEM:
- LDA ZRDFLG ; See if zrdos running
- ORA A
- RNZ ; Yes. quit this.
-
- LDA VERFLG ; Check version
- CPI 30H ; See if error mode call is available
- JC SWAP20 ; If not, use bdos error vectors
- MVI C,45
- MVI E,0FFH ; Use set error mode call
- CALL CPM ; Set "return code only" mode
- RET
- ;.....
- ;
- ;
- SWAP20: LHLD BDOS+1 ; Get pointer to base of bdos
- ENDIF ; Dopt
- ;
- IF DOPT AND LOWCCP
- LDA BDOSPG ; Get "proper" bdos page
- MOV E,A ; Save it in "E"
- MOV A,H ; Get location of bdos
- CMP E ; Is it where bdos normally is?
- JZ BDCHK2 ; Yes, but perform 2nd check to be sure
- INX H ; Swap in the new pointer if running a
- MOV E,M ; Program below the ccp
- INX H
- MOV D,M
- XCHG ; Now hl points to the proper vector
- JMP SWAPOK ; Bypass second check
- ENDIF ; Dopt and lowccp
- ;
- IF DOPT
- BDCHK2: MOV A,L
- SUI 6 ; Check if pointing directly to bdos
- JZ SWAPOK ; Continue if true
- MVI A,'D' ; Undo option request for multi-disk
- STA DOPFLG
- ;
- SWAPOK: MVI L,9 ; Point to sector error vector
- LXI D,VECTBL ; Exchanging with our own vector table
- MVI A,4 ; 4 bytes to swap
- ;
- SWAPLP: MOV B,M ; Get byte from hl
- XCHG
- MOV C,M ; Get byte from de
- MOV M,B ; Put byte from hl
- XCHG
- MOV M,C ; Put byte from de
- INX H ; Bump exchange pointers
- INX D
- DCR A ; Dock counter
- JNZ SWAPLP ; Continue swapping til done
- RET
- ENDIF ; Dopt
- ;.....
- ;
- ;
- ; Check CP/M version number. Return carry flag set if pre-CP/M 2. If
- ; CP/M 2 or later or MP/M (any version), return carry clear.
- ;
- CKVER: LDA VERFLG
- CPI 20H
- RET
- ;.....
- ;
- ;
- ; Recovery point from intercepted BDOS select and bad sector errors.
- ;
- DSKERR: IF DOPT
- LXI SP,STACK ; Get out of bdos' stack
- JMP EXIT ; And exit back to ccp
- ENDIF ; Dopt
- ;
- ;-----------------------------------------------------------------------
- ; start of FNAME routine
- ; FNAME module
- ;
- IF DUOPT
- MAXDISK EQU 16 ; Maximum number of disks
- MAXUSER EQU 31 ; Maximum user number
- ;
- ; MAIN MODULE
- ; ON ENTRY, DE PTS TO FCB TO BE FILLED AND HL PTS TO FIRST BYTE OF
- ; TARGET STRING; FCB IS 36 BYTES LONG
- ; ON EXIT, B=DISK NUMBER (1 FOR A, ETC) AND C=USER NUMBER
- ; HL PTS TO TERMINATING CHAR
- ; A=0 AND Z SET IF ERROR IN DISK OR USER NUMBERS,
- ; A=0FFH AND NZ
- ; IF OK
- ;
- FNAME: PUSH D ; Save de
- MVI A,0FFH ; Set default disk and user
- STA DISK
- STA USER
- MVI B,36 ; Initialize fcb
- PUSH D ; Save pointer
- XRA A ; A=0
- ;
- FNINI: STAX D ; Store zero
- INX D ; Point to next
- DCR B ; Count down
- JNZ FNINI
- POP D ; Get pointer back
- ;
- ;
- ; Scan for colon in string
- ;
- PUSH H ; Save pointer
- ;
- COLON: MOV A,M ; Scan fora colon or space
- INX H ; Point to next
- CPI ':' ; Colon found?
- JZ COLON1
- CPI ',' ; Comma found?
- JZ GETF1
- CPI ' '+1 ; Delimiter?
- JC GETF1
- JMP COLON ; Continue if not end of line
- ;
- COLON1: POP H ; Clear stack
- MOV A,M ; Save possible drive specification
- CALL CAPS ; Capitalize
- CPI 'A' ; Digit if less than 'a'
- JC USERCK ; Process user number
- SUI 'A' ; Convert to 0-31
- CPI MAXDISK ; Within bounds?
- JC SVDISK
- ;
- ERREXIT:XRA A ; Error indicator
- POP D ; Restore 'de'
- RET
- ;...
- ;
- ;
- ; Log in specified disk
- ;
- SVDISK: INR A ; Adjust to 1 for 'a'
- STA DISK ; Save flag
- INX H ; Point to next character
- ;
- ;
- ; Check for user
- ;
- USERCK: MOV A,M ; Get possible user number
- CPI ':' ; No user number
- JZ GETFILE
- CPI '?' ; All user numbers?
- JNZ USERC1
- STA USER ; Set value
- INX H ; Point to after
- MOV A,M ; Must be colon
- CPI ':'
- JZ GETFILE
- JMP ERREXIT ; Fatal error if not colon after ?
- ;
- USERC1: XRA A ; Zero user number
- MOV B,A ; 'b' = accumulator for user number
- ;
- USRLOOP:MOV A,M ; Get digit
- INX H ; Point to next
- CPI ':' ; Done?
- JZ USRDN
- SUI '0' ; Convert to binary
- JC ERREXIT ; User number error?
- CPI 10
- JNC ERREXIT
- MOV C,A ; Next digit in 'c'
- MOV A,B ; Old number in 'a'
- ADD A ; *2
- ADD A ; *4
- ADD B ; *5
- ADD A ; *10
- ADD C ; *10+new digit
- MOV B,A ; Result in 'b'
- JMP USRLOOP
- ;
- USRDN: MOV A,B ; Get nuer user number
- CPI MAXUSER+1 ; Within range?
- JNC ERREXIT
- STA USER ; Save in flag
- JMP GETFILE
- ;
- ;
- ; Extract file name
- ;
- GETF1: POP H ; Get pointer to byte
- ;
- GETFILE:MOV A,M ; Pointing to colon?
- CPI ':'
- JNZ GFILE1
- INX H ; Skip over colon
- ;
- GFILE1: MOV A,M ; Get next character
- CPI ',' ; Delimiter?
- JZ GFQUES
- CPI ' '+1 ; Not a delimiter?
- JNC GFILE2
- ;
- GFQUES: INX D ; Fill with ???
- MVI B,11 ; 11 bytes
- MVI A,'?'
- ;
- GFFILL: STAX D ; Put?
- INX D ; Point to next
- DCR B ; Count down
- JNZ GFFILL
- ;
- FNDONE: LDA DISK ; Get disk number
- MOV B,A ; In 'b'
- LDA USER ; Get user number
- MOV C,A ; In 'c'
- POP D ; Restore registers
- MVI A,0FFH ; No error
- ORA A ; Set flags
- RET
- ;.....
- ;
- ;
- ; Get file name fields
- ;
- GFILE2: MVI B,8 ; At most, 8 bytes for filename
- CALL SCANF ; Scan and fill
- MVI B,3 ; At most, 3 bytes for filetype
- MOV A,M ; Get delimiter
- CPI '.' ; Filename ending in '.'?
- JNZ GFILE3
- INX H ; Point to character after '.'
- CALL SCANF ; Scan and fill
- JMP FNDONE ; Done...return to 'args'
- ;...
- ;
- ;
- GFILE3: CALL SCANF4 ; Fill with spaces
- JMP FNDONE
- ;.....
- ;
- ;
- ; Scanner routine
- ;
- SCANF: CALL DELCK ; Check for delimiter
- JZ SCANF4 ; Fill with spaces if found
- INX D ; Point to next byte in filename
- CPI '*' ; Question mark fill ?
- JNZ SCANF1
- MVI A,'?' ; Place '?'
- STAX D
- JMP SCANF2
- ;
- SCANF1: STAX D ; Place character
- INX H ; Point to next position
- ;
- SCANF2: DCR B ; Count down
- JNZ SCANF ; Continue loop
- ;
- SCANF3: CALL DELCK ; "b" chars or more - skip to delimiter
- RZ
- INX H ; Point to next
- JMP SCANF3
- ;
- SCANF4: INX D ; Point to next filename or filetype
- MVI A,' ' ; Fill with spaces
- STAX D
- DCR B ; Count down
- JNZ SCANF4
- RET
- ;.....
- ;
- ;
- ; Buffers
- ;
- DISK: DB 0 ; Disk number
- USER: DB 0 ; User number
- ;
- ;
- ; Check character pointed to by 'HL' for a delimiter, return with Zero
- ; flage set if the character is a delimiter
- ;
- DELCK: MOV A,M ; Get the character
- CALL CAPS ; Capitalize
- ORA A ; 0=delimiter
- RZ
- CPI ' '+1 ; Space character+1
- JC DELCK1 ; Space character or less
- CPI '='
- RZ
- CPI 5FH ; Underscore
- RZ
- CPI '.'
- RZ
- CPI ':'
- RZ
- CPI ';'
- RZ
- CPI ','
- RZ
- CPI '<'
- RZ
- CPI '>'
- RET
- ;...
- ;
- ;
- DELCK1: CMP M ; Compare with self for ok
- RET
- ;...
- ;
- ;
- CAPS: CPI 'a'
- RC
- CPI 'z'+1
- RNC
- SUI 20H
- RET
- ENDIF ; Duopt
- ;.....
- ; end of FNAME routine
- ;
- ;=======================================================================
- ;
- ; SUBROUTINES to read library file directory
- ;
- ;=======================================================================
- ; start of LOPT routine
- ;
- IF LOPT
- PRTLMEM:LXI H,ORDER ; Initialize order table pointer
- SHLD NEXTL
- XRA A
- STA LNCNT
- ;
- ENTRYL: LHLD LCOUNT ; Get fcb count
- DCX H ; Decrement it
- SHLD LCOUNT
- MOV A,H ; Is this the last file?
- ORA L
- JZ LBRTST ; If count=0, last file skip compare
- PUSH B
- CALL CKABRT ; Check for abort code from keyboard
- LHLD NEXTL
- MVI A,11
- CALL COMPR ; Does this entry match next one?
- POP B
- JNZ LBRTST ; No, print it
- INX H
- INX H ; Skip, highest extent comes last in list
- SHLD NEXTL
- JMP ENTRYL ; Loop back for next lowest extent
- ;
- ;
- ; Exit Library member printing
- ;
- LBEXIT: LHLD LMTOTL
- MOV A,H
- ORA L
- RZ
- PUSH H ; Save member count
- XRA A ; Get a zero to...
- STA SUPSPC ; Suppress leading spaces in totals
- LXI H,MNPL ; If last line is full, don't turn
- LDA LNCNT ; Up extra line
- CMP M
- CNZ CRLF ; If partial line, extra line needed
- ENDIF ; Lopt
- ;
- IF PRBRDR AND LOPT
- CALL BDRCH2
- LXI D,CONTM1 ; Print "There are "
- ENDIF ; Prbrdr and lopt
- ;
- IF NOT PRBRDR AND LOPT
- LXI D,CONTM2
- ENDIF ; Not prbrdr and lopt
- ;
- IF LOPT
- CALL PRINT
- POP H ; Get total member count back
- CALL DECPRT
- LXI D,MFILES ; Print "Members in "
- CALL PRINT
- LHLD LBTOTL
- CALL DECPRT
- LXI D,LIBR
- JMP PRINT
- ;.....
- ;
- ;
- ; Valid entry obtained - spit it out.
- ;
- LBRTST: LHLD NEXTL ; Get order table pointer
- MOV E,M ; Get low order address
- INX H
- MOV D,M ; Get high order address
- INX H
- SHLD NEXTL ; Save updated table pointer
- LXI H,8
- DAD D
- CALL CKLBR
- JNZ LBRNEX
- PUSH D
- LXI H,MNPL
- LDA LNCNT ; Old code here
- CMP M
- CNZ CRLF
- PUSH PSW ; Just in case
- LDA MNPL ; Load a with # of names per line
- CPI 4 ; Is it 4?
- JZ LBMS ; If so then jump to long lbr message
- CPI 3 ; Is it 3?
- JZ LBMS ; If so then jump to long lbr message
- ENDIF ; Lopt
- ;
- IF PRBRDR AND LOPT
- LXI D,LFMSP3 ; Set up short "LBR members" message
- ENDIF ; Prbrdr and lopt
- ;
- IF NOT PRBRDR AND LOPT
- LXI D,LFMSP4
- ENDIF ; Not prbrdr and lopt
- ;
- IF LOPT
- CALL PRINT ; Print it
- JMP SKLBMS ; Skip past long message
- ENDIF ; Lopt
- ;
- LBMS: IF PRBRDR AND LOPT
- LXI D,LFMSP1 ; Set up long "Library directory" message
- ENDIF ; Prbrdr and lopt
- ;
- IF NOT PRBRDR AND LOPT
- LXI D,LFMSP2
- ENDIF ; Not prbrdr and lopt
- ;
- IF LOPT
- CALL PRINT ; Print it
- ;
- SKLBMS: POP PSW ; Put it back
- LDA FCB ; Get current drive
- ADI 'A'-1 ; Convert to ascii
- CALL TYPE ; Print it
- ENDIF ; Lopt
- ;
- IF REPUSR AND LOPT
- CALL TYPUSR ; Print user # after it
- ENDIF ; Repusr and lopt
- ;
- IF LOPT
- MVI A,':' ; And colon
- CALL TYPE
- POP H
- PUSH H
- MVI B,8 ; File name length
- CALL TYPEIT
- MVI A,'.' ; Period after fn
- CALL TYPE
- MVI B,3 ; Display 3 characters of filetype
- CALL TYPEIT
- CALL DOIT ; Compute size of library in k
- XCHG
- CALL DECPRT
- MVI A,'k'
- CALL TYPE
- CALL CRLF
- POP H
- ;
- ;
- ; Saves the library file name into LBRFCB
- ;
- LDA FCB
- LXI D,LBRFCB ; To
- STAX D
- INX D
- MVI B,11 ; Len
- CALL MOVE ; Do the move
- XCHG
- MVI B,25
- ;
- CLMFCB: MVI M,0
- INX H
- DCR B
- JNZ CLMFCB
- CALL SETLDMA
- LXI D,LBRFCB ; Point to file
- MVI C,OPEN ; Get function
- CALL CPM ; Open it
- MVI C,READ
- LXI D,LBRFCB
- CALL CPM
- CALL SETFOP
- LXI H,LBBUF
- MOV A,M
- ORA A
- JZ CKLDIR ; Check directory present?
- ;
- BADLBR: LXI H,NLBRF
- MVI B,25
- CALL TYPEIT
- ;
- LMLEXI: CALL LBCLOSE
- ;
- ;
- ; Do next library file
- ;
- LBRNEX: LHLD LCOUNT ; Check count
- MOV A,H
- ORA L
- JZ LBEXIT ; No more, all done
- JMP ENTRYL ; Else, get next .lbr file
- ;
- NLBRF: DB '++ Not a LIBRARY file ++',CR,LF
- ;
- ;
- ; Close the library file
- ;
- LBCLOSE:LXI D,LBRFCB
- MVI C,CLOSE
- CALL CPM
- RET
- ;.....
- ;
- ;
- ; Set the Library file DMA adderss
- ;
- SETLDMA:CALL CKVER ; Set carry if pre-cp/m 2
- LDA NEWUSR ; Get user area for directory
- MOV E,A
- MVI C,CURUSR ; Get the user function
- CNC CPM ; And set new user number if cp/m 2
- LXI D,LBBUF
- MVI C,SETDMA
- CALL CPM
- RET
- ;.....
- ;
- ;
- ; Check to see if there indeed is a LBR file directory and barf if not!
- ;
- CKLDIR: MVI B,11 ; Length of file name
- MVI A,' ' ; Space
- INX H
- ;
- CKDLP: CMP M
- JNZ BADLBR
- DCR B
- INX H
- JNZ CKDLP
- ;
- ;
- ; The first entry in the LBR directory is indeed blank. Now see if the
- ; directory size is >0
- ;
- MOV E,M ; File starting location low
- INX H ; Must be zero here
- MOV A,M ; File starting location high
- ORA E ; Must be zero here also
- JNZ BADLBR
- INX H
- MOV E,M ; Get library size low
- INX H ; Point to library size high
- MOV D,M ; Get library size high
- MOV A,D
- ORA E ; Library must have some size
- JZ BADLBR
- DCX D
- XCHG
- SHLD SLFILE
- LHLD LBTOTL
- INX H
- SHLD LBTOTL
- LDA MNPL
- STA LNCNT ; Reset names per line counter
- MVI B,3
- LXI H,17
- DAD D
- JMP LMTEST
- ;
- LFMLOP: LHLD SLFILE ; Get
- MOV A,L
- ORA H
- JZ LMLEXI
- DCX H
- SHLD SLFILE
- CALL SETLDMA
- MVI C,READ
- LXI D,LBRFCB
- CALL CPM
- CALL SETFOP
- MVI B,4 ; Get file count per sector
- LXI H,LBBUF ; Get buffer starting address
- ;
- LMTEST: MOV A,M ; Get member open flag
- ORA A ; Test for open
- JZ PRMNAM
- ;
- LMTESA: LXI D,32 ; Member not open get offset
- DAD D ; To next and add it in.
- DCR B ; Is buffer empty ?
- JNZ LMTEST ; No so test next entry
- JMP LFMLOP ; Yes get next buffer...
- ;
- PRMNAM: PUSH H ; Print member name and size
- PUSH B
- CALL CKABRT ; Check for abort code from keyboard
- LXI H,LNCNT
- LDA MNPL
- CMP M
- JNZ PRMNA1
- ENDIF ; Lopt
- ;
- IF PRBRDR AND LOPT
- MVI A,'*' ; Load a reg with border character
- CALL TYPE ; Print it
- MVI A,' ' ;
- CALL TYPE ; Print space between border & text
- ENDIF ; Prbrdr and lopt
- ;
- IF PRDI AND PRLIBD AND LOPT
- LDA LBRFCB ; Precede new line with drive name
- ADI 'A'-1
- CALL TYPE
- ENDIF ; Prdi and prlibd and lopt
-
- ;
- IF (PRDI AND PRLIBD) AND (REPUSR AND PRUS) AND LOPT
- CALL CKVER ; Under cp/m 2, output the user number
- CNC TYPUSR ; Too
- ENDIF ; (prdi and prlibd) and (repusr and prus) and lopt
- ;
- IF PRDI AND PRLIBD AND LOPT
- MVI A,':' ; Tag header with a colon and a space
- CALL FPAD ; And exit back to entry
- ENDIF ; Prdi and prlibd and lopt
- ;
- IF LOPT
- PRMNA1: POP B
- POP H
- PUSH H
- PUSH B
- INX H
- MVI B,8 ; File name length
- CALL TYPEIT
- MVI A,'.' ; Period after fn
- CALL TYPE
- MVI B,3 ; Display 3 characters of filetype
- CALL TYPEIT
- INX H
- INX H
- MOV E,M
- INX H
- MOV D,M
- XCHG
- ;
- ;
- ; Output the size of the individual file.
- ;
- PUSH D
- PUSH H
- PUSH H
- LHLD LLENLOC
- PUSH H
- POP D
- POP H
- DAD D
- SHLD LLENLOC
- POP H
- ;
- ;
- ; New code added to convert lib members from sectors to 'k'
- ;
- ; Upon entry member's size in sectors is in HL
- ;
- ; Begin "0K" library bug fix here. The problem was a single byte add
- ; when a double byte add was required.
-
- LXI D,7 ; Round up to nearest 1k
- DAD D
- XCHG
- LXI H,0
- MOV A,E ; Put low byte of sector count in a
- ;
- RRC
- RRC
- RRC
- ANI 1FH
- MOV E,A ; And put it back
- MOV L,D ; Get the high byte if any
- MVI D,0 ; Clean out the old resting place
- DAD H ; Multiply it by 32 to convert to
- DAD H ; Number
- DAD H ; Of
- DAD H ; K
- DAD H ; Bytes
- DAD D ; And add in the low byte
- POP D
- CALL FDECPRT ; Go print it
- MVI A,'k' ; And follow with size
- CALL TYPE
- ;
- ;
- ; At least one more file to output - can we put it on the current line?
- ;
- LHLD LMTOTL
- INX H
- SHLD LMTOTL
- LDA LNCNT
- DCR A
- STA LNCNT
- PUSH PSW
- CNZ FENCE ; If room left, output the fence char.
- POP PSW
- POP B
- POP H
- JNZ LMTESA ; And go output another file
- ;
- ;
- ; Current line full, start a new one.
- ;
- LDA MNPL
- STA LNCNT ; Reset names per line counter
- CALL CRLF ; Space down to next line
- JMP LMTESA
- ;.....
- ;
- ;
- ; Move characters from 'HL' to 'DE' length in 'B'
- ;
- MOVE: MOV A,M ; Get a character
- STAX D ; Store it
- INX H ; To next 'from'
- INX D ; To next 'to'
- DCR B ; More?
- JNZ MOVE ; Yes, loop
- RET ; No, return
- ;.....
- ;
- ;
- ; Test file extent for LBR
- ;
- CKLBR: PUSH H
- PUSH D
- PUSH B
- XCHG
- LXI H,LBRTYP
- MVI C,3
- ;
- CKLBL: LDAX D
- ANI 7FH
- CMP M
- JNZ CKLBX
- INX H
- INX D
- DCR C
- JNZ CKLBL
- ;
- CKLBX: POP B
- POP D
- POP H
- RET
- ;.....
- ;
- ;
- BDRCH2: MVI A,'*'
- CALL TYPE
- POP PSW
- ;
- BDRCH1: MVI A,'*'
- CALL TYPE
- POP PSW
- RET
- ;.....
- ;
- ;
- LFMSP1: DB CR,LF,'** Library Directory for ',0
- LFMSP2: DB CR,LF,'Library Directory for ',0
- LFMSP3: DB CR,LF,'** Lbr Members in ',0
- LFMSP4: DB CR,LF,'Lbr Members in ',0
- LBRTYP: DB 'LBR'
- ENDIF ; Lopt (from waaaaay back in pgm)
- ;
- ; end of LOPT routine
- ;***********************************************************************
- ;
- ; TIME: Report users Time on system
- ;
- ;***********************************************************************
- ;
- IF TIMEON
- ;
- ; Go through a search to see if (M)BYE(+) is active.
- ;
- TIME: LHLD 0001H ; Point to warm boot again
- DCX H ; If BYE active,
- MOV D,M ; Pick up pointer to BYE variables
- DCX H ; (COVECT) followed by 'BYE'
- MOV E,M
- LXI H,15 ; Calculate address of BYE variable
- DAD D ; Where ptr to orig BIOS vector stored
- MOV E,M ; Load that address
- INX H ; Into DE. If BIOS active, DE now points
- MOV D,M ; To original BIOS console output vector
- INX H ; Point to BYE signon message
- ;
- MOV A,M ; Get letter
- ANI 05FH ; Convert to upper case if needed
- CPI 'B' ; Try to match 'BYE'
- RNZ ; Out if BYE not active
- INX H
- MOV A,M
- ANI 05FH ; Convert to upper case if needed
- CPI 'Y'
- RNZ
- INX H
- MOV A,M
- ANI 05FH ; Convert to upper case if needed
- CPI 'E'
- RNZ
- ;
- LXI D,6 ; Bye is running, so point to RTCBUF
- DAD D
- MOV E,M ; Get RTCBUF address
- INX H ; And
- MOV D,M ; Stuff in DE
- XCHG ; Then put in HL (RTCBUF address)
- LXI D,7
- DAD D ; Further offset to time-on-system byte
- MOV A,M ; (A) now has time-on
- LXI H,TONMS1 ; Where to store it in ascii
- CALL DEC8 ; Convert binary to ascii
- LXI D,TONMSG
- CALL PRINT ; Print the message
- RET ; And return
- ;
- ; DEC8 will convert an 8 bit binary number in A to 3 ASCII bytes.
- ; HL points to the MSB location where the ASCII bytes will be stored.
- ; Leading zeros are suppressed, so store spaces in your buffer before calling.
- ;
- DEC8: PUSH B
- PUSH D
- MVI E,0 ; Leading zero flag
- MVI D,100
- DEC81: MVI C,'0'-1
- DEC82: INR C
- SUB D ; 100 or 10
- JNC DEC82 ; Still +
- ADD D ; Now add it back
- MOV B,A ; Remainder
- MOV A,C ; Get 100/10
- CPI '1' ; Zero?
- JNC DEC84 ; Yes
- MOV A,E ; Check flag
- ORA A ; Reset?
- MOV A,C ; Restore byte
- JZ DEC85 ; Leading zeros are skipped
- DEC84: MOV M,A ; Store it in buffer pointed at by HL
- INX H ; Increment storage location
- MVI E,0FFH ; Set zero flag
- DEC85: MOV A,D
- SUI 90 ; 100 to 10
- MOV D,A
- MOV A,B ; Remainder
- JNC DEC81 ; Do it again
- ADI '0' ; Make ascii
- MOV M,A ; And store it
- POP D
- POP B
- RET
- ;
- TONMSG: DB CR,LF,'Time on system is '
- TONMS1: DB ' minutes',0
- ENDIF ; TIMEON
- ;
- ; end of TIMEON routine
- ;======================================================================
- ;
- IF HELP
- ;
- ; SD options help menu when $? option entered
- ;
- HELPME:
- LXI D,OPTMSG ; Point at message
- CALL PRINT ; Print it
- JMP EXIT ; And exit
- ;
- OPTMSG:
- DB CR,LF,LF
- DB ' Options (precede with a $):',CR,LF,LF
- DB ' A - all user areas C - Clear screen',CR,LF
- DB ' D - all drives *F - file output (SD.DIR)',CR,LF
- DB ' L - list .LBR members N - no page pause',CR,LF
- DB '*P - printer output R - reset disk',CR,LF
- DB '*S - include $SYS files U - user area to start',CR,LF
- DB ' V - display version # 4 - 40 col display (2-wide)',CR,LF
- DB ' 6 - 64 col display (3-wide) 8 - 80 col display (default)',CR,LF,LF
- DB ' Example: A0>sd $adn List all users & drives with no pauses'
- DB CR,LF,LF
- DB ' Options marked with a "*" are usually not available',CR,LF
- DB ' to remote users.'
- DB CR,LF,0
- ;
- ENDIF ; Help
- ;
- ;
- ;-----------------------------------------------------------------------
- ;
- ; end of program code
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Initialized data area
- ;
- DRUMSG: DB 'Drive/User',0
- ;
- IF PGPAWS
- EOSMSG: DB ' [more]',CR,'$'
- MORERA: DB ' ',CR,'$'
- ENDIF ; Pgpaws
- ;
- ERRMS1: DB ' '
- ERRMS2: DB 'Error',0
- ;
- IF REPERR
- ERRTAG: DB ' ->',0
- ENDIF ; Reperr
- ;
- NOFMS1: DB CR,LF,CR,LF
- ;
- IF REVIDEO
- REVMS1: DB LEADIN,INTOREV
- ENDIF ; Revideo
- ;
- IF REVIDEO AND THREBYT
- DB TBYTE
- ENDIF
- ;
- DB ' ',0
- ;
- NOFLM: DB '>> No detectable file(s) on ',0
- NOFSM: DB '>> No file(s) on ',0
- NOFMS2: DB ': ',0
- TOTMS1: DB CR,LF
- ;
- IF REVIDEO
- REVMS2: DB LEADIN,INTOREV
- ENDIF ; Revideo
- ;
- IF REVIDEO AND THREBYT
- DB TBYTE
- ENDIF
- ;
- DB ' Drive ',0
- ;
- TOTMS3: DB ' ',CR,LF,0
- TOTMS4: DB ' space used: ',0
- TOTMS5: DB 'k ',0
- TOTMS6: DB ': files: ',0
- TOTMS7: DB '(',0
- TOTMS8: DB 'k free) '
- ;
- IF REVIDEO
- REVMS3: DB LEADIN,OUTAREV
- ENDIF ; Revideo
- ;
- IF REVIDEO AND THREBYT
- DB TBYTE
- ENDIF
- ;
- DB ' ',0 ; Eliminate double lf
- ;
- IF LOPT
- CONTM1: DB CR,LF,'*** There are ',0
- CONTM2: DB CR,LF,'There are ',0
- MFILES: DB ' member files in ',0
- LIBR: DB ' library(s)',0
- ENDIF ; Lopt
- ;
- ;
- ;=======================================================================
- ;
- ; Permanently initialized data area
- ;
- ;=======================================================================
-
- IF DOPT
- VECTBL: DW DSKERR ; Bdos sector error intercept vector
- DW DSKERR ; Bdos select error intercept vector
- ENDIF ; Dopt
- ;
- ;
- ;=======================================================================
- ;
- ; Template of initialization data for when SD is run or rerun
- ;
- ; The values here are copied by initialization code into
- ; the area in which they are actually used by the program
- ;
- ;=======================================================================
- ;
- TMPLT0 EQU $ ; Mark start of initialization template
- ;
- ; Option field lookup table. Note that you can force any of these op-
- ; tions as a DEFAULT by changing the letter for the option into a zero
- ; (assuming that its enabling equate is true). Each option that you
- ; hard-wire in this manner will no longer be recognized as a command
- ; line OPTION, and if you redundantly key it in, SD will flag it as un-
- ; recognized.
- ;
- OTBL0: IF NOT WHLA AND AOPT
- DB 'A' ; Axl users option flag
- ENDIF ; Not whla and aopt
- ;
- IF WHLA AND AOPT
- DB 'a'
- ENDIF ; Whla and aopt
- ;
- IF NOT WHLC AND COPT
- DB 'C' ; Clear screen option flag
- ENDIF ; Not whlc and copt
- ;
- IF WHLC AND COPT
- DB 'c'
- ENDIF ; Whlc and copt
- ;
- IF NOT WHLCL AND CLOPT
- DB '4'
- ENDIF ; Not whlcl and clopt
- ;
- IF WHLCL AND CLOPT
- DB '4'+40H
- ENDIF ; Whlcl and clopt
- ;
- IF NOT WHLCL AND CLOPT
- DB '6'
- ENDIF ; Not whlcl and clopt
- ;
- IF WHLCL AND CLOPT
- DB '6'+40H
- ENDIF ; Whlcl and clopt
- ;
- IF NOT WHLCL AND CLOPT
- DB '8'
- ENDIF ; Not whlcl and clopt
- ;
- IF WHLCL AND CLOPT
- DB '8'+40H
- ENDIF ; Whlcl and clopt
- ;
- IF NOT WHLD AND DOPT
- DB 'D' ; Multi-disk option flag
- ENDIF ; Not whld and dopt
- ;
- IF WHLD AND DOPT
- DB 'd'
- ENDIF ; Whld and dopt
- ;
- IF NOT WHLF AND FOPT
- DB 'F' ; Sd.dir file output option
- ENDIF ; Not whlf and fopt
- ;
- IF WHLF AND FOPT
- DB 'f'
- ENDIF ; Whlf and fopt
- ;
- IF NOT WHLL AND LOPT
- DB 'L' ; Display library members flag
- ENDIF ; Not whll and lopt
- ;
- IF WHLL AND LOPT
- DB 'l'
- ENDIF ; Whll and lopt
- ;
- IF NOPT AND PGPAWS ; No page-pause option flag
- DB 'N'
- ENDIF ; Nopt and pgpaws
- ;
- IF NOT WHLP AND POPT
- DB 'P' ; Printer output option
- ENDIF ; Not whlp and popt
- ;
- IF WHLP AND POPT
- DB 'p'
- ENDIF ; Whlp and popt
- ;
- IF NOT WHLR AND ROPT
- DB 'R' ; If not auto reset and not wheel restr.
- ENDIF ; Not whlf and ropt
- ;
- IF WHLR AND ROPT
- DB 'r' ; If not auto reset and is wheel restr.
- ENDIF ; Whlr and ropt
- ;
- IF NOT WHLS AND SOPT
- DB 'S'
- ENDIF ; Not whls and sopt
- ;
- IF WHLS AND SOPT
- DB 's'
- ENDIF ; Whls and sopt
- ;
- IF VOPT ; Display version number flag
- DB 'V'
- OEND0: ENDIF ; Vopt
- ;
- ;
- ; End of option lookup table
-
- IF FOPT
- BUFPN0: DW OUTBUF ; Ptr to next location in output buffer
- BUFCN0: DB 128 ; Number of bytes left in output buffer
- OUTFC0: DB 0,'SD DIR'
- ENDIF ; Fopt
-
- TMPLT1 EQU $ ; Mark end of initialization data template
-
- ; THIS IS THE END OF THE CODE THAT MUST BE STORED ON DISK IN THE COM FILE
- ;
- ;=======================================================================
- ;
- ; data area reinitialized by code when SD is run or rerun
- ;
- ;=======================================================================
-
- DATA0 EQU $ ; Mark beginning of area to initialize
-
-
- OTBL EQU $ ; Mark start of option table
- ;
- IF AOPT
- AOPFLG: DS 1
- ENDIF ; Aopt
- ;
- IF COPT
- COPFLG: DS 1
- ENDIF ; Copt
- ;
- IF CLOPT
- CL4FLG: DS 1
- CL6FLG: DS 1
- CL8FLG: DS 1
- ENDIF ; Clopt
- ;
- IF DOPT
- DOPFLG: DS 1
- ENDIF ; Dopt
- ;
- IF FOPT
- FOPFLG: DS 1
- ENDIF ; Fopt
- ;
- IF LOPT
- LOPFLG: DS 1
- ENDIF ; Lopt
- ;
- IF NOPT AND PGPAWS ; No page-pause option flag
- NOPFLG: DS 1
- ENDIF ; Nopt and pgpaws
- ;
- IF POPT
- POPFLG: DS 1
- ENDIF ; Popr
- ;
- IF ROPT
- ROPFLG: DS 1
- ENDIF ; Autor or ropt
- ;
- IF SOPT
- SOPFLG: DS 1
- ENDIF ; Sopt
- ;
- IF VOPT ; Display version number flag
- VOPFLG: DS 1
- ENDIF ; Vopt
- ;
- OEND EQU $ ; Mark end of option table
- ;
- ;
- ; End of option lookup table
-
- IF FOPT
- BUFPNT: DS 2 ; Ptr to next location in output buffer
- BUFCNT: DS 1 ; Number of bytes left in output buffer
- OUTFCB: DS 1 + 8 + 3 ; Space for user #, filename, and filetype
- ENDIF ; Fopt
- ;-----------------------------------------------------------------------
- ;
- ; BEGINNING OF AREA REINITIALIZED TO ZERO EACH TIME SD IS RUN
- ;
- IF FOPT
- DS 21 ; Rest of sd.dir fcb
- OPNFLG: DS 1 ; File open flag for all user file output
- ENDIF ; Fopt
- ;
- AFLAG: DS 1 ; If a option check for prior u option
- DFLAG: DS 1 ; If d option check for prior drive spec.
- FNDFLG: DS 1 ; Flag whether any files matched
- ;
- IF PGPAWS
- LINCNT: DS 1 ; Count of lines printed on screen
- ENDIF ; Pgpaws
- ;
- ;
- IF LOPT
- LLENLOC:DS 2 ; Running total of .lbr length
- LMTOTL: DS 2
- LBTOTL: DS 2
- LNCNT: DS 1
- LCOUNT: DS 2
- NEXTL: DS 2
- SLFILE: DS 2
- ENDIF ; Lopt
- ;
- IF VCODE
- LINES: DS 1 ; Number of lines to be printed out.
- ENDIF ; Vcode
- ;
- IF VOPT
- FIRSTT: DS 1 ; First time flag for version # display
- ENDIF ; Vopt
-
-
- DATA1 EQU $ ; Mark end of area to initialize
-
- ;
- ;=======================================================================
- ;
- ; Uninitialized data area
- ;
- ;=======================================================================
-
- IF FOPT
- OUTBUF: DS 128 ; Output file buffer
- ENDIF ; Vopt
- ;
- BASUSR: DS 1 ; Dupe of original dir. user # to search
- BLKMAX: DS 2 ; Highest block # on drive
- BLKMSK: DS 1 ; Sec/blk - 1
- BLKSHF: DS 1 ; # shifts to mult by sec/blk
- COUNT: DS 2 ; Entry count
- DIRMAX: DS 2 ; Highest file # in directory
- FREEBY: DS 2 ; Contains number of k left on dir. drive
- GAP: DS 2 ; Sort routine storage
- HITRAP: DS 1 ; Highlit trap (previously typed char)
- I: DS 2 ; Sort routine storage
- J: DS 2 ; Sort routine storage
- JG: DS 2 ; Sort routine storage
- LZFLG: DS 1 ; 0 when printing leading zeros
- MAXUSR: DS 1 ; Max user # for drive from lookup table
- NEWUSR: DS 1 ; Contains user # selected by "$U" option
- NEXTT: DS 2 ; Next table entry
- OLDDSK: DS 1 ; Holder for currently logged-in drive
- OLDUSR: DS 1 ; Contains user number upon invocation
- SCOUNT: DS 2 ; # to sort
- SUPSPC: DS 1 ; Leading space flag for decimal routine
- TBLOC: DS 2 ; Pointer to start of name table
- TEMP: DS 2 ; Save dir entry
- TOTFIL: DS 2 ; Total number of files
- TOTSIZ: DS 2 ; Total size of all files
- VERFLG: DS 1 ; Cx/m version number (0=pre-cp/m 2)
- ZRDFLG: DS 1 ; Zrdos version number
- ;
- IF LOPT
- LBRFCB: DS 36
- LBBUF: DS 80H
- ENDIF ; Lopt
- ;
- IF VCODE
- NEWPTR: DS 2 ; Pointer to start of second table
- XPOINT: DS 2 ; Ditto
- JUMPER: DS 2 ; Amount to increment by in second table
- ; To keep vertical file alignment
- ENDIF ; Vcode
- ;
- DS 60 ; Stack area
- STACK: DS 2 ; Save old stack pointer here
- ;
- ORDER EQU $ ; Order table starts here
- ;
- ;
- END