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.
1020 lines
19 KiB
1020 lines
19 KiB
;
|
|
; Program: MKDIR
|
|
; Author: Richard Conn
|
|
; Version: 3.2
|
|
; Date: 20 Nov 84
|
|
; Previous Versions: 3.1 (28 Aug 84), 3.0 (5 Mar 84)
|
|
;
|
|
version equ 32
|
|
|
|
;
|
|
; MKDIR is used to edit existing named directory files and to
|
|
; create new ones.
|
|
;
|
|
|
|
;
|
|
; Basic Equates
|
|
;
|
|
z3env SET 0f400h ;address of ZCPR3 Environment
|
|
;
|
|
fcb equ 5ch
|
|
tbuff equ 80h
|
|
cr equ 0dh
|
|
lf equ 0ah
|
|
|
|
;
|
|
; SYSLIB Routines
|
|
;
|
|
ext print,putud,getud,logud,retud,zfname,getenv
|
|
ext cout,crlf,compb,capine,pfn1
|
|
ext f$open,f$read,f$close
|
|
ext f$make,f$write,initfcb,f$delete,f$exist,gfa
|
|
ext bbline,padc,codend,sksp
|
|
ext hmovb,hfilb
|
|
ext sort
|
|
ext z3init,getndr,getwhl
|
|
|
|
;
|
|
; 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
|
|
;
|
|
; Print Banner
|
|
;
|
|
call print ;check quiet flag
|
|
db 'MKDIR, Version '
|
|
db (version/10)+'0','.',(version mod 10)+'0'
|
|
db cr,lf,0
|
|
;
|
|
; Check for Wheel Powers
|
|
;
|
|
call getwhl ;get wheel byte
|
|
jnz ndir0
|
|
call print
|
|
db ' Permission to Run MKDIR Denied - Not Wheel',0
|
|
ret
|
|
;
|
|
; Check for Availability of Named Directory
|
|
;
|
|
ndir0:
|
|
call getndr ;get location of directory
|
|
jnz ndir1
|
|
call print
|
|
db ' Named Directory Buffer Not Available',0
|
|
ret
|
|
ndir1:
|
|
xra a ; A=0
|
|
sta chflag ; set no changes
|
|
sta flflag ; set no file loaded
|
|
sta ecount ; set no entries
|
|
lda fcb+1 ; check for help
|
|
cpi '/'
|
|
jnz start1
|
|
call print ; print help message
|
|
db cr,lf,' MKDIR is used to read and edit named directory files.'
|
|
db cr,lf,'It is invoked by the following forms --'
|
|
db cr,lf
|
|
db cr,lf,' MKDIR <-- Enter System'
|
|
db cr,lf,' MKDIR dir:filename.typ <-- Define File First'
|
|
db cr,lf,' MKDIR // <-- Print this Help'
|
|
db cr,lf,0
|
|
ret
|
|
|
|
start1:
|
|
call putud ; save current dir for quick return
|
|
lxi h,dnfile ; set default file name
|
|
lxi d,dfcb+1 ; copy into fcb
|
|
mvi b,11 ; 11 chars
|
|
call hmovb
|
|
lxi h,fcb+1 ; pt to fcb
|
|
mov a,m ; get name
|
|
cpi ' ' ; no entry?
|
|
jz mkdir ; enter system
|
|
dcx h ; pt to name
|
|
lxi d,dfcb ; store name in DFCB
|
|
mvi b,16 ; copy 16 chars
|
|
call hmovb
|
|
jmp loadf0 ; enter load file
|
|
|
|
;
|
|
; Main Entry Point for Loading a File
|
|
;
|
|
loadfile:
|
|
lxi d,dfcb ; set up default file name
|
|
call zfname ; extract info
|
|
loadf0:
|
|
call retud ; get UD in CB
|
|
lda dfcb ; get disk
|
|
ora a ; current?
|
|
jz loadf1
|
|
dcr a ; A=0
|
|
mov b,a ; disk in B
|
|
loadf1:
|
|
lda dfcb+13 ; get user
|
|
mov c,a ; in C
|
|
call logud ; log into UD to begin search
|
|
;
|
|
; Entry Point for Loading File in DFCB
|
|
;
|
|
ffile:
|
|
lxi d,dfcb ; pt to FCB
|
|
call initfcb ; init it
|
|
call f$open ; try to open file
|
|
jz ffile1
|
|
call print
|
|
db cr,lf,'File ',0
|
|
lxi d,dfcb+1 ; print name
|
|
call pfn1
|
|
call print
|
|
db ' Not Found',0
|
|
jmp mkdir
|
|
ffile1:
|
|
call getnd ; get max size of file
|
|
mov b,a ; ... in B
|
|
inr b ; add 1 for overflow
|
|
call codend ; pt to scratch buffer
|
|
readf:
|
|
lxi d,dfcb ; pt to FCB
|
|
call f$read ; read next block
|
|
jnz readd ; done if EOF
|
|
push b ; save count
|
|
mvi b,128 ; copy 128 bytes
|
|
lxi d,tbuff ; ... from TBUFF
|
|
xchg
|
|
call hmovb
|
|
xchg ; HL pts to next block to copy into
|
|
pop b ; get count
|
|
dcr b ; count down
|
|
jnz readf
|
|
call print
|
|
db cr,lf,'Named Directory File too Large for System',0
|
|
call getud ; return home
|
|
jmp mkdir ; reset parameters
|
|
readd:
|
|
call f$close ; close file
|
|
call getud ; return home
|
|
;
|
|
; Fill in empty space at end of buffer
|
|
;
|
|
readd1:
|
|
mov a,b ; get count
|
|
cpi 1 ; done?
|
|
jz readd2
|
|
push b ; save count
|
|
mvi b,128 ; fill 128 bytes with 0
|
|
xra a
|
|
call hfilb
|
|
pop b ; get count
|
|
dcr b ; count down
|
|
jmp readd1
|
|
readd2:
|
|
mvi a,0ffh
|
|
mov m,a ; set EOF mark
|
|
sta flflag ; set file loaded flag
|
|
;
|
|
; Determine Entry Count
|
|
;
|
|
call codend ; pt to first entry
|
|
mvi b,0 ; set entry count
|
|
lxi d,18 ; size of entry
|
|
readd3:
|
|
mov a,m ; get first char of next entry
|
|
ora a ; done?
|
|
jz readd4
|
|
inr b ; increment count
|
|
dad d ; pt to next
|
|
jmp readd3
|
|
readd4:
|
|
mov a,b ; set entry count
|
|
sta ecount
|
|
jmp mkdir1 ; enter MKDIR
|
|
;
|
|
; Enter MKDIR System and Init Environ
|
|
; Enter at MKDIR if no file loaded, enter at MKDIR1 if file loaded
|
|
;
|
|
mkdir:
|
|
call dinit0 ; init directory
|
|
xra a ; A=0
|
|
sta ecount ; set no entries present
|
|
sta flflag ; set no file loaded
|
|
sta chflag ; set no changes
|
|
mkdir1:
|
|
call print
|
|
db cr,lf,'MKDIR Command (? for Help)? ',0
|
|
call capine ; get command
|
|
lxi d,mkdir1 ; set ret address
|
|
push d
|
|
lxi h,ctable ; scan command table for it
|
|
mov c,a ; command in C
|
|
mkdir2:
|
|
mov a,m ; get command letter
|
|
ora a ; end of table?
|
|
jz mkdirh
|
|
cmp c ; match?
|
|
jz mkdir3
|
|
inx h ; skip over address
|
|
inx h
|
|
inx h
|
|
jmp mkdir2
|
|
mkdir3:
|
|
inx h ; get address in HL
|
|
mov a,m ; low
|
|
inx h
|
|
mov h,m
|
|
mov l,a ; HL is address of routine
|
|
pchl ; "call" routine
|
|
;
|
|
; Print MKDIR Command Help
|
|
;
|
|
mkdirh:
|
|
call print
|
|
db cr,lf,'MKDIR Commands are --'
|
|
db cr,lf,' C -- Change Directory (Add/Rename/Delete Entries)'
|
|
db cr,lf,' I -- Initialize Directory'
|
|
db cr,lf,' P -- Print Directory'
|
|
db cr,lf,' R -- Read Directory File'
|
|
db cr,lf,' S -- Status of MKDIR Environment'
|
|
db cr,lf,' W -- Write Directory File'
|
|
db cr,lf,' X -- Exit Program'
|
|
db cr,lf,0
|
|
ret
|
|
;
|
|
; Command Table
|
|
;
|
|
ctable:
|
|
db 'C' ; change directory
|
|
dw change
|
|
db 'I' ; init directory
|
|
dw dinit
|
|
db 'P' ; print directory
|
|
dw pwd
|
|
db 'R' ; read file
|
|
dw read
|
|
db 'S' ; status
|
|
dw status
|
|
db 'W' ; write file
|
|
dw write
|
|
db 'X' ; exit
|
|
dw exit
|
|
db 0 ; end of table
|
|
;
|
|
; Status
|
|
;
|
|
status:
|
|
call print
|
|
db cr,lf,'** MKDIR Status **',cr,lf,cr,lf,0
|
|
call prec ; print entry count
|
|
call print
|
|
db cr,lf,'Working File Name: ',0
|
|
lxi d,dfcb+1
|
|
call pfn1
|
|
call crlf ; new line
|
|
call crlf
|
|
lda chflag ; changes made?
|
|
ora a
|
|
jnz stat1
|
|
call print
|
|
db 'No ',0
|
|
stat1:
|
|
call print
|
|
db 'Changes made to Directory since Startup'
|
|
db cr,lf,0
|
|
lda flflag ; file loaded?
|
|
ora a ; 0=no
|
|
jnz stat2
|
|
call print
|
|
db 'No ',0
|
|
stat2:
|
|
call print
|
|
db 'File has been loaded',cr,lf,0
|
|
ret
|
|
|
|
;
|
|
; Init Directory
|
|
;
|
|
dinit:
|
|
call print
|
|
db cr,lf,' Are you sure you want to Initialize the Directory '
|
|
db '(Y/N/<CR>=N)? ',0
|
|
call capine ; get response
|
|
call crlf
|
|
cpi 'Y' ; Yes is only valid reply
|
|
rnz
|
|
dinit0:
|
|
xra a ; A=0
|
|
sta ecount
|
|
cma
|
|
sta chflag ; set change flag
|
|
call getnd ; get directory size
|
|
mov b,a ; ... in B
|
|
call codend ; pt to directory
|
|
dinit1:
|
|
push b ; save counter
|
|
xra a ; zero fill
|
|
mvi b,128 ; 128 bytes
|
|
call hfilb
|
|
pop b ; get counter
|
|
dcr b ; count down
|
|
jnz dinit1
|
|
mvi m,0ffh ; store ending mark
|
|
ret
|
|
;
|
|
; Read File
|
|
;
|
|
read:
|
|
pop psw ; clear stack
|
|
call getfname ; get file name
|
|
ora a ; none?
|
|
jz ffile ; just find default file and load it
|
|
jmp loadfile ; parse entry and load file
|
|
;
|
|
; Get File Name from User
|
|
;
|
|
getfname:
|
|
call print
|
|
db cr,lf,'Name of File (<RETURN> = ',0
|
|
call retud ; get current DU
|
|
mov a,b ; print disk
|
|
adi 'A'
|
|
call cout
|
|
mov a,c ; print user
|
|
call padc
|
|
call print
|
|
db ': ',0
|
|
lxi d,dfcb+1 ; print default name
|
|
call pfn1
|
|
call print
|
|
db ')? ',0
|
|
mvi a,0ffh ; capitalize
|
|
call bbline ; get user input
|
|
call sksp ; skip to non-blank
|
|
mov a,m
|
|
ora a ; default?
|
|
ret
|
|
;
|
|
; Write File
|
|
;
|
|
write:
|
|
call getfname ; get file name
|
|
jz write1
|
|
lxi d,dfcb ; parse into DFCB
|
|
call zfname ; parse file name
|
|
call retud ; get current DU
|
|
lda dfcb ; get disk
|
|
ora a ; current?
|
|
jz write0
|
|
dcr a ; adjust for A=0
|
|
mov b,a ; ... in B
|
|
write0:
|
|
lda dfcb+13 ; get user
|
|
mov c,a ; ... in C
|
|
call logud ; log into new dir
|
|
write1:
|
|
lxi d,dfcb ; open file for output
|
|
call initfcb
|
|
call f$exist ; does file exist?
|
|
jz wf0
|
|
call gfa ; get file attributes
|
|
ani 1 ; R/O?
|
|
jz wf0
|
|
call print
|
|
db cr,lf,'File is R/O',0
|
|
jmp getud ; go home
|
|
wf0:
|
|
call f$make ; open file
|
|
inr a ; a was 0ffh if error
|
|
jz werr ; write error and abort
|
|
call print
|
|
db cr,lf,'Writing Directory to Disk ... ',0
|
|
call getnd ; get size of file
|
|
mov b,a ; count in B
|
|
call codend ; pt to start of buffer
|
|
wf1:
|
|
push b ; save counter
|
|
lxi d,tbuff ; copy into buffer
|
|
mvi b,128 ; 128 bytes
|
|
call hmovb
|
|
lxi d,dfcb ; pt to FCB
|
|
call f$write ; write block
|
|
pop b ; get ptr
|
|
jnz werr
|
|
dcr b ; count down
|
|
jnz wf1
|
|
lxi d,dfcb ; pt to FCB
|
|
call f$close ; close file
|
|
call getud ; go home
|
|
xra a ; A=0
|
|
sta chflag ; set no changes flag
|
|
call print
|
|
db 'Done',0
|
|
ret
|
|
werr:
|
|
call print
|
|
db cr,lf,'Error in Disk Write',0
|
|
jmp getud ; go home
|
|
;
|
|
; Exit from MKDIR
|
|
;
|
|
exit:
|
|
pop psw ; clear stack
|
|
lda chflag ; check for any changes
|
|
ora a ; 0=No
|
|
rz
|
|
call print
|
|
db cr,lf
|
|
db cr,lf,'Directory has changed since last Write'
|
|
db cr,lf,'Do you want to write Directory to Disk '
|
|
db '(Y/N)? ',0
|
|
call capine ; get response
|
|
call crlf ; new line
|
|
cpi 'N' ; no?
|
|
cnz write ; write if not No
|
|
ret
|
|
;
|
|
; Change Directory Contents
|
|
;
|
|
change:
|
|
call setduok ; save old DUOK flag and set new one
|
|
call print
|
|
db cr,lf,'** MKDIR Change Mode **',0
|
|
ch0:
|
|
call print
|
|
db cr,lf,'Directory Entry (?<RETURN> for Help)? ',0
|
|
mvi a,0ffh ; caps
|
|
call bbline ; get user input
|
|
call sksp ; skip to non-blank
|
|
mov a,m ; get char
|
|
ora a ; no input?
|
|
jz chprint ; done, so print directory
|
|
mov a,m ; get first char
|
|
cpi 'X' ; Exit?
|
|
jz chexit ; if so, sort and then exit
|
|
cpi '/' ; help?
|
|
jz chhelp
|
|
cpi '?' ; help?
|
|
jnz ch1
|
|
chhelp:
|
|
call print
|
|
db cr,lf
|
|
db cr,lf,'MKDIR Change Mode --'
|
|
db cr,lf,' You may issue the following commands at this point:'
|
|
db cr,lf
|
|
db cr,lf,' DU:dirname <-- Create/Rename Dir Entry'
|
|
db cr,lf,' DU: <-- Delete Dir Entry'
|
|
db cr,lf,' <RETURN> <-- Print Directory'
|
|
db cr,lf,' X <-- Exit'
|
|
db cr,lf,' ? <-- Print this Help'
|
|
db cr,lf,0
|
|
jmp ch0
|
|
chprint:
|
|
call dsort ; use dsort routine
|
|
call pwd ; use pwd routine
|
|
jmp ch0 ; continue
|
|
ch1:
|
|
lxi d,tfcb ; extract user and disk info as well as name
|
|
call zfname ; get info
|
|
call retud ; get DU
|
|
lda tfcb ; get disk
|
|
ora a ; default?
|
|
jz ch2
|
|
dcr a
|
|
mov b,a ; A=0
|
|
ch2:
|
|
inr b ; A=1
|
|
lda tfcb+13 ; get user
|
|
mov c,a ; ... in C
|
|
mov a,b ; save as temp disk and user
|
|
sta tdisk
|
|
mov a,c
|
|
sta tuser
|
|
;
|
|
; Scan Directory for Temp Disk and User
|
|
;
|
|
call codend ; pt to first entry
|
|
scanud:
|
|
mov a,m ; done?
|
|
ora a
|
|
jz scanud2
|
|
inx h ; pt to name
|
|
inx h
|
|
mov a,m ; get first char of name
|
|
dcx h
|
|
dcx h ; pt to disk
|
|
cpi ' ' ; deleted entry?
|
|
jz scanud1
|
|
mov a,m ; get disk
|
|
cmp b
|
|
jnz scanud1
|
|
inx h ; pt to user
|
|
mov a,m ; get user
|
|
dcx h ; pt back
|
|
cmp c ; compare it
|
|
jz udfound
|
|
scanud1:
|
|
lxi d,18 ; pt to next
|
|
dad d
|
|
jmp scanud
|
|
;
|
|
; DU not found
|
|
;
|
|
scanud2:
|
|
lda tfcb+1 ; delete?
|
|
cpi ' ' ; space if so
|
|
jnz addname
|
|
call print
|
|
db cr,lf,' DU not Found',0
|
|
jmp ch0
|
|
;
|
|
; Found Possible Directory Entry
|
|
;
|
|
udfound:
|
|
inx h ; found existing entry
|
|
inx h ; pt to name
|
|
lda tfcb+1 ; delete?
|
|
cpi ' ' ; space if so
|
|
jz delname
|
|
;
|
|
; Rename Function
|
|
;
|
|
call print
|
|
db cr,lf,' Renaming ',0
|
|
mvi b,8 ; 8 chars
|
|
call prhlb ; print name
|
|
push h ; save ptr to name
|
|
call etest ; check for duplicate name
|
|
pop d ; restore ptr to name
|
|
jz ch0 ; abort since duplicate
|
|
lxi h,tfcb+1 ; pt to new name
|
|
mvi b,8 ; 8 chars
|
|
call hmovb ; copy
|
|
mvi a,0ffh ; set change
|
|
sta chflag
|
|
jmp ch0
|
|
;
|
|
; Add Function
|
|
;
|
|
addname:
|
|
call print
|
|
db cr,lf,' Adding ',0
|
|
lxi h,tfcb+1 ; print name of entry to add
|
|
mvi b,8
|
|
call prhlb
|
|
;
|
|
; Test for Duplicate Name
|
|
;
|
|
putname:
|
|
call etest ; test for duplicate name
|
|
jz ch0 ; abort if duplicate
|
|
;
|
|
; Test to see if there is room for another entry
|
|
;
|
|
putn1:
|
|
mvi b,18 ; 18 bytes required for entry
|
|
push h ; save ptr
|
|
putn2:
|
|
mov a,m ; check for 0FFH
|
|
cpi 0ffh
|
|
jz putn3
|
|
inx h ; pt to next
|
|
dcr b
|
|
jnz putn2
|
|
pop h ; get ptr to entry
|
|
jmp putn4 ; make entry
|
|
putn3:
|
|
pop psw ; clear stack
|
|
call print
|
|
db cr,lf,'** Directory Full **',0
|
|
jmp ch0
|
|
;
|
|
; Make Directory Entry
|
|
;
|
|
putn4:
|
|
mvi a,0ffh ; set change flag
|
|
sta chflag
|
|
lda tdisk ; set disk and user
|
|
mov m,a
|
|
inx h
|
|
lda tuser
|
|
mov m,a
|
|
inx h
|
|
lxi d,tfcb+1 ; pt to new name
|
|
xchg
|
|
mvi b,8 ; 8 chars
|
|
call hmovb ; set new name
|
|
call password ; enter password into buffer at DE
|
|
lda ecount ; print count
|
|
inr a ; increment entry count
|
|
sta ecount
|
|
jmp precount ; print count
|
|
;
|
|
; Test for Duplicate Directory Name
|
|
;
|
|
etest:
|
|
call codend ; pt to first entry
|
|
etest0:
|
|
mov a,m ; done?
|
|
ora a
|
|
jz etest2
|
|
inx h ; pt to name
|
|
inx h
|
|
lxi d,tfcb+1 ; pt to new name
|
|
mvi b,8 ; 8 chars
|
|
call compb ; compare
|
|
jnz etest1
|
|
call crlf
|
|
lxi h,tfcb+1
|
|
mvi b,8 ; 8 chars
|
|
call prhlb ; print dir name
|
|
call print
|
|
db ' is a Duplicate Name',0
|
|
xra a ; return Z
|
|
ret
|
|
;
|
|
; Last Entry was OK - Pt to Next
|
|
;
|
|
etest1:
|
|
lxi d,16 ; pt to next entry
|
|
dad d
|
|
jmp etest0
|
|
;
|
|
; No Duplicate Entries - Return NZ and HL pts to after last entry
|
|
;
|
|
etest2:
|
|
dcr a ; set NZ
|
|
ret
|
|
;
|
|
; Enter 8-char password into memory pted to by HL
|
|
;
|
|
password:
|
|
push d ; save ptr
|
|
call print
|
|
db ' -- Password? ',0
|
|
mvi a,0ffh ; caps
|
|
call bbline ; get line from user
|
|
call crlf ; new line
|
|
mvi b,8 ; 8 chars max
|
|
pop d ; pt to destination
|
|
pword1:
|
|
mov a,m ; get char
|
|
ora a ; done?
|
|
jz pword2
|
|
stax d ; put char
|
|
inx h ; pt to next
|
|
inx d
|
|
dcr b ; count down
|
|
jnz pword1
|
|
ret
|
|
pword2:
|
|
mvi a,' ' ; rest are spaces
|
|
stax d ; store space
|
|
inx d ; pt to next
|
|
dcr b ; count down
|
|
jnz pword2
|
|
ret
|
|
|
|
;
|
|
; Delete Function
|
|
;
|
|
delname:
|
|
mvi a,0ffh ; change made
|
|
sta chflag
|
|
call print
|
|
db cr,lf,' Deleting ',0
|
|
mvi b,8 ; 8 chars
|
|
call prhlb
|
|
mvi m,' ' ; space fill
|
|
call dirpack ; pack directory
|
|
call print
|
|
db ' -- ',0
|
|
lda ecount ; decrement entry count
|
|
dcr a
|
|
sta ecount
|
|
;
|
|
; Print Number of Remaining Entries in Directory
|
|
;
|
|
precount:
|
|
call prec ; print count
|
|
jmp ch0
|
|
prec:
|
|
lda ecount ; print remaining count
|
|
call padc
|
|
call print
|
|
db ' Entries in Directory',0
|
|
ret
|
|
;
|
|
; Pack Memory-Based Directory -- One Entry has been Deleted
|
|
;
|
|
dirpack:
|
|
call codend ; get address of first entry
|
|
mov d,h ; DE pts to it also
|
|
mov e,l
|
|
dirp0:
|
|
mov a,m ; get first byte
|
|
ora a ; done if zero
|
|
jz dirp2
|
|
push b ; save counts
|
|
inx h ; pt to name
|
|
inx h
|
|
mov a,m ; get char
|
|
dcx h ; pt back to disk
|
|
dcx h
|
|
cpi ' ' ; no entry if space
|
|
jz dirp1
|
|
mvi b,18 ; copy 18 bytes
|
|
call hmovb
|
|
pop b ; get counts
|
|
jmp dirp0
|
|
dirp1:
|
|
lxi b,18 ; pt to next entry
|
|
dad b
|
|
pop b ; get counts
|
|
jmp dirp0
|
|
dirp2:
|
|
mvi b,18 ; fill last entry with zeroes
|
|
xra a
|
|
xchg ; HL pts to last entry
|
|
jmp hfilb
|
|
;
|
|
; Exit Change Routine
|
|
;
|
|
chexit:
|
|
call resduok ; restore DUOK flag and fall thru to DSORT
|
|
;
|
|
; Sort Directory
|
|
;
|
|
dsort:
|
|
lda ecount ; number of elements
|
|
ora a ; any?
|
|
rz ; done if none
|
|
sta ssbcnt ; set count
|
|
call codend ; pt to first element
|
|
shld ssbstrt ; set starting address
|
|
lxi d,ssb ; pt to sort specifiction block
|
|
jmp sort ; sort
|
|
;
|
|
; Sort Compare Routine
|
|
;
|
|
compare:
|
|
push h ; don't change regs
|
|
push d
|
|
ldax d ; compare disk
|
|
cmp m
|
|
jnz comp1
|
|
inx h ; pt to user
|
|
inx d
|
|
ldax d ; compare user
|
|
cmp m
|
|
comp1:
|
|
pop d ; restore regs
|
|
pop h
|
|
ret
|
|
|
|
;
|
|
; SETDUOK - Save Old DUOK Flag and Set Flag to TRUE
|
|
; RESDUOK - Restore Old DUOK Flag
|
|
;
|
|
setduok:
|
|
push h ;save regs
|
|
push d
|
|
call getenv ;get ptr to environment descriptor
|
|
lxi d,2EH ;offset to DUOK Flag
|
|
dad d
|
|
mov a,m ;get flag
|
|
sta duoksav ;save flag
|
|
mvi m,1 ;turn flag on
|
|
pop d ;restore regs
|
|
pop h
|
|
ret
|
|
resduok:
|
|
push h ;save regs
|
|
push d
|
|
call getenv ;get ptr to environment descriptor
|
|
lxi d,2EH ;offset to DUOK Flag
|
|
dad d
|
|
lda duoksav ;get save flag
|
|
mov m,a ;set flag
|
|
pop d ;restore regs
|
|
pop h
|
|
ret
|
|
|
|
;
|
|
; Print Names of Directory Elements
|
|
;
|
|
pwd:
|
|
call crlf ; new line
|
|
lda ecount ;check count first
|
|
ora a ;no entries?
|
|
jnz pwd01
|
|
call print
|
|
db ' No Entries in Directory',0
|
|
ret
|
|
;
|
|
; Print Header for Password Entries
|
|
;
|
|
pwd01:
|
|
mvi b,2 ;2 times
|
|
pwd0a:
|
|
call print
|
|
db ' DU : DIR Name - Password ',0
|
|
dcr b ;count down
|
|
jnz pwd0a
|
|
call crlf
|
|
mvi b,2
|
|
pwd0b:
|
|
call print
|
|
db '---- -------- -------- ',0
|
|
dcr b ;count down
|
|
jnz pwd0b
|
|
call crlf
|
|
;
|
|
; Begin Output Processing
|
|
;
|
|
mvi c,0 ;set entry count
|
|
mvi b,1 ;set disk 1
|
|
call codend ;pt to buffer containing new directory
|
|
;
|
|
; Print Each Resident Command Name
|
|
;
|
|
pwd1:
|
|
mov a,m ;get table entry
|
|
ora a ;end of table?
|
|
rz ;exit
|
|
cmp b ;same disk?
|
|
jz pwd2
|
|
;
|
|
; Advance to Next Set of Entries for New Disk
|
|
;
|
|
mov b,a ;set new disk
|
|
mov a,c ;get count
|
|
ani 3 ;see if newline already given
|
|
cnz crlf ;complete current line
|
|
call crlf ;1 additional line
|
|
mvi c,0 ;reset count
|
|
pwd2:
|
|
push b ;save counters
|
|
;
|
|
; Print DU:
|
|
;
|
|
mov a,m ;get disk
|
|
adi '@' ;convert to letter (A to P)
|
|
call cout
|
|
inx h ;pt to user
|
|
mov a,m ;get user
|
|
call padc ;print user number
|
|
call print ;print separator
|
|
db ': ',0
|
|
inx h ;pt to name
|
|
;
|
|
; Print DIR
|
|
;
|
|
call prname ;print name of directory
|
|
call print
|
|
db ' - ',0
|
|
call prname ;print name of password
|
|
pop b ;get counters
|
|
inr c ;another entry
|
|
push b ;save counters
|
|
;
|
|
; Print Separator
|
|
;
|
|
call print ;print separator
|
|
db ' ',0
|
|
pop b ;get counters
|
|
;
|
|
; New Line Counter
|
|
;
|
|
inr c ;increment entry counter
|
|
mov a,c ;check for done
|
|
ani 3 ;every 4
|
|
cz crlf ;new line
|
|
jmp pwd1
|
|
;
|
|
; Print 8-char name (directory or password) and advance ptr
|
|
;
|
|
prname:
|
|
mvi b,8 ;print name
|
|
prn1:
|
|
mov a,m ;get char
|
|
call cout
|
|
inx h ;pt to next
|
|
dcr b ;count down
|
|
jnz prn1
|
|
ret
|
|
|
|
;
|
|
; Utilities
|
|
;
|
|
|
|
;
|
|
; Print chars pted to by HL for B bytes
|
|
;
|
|
prhlb:
|
|
push h ; save HL
|
|
prhlb1:
|
|
mov a,m ; print chars
|
|
inx h ; pt to next
|
|
call cout
|
|
dcr b ; count down
|
|
jnz prhlb1
|
|
pop h ; get HL
|
|
ret
|
|
|
|
;
|
|
; Compute Number of 128-byte blocks in Named Dir
|
|
; Return with Number in A and HL pting to it
|
|
;
|
|
getnd:
|
|
call getndr ; get ptr to NDR and number of entries in A
|
|
push h ; save ptr
|
|
mvi h,0 ; HL = value
|
|
mov l,a
|
|
dad h ; *2
|
|
mov d,h ; DE = value * 2
|
|
mov e,l
|
|
dad h ; *4
|
|
dad h ; *8
|
|
dad h ; *16
|
|
dad d ; *18
|
|
mov a,h ; /128
|
|
rlc
|
|
ani 0feh
|
|
mov h,a
|
|
mov a,l
|
|
rlc
|
|
ani 1
|
|
ora h ; A = value * 18 / 128
|
|
inr a ; +1
|
|
pop h ; get ptr
|
|
ret
|
|
|
|
;
|
|
; Default File Name
|
|
;
|
|
dnfile:
|
|
db 'NAMES '
|
|
db 'NDR'
|
|
|
|
;
|
|
; Sort Specification Block
|
|
;
|
|
ssb:
|
|
ssbstrt:
|
|
ds 2 ; start address of dir
|
|
ssbcnt:
|
|
dw 0 ; number of records to sort
|
|
dw 18 ; 18 bytes/record
|
|
dw compare ; compare routine
|
|
dw 0 ; no ptr table
|
|
db 0,0 ; don't use ptrs
|
|
;
|
|
; Buffers
|
|
;
|
|
duoksav:
|
|
ds 1 ; save value for DUOK flag
|
|
tdisk:
|
|
ds 1 ; temp disk
|
|
tuser:
|
|
ds 1 ; temp user
|
|
flflag:
|
|
ds 1 ; file loaded flag
|
|
chflag:
|
|
ds 1 ; dir changed flag
|
|
ecount:
|
|
ds 1 ; entry count
|
|
crcnt:
|
|
ds 1 ; new line count
|
|
tfcb:
|
|
ds 36 ; temp FCB
|
|
dfcb:
|
|
ds 36 ; Default FCB
|
|
|
|
end
|
|
|