home *** CD-ROM | disk | FTP | other *** search
- ;
- ; 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
- ╓