; CP4UTL.ASM
;	KERMIT - (Celtic for "FREE")
;
;	This is the CP/M-80 implementation of the Columbia University
;	KERMIT file transfer protocol.
;
;	Version 4.0
;
;	Copyright June 1981,1982,1983,1984
;	Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others. 
;
;	Utility routines, pure and impure data.
;
; revision history:
; edit 4: September 9, 1984
;	Move command tables and associated help text to CP4MIT.  Add
;	makfil/clofil routines and modify outbuf to write files in big
;	chunks.  Update Kermit's version to 4.03.
;
; edit 3: August 21, 1984
;	Make inbuf read files in big chunks to minimize disk start/stop
;	delays.  Buffer size and address is specified by system-dependent
;	overlay.
;
; edit 2: August 3, 1984
;	move "mover" to CP4SYS to allow use of Z80 block move instruction.
;
; edit 1: July 27, 1984
;	extracted from CP4MIT.M80 edit 2, as part of LASM support.  This is
;	the last file linked for the system-independent code.
;
utlver:	db	'CP4UTL.ASM (4)  9-Sep-84$'

;	Set the parity for a character in A.
;	called by: spack, rexmit, logit, vt52, conchr, intchr

setpar:	push	h		;Save HL.
	push	b
	lxi	h,parity
	mov	c,m		;Get the parity routine.
	mvi	b,0
	lxi	h,parjmp	;Get the first address.
	dad	b
	pchl

parjmp:	jmp	even
	jmp	mark
	jmp	none
	jmp	odd
	jmp	space

none:	jmp	parret		;Don't touch the parity bit.

even:	ani	7FH		;Strip parity.
	jpe	parret		;Already even, leave it.
	ori	80H		;Make it even parity.
	jmp	parret

mark:	ori	80H		;Turn on the parity bit.
	jmp	parret

odd:	ani	7FH		;Strip parity.
	jpo	parret		;Already odd, leave it.
	ori	80H		;Make it odd parity.
	jmp	parret

space:	ani	7FH		;Turn off the parity bit.
	jmp	parret

parret:	pop	b
	pop	h		;Restore HL.
	ret
;
;	Print the escape char.
;	called by: stat01, xmit, telnet, intchr

escpr:	lda	escchr		;Get the escape char.
	cpi	' '		;Is it a control char?
	jp	escpr2
	lxi	d,inms10	;Output "Control-".
	call	prtstr
	lda	escchr
	ori	100O		;De-controlify.
escpr2:	mvi	c,conout	;Output the char
	mov	e,a
	call	bdos
	ret

;	fetch keyword; if unsuccessful, return to command level.
;	called by: kermit, setcom

keycmd:	mvi	a,cmkey
	call	comnd
	 jmp	keycm2		;no match
	ret

keycm2:	lxi	d,ermes1	;"Unrecognized Command"
	call	prtstr
	jmp	kermit		;Do it again.

;	request confirmation; if unsuccessful, return to command level
;	called by: bye, exit, help, log, setcom, show, status, send,
;		finish, logout, xmit, telnet

cfmcmd:	mvi	a,cmcfm
	call	comnd
	 jmp	kermt3		;"Not confirmed"
	ret
;

;	This routine prints the number in HL on the screen in decimal.
;	Uses all ACs.
;	called by: cp4sys, read, send, updrtr, dir

nout:	lxi	b,-10		;Get some useful constants.
nout1:	lxi	d,-1

nout2:	dad	b		;Subtract as many 10s as possible.
	inx	d		;Count them.
	jc	nout2		;If some left keep going.
	push	h		;save remainder - 10
	xchg			;Swap the remainder and the quotient.
	mov	a,h		;Get the number of 10s found.
	ora	l		;check for quotient non zero
	cnz	nout1		;If non zero, recurse.
	pop	h		;Get the remainder - 10
	mov	a,l		;in a
	adi	'0'+10		;Make the number printable and add the 10 back
	mov	e,a		;Output the digit.
	mvi	c,conout
	jmp	bdos

