; PUBLIC - SET AND CLEAR PUBLIC FILE ATTRIBUTE 3/6/85 FALSE EQU 0 TRUE EQU NOT FALSE LISTPUBBIT EQU 0 MAKPUBBIT EQU 1 FENCE EQU '|' NULL EQU 0 BELL EQU 7 CR EQU 0DH LF EQU 0AH ESC EQU 1BH SPACE EQU ' ' DEL EQU 7FH drivefn equ 14 openfn equ 15 closefn equ 16 srchfstfn equ 17 srchnxtfn equ 18 deletefn equ 19 readfn equ 20 writefn equ 21 makefn equ 22 renamefn equ 23 logvecfn equ 24 curdskfn equ 25 dmafn equ 26 setattrfn equ 30 getaddrfn equ 31 userfn equ 32 readrfn equ 33 writerfn equ 34 sizefn equ 35 reccnt equ 15 currec equ 32 r0 equ 33 tbuff equ 80h fcb equ 5ch fcb2 equ fcb+16 boot equ 0000h bdos equ 0005h bdoslen equ 0e00h org 100h top: jmp start usage: db CR,LF,'Usage: PUBLIC [d:] -- list PUBLIC files [on d:]' db CR,LF,' PUBLIC [d:]file.ext -- make file PUBLIC' db CR,LF,' PUBLIC [d:]file.ext X -- make file private' db CR,LF,'$' header: db CR,LF,'The currently PUBLIC files are:',CR,LF,'$' tomsg: db ' set to ==> $' pubnam: db 'PUBLIC $' privnam: db 'PRIVATE $' ismsg: db ' ==> is already $' nopubs: db CR,LF,'(There are no PUBLIC files.)$' multimsg: db CR,LF,LF,BELL,"*** Multiple copies, can't change!$" nonemsg: db CR,LF,BELL,'*** No File!$' cantmsg: db CR,LF,BELL,"*** Can't make file $" start: sspd ustack lxi sp,stack lxi h,fcb+1 mov a,m cpi SPACE lxi h,flags res LISTPUBBIT,m jrnz setup bset LISTPUBBIT,m lxi d,header call printde setup: mvi c,dmafn ; set directory buffer lxi d,buf call bdos mvi c,curdskfn ; save current drive call bdos sta drive sta udrive lda fcb ; check for specified drive ora a jrz savusr dcr a sta drive ; login specified drive mov e,a mvi c,drivefn call bdos savusr: mvi c,userfn ; save user number lxi d,0ffh call bdos sta uuser mvi c,getaddrfn ; get extent mask for this drive call bdos inx h inx h inx h inx h mov a,m sta EXTMASK xra a sta count lda fcb2+1 cpi 'X' lxi h,flags res MAKPUBBIT,m jrz find bset MAKPUBBIT,m ; ; find all filename entries in all user numbers ; find: lxi h,fcb mvi m,'?' ; match ALL dir entries xchg mvi c,srchfstfn call bdos sta indx ; save position in buffer inr a jrz done ; no entries at all findall: call chknxt ; is entry PUBLIC or specified filename? jrnz findnxt call savefcb ; yes -- save it call setcol call printentry ; list it lxi h,count ; and count it inr m findnxt: mvi c,srchnxtfn ; lxi d,fcb call bdos sta indx inr a jrnz findall nomore: lxi h,flags bit LISTPUBBIT,m lda count jrz nom0 ora a jrnz done lxi d,nopubs call printde jr done nom0: sui 1 jrc none jrnz nochanges lxi h,flags ; exactly 1 file found bit MAKPUBBIT,m jrz nom1 call setpub jr done nom1: call setpriv jr done ; ; can't be PUBLIC if > 1 match on drive ; nochanges: lxi d,multimsg call printde jr done none: lxi d,nonemsg call printde jr done nopub: lxi d,pubnam call cant ; ; all done -- restore drive/user and return ; done: call crlf lxi h,flags bit LISTPUBBIT,m jrz done0 lxi d,usage call printde done0: lda udrive ; relogin user's drive mov e,a mvi c,drivefn call bdos done1: lda uuser mov e,a mvi c,userfn call bdos call crlf xit: lspd ustack ret ; ; set the PUBLIC attribute bit ; setpub: lxi h,pubfcb+2 ; test attr bit 2 bit 7,m jrnz ispub ; quit if already PUBLIC bset 7,m ; set attr bit 2 lda pubfcb ; save user number for output mov e,a ; set user number for this file mvi c,userfn ; call bdos ; lxi h,pubfcb mvi m,0 ; put default drive into fcb xchg mvi c,setattrfn ; call bdos inr a jrz nopub lxi d,tomsg call printde lxi d,pubnam call printde setpend: lxi h,pubfcb jmp prnent1 ispub: lxi d,pubnam jmp istype ; ; reset the public attribute bit ; setpriv: lda pubfcb ; save file user number mov e,a ; set user number of fcb mvi c,userfn call bdos lxi h,pubfcb+2 ; reset PUBLIC attr bit bit 7,m ; jrz ispriv ; quit if it's alread private res 7,m lxi h,pubfcb mvi m,0 ; default drive xchg mvi c,setattrfn ; call bdos inr a jrz nopriv lxi d,tomsg call printde lxi d,privnam call printde jr setpend nopriv: lxi d,privnam jmp cant ispriv: lxi d,privnam istype: push d lxi d,ismsg call printde pop d printde: mvi c,9 jmp bdos cant: push d lxi d,cantmsg call printde pop d jr printde ; ; check next directory entry ; if listing PUBLIC files, ret Z if PUBLIC and 0th extent. ; if matching a filename, ret Z if same name, type and extent ; else ret NZ ; chknxt: call findentry mov a,m cpi 0e5h ; don't match erased entries jrnz chkn0 ora a ; set NZ ret chkn0: inx h lda flags bit LISTPUBBIT,a jrz chkn1 ; ; list all PUBLIC files ; inx h ; point at 2nd char of filename mov a,m cma ani 80h ; check complement of attr bit rnz ; not PUBLIC -- ret NZ lxi d,12-2 ; have a PUBLIC file dad d ; point at its extent byte xra a ; and check for extent 0 jr chkn3 ; ; check for match with specified filename / extent 0 ; ; note: doesn't allow wiled cards. ; chkn1: lxi d,fcb+1 mvi b,11 ; name & type chkn2: ldax d sub m ani 7fh ; don't test attr bits inx h inx d rnz : NZ if no match djnz chkn2 ldax d ; now check the extent chkn3: mov c,m ; ; check for same extent in a,c ; samext: push psw extmask equ $+1 mvi a,0 cma mov b,a ; save mask mov a,c ; mask c ana b mov c,a ; save in c pop psw ; ana b sub c ani 1fh ; check only legal bits 0..4 ret savefcb: call findentry mov a,m ; save the user number sta fileuserno lxi d,pubfcb lxi b,32 ldir ret ; ; find entry in buffer ; findentry: lda indx ; point to fcb found add a ; * 32 add a add a add a add a lxi h,buf add l mov l,a rnc inr h ret setcol: lda count ani 3 jz crlf call twosp mvi c,fence call charout twosp: mvi c,SPACE call charout mvi c,SPACE jmp charout ; ; print drive/user/filename ; printentry: call findentry prnent1: push h call printdrv fileuserno equ $+1 mvi a,0 call printuser pop h print$fn: inx h ; print finename.ext mvi b,8 call prfn mvi c,'.' call charout mvi b,3 prfn: mov a,m ; print filename char, lowercase if attr bit set ani 7fh ; kill attr bit when printing cmp m ; jrz prfn1 ori 20h ; set lower case prfn1: mov c,a call charout inx h djnz prfn ret printdrv: lda drive ; print drive adi 'A' mov c,a jr charout crlf: mvi c,CR call charout mvi c,LF charout: push h push b push d mov e,c mvi c,2 call bdos pop d pop b pop h ret printuser: cpi 10 ; print A as user number jrnc printu1 push psw ; 1 space if single digit mvi c,SPACE call charout pop psw printu1: mov l,a mvi h,0 call printdec mvi c,':' jr charout printdec: decout: push psw push b push d push h lxi b,-10 lxi d,-1 decou2: dad b inx d jc decou2 lxi b,10 dad b xchg mov a,h ora l cnz decout ; recursive mov a,e adi '0' mov c,a call charout pop h pop d pop b pop psw ret flags db 0 indx db 0 drive db 0 count db 0 udrive db 0 uuser db 0 ustack dw 0 pubfcb equ $ stack equ pubfcb+32+48 buf equ stack end