; ; Create an alias directory entry for file on same user ; Mark original and alias as read-only. Preserve any ; other attribute bits. ; ; File must be described in one directory entry. ; reboot equ 0 bdos equ reboot+5 ; tfcb equ reboot+05ch tfcb.ro equ tfcb+9; high bit only tfcb.xtnt equ tfcb+12 tfcb.nxt equ tfcb+32 tfcb.rr equ tfcb+33 ; afcb equ tfcb+16; 2nd parameter here ; ; Bdos calls @tstr equ 9 @ver equ 12 @seldsk equ 14 @fopen equ 15 @fclose equ 16 @make equ 22 @curdsk equ 25 @sfattr equ 30; set file attributes @dparms equ 31; get disk parameters @fsize equ 35; get file size ; cr equ 0dh lf equ 0ah ; ; ----------- ; lxi h,0 dad sp lxi sp,stack push h lda tfcb+1 cpi ' ' stc lxi h,help jz msgxit mvi c,@ver call bdos; get hl value inr h dcr h stc lxi h,badver jnz msgxit; MPM? cpi 22h cnc alias; version ok msgxit: cc tstr; message on failure exit: pop h sphl ret ; ; Create alias. Exit with carry & hl pointer to message on error. ; a,f,b,c,d,e,h,l alias: lxi h,afcb; save 2nd parameter lxi d,fcb mvi b,16 call move ; " " ; Now verify all the things that can go wrong. lxi d,fcb call wldchk jc nowild inx d ldax d cpi ' ' lxi h,needf stc rz lxi d,tfcb; 1st parameter ldax d ora a sta fcb; jam to same drives lxi h,spec stc rz; must specify drive call wldchk jc nowild mvi a,0ffh sta tfcb.nxt; to get byte size returned mvi a,@fopen call dos lxi h,nofile inr a stc rz; open failure lda tfcb.nxt; CPM2.2 returns garbage sta bytcnt; (harmless). DOS+/CPM3 rtn size. mvi a,@fopen call foper inr a stc lxi h,exists rnz; alias exists mvi a,@curdsk call dos push psw; save current drive lda tfcb dcr a mov e,a mvi a,@seldsk call dos; select appropriate drive mvi c,@dparms call bdos; need hl result here inx h inx h inx h inx h mov a,m; get extent mask (extents/entry) inr a; count of 16k blocks/dir entry lxi h,0 lxi d,128; records/16k block alias1: dad d; * blocks/entry dcr a; = records/entry jnz alias1; compute max size in 1 dir entry pop psw mov e,a mvi a,@seldsk; have info, so call dos; restore current drive push h; save max size value lxi d,tfcb mvi a,@fsize call dos; get size of file pop b; max size to bc lda tfcb.rr+2 ora a lxi h,toobig stc rnz; file too large xchg lhld tfcb.rr xchg mov a,c sub e mov a,b sbb d rc; file too large for 1 dir entry mvi a,@make call foper; create empty file inr a stc lxi h,nodir rz; no directory space ; " " ; Now the source file is open, destination created on same drive, ; and we know that the source is described in one directory entry. ; Copy its allocation/size information to the alias FCB lxi h,tfcb.xtnt lxi d,fcb.xtnt mvi b,20 call move ; " " ; Mark the alias modified (to record on close) and close. Then set ; r/o attribute in original, and set bytecount/attributes in alias. ; On DOS+ the alias create/modify date will set to current time. lxi h,fcb.s2 mov a,m ani 07fh mov m,a; mark file dirty mvi a,@fclose call foper lxi h,tfcb.ro mov a,m ori 080h mov m,a; mark read only lxi d,tfcb mvi a,@sfattr call dos lxi h,fcb push h mvi b,11 alias2: inx d inx h ldax d ani 080h; copy all file attributes ora m mov m,a dcr b jnz alias2 lxi h,fcb.ifc6 mov a,m ori 80h; set interface attribute for bytecount mov m,a lda bytcnt; this for DOS+ and CPM3 only sta fcb.nxt pop d; fcb mvi a,@sfattr call dos; and set attributes/byte count xra a; signal success ret ; ; No wild card message nowild: lxi h,nowld call tstr lxi h,help stc ret ; ; Type string hl^ to console ; a,f tstr: xchg mvi a,@tstr call dos xchg ret ; ; operate on file fcb ; a,f,d,e foper: lxi d,fcb ; " " ; protected dos call, function a, set flags on returned value ; a,f dos: push h push d push b mov c,a call bdos pop b pop d pop h ora a ret ; ; scan fcb de^ for wildcards. Carry if any ; a,f,b wldchk: push d xchg mvi b,11 mvi a,'?' wldck1: inx h cmp m stc jz wldck2; wild card dcr b jnz wldck1 xra a; ok, no wilds wldck2: xchg pop d ret ; ; move b bytes from hl^ to de^ move: mov a,m stax d inx h inx d dcr b jnz move ret ; nodir: db 'No directory space available$' spec: db 'Must specify drive$' exists: db 'Alias name already exists$' nowld: db 'No wild cards allowed',cr,lf,cr,lf,'$' nofile: db 'Can''t find file$' badver: db 'Need CPM 2.2 or DOS+$' toobig: db 'File too large for alias entry$' needf: db 'No alias name specified',cr,lf,cr,lf help: db 'usage: ALIAS d:fn.ft newnm.newt',cr,lf db ' creates an alias directory entry for fn.ft',cr,lf db ' allowing fn.ft to be referanced as newnm.newt',cr,lf db 'BOTH files are then marked read/only',cr,lf,cr,lf db 'IF EITHER erased, do immediate ^C to protect other$' ; fcb: ds 1 fcb.nm ds 8 fcb.ifc6 equ fcb+6; high bit only, interface attribute fcb.typ: ds 3 fcb.xtnt: ds 1 fcb.s1: ds 1; bytecount kept here fcb.s2: ds 1; high extent, clean bit fcb.rc ds 1; records in last xtnt fcb.dm ds 16; disk map fcb.nxt: ds 1 fcb.rr: ds 3; random rcd # ; bytcnt: ds 1 ds 64 stack: end