; prcrlf - print a CR/LF.  (Saves no registers.) [Toad Hall]
; prtstr - print string pointed to by DE
;	called by: lots of places.
prcrlf:	lxi	d,crlf		;Point to the CR/LF
prtstr:	mvi	c,prstr		; output string
	jmp	bdos		;a CALL followed by a RET becomes a JMP

;	Jumping to this location is like retskp.  It assumes the instruction
;	after the call is a jmp addr.
;	here from: many places.
rskp:	pop	h		;Get the return address.
	inx	h		;Increment by three.
	inx	h
	inx	h
	pchl

;	Jumping here is the same as a ret.  'jmp r' is used after routines
;	that have skip returns, where the non-skip instruction must be 3 bytes.
;	here from: many places.
r:	ret
;
;	Open a file for reading (with inbuf).  The filename is already
;	in fcb;	upon return, the end of file flag is cleared and chrcnt
;	is set to zero, so inbuf will be called to get a buffer when we
;	next attempt to get a character.
;	called by: sinit, seof, xmit

getfil: xra	a
	sta	chrcnt		;Buffer is empty.
	sta	seccnt		;No sectors buffered.
	sta	eoflag		;Not the end of file.
	sta	endsts		;No EOF/error pending.
	sta	fcb+0CH		;Zero the extent.
	sta	fcb+0EH		;Must be zero for MAKEF or OPENF.
	sta	fcb+20H		;Zero the current record.
	mvi	c,openf		;Open the file.
	lxi	d,fcb
	call	bdos
	ret

;	Get next sector.  If necessary, read some more from disk.
;	preserves bc, de, hl
;	returns nonskip if EOF or error;
;	returns skip with chrcnt and bufpnt updated if success.
;	called by: gtchr, xnext

inbuf:	lda	eoflag		;Have we reached the end?
	ora	a
	rnz			;Return if so.
	push	b
	push	d
	push	h
inbuf1:	lda	seccnt		; Do we have any sectors left?
	ora	a
	jz	inbuf3		; If not, go get some more.
inbuf2:	lhld	nxtbuf		; Yes.  Get address of next sector
	shld	bufpnt		; Update current buffer pointer
	lxi	b,bufsiz	; Get number of bytes in sector
	dad	b		; Update HL to point to next sector
	shld	nxtbuf		; Save for next time
	dcr	a		; Decrement count of buffered sectors
	sta	seccnt		; Put it back
	mvi	a,bufsiz-1	; Number of bytes in buffer (pre-decremented)
	sta	chrcnt		; Store for our caller
	pop	h
	pop	d
	pop	b
	jmp	rskp		; Return success

; We don't have any sectors buffered.  If we've already hit an error or
; EOF, return that status to the user.

inbuf3:	lda	endsts		; Check status from previous read
	ora	a
	jz	inbuf4		; It was OK.  Get some more sectors.
	sta	eoflag		; End of file or error.  Set the flag.
	xra	a
	sta	chrcnt		; Say no characters in buffer.
	pop	h
	pop	d
	pop	b
	ret			; Return failure

; Read sectors until we fill the buffer or get an error or EOF, then return
; the first buffer to the user.  (seccnt is zero)

inbuf4:	lhld	bufadr		; Get address of big buffer
	shld	nxtbuf		; Store as next buffer address to give user
inbuf5:	shld	bufpnt		; Store as next buffer address to read into
	xchg			; Move buffer address to DE
	mvi	c,setdma	; Tell CP/M where to put the data
	call	bdos		;  ...
	mvi	c,readf		; Read a record.
	lxi	d,fcb
	call	bdos
	sta	endsts		; Save ending status
	ora	a		; 00H => read O.K
	jnz	inbuf6		; EOF/error: stop reading.
	lxi	h,seccnt	; Success.  Get addr of sector count
	inr	m		; Bump sector count by one
	lda	bufsec		; Get max number of sectors in buffer
	cmp	m		; Are we there yet?
	jz	inbuf7		; Yes, can't read any more.
	lhld	bufpnt		; No, try for another.  Get buffer address,
	lxi	d,bufsiz	;  and size of sector,
	dad	d		;  giving next buffer address in HL
	jmp	inbuf5		; Go read another sector.

