mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1888 lines
38 KiB
1888 lines
38 KiB
;
|
|
; PROGRAM: XDIR III
|
|
; AUTHOR: RICHARD CONN
|
|
; VERSION: 2.0
|
|
; DATE: 9 APR 84
|
|
; PREVIOUS VERSIONS: 1.6 (19 NOV 83)
|
|
; PREVIOUS VERSIONS: 1.5 (9 JAN 83), 1.4 (6 JAN 83), 1.3 (7 DEC 82)
|
|
; PREVIOUS VERSIONS: 1.2 (2 NOV 82), 1.1 (30 OCT 82), 1.0 (20 OCT 82)
|
|
;
|
|
vers equ 20
|
|
z3env SET 0f400h
|
|
|
|
;
|
|
; XDIR III -- Extended Disk Directory Program
|
|
; ZCPR3 Version
|
|
;
|
|
; XDIR III produces a formatted, alphabetized listing of the contents
|
|
; of the disk directory of the implied (current logged-in) or specified disk.
|
|
;
|
|
; XDIR III is invoked by a command line of the following form --
|
|
;
|
|
; XDIR dir:filename.typ ooo...
|
|
; or
|
|
;
|
|
; XDIR /oooo...
|
|
;
|
|
; where:
|
|
; dir is an optional directory name or a disk/user specification (du)
|
|
; if dir is omitted, XDIR III defaults to the current disk/user
|
|
; filename.typ is an ambiguous file name and type (* and ? may be used)
|
|
; o are option letters as follows:
|
|
; Aa - Set the attributes of the files to be displayed;
|
|
; a=S for System Files, a=N for Non-System Files
|
|
; a=A for All Files (System and Non-System)
|
|
; D - Send Output to Disk as well as screen
|
|
; Ff - Engage File Name Buffer Facility
|
|
; f=L to Log File Names to Disk
|
|
; f=P to Print Names Logged to Disk
|
|
; f=S to Scan Disk for File Names and Compare to Logged
|
|
; I - Inspect files selected by FL option for inclusion
|
|
; N - Negate selection; select those files which do NOT
|
|
; match the ambiguous file name
|
|
; Oo - Set Output Parameters;
|
|
; o=A to Toggle File Attributes, o=F to Form Feed at end
|
|
; o=G to Toggle Grouping, o=H to Toggle Hor/Vert
|
|
; P - Print display as well as show it on the screen
|
|
; PF - Same as POF
|
|
; U - Select All User Areas
|
|
;
|
|
; Options may be combined as desired; note that AA is the same as AS and AN,
|
|
; but AS by itself negates AN and vice-versa, with AN taking precident
|
|
;
|
|
|
|
|
|
;
|
|
; CP/M Equates
|
|
;
|
|
base equ 0
|
|
wboot equ base
|
|
bdose equ base+5
|
|
fcb equ base+5ch
|
|
buff equ base+80h
|
|
ctrlc equ 'C'-'@'
|
|
cr equ 0dh
|
|
ff equ 0ch
|
|
lf equ 0ah
|
|
esize equ 16 ; size of directory entries
|
|
optch equ '/' ; option char
|
|
maxent equ 54 ; maximum number of entries/screen
|
|
|
|
;
|
|
; External Routines
|
|
;
|
|
ext bdos ; BDOS
|
|
ext dutdir ; convert DU to DIR form
|
|
ext z3log ; log into DU or DIR
|
|
ext z3init ; init buffers
|
|
ext dbuffer ; disk routines
|
|
ext dfree
|
|
ext diralpha
|
|
ext dirsload
|
|
ext dirpack
|
|
ext dirnpack
|
|
ext dirsel
|
|
ext dparam
|
|
ext fsize
|
|
ext fo0$open ; byte-oriented file output
|
|
ext fo0$close
|
|
ext f0$put
|
|
ext fo1$open
|
|
ext fo1$close
|
|
ext f1$put
|
|
ext fi1$open
|
|
ext fi1$close
|
|
ext f1$get
|
|
ext bbline ; input line editor
|
|
ext retud ; get current user and disk
|
|
ext print ; print routines
|
|
ext pstr
|
|
ext lpstr
|
|
ext lcrlf
|
|
ext caps ; capitalize char
|
|
ext cin ; console in char
|
|
ext lout ; print char
|
|
ext cout ; console out char
|
|
ext crlf ; new line
|
|
ext madc ; a as dec chars in memory
|
|
ext mhldc ; hl as dec chars in memory
|
|
ext fillb ; memory fill
|
|
ext moveb ; memory move
|
|
ext codend ; beginning of buffer area
|
|
|
|
;
|
|
; Environment Definition
|
|
;
|
|
if z3env ne 0
|
|
;
|
|
; External ZCPR3 Environment Descriptor
|
|
;
|
|
jmp start
|
|
db 'Z3ENV' ;This is a ZCPR3 Utility
|
|
db 1 ;External Environment Descriptor
|
|
z3eadr:
|
|
dw z3env
|
|
start:
|
|
lhld z3eadr ;pt to ZCPR3 environment
|
|
;
|
|
else
|
|
;
|
|
; Internal ZCPR3 Environment Descriptor
|
|
;
|
|
MACLIB Z3BASE.LIB
|
|
MACLIB SYSENV.LIB
|
|
z3eadr:
|
|
jmp start
|
|
SYSENV
|
|
start:
|
|
lxi h,z3eadr ;pt to ZCPR3 environment
|
|
endif
|
|
|
|
;
|
|
; Start of Program -- Initialize ZCPR3 Environment
|
|
;
|
|
call z3init ;initialize the ZCPR3 Env and the VLIB Env
|
|
jmp start0
|
|
;
|
|
; Other Buffers (Set by GENINS)
|
|
;
|
|
igrp: db 0ffh ; Group by file type and name
|
|
ifmt: db 0 ; vertical format
|
|
iatt: db 10000000b ; Non-System files only
|
|
iscn: db 0 ; 0=dir display, 0ffh=scan for files by default
|
|
fenab: db 0ffh ; enable F options (0=no)
|
|
lenab: db 0ffh ; enable FL option (0=no)
|
|
asenab: db 0ffh ; enable AS option (0=no)
|
|
irs: db 0ffh ; enable attribute display (0=no)
|
|
iff: db 0 ; enable form feed at end (0=no)
|
|
|
|
;
|
|
; Command Line Option Table
|
|
;
|
|
optab:
|
|
db 'A'
|
|
dw opta
|
|
db 'D'
|
|
dw optd
|
|
db 'F'
|
|
dw optf
|
|
db 'I'
|
|
dw opti
|
|
db 'N'
|
|
dw optn
|
|
db 'O'
|
|
dw opto
|
|
db 'P'
|
|
dw optp
|
|
db 'U'
|
|
dw optu
|
|
db 0
|
|
|
|
;
|
|
; **** Start of XDIR III ****
|
|
;
|
|
start0:
|
|
|
|
;
|
|
; Save stack ptr for return later
|
|
;
|
|
lxi h,0 ; get stack
|
|
dad sp
|
|
shld stack ; save stack ptr for return
|
|
call codend ; determine free space (CODEND also pts to Command
|
|
; Line Save Area)
|
|
lxi d,100h ; block size to save
|
|
dad d
|
|
dad d ; allow for 256-byte stack
|
|
shld buffer ; start of free buffer area
|
|
sphl ; set stack ptr
|
|
|
|
;
|
|
; Save command line in CMDLNE buffer
|
|
;
|
|
call codend ; pt to command line buffer
|
|
xchg ; ... in DE
|
|
lxi h,buff+1 ; copy input line into command line buffer
|
|
start1:
|
|
mov a,m ; get byte
|
|
stax d ; put byte
|
|
inx h ; pt to next
|
|
inx d
|
|
ora a ; end of line?
|
|
jnz start1
|
|
|
|
;
|
|
; Get and save current user number
|
|
;
|
|
noext:
|
|
call retud ; get current user and disk
|
|
mov a,b ; get disk into A
|
|
sta curdisk ; current disk number
|
|
mov a,c ; set current user
|
|
sta curuser
|
|
|
|
;
|
|
; Log into DU or DIR
|
|
;
|
|
lxi d,fcb ; use data determined by ZCPR3
|
|
call z3log ; ZCPR3 command line interpretation
|
|
call retud ; get current user and disk
|
|
mov a,c ; set current user
|
|
sta aflg
|
|
mov a,b ; set disk
|
|
sta disk
|
|
|
|
;
|
|
; Set flag values
|
|
;
|
|
lda irs ; get RS display option
|
|
sta rsflg ; set RS display option
|
|
lda iff ; get form feed option
|
|
sta ffflg ; set form feed option
|
|
lda igrp ; set grouping (file name/type or type/name)
|
|
sta gflg
|
|
lda ifmt ; set listing format (vertical or horizontal, 0=vert)
|
|
sta hflg
|
|
lda iatt ; set file attributes
|
|
mov c,a ; save in c
|
|
lda aflg ; get current user number
|
|
ora c ; mask in file attributes
|
|
sta aflg ; save flag
|
|
lda iscn ; set initial function (Scan or Dir)
|
|
sta fflg
|
|
xra a ; A=0
|
|
sta nflg ; set no negation
|
|
sta dflg ; set no disk output
|
|
sta pflg ; set no printer output
|
|
sta iflg ; set no file name inspection (for /FP)
|
|
|
|
;
|
|
; Assume wild file name
|
|
;
|
|
lxi h,fcb+1 ; store '?' chars
|
|
mvi b,11 ; 11 chars
|
|
mov a,m ; check for entry specified
|
|
cpi ' ' ; test for space (means no entry)
|
|
mvi a,'?' ; prepare for '?' fill
|
|
cz fillb
|
|
mov a,m ; check for option caught
|
|
cpi optch ; test for option flag
|
|
mvi a,'?' ; prepare for '?' fill
|
|
cz fillb
|
|
|
|
;
|
|
; Scan command line for options
|
|
;
|
|
call codend ; pt to first char
|
|
call sblank ; skip over blanks
|
|
ora a ; end of line?
|
|
jz xdir ; begin main processing
|
|
inx h ; prep for invalid option
|
|
cpi optch ; option?
|
|
jz opt ; process options
|
|
dcx h ; ok to process for dir:filename.typ form
|
|
;
|
|
; skip over character of file name
|
|
;
|
|
skipo1:
|
|
mov a,m ; get char
|
|
inx h ; pt to next
|
|
cpi ' '
|
|
jz skipo2
|
|
ora a
|
|
jnz skipo1
|
|
jmp xdir ; run XDIR if no options follow
|
|
;
|
|
; Scan complete -- look for possible following option char
|
|
;
|
|
skipo2:
|
|
call sblank ; skip over blanks
|
|
mov a,m ; option char follows?
|
|
cpi optch
|
|
jnz opt
|
|
inx h ; skip over option char
|
|
;
|
|
; Look for options -- main loop; HL pts to next char
|
|
;
|
|
opt:
|
|
mov a,m ; get option char
|
|
inx h ; pt to next
|
|
ora a ; end of line?
|
|
jz xdir ; begin main processing
|
|
cpi ' ' ; skip over spaces
|
|
jz opt
|
|
cpi optch ; option char?
|
|
jz opterr ; loop back if so
|
|
lxi d,optab ; pt to option table
|
|
mov b,a ; option char in b
|
|
;
|
|
; Scan option table
|
|
;
|
|
opt1:
|
|
ldax d ; get option table char
|
|
ora a ; end of table?
|
|
jz opterr ; invalid option error
|
|
cmp b ; compare to passed option
|
|
jz opt2 ; process if match
|
|
inx d ; skip address
|
|
inx d
|
|
inx d ; pt to next opt char
|
|
jmp opt1
|
|
;
|
|
; Process option found
|
|
;
|
|
opt2:
|
|
inx d ; pt to low-order address
|
|
ldax d ; get it
|
|
mov c,a ; low in C
|
|
inx d ; pt to high-order address
|
|
ldax d ; get it
|
|
mov b,a ; high in B
|
|
push b ; BC on stack
|
|
ret ; Process option routine
|
|
;
|
|
; Option A -- File Attributes
|
|
;
|
|
opta:
|
|
mov a,m ; get next option letter
|
|
cpi 'N' ; Non-System files?
|
|
jz optan
|
|
cpi 'S' ; System files?
|
|
jz optas
|
|
cpi 'A' ; All files?
|
|
jnz opterr ; error if not
|
|
;
|
|
; Option AA -- All Files
|
|
;
|
|
optaa:
|
|
lda asenab ; enable system files?
|
|
ora a ; 0=no
|
|
jz optan
|
|
mvi c,11000000b ; System and Non-system
|
|
optaret:
|
|
lda aflg ; get flag
|
|
ani 3fh ; leave in user selection
|
|
ora c ; mask in sys/non-sys
|
|
sta aflg ; restore flag
|
|
inx h ; pt to next
|
|
jmp opt
|
|
;
|
|
; Option AS -- System Files
|
|
;
|
|
optas:
|
|
lda asenab ; enable system files?
|
|
ora a ; 0=no
|
|
jz optan
|
|
mvi c,01000000b ; System Only
|
|
jmp optaret
|
|
;
|
|
; Option AN -- Non-System Files
|
|
;
|
|
optan:
|
|
mvi c,10000000b ; Non-system Only
|
|
jmp optaret
|
|
|
|
;
|
|
; Option F - select file name buffer functions
|
|
;
|
|
optf:
|
|
mvi a,0ffh ; set flag
|
|
sta fflg
|
|
mov a,m ; get option char
|
|
sta fopt
|
|
cpi 'L' ; log file names to disk
|
|
jz optfok
|
|
cpi 'P' ; print names of files
|
|
jz optfok
|
|
cpi 'S' ; scan disk for files
|
|
jz optfok
|
|
jmp opterr ; error otherwise
|
|
optfok:
|
|
inx h ; pt to next option letter
|
|
jmp opt
|
|
|
|
;
|
|
; Option I -- enable it; inspect for FL option only
|
|
;
|
|
opti:
|
|
mvi a,0ffh ; ON
|
|
sta iflg
|
|
jmp opt
|
|
|
|
;
|
|
; Option D -- enable it; Disk output
|
|
;
|
|
optd:
|
|
mvi a,0ffh ; ON
|
|
sta dflg
|
|
jmp opt
|
|
|
|
;
|
|
; Option P -- enable it; Printer output
|
|
;
|
|
optp:
|
|
mvi a,0ffh ; ON
|
|
sta pflg
|
|
mov a,m ; get possible 2nd letter
|
|
cpi 'F' ; set form feed if F
|
|
jnz opt ; process as next option letter if not F
|
|
inx h ; pt to next
|
|
jmp optof
|
|
|
|
;
|
|
; Option O -- control Output parameters
|
|
;
|
|
opto:
|
|
mov a,m ; get 2nd letter
|
|
inx h ; pt to next
|
|
cpi 'A' ; attributes?
|
|
jz optoa
|
|
cpi 'F' ; form feed?
|
|
jz optof
|
|
cpi 'G' ; grouping?
|
|
jz optog
|
|
cpi 'H' ; horizontal/vertical?
|
|
jz optoh
|
|
dcx h ; adjust back
|
|
jmp opterr
|
|
;
|
|
; Toggle File Attributes Flag
|
|
;
|
|
optoa:
|
|
lda rsflg ; flip flag
|
|
cma
|
|
sta rsflg
|
|
jmp opt
|
|
;
|
|
; Toggle Form Feed Flag
|
|
;
|
|
optof:
|
|
lda ffflg ; flip flag
|
|
cma
|
|
sta ffflg
|
|
jmp opt
|
|
;
|
|
; Toggle Grouping
|
|
;
|
|
optog:
|
|
lda gflg ; flip flag
|
|
cma
|
|
sta gflg ; 0=file name and type
|
|
jmp opt
|
|
;
|
|
; Toggle Horizontal/Vertical Listing
|
|
;
|
|
optoh:
|
|
lda hflg ; flip flag
|
|
cma
|
|
sta hflg ; 0=vertical
|
|
jmp opt
|
|
|
|
;
|
|
; Option N -- enable it; Negate Selection
|
|
;
|
|
optn:
|
|
mvi a,0ffh ; ON
|
|
sta nflg
|
|
jmp opt
|
|
|
|
;
|
|
; Option U - enable it; Select All User Areas
|
|
;
|
|
optu:
|
|
lda aflg ; get current attributes flag
|
|
ori 20h ; select all user areas
|
|
sta aflg ; put flag back
|
|
jmp opt
|
|
|
|
;
|
|
; Option error message
|
|
;
|
|
opterr:
|
|
xra a ; set no disk or printer output
|
|
sta dflg
|
|
sta pflg
|
|
call banner ; print banner
|
|
call print
|
|
db cr,lf,'Syntax:'
|
|
db cr,lf,' XDIR dir:filename.typ ooo...'
|
|
db cr,lf,'or XDIR /oooo...'
|
|
db cr,lf,'Options:'
|
|
db cr,lf,' Aa - File Attributes'
|
|
db cr,lf,' a=S for System, a=N for Non-System'
|
|
db cr,lf,' a=A for All Files (System and Non-System)'
|
|
db cr,lf,' D - Send Output to Disk File XDIR.DIR'
|
|
db cr,lf,' Ff - Enable a File Buffer Function'
|
|
db cr,lf,' f=L for Log Names to FNAMES.DIR'
|
|
db cr,lf,' f=P to Print Names stored in FNAMES.DIR'
|
|
db cr,lf,' f=S to Scan Disk and Compare to FNAMES.DIR'
|
|
db cr,lf,' I - Inspect Logged Files (FL Option Only)'
|
|
db cr,lf,' N - Negate Selection'
|
|
db cr,lf,' Oo - Toggle Output Features'
|
|
db cr,lf,' o=A for File Attributes, o=F for Form Feed'
|
|
db cr,lf,' o=G for Grouping, o=H for Horiz/Vert Format'
|
|
db cr,lf,' P - Send Display to Printer'
|
|
db cr,lf,' PF - Same as POF'
|
|
db cr,lf,' U - Select All User Areas'
|
|
db 0
|
|
|
|
;
|
|
; Return to CP/M
|
|
;
|
|
return:
|
|
lda dflg ; disk output?
|
|
ora a ; 0=no
|
|
cnz fo0$close ; close file if so
|
|
lhld stack ; get old stack ptr
|
|
sphl
|
|
ret ; return to CP/M
|
|
|
|
;
|
|
; Memory Overflow Error
|
|
;
|
|
memerr:
|
|
call printx
|
|
db cr,lf,'TPA Error',0
|
|
jmp return
|
|
|
|
;
|
|
; Print banner of XDIR III
|
|
;
|
|
banner:
|
|
call printx
|
|
db 'XDIR III, Version '
|
|
db vers/10+'0','.',(vers mod 10)+'0',0
|
|
ret
|
|
|
|
;
|
|
; Begin XDIR III processing
|
|
;
|
|
xdir:
|
|
|
|
;
|
|
; This section disables the /Ff option and /FL option if default set
|
|
;
|
|
lda fenab ; enable FFLG? (/Ff option)
|
|
ora a ; 0=no
|
|
jnz xdst1
|
|
xra a ; turn off FFLG
|
|
sta fflg
|
|
xdst1:
|
|
lda lenab ; enable FL option?
|
|
ora a ; 0=no
|
|
jnz xdst2
|
|
lda fflg ; FFLG on?
|
|
ora a ; 0=no
|
|
jz xdst2
|
|
lda fopt ; check for L
|
|
cpi 'L'
|
|
jnz xdst2
|
|
mvi a,'P' ; switch L to P
|
|
sta fopt
|
|
xdst2:
|
|
lda fflg ; file name buffer option?
|
|
ora a ; 0=no
|
|
jz xdirst
|
|
xra a ; A=0
|
|
sta gflg ; group by file name and type
|
|
lda fopt ; print immediately if P option
|
|
cpi 'P' ; print?
|
|
jnz xdirst
|
|
call banner ; print banner
|
|
jmp xdirfp ; print file names
|
|
|
|
; Check for Print Option and Ask for and Print Header if so
|
|
xdirst:
|
|
lda pflg ; printer output?
|
|
ora a ; 0=no
|
|
jz xdirgo
|
|
call print ; message to user
|
|
db cr,lf,'Please Input Header: ',0
|
|
xra a ; no caps
|
|
call bbline ; input line from user
|
|
ora a ; no chars?
|
|
jz xdirgo
|
|
call lcrlf ; new line
|
|
call lpstr ; print header line
|
|
call lcrlf ; new line
|
|
|
|
; Get Files from Disk
|
|
xdirgo:
|
|
lhld buffer ; end of code
|
|
call dbuffer ; set buffers
|
|
jz memerr ; memory overflow error?
|
|
push h ; save regs
|
|
push d
|
|
call dfree ; compute amount of free space on disk
|
|
xchg ; amount in hl
|
|
shld freesiz ; save free space count
|
|
pop d ; get regs
|
|
pop h
|
|
call dirsload ; load with sizing information
|
|
jz memerr ; memory overflow error?
|
|
push h ; save hl
|
|
mov h,b ; HL=number of files loaded
|
|
mov l,c
|
|
shld totfil ; save total count
|
|
push b ; save bc
|
|
lda curdisk ; prepare to relog in disk
|
|
mov e,a
|
|
mvi c,14 ; select disk
|
|
call bdos
|
|
lda curuser ; prepare to relog in user
|
|
mov e,a
|
|
mvi c,32 ; select user
|
|
call bdos
|
|
|
|
; Open disk file if necessary for disk output
|
|
lda dflg ; disk output?
|
|
ora a ; 0=no
|
|
jz xdir0
|
|
lxi d,dskfcb ; open disk file for char output
|
|
call fo0$open ; open file for output
|
|
xdir0:
|
|
pop b ; get count
|
|
pop h ; get ptr
|
|
|
|
; Continue processing; select desired files
|
|
lda aflg ; get file attributes
|
|
lxi d,fcb ; get ptr to fcb
|
|
call dirsel ; select files
|
|
|
|
; Now, pack and alphabetize directory
|
|
lda nflg ; negate selection?
|
|
ora a ; 0=no
|
|
cz dirpack ; select marked entries
|
|
cnz dirnpack ; select unmarked entries
|
|
lda gflg ; get grouping flag
|
|
call diralpha ; alphabetize directory
|
|
shld firstf ; save ptr to first file
|
|
mov h,b ; HL=file count
|
|
mov l,c
|
|
shld fcount ; save file count
|
|
shld countf ; save file down count
|
|
lxi h,0 ; set file size counter
|
|
shld totsiz ; save counter
|
|
lda dflg ; set temp flags
|
|
sta dflgt
|
|
lda pflg
|
|
sta pflgt
|
|
|
|
;
|
|
; Major feature selection --
|
|
; Two major features of XDIR are selected at this time:
|
|
; 1. Directory Display Functions
|
|
; 2. File Name Buffer Functions
|
|
; At this point, the following key values are know:
|
|
; FIRSTF - Pointer to First File
|
|
; FCOUNT, COUNTF - Number of Files
|
|
;
|
|
lda fflg ; get flag
|
|
ora a ; Z=Directory Display, NZ=File Name Buffer Fcts
|
|
jnz xdirf ; Do File Name Buffer Fcts
|
|
|
|
;
|
|
; Main Directory Print Routine -- This routine displays the directory to
|
|
; the console, printer, or disk as desired
|
|
;
|
|
; Print header lines and one screen of entries
|
|
xdir2:
|
|
lda dflg ; save disk and print output flags
|
|
sta dflgs
|
|
lda pflg
|
|
sta pflgs
|
|
lda dflgt ; use temp flags
|
|
sta dflg
|
|
lda pflgt
|
|
sta pflg
|
|
xra a ; A=0
|
|
sta dflgt ; clear temp flags so no banner 2nd time around
|
|
sta pflgt
|
|
|
|
; Print: Main Banner
|
|
call banner ; print banner
|
|
|
|
; Print: Horizontal/Vertical Listing Message
|
|
call printx
|
|
db ' ',0
|
|
lda hflg ; get horizontal/vertical flag
|
|
ora a ; 0=vertical
|
|
jnz xdir2a
|
|
call printx
|
|
db 'Vertical',0
|
|
jmp xdir3
|
|
xdir2a:
|
|
call printx
|
|
db 'Horizontal',0
|
|
|
|
; Print: Listing by File Name and Type or Type and Name Message
|
|
xdir3:
|
|
call printx
|
|
db ' Listing by File ',0
|
|
lda gflg ; grouping flag
|
|
ora a ; 0=name and type
|
|
jnz xdir3a
|
|
call printx
|
|
db 'Name/Type',0
|
|
jmp xdir4
|
|
xdir3a:
|
|
call printx
|
|
db 'Type/Name',0
|
|
|
|
;
|
|
; Print: Disk and User
|
|
;
|
|
xdir4:
|
|
call printx ; print everywhere
|
|
db cr,lf,' Disk: ',0
|
|
lda disk ; get current disk
|
|
adi 'A' ; convert to ASCII
|
|
call coutx ; print everywhere
|
|
call printx ; print everywhere
|
|
db ' User: ',0
|
|
lda aflg ; get user number
|
|
ani 20h ; all?
|
|
jz xdir4b
|
|
call printx
|
|
db 'All',0
|
|
jmp xdir5
|
|
xdir4b:
|
|
lda aflg ; get selected user
|
|
ani 1fh ; select user number
|
|
lxi d,numbuf ; store number in buffer
|
|
call madc ; get number
|
|
mvi b,3 ; 3 digits
|
|
call prnumx ; print number everywhere
|
|
|
|
;
|
|
; Print: Directory Name
|
|
;
|
|
xdir5:
|
|
lda aflg ; check for all users
|
|
mov c,a ; save in C
|
|
ani 20h
|
|
jnz xdir5fa
|
|
mov a,c ; get user
|
|
ani 1fh ; mask for just user
|
|
mov c,a
|
|
lda disk ; select disk
|
|
mov b,a
|
|
call dutdir ; determine if name available
|
|
jz xdir5fa
|
|
call printx
|
|
db ' Name: ',0
|
|
mvi b,8 ; 8 chars to name
|
|
xdir5n:
|
|
mov a,m ; get char
|
|
inx h ; pt to next
|
|
cpi ' ' ; don't print spaces
|
|
cnz coutx
|
|
dcr b ; count down
|
|
jnz xdir5n
|
|
;
|
|
; Print: Selected File Attributes
|
|
;
|
|
xdir5fa:
|
|
call printx
|
|
db ', File Attributes: ',0
|
|
lda aflg ; get flag
|
|
push psw ; save A
|
|
ani 80h ; Non-system?
|
|
jz xdir5a
|
|
call printx
|
|
db ' Non-System',0
|
|
xdir5a:
|
|
pop psw ; get A
|
|
ani 40h ; System?
|
|
jz xdir5b
|
|
call printx
|
|
db ' System',0
|
|
|
|
; See if any files selected
|
|
xdir5b:
|
|
lhld countf ; get file down count
|
|
mov a,h ; any files?
|
|
ora l
|
|
jnz xdir6
|
|
call printx ; print everywhere
|
|
db cr,lf,'No files selected -- ',0
|
|
jmp xdir11
|
|
|
|
;
|
|
; This is the main looping entry point for each screen display
|
|
;
|
|
xdir6:
|
|
lda aflg ; all users selected?
|
|
ani 20h
|
|
jnz xdir6a
|
|
;
|
|
; This is the header which is printed if the files in only one user area are
|
|
; displayed
|
|
;
|
|
call crlfx ; new line
|
|
call hdr2 ; pt to header
|
|
lda rsflg
|
|
ora a ; Z=no
|
|
cnz sp0 ; print RS
|
|
call sp2 ; print leading spaces
|
|
call hdr2 ; print header
|
|
lda rsflg
|
|
ora a ; Z=no
|
|
cnz sp0 ; print RS
|
|
call sp2 ; print leading spaces
|
|
call hdr2 ; print header
|
|
lda rsflg
|
|
ora a
|
|
cnz sp0
|
|
call crlfx ; new line
|
|
call hdr1 ; print underlines
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
call sp2 ; leading spaces
|
|
call hdr1 ; underlines
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
call sp2 ; leading spaces
|
|
call hdr1 ; underlines
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
jmp xdir6b
|
|
;
|
|
; General-Purpose Header Print Routines
|
|
;
|
|
sp0:
|
|
call printx
|
|
db ' RS',0
|
|
ret
|
|
sp1:
|
|
call printx
|
|
db ' --',0
|
|
ret
|
|
sp2:
|
|
call printx
|
|
db ' ',0
|
|
ret
|
|
spu:
|
|
call printx
|
|
db ' U ',0
|
|
ret
|
|
spu1:
|
|
call printx
|
|
db ' ',0
|
|
ret
|
|
spu2:
|
|
call printx
|
|
db ' - ',0
|
|
ret
|
|
hdr1:
|
|
call printx
|
|
db '-------- --- ------',0
|
|
ret
|
|
hdr2:
|
|
call printx
|
|
db 'Filename.Typ Size K',0
|
|
ret
|
|
;
|
|
; This is the header which is printed if the files in all user areas are
|
|
; displayed
|
|
;
|
|
xdir6a:
|
|
call crlfx
|
|
call spu ; print U
|
|
call hdr2 ; print header
|
|
lda rsflg
|
|
ora a
|
|
cnz sp0 ; RS
|
|
call spu1
|
|
call spu ; print U
|
|
call hdr2 ; print header
|
|
lda rsflg
|
|
ora a
|
|
cnz sp0 ; RS
|
|
call spu1
|
|
call spu ; print U
|
|
call hdr2 ; print header
|
|
lda rsflg
|
|
ora a
|
|
cnz sp0 ; RS
|
|
call crlfx
|
|
call spu2 ; 1 underscore
|
|
call hdr1 ; underscores
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
call spu1
|
|
call spu2 ; 1 underscore
|
|
call hdr1 ; underscores
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
call spu1
|
|
call spu2 ; 1 underscore
|
|
call hdr1 ; underscores
|
|
lda rsflg
|
|
ora a
|
|
cnz sp1
|
|
|
|
;
|
|
; Prepare Columnar Output
|
|
;
|
|
xdir6b:
|
|
lda dflgs ; restore disk and print flags
|
|
sta dflg
|
|
lda pflgs
|
|
sta pflg
|
|
lhld countf ; get file count down
|
|
lxi d,maxent ; assume maxent entries to print
|
|
mov a,h ; within range?
|
|
ora a ; outside of range if not
|
|
jnz xdir7 ; subtract entries to print from total entries
|
|
mov a,l ; within range?
|
|
cpi maxent ; less than maxent entries left?
|
|
jnc xdir7 ; subtract entries to print from total entries
|
|
mov d,h ; DE=HL=number of entries to print
|
|
mov e,l
|
|
xdir7:
|
|
mov a,l ; subtract entries to print (DE) from total (HL)
|
|
sub e
|
|
mov l,a
|
|
mov a,h
|
|
sbb d
|
|
mov h,a ; HL=result
|
|
shld countf ; save new down count
|
|
mov b,h ; BC=count
|
|
mov c,l
|
|
lhld firstf ; pt to first file
|
|
;
|
|
; At this point, BC=number of remaining entries, DE=number of entries to
|
|
; print, and HL pts to first entry to print
|
|
;
|
|
shld ptr1 ; save ptr to 1st entry
|
|
lda hflg ; horizontal listing?
|
|
ora a ; 0ffh = yes
|
|
jnz xdir7c ; don't worry about columns if horizontal
|
|
push d ; save count
|
|
call divde3 ; divide DE by 3, result*esize in BC, remainder in A
|
|
lxi d,esize ; DE=ESIZE (size of entry)
|
|
dad b ; add BC as a minimum
|
|
ora a ; any remainder?
|
|
jz xdir7a ; skip if none
|
|
dad d ; add in ESIZE for additional length of 1st col
|
|
xdir7a:
|
|
shld ptr2 ; save ptr to col 2
|
|
dad b ; add BC as a minimum
|
|
cpi 2 ; if remainder 2, add ESIZE for additional
|
|
jc xdir7b
|
|
dad d ; add in ESIZE
|
|
xdir7b:
|
|
shld ptr3 ; save ptr to col 3
|
|
pop d ; get count in de
|
|
;
|
|
; Main entry print routine
|
|
;
|
|
xdir7c:
|
|
mvi d,1 ; set 3's counter
|
|
xdir8:
|
|
lhld ptr1 ; pt to first entry
|
|
call prentry ; print entry
|
|
shld ptr1 ; put ptr
|
|
lda hflg ; horizontal?
|
|
ora a ; 0ffh = yes
|
|
jnz xdir9
|
|
dcr e ; count down
|
|
jz xdir10
|
|
lhld ptr2 ; get ptr
|
|
call prentry ; print entry
|
|
shld ptr2 ; put ptr
|
|
dcr e ; count down
|
|
jz xdir10
|
|
lhld ptr3 ; get ptr
|
|
call prentry ; print entry
|
|
shld ptr3 ; put ptr
|
|
xdir9:
|
|
dcr e ; count down
|
|
jnz xdir8 ; continue if not zero
|
|
shld firstf ; save ptr to first of next set of entries to print
|
|
lhld countf ; get count of remaining entries
|
|
;
|
|
; At this point, HL=number of entries left
|
|
;
|
|
mov a,h ; anything left?
|
|
ora l
|
|
jz xdir10
|
|
lda dflg ; no message if disk or printer output
|
|
mov b,a
|
|
lda pflg
|
|
ora b
|
|
jnz xdir6
|
|
call print ; screen break
|
|
db cr,lf,' --> Screen Break -- Strike any char <-- ',0
|
|
call cin ; get response
|
|
cpi ctrlc ; abort?
|
|
jz return
|
|
jmp xdir6 ; new screen display
|
|
;
|
|
; Print end statistics and exit
|
|
;
|
|
xdir10:
|
|
call crlfx ; new line
|
|
lhld fcount ; print file count
|
|
call prhlx ; print it everywhere
|
|
call printx
|
|
db ' Files Using ',0
|
|
lhld totsiz ; get total of file sizes
|
|
call prhlx ; print it everywhere
|
|
call printx
|
|
db 'K, ',0
|
|
lhld totfil ; print total file count
|
|
call prhlx ; print it everywhere
|
|
call printx
|
|
db ' Files on Disk and ',0
|
|
|
|
;
|
|
; Print Amount of Free Space Left on Disk
|
|
; Entry Point if No Files Found
|
|
;
|
|
xdir11:
|
|
lhld freesiz ; get amount of free space
|
|
call prhlx ; print it everywhere
|
|
call printx
|
|
db 'K Left',0
|
|
lda dflg ; if disk or printer output, new line
|
|
mov b,a
|
|
lda pflg
|
|
ora b
|
|
jz return
|
|
call crlfx ; new line for disk and/or printer
|
|
lda pflg ; print output
|
|
mov b,a
|
|
lda ffflg ; form feed
|
|
ana b ; if print and form feed ... NZ is set
|
|
mvi a,ff ; form feed char
|
|
cnz lout ; form feed to printer
|
|
jmp return
|
|
|
|
;
|
|
; File Name Buffer Functions
|
|
;
|
|
xdirf:
|
|
call banner ; print banner
|
|
lda iscn ; just scan?
|
|
ora a ; 0=no
|
|
jnz xdirfs
|
|
lda fopt ; get option of F command
|
|
cpi 'L' ; log names to disk?
|
|
jz xdirfl
|
|
cpi 'S' ; scan names on disk?
|
|
jz xdirfs
|
|
;
|
|
; File Name Print Option; /FP option
|
|
;
|
|
xdirfp:
|
|
call openin ; open FNAMES.DIR for input
|
|
xdfp0:
|
|
call printx
|
|
db cr,lf,cr,lf
|
|
db 'Printout of Recorded File Names --',cr,lf,' ',0
|
|
;
|
|
; Extract File Name Count
|
|
;
|
|
call f1$get ; get low count
|
|
jnz geterr
|
|
mov l,a ; save in L
|
|
call f1$get ; get high count
|
|
jnz geterr
|
|
mov h,a ; save in H
|
|
push h ; save HL
|
|
call prhlx ; print HL everywhere
|
|
call printx
|
|
db ' File Names',cr,lf,0
|
|
call prfhdr ; print file name header
|
|
pop h ; get HL
|
|
mvi c,0 ; set entry counter
|
|
|
|
;
|
|
; Loop for extracting names from FNAMES.DIR and printing them
|
|
;
|
|
xdfp1:
|
|
mov a,h ; no more entries?
|
|
ora l
|
|
jz xdfp2
|
|
dcx h ; count down
|
|
call getdfn ; get next disk file name from FNAMES.DIR
|
|
call prfnfx ; print file name entry
|
|
inr c ; increment count
|
|
mov a,c ; new line time?
|
|
ani 3
|
|
cz crlfx
|
|
jmp xdfp1
|
|
xdfp2:
|
|
call fi1$close
|
|
call crlfx ; new line
|
|
jmp return
|
|
|
|
;
|
|
; Log File Names to Disk; /FL option
|
|
; Structure of FNAMES.DIR file is:
|
|
; File Name Count, Low-Order Byte
|
|
; File Name Count, High-Order Byte
|
|
; File Names, stored as 12 bytes -- User Number, FN, and FT
|
|
;
|
|
xdirfl:
|
|
lxi d,fnfcb ; open file for output
|
|
call fo1$open
|
|
jz xdfl1
|
|
call printx
|
|
db cr,lf,'Cannot Create FNAMES.DIR',0
|
|
jmp return
|
|
|
|
; Log Files to Disk with possible initial inspect and select by user
|
|
xdfl1:
|
|
lda iflg ; inspect?
|
|
ora a ; 0=no
|
|
cnz flinsp ; inspect if selected
|
|
|
|
; Print file count
|
|
call printx
|
|
db cr,lf,cr,lf
|
|
db 'Logging File Names to Disk --',cr,lf,' ',0
|
|
lhld fcount ; get count
|
|
call prhlx ; print it
|
|
call printx
|
|
db ' File Names',cr,lf,0
|
|
|
|
; Check file count and print appropriate header
|
|
lhld fcount ; get number of files
|
|
mov a,h ; any files?
|
|
ora l
|
|
jz xdfl1a
|
|
call prfhdr ; print file name header
|
|
jmp xdfl1b
|
|
xdfl1a:
|
|
call printx ; no files
|
|
db ' No Files to be Logged',0
|
|
|
|
; Store file count to disk
|
|
xdfl1b:
|
|
mov a,l ; store low count
|
|
call f1$put
|
|
jnz puterr
|
|
mov a,h ; store high count
|
|
call f1$put
|
|
jnz puterr
|
|
xchg ; ... in DE
|
|
lhld firstf ; pt to first file
|
|
mvi c,0 ; set display counter
|
|
|
|
; Loop to store files names
|
|
xdfl2:
|
|
mov a,d ; done?
|
|
ora e
|
|
jz xdfl3
|
|
dcx d ; count down
|
|
|
|
; Write entry to disk
|
|
push d ; save count
|
|
push h ; save ptr to file
|
|
mov a,m ; get user number
|
|
call f1$put ; save it
|
|
jnz puterr
|
|
lxi d,numbuf ; print user number
|
|
push d ; save ptr
|
|
call madc
|
|
pop d ; get ptr
|
|
inx d ; pt to 1st digit
|
|
ldax d ; get it
|
|
call coutx
|
|
inx d ; pt to last digit
|
|
ldax d ; get it
|
|
call coutx
|
|
mvi a,' ' ; <SP>
|
|
call coutx
|
|
inx h ; pt to FN
|
|
mvi b,8 ; 8 chars
|
|
call xdput
|
|
mvi a,'.'
|
|
call coutx
|
|
mvi b,3 ; 3 chars
|
|
call xdput
|
|
mvi a,' ' ; print <SP>
|
|
call coutx
|
|
call coutx
|
|
inr c ; increment count
|
|
mov a,c ; get count
|
|
ani 3
|
|
cz crlfx
|
|
pop h ; get ptr to first file
|
|
pop d ; get count
|
|
push b
|
|
lxi b,esize ; pt to next file
|
|
dad b
|
|
pop b
|
|
jmp xdfl2
|
|
|
|
; Done with creation of FNAMES.DIR
|
|
xdfl3:
|
|
call fo1$close ; close file
|
|
call crlfx
|
|
jmp return
|
|
|
|
; Write B chars pted to by HL to FNAMES.DIR and user
|
|
xdput:
|
|
mov a,m ; get char
|
|
call coutx ; print it everywhere
|
|
call f1$put ; put it on disk
|
|
jnz puterr
|
|
inx h ; pt to next
|
|
dcr b ; count down
|
|
jnz xdput
|
|
ret
|
|
|
|
;
|
|
; Inspect Files for Logging to Disk
|
|
;
|
|
flinsp:
|
|
lhld fcount ; get count of files
|
|
xchg ; ... in DE
|
|
mov a,d ; any files selected?
|
|
ora e
|
|
rz ; abort if none
|
|
|
|
; Inspection banner
|
|
call printx
|
|
db cr,lf,'Inspection of Files to be Logged',0
|
|
lhld firstf ; pt to first file
|
|
|
|
; Main inspection loop
|
|
flil1:
|
|
mov a,d ; any files selected?
|
|
ora e
|
|
jz flil3 ; done if not
|
|
dcx d ; count down
|
|
push d ; save count
|
|
lxi d,dfnbuf ; copy file name to buffer
|
|
mvi b,12 ; 12 bytes
|
|
call moveb
|
|
call printx
|
|
db cr,lf,'Log ',0
|
|
call prfnfx ; print file name for prompt
|
|
call printx
|
|
db ' to Disk (Y/N)? ',0
|
|
call cin ; get response
|
|
call caps ; capitalize
|
|
call coutx
|
|
cpi 'N' ; No?
|
|
jz flil2
|
|
mov a,m ; mark user number
|
|
ori 80h
|
|
mov m,a
|
|
flil2:
|
|
lxi d,esize ; skip to next entry
|
|
dad d
|
|
pop d ; get count
|
|
jmp flil1
|
|
flil3:
|
|
lhld fcount ; get number of files
|
|
mov b,h ; count in BC
|
|
mov c,l
|
|
lhld firstf ; pt to first file
|
|
call dirpack ; pack directory
|
|
mov h,b ; new count in HL
|
|
mov l,c
|
|
shld fcount ; set counts
|
|
shld countf
|
|
ret
|
|
|
|
;
|
|
; Error Message for Output
|
|
;
|
|
puterr:
|
|
call printx
|
|
db cr,lf,'Disk Write Error',0
|
|
jmp return
|
|
|
|
;
|
|
; Scan Disk for File Names; /FS option
|
|
;
|
|
xdirfs:
|
|
call printx
|
|
db cr,lf,'File Name Scanner',0
|
|
call openin ; open FNAMES.DIR for input
|
|
xdfs1:
|
|
call printx
|
|
db cr,lf,'Files Named in FNAMES.DIR missing from Disk --',cr,lf,0
|
|
|
|
; Get file name count
|
|
call f1$get ; get file name count from disk
|
|
jnz geterr
|
|
mov c,a ; store low
|
|
call f1$get
|
|
jnz geterr
|
|
mov b,a ; store high
|
|
lhld fcount ; get count of number of files
|
|
xchg ; ... in DE
|
|
lhld firstf ; pt to first file
|
|
xra a ; A=0
|
|
sta crcnt ; set counter for CRLF
|
|
sta fmark ; mark no first file yet
|
|
|
|
;
|
|
; At this point, HL pts to first file in buffer, DE is number of files in
|
|
; buffer, and BC is number of files in FNAMES.DIR
|
|
;
|
|
mov a,b ; any names in FNAMES.DIR?
|
|
ora c
|
|
jz xdfs5 ; mark all names in buffer if not
|
|
call getdfn ; get first disk name
|
|
xdfs2:
|
|
mov a,b ; see if any more files in FNAMES.DIR
|
|
ora c
|
|
jz xdfs5 ; mark rest of files in buffer and continue
|
|
mov a,d ; see if any more files in buffer
|
|
ora e
|
|
jz xdfs6 ; name rest of files in FNAMES.DIR as missing and cont
|
|
call compfn ; compare to file name pted to by HL
|
|
jz xdfs3a ; advance to next file if they match
|
|
jc xdfs3 ; mark file name pted to by HL as additional
|
|
lda fmark ; first file?
|
|
ora a ; 0=yes
|
|
jnz xdfs2a
|
|
mvi a,0ffh ; set mark
|
|
sta fmark
|
|
call prfhdr ; print header
|
|
xdfs2a:
|
|
call prfnfx ; print file name in FNAMES.DIR
|
|
dcx b ; count down
|
|
mov a,b ; done?
|
|
ora c
|
|
jz xdfs2
|
|
call getdfn ; get next name
|
|
lda crcnt ; get entry counter
|
|
inr a ; increment
|
|
sta crcnt
|
|
ani 3 ; mask
|
|
cz crlfx ; new line every 4
|
|
jmp xdfs2
|
|
xdfs3:
|
|
mov a,m ; get user number
|
|
ori 80h ; mark it
|
|
mov m,a ; put it back
|
|
jmp xdfs4
|
|
xdfs3a:
|
|
call getdfn ; get next name
|
|
dcx b ; count down on names
|
|
xdfs4:
|
|
push d ; save count
|
|
lxi d,esize ; pt to next entry
|
|
dad d
|
|
pop d ; get count
|
|
dcx d ; count down
|
|
jmp xdfs2 ; continue
|
|
|
|
; Mark rest of files in buffer
|
|
xdfs5:
|
|
mov a,d ; check count
|
|
ora e
|
|
jz xdfs7
|
|
dcx d ; count down
|
|
mov a,m ; get user number
|
|
ori 80h ; mark it
|
|
mov m,a ; put user number
|
|
lxi b,esize ; skip to next file
|
|
dad b
|
|
jmp xdfs5 ; continue
|
|
|
|
; Name rest of files in FNAMES.DIR as missing
|
|
xdfs6:
|
|
call prfnfx ; print file name in FNAMES.DIR
|
|
dcx b ; count down
|
|
mov a,b ; done?
|
|
ora c
|
|
jz xdfs7 ; next phase
|
|
lda crcnt ; get entry counter
|
|
inr a ; increment
|
|
sta crcnt
|
|
ani 3 ; mask
|
|
cz crlfx ; new line every 4
|
|
call getdfn ; get next name
|
|
jmp xdfs6
|
|
|
|
; Part 2 of Scan - Name Additional Files
|
|
xdfs7:
|
|
lda fmark ; no files printed?
|
|
ora a ; 0=none
|
|
jnz xdfs7a
|
|
call printx
|
|
db ' No Files Missing',0
|
|
xdfs7a:
|
|
xra a ; A=0
|
|
sta fmark ; set mark for 2nd part
|
|
call printx
|
|
db cr,lf,'Additional Files on Disk NOT in FNAMES.DIR --',cr,lf,0
|
|
lhld fcount ; get count of files
|
|
xchg ; ... in DE
|
|
lhld firstf ; pt to first file
|
|
xra a ; A=0
|
|
sta crcnt ; set counter
|
|
xdfs8:
|
|
mov a,d ; check count
|
|
ora e
|
|
jz xdfs9 ; done if zero
|
|
dcx d ; count down
|
|
mov a,m ; get user number
|
|
ani 80h ; marked?
|
|
jz xdfs8b ; skip if not
|
|
mov a,m ; get user number
|
|
ani 7fh ; mask
|
|
mov m,a ; replace
|
|
lda fmark ; first time?
|
|
ora a ; 0=yes
|
|
jnz xdfs8a
|
|
mvi a,0ffh ; set mark
|
|
sta fmark
|
|
call prfhdr ; print header
|
|
xdfs8a:
|
|
push d ; save count
|
|
lxi d,dfnbuf ; copy to buffer for print
|
|
mvi b,12 ; 12 bytes
|
|
call moveb ; copy
|
|
pop d
|
|
call prfnfx ; print file name
|
|
lda crcnt ; count down
|
|
inr a
|
|
sta crcnt
|
|
ani 3 ; new line?
|
|
cz crlfx
|
|
xdfs8b:
|
|
lxi b,esize ; pt to next entry
|
|
dad b
|
|
jmp xdfs8 ; continue
|
|
|
|
; Done with Scan
|
|
xdfs9:
|
|
lda fmark ; no files printed?
|
|
ora a ; 0=none
|
|
jnz xdfs9a
|
|
call printx
|
|
db ' No Additional Files',0
|
|
xdfs9a:
|
|
jmp return
|
|
|
|
;
|
|
; Compare file name pted to by HL with that in DFNBUF; return with Z if same,
|
|
; C if (HL)<(DFNBUF)
|
|
;
|
|
compfn:
|
|
push h ; save regs
|
|
push d
|
|
push b
|
|
lxi d,dfnbuf ; pt to buffer
|
|
xchg ; DE pts to file name, HL pts to DFNBUF
|
|
push h ; save ptrs
|
|
push d
|
|
mvi b,11 ; compare FN and FT
|
|
cfn1:
|
|
inx h ; pt to next
|
|
inx d
|
|
mov a,m ; get char from DFNBUF
|
|
ani 7fh ; mask MSB
|
|
mov c,a ; save in C
|
|
ldax d ; get name in memory buffer
|
|
ani 7fh ; mask MSB
|
|
cmp c ; compare to name in DFNBUF
|
|
jnz cfn2 ; not same, so exit with flag set
|
|
dcr b ; count down
|
|
jnz cfn1
|
|
pop d ; same so far, so compare user numbers
|
|
pop h
|
|
mov a,m ; get user number
|
|
ani 7fh ; mask MSB
|
|
mov c,a ; save in C
|
|
ldax d ; get user number
|
|
ani 7fh ; mask MSB
|
|
cmp c ; compare
|
|
push h ; fill stack for ext
|
|
push h
|
|
cfn2:
|
|
pop h ; clear stack
|
|
pop h
|
|
pop b ; get regs and exit
|
|
pop d
|
|
pop h
|
|
ret
|
|
|
|
;
|
|
; General Utility Routines
|
|
;
|
|
|
|
;
|
|
; Print user and file name stored in DFNBUF for /Ff functions
|
|
;
|
|
prfnfx:
|
|
push h ; save regs
|
|
push d
|
|
push b
|
|
lxi h,dfnbuf ; pt to first byte of buffer
|
|
mov a,m ; get first byte (user number)
|
|
lxi d,numbuf ; convert to chars in memory
|
|
call madc
|
|
lxi d,numbuf+1 ; pt to first char
|
|
ldax d ; get it
|
|
call coutx
|
|
inx d ; pt to 2nd char
|
|
ldax d ; get it
|
|
call coutx
|
|
mvi a,' ' ; <SP>
|
|
call coutx
|
|
inx h ; pt to FN
|
|
mvi b,8 ; 8 chars for FN
|
|
call prch
|
|
mvi a,'.'
|
|
call coutx
|
|
mvi b,3 ; 3 chars for FT
|
|
call prch
|
|
call prfhs ; 2 <sp>
|
|
pop b ; get regs
|
|
pop d
|
|
pop h
|
|
ret
|
|
;
|
|
; Get next User Number, FN, and FT from disk and save it in buffer
|
|
;
|
|
getdfn:
|
|
push h ; save regs
|
|
push d
|
|
push b
|
|
lxi h,dfnbuf ; pt to buffer
|
|
mvi b,12 ; 12 bytes
|
|
getdf1:
|
|
call f1$get ; get user
|
|
jnz geterr
|
|
mov m,a ; store user
|
|
inx h ; pt to next
|
|
dcr b ; count down
|
|
jnz getdf1
|
|
pop b ; restore regs
|
|
pop d
|
|
pop h
|
|
ret
|
|
;
|
|
; Print File Buffer Names Header Everywhere
|
|
;
|
|
prfhdr:
|
|
mvi b,3 ; 3 times
|
|
prfhd1:
|
|
call prfh1 ; print header
|
|
call prfhs ; print 2 spaces
|
|
dcr b
|
|
jnz prfhd1
|
|
call prfh1
|
|
call crlfx
|
|
mvi b,3 ; 3 times
|
|
prfhd2:
|
|
call prfh2 ; print header
|
|
call prfhs ; print 2 spaces
|
|
dcr b
|
|
jnz prfhd2
|
|
call prfh2
|
|
call crlfx
|
|
ret
|
|
prfhs:
|
|
call printx
|
|
db ' ',0
|
|
ret
|
|
prfh1:
|
|
call printx
|
|
db ' U Filename.Typ',0
|
|
ret
|
|
prfh2:
|
|
call printx
|
|
db ' - -------- ---',0
|
|
ret
|
|
;
|
|
; Get Error Message and Abort
|
|
;
|
|
geterr:
|
|
call printx
|
|
db cr,lf,'Premature EOF',0
|
|
jmp return
|
|
;
|
|
; Open FNAMES.DIR for byte-oriented input
|
|
;
|
|
openin:
|
|
lxi d,fnfcb ; open file
|
|
call fi1$open ; open for input
|
|
rz
|
|
call printx
|
|
db cr,lf,'FNAMES.DIR Not Found',0
|
|
jmp return
|
|
;
|
|
; Print disk entry for normal directory display functions
|
|
;
|
|
prentry:
|
|
dcr d ; count <CRLF> counter
|
|
jnz prent1
|
|
mvi d,3 ; reset count
|
|
call crlfx
|
|
prent1:
|
|
shld entptr ; save entry ptr
|
|
lda aflg ; all users selected?
|
|
ani 20h
|
|
jz prent2
|
|
;
|
|
; The following prints the user number if all user numbers are selected
|
|
;
|
|
push h ; save regs
|
|
push d
|
|
push b
|
|
mov a,m ; get user number
|
|
ani 1fh ; mask it
|
|
lxi d,numbuf
|
|
call madc ; convert to chars in memory
|
|
lxi h,numbuf+1 ; pt to first char
|
|
mov a,m ; get it
|
|
call coutx
|
|
inx h ; get 2nd char
|
|
mov a,m
|
|
call coutx
|
|
mvi a,' ' ; print <SP>
|
|
call coutx
|
|
pop b ; get regs
|
|
pop d
|
|
pop h
|
|
prent2:
|
|
inx h ; pt to first char of file name
|
|
mvi b,8 ; print 8 chars
|
|
call prch
|
|
mvi a,'.' ; print dot
|
|
call coutx
|
|
push h ; save RS ptr
|
|
mvi b,3 ; print 3 chars
|
|
call prch
|
|
push d ; save de
|
|
lhld entptr ; pt to entry
|
|
mvi a,' ' ; skip 2 spaces
|
|
call coutx
|
|
call coutx
|
|
call fsize ; compute file size
|
|
lhld totsiz ; get total file size counter
|
|
dad d ; add in new file
|
|
shld totsiz ; save new total file size counter
|
|
xchg ; get file size into HL
|
|
call prhlx ; print HL value
|
|
pop d ; get de
|
|
pop h ; pt to RS
|
|
lda rsflg ; print RS fields?
|
|
ora a ; Z=no
|
|
jz pren2a
|
|
mvi a,' ' ; print 1 space
|
|
call coutx
|
|
mvi b,'R' ; letter
|
|
call prletx ; print R if bit set
|
|
inx h
|
|
mvi b,'S' ; letter
|
|
call prletx ; print S if bit set
|
|
dcx h ; ... for following inx h
|
|
pren2a:
|
|
inx h ; point correctly
|
|
mvi a,' ' ; 1 space
|
|
call coutx
|
|
lda aflg ; all users?
|
|
ani 20h
|
|
jnz prent3
|
|
;
|
|
; The following prints 2 additional spaces if only one user area is selected
|
|
;
|
|
mvi a,' ' ; 2 more spaces for not all users
|
|
call coutx
|
|
call coutx
|
|
prent3:
|
|
lxi b,6 ; pt to next entry
|
|
dad b
|
|
ret
|
|
;
|
|
; Print B chars pted to by HL
|
|
;
|
|
prch:
|
|
mov a,m ; get char
|
|
inx h ; pt to next
|
|
ani 7fh ; mask out msb
|
|
cpi ' ' ; within range?
|
|
jnc prch1 ; print special char if not valid char
|
|
mvi a,'?' ; print ? if not valid char
|
|
prch1:
|
|
call coutx ; print it
|
|
dcr b ; count down
|
|
jnz prch
|
|
ret
|
|
;
|
|
; Extended Print Routines
|
|
;
|
|
prletx:
|
|
mov a,m ; get byte
|
|
ani 80h ; look at msb
|
|
jz prlets
|
|
mov a,b ; get letter
|
|
call coutx
|
|
ret
|
|
prlets:
|
|
mvi a,' ' ; print <sp>
|
|
call coutx
|
|
ret
|
|
prhlx:
|
|
lxi d,numbuf ; store in number buffer
|
|
call mhldc ; hl into memory as decimal
|
|
mvi b,5 ; 5 digits
|
|
prnumx:
|
|
lxi h,numbuf ; pt to buffer
|
|
prnum:
|
|
mov a,m ; get digit
|
|
inx h ; pt to next
|
|
call coutx ; print everywhere
|
|
dcr b ; count down
|
|
jnz prnum
|
|
ret
|
|
printx:
|
|
xthl ; pt to string
|
|
call prxl ; print string at HL
|
|
xthl
|
|
ret
|
|
prxl:
|
|
mov a,m ; get byte
|
|
inx h ; pt to next
|
|
ora a ; done?
|
|
rz
|
|
call coutx ; print everywhere
|
|
jmp prxl
|
|
coutx:
|
|
push b ; save bc
|
|
push psw ; save char
|
|
ani 7fh ; mask out msb
|
|
mov b,a ; char in B
|
|
call cout ; print to screen
|
|
lda pflg ; printer on?
|
|
ora a ; 0=no
|
|
mov a,b ; get char
|
|
cnz lout ; printer output if on
|
|
lda dflg ; disk on?
|
|
ora a ; 0=no
|
|
mov a,b ; get char
|
|
cnz f0$put ; output to file
|
|
pop psw ; get char
|
|
pop b ; get bc
|
|
ret
|
|
crlfx:
|
|
push psw ; save A
|
|
call printx
|
|
db cr,lf,0
|
|
pop psw ; get A
|
|
ret
|
|
;
|
|
; Divide DE by 3; return with BC=result*esize, a=remainder
|
|
;
|
|
divde3:
|
|
push d ; save de, hl
|
|
push h
|
|
mvi d,0 ; make sure D=0
|
|
mov a,e ; value in A
|
|
divd31:
|
|
sui 3 ; subtract 3
|
|
jc divd32
|
|
jz divd33
|
|
inr d ; add 1 to result
|
|
jmp divd31
|
|
divd32:
|
|
adi 3 ; add back in
|
|
jmp divd34
|
|
divd33:
|
|
inr d ; add 1 for even division
|
|
divd34:
|
|
sta rem ; save remainder
|
|
lxi b,esize
|
|
lxi h,0
|
|
divd35:
|
|
mov a,d ; done?
|
|
ora a ; 0=yes
|
|
jz divd36
|
|
dcr d
|
|
dad b ; add in another ESIZE
|
|
jmp divd35
|
|
divd36:
|
|
mov b,h ; BC is result
|
|
mov c,l
|
|
lda rem ; A is remainder
|
|
pop h ; restore regs
|
|
pop d
|
|
ret
|
|
;
|
|
; Skip blanks
|
|
;
|
|
sblank:
|
|
mov a,m ; pt to char
|
|
cpi ' ' ; blank?
|
|
rnz
|
|
inx h ; pt to next
|
|
jmp sblank
|
|
|
|
;
|
|
; Buffers
|
|
;
|
|
aflg: ds 1 ; attibute flag
|
|
dflg: ds 1 ; disk output on flag
|
|
fflg: ds 1 ; 0=no file name buffer function
|
|
gflg: ds 1 ; 0=group by name/type
|
|
hflg: ds 1 ; 0=vertical list
|
|
iflg: ds 1 ; 0=no inspect
|
|
nflg: ds 1 ; 0=no negate
|
|
pflg: ds 1 ; printer output on flag
|
|
fopt: ds 1 ; file name buffer option
|
|
crcnt: ds 1 ; entry counter
|
|
fmark: ds 1 ; first file marker
|
|
dflgt: ds 1 ; temp flags
|
|
pflgt: ds 1
|
|
dflgs: ds 1
|
|
pflgs: ds 1
|
|
rsflg: ds 1 ; RS Display Flag
|
|
ffflg: ds 1 ; form feed flag
|
|
disk: ds 1 ; selected disk
|
|
curdisk:
|
|
ds 1 ; current disk
|
|
curuser:
|
|
ds 1 ; current user
|
|
rem: ds 1 ; remainder buffer
|
|
firstf: ds 2 ; ptr to first file of group to print
|
|
totfil: ds 2 ; total number of files on disk
|
|
fcount: ds 2 ; count of files
|
|
countf: ds 2 ; down count of files
|
|
freesiz:
|
|
ds 2 ; amount of free space on disk
|
|
totsiz:
|
|
ds 2 ; total size of all files
|
|
ptr1: ds 2 ; col output ptrs
|
|
ptr2: ds 2
|
|
ptr3: ds 2
|
|
entptr: ds 2 ; current entry ptr
|
|
numbuf: ds 6 ; number buffer
|
|
dfnbuf:
|
|
ds 12 ; disk file name buffer
|
|
dskfcb:
|
|
db 0
|
|
db 'XDIR DIR'
|
|
db 0,0,0,0
|
|
ds 16
|
|
ds 4
|
|
fnfcb:
|
|
db 0
|
|
db 'FNAMES DIR'
|
|
db 0,0,0,0
|
|
ds 16
|
|
ds 4
|
|
cmdlne: ds 2 ; pointer to command line
|
|
buffer: ds 2 ; pointer to free space buffer
|
|
stack: ds 2 ; stack ptr
|
|
|
|
end
|
|
|