home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
ZSUS
/
ZSUS002.LBR
/
CONCAT07.LBR
/
CONCAT07.MZC
/
CONCAT07.MAC
Wrap
Text File
|
1989-12-16
|
22KB
|
887 lines
; CONCAT.MAC -- file concatenation utility
;
Vers equ 07 ; version number
SubVers equ 'a' ; modification level
;
; Concatenates two or more source files into a destination file.
; For ZCPR3 only.
;
; USAGE:
;
; CONCAT {dir:}outfile = {dir:}infile {{dir:}infile {...}} {/options}
;
; Any file without a DU or DIR specification is assumed to be in
; the current drive/user.
;
; OPTIONS:
;
; A Append mode. Appends sources files to end of target
; file, which must exist.
;
; O object file mode; ignore ^Z. The default is text mode,
; checking for a ^Z (CP/M end-of-file character).
;
; Q toggle quiet mode. A configuration byte at 111h decides
; whether CONCAT will print the names of the output and
; source files (a non-zero value defaults to quiet mode).
; This option puts CONCAT in the opposite mode. Setting
; the ZCPR3 quiet flag also puts CONCAT in quiet mode, but
; this option will toggle the meaning of the quiet flag.
;
; CONCAT requires an output file and at least one input file. Actually,
; it can be used as a simple file-copy utility, but that's not its
; purpose. The same filename may be given repeatedly in the input file
; list. The equal sign separates the output file from the input files.
; Commas and/or spaces separate multiple input files. While the equal
; sign is required, it may be separated from the filenames by one or
; more spaces. A filename cannot begin with a slash unless it is
; preceded by a DU or DIR specification.
;
; If an error occurs, such as an input file not found, the incomplete
; output file is erased (and the ZCPR3 error flag is set). If another
; file has the same name as the output file, it will be renamed to
; filetype BAK.
;
; Append mode (option A) by-passes several of the program's safety
; features, so use it with caution. For instance, no temporary file or
; BAK file is created. The target (output) file must already exist. On
; error, the output file is closed after appending any text that was
; read before the error occurred. The output file is not erased.
;
; An invalid option will be ignored. If the quiet flag is set, only
; error messages will be displayed (unless the Q option is used).
;
; On error the ZCPR3 error flag is set as follows:
; 8 ambiguous or missing output or source filename
; 10 source or target file not found or not given
; 11 disk or directory full (write error)
; 4 all other errors
;
; Version 0.7 -- December 17, 1989 -- Gene Pizzetta
; Added A (append) option, which by-passes several of CONCAT's
; safety features. A few more optimizations.
;
; Version 0.6 -- December 3, 1989 -- Gene Pizzetta
; Minor changes in setting error flag. Corrected serious error
; in detecting top of memory, found by Howard Goldstein, who also
; suggested several changes to make the code more efficient.
; Thanks, Howard.
;
; Version 0.5 -- November 25, 1989 -- Gene Pizzetta
; Added Q (quiet) option and error flag support. Fixed parser
; bug that allowed a null output filename. Now closes output
; file on error before erasing it. Tightened code.
;
; Version 0.4 -- November 12, 1989 -- Gene Pizzetta
; Added large output buffer. Corrected error in parsing filespec
; in current user. Relaxed command line syntax: commas no longer
; required. Now obeys quiet flag.
;
; Version 0.3 -- September 19, 1989 -- Gene Pizzetta
; First preliminary release.
;
; To report bugs or make suggestions:
; Gene Pizzetta
; 481 Revere Street
; Revere, MA 02151
;
; Newton Centre Z-Node: (617) 965-7259
; Lilliput Z-Node: (312) 649-1730
; Voice: (617) 284-0891
;
; Re-assembly requires MAC or SLRMAC and SYSLIB, Version 4. With MAC,
; Z80.LIB will also be needed.
;
Bdos equ 05h
CpmDma equ 80h
TPA equ 100h
;
; Bdos functions . . .
;
FRead equ 20
FWrite equ 21
CurDsk equ 25
SetDma equ 26
CurUsr equ 32
;
LF equ 0Ah
CR equ 0Dh
CpmEOF equ 1Ah
;
; The following output buffer size is in sectors (records) of 128 bytes.
; It may may be set to any number of sectors up to a maximum of 256 (32K).
;
BufSiz equ 256 ; output buffer in sectors
;
MACLIB Z80
;
; Following routines are from VLIB, Z3LIB, and SYSLIB, Version 4
;
ext f$exist,f$open,f$mopen,f$rename,f$delete,f$close
ext logud,epstr,pfn2,crlf,cout,pafdc,initfcb,codend
ext z3vinit,zfname,stndout,stndend,getquiet,gzmtop
ext puter2,f$appl
;
jmp Start
;
db 'Z3ENV'
db 1
Z3EAdr: dw 0FE00h ; address of environment descriptor
;
db 'QUIET>'
QtFlag: db 0 ; 0 defaults to noisy mode
; ..non-zero defaults to quiet mode
;
; Messages . . .
;
MsgUse: db 'CONCAT Version '
db Vers/10+'0','.',Vers mod 10+'0',SubVers,CR,LF
db 'Usage:',CR,LF
db ' CONCAT {dir:}outfile = {dir:}infile {{dir:}infile {...}}'
db ' {/options}',CR,LF
db 'Concatenates infiles to outfile.',CR,LF
db 'Options:',CR,LF
db ' A append to existing file',CR,LF
db ' O object files, ignore ^Z',CR,LF
db ' Q toggle quiet mode ',0
MsgUon: db 'on',0
MsgUof: db 'off',0
MsgWrt: db 'Writing to ',0
MsgApd: db 'Appending to ',0
MsgRd: db ' Reading from ',0
MsgNIG: db 'No source file given.',0
MsgNIF: db 'File not found.',0
MsgTNF: db 'Target file not found.',0
MsgFul: db 'Output file is full.',0
MsgNOG: db 'No output file given.',0
MsgREr: db 'Read error.',0
MsgWEr: db 'Disk full!',0
MsgCEr: db 'Error closing file.',0
MsgAmb: db 'No ambiguous filenames.',0
MsgDlm: db 'Illegal command line.',0
MsgDne: db 'Done!',0
;
Start: lhld Z3EAdr ; set up environment
call z3vinit
sspd OldStk ; save old stack pointer
call gzmtop ; get top of memory
sphl ; ..and setup new stack
;
call codend ; set buffer addresses
shld IWork
lxi d,128
dad d
shld OWork
call getquiet ; is ZCPR quiet flag set?
jrnz SetZQt ; (yes)
lda QtFlag ; no, get quiet config byte
SetZQt: sta OpQFlg ; ..and store in Q option flag
sub a
sta OpAFlg ; initialize A option flag
sta OpOFlg ; initialize O option flag
call GetDfD ; get and store default disk and user
lda CpmDma ; see if there's a tail
ora a
jz OptH ; (no)
;
GtTail: mov c,a ; move command tail to storage
inr c
mvi b,0
lxi h,CpmDma+1
lxi d,CTail
ldir
;
call GetOpt ; get options, if any
lxi h,CTail ; get output filename from tail
call EatSpc ; eat any spaces
ora a ; is it NUL?
jrz NoOFl ; (yes, no filename)
cpi '/' ; is it a slash?
jrz NoOFl ; (yes, no filename)
cpi '=' ; is it an equal sign?
jrnz GtOFl ; (no)
NoOFl: mvi a,8 ; set error flag
lxi h,MsgNOG
jmp ErExit
;
GtOFl: lxi d,OutFcb ; ..and put it in FCB
call zfname
jrz CkDelm ; (okay, so far)
mvi a,8 ; set error flag
lxi h,MsgAmb ; it's ambiguous
jmp ErExit
;
CkDelm: lda FcbOFn ; make sure there's a filename
cpi '!'
jrc NoOFl ; (there's not)
call EatSpc
mov a,m
cpi '=' ; equal sign after filename?
jrz GtOUsr ; (yes)
mvi a,4 ; set error flag
lxi h,MsgDlm
jmp ErExit
;
GtOUsr: inx h ; get past delimiter
shld TailPt ; save command tail pointer
lda OpAFlg ; check for append mode
ora a
jrnz SkpTmp ; (yes, no temporary file)
lxi h,FcbOFn
lxi d,OutFil
lxi b,11
ldir
lxi h,TmpTyp
lxi d,FcbOFt
lxi b,3
ldir
SkpTmp: lda OutFcb ; get drive (A=1)
ora a ; is there one?
jrnz GtOUs1 ; (yes)
lda DftDsk ; no, get default
GtOUs1: dcr a ; make A=0
sta OutDrv ; ..and store it
lda OutFcb+13 ; get user
sta OutUsr ; ..and store it
call OpnOut ; open output file
;
lhld TailPt
call EatSpc
ora a
jrz NoIFl
cpi '/'
jrnz GtIFl
NoIFl: mvi a,10 ; set error flag
lxi h,MsgNIG
jmp ErExit
;
GtIFl: call SetIFl ; set up input FCB
call OpnInp ; open input file
; call OpnOut ; open output file
;
lda OpQFlg ; quiet option?
ora a
jrnz NoPrt1 ; (yes, don't print anything)
lda OpAFlg ; append mode?
ora a
jrz WrtMsg ; (no)
lxi d,FcbOFn ; print name of append file
lxi h,MsgApd
jr WrtMs1
WrtMsg: lxi d,OutFil ; print name of output file
lxi h,MsgWrt
WrtMs1: call epstr
lda OutDrv
mov b,a
lda OutUsr
mov c,a
call PrtFn
lxi h,MsgRd ; ..and the file we're reading
call epstr
lda InDrv
mov b,a
lda InUsr
mov c,a
lxi d,FcbIFn
call PrtFn
;
NoPrt1: call RdLoop ; read and write files
;
CkMore: call ClsIFl ; close input file
lda DftUsr ; set default user for parser
mov e,a
mvi c,CurUsr
call Bdos
lhld TailPt ; any more input files?
call EatSpc
cpi ','
jrnz CkMor2
inx h
call EatSpc
CkMor2: ora a
jrz NoMore
cpi '/'
jrz NoMore
call SetIFl ; set up input FCB
call OpnInp ; open input file
lda OpQFlg ; quiet option?
ora a
jrnz NoPrt2 ; (yes, don't print anything)
lxi h,MsgRd ; print filename we're reading
call epstr
lda InDrv
mov b,a
lda InUsr
mov c,a
lxi d,FcbIFn
call PrtFn
NoPrt2: call RdLoop ; read and write files
jr CkMore
;
Abort: push psw ; save error code
push h ; save message
call ClsOut ; close output file
lda OpAFlg ; append mode?
ora a
jrnz Abort1 ; (yes, skip erase)
call f$delete ; erase output file
Abort1: pop h ; get back message
pop psw
jmp ErExit
;
NoMore: call ClsOFl ; close output file
lda OpAFlg ; append mode?
ora a
jrnz Finish ; (yes, skip renaming)
lxi h,OutTyp ; move real filetype into FCB
lxi d,FcbOFt
lxi b,3
ldir
lxi d,OutFcb
call initfcb
call f$exist ; see if XXX already exists
jrz SkpBak ; (it doesn't)
lxi h,BakTyp
lxi d,FcbOFt
lxi b,3
ldir
lxi d,OutFcb ; point to existing BAK name
call f$delete ; erase any existing file
lxi h,FcbOFn
lxi d,FcbOFn+12
lxi b,11
ldir
lxi h,OutFil
lxi d,FcbOFn
lxi b,11
ldir
lxi d,OutFcb ; point to old XXX name
lxi h,OutFcb+12 ; point to new BAK name
call f$rename ; ..and rename file
SkpBak: lxi h,TmpTyp ; rename temporary $$$ file
lxi d,FcbOFt ; ..to output filename
lxi b,3
ldir
lxi h,OutFil
lxi d,FcbOFn+12
lxi b,11
ldir
lxi h,OutFcb+12 ; point to new XXX name
lxi d,OutFcb ; point to old $$$ name
call f$rename
;
Finish: lda OpQFlg ; quiet option?
ora a
mvi a,0 ; reset error flag
jrnz Exit ; (yes)
lxi h,MsgDne
ErExit: call epstr ; print message
Exit: call puter2 ; set error code
lspd OldStk ; restore old stack pointer
ret ; ..and return to CCP
;
; Subroutines . . .
;
; SetIFl -- set up input file control block
;
SetIFl: lxi d,InpFcb ; point to input FCB
call zfname ; ..and parse filespec
jrz GtIUsr ; (still okay)
mvi a,8 ; set error flag
lxi h,MsgAmb ; it's ambiguous
jmp Abort
;
GtIUsr: shld TailPt ; save command tail pointer
lda InpFcb ; get driv (A=1)
ora a ; is there one?
jrnz GtIUs1 ; (yes)
lda DftDsk ; no, get default
GtIUs1: dcr a ; make A=0
sta InDrv ; ..and store it
lda InpFcb+13 ; get user
sta InUsr ; ..and store it
ret
;
; OpnInp -- open input file
;
OpnInp: mvi a,128 ; initialize pointer
sta GetPtr
sub a ; initialize end-of-file flag
sta GetFlg
lxi d,InpFcb
call initfcb
call InDU ; set drive/user for input
call f$open
rz ; (all okay)
lda OpAFlg ; append mode?
ora a
cnz ClsOFl ; (yes, write buffer)
mvi a,10 ; set error flag
lxi h,MsgNIF ; open error
jmp Abort
;
; OpnOut -- open output file
;
OpnOut: sub a ; initialize counters
sta PutCtr
sta PutSec
lhld OWork ; initialize buffer pointer
shld PutPtr
lxi d,OutFcb
call initfcb ; initialize FCB
call OutDU
lda OpAFlg ; append mode?
ora a
jrnz OpnApd ; (yes)
call f$delete ; erase any existing file
call f$mopen
rz ; (okay)
mvi a,11 ; set error flag
lxi h,MsgWEr ; open error
jmp ErExit
;
OpnApd: push d ; save FCB pointer
lded OWork ; put DMA address in DE
mvi c,SetDMA ; ..and set DMA address
call Bdos
pop d ; recover FCB address
call f$appl ; read append file
ora a ; any errors?
jrnz ApdErr ; (yes)
lda OpOFlg ; object file mode?
ora a
jrnz ApdObj ; (yes)
lhld PutPtr ; point to output buffer
lda PutCtr ; get counter to B
mov b,a
ApdLp: mov a,m ; get character
cpi CpmEof ; end of file?
jrz ApdEnd ; (end)
inx h ; increment pointer
inr b ; increment counter
mov a,b
cpi 128 ; end of sector?
jrz ApdObj ; (yes, no ^Z)
jr ApdLp ; continue
;
ApdEnd: mov a,b ; store current counter position
sta PutCtr
ret
;
ApdObj: mvi a,128 ; set counter for full sector
sta PutCtr
ret
;
ApdErr: cpi 3 ; file empty?
rz ; (yes)
cpi 2 ; file full?
jrnz ApdEr1 ; (no)
mvi a,4
lxi h,MsgFul
jmp ErExit
;
ApdEr1: mvi a,10 ; must be file not found
lxi h,MsgTNF
jmp ErExit
;
; RdLoop -- reads and writes until end of file
;
RdLoop: call FGetC ; get a character
jc RdErr ; (read error)
rz ; (end of file)
cpi CpmEof ; end of file?
cz ChkEof ; (yes, check mode)
rz ; (yes)
call FPutC ; write character
jc WrtErr ; (write error)
jr RdLoop
;
RdErr: mvi a,4 ; set error flag
lxi h,MsgREr ; we have an input read error
jmp Abort
;
WrtErr: mvi a,11 ; set error flag
lxi h,MsgWEr ; we have an output write error
jmp Abort
;
; ChkEof -- checks for Option O and, if so, ignores end-of-file character
;
ChkEof: mov b,a ; save character in B
lda OpOFlg ; get object flag
ora a
mov a,b ; get character back in A
ret
;
; ClsIFl -- close input file
;
ClsIFl: call InDU ; close input file
lxi d,InpFcb
call f$close
rz ; (okay)
mvi a,4 ; set error flag
lxi h,MsgCEr
jmp Abort
;
; ClsOFl -- closes output file
;
ClsOFl: call OutDU
lda OpOFlg ; check option O flag
ora a
jrnz WrLst ; (object file transfer, skip EOF)
mvi a,CpmEof ; put end-of-file character
call FPutC
lda PutCtr ; check pointer
ora a
jz WrLst ; (sector finished)
mov b,a
mvi a,128 ; fill rest of sector with ^Z
sub b
mov b,a
FillZ: mvi a,CpmEof
push b
call FPutC
pop b
djnz FillZ
jr WrLst
;
WrLst: lded OWork ; get beginning buffer address to DE
lxi h,PutPtr ; HL -> buffer pointer
mov a,e ; is pointer at zero?
cmp m
jrnz WrLst2 ; (no)
mov a,d
inx h
cmp m
jrnz WrLst2 ; (no)
lda PutCtr ; is counter at zero?
ora a
jrnz WrLst2 ; (no)
jr ClsOut ; nothing to write, so close it
;
WrLst2: call FWrtF ; write what's left
ora a ; check for error
jnz WrtErr ; (yes, abort)
;
ClsOut: call OutDU ; close output file
lxi d,OutFcb
call f$close
rz ; (okay)
mvi a,4 ; set error flag
lxi h,MsgCEr
jmp ErExit
;
; GetDfD -- gets default user and stores it; gets default disk (A=0)
; and stores it (A=1)
;
GetDfD: mvi e,0FFh ; get current user
mvi c,CurUsr
call Bdos
sta DftUsr
mvi c,CurDsk ; get default disk
call Bdos
inr a ; make it fcb compatible
sta DftDsk
ret
;
; PrtFn -- Prints drive/user and filename on console
;
PrtFn: call stndout
mov a,b ; get drive
adi 'A' ; make it printable
call cout ; ..and print it
mov a,c ; get user
call pafdc ; ..and print it
mvi a,':'
call cout
call pfn2 ; print filename
call stndend
call crlf
ret
;
; EatSpc -- gobbles up spaces
;
EatSpc: mov a,m
cpi ' ' ; is it a space?
inx h
jrz EatSpc ; (yes)
dcx h
ret
;
; OutDU -- sets default drive and user for output file
;
OutDU: lda OutUsr
mov c,a
lda OutDrv
mov b,a
call logud
ret
;
; InDU -- sets default drive and user for input file
;
InDU: lda InUsr
mov c,a
lda InDrv
mov b,a
call logud
ret
;
; FGetC -- returns character from file. Assumes file has been
; successfully opened. Returns character or ^Z (end-of-file) in
; A. Zero set (Z) on end of file. Carry set (C) if error.
;
FGetC: lda GetFlg ; check end-of-file flag
ora a
jrnz GetEof ; (yes)
lda GetPtr ; get pointer
cpi 128 ; done with buffer?
jrc GetChr ; (no, get a character)
lded IWork
mvi c,SetDMA ; set DMA address
call Bdos
call InDU ; set DU
lxi d,InpFcb
mvi c,FRead ; read more file
call Bdos
cpi 1 ; return code?
jrz GetEof ; (end of file)
jrnc GetErr ; (a problem)
sta GetPtr ; put 0 in pointer
;
GetChr: lhld IWork ; point to DMA buffer
mov e,a ; put pointer in DE
mvi d,0
dad d ; add it to HL
mov a,m ; get next character
lxi h,GetPtr ; increment pointer
inr m
stc
cmc ; clear carry
ret
;
GetEof: mvi a,CpmEof
sta GetFlg ; set end-of-file flag
stc
cmc ; clear carry
ret
;
GetErr: mvi a,CpmEof
sta GetFlg
stc ; set carry
ret
;
; FPutC -- Writes character to file. Assumes file has been successfully
; opened. Expects character in A. Returns carry set (C) on error.
;
FPutC: mov c,a ; save character in C
lda PutCtr ; get counter
cpi 128 ; buffer full?
jrc PutChr ; (no, so do it)
push b ; the character is threatened from all sides
lda PutSec ; get sector count
cpi BufSiz-1 ; end of buffer?
jrz FPutC2 ; (yes, we need to write it)
inr a ; increment sector count
sta PutSec ; ..and store it
lhld PutPtr ; get current sector pointer
lxi d,128 ; ..add 128 to it
dad d
shld PutPtr ; ..and store it
xra a ; make A = 0
jr FPutC3
;
FPutC2: call FWrtF ; write buffer to disk
push psw
lhld OWork ; reset buffer pointer
shld PutPtr
xra a ; reset sector counter
sta PutSec
pop psw
;
FPutC3: pop b ; get back output character
ora a ; return code?
jrnz PutErr ; (problem)
sta PutCtr ; reset counter to 0
;
PutChr: lhld PutPtr ; point to current DMA buffer
mov e,a ; move counter to DE
mvi d,0
dad d ; ..and add it to HL
mov m,c ; write character
lda PutCtr
inr a ; increment counter
sta PutCtr
sub a ; clear carry
ret
;
PutErr: stc ; set carry
ret
;
; FWrtF -- write output buffer to disk
;
FWrtF: lda PutSec ; get buffer sector count
mov b,a ; put it in B
lded OWork ; point to beginning of buffer
FWrtF2: push b ; save sector count
push d ; save DMA address
call WrtSec ; write the sector
pop h ; DMA address recovered in HL
pop b ; get back sector count
ora a ; write error?
rnz ; (yes)
cmp b ; end of buffer?
rz ; (yes)
dcr b ; decrement sector count
lxi d,128 ; increment DMA address
dad d
xchg
jr FWrtF2
;
WrtSec: mvi c,SetDma ; set DMA address
call Bdos
call OutDu ; set drive and user
lxi d,OutFcb ; ..and write sector
mvi c,FWrite
call Bdos
ret
;
; GetOpt -- checks command tail for user supplied options and sets
; appropriate option flags. Invalid options are ignored.
;
GetOpt: lxi h,CTail ; point to command tail
lda CpmDma ; anything there?
ora a
rz ; (no)
mov b,a ; yes, put number of chars in B
ScnDLp: mov a,m ; get character
cpi '/' ; delimiter?
jz ScnOpt ; (yes)
mov d,a ; save character
ScnDL2: inx h ; no, keep looking
djnz ScnDLp
ret ; (none found, return)
;
ScnOpt: push psw ; save current character
mov a,d ; get back previous character
pop d ; put current character in D
cpi ' ' ; was previous char a space?
jnz ScnDL2 ; (no)
jmp ScnOp2
;
ScnOLp: call ScnTbl
xchg ; point back to options
ScnOp2: inx h
djnz ScnOLp ; loop through options
ret
;
ScnTbl: mov c,m ; put option in C
lxi d,OptTbl ; point DE to option table
ScnTLp: ldax d ; get table option
ora a ; end of table?
jz NoMat ; (yes, no match)
inx d ; no, keep looking
cmp c ; match?
jz TMatch ; (yes)
inx d ; move pointer to next entry
inx d
jmp ScnTLp ; ..and keep looking
;
NoMat: xchg
ret
;
TMatch: push h ; save option pointer
ldax d ; put address from table into HL
mov l,a
inx d
ldax d
mov h,a
pop d ; recover option pointer in DE
mvi a,1 ; set option flag by jumping to
pchl ; ..table routine and returning
;
; OptTbl -- Option Jump Table
;
OptTbl: db '/' ; / = usage message
dw OptH
db 'A' ; A = append mode
dw OptA
db 'O' ; O = object file transfer
dw OptO
db 'Q' ; Q = toggle configured quiet flag
dw OptQ
db 0 ; end of option jump table
;
; Option setting routines
;
OptH: lxi h,MsgUse ; print usage message
call epstr
lda OpQFlg ; check quiet mode
ora a
mvi a,0 ; reset error flag
jrz OptH2 ; (off)
lxi h,MsgUof
jmp ErExit
OptH2: lxi h,MsgUon
jmp ErExit
;
OptA: sta OpAFlg
ret
;
OptO: sta OpOFlg
ret
;
OptQ: lda OpQFlg ; get Q flag
ora a
jrz OptQ2 ; (not set)
sub a
sta OpQFlg ; zero it
ret
OptQ2: mvi a,1
sta OpQFlg ; set it
ret
;
; Data storage . . .
;
OutFil: db ' ' ; save original output filename here
OutTyp: db ' '
BakTyp: db 'BAK' ; for BAK file
TmpTyp: db '$$$' ; for temporary filename
;
InpFcb: db 0 ; input file fcb
FcbIFn: db ' '
FcbIFt: db ' '
ds 24
;
OutFcb: db 0 ; output file fcb
FcbOFn: db ' '
FcbOFt: db ' '
ds 24
;
DSEG
;
; Uninitialized storage . . .
;
OpAFlg: ds 1
OpOFlg: ds 1
OpQFlg: ds 1
;
GetFlg: ds 1 ; FGetC end-of-file flag
GetPtr: ds 1 ; FGetC pointer
PutCtr: ds 1 ; FPutC counter
PutPtr: ds 2 ; FPutC pointer
PutSec: ds 1 ; FPutC sector counter
IWork: ds 2 ; input buffer address
OWork: ds 2 ; output buffer address
DftUsr: ds 1 ; default user area
DftDsk: ds 1 ; default drive
InDrv: ds 1 ; input file drive
InUsr: ds 1 ; input file user
OutDrv: ds 1 ; output file drive
OutUsr: ds 1 ; output file user
OldStk: ds 2 ; old stack pointer
TailPt: ds 2 ; command tail index pointer
CTail: ds 128 ; command tail storage
;
end