; We hit EOF or got an error.  Put the DMA address back where it belongs,
; then go see if we have any sectors (before the one that got the error)
; to return to the caller.  Nxtbuf points to the first good sector, if
; any; seccnt contains the count of good sectors.

inbuf6:	call	inbuf8
	jmp	inbuf1		; Go see if we have some data to return

; We've filled the big buffer.  Reset the DMA address, then go return a
; sector to the caller.  nxtbuf points to the beginning of the buffer;
; seccnt contains the number of sectors successfully read (except that
; if we've read 256 sectors, seccnt contains zero, so we can't just go
; to inbuf1).

inbuf7:	call	inbuf8
	lda	seccnt		; Get sector count again.
	jmp	inbuf2		; Return a sector.

; Reset DMA address to the default buffer
inbuf8:	lxi	d,buff
	mvi	c,setdma
	jmp	bdos

;
;	Create a file, deleting any previous version.  The filename is in
;	fcb.
;	Returns nonskip if file could not be created.
;	If successful, takes skip return with bufpnt and chrcnt initialized
;	for output; buffers should be output via outbuf.
;	called by: gofil
makfil:	mvi	c,delf		; delete the file if it exists.
	lxi	d,fcb
	call	bdos
	xra	a
	sta	fcb+0CH		; zero the extent.
	sta	fcb+0EH		; must be zero for MAKEF or OPENF.
	sta	fcb+20H		; zero the current record.
	mvi	c,makef		; now create it.
	lxi	d,fcb
	call	bdos
	cpi	0FFH		; is the disk full?
	rz			; take error return if so.
; success. set up pointers and counters for multisector buffering.
	lhld	bufadr		; find beginning of buffer space.
	shld	bufpnt		; make it current buffer.
	lxi	d,bufsiz	; get sector size.
	dad	d		; find beginning of next buffer.
	shld	nxtbuf		; store for later.
	mov	a,e		; store buffer size
	sta	chrcnt		;  for caller.
	xra	a
	sta	seccnt		; no sectors stored yet.
	jmp	rskp		; take success return.

;	get a fresh output buffer, flushing big buffer if necessary.
;	returns nonskip if disk full.
;	if successful, returns skip with bufpnt and chrcnt updated.  Note
;	that chrcnt holds one less than the buffer size.
;	preserves BC.
;	called by: ptchr

outbuf:	push	b
	lxi	h,seccnt	; count another buffered sector
	inr	m		;  ...
	lda	bufsec		; get number of sectors we can hold
	cmp	m		; full?
	jnz	outbf2		; if not, set up pointers and return
	call	outmbf		; flush the big buffer
	 jmp	outbf9		; disk error.
outbf2:	lhld	nxtbuf		; get pointer to fresh buffer
	shld	bufpnt		; store for caller
	lxi	d,bufsiz	; advance our pointer to next buffer
	dad	d
	shld	nxtbuf
	mvi	a,bufsiz-1	; get buffer size (pre-decremented)
	sta	chrcnt		; store for caller
	pop	b
	jmp	rskp		; return success.

outbf9: pop	b		; clean up stack
	ret			; and take error return.

;	flush incore output buffers.
;	returns nonskip if disk full.
;	if successful, returns skip with nxtbuf reset to start of buffer and
;	seccnt zero.
;	destroys all ac's.
;	called by: outbuf, clofil.

outmbf:	lhld	bufadr		; get start of buffer
	shld	nxtbuf		; store for next fill cycle
	shld	bufpnt		; store for empty loop
outmb2:	lhld	bufpnt		; get address of current sector
	xchg			;  into DE
	lxi	h,bufsiz	; advance HL to next sector
	dad	d		;  ...
	shld	bufpnt		;  and store for later
	mvi	c,setdma
	call	bdos		; point CP/M at current sector
	lxi	d,fcb
	mvi	c,writef
	call	bdos		; output the sector
	ora	a		; test for error (A non-zero)
	rnz			; take nonskip return if so
	lxi	h,seccnt
	dcr	m		; count down buffered sectors
	jnz	outmb2		; loop if more saved
	lxi	d,buff		; done. restore standard DMA address
	mvi	c,setdma
	call	bdos
	jmp	rskp		; return success.

;	output current buffer, flush incore buffers, and close output file.
;	returns nonskip if disk full; skip if successful.
;	called by: rdata

clofil:
	lda	chrcnt		; get the number of chars left in the buffer.
	cpi	bufsiz		; Virgin buffer?
	jz	clofl3		; yes, don't output it.
	lhld	bufpnt		; get the buffer pointer.
clofl1:	dcr	a		; lower the count.
	jm	clofl2		; if full then stop.
	mvi	m,'Z'-100O	; put in a ^Z for EOF.
	inx	h		; point to the next space.
	jmp	clofl1

clofl2:	call	outbuf		; output the last buffer.
	 jmp	r		; give up if the disk is full.
clofl3:	lda	seccnt		; any sectors buffered in memory?
	ora	a
	jz	clofl4		; if not, don't try to flush.
	call	outmbf		; flush buffers
	 jmp	r		; disk full.
clofl4:	mvi	c,closf		; close up the file.
	lxi	d,fcb
	call	bdos
	jmp	rskp		; return success.
;

version:db	'Kermit-80 v4.03 $'
kerm:	db	'Kermit-80  '
kerm1:	db	'x:>$'		;'x' filled in at startup with DRIVE name
crlf:	db	cr,lf,'$'
ermes1:	db	cr,lf,'?Unrecognized command$'
ermes3:	db	cr,lf,'?Not confirmed$'
ermes4:	db	'?Unable to receive initiate',cr,lf,'$'
ermes5:	db	'?Unable to receive file name',cr,lf,'$'
ermes6:	db	'?Unable to receive end of file',cr,lf,'$'
erms10:	db	'?Unable to receive data',cr,lf,'$'
erms11:	db	'?Disk full',cr,lf,'$'
erms14:	db	'?Unable to receive an acknowledgement from the host',cr,lf,'$'
erms15:	db	cr,lf,'?Unable to find file',cr,lf,'$'
erms16:	db	'?Unable to rename file$'
erms17: db	cr,lf,'?Disk full$'
erms18: db	cr,lf,'?Unable to tell host that the session is finished$'
erms19: db	cr,lf,'?Unable to tell host to logout$'
erms20: db	cr,lf,'?Kermit has not been configured for a target system$'
erms21: db	cr,lf,'?Consistency check on configuration failed$'

infms3:	db	bell,'Completed$'
infms4:	db	bell,'Failed$'
infms5:	db	'%Renaming file to $'
infms6:	db	cr,lf,'[Closing the log file]$'
infms7:	db	cr,lf,'[Connected to remote host.  Type $'
infms8:	db	'C to return;',cr,lf,' type $'
inms8a:	db	'? for command list]',cr,lf,'$'
infms9:	db	cr,lf,'[Connection closed, back at micro]$'
inms10:	db	'Control-$'
inms12:	db	' (Not implemented)',cr,lf,'$'
inms13:	db	bell,'Interrupted$'
inms14:	db	TAB,TAB,'    Directory for drive '
dnam14:	db	'x:',cr,lf,'$'		;filled in by dir routine.
inms15:	DB	CR,LF,TAB,TAB,'Drive $'
inms16:	DB	'  has $';filled in by summary code with drive letter
inms17:	DB	'K bytes free',CR,LF,'$'
inms18:	DB	CR,LF,'File(s) erased$',CR,LF
inms19:	db	cr,lf,'[Transmitting file to host:'
	db	cr,lf,' 1. Type any character to send a line.'
	db	cr,lf,' 2. Type RETURN to terminate the line '
	db	'and to get the next line (go back to 1.)'
	db	cr,lf,'    (You may send other characters '
	db	'before RETURN.),'
	db	cr,lf,'   or type $'
inms20:	db	'R to send the same line again,'
	db	cr,lf,'   or type $'
inms21: db	'C to abort transmission.]',cr,lf,'$'
inms22:	db	cr,lf,'[Transmission done. Connected normally '
	db	'to remote host,'
	db	cr,lf,' type $'
inms23:	db	'Sending...$'
inms24:	db	'Receiving...$'
inms25:	db	bell,'Warning: eighth bit cannot be sent$'
inms26:	db	cr,lf,'For help, type ? at any point in a command$'

escmes:	db	cr,lf,'Type the new escape character:  $'
tacmes:	db	cr,lf,'Type the new TAC intercept character:  $'

xmthlp:	db	cr,lf,'R Send the same line again$'
inthlp:	db	cr,lf,'?  This message'
	db	cr,lf,'C  Close the connection'
	db	cr,lf,'0  (zero) Transmit a NULL'
	db	cr,lf,'S  Status of the connection$'
inhlp1:	db	cr,lf,'Typing another $'
inhlp2:	db	' will send it to the host'
	db	cr,lf,cr,lf,'Command>$'

xmtst:	db	cr,lf,'Transmitting a file$'
locst:	db	cr,lf,'Local echo$'
onstr:	db	' on$'
offstr:	db	' off$'
vtemst:	db	cr,lf,'VT52 emulation$'
cpmst:	db	cr,lf,'File Mode$'
defstr: db	' default$'
ascstr: db	' ASCII$'
binstr:	db	' binary$'
ibmst:	db	cr,lf,'IBM flag$'
filst:	db	cr,lf,'File warning$'
prst:	db	cr,lf,'Printer copy$'
escst:	db	cr,lf,'Escape char: $'
bckst:	db	cr,lf,'Block check type: $'
bckst1:	db	'-character$'
parst:	db	cr,lf,'Parity: $'
pnonst:	db	'none$'
pmrkst:	db	'mark$'
pspcst:	db	'space$'
poddst:	db	'odd$'
pevnst:	db	'even$'
spdst:	db	cr,lf,'Speed $'
spdust:	db	'is indeterminate (not SET)$'
timmsg:	db	'Timer$'
tacst:	db	cr,lf,'Current TACTrap Status/Intercept Character:  $'

cmer00:	db	cr,lf,'?Program error:  Invalid COMND call$'
cmer01:	db	cr,lf,'?Ambiguous$'
cmer02:	db	cr,lf,'?Illegal CP/M file specification$'
cmer03:	db	cr,lf,'?"*" not allowed in file specification$'
cmin00:	db	' Confirm with carriage return$'
;
	;Impure data

;COMND storage

cmstat:	ds	1		;What is presently being parsed.
cmaflg:	ds	1		;Non-zero when an action char has been found.
cmccnt:	ds	1		;Non-zero if a significant char is found.
cmsflg:	ds	1		;Non-zero when the last char was a space.
cmostp:	ds	2		;Old stack pointer for reparse.
cmrprs:	ds	2		;Address to go to on reparse.
cmprmp:	ds	2		;Address of prompt.
cmptab:	ds	2		;Address of present keyword table.
cmhlp:	ds	2		;Address of present help.
cmdbuf:	ds	80H		;Buffer for command parsing.
cmfcb:	ds	2		;Pointer to FCB.
cmfcb2:	ds	2		;Pointer to position in FCB.
cmfwld:	ds	1		;Wildcard flag
cmcptr:	ds	2		;Pointer for next char input.
cmdptr:	ds	2		;Pointer into the command buffer.
cmkptr:	ds	2		;Pointer to keyword.
cmsptr:	ds	2		;Place to save a pointer.
;
oldsp:	ds	2		;Room for old system stack.
	ds	40H		;Room for 32 levels of calls.
stack:	ds	2
eoflag:	ds	1		;EOF flag;non-zero on EOF.
curdsk:	db	0		;holds "logged" disk
prnflg:	db	0		;Flag copy to printer
timflg:	db	0		;[jd] timer flag: 0 -> no timer
timval:	dw	0		;[jd] timer value
wrn8:	db	0		;[jd] non-zero if 8-bit-lost warning sent
qbchr:	db	'&'		;[jd] binary quote character.
quot8:	db	0		;[jd] non-zero if doing 8-bit quoting
logflg:	db	0		;Flag for a log file.
escflg:	db	0		;Escape flag (start off).
fileio:	db	0		;Line-by-line from file (default off).
xofflg:	db	0		;X-OFF (=^S) received from COMM-line
;				;X-ON (=^Q) received resets this
vtyval:	ds	1		; holds row number for VT52 cursor positioning
chrcnt:	ds	1		;Number of chars in the file buffer.
filcnt:	ds	1		;Number of chars left to fill.
outpnt:	ds	2		;Position in packet.
bufpnt:	ds	2		;Position in file buffer.
fcbptr:	ds	2		;Position in FCB.
datptr:	ds	2		;Position in packet data buffer.
cbfptr:	ds	2		;Position in character buffer.
pktptr:	ds	2		;Position in receive packet.
size:	ds	1		;Size of data from gtchr.
curchk:	ds	1		;Current checksum type
inichk:	ds	1		;Agreed upon checksum type
czseen:	ds	1		;Flag that control-Z was typed
pktnum:	ds	1		;Packet number.
numpkt:	ds	2		;Total number of packets sent.
numrtr:	ds	2		;Total number of retries.
numtry:	ds	1		;Number of tries on this packet.
oldtry:	ds	1		;Number of tries on previous packet.
state:	ds	1		;Present state of the automaton.
packet:	ds	4		;Packet (data is part of it).
data:	ds	5AH		;Data and checksum field of packet.
recpkt:	ds	65H		;Receive packet storage (use the following).
recpkx:	db	cr,'$'		;=	=	= buffer limit
filbuf:	ds	65H		;Character buffer.
fnbuf:	ds	20h		;[jd] file name buffer
;** Temp 1 & 2 must be in order
temp1:	ds	1		;Temporary storage.
lstchr	EQU	temp1		;Last console input character.
temp2:	ds	1
temp3:	ds	1
temp4:	ds	1

argblk:	ds	20H		;Used for subroutine arguments

maxfil	EQU	2		; currently, only two names used.
fcbblk:	ds	maxfil*10H	;Used for a list of FCB's

; Bookkeeping storage for multiple-sector buffering.  The actual buffer
; is somewhere in the system-dependent overlay. (at the end, I hope).
nxtbuf:	ds	2		; Pointer to next sector
seccnt:	ds	1		; Number of sectors buffered
endsts:	ds	1		; Status for last read into buffer

patch:	ds	100		; Guarantee some patch space

	ORG	($ + 0ffH) AND 0ff00H	; move to start of next page
;
;	hooks for system-dependent routines:
;	This area is overwritten by the system-dependent overlay.
;
lnkflg:	dw	0	; linkage information for consistency check.
lnkent:	dw	0	; more of the same.
ovlver:	dw	0	; pointer to overlay's version string
;
; Input/output routines.  Note that outmdm and outcon may actually be the
;	same routine if selmdm and selcon do anything.  (the same is true
;	of inpmdm and inpcon).
;
selmdm:	jmp	$-$	; select modem for I/O
outmdm:	jmp	$-$	; output character in E to modem
inpmdm:	jmp	$-$	; read character from modem. return character or 0 in A.
flsmdm:	jmp	$-$	; flush pending input from modem
selcon:	jmp	$-$	; select console for I/O
outcon:	jmp	$-$	; output character in E to console
inpcon:	jmp	$-$	; read char from console. return character or 0 in A
outlpt:	jmp	$-$	; output character in E to printer
;
; screen formatting routines
clrlin:	jmp	$-$	; erase current line
clrspc:	jmp	$-$	; erase current position (after backspace)
delchr:	jmp	$-$	; make delete look like backspace
clrtop:	jmp	$-$	; erase screen and go home
;
; these routines are called to display a field on the screen.
scrend:	jmp	$-$	; move to prompt field
screrr:	jmp	$-$	; move to error message field
scrfln:	jmp	$-$	; move to filename field
scrnp:	jmp	$-$	; move to packet count field
scrnrt:	jmp	$-$	; move to retry count field
scrst:	jmp	$-$	; move to status field
rppos:	jmp	$-$	; move to receive packet field (debug)
sppos:	jmp	$-$	; move to send packet field (debug)
;
sysinit: jmp	$-$	; program initialization
sysexit: jmp	$-$	; program termination
syscon:	jmp	$-$	; remote session initialization
syscls:	jmp	$-$	; return to local command level
sysinh:	jmp	$-$	; help text for interrupt (escape) extensions
sysint:	jmp	$-$	; interrupt (escape) extensions, including break
sysflt:	jmp	$-$	; filter for incoming characters.
			;  called with character in E.
sysbye:	jmp	$-$	; terminate remote session
sysspd:	jmp	$-$	; baud rate change routine.
			; called with value from table in DE
sysprt:	jmp	$-$	; port change routine.
			; called with value from table in DE
sysscr:	jmp	$-$	; screen setup for file transfer
			; called with Kermit's version string in DE
csrpos:	jmp	$-$	; move cursor to row B, column C
sysspc:	jmp	$-$	; calculate free space for current disk
mover:	jmp	$-$	; block move
;
; Data initialized by system-dependent overlay:
;
pttab:	ds	2	; points to local equivalents to VT52 escape sequences
spdtab:	ds	2	; address of baud rate command table, or zero
spdhlp:	ds	2	; address of baud rate help table, or zero
prttab:	ds	2	; address of port command table, or zero
prthlp:	ds	2	; address of port help table, or zero
timout:	ds	2	; Initial value for fuzzy timeout
vtflg:	ds	1	; VT52 emulation flag
escchr:	ds	1	; Storage for the escape character.
speed:	ds	2	; storage for the baud rate
dbgflg:	ds	1	; debugging flag
ecoflg:	ds	1	; Local echo flag (default off).
flwflg:	ds	1	; File warning flag (default on).
ibmflg:	ds	1	; IBM flag (default off).
cpmflg:	ds	1	; File mode flag (ascii/binary/default)
parity:	ds	1	; Current parity.
spsiz:	ds	1	; Send packet size.
rpsiz:	ds	1	; Receive packet size.
stime:	ds	1	; Send time out.
rtime:	ds	1	; Receive time out.
spad:	ds	1	; Send padding.
rpad:	ds	1	; Receive padding.
spadch:	ds	1	; Send padding char.
rpadch:	ds	1	; Receive padding char.
seol:	ds	1	; Send EOL char.
reol:	ds	1	; Receive EOL char.
squote:	ds	1	; Send quote char.
rquote:	ds	1	; Receive quote char.
chktyp:	ds	1	; Checksum type desired
tacflg:	ds	1	; TACTrap flag (zero=off, nonzero=on; when non-zero,
			;  contains current TAC intercept character)
tacchr:	ds	1	; TAC intercept character
bufadr:	ds	2	; Pointer to big buffer for multiple-sector I/O
bufsec:	ds	1	; Number of sectors big buffer can hold (0 means 256)
; space used by directory command; here because space calculation is
;  (operating) system-dependent
bmax:	ds	2	; highest block number on drive
bmask:	ds	1	; (records/block)-1
bshiftf: ds	1	; number of shifts to multiply by rec/block
nnams:	ds	1	; counter for filenames per line

lnksiz	equ	$-lnkflg ; length of linkage section, for consistency check.

	END	START
