.TITLE  KERMIT-65	KL10 Error-free Reciprocol Micro-interface Transfer
.SBTTL  6502 version - Antonino N. J. Mione
.SBTTL	Commodore 64 version converted from Apple version 1.1
.SBTTL	By Dave Mcdermott  March, 1984
.SBTTL	Additional improvements by Eric Lavitsky, Nov, Dec 1984

;
;	Based on the KERMIT Protocol.
;

.SBTTL  Revision History

;
; Edit #	Description
; ------	-----------
;   01		By: David Dermott	       On: Mar 1984
;		Start converting to C-64
;               Edits 15,18,25,27 from APPLEK included
;
;   02		By: David Dermott	       On: Jul 1984
;		Add SET RS232 REGISTERS to change baud rate
;
;   03		By: David Dermott	       On: Jul 1984
;		Add ASCII,PETASCI and SCRIPT file formats
;
;   04		By: David Dermott
;		Add code to terminal emulate for lower case
;
;   05		By: David Dermott	       On: Oct 1984
;		Include macros movadr,ldadr,movw,ldxy,stxy,
;		pusw,pulw,pusb,pulb
;
;   06		By: David Dermott	       On: Oct 1984
;		Change indexed jump with JMPIND
;
;   07		By: David Dermott	       On: Nov 1984
; 		Add code to RPAK to set PTYPE to "false" if
;   		checksum fails.
;
;   08		By: David Dermott	       On: Nov 1984
;		Add DOS command for local file management
;
;
;   09		By: Eric Lavitsky		On: 28-Nov-1984
;		Reformatted Dave Dermotts' code to look more like
;		the current Apple version (2.1).
;
;
;   10		By: Eric Lavitsky		On: 29-Nov-1984
;		Added or completed Apple revisions 11,13,14,20,
;		21,23,26. This includes fixes to the parser and
;		new server commands.
;
;
;   11		By: Eric Lavitsky		On: 01-Dec-1984
;		Replaced prrstr with prstr since C64 can display 
;		lower case.
;
;
;   12		By: Eric Lavitsky		On: 03-Dec-1984
;		Make Kermit switch to upper/lower case mode at start
;		and close all open channels. Also did more reformating 
;		of code.
;
;
;   13		By: Eric Lavitsky		On: 05-Dec-1984
;		Remove macros pulw,pusw,pulb,pusb,ldadr,movadr,movw
;		to be more consistent with Apple code.
;
;
;   14		By: Eric Lavitsky		On: 06-Dec-1984
;		Fixed cursor routines, added blink, nblink. Added
;		new bell procedure which turns off at next cursor blink. 
;		Added new definitions for C64 video and sound routines.
;		Added a confirm before going into DOS. Cleaned keyword 
;		table organization to coincide with Apple definitions.
;
;
;   15		By: Eric Lavitsky		On: 08-Dec-1984
;		Make the version 1.0 for the first release. Remove
;		all Apple edit histories. Leave only [DD] for Dave
;		Dermotts' remaining edits and [EL] for those that I
;		have done. Future edits will include an edit number
;		in the source.
;
;
; nnn		By: xxxxxxxx xxxxxxxx		On: nn-XXX-19nn
;		xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;		xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;		xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;
;+

.SBTTL	Define start address for assembly

	       .=	$801		; Start assembly at hex 801

.SBTTL		BASIC start sequence   10 SYS(2064)

basic:	.byte	$0D,$08,$0A,$00		; Line 10 in BASIC
	.byte	$9E			; SYS
	.ascii	/(2064)/		;
	.byte	$00,$00,$00		; end of line

	.byte	$00

		.=	$810

.SBTTL  Jump to start of code

kst:	jmp	kstart		; Go past the data to the beginning of the code

.SBTTL	Macro definitions

; Macro to open a file
.macro openm,p1,p2,p3,p4,p5	 ;lun,dv,sa,fnm,len
	lda 	p1	
	ldx 	p2
	ldy 	p3
	jsr	setlfs
	ldx	#p4\
	ldy	#p4^
	lda	p5
	jsr	setnam
	jsr	open
.endm

.SBTTL	C64 kernel entry points

chkin	=	$ffc6		; change kernel input channel
chkout	=	$ffc9		; change kernel output channel
chrin	=	$ffcf		; input a character
chrout	=	$ffd2		; output a character
cint	=	$ff81		; [EL] initialize screen editor
clall	=	$ffe7		; close all channels and files
close	=	$ffc3		; close a channel
clrchn	=	$ffcc		; close input and output channel
getin	=	$ffe4		; input a character
ioinit	=	$ff84		; [EL] initialize I/O devices
open	=	$ffc0		; open a channel
plot	=	$fff0		; fetch/set cursor position (40 col)
ramtas	=	$ff87		; [EL] init RAM, tape buffer, screen memory
readst	=	$ffb7		; read I/O status
restoi	=	$ff8a		; [EL] restore default I/O vectors
setlfs	=	$ffba		; [EL] set open parameters
setnam	=	$ffbd		; [EL] set filename

vtabz	=	$e9f0		; Routine - calculate base addr of line in xr
dos	=	$a002		; BASIC NMI vector

.SBTTL  Character and string definitions

nul	=	$00		; <null>
soh	=	$01		; <soh>
bs	=	$08		; <bs>
tab	=	$09		; <tab> (ctrl/I)
lf	=	$0a		; <lf>
ffd	=	$0c		; Form feed
cr	=	$0d		; <cr>
ctrlu	=	$15		; <ctrl/U>
ctrlx	=	$18		;[0] <ctrl/X>
esc	=	$1b		; <esc>
sp	=	$20		; <space>
space	=	$20		; """"
del	=	$7f		; <del>
cdel	=	$14		; commodore del
quest	=	$3F		; <?>
ctrlw	=	$17		; <ctrl/W>
dquot	=	$22		; '"'		?
quot	=	$27		; "'"		?
slash	=	$2f		; '/'		?
apos	=	quot		; "'"		?
rabr	=	$3e		; '>'		?
colon	=	$3a		; ':'		?

; Commodore I/O addresses

vcr	=	$d011		;[EL] vic control register
vmcr	=	$d018		;[EL]  vic memory control register
ccra	=	$dc0e		;[EL]  cia control register A
bgnd	=	$d021		;[EL]  40 column background color
bord	=	$d020		;[EL]  border color
freqhi	=	$d401		;[EL]  sid frequency (high byte)
attdec	=	$d405		;[EL]  sid attack/decay
susrel	=	$d406		;[EL]  sid sustain/release
vol	=	$d418		;[EL]  sid volume
wave	=	$d404		;[EL]  sid waveform select
ddrpa2	=	$dd02		;[EL]  cia-2 data direction reg (port a)
dpa2	=	$dd00		;[EL]  cia-2 data port a
colram	=	$d800		;[EL]  color ram address (40 col)
vidmat4	=	$0400		;[EL]  video matrix address (40 col)

ch	=	$d3		; Cursor Horizontal position (col)
cv	=	$d6		; Cursor Vertical position (row)
basl	=	$d1		; L.O. byte of base address of current line
bash	=	$d2		; H.O. byte of base address of current line
bas2l	=	$50		; Base address work area
bas2h	=	$51		; Base address work area
ncol	=	40		;[EL] no of columns
ndx	=	$c6		;[EL] number of keyboard bytes pending
r6510	=	$01		;[EL] Memory control register for 6510 
clock	=	$a0		;[EL] Jiffy clock (3-byte)
qtsw	=	$d4		;[EL] quote-mode switch (40 col)

ridbe	=	$29b		;[EL] RS-232 index to end of input buffer
ridbs	=	$29c		;[EL] RS-232 index to start of input buffer
shflag	=	$28d		;[EL] shift key flags (commodore key = bit 1)
hibase	=	$288		;[EL] video matrix page number (40 col)
color	=	$286		;[EL] 40 column foreground color

lpcnt:	.byte	0		;[EL] cursor blink counter
lpmax:	.byte	$00		;[EL] cursor blink loop reset value
cntrl:	.byte	$06		;[EL] rs-232 control reg (300 baud default)
cmmnd:	.byte	$00		;[EL] rs-232 command reg
optbdl:	.byte	$3c		;[EL] kluge value for 1200 baud
optbdh:	.byte	$01		;[EL] kluge value for 1200 baud
fgbg4:	.byte	$1b		;[EL] 40 col fgnd/bgnd colors (white/gray1)

wndbtm:	.byte	24		;
wndtop: .byte	0		;
wndwth: .byte	39		;

.SBTTL	Flag definitions

;	The following are flags passed in the Y register

cmfehf	=	1		;[EL] Extra help available
cmfdff	=	2		;[EL] Default value present

.SBTTL  Parse types

;	The following are different items to parse for

cmini	=	0		; Token to indicate parser init
cmkey	=	1		; Token to parse for keyword
cmifi	=	2		; Token to parse for input file
cmofi	=	3		; Token to parse for output file
cmcfm	=	4		; Token to parse for confirm
cmnum	=	5		; Token to parse for a number
cmswi	=	6		; Token to parse for a switch
cmfls	=	7		; Token to parse for a floating-point number
cmtxt	=	8		; Token to parse for an unquoted string
cmtok	=	9		; Token to parse for a single char token

.SBTTL  Parser support

;  Define storage for pointers into command buffer. They must be
;  on zero-page to take advantage of pre- and post-indexed indirect
;  and also the simulated indirect addressing mode.

saddr	=	$20		; Saved string address - must be on page zero
cm.rty  =	$22		; Byte pointer to CTRL/R Text
cm.bfp  =	$04		; Byte pointer to start of text buffer
cm.ptr  =	$06		; Byte pointer to Next Input to be parsed
cm.inc  =	$08		; Number of characters left in buffer
cm.cnt  =	$09		; Space left in buffer
cminf1  =	$0a		; Information passed to comnd routines
cminf2  =	$0c
cmdptr	=	cminf2		;  Pointer to default for parse
cmkptr  =	$0e		; Pointer for Cmkeyw routine
cmsptr  =	$10		; Saved character pointer
cmspt2  =	$12		; Saved keyword table pointer
cmspt3  =	$14		; Saved buffer pointer
cmhptr  =	$24		; Ptr. to current help text
cmptab  =	$26		; Ptr. to beginning of current keyword table
cmfcb	=	$1a		; Pointer to FCB
cmehpt	=	$1c		; Pointer to help commands

.SBTTL	COMND package entry points

;
;	The following addresses are locations in a jump table which
;	dispatch to appropriate routines in the Comnd package.
;

mul16	=	comnd+3		; 16-bit multiply routine
prcrlf	=	mul16+3		; Routine to print a crelf
prstr	=	prcrlf+3	; Routine to print an ASCIZ string
rskp	=	prstr+3		; Routine to skip 3 bytes on return
setbrk	=	rskp+3		; Routine to set a break char in brkwrd
rstbrk	=	setbrk+3	; Routine to reset break char in brkwrd

.SBTTL  COMND JSYS routines

;
;	The following set of routines provides a user oriented way of parsing
;	commands. It is similar to that of the COMND JSYS in TOPS-20. For
;	convenience, a dispatch table is used.
;

comnd:  jmp	comand		;  Dispatch to main command routine
	jmp	ml16		;  Dispatch to 16-bit multiply routine
	jmp	prcl.0		;  Dispatch to Prcrlf
	jmp	prst.0		;  Dispatch to Prstr
	jmp	rskp.0		;  Dispatch to Rskp
	jmp	sbrk.0		;  Dispatch to Setbrk
	jmp	rbrk.0		;  Dispatch to Rstbrk

.SBTTL  	Storage Declarations

;
;	Following is the storage decalarations for the Comnd routines
;

cmbuf:  .blkb	$100		; Input command buffer
atmbuf:	.blkb	$100		;  Atombuffer, (for cmtxt and cmifil)
lenabf:	.byte			;  Length of atom in Atombuffer
brkwrd:	.blkb	$16		;  Break mask
savea:  .byte			;
savex:  .byte			;
savey:  .byte			;
cmbase: .byte			; Base of integer to be parsed
cmmres: .blkb	4		; Return value from cmmult call
cmintg: .blkb	4		; Return value for cminum call
cmfltp: .blkb	6		; Return value for cmflot call
cmflen: .byte			; Field length
cmcdrv: .byte			; Current drive
cmostp: .word			; Save area for stack pointer
cmrprs: .word			; Reparse address
cmaflg: .byte			; Non-zero when an action char has been found
cmcffl:	.byte	0		;  Non-Zero when previous command failed
cmfrcf:	.byte	0		;  Non-Zero when signif char has been seen
cmccnt: .byte			; Non-zero if a significant char is found
cmocnt:	.byte			;  Saved length of command buffer
cmoptr:	.word			;  Saved ptr to command buffer for <ctrl/H>
cmsflg: .byte			; Non-zero when the last char was a space
cmstat: .byte			; Save area for parse type
cmprmx:	.byte			;  Hold area for Comnd parameters
cmprmy:	.byte			;  Hold area for Comnd flags
cmkyln: .byte			; Keyword length
cmtlen: .byte			; Test length (for ?-prompting)
cmscrs: .byte			; Screen output switch
cmentr: .byte			; Number of remaining entries in table
cmehix:	.byte			;  Index to extra help command buffer
keylen: .byte			; Keyword length
cmwrk1: .byte			; Command processing scratch area
cmwrk2: .byte			;
cmwrk3: .byte			;
cmwrk4: .byte			;

.SBTTL  Symbol definitions

true	=	$01		; Symbol for true return code
false	=	$00		; Symbol for false return code
on	=	$01		; Symbol for value of 'on' keyword
off	=	$00		; Symbol for value of 'off' keyword
yes	=	$01		; Symbol for value of 'yes' keyword
no	=	$00		; Symbol for value of 'no' keyword

.SBTTL	Prompt subroutine

;
;	This routine prints the prompt for the program and specifies the
;	reparse address.
;
;		Inputs:		X - L.O. byte address of prompt
;				Y - H.O. byte address of prompt
;
;		Outputs:
;
;		Registers destroyed:	A,X,Y
;

prompt: pla
	sta	cmrprs
	pla
	sta	cmrprs+1
	pha		
	lda	cmrprs		;  address to the stack
	pha
	clc			; Clear the carry
	adc	#$01		; Increment this address since it is one
	sta	cmrprs		;	short of the desired target.
	lda	cmrprs+1	; Accoutnt for the carry, if any
	adc	#$00		;
	sta	cmrprs+1	;
	stx	cm.rty		;  Save the address of the prompt in
	sty	cm.rty+1	; pointer to the ctrl/r text
	tsx			; Get the stack pointer
	stx	cmostp		; Save it for later restoral
	lda	#cmbuf\		; Init start of text buffer
	sta	cm.bfp		;
	sta	cm.ptr		; Init next input to be parsed
	lda	#cmbuf^		;
	sta	cm.bfp+1	;
	sta	cm.ptr+1	;
	lda	#$00		; Clear AC
	sta	cmaflg		; Clear the flags
	sta	cmccnt		;
	sta	cmsflg		;
	jsr	prcrlf		; Print crlf
	ldx	cm.rty		; Get L.O. byte of prompt address to be passed
	ldy	cm.rty+1	; Get H.O. byte of prompt address
	jsr	prstr		; Print the prompt
	rts			; Return

.SBTTL	Repars routine

;
;	This routine sets stuff up to reparse the current command
;	buffer.
;
;		Input:
;
;		Output:		Reinitialize comnd pointers and flags
;
;		Registers destroyed:	A,X
;

repars: ldx	cmostp		; Fetch old Stack pointer
	txs			; Make it the current one
	lda	#cmbuf\		; Get L.O. byte address of cmbuf
	sta	cm.ptr		; Stuff it
	lda	#cmbuf^		; Get H.O. byte address of cmbuf
	sta	cm.ptr+1	; The buffer pointer is now reset
	lda	#$00		; Clear AC
	sta	cmsflg		; Clear the space flag
	jmp	(cmrprs)	; Jump at the reparse address

.SBTTL	Prserr routine

;
;	This routine is used when a parsing error occurs. It resets ALL
;	of the pointers and flags and then goes to the reparse address.
;
;		Input:
;
;		Output:
;
;		Registers destroyed:
;

Prserr:	lda	cm.ptr		;  Store old command line pointer
	sta	cmoptr		; 
	lda	cm.ptr+1	; 
	sta	cmoptr+1	; 
	lda	cmccnt		;  Store old character count
	sta	cmocnt		; 
	lda	#$ff		;  Set the failure flag
	sta	cmcffl		;
	ldx	cmostp		; Fetch the saved SP
	txs			; Make it the current one
	lda	cmbuf\		; Set up the command buffer
	sta	cm.bfp		; address in both the
	sta	cm.ptr		; buffer pointer and the next input pointer.
	lda	#cmbuf^		;
	sta	cm.bfp+1	;
	sta	cm.ptr+1	;
	lda	#$00		; Clear AC
	sta	cmaflg		; Zero the action flag
	sta	cmccnt		;	the character count
	sta	cmsflg		;	and the space flag
	jsr	prcrlf		; Print a crelf
	ldx	cm.rty		;  Get the address of the prompt
	ldy	cm.rty+1	;
	jsr	prstr		; Reprint the prompt
	jmp	(cmrprs)	; Jump at the reparse address

.SBTTL	COMND - Entry point for command Jsys stuff

;
;	COMND routine - This routine checks the code in the AC for
;	what parse type is wanted and then dispatches to an appropriate
;	routine to look for it. Additional information is located in
;	CMINF1 and CMINF2 on page zero.
;
;		Input:		A - parse type
;				X,Y - optional parameters
;
;		Output:		A - +1 = success
;				    +4 = failure (assumes JMP after call)
;
;		Registers destroyed:	A
;

comand: sta	cmstat		; Save what we are parsing
	stx	cmprmx		;  Save these parameters also
	sty	cmprmy		; 
	cmp	#cmini		; Initialize the world?
	bne	comn0		; No, handle like a normal parse type
	jmp	prompt		; Do the prompt routine to set things up
comn0:  jsr	cminbf		; Get characters until action or erase
	cmp	#cmcfm		; Parse a confirm?
	bne	comn1		; Nope
	jmp	cmcfrm		; Yes, try for the confirm
comn1:  cmp	#cmkey		; Parse a keyword perhaps?
	bne	comn2		; No, next item
	jmp	cmkeyw		; Get the keyword
comn2:  cmp	#cmifi		; Parse an input file?
	bne	comn3		; No, try next one
	jmp	cmifil		; Get the input file
comn3:  cmp	#cmofi		; Parse an output file?
	bne	comn4		; No, try next
	jmp	cmofil		; Get the output file
comn4:  cmp	#cmswi		; Parse a switch?
	bne	comn5		; No, try next again
	jmp	cmswit		; Yes, do a switch
comn5:  cmp	#cmnum		; Parse an integer?
	bne	comn6		; No, try next type
	jmp	cminum		; Do the parse integer routine
comn6:  cmp	#cmfls		; Parse a floating point?????
	bne	comn7		; Nope, thats it for types
	jmp	cmflot		; Yes, go get a floating point number
comn7:	cmp	#cmtxt		;  Parse for an unquoted string?
	bne	comn8		;  Nope, go try last type
	jmp	cmunqs		;  Go parse the string
comn8:	cmp	#cmtok		;  Parse for a single character?
	bne	comn9		;  Nope, no more parse types
	jmp	cmtokn		;  Go parse for char
comn9:  ldx	#cmer00\	; Error 0 - Bad parse type
	ldy	#cmer00^
	jsr	prstr		; Print the error text
	lda	#$04		; Fail
	rts			; Return to caller

.SBTTL	Cmcfrm routine - get a confirm

;
;	This routine tries to get a confirm from the command input
;	buffer.
;
;		Input:  Cm.ptr  - Beginning of next field to be parsed
;
;		Output: On success, routine skip returns
;
;		Registers destroyed:	A,X,Y
;

cmcfrm: lda	cm.ptr		; Save the current comand line pointer
	pha
	lda	cm.ptr+1
	pha
cmcfr0: jsr	cmgtch		; Get a character
	cmp	#$00		; Is it negative?
	bpl	cmcfrr		; No, fail
	and	#$7f		; Yes, zero the sign bit
	cmp	#esc		; An escape?
	bne	cmcfr2		; No, continue
	jsr	bell		; Sound bell, er
	lda	#$00		; Clear AC
	sta	cmaflg		; Clear the action flag
	sec			; Set carry for subtraction
	lda	cm.bfp		; Get L.O. byte
	sbc	#$01		; Decrement it once
	sta	cm.bfp		; Store it back
	sta	cm.ptr		; Make this pointer look like the other one
	bcs	cmcfr1		; If set, we don't have to do H.O. byte
	dec	cm.bfp+1	; Adjust H.O. byte
cmcfr1: lda	cm.bfp+1	; Move this to H.O. byte of the other pointer
	sta	cm.ptr+1
	dec	cmccnt		; Decrement the character count
	jmp	cmcfr0		; Try again.
cmcfr2: cmp	#'?		; User need help??
	bne	cmcfr3		; Nope
	jsr	cout		; Print the '?'
	ldx	#cmin00\	; Get address of some help info
	ldy	#cmin00^	;
	jsr	prstr		; Print it.
	jsr	prcrlf		; Print the crelf
	ldx	cm.rty		;  Get address of prompt
	ldy	cm.rty+1	;
	jsr	prstr		; Reprint the prompt
	lda	#$00		; Clear AC
	ldy	#$00		; Clear Y
	sta	(cm.ptr),y	; Drop null at end of command buffer
	sec			; Set carry for subtraction
	lda	cm.bfp		; Get L.O. byte
	sbc	#$01		; Decrement it
	sta	cm.bfp		; Store it back
	lda	cm.bfp+1	; Now do H.O. byte
	sbc	#$00		;
	sta	cm.bfp+1	;
	ldx	#cmbuf\		; Get address of the command buffer
	ldy	#cmbuf^		;
	jsr	prstr		; Reprint the command line
	lda	#$00		; Clear AC
	sta	cmaflg		; Action flag off
	jmp	repars		; Go reparse the line
cmcfr3: cmp	#ffd		; Is it a form feed?
	bne	cmcfr4		; Nope
	jsr	home		; Yes, blank the screen
cmcfr4: pla			; Since this succeeded, we can flush the
	pla			;	old command line pointer
	lda	#$00		;  Reset the failure flag
	sta	cmcffl		; 
	jmp	rskp		; Do a return skip

cmcfrr: pla			;  Restore the old comand line pointer
	sta	cm.ptr+1	; 
	sta	cmoptr+1	; 
	pla			; 
	sta	cm.ptr		; 
	sta	cmoptr		; 
	lda	cmccnt		;  Save count in case of <ctrl/H>
	sta	cmocnt		; 
	lda	#$ff		;  Set failure
	sta	cmcffl		; 
	rts			; Return

.SBTTL	Cmkeyw - Try to parse a keyword next

;
;	This routine tries to parse a keyword from the table
;	pointed to by cminf1. The keywords must be in alphabetical
;	order. The routine returns the two bytes of data associated
;	with the keyword. The format of the table is as follows:
;
;	addr:	.byte	n	; Where n is the # of entries in the table.
;		.byte	m	; m is the size of the next keyword
;		.asciz  /string/; keyword ending in a null
;		.byte	a,b	; 16 bits of data related to keyword
;
;		Input:  Cminf1- Pointer to keyword table
;
;		Output: X-	byte a
;			Y-	byte b
;
;		Registers destroyed:	A,X,Y
;

cmkeyw: lda	cm.ptr		; Save the old comand line pointer
	pha			;
	lda	cm.ptr+1
	pha			;
	lda	#$00		;  Clear the 'real character' flag
	sta	cmfrcf		; 
	lda	cminf1		; Copy to address of
	sta	cmptab		;	the keyword table
	clc			; Clear the carry
	adc	#$01		; Add one to the addr. (pass the table length)
	sta	cmkptr		; Save the keyword pointer (L.O. byte)
	lda	cminf1+1	; Get H.O. byte
	sta	cmptab+1	; Save a copy of that
	bcc	cmkey1		; Carry?
	adc	#$00		; Add in the carry for cmkptr
cmkey1: sta	cmkptr+1	; Save it
	ldy	#$00		; Clear Y
	lda	(cmptab),y	; Get the table length
	sta	cmentr		; Save number of entries in the table
cmky10:	jsr	cmgtch		; Get first character
	cmp	#$00		; Was the first character a terminator?
	bmi	cmky11		; Yup, the saved pointer does not get decr.
	sec			; Make sure saved buffer pointer is correct
	lda	cm.ptr		; Now, reset it back one character for later
	sbc	#$01		;
	sta	cm.ptr		;
	sta	cmsptr		;
	lda	cm.ptr+1	;
	sbc	#$00		;
	sta	cm.ptr+1	;
	sta	cmsptr+1	;
	jmp	cmkey2		; Continue
cmky11: ldy	cm.ptr		; Just move the pointer to the save area
	sty	cmsptr		;
	ldy	cm.ptr+1	;
	sty	cmsptr+1	;
	and	#$7f		; [EL] ????
	cmp	#esc		;  Was the first terminator an escape?
	beq	cmky12		;  Yes, handle this
	jmp	cmkey2		;  No, continue
cmky12:	lda	#cmfdff		;  Is there a default?
	bit	cmprmy		; 		...
	bne	cmky13		;  Yes, go copy it
	lda	#$00		;  Shut the action flag
	sta	cmaflg		; 		...
	jsr	bell		;  Yes, start by feeping terminal
	sec			;  Set the carry bit for subtraction
	lda	cm.bfp		;  Take L.O. byte of buffer pointer
	sbc	#$01		;  Decrement it (back up before escape)
	sta	cm.bfp		;  Store it
	sta	cm.ptr		;  And stuff it in next input char pointer
	bcs	cmkync		;  If carry is clear, we are done
	dec	cm.bfp+1	;  Do the carry on H.O. byte
cmkync:	lda	cm.bfp+1	;  Copy this to next char to parse pointer
	sta	cm.ptr+1	; 		...
	jmp	cmky10		;  Continue by fetching a character again
cmky13:	lda	#$00		;  Zero the action flag
	sta	cmaflg		; 		...
	jmp	cmcpdf		;   Do the copy	
cmkey2: lda	cmentr		; Get number of entries left
	cmp	#$00		; 0 entries left?
	bne	cmky21		; No, go try next entry
	pla			; Fetch back to previous comand line pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr+1	;		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		;		...
	lda	cmccnt		; Save count in case of <ctrl/H>
	sta	cmocnt		;		...
	lda	#$ff		; Set the command-failure flag
	sta	cmcffl		;		...
	rts
cmky21: ldy	#$00		; Clear Y
	lda	(cmkptr),y	; Get length of keyword
	sta	keylen		; Store it
	lda	cmkptr		; Get the new table pointer
	sta	cmspt2		;	and save it for later
	lda	cmkptr+1	;		...
	sta	cmspt2+1	;		...
	inc	cmkptr		; Increment the L.O. byte once
	bne	cmkey3		; If it didn't wrap, there is no carry
	inc	cmkptr+1	; There was a carry, add it in.
cmkey3: dec	keylen		; Decrement the number of chars. left
	lda	keylen		; Get the remaining length
	cmp	#$ff		; Have we passed the end
	bpl	cmk3a		; No
	jmp	cmkey5		; Yes
cmk3a:  jsr	cmgtch		; Get a character
	cmp	#$00		; Is it a terminator?
	bmi	cmk3b		; Yup, it is negative
	jmp	cmkey4		; Nope, it's positive
cmk3b:  and	#$7f		; Shut off the minus bit
	cmp	#'?		; Need any help?
	bne	cmky31		; Nope
	jsr	cout		; And print the question mark
	lda	#$00		; Clear AC
	sta	cmaflg		; Clear the action flag
	lda	cmstat		; Get saved parse type
	cmp	#cmswi		; Are we really doing a switch?
	beq	cmk3b1		; Yes, give that message instead
	ldx	#cmin01\	; L.O. byte addr of informational message
	ldy	#cmin01^	; H.O. byte of addr
	jmp	cmk3b2		; Go print the message
cmk3b1: ldx	#cmin02\	; Load address of switch message
	ldy	#cmin02^	;		...
cmk3b2: jsr	prstr		; Print the message
	jsr	prcrlf		; Print a crelf
	jsr	cmktp		;	and the valid entries in keyword table
	jsr	prcrlf		; Print another crlf
	lda	#cmfehf		;  Load extra help flag
	bit	cmprmy		;  Test bit
	beq	cmk3b3		;  No extra help
	jsr	cmehlp		;  Go give extra help
cmk3b3:	ldx	cm.rty		; Get  address of prompt
	ldy	cm.rty+1	; 
	jsr	prstr		; Reprint the prompt
	lda	#$00		; Clear AC
	ldy	#$00		; Clear Y
	sta	(cm.ptr),y	; Stuff a null in the buffer at that point
	sec			; Set the carry
	lda	cm.bfp		; Get ready to decrement buffer pointer
	sbc	#$01		; Subtract it
	sta	cm.bfp		; Store it
	bcs	cmky3a		; Do we have to account for carry
	dec	cm.bfp+1	; Decrement the H.O. byte
cmky3a: ldx	#cmbuf\		; Get  address of buffer
	ldy	#cmbuf^		;
	jsr	prstr		; Reprint the command line
	jmp	repars		; Go reparse all of it
cmky31: cmp	#esc		; escape character?
	beq	cmk3c		; Yup, process it
	jmp	cmky35		; Nope.
cmk3c:  lda	#$00		; Clear AC
	sta	cmaflg		; Clear action flag
	lda	keylen		; Save on the stack, the
	pha			;	keylength
	lda	cmentr		;	number of entries left
	pha			;		...
	lda	cmkptr		;	L.O. byte of keyword table pointer
	pha			;		...
	lda	cmkptr+1	;	H.O. byte of keyword table pointer
	pha			;		...
	jsr	cmambg		; Is it ambiguous?
	 jmp	cmky32		; Nope
	lda	#cmfdff		;  Load the default-present flag
	bit	cmprmy		;  Check against flags
	beq	cmk3d		;  No, complain to user
	lda	cmfrcf		;  Have we seen a real character yet?
	bne	cmk3d		;  No, tell user
	jmp	cmcpdf		;  Yes, go copy the default
cmk3d:	jsr	bell		; Yes, start by feeping terminal
	sec			; Set the carry bit for subtraction
	lda	cm.bfp		; Take L.O. byte of buffer pointer
	sbc	#$01		; Decrement it (back up before escape)
	sta	cm.bfp		; Store it
	sta	cm.ptr		; And stuff it in next input char pointer
	bcs	cmky3b		; If carry is clear, we are done
	dec	cm.bfp+1	; Do the carry on H.O. byte
cmky3b: lda	cm.bfp+1	; Copy this to the next char to parse pointer
	sta	cm.ptr+1	;		...
	dec	cmccnt		; Decrement the character count
	pla			;		...
	sta	cmkptr+1	; Restore the keyword table pointer
	pla			;		...
	sta	cmkptr		;
	pla			;
	sta	cmentr		;	Number of entries left in table
	pla			;		...
	sta	keylen		;	And the remaining keylength
	inc	keylen		; Adjust the keylength to make it correct
	jmp	cmkey3		; And go back to try again
cmky32: ldy	#$00		; Clear Y
	sec			; Set the carry flag
	lda	cm.bfp		; Move buffer pointer behind the escape
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	sta	cm.ptr		;		...
	bcs	cmk32c		;		...
	dec	cm.bfp+1	; Have to adjust the H.O. byte
cmk32c: lda	cm.bfp+1	;		...
	sta	cm.ptr+1	;		...
	pla			; Fetch the old keytable pointer
	sta	cmkptr+1	;		...
	pla			;		...
	sta	cmkptr		;		...
	pha			; Now push it back on the stack
	lda	cmkptr+1	;		...
	pha			;		...
cmky33: lda	(cmkptr),y	; Get next character
	cmp	#$00		; Done?
	beq	cmky34		; Yes
	tax			; No, hold on to the byte
	clc			; Clear the carry flag
	lda	cmkptr		; Adjust the keyword pointer up one place
	adc	#$01		; Do L.O. byte
	sta	cmkptr		; Store it
	bcc	cmky3c		; Carry?
	inc	cmkptr+1	; Yes, increment H.O. byte
cmky3c: txa			; Get the data
	sta	(cm.ptr),y	; Stuff it in the buffer
	clc			; Clear the carry flag again
	lda	cm.ptr		; Get L.O byte of buffer pointer
	adc	#$01		; Increment it
	sta	cm.ptr		; Store it
	bcc	cmky3d		; Carry?
	inc	cm.ptr+1	; Increment H.O. byte
cmky3d: inc	cmccnt		; Increment character count
	jmp	cmky33		; Get next character from table
cmky34: inc	cmccnt		; Incrment the character count
	lda	#$a0		; Clear AC (this is a terminator!)
	sta	(cm.ptr),y	; Stuff a null in the buffer
	ldx	cm.bfp		; Get L.O. byte of buffer pointer
	ldy	cm.bfp+1	;	and H.O byte - save these for later
	clc			; Clear carry
	lda	cm.ptr		; Increment next char of input pointer
	adc	#$01		;		...
	sta	cm.ptr		;		...
	sta	cm.bfp		;		...
	bcc	cmky3e		; Carry?
	inc	cm.ptr+1	; Do H.O. byte
cmky3e: lda	cm.ptr+1	; Make buffer pointer match next char pointer
	sta	cm.bfp+1	;		...
	sty	savey		; Hold y for a bit
	lda	#$00		; Put a null in the buffer to terminate string
	ldy	#$00		;		...
	sta	(cm.ptr),y	;		...
	ldy	savey		; Get Y value back
	jsr	prstr		; Print remainder of keyword
	pla			; Restore the
	sta	cmkptr+1	;	H.O. byte of keyword table pointer
	pla			;		...
	sta	cmkptr		; 	L.O. byte of keyword table pointer
	pla			;		...
	sta	cmentr		;	Number of entries left in table
	pla			;		...
	sta	keylen		;	And the remaining keylength
	jmp	cmky37		; Go get some data to return
cmky35: lda	cmkptr		; Save on the stack the  keyword table pointer
	pha			;
	lda	cmkptr+1	;
	pha			;		...
	lda	keylen		;	The keylength
	pha			;		...
	jsr	cmambg		; Check for ambiguity
	 jmp	cmky36		; Not ambiguous
	ldx	#cmer01\	; Get addr of ambiguous error
	ldy	#cmer01^	;		...
	jsr	prstr		; Print the error message
	jmp	prserr		; Go do parsing error stuff
cmky36: pla			; Fetch off of the stack 
	sta	keylen		;	remaining keylength
	pla			;		...
	sta	cmkptr+1	;	H.O. byte of keyword table address
	pla			;		...
	sta	cmkptr		; 	L.O. byte of keyword table address
cmky37: inc	keylen		; Adjust the remaining keylength
	inc	keylen		;		...
	clc			; Clear the carry flag
	lda	cmkptr		; Get the keyword table pointer
	adc	keylen		; Add in remaining keylength
	sta	cmkptr		; Store it
	bcc	cmky3f		; Carry?
	inc	cmkptr+1	; Yes, adjust H.O. byte
cmky3f: ldy	#$00		; Make sure Y is clear
	lda	(cmkptr),y	; Get first data byte
	tax			; Put it in X
	iny			; Up the index once
	lda	(cmkptr),y	; Get the second data byte
	tay			; Put that in Y
	pla			; Flush the old comand line pointer
	pla			;		...
	lda	#$00		; Reset the failure flag
	sta	cmcffl		; 
	jmp	rskp		; Return skip means it succeeds!
cmkey4: cmp	#$61		; Check range for lower case
	bmi	cmky41		;		...
	cmp	#$7b		;		...
	bpl	cmky41		;		...
	and	#$5f		; Cutesy way to capitalize it
cmky41: sta	cmwrk3		; Save the character
	lda	#$ff		;  Set the 'real character' flag
	sta	cmfrcf		; 
	ldy	#$00		; Clear Y again
	lda	(cmkptr),y	; Get next keyword byte
	sta	cmwrk4		; Hold that for now
	clc			; Clear the carry flag
	lda	cmkptr		; Get L.O. byte of keyword pointer
	adc	#$01		; Add one
	sta	cmkptr		; Store it
	bcc	cmky4a		; Need to do carry?
	inc	cmkptr+1	; Yes, do H.O. byte
cmky4a: lda	cmwrk3		; Get input character
	cmp	cmwrk4		; Does it match keyword character?
	bne	cmkey5		; No, advance to next keyword in table
	jmp	cmkey3		; Yup, try next input byte
cmkey5: inc	keylen		; Adjust keylength so that it is correct
	inc	keylen		;		...
	inc	keylen		;		...
	clc			; Clear carry
	lda	cmkptr		; Ok, get keyword pointer and
	adc	keylen		; Add the remaining keylength
	sta	cmkptr		; Store it
	bcc	cmky5a		; See if we have to do carry
	inc	cmkptr+1	; Yes, increment H.O. byte
cmky5a: dec	cmentr		; Decrement the number of entries left
	lda	cmsptr		; Get the saved buffer pointer and
	sta	cm.ptr		;	restore it
	lda	cmsptr+1	;		...
	sta	cm.ptr+1	;		...
	jmp	cmkey2		; Try to parse this keyword now

.SBTTL	Cmambg - check if keyword prefix is ambiguous

;
;	This routine looks at the next keyword in the table and
;	determines if the prefix entered in the buffer is ambiguous
;	or not. If it is ambiguous, it skip returns, otherwise it
;	returns normally.
;
;		Input:  Cmentr- number of entries left in table
;			Cmkptr- current keyword table pointer
;			Keylen- remaining keyword length
;
;		Output: If ambiguous, does a skip return
;
;		Registers destroyed:	A,X,Y
;

cmambg: dec	cmentr		; Start by decrementing remaining entries
	bpl	cma1		; We still have stuff left
	rts			; Nothing left, it can't be ambiguous
cma1:	inc	keylen		; Adjust this up by one
	lda	keylen		; Save character count
	sta	cmwrk3		;		...
	clc			; Clear the carry
	adc	#$03		; Adjust the keylength to include terminator
	sta	keylen		;	and data bytes
	clc			; Clear carry
	lda	cmkptr		; Up the keyword table pointer
	adc	keylen		;	by remaining keylength
	sta	cmkptr		; Save it
	bcc	cma2		; Need to adjust H.O byte?
	inc	cmkptr+1	; Yes, do it
cma2:	ldy	#$00		; Clear Y
	lda	(cmkptr),y	; Get keyword length
	sta	cmwrk4		; Hold that byte
	clc			; Clear carry
	lda	cmkptr		; Advance keyword table pointer
	adc	#$01		;		...
	sta	cmkptr		;		...
	bcc	cma3		;		...
	inc	cmkptr+1	;		...
cma3:	lda	(cmspt2),y	; Get previous keyword length
	sec			; Set carry
	sbc	cmwrk3		; Subtract number of characters left
	beq	cmambs		;  If test len is 0, don't bother trying
	sta	cmtlen		; This is the testing length
	cmp	cmwrk4		; Check this against length of new keyword
	bmi	cmamb0		; This may be ambiguous
	rts			; Test length is longer, cannot be ambiguous
cmamb0: ldy	#$00		; Clear Y
cmamb1: dec	cmtlen		; Decrement the length to test
	bpl	cma4		; Still characters left to check
cmambs:	jmp	rskp		;  The whole thing matched, it is ambiguous
cma4:	lda	(cmkptr),y	; Get next character of keyword
	sta	cmwrk3		; Hold that for now
	lda	(cmsptr),y	; Get next parsed character
	iny			; Up the pointer once
	cmp	#$61		; Check the range for lower case
	bmi	cmamb2		;		...
	cmp	#$7b		;		...
	bpl	cmamb2		;		...
	and	#$5F		; Capitalize it
cmamb2:	and	#$7f		; Reset the H.O. bit
	cmp	cmwrk3		; Same as keyword table character
	beq	cmamb1		; Yup, check next character
	rts			; Nope, prefix is not ambiguous


.SBTTL	Cmktp - print entries in keyword table matching prefix

;
;	This routine steps through the keyword table passed to cmkeyw
;	and prints all the keywords with the prefix currently in the
;	command buffer. If there is no prefix, it issues an error.
;
;		Input:  Cmptab- ptr to beginning of table
;			Cmsptr- saved buffer pointer
;			Cm.ptr- current buffer pointer
;
;		Output: List of possible keywords to screen
;
;		Registers destroyed:	A,X,Y
;

cmktp:  lda	cmptab		; Get a copy of the pointer
	sta	cminf2		;	to the beginning of
	lda	cmptab+1	;	the current keyword table
	sta	cminf2+1	;		...
	ldy	#$00		; Clear Y
	sty	cmscrs		; Clear the 'which half of screen' switch
	sty	cmwrk3		; Clear the 'print any keywords?' switch
	lda	(cminf2),y	; Get the table length
	sta	cmwrk1		;	and save it in a safe place
	sec			; Prepare for some subtracting
	lda	cm.ptr		; Get difference between the current pointer
	sbc	cmsptr		;	and pointer to beginning of keyword
	sta	cmtlen		; That is how much we must test
	clc			; Clear carry
	lda	cminf2		; Increment the pointer to the table
	adc	#$01		;		...
	sta	cminf2		;		...
	bcc	cmktp1		; Need to increment H.O. byte?
	inc	cminf2+1	; Yup
cmktp1: dec	cmwrk1		; 1 less keyword to do
	lda	cmwrk1		; Now...
	bmi	cmkdon		; No keywords left, we are done
	lda	(cminf2),y	; Get the keyword length
	sta	cmkyln		;	and stuff it
	clc			; Clear carry
	lda	cminf2		; Increment pointer to table again
	adc	#$01		;		...
	sta	cminf2		;		...
	bcc	cmktp2		; Need to up the H.O. byte?
	inc	cminf2+1	; Yup
cmktp2: lda	cmtlen		; Get test length
	beq	cmktp3		; If test length is zero, just print keyword
cmkp21: lda	(cminf2),y	; Get character from table
	cmp	(cmsptr),y	; Compare it to the buffer character
	bne	cmadk		; Nope, advance to next keyword
	iny			; Up the index
	cpy	cmtlen		; Compare with the test length
	bmi	cmkp21		; Not yet, do next character
cmktp3: jsr	cmprk		; Print the keyword

cmadk:  inc	cmkyln		; Adjust cmkyln to include terminator and data
	inc	cmkyln		;		...
	inc	cmkyln		;		...
	clc			; Clear the carry
	lda	cminf2		; Get the L.O. byte
	adc	cmkyln		; Add in the keyword length
	sta	cminf2		; Store it away
	bcc	cmadk2		; Need to do the H.O. byte?
	inc	cminf2+1	; Yup
cmadk2: ldy	#$00		; Zero the index
	jmp	cmktp1		; Go back to the top of the loop

cmkdon: lda	cmwrk3		; See if we printed anything
	bne	cmkdn2		; Yup, go exit
	lda	cmstat		; Are we parsing switches or keywords?
	cmp	#cmswi		;		...
	beq	cmkdse		; The error should be for switches
	ldx	#cmer03\	; Nope, get address of error message
	ldy	#cmer03^	;		...
	jmp	cmkdn1		; Go print the message now
cmkdse: ldx	#cmer04\	; Get address of switch error message
	ldy	#cmer04^	;		...
cmkdn1: jsr	prstr		; Print error
	jsr	prcrlf		; Print a crelf
cmkdn2: lda	cmscrs		; Where did we end up?
	beq	cmkdn3		; Beginning of line, good
	jsr	prcrlf		; Print a crelf
cmkdn3: rts			; Return

;
;	Cmprk - prints one keyword from the table. Consults the
;		cmscrs switch to see which half of the line it
;		is going to and acts accordingly.
;
;		Input:  Cmscrs- Which half of screen
;			Cminf2- Pointer to string to print
;
;		Output: print keyword on screen
;
;		Registers destroyed:	A,X,Y
;

cmprk:  lda	#on		; Make sure to tell them we printed something
	sta	cmwrk3		; Put it back
	lda	cmstat		; Get saved parse type
	cmp	#cmswi		; Is it a switch we are looking for?
	bne	cmpr2		;
	lda	#'/		; Yes, do not forget slash prefix
	jsr	cout		; Print slash
cmpr2:  ldx	cminf2		; L.O. byte of string pointer
	ldy	cminf2+1	; H.O. byte of string pointer
	jsr	prstr		; Print the keyword
	lda	cmscrs		; Where were we?
	bne	cmprms		; Mid screen
	jsr	clreol		; Clear to end of line
	lda	#$14		; Advance cursor to middle of screen
	sta	ch		;		...
	ldy	ch		; [DD]
	ldx	cv		; [DD]
	clc			; [DD]
	jsr	plot		; [DD]
	jmp	cmprdn		; We are done
cmprms: jsr	prcrlf		; Print a crelf
cmprdn: lda	cmscrs		; Flip the switch now
	eor	#$01
	sta	cmscrs		; Stuff it back
	rts			; Return

.SBTTL	Cmswit - try to parse a switch next

;
;	This routine tries to parse a switch from the command buffer. It
;	first looks for the / and then calls cmkeyw to handle the keyword
;	lookup.
;
;		Input:  Cminf1- Address of keyword table
;
;		Output: X-	byte a
;			Y-	byte b
;
;		Registers destroyed:	A,X,Y
;

cmswit: lda	cm.ptr		; Save the old comand line pointer
	pha			;	user wants to try another item
	lda	cm.ptr+1	;		...
	pha			;		...
cmswi0: jsr	cmgtch		; Go get a character
	cmp	#$00		; Action?
	bmi	cmswi1		; Yes, process it
	jmp	cmswi3		; No, it is a real character
cmswi1: and	#$7f		; Turn off the minus
	cmp	#'?		; Does the user need help?
	bne	cmsw12		; No
	jsr	cout		; And print the question mark
	lda	#$00		; Clear AC
	sta	cmaflg		; Clear Action flag
	ldx	#cmin02\	; Low order byte addr of info message
	ldy	#cmin02^	; High order byte addr of info message
	jsr	prstr		; Print the message
	jsr	prcrlf		; Print a crelf
	jsr	cmktp		; Any valid entries from keyword table
	jsr	prcrlf		; And another crelf
	lda	#cmfehf		;  Load extra help flag
	bit	cmprmy		;  Test bit
	beq	cmsw10		;  No extra help
	jsr	cmehlp		;  Go give extra help
cmsw10:	ldx	cm.rty		; Load the address of the prompt
	ldy	cm.rty+1	;
	jsr	prstr		; Reprint it
	lda	#$00		; Clear AC
	ldy	#$00		; Clear Y
	sta	(cm.ptr),y	; Stuff a null at the end of the buffer
	sec			; Set the carry flag
	lda	cm.bfp		; Increment buffer pointer
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	bcs	cmsw1a		; Borrow?
	dec	cm.bfp+1	; Yup
cmsw1a: ldx	#cmbuf\		; L.O. addr of command buffer
	ldy	#cmbuf^		; H.O. byte
	jsr	prstr		; Reprint the command line
	jmp	repars		; Go reparse everything
cmsw12: cmp	#esc		; Lazy??
	beq	cmsw2a		; Yes, try to help
	jmp	cmswi2		; No, this is something else
cmsw2a: lda	#$00		; Clear AC
	sta	cmaflg		; Clear action flag
	lda	#cmfdff		;  See if there is a default
	bit	cmprmy		; 
	beq	cmswnd		;  No help, tell user
	jmp	cmcpdf		;  Go copy the default
cmswnd:	jsr	bell		; Yes, it is ambiguous - ring bell
	sec			; Set carry
	lda	cm.bfp		; Decrement buffer pointer
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	sta	cm.ptr		; Make this pointer point there too
	bcs	cmsw2b		; No carry to handle
	dec	cm.bfp+1	; Do H.O. byte
cmsw2b: lda	cm.bfp+1	; Now make H.O. byte match
	sta	cm.ptr+1	;		...
	dec	cmccnt		; Decrement the character count
	jmp	cmswi0		; Try again
cmsw2c: lda	#'/		; Load a slash
	jsr	cout		; Print slash
	clc			; Clear carry
	lda	cminf1		; Set the keyword table pointer
	adc	#$02		;	to point at the beginning
	sta	cmkptr		;	of the keyword and move it
	lda	cminf1+1	;	to cmkptr
	bcc	cmsw2d		;		...
	adc	#$00		;		...
cmsw2d: sta	cmkptr+1	;		...
	ldy	#$00		; Clear Y
	sec			; Set carry
	lda	cm.bfp		; Increment the buffer pointer
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	bcs	cmsw2e		;		...
	dec	cm.bfp+1	;		...
cmsw2e: lda	(cmkptr),y	; Get next character
	cmp	#$00		; Done?
	beq	cmsw13		; Yes
	tax			; No, hold on to the byte
	clc			;	while we increment the pointer
	lda	cmkptr		; Do L.O. byte
	adc	#$01		;		...
	sta	cmkptr		;		...
	bcc	cmsw2f		; And, if neccesary
	inc	cmkptr+1	;	the H.O. byte as well
cmsw2f: txa			; Get the data
	sta	(cm.ptr),y	; Stuff it in the buffer
	clc			; Clear carry
	lda	cm.ptr		; Increment the next character pointer
	adc	#$01		;		...
	sta	cm.ptr		;		...
	bcc	cmsw2g		;		...
	inc	cm.ptr+1	;		...
cmsw2g: inc	cmccnt		; Increment the character count
	jmp	cmsw2e		; Get next character from table
cmsw13: inc	cmccnt		; Increment the character count
	lda	#$00		; Clear AC
	sta	(cm.ptr),y	; Stuff a null in the buffer
	ldx	cm.bfp		; Hold on to this pointer
	ldy	cm.bfp+1	;	for later printing of switch
	clc			; Clear carry
	lda	cm.ptr		; Now make both pointers look like
	adc	#$01		;	(cm.ptr)+1
	sta	cm.ptr		;		...
	sta	cm.bfp		;		...
	bcc	cmsw3a		;		...
	inc	cm.ptr+1	;		...
cmsw3a: lda	cm.ptr+1	; Copy H.O. byte
	sta	cm.bfp+1	;		...
	jsr	prstr		; Now print string with pointer saved earlier
	ldx	#$01		; Set up argument
	jsr	prbl2		; Print one blank
cmsw14: clc			; Clear carry
	lda	cmkptr		; Increment keyword pointer
	adc	#$01		; Past null terminator
	sta	cmkptr		;		...
	bcc	cmsw4a		;		...
	inc	cmkptr+1	;		...
cmsw4a: ldy	#$00		; Clear Y
	lda	(cmkptr),y	; Get first data byte
	tax			; Put it here
	iny			; Up the index
	lda	(cmkptr),y	; Get second data byte
	tay			; Put that in Y
	pla			; Flush the old comand line pointer
	pla			;		...
	lda	#$00		;  Clear the failure flag
	sta	cmcffl		; 		...
	jmp	rskp		; And give a skip return
cmswi2: ldy	#$00		; Clear Y
	lda	(cminf1),y	; Get length of table
	cmp	#$02		; Greater than 1
	bmi	cmsw21		; No, go fetch data
	ldx	#cmer01\	; Yes, fetch pointer to error message
	ldy	#cmer01^	;		...
	jsr	prstr		; Print the error
	jmp	prserr		; And go handle the parser error
cmsw21: iny			; Add one to the index
	lda	(cminf1),y	; Get the length of the keyword
	sta	keylen		; Save that
	lda	cminf1+1	; Copy pointer to table
	sta	cmkptr+1	;		...
	clc			; Get set to increment an address
	lda	cminf1		; Do L.O. byte last for efficiency
	adc	keylen		; Add in the keyword length
	adc	#$02		; Now account for table length and terminator
	sta	cmkptr		; Save the new pointer
	bcc	cmsw22		; If no carry, continue
	inc	cmkptr+1	; Adjust H.O. byte
cmsw22: jmp	cmsw4a		; Go to load data and skip return
cmswi3: cmp	#'/		; Is the real character a slash?
	beq	cmswi4		; Yes, go do the rest
	tax			; Move the data byte
	lda	#$00		; Clear AC
	pla			; Fetch back the old comand line pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr+1	; 		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		;		...
	lda	cmccnt		;  Save count in case of <ctrl/H>
	sta	cmocnt		;  
	lda	#$ff		;  Set failure  flag
	sta	cmcffl		; 		...
	rts			; Fail - non-skip return
cmswi4: jsr	cmkeyw		; Let Keyw do the work for us
	 jmp	cmswi5		; We had problems, restore comand ptr and ret.
	pla			; Flush the old comand pointer
	pla
	lda	#$00		;  Reset the failre flag
	sta	cmcffl		; 
	jmp	rskp		; Success - skip return!
cmswi5: pla			; Fetch back the old comand line pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr+1	; 		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		; 		...
	lda	cmccnt		;  Save count in case of <ctrl/H>
	sta	cmocnt		; 
	lda	#$ff		;  Set failure flag
	sta	cmcffl		; 
	rts			; Now return

.SBTTL	Cmifil - try to parse an input file spec next

;
;	This routine attempts to parse an input file spec.
;
;		Input:  X - Max filename length
;
;		Output: Filename parsed is in buffer pointed to by X,Y
;
;		Registers destroyed:	A,X,Y
;

cmifil: inx			;  Increment max file length for tests
	stx	cmprmx		;  Maximum filename length
	lda	cm.ptr		; Save the old comand line pointer in case
	pha			;
	lda	cm.ptr+1	;
	pha			;
	lda	#$00		; Zero the
	sta	lenabf		;  length of the atom buffer
cmifl0: ldy	#$00		; Zero Y
	lda	#'  		; Blank the AC 
;	ora	#$80		; Make it look like a terminator
cmifi0: sta	atmbuf,y	; Now zero the buffer
	iny			;		...
	cpy	cmprmx  	;  Done?
	bpl	cmifi1		; Yes, start parsing
	jmp	cmifi0		; No, continue blanking
cmifi1: jsr	cmgtch		; Get a character from command buffer
	cmp	#$00		; Is it an action character?
	bmi	cmif10		;  Yes, check it out
	jmp	cmifi2		;  No , process it as a normal character
cmif10:	and	#$7f		;  Yes, turn off the minus bit
	cmp	#'?		; Does the user need help?
	bne	cmif12		; Nope
	jsr	cout		; And print the question mark
	ldy	#$00		; Yes
	sty	cmaflg		; Clear the action flag
	ldx	#cmin03\	; Now get set to give the 'file spec' message
	ldy	#cmin03^	;		...
	jsr	prstr		; Print it
	jsr	prcrlf		; Print a crelf
	lda	#cmfehf		;  Load extra help flag
	bit	cmprmy		;  Test bit
	beq	cmifnh		;  No extra help
	jsr	cmehlp		;  Go give extra help
cmifnh:	ldx	cm.rty		;  Set up to reprint the prompt
	ldy	cm.rty+1	;		...
	jsr	prstr		; Do it
	sec			; Set the carry flag for subtraction
	lda	cm.bfp		; Get the buffer pointer
	sbc	#$01		; Decrement it once
	sta	cm.bfp		;		...
	bcs	cmif11		; If it's set, we need not do H.O. byte
	dec	cm.bfp+1	; Adjust the H.O. byte
cmif11: dec	cmccnt		; Decrement the character count
	ldy	#$00		; Clear Y
	lda	#$00		; Clear AC
	sta	(cm.bfp),y	; Stuff a null at the end of the command buffer
	ldx	#cmbuf\		; Now get the address of the command buffer
	ldy	#cmbuf^		;		...
	jsr	prstr		; Reprint the command line
	jmp	cmifi1		; Go back and continue
cmif12: cmp	#esc		; Got an escape?
	bne	cmif13		; No
	lda	#$00		; Yup, clear the action flag
	sta	cmaflg		;		...
	lda	#cmfdff		;  Load default-present flag
	bit	cmprmy		;  Test bit
	beq	cmifnd		;  No default
	lda	lenabf		;  Now check if user typed anything
	bne	cmifnd		;  Yup, can't use default
	jmp	cmcpdf		;  Go copy the default
cmifnd:	jsr	bell		; Escape does not work here, ring the bell
	sec			; Set carry for subtraction
	lda	cm.bfp		; Decrement the buffer pointer
	sbc	#$01		;	once
	sta	cm.bfp		;		...
	sta	cm.ptr		; Make both pointers look at the same spot
	lda	cm.bfp+1	;		...
	sbc	#$00		; H.O. byte adjustment
	sta	cm.bfp+1	;		...
	sta	cm.ptr+1	;		...
	dec	cmccnt		; Decrement the character count
	jmp	repars		;	and go reparse everything
cmif13: lda	lenabf		;  Get the length of the buffer
	cmp	#$00		; Is it zero?
	bne	cmif14		; No, continue
	jmp	cmifi9		; Yes, this is not good
cmif14: cmp	cmprmx  	;  Are we over the maximum file length?
	bmi	cmif15		; Not quite yet
	jmp	cmifi9		; Yes, blow up
cmif15: ldy	lenabf		;  Get the filename length
	lda	#nul		;	and stuff a null at that point
	sta	atmbuf,y	; 
	pla			; Flush the old comand line pointer
	pla			;		...
	ldx	#atmbuf\	;  Set up the atombuffer address
	ldy	#atmbuf^	;		...
	lda	#$00		;  Reset the failure flag
	sta	cmcffl		; 
	lda	lenabf		;  Load length into AC to be passed back
	jmp	rskp		; No, we are successful
cmifi2: cmp	#sp		;  Bad character?
	bmi	cmifi9		; Yes, blow up
	cmp	#del		; 
	bpl	cmifi9		; This is bad, punt
	cmp	#$61		; Lower case alphabetic?
	bmi	cmifi8		; Don't capitalize if it's not alphabetic
	cmp	#$7b		;		...
	bpl	cmifi8		;		...
	and	#$5f		; Capitalize
cmifi8: ldy	lenabf		;  Set up length of buffer in Y
	sta	atmbuf,y	;  Stuff character in FCB
	inc	lenabf		;  Increment the length of the name
	jmp	cmifi1		; Go back for the next character
cmifi9: pla			; Restore the old comand line pointer
	sta	cm.ptr+1	;  in case the user wants to parse
	sta	cmoptr+1	; 		...
	pla			;	for something else
	sta	cm.ptr		;		...
	sta	cmoptr		; 		...
	lda	cmccnt		;  Save count in case of <ctrl/H>
	sta	cmocnt		; 		...
	lda	#$ff		;  Set failure flag
	sta	cmcffl		; 
	rts

.SBTTL	Cmofil - try to parse an output file spec

;
;	This routine attempts to parse an output file spec from the
;	command buffer.
;
;		Input:  cminf1- Pointer to FCB
;
;		Output:
;
;		Registers destroyed:
;

cmofil: jmp	cmifil		; Same as parsing input file spec for now

.SBTTL	Cminum - Try to parse an integer number

;
;	This routine tries to parse an integer number in the base
;	specified. It will return a 16-bit number in cmintg.
;	Cmintg is formatted H.O. byte first!
;
;		Input:  X-	Base of integer (2<=x<=16)
;
;		Output: Cmintg- 16-bit integer
;
;		Registers destroyed:	A,X,Y
;

cminum: lda	cm.ptr		; Save the old comand line pointer
	pha			;		...
	lda	cm.ptr+1	;		...
	pha			;		...
	cpx	#$11		; Are we within the proper range?
	bmi	cmin1		; If so, check high range
	jmp	cmine1		; No, tell them about it
cmin1:  cpx	#$02		; Too small of a base??
	bpl	cmin2		; No, continue
	jmp	cmine1		; Base too small, tell them about it
cmin2:  stx	cmbase		; The base requested is good, store it
	lda	#$00		; Clear AC
	sta	cmmres		;	and initialize these areas
	sta	cmmres+1	;		...
	sta	cmmres+2	;		...
	sta	cmmres+3	;		...
	sta	cmintg		;		...
	sta	cmintg+1	;		...
	sta	cmintg+2	;		...
	sta	cmintg+3	;		...
cminm1: jsr	cmgtch		; Get next character from command buffer
	cmp	#$00		; Is this an action character
	bmi	cmin1a		; Yes, handle it
	jmp	cminm4		; No, look for a digit
cmin1a: and	#$7f		; It is, turn off the H.O. bit
	cmp	#esc		; Is it an escape?
	bne	cminm2		; No, try something else
	lda	#cmfdff		;  Load default-present flag
	bit	cmprmy		;  Test bit
	beq	cminnd		;  No, default
	lda	cmmres		;  Check if user typed anything significant
	ora	cmmres+1	; 		...
	bne	cminnd		;  Yup, can't use default
	jmp	cmcpdf		;  Go copy the default
cminnd:	jsr	bell		; Yes, but escape is not allowed, ring bell
	lda	#$00		; Zero
	sta	cmaflg		;	the action flag
	sec			; Set the carry flag for subtraction
	lda	cm.bfp		; Get the command buffer pointer
	sbc	#$01		; Decrement it once
	sta	cm.bfp		; Store it away
	sta	cm.ptr		; Make this pointer look like it also
	bcs	cmin11		; If carry set don't adjust H.O. byte
	dec	cm.bfp+1	; Adjust the H.O. byte
cmin11: lda	cm.bfp+1	; Move a copy of this H.O. byte
	sta	cm.ptr+1	;	to this pointer
	dec	cmccnt		; Decrement the character count
	jmp	cminm1		; Go try for another character
cminm2: cmp	#'?		; Does the user need help?
	bne	cminm3		; If not, back up the pointer and accept
	jsr	cout		; And print the question mark
	ldx	#cmin05\	; Set up the pointer to info message to be
	ldy	#cmin05^	;	printed
	jsr	prstr		; Print the text of the message
	lda	cmbase		; Get the base of the integer number
	cmp	#$0a		; Is it greater than decimal 10?
	bmi	cmin21		; No, just print the L.O. digit
	clc			; Clear the carry
	lda	#$01		; Print the H.O. digit as a 1
	adc	#$30		; Make it printable
	jsr	cout		; Print the '1'
	lda	cmbase		; Get the base back
	sec			; Set the carry flag for subtraction
	sbc	#$0a		; Subtract off decimal 10
cmin21: clc			; Clear carry for addition
	adc	#$30		; Make it printable
	jsr	cout		; Print the digit
	jsr	prcrlf		; Print a crelf
	lda	#cmfehf		;  Load extra help flag
	bit	cmprmy		;  Test bit
	beq	cminnh		;  No extra help
	jsr	cmehlp		;  Go give extra help
cminnh:	ldx	cm.rty		; Set up the pointer so we can print the prompt
	ldy	cm.rty+1	;		...
	jsr	prstr		; Reprint the prompt
	lda	#$00		; Clear AC
	ldy	#$00		; Clear Y
	sta	(cm.ptr),y	; Drop a null at the end of the command buffer
	sec			; Set the carry flag for subtraction
	lda	cm.bfp		; Get the L.O. byte of the address
	sbc	#$01		; Decrement it once
	sta	cm.bfp		; Store it back
	bcs	cmin22		; If carry set, don't adjust H.O. byte
	dec	cm.bfp+1	; Adjust H.O. byte
cmin22: ldx	#cmbuf\		; Get the address of the command buffer
	ldy	#cmbuf^		;		...
	jsr	prstr		; Reprint the command buffer
	lda	#$00		; Clear the
	sta	cmaflg		;	action flag
	jmp	repars		; Reparse everything
cminm3: ldx	cmmres		;  Move L.O. byte
	ldy	cmmres+1	;  Move H.O. byte
	pla			; Flush the old comand line pointer
	pla			;		...
	lda	#$00		;  Reset the failure flag
	sta	cmcffl		; 
	jmp	rskp		;
cminm4: cmp	#$40		; Is this a letter?
	bmi	cmin41		; Nope, skip this stuff
	sec			; It is, bring it into the proper range
	sbc	#$07		;		...
cmin41: sec			; Set carry for subtraction
	sbc	#$30		; Make the number unprintable
	cmp	#$00		; Is the number in the proper range?
	bmi	cminm5		; No, give an error
	cmp	cmbase		;		...
	bmi	cminm6		; This number is good
cminm5: pla			; Restore the old comand line pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr		; 		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		; 		...
	lda	cmccnt		;  Save count in case of <ctrl/H>
	sta	cmocnt		; 		...
	lda	#$ff		;  Set failure flag
	sta	cmcffl		; 		...
	rts			; Then return
cminm6: pha			; Save the number to add in
	lda	cmmres+1	; Move the number to multiply
	pha			; 	onto the stack for 
	lda	cmmres		;	call to mul16
	pha			;		...
	lda	#$00		; Move base onto the stack (H.O. byte first)
	pha			;		...
	lda	cmbase		;		...
	pha			;		...
	jsr	mul16		; Multiply this out
	pla			; Get L.O. byte of product
	sta	cmmres		; Store it for now
	pla			; Get H.O. byte of product
	sta	cmmres+1	; Store that too
	pla			; Get the digit to add in
	clc			; Clear the carry for the add
	adc	cmmres		; Add in L.O. byte of result
	sta	cmmres		; Store it back
	lda	cmmres+1	; Get the H.O. byte
	adc	#$00		; Add in the carry
	sta	cmmres+1	; Save the H.O. byte
	bcs	cmine2		; Wrong, we overflowed
	jmp	cminm1		; Try for the next digit
cmine1: ldx	#cmer06\	; Get the address of the error message
	ldy	#cmer06^	;		...
	jsr	prstr		; Print the error
	jmp	prserr		; Handle the parse error
cmine2: ldx	#cmer07\	; Get the address of the error message
	ldy	#cmer07^	;		...
	jsr	prstr		; Print the error message
	jmp	prserr		; Handle the error

.SBTTL	Cmflot - Try to parse a floating point number

;
;	This routine tries to parse a floating point number in the
;	format:
;		sd-d.d-dEsddd
;
;		s is an optional sign bit
;		d is a decimal digit
;		E is the letter 'E'
;		. is a decimal point
;
;		Input:
;
;		Output: Cmfltp- 6 byte floating point number
;				4.5 byte signed mantissa
;				1.5 byte signed exponent
;
;
;		bit	0 1	  35 36 37    47
;
;		Registers destroyed:	A,X,Y
;

cmflot: rts

.SBTTL	Cmunqs - Try to parse an unquoted string

;
;	This routine tries to parse an unquoted string terminating
;	with one of the break characters in brkwrd.
;
;		Input:	
;
;		Output:	X - L.O. byte address of ASCII string
;			Y - H.O. byte address of ASCII string
;			A - Length of string parsed
;
;		Registers destroyed:	A,X,Y
;

cmunqs:	lda	cm.ptr		; Save the command buffer pointer
	pha			;		...
	lda	cm.ptr+1	;		...
	pha			;		...
	lda	#$00		; Zero length of Atom buffer
	sta	lenabf		;		...
cmunq1:	jsr	cmgtch		; Get a character
	jsr	chkbrk		; Is it one of the break characters?
	 jmp	cmunq3		; Yes, handle that condition
	cmp	#$00		; No, is it an action character?
	bpl	cmunq2		; No, handle it as normal text
	and	#$7f		; We don't need the H.O. bit
	cmp	#'?		; Does the user need help?
	bne	cmun13		; Nope, try next possibility
	jsr	cout		; Print '?'
	ldy	#$00		; Zero the action flag
	sty	cmaflg		;		...
	ldx	#cmin06\	; Get the help message
	ldy	#cmin06^	;		...
	jsr	prstr		;	and print it.
	jsr	prcrlf		; Print a crelf after it
	lda	#cmfehf		; Check for extra help.
	bit	cmprmy		;		...
	beq	cmun11		; If no help, continue
	jsr	cmehlp		; Process extra help
cmun11:	ldx	cm.rty		; Go reprint prompt
	ldy	cm.rty+1	;		...
	jsr	prstr		;		...
	sec			; Adjust buffer pointer
	lda	cm.bfp		;		...
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	bcs	cmun12		;		...
	dec	cm.bfp+1	; Adjust H.O. byte
cmun12:	dec	cmccnt		; Correct character count
	ldy	#$00		; Stuff a null at end of usable buffer
	lda	#$00		;		...
	sta	(cm.bfp),y	;		...
	ldx	#cmbuf\		; Reprint command line
	ldy	#cmbuf^		;		...
	jsr	prstr		;		...
	jmp	cmunq1		; Go back for more characters
cmun13:	cmp	#esc		; Did the user type <esc>?
	bne	cmunq2		; No, just stuff the character and cont.
	lda	#$00		; Clear the action flag
	sta	cmaflg		;		...
	lda	#cmfdff		; Check if there is a default value
	bit	cmprmy		;		...
	beq	cmun14		; If not, the <esc> loses
	lda	lenabf		; Ok, there is a default, but if
	bne	cmun14		;	something has been typed, <esc> loses
	jmp	cmcpdf		; Go copy default and reparse
cmun14:	jsr	bell		; Feep at user
	sec			;	and reset the buffer pointer
	lda	cm.bfp		;		...
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	sta	cm.ptr		;		...
	lda	cm.bfp+1	;		...
	sbc	#$00		;		...
	sta	cm.bfp+1	;		...
	sta	cm.ptr+1	;		...
	dec	cmccnt		; Adjust the character count
	jmp	repars		;	and reparse the command line
cmunq2:	ldy	lenabf		; Fetch where we are in atmbuf
	sta	atmbuf,y	;	and store our character there
	inc	lenabf		; Reflect increased length
	jmp	cmunq1		; Go back for more characters
cmunq3:	lda	lenabf		; Get the length
	beq	cmunqf		; If we parsed a null string, fail
	pla			; Flush old command line pointer
	pla			;		...
	ldx	#atmbuf\	; Now, set up the return parameter
	ldy	#atmbuf^	;		...
	lda	#$00		; Reset the failure flag
	sta	cmcffl		;		...
	lda	lenabf		; Set up atom length
	jmp	rskp		; Return
cmunqf:	pla			; Restore old command line pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr+1	;		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		;		...
	lda	cmccnt		; Save count in case of <ctrl/H>
	sta	cmocnt		;		...
	lda	#$ff		; Set failure flag
	sta	cmcffl		;		...
	rts			; Return

.SBTTL	Cmtokn - Try to parse for a single character token

;
;	This routine tries to parse for the character in the X-register.
;
;		Input:	X - Character to be parsed	
;
;		Output: +1 - failed to find character
;			+4 - success, found character
;
;		Registers destroyed:	A,X,Y
;

cmtokn:	lda	cm.ptr		; First, save the old command pointer
	pha			;	on the stack
	lda	cm.ptr+1	;		...
	pha			;		...
cmtk0:	jsr	cmgtch		; Fetch the next character
	bpl	cmtk3		; Not an action character
	and	#$7f		; It's an action character
	cmp	#esc		; User trying to be lazy?
	bne	cmtk2		; Nope, try next option
	jsr	bell		; Yes, well, he's not allowed to be lazy
	lda	#$00		; Clear the action flag
	sta	cmaflg		;		...
	sec			; Adjust the buffer pointer back once
	lda	cm.bfp		;		...
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	sta	cm.ptr		; Copy it into command pointer
	bcs	cmtk1		; Need to adjust H.O. byte?
	dec	cm.bfp+1	; Yes, do it
cmtk1:	lda	cm.bfp+1	; Copy it to command pointer
	sta	cm.ptr+1	;		...
	dec	cmccnt		; Adjust the character count
	jmp	cmtk0		;	and try again
cmtk2:	cmp	#'?		; User need help?
	bne	cmtk4		; No, go fail
	jsr	cout		; Print it
	ldx	#cmin07\	; Point to the information message
	ldy	#cmin07^	;		...
	jsr	prstr		;	and print it
	lda	#dquot		; Print the character we are looking for
	jsr	cout		;	in between double quotes
	lda	cmprmx		;		...
	jsr	cout		;		...
	lda	#dquot		;		...
	jsr	cout		;		...
	jsr	prcrlf		; End it with a crelf
	lda	#cmfehf		; Load extra help flag
	bit	cmprmy		; Test bit
	beq	cmtknh		; No extra help
	jsr	cmehlp		; Go give extra help
cmtknh:	ldx	cm.rty		; Point to prompt
	ldy	cm.rty+1	;		...
	jsr	prstr		;	and print it
	sec			; Adjust the buffer pointer back one
	lda	cm.bfp		;		...
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	lda	cm.bfp+1	;		...
	sbc	#$00		;		...
	sta	cm.bfp+1	;		...
	lda	#$00		; Stuff a null at the end of the buffer
	ldy	#$00		;		...
	sta	(cm.ptr),y	;		...
	ldx	#cmbuf\		; Point to command buffer
	ldy	#cmbuf^		;		...
	jsr	prstr		;	and reprint it
	lda	#$00		; Clear action flag
	sta	cmaflg		;		...
	jmp	repars		;	and go reparse
cmtk3:	cmp	cmprmx		; Ok, this either is or is not the
	bne	cmtk4		;	char we want. If not, go fail.
	pla			; It is, flush the old address
	pla			;		...
	lda	#$00		; Reset the failure flag
	sta	cmcffl		;		...
	jmp	rskp		;	and skip return
cmtk4:	pla			; Restore old pointer
	sta	cm.ptr+1	;		...
	sta	cmoptr+1	;		...
	pla			;		...
	sta	cm.ptr		;		...
	sta	cmoptr		;		...
	lda	cmccnt		; Save the count for <ctrl/H>
	sta	cmocnt		;		...
	lda	#$ff		; Set failure flag
	sta	cmcffl		;		...
	rts			; Return

.SBTTL	Cminbf - read characters from keyboard
;
;	This routine reads characters from the keyboard until
;	an action or editing character comes up.
;
;		Input:
;
;		Output:		Cmbuf- characters from keyboard
;
;		Registers destroyed:
;

cminbf: pha			; Save the AC
	txa			;	and X
	pha			;		...
	tya			;	and Y
	pha			;		...
	php			; Save the processor status
	ldy	#$00		; Clear Y
	lda	cmaflg		; Fetch the action flag
	cmp	#$00		; Set??
	beq	cminb1		; Nope
	jmp	cminb9		; Yes, so leave
cminb1: inc	cmccnt		; Up the character count once
	bne	cminb0		;  If we are overflowing the command buffer
	jsr	bell		;    Feep at the user and do Prserr
	dec	cmccnt		;  Make sure this doesn't happen again
	jmp	prserr		;    for same string
cminb0:	jsr	rdkey		; Get next character from keyboard
	cmp	#cdel		;  User wnat a retry?
	bne	cmnbnh		;  No, go on
	ldx	cmccnt		;  Check character count
	cpx	#$01		;  Is this the first character?
	bne	cmnbnh		;  Nope, can't help him
	ldx	cmcffl		;  Did the previous command fail?
	bpl	cmnbnh		;  No, we can't reparse a good command
	lda	cmoptr		;  Ok, get the old pointer and set up
	sta	cm.ptr		; 	the old command line again
	sta	cm.bfp		; 		...
	lda	cmoptr+1	; 		...
	sta	cm.ptr+1	; 		...
	sta	cm.bfp+1	; 		...
	lda	cmocnt		;  Restore the character count
	sta	cmccnt		; 		...
	lda	#$00		;  Zero this so we can safely use the
	sta	cmwrk2		; 	code that reprints a line after ^W
	jmp	cmnbna		;  Go reprint the line
cmnbnh:	ldy	#$00		;		...
	sta	(cm.bfp),y	; Stuff it in buffer
	tax			; Hold it here for a while
	clc			; Clear the carry
	lda	cm.bfp		; Increment the buffer pointer
	adc	#$01		;		...
	sta	cm.bfp		;		...
	bcc	cmnb11		; Carry?
	inc	cm.bfp+1	; Yup, do H.O. byte
cmnb11: txa			; Get the data back
	cmp	#ctrlu		; Is it a ^U
	bne	cminb2		; Nope
cmnb12: jsr	scrl3		; Yes, clear the whole line
	ldy	#$00		; [DD] Reset cursor position to beg. of line
	ldx	cv		; [DD]
	clc			; [DD]
	jsr	plot		; [DD]
	ldx	cm.rty		;  Get L.O. byte addr of prompt
	ldy	cm.rty+1	; 	and H.O. byte
	jsr	prstr		; Reprint the prompt
	jsr	clreol		; Get rid of garbage on that line
	lda	#cmbuf\		; Now reset the buffer pointer
	sta	cm.bfp		; 	to the beginning of the buffer
	lda	#cmbuf^		;		...
	sta	cm.bfp+1	;		...
	lda	#$00		; Clear AC
	sta	cmccnt		; Clear the character count
	jmp	repars		; Reparse new line from beginning
cminb2: cmp	#bs		; Is it a <bs>?
	beq	cminb3		; Yes
	cmp	#cdel		; A <del>?
	bne	cminb4		; No
cminb3: lda	#cdel		; [DD]
	jsr	cout		; Output a Commodore delete
	jsr	clreol		; Now clear from there to end of line
	dec	cmccnt		; Decrement the character count
	dec	cmccnt		;	twice.
	lda	cmccnt		; Now fetch it
	cmp	#$00		; Did we back up too far??
	bpl	cmnb32		; No, go on
	jsr	bell		; Yes, ring the bell and
	jmp	cmnb12		;	go reprint prompt and reparse line
cmnb32: sec			; Set the carry
	lda	cm.bfp		; Now decrement the buffer pointer
	sbc	#$02		;	twice.
	sta	cm.bfp		; Store it
	bcs	cmnb33
	dec	cm.bfp+1	; Decrement to account for the borrow
cmnb33: jmp	repars		; Time to reparse everything
cminb4:	cmp	#ctrlw		;  Delete a word?
	beq	cmnb41		;  Yes, go take care of that
	jmp	cmib40		;  Nope, continue
cmnb41:	lda	#$03		;  Set up negative offset count
	sta	cmwrk2		; 		...
	sec			;  Set up to adjust buffer pointer
	lda	cm.bfp		;  Get the L.O. byte
	sbc	#$03		;  Adjust pointer down by 3
	sta	cm.bfp		;  Store it back
	bcs	cmnb42		;  Don't worry about H.O. byte
	dec	cm.bfp+1	;  Adjust H.O. byte also
cmnb42:	lda	cmwrk2		;  First, check the count
	cmp	cmccnt		;  Cmwrk2 > cmccnt?
	bmi	cmints		;  No, go test characters
	jmp	cmnb12		;  Yes, go clear the whole line
cmints:	ldy	#$00		;  Zero Y
	lda	(cm.bfp),y	;  Get previous character
	cmp	#lf		;  Start to test ranges...
	bpl	cmits1		; 	Between <lf> and <cr>?
	jmp	cminac		;  No, not in range at all
cmits1:	cmp	#cr+1		; 		...
	bmi	cmnb43		;  Yes, handle it
	cmp	#space		;  Between <sp> and '"'?
	bpl	cmits2		;  Possible, continue
	jmp	cminac		;  No, advance to previous character
cmits2:	cmp	#dquot+1	; 		...
	bmi	cmnb43		;  Yes, delete back to there
	cmp	#apos		;  Between Apostrophy and '/'?
	bpl	cmits3		;  Could be, continue
	jmp	cminac		;  Nope, advance character
cmits3:	cmp	#slash+1	; 		...
	bmi	cmnb43		;  Yup, found a delimiter
	cmp	#colon		;  Between ':' and '>' perhaps?
	bpl	cmits4		;  Maybe
	jmp	cminac		;  Nope, advance to previous character	
cmits4:	cmp	#rabr+1 	; 		...
	bmi	cmnb43		;  It is, go delete back to there
	cmp	#quot		;  Is it a "'"?
	bne	cminac		;  No, advance
cmnb43:	dec	cmwrk2		;  Adjust this count
	clc			; 	and the buffer pointer
	lda	cm.bfp		; 		...
	adc	#$01		; 		...
	sta	cm.bfp		; 		...
	bcc	cmnb44		; 		...
	inc	cm.bfp+1	; 		...
cmnb44:	lda	cmccnt		;  Get the command buffer length
cmnbcc:	cmp	ch		;  Check against horizontal cursor position
	bmi	cmnbna		;  It's smaller, skip vert. cursor adjust
	dec	cv		;  Adjust cursor vertical position
	pha			; Save the AC across this call
	ldx	cv		;
	ldy	ch		;
	clc			;
	jsr	plot		;
	pla			; Restore the AC
	sec			;  Reflect this in number of characters
	sbc	#$28		; 	we skipped back over
	jmp	cmnbcc		;  Go check again
cmnbna:	lda	#$00		;  Put a null at the end of the buffer
	ldy	#$00		; 		...
	sta	(cm.bfp),y	; 		...
	sta	ch		;  Zero position on current line
	jsr	scrl3		;  Clear current line
	ldx	cv		;		...
	jsr	plot		;		...
	ldx	cm.rty		;  Reprint prompt
	ldy	cm.rty+1	; 		...
	jsr	prstr		; 		...
	ldx	#cmbuf\		;  Reprint command buffer
	ldy	#cmbuf^		; 		...
	jsr	prstr		; 		...
	sec			;  Now adjust the command character count
	lda	cmccnt		; 		...
	sbc	cmwrk2		; 	by what we have accumulated
	sta	cmccnt		; 		...
	jsr	clreol		;  Clear to the end of this line
	jmp	repars		;  Go reparse the command
cminac:	inc	cmwrk2		;  Increment count of chars to back up
	sec			;  Adjust the buffer pointer down again
	lda	cm.bfp		; 		...
	sbc	#$01		; 		...
	sta	cm.bfp		; 		...
	bcs	cmnb45		;  If carry set, skip H.O. byte adjustment
	dec	cm.bfp+1	;  Adjust this
cmnb45:	jmp	cmnb42		;  Go around once again

cmib40:	cmp	#quest		; Need help?
	beq	cminb6		;		...
	cmp	#esc		; Is he lazy?
	beq	cminb6		;		...
	cmp	#cr		; Are we at end of line?
	beq	cminb5		;		...
	cmp	#lf		; End of line?
	beq	cminb5		;		...
	cmp	#ffd		; Is it a form feed?
	bne	cminb7		; None of the above
	jsr	home		; Clear the whole screen
cminb5: lda	cmccnt		; Fetch character count
	cmp	#$01		; Any characters yet?
	bne	cminb6		; Yes
	jmp	prserr		; No, parser error
cminb6: lda	#$ff		; Go
	sta	cmaflg		;	and set the action flag
	jmp	cminb9		; Leave
cminb7:	cmp	#space		; Is the character a space ?
	bne	cmnb71		; No
	jsr	cout		; Output the character
	jmp	cminb1		; Yes, get another character
cmnb71:	cmp	#tab		; Is it a <tab>?
	bne	cmnb72		; No
	jsr	cout		; Output the character
	jmp	cminb1		; Yes, get more characters 
cmnb72:	jsr	cout		; Print the character on the screen
	jmp	cminb1		; Get more characters
cminb9: dec	cmccnt		; Decrement the count once
	plp			; Restore the processor status
	pla			;	the Y register
	tay			;		...
	pla			;	the X register
	tax			;		...
	pla			;	and the AC
	rts			;	and return!


.SBTTL	Cmgtch - get a character from the command buffer

;
;	This routine takes the next character out of the command
;	buffer, does some checking (action character, space, etc.)
;	and then returns it to the calling program in the AC
;
;		Input:  NONE
;
;		Output: A-	Next character from command buffer
;
;		Registers destroyed:	A,X,Y
;

cmgtch: ldy	#$00		; Y should always be zero here to index buffer
	lda	cmaflg		; Fetch the action flag
	cmp	#$00		; Set??
	bne	cmgt1		; Yes
	jsr	cminbf		; No, go fetch some more input
cmgt1:  lda	(cm.ptr),y	; Get the next character
	tax			; Hold on to it here for a moment
	clc			; Clear the carry flag
	lda	cm.ptr		; Increment
	adc	#$01		;	the next character pointer
	sta	cm.ptr		;		...
	bcc	cmgt2		;		...
	inc	cm.ptr+1	; Have carry, increment H.O. byte
cmgt2:  txa			; Now, get the data
	cmp	#space		; Space?
	beq	cmgtc2		; Yes
	cmp	#tab		; <tab>?
	bne	cmgtc3		; Neither space nor <tab>
cmgtc2:	pha			; Hold the character here till we need it
	lda	#cmtxt		; Are we parsing a string?
	cmp	cmstat		; 		...
	beq	cmgtis		; Yes, ignore space flag test
	lda	#cmifi		; Are we parsing a file name?
	cmp	cmstat		;		...
	beq	cmgtis		; Yes, ignore the space flag test
	lda	cmsflg		; Get the space flag
	cmp	#$00		; Was the last character a space?
	beq	cmgtis		;  No, go set space flag
	pla			;  Pop the character off
	jmp	cmgtch		;  But ignore it and get another
cmgtis:	lda	#$ff		; Set
	sta	cmsflg		;	the space flag
	pla			;  Restore the space or <tab>
	jmp	cmgtc5		; Go return
cmgtc3: php			; Save the processor status
	pha			; Save this so it doesn't get clobbered
	lda	#$00		; Clear AC
	sta	cmsflg		; Clear space flag
	pla			; Restore old AC
	plp			; Restore the processor status
	cmp	#esc		; Escape?
	beq	cmgtc5		;
	cmp	#quest		; Need help?
	beq	cmgtc4		;
	cmp	#cr		; <cr>?
	beq	cmgtc4		;
	cmp	#lf		; <lf>?
	beq	cmgtc4		;
	cmp	#ffd		; <ff>?
	beq	cmgtc4		;
	and	#$7f		; Make sure the character is positive
	rts			; Not an action character, just return
cmgtc4: tax			; Hold the data
	sec			; Set the carry flag
	lda	cm.ptr		; Get the next character pointer
	sbc	#$01		;	and decrement it
	sta	cm.ptr		;
	bcs	cmgtc5		;
	dec	cm.ptr+1	;
cmgtc5: txa			; Now, fetch the data
	ora	#$80		; Make it look like a terminator
	rts			; Go back

.SBTTL	Prcrlf subroutine - print a crelf

;
;	This routine sets up a call to prstr pointing to the crlf
;	string.
;
;		Registers destroyed:	A
;

prcl.0: lda	#cr		; Get a cr in the AC
	jsr	cout		;	and print it out
	rts			; Return

.SBTTL	Prstr subroutine

;
;	This routine prints a string ending in a null.
;
;		Input:  X-	Low order byte address of string
;			Y-	High order byte address of string
;
;		Output:		Prints string on screen
;
;		Registers destroyed:	A,X,Y
;

prst.0: stx	saddr		; Save Low order byte
	sty	saddr+1		; Save High order byte
	ldx	#3		; [DD]
	jsr	chkout		; [DD] open chan 3 for output
	ldy	#$00		; Clear Y reg

prst1:  lda	(saddr),y	; Get the next byte of the string
	beq	prsdon		; If it is null, we are done
	and	#$7f		; [DD] mask 7 bits
	jsr	chrout		; [DD] output to screen
	iny			; Up the index
	bne	prst2		; If it is zero, the string is <256, continue
	inc	saddr+1		; Increment page number
prst2:  jmp	prst1		; Go back to print next byte

prsdon: rts			; Return

.SBTTL	Mul16 - 16-bit multiply routine

;
;	This and the following four routines is math support for the
;	Comnd package. These routines come from '6502 Assembly Language
;	Subroutines' by Lance A. Leventhal. Refer to that source for
;	more complete documentation.
;

ml16:	pla			; Save the return address
	sta	rtaddr		;		...
	pla			;		...
	sta	rtaddr+1	;		...
	pla			; Get multiplier
	sta	mlier		;		...
	pla			;		...
	sta	mlier+1		;		...
	pla			; Get multiplicand
	sta	mcand		;		...
	pla			;		...
	sta	mcand+1		;		...
	lda	#$00		; Zero
	sta	hiprod		;	high word of product
	sta	hiprod+1	;		...
	ldx	#17		; Number of bits in multiplier plus 1, the
				;	extra loop is to move the last carry
				;	into the product.
	clc			; Clear carry for first time through the loop
mullp:  ror	hiprod+1	; Shift the whole thing down
	ror	hiprod		;		...
	ror	mlier+1		;		...
	ror	mlier		;		...
	bcc	deccnt		; Branch if next bit of multiplier is 0
	clc			; next bit is 1 so add multiplicand to product
	lda	mcand		;		...
	adc	hiprod		;		...
	sta	hiprod		;		...
	lda	mcand+1		;		...
	adc	hiprod+1	;		...
	sta	hiprod+1	; Carry = overflow from add
deccnt: dex			;		...
	bne	mullp		; Continue until done
	lda	mlier+1		; Get low word of product and push it
	pha			;	onto the stack
	lda	mlier		;		...
	pha			;		...
	lda	rtaddr+1	; Restore the return address
	pha			;		...
	lda	rtaddr		;		...
	pha			;		...
	rts			; Return

mcand:  .blkb	2		; Multiplicand
mlier:  .blkb	2		; Multiplier and low word of product
hiprod: .blkb	2		; High word of product
rtaddr: .blkb	2		; Save area for return address

.SBTTL	Rskp - Do a skip return

;
;	This routine returns, skipping the instruction following the
;	original call. It is assumed that the instruction following the
;	call is a JMP.
;
;		Input:
;
;		Output:
;
;		Registers destroyed:	X,Y
;

rskp.0:	sta	savea		; Save the registers
	stx	savex		;
	sty	savey		;
	sta	cminf2		; Save AC in scratch area
	pla			; Get Low order byte of return address
	tax			; Hold it
	pla			; Get High order byte
	tay			; Hold that
	txa			; Get Low order byte
	clc			; Clear the carry flag
	adc	#$04		; Add 4 to the address
	bcc	rskp2		; No carry
	iny			; Increment the high order byte
rskp2:  sta	saddr		; Store L.O. byte
	sty	saddr+1		; Store H.O. byte
	lda	cminf2		; Restore AC value
	lda	savea		;
	ldx	savex		;
	ldy	savey		;
	jmp	(saddr)		; Jump at the new address

.SBTTL	Setbrk and Rstbrk

;
;	These routines are called from the user program to set or reset
;	break characters to be used by Cmunqs. The byte to set or reset
;	is located in the Accumulator. Rstbrk has the option to reset
;	the entire break-word. This occurs if the H.O. bit of AC is on.
;

sbrk.0:	and	#$7f		; We don't want the H.O. bit
	ldy	#$00		; Set up Y to index the byte we want
sbrkts:	cmp	#$08		; Is the offset > 8
	bmi	sbrkfw		; No, we are at the right byte now
	sec			; Yes, adjust it down again
	sbc	#$08		;		...
	iny			; Advance index
	jmp	sbrkts		;	and try again
sbrkfw:	tax			; This is the remaining offset
	lda	#$80		; Start with H.O. bit on
sbrklp:	cpx	#$00		; Is it necessary to shift down?
	beq	sbrkfb		; No, we are done
	dex			; Yes, adjust offset
	lsr	a		; Shift bit down once
	jmp	sbrklp		; Go back and try again
sbrkfb:	ora	brkwrd,y	; We found the bit, use the byte offset
	sta	brkwrd,y	;	from above, set the bit and resave
	rts			; Return

rbrk.0:	asl	a		; Check H.O. bit
	bcs	rbrkal		; If that was on, Zero entire brkwrd
	lsr	a		; Else shift back (H.O. bit is zeroed)
rbrkts:	cmp	#$08		; Are we in the right word?
	bmi	rbrkfw		; Yes, go figure the rest of the offset
	sec			; No, Adjust the offset down
	sbc	#$08		;		...
	iny			;	and the index up
	jmp	rbrkts		; Try again
rbrkfw:	tax			; Stuff the remaining offset in X
	lda	#$7f		; Start with H.O. bit off
rbrklp:	cpx	#$00		; Do we need to offset some more?
	beq	rbrkfb		; No, we have the correct bit
	dex			; Yes, decrement the offset
	sec			; Make sure carry is on
	ror	a		;	and rotate a 1 bit into mask
	jmp	rbrklp		; Go back and try again
rbrkfb:	and	brkwrd,y	; We found the bit, now shut it off
	sta	brkwrd,y	;		...
	rts			;	and return
rbrkal:	lda	#$00		; Go stuff zeros in the entire word
	ldy	#$00		;		...
rbrksz:	sta	brkwrd,y	; Stuff the zero
	iny			; Up the index once
	cpy	#$10		; Are we done?
	bmi	rbrksz		; Not yet
	rts			; Yes, return

.SBTTL	Chkbrk

;
;	Chkbrk - This routine looks for the flag in the break word
;	which represents the character passed to it. If this bit is
;	on, it is a break character and the routine will simply
;	return. If it is not a break character, the routine skips..
;

chkbrk:	sta	savea		; Save byte to be checked
	and	#$7f		; Shut H.O. bit
	ldy	#$00		; Zero this index
cbrkts:	cmp	#$08		; Are we at the right word?
	bmi	cbrkfw		; Yes, go calculate bit position
	sec			; No, adjust offset down
	sbc	#$08		;		...
	iny			; Increment the index
	jmp	cbrkts		; Go back and test again
cbrkfw:	tax			; Stuff the remaining offset in X
	lda	#$80		; Set H.O. bit on for testing
cbrklp:	cpx	#$00		; Are we in position yet?
	beq	cbrkfb		; Yes, go test the bit
	dex			; No, decrement the offset
	lsr	a		;	and adjust the bit position
	jmp	cbrklp		; Go and try again
cbrkfb:	and	brkwrd,y	; See if the bit is on
	bne	cbrkbc		; It is a break character
	lda	savea		; Restore the character
	jmp	rskp		; Not a break character, skip return
cbrkbc:	lda	savea		; Restore the character
	rts			; Return

.SBTTL	Cmehlp - Do extra help on Question-mark prompting

;
;	Cmehlp - This routine uses a string of commands passed to it
;	in order to display alternate valid parse types to the user.
;
;		Input:	Cmehpt-	Pointer to valid parse types (end in 00)
;
;		Output:	Display on screen, alternate parse types
;
;		Registers destroyed:	A,X,Y
;

cmehlp:	lda	cmstat		; We are going to need this so
	pha			;	save it across the call
	ldy	#$00		; Zero out the help index
	sty	cmehix		;		...
cmehl1:	ldy	cmehix		; Load the extra help index
	lda	(cmehpt),y	; Fetch next type
	sta	cmstat		; Store it here
	inc	cmehix		; Increase the index by one
	cmp	#$00		; Is the type null?
	bne	cmeh0		; No, continue
	jmp	cmehrt		; Yes, terminate
cmeh0:	cmp	#cmtok+1	; If the type is out of range, leave
	bmi	cmeh1		;		...
	jmp	cmehrt		;		...
cmeh1:	pha			; Save the type across the call
	ldx	#cmors\		; Set up address of 'OR ' string
	ldy	#cmors^		;		...
	jsr	prstr		;	and print it
	pla			; Restore AC
	cmp	#cmkey		; Compare with keyword
	bne	cmeh2		; No, try next type
cmeh10:	tax			; Hold type in X register
	lda	cmsptr		; Save these parms so they can be restored
	pha			;		...
	lda	cmsptr+1	;		...
	pha			;		...
	lda	cm.ptr		; Copy the pointer to the saved pointer
	sta	cmsptr		;	so the keyword print routine prints
	pha			;	the entire table. Also, save it on
	lda	cm.ptr+1	;	the stack so it can be restored later
	sta	cmsptr+1	;		...
	pha			;		...
	lda	cmptab		; Save the table address also
	pha			;		...
	lda	cmptab+1	;		...
	pha			;		...
	txa			; Restore type
	cmp	#cmkey		; Keyword?
	bne	cmeh11		; No, it must be a switch table
	ldx	#cmin01\	; Set up address of message
	ldy	#cmin01^	;		...
	jmp	cmeh12		; Go print the string
cmeh11:	ldx	#cmin02\	; Set up address of 'switch' string
	ldy	#cmin02^	;		...
cmeh12:	jsr	prstr		; Print the message
	ldy	cmehix		; Get the index into help string
	lda	(cmehpt),y	; Fetch L.O. byte of table address
	sta	cmptab		; Set that up for Cmktp
	iny			; Increment the index
	lda	(cmehpt),y	; Get H.O. byte
	sta	cmptab+1	; Set it up for Cmktp
	iny			; Advance the index
	sty	cmehix		;	and store it
	jsr	cmktp		; Print the keyword table
	pla			; Now restore all the stuff we saved before
	sta	cmptab+1	;		...
	pla			;		...
	sta	cmptab		;		...
	pla			;		...
	sta	cm.ptr+1	;		...
	pla			;		...
	sta	cm.ptr		;		...
	pla			;		...
	sta	cmsptr+1	;		...
	pla			;		...
	sta	cmsptr		;		...
	jmp	cmehl1		; See if there is more to do
cmeh2:	cmp	#cmswi		; Type is switch?
	bne	cmeh3		; No, continue
	jmp	cmeh10		; We can treat this just like a keyword
cmeh3:	cmp	#cmifi		; Input file?
	bne	cmeh4		; No, go on
	ldx	#cmin03\	; Set up the message address
	ldy	#cmin03^	;		...
	jmp	cmehps		; Go print it
cmeh4:	cmp	#cmofi		; Output file?
	bne	cmeh5		; Nope, try again
	ldx	#cmin04\	; Set up message address
	ldy	#cmin04^	;		...
	jmp	cmehps		; Go print the string
cmeh5:	cmp	#cmcfm		; Confirm?
	bne	cmeh6		; No
	ldx	#cmin00\	; Set up address
	ldy	#cmin00^	;		...
	jmp	cmehps		; Print the string
cmeh6:	cmp	#cmtxt		; Unquoted string?
	bne	cmeh7		; No, try next one
	ldx	#cmin06\	; Set up address
	ldy	#cmin06^	;		...
	jmp	cmehps		; Print
cmeh7:	cmp	#cmnum		; Integer?
	bne	cmeh8		; Try again
	ldx	#cmin05\	; Set up message
	ldy	#cmin05^	;		...
	jsr	prstr		; Print it
	ldy	cmehix		; Get index
	inc	cmehix		; Advance index
	lda	(cmehpt),y	; Get base of integer
	cmp	#$0a		; Is it greater than decimal 10?
	bmi	cmeh71		; No, just print the L.O. digit
	lda	#$b1		; Print the H.O. digit as a 1
	jsr	cout		; Print the '1'
	ldy	cmehix		; Load index
	dey			; Point back to last byte
	lda	(cmehpt),y	; Get the base back
	sec			; Set the carry flag for subtraction
	sbc	#$0a		; Subtract off decimal 10
cmeh71:	clc			; Clear carry for addition
	adc	#$b0		; Make it printable
	jsr	cout		; Print the digit
	jsr	prcrlf		; Print a crelf
	jsr	prbyte		; Print the byte
	jmp	cmehl1		; Go back for more
cmeh8:	ldx	#cmin07\	; Assume it's a token
	ldy	#cmin07^	;		...
cmehps:	jsr	prstr		; Print string
	jsr	prcrlf		; Print a crelf
	jmp	cmehl1		; Go back
cmehrt:	pla			; Restore
	sta	cmstat		;	current parse type
	rts

.SBTTL	Cmcpdf - Copy a default string into the command buffer

;
;	Cmcpdf - This routine copies a default for a field
;	into the command buffer andreparses the string.
;
;		Input:	Cmdptr-	Pointer to default field value (asciz)
;
;		Output:
;
;		Registers destroyed:	A,X,Y
;

cmcpdf:	sec			; Reset the buffer pointer
	lda	cm.bfp		;		...
	sbc	#$01		;		...
	sta	cm.bfp		;		...
	bcs	cmcpst		; If carry set, don't adjust H.O. byte
	dec	cm.bfp+1	;		...
cmcpst:	dec	cmccnt		; Adjust the character count
	ldy	#$00		; Zero the index
cmcplp:	lda	(cmdptr),y	; Get byte
	beq	cmcpdn		; Copy finished, leave
	ldx	cmccnt		; Check character count
	inx			; If it is just short of wrapping
	bne	cmcpl1		;	then we are overflowing buffer
	jsr	bell		; If that is the case, tell the user
	dec	cmccnt		; Make sure it doesn't happen again
	jmp	prserr		;	for same string.
cmcpl1:	
;	ora	#$80		; Be consistent, make sure H.O. bit is on
	sta	(cm.bfp),y	; Stuff it in the buffer
	inc	cmccnt		; Adjust character count
	iny			; Up the buffer index
	jmp	cmcplp		; Go to top of loop
cmcpdn:	lda	#space		; Get a space
	sta	(cm.bfp),y	;	and place it in buffer after keyword
	iny			; Increment the buffer index
	lda	#nul		; Get a null
	sta	(cm.bfp),y	;	and stuff that at the end of buffer
	clc			; Now recompute the end of usable buffer
	tya			; Get the number of chars added
	adc	cm.bfp		; Add that to the buffer pointer
	sta	cm.bfp		;		...
	lda	#$00		;		...
	adc	cm.bfp+1	;		...
	sta	cm.bfp+1	;		...
	lda	#$00		; Reset the action flag
	sta	cmaflg		;		...
	sec			; Now adjust the command pointer to the
	lda	cm.ptr		;	beginning of the copied field
	sbc	#$01		;		...
	tax			; Set it up in X and Y so we can call Prstr
	lda	cm.ptr+1	;		...
	sbc	#$00		;		...
	tay			;		...
	jsr	prstr		; Print the added field
	jmp	repars		; Now go reparse the whole command

.SBTTL	Comnd Jsys messages and table storage

cmer00: .byte	cr
	.asciz	'?program error:  invalid comnd call'
cmer01: .byte	cr
	.asciz	'?ambiguous'
cmer02: .byte	cr
	.asciz	'?illegal input file spec'
cmer03: .byte	cr
	.asciz	'?no keywords match this prefix'
cmer04: .byte	cr
	.asciz	'?no switches match this prefix'
cmer05: .byte	cr
	.asciz	'?bad character in integer number'
cmer06: .byte	cr
	.asciz	'?base of integer out of range'
cmer07: .byte	cr
	.asciz	'?overflow while reading integer number'
cmin00: .asciz	' confirm with carriage return'
cmin01: .asciz	' keyword, one of the following:'
cmin02: .asciz	' switch, one of the following:'
cmin03: .asciz	' input file spec'
cmin04: .asciz	' output file spec'
cmin05: .asciz	' integer number in base '
cmin06:	.asciz	' unquoted text string '
cmin07:	.asciz	' single character token '

cmors:	.asciz	' or '

.SBTTL	Kermit defaults for operational parameters

;
;	The following are the defaults which this Kermit uses for
;	the protocol.
;

dquote  =	'#		; The quote character
dpakln  =	$5e		; The packet length
dpadch  =	nul		; The padding character
dpadln  =	0		; The padding length
dmaxtr  =	$14		; The maximum number of tries
debq	=	'&		; The eight-bit-quote character
dtime	=	15		; The default time-out amount
deol	=	cr		; The end-of-line character

.SBTTL	Kermit data

;
;	The following is data storage used by Kermit
;

mxpack  =	dpakln		; Maximum packet size
mxfnl	=	$1e		; Maximum file-name length
eof	=	$01		; This is the value for End-of-file
buflen  =	$ff		; Buffer length for received data
kerbf1  =	$1a		; This always points to packet buffer
kerbf2	=	$1c		; This always points to data buffer
true	=	$01		; Symbol for true return code
false	=	$00		; Symbol for false return code
on	=	$01		; Symbol for value of 'on' keyword
off	=	$00		; Symbol for value of 'off' keyword
yes	=	$01		; Symbol for value of 'yes' keyword
no	=	$00		; Symbol for value of 'no' keyword
terse	=	$01		; Symbol for terse debug mode
verbose	=	$02		; Symbol for verbose debug mode
xon	=	$11		; Xon for Ibm-mode
fbsbit  =	$01		; Value for SEVEN-BIT FILE-BYTE-SIZE
fbebit  =	$00		; Value for EIGHT-BIT FILE-BYTE-SIZE
nparit	=	$00		; Value for PARITY NONE
sparit	=	$01		; Value for PARITY SPACE
mparit	=	$02		; Value for PARITY MARK
oparit	=	$03		; Value for PARITY ODD
eparit	=	$04		; Value for PARITY EVEN
eprflg	=	$40		;	'Error packet received' flag
errcri  =	$01		; Error code - cannot receive init
errcrf  =	$02		; Error code - cannot receive file-header
errcrd  =	$03		; Error code - cannot receive data
errmrc  =	$04		; Error code - maximum retry count exceeded
errbch  =	$05		; Error code - bad checksum
errfae  =	$0a		; Error code - file already exists
emesln  =	$19		; Standard error message length
kerrns  =	$1f		; Routine name and action string length
kerdel  =	$15		; Disk error length
kerems  =	$19		; Error message size
kerfts	=	$0b		; Size of file-type strings (incl. term. nul)
kerdsz	=	$09		; Length of debug mode strings
kerpsl	=	$06		; Size of parity strings
kerfrm	=	cminf1		; 'From string' pointer for Kercpy routine
kerto	=	cminf2		; 'To string' pointer for Kercpy routine

pdbuf:  .blkb	mxpack-2	; Packet buffer
pdlen:  .byte			; Common area to place data length
ptype:  .byte			; Common area to place current packet type
pnum:	.byte			; Common area to put packet number received
plnbuf: .blkb	$100		; [DD] Port line buffer
pdtend: .byte			; End of plnbuf pointer
pdtind: .byte			; Index for plnbuf
rstat:  .byte			; Return status
	.byte
kerrta: .word			; Save area for return address
prmt:	.asciz	'kERMIT-65>'	; Prompting text
lprmt	=	.-prmt		;  Length of prompting text
escp:	.byte	$19		; Character for escape from connection
fbsize: .byte	fbsbit		;  File-byte-size
filmod: .byte			; Current file type
usehdr: .byte	off		; Switch - where to get filename (on=file-head)
lecho:  .byte	off		; Local-echo switch
ibmmod: .byte	off		; Ibm-mode switch
vtmod:  .byte	on		; VT-52 Emulation mode switch
parity: .byte	nparit		; Parity setting
delay:  .byte			; Amount of delay before first send
filwar: .byte	off		; File-warning switch
debug:  .byte	off		; Debug switch
ebqmod: .byte	off		; Eight-bit-quoting mode
datind: .byte			; Data index into packet buffer
chebo:  .byte			; Switch to tell if 8th-bit was on
escflg: .byte			; Flag indicating we have seen and escape ($1b)
xfillen: .word			; Length of current file left to send
fetfl:  .byte			; Flag indicating we need the file length
addlf:  .byte			; Add a <lf> flag
dellf:  .byte			; Flush a <lf> flag
jtaddr: .word			; Jump table address hold area
hch:	.byte			; Hold area for ch
hcv:	.byte			; Hold area for cv
kwrk01: .byte			; Work area for Kermit
kwrk02: .byte			; Work area for Kermit
kertpc:	.byte			; Hold area for parity check
ksavea:	.byte			; Save area for accumulator
ksavex:	.byte			; Save area for X reg
ksavey:	.byte			; Save area for Y reg
kerchr: .byte			; Current character read off port
kermbs: .word			; Base address of message table
debchk: .byte			; Checksum for debug routine
debinx: .byte			; Debug routine action index
fld:	.byte			; State of receive in rpak routine
retadr: .word			; Hold area for return address
n:	.byte			; Message #
numtry: .byte			; Number of tries for this packet
oldtry: .byte			; Number of tries for previous packet
maxtry: .byte	dmaxtr		; Maximum tries allowed for a packet
state:  .byte			; Current state of system
local:	.byte			;  Local/Remote switch
size:	.byte			; Size of present data
chksum: .byte			; Checksum for packet
rtot:	.word			; Total number of characters received
stot:	.word			; Total number of characters sent
rchr:	.word			; Number characters received, current file
schr:	.word			; Number of characters sent, current file
rovr:	.word			; Number of overhead characters on receive
sovr:	.word			; Number of overhead characters on send
tpak:	.word			;  Number of packets for this transfer
eofinp: .byte			; End-of-file (no characters left to send)
eodind: .byte			;  End-of-data reached on disk
errcod: .byte			; Error indicator
errrkm:	.blkb	mxpack-2	;  Error message from remote Kermit
lsterr: .word			; Last error address [D.D.]
kerosp: .byte			; Save area for stack pointer
oldch:	.byte			; Save loc for cursor address x coord.
curchr:	.byte			; True value for char under cursor

;
;	These fields are set parameters and should be kept in this
;	order to insure integrity when setting and showing values
;

srind:  .byte			; Switch to indicate which parm to print
ebq:	.byte	debq		; Eight-bit quote character (rec. and send)
	.byte	debq
pad:	.byte	dpadln		; Number of padding characters (rec. and send)
	.byte	dpadln
padch:  .byte	dpadch		; Padding character (receive and send)
	.byte	dpadch
eol:	.byte	deol		; End-of-line character (recevie and send)
	.byte	deol
psiz:	.byte	dpakln		; Packet size (receive and send)
	.byte	dpakln
time:	.byte	dtime		; Time-out interval (receive and send)
	.byte	dtime		;
quote:  .byte	dquote		; Quote character (receive and send)
	.byte	dquote

;
;	Some definitions to make life easier when referencing the above
;	fields.
;

rebq	=	ebq
sebq	=	ebq+1
rpad	=	pad
spad	=	pad+1
rpadch  =	padch
spadch  =	padch+1
reol	=	eol
seol	=	eol+1
rpsiz	=	psiz
spsiz	=	psiz+1
rtime	=	time
stime	=	time+1
rquote  =	quote
squote	=	quote+1

.SBTTL	Kermit - CBM DOS support

;
;	The following definitions and storage will be used when setting
;	up and executing calls to the DOS.
;

fncrea  =	'R		; Read function code
fncwrt  =	'W		; Write function code
kerfcb	=	$1e		; Pointer to FCB
buff	=	$200		; 
fcb1:	.blkb	$1f		; Fcb for file being transmitted
primfn: .blkb	$23		; File name
dsbend: .byte	$00		; DOS buffer len
flsrw:  .byte	0		; switch for r(ead) or w(rite)
flssp:  .byte	0		; switch for file type s or p
len:	.byte	0
fcmd:	.byte	'I,'0
fmrcod: .byte	0
dmes:	.asciz	/dOS>/

.SBTTL	Kermit initialization

;
;	The following code sets up Kermit-65 for normal operation.
;

kstart:	jsr	clall		; First close all open channels
	openm #1,#0,#$ff,cntrl,#0	; Open keyboard
	openm #3,#3,#$ff,cntrl,#0	; Open screen
;
	jsr	home		; Start by clearing the screen
	lda	#$0c		; Set border to gray 2
	sta	bord		;		...
s40:	lda	fgbg4		; set 40 col bgnd color
	and	#$0f		;
	sta	bgnd		;
	lda	fgbg4		; set 40 col foreground color
	lsr	a		;
	lsr	a		;
	lsr	a		;
	lsr	a		;
	sta	color		; continue into common code

	lda	#$0e		; Switch to upper/lower case mode
	jsr	cout		;
	lda	#$08		; Disable Shift-Commodore
	jsr	cout		;
	ldx	#versio\	; Get address of version message
	ldy	#versio^
	jsr	prstr		; Print the version
	jsr	prcrlf		; Print a crlf
	jsr	kermit		; Go execute kermit
	jmp	($a002)
	brk			; Break

.SBTTL	Kermit - main routine
;
;	This routine is the main KERMIT loop. It prompts for commands
;	and then it dispatches to the appropriate routine.
;

kermit: tsx			; Get the stack pointer
	stx	kerosp		;	and save it in case of a fatal error
	ldx	#prmt\		;  Fetch the address of the prompt
	ldy	#prmt^
	lda	#cmini		; Argument for comnd call
	jsr	comnd		; Set up the parser and print the prompt
	lda	#kercmd\	; addr of command table
	sta	cminf1
	lda	#kercmd^
	sta	cminf1+1
	lda	#kerhlp\	; Storeaddr of help text in help pointer
	sta	cmhptr
	lda	#kerhlp^
	sta	cmhptr+1
	ldy	#$00		;  No special flags needed
	lda	#cmkey		; Set up for keyword parse
	jsr	comnd		; Try to parse it
	 jmp	kermt2		; Failed
	lda	#kermtb\	; Get address of jump table
	sta	jtaddr
	lda	#kermtb^
	sta	jtaddr+1
	txa			; Offset to AC
jmpind: clc			; Jump indexed [D.D.]
	adc  jtaddr		; Add offset to low byte
	sta  jtaddr
	bcc  jmpin1
	inc  jtaddr+1		; If carry inc high byte
jmpin1: jmp	(jtaddr)	; Jump to address
kermtb: jmp	telnet		; Connect command
	jmp	exit		; Exit command
	jmp	help		; Help command
	jmp	log		; Log command
	jmp	exit		; Quit command
	jmp	receve		; Receive command
	jmp	send		; Send command
	jmp	setcom		; Set command
	jmp	show		; Show command
	jmp	status		; Status command
	jmp	bye		;  Shut and logout remote server command
	jmp	finish		;  Shut remote server
	jmp	getfrs		;  Get file from remote server
	jmp	dosst		; Send DOS command [D.D.]
kermt2: ldx	#ermes1\	; L.O. byte of error message
	ldy	#ermes1^
	jsr	prstr		; Print the error
	jmp	kermit		; Go back
kermt3: ldx	#ermes3\	; L.O. byte of error
	ldy	#ermes3^
	jsr	prstr		; Print it
	jmp	kermit		; Try again
kermt4: ldx	#ermes4\	; L.O. byte of error
	ldy	#ermes4^
	jsr	prstr		; Print the text
	jmp	kermit		; Try again
kermt5: ldx	#ermes6\	; L.O. byte of error
	ldy	#ermes6^
	jsr	prstr		; Print error text ('keyword')
	jmp	kermit		; Start at the beginning again
kermt6: ldx	#ermes7\	; L.O. byte of error
	ldy	#ermes7^
	jsr	prstr		; Print the error message ('file spec')
	jmp	kermit		;	and try again
kermt7: ldx	#ermes8\	; L.O. byte of error message text
	ldy	#ermes8^
	jsr	prstr		; Print it ('integer')
	jmp	kermit		; Try for another command line
kermt8: ldx	#ermes9\	; L.O. byte of error
	ldy	#ermes9^
	jsr	prstr		; Print the message ('switch')
	jmp	kermit		;
kermt9: ldx	#ermesa\	;
	ldy	#ermesa^
	jsr	prstr		;
	jmp	kermit		;
kermta:	ldx	#ermesb\	;
	ldy	#ermesb^
	jsr	prstr		;
	jmp	kermit		; Go back to top of loop

.SBTTL	Telnet routine
;
;	This routine handles the connect command. After connecting
;	to a host system, this routine alternates calling routines
;	which will pass input from the port to the screen and pass
;	output from the keyboard to the port. This kermit will
;	ignore all characters until it sees and assigned escape
;	character.
;
;		Input:  RS232 REGISTERS IN CNTRL,CMMND
;
;		Output: NONE
;
;		Registers destroyed:	A,X,Y
;

telnet: jsr	prcfm		; Parse and print a confirm
	ldx	#inf01a\	; Get address of first half of message
	ldy	#inf01a^
	jsr	prstr		; Print it out
	lda	escp		; Get the 'break connection' character
	jsr	prchr		; Print that as a special character
	ldx	#inf01b\	; Get address of second half of message
	ldy	#inf01b^
	jsr	prstr		; Print that
	jsr	prcrlf		;	and a crelf
	lda	#2		; [DD]
	jsr	close		; Close existing rs232 channel  [DD]
	openm	#2,#2,#$ff,cntrl,#2	;Open rs232 [DD]
chrlup: jsr	telprc		; Check for port character, write to screen
	jsr	telcnc		; Check for console character, write to port
	 jmp	kermit		; This means user wants to shut connection
	jmp	chrlup		; Go back and do all that again

telprc:	jsr	getrs		; Check for a port character
	and	#$7f
	cmp	#false		; No character
	beq	telprr		; Return
	nop			;character in A
	nop
	nop
	jsr	nblink		; Turn cursor off
telpr2: tay			; Hold the character here
	lda	vtmod		; Are we in vt52 mode?
	cmp	#on
	bne	telpr3		; If not, we do not need any of this, continue
	lda	escflg		; Was previous character an escape?
	cmp	#on
	bne	telp2a		; If not, skip vt52 emulation stuff
	jmp	vt52		; It was escape, do vt52 emulation
telp2a: tya			; Get the character back
	cmp	#del		; Was it a delete?
	beq	telprr		; If so, return
	cmp	#esc		; Was it an 'escape'?
	bne	telpr3		; If not, just output the character
	lda	#on		; Set the escape flag on
	sta	escflg
	jmp	telprc		; Go try for another character
;
telpr3: tya			; Get the data into the AC
	and	#$7f		; Make absolutely sure the H.O. bit is off
	jsr	cas2pt		;Convert to PETASCI [D.D.]
	nop
	nop
	nop
	nop
	nop
	nop
	cmp	#$20		;check for ctl chars
	bcs	telpr4		;no so continue
tlpr3a: cmp	#7		;check ctl g (bell)
	bne	tlpr3b
	jsr	bell		;ring bell
	jmp	telprc		;and go back for more
;
tlpr3b: cmp	#bs		;check for backspace
	bne	tlpr3c
	lda	#157		;cmdr [left]
	bne	telpr4
tlpr3c: cmp	#cr
	bne	tlpr3d
	jsr	crout		;print a c/r
	jmp	telprc
tlpr3d: cmp	#lf
	bne	tlpr3e
	jsr	lfeed
	jmp	telprc
tlpr3e: jmp	telprc
;
telpr4: jsr	cout		; Print the character we got above
	jmp	telprc		; Try for another
telprr: rts			; Return
telcp:  jsr	getrs		;Get char. from rs232
	rts			;Will be 0 if no character
	nop
	nop
	beq	telnc		;No char return false
	lda	#true		; Successful return
	rts
telnc:  lda	#false		; Indicate failure
	rts			;	and return
telgpc: jsr	getrs		;fetch from port
	rts
telcnc: jsr	getkey		;read keyboard
	cmp	#00
	beq	telcrs		;if no character return skip
	cmp	#$14		;if commodore delete
	bne	tlcnc1
	lda	#del		;make it ascii delete
tlcnc1: cmp	#$85		;if <f1> key
	bne	tlcnc2
	lda	#esc		;make it esc
tlcnc2: cmp	#$86		;if <f2> key
	bne	tlcnc3		;make it null
	lda	#00
tlcnc3: jsr	cpt2as		; Convert PETASCI to ASCII [D.D.]
	cmp	escp		; Is it the connect-escape character?
	beq	intchr		; If so, go handle the interupt character
	jsr	telppc		; Output the port character
	tax			; Hold it in X
	lda	lecho		; Is local-echo turned on?
	cmp	#on
	bne	telcrs		; If not, we are done, return skip
	txa			; Output a copy to the screen
	jsr	cas2pt		; [DD]
	jsr	cout		;
telcrs: jmp	rskp		; Skip return
telppc: jsr	putrs		; Send to rs232
	rts			; Return


;
;	Intchr - processes the character which frollows the interupt
;	character and performs functions based on what that character
;	is.
;

intchr: jsr	rdkey		; Get the next character
	sta	kerchr		; Save a copy of it
	and	#$5f		; Capitalize it
	cmp	#'C		; Does user want the connection closed?
	bne	intch0		; If not, try next option
	rts			; Otherwise, do non-skip return and end it
intch0: cmp	#'S		; Does the user want status?
	bne	intch1		; Nope
	jmp	stat01		; Give it to him
intch1: cmp	#'B		; Send break? [D.D.]
	bne	intc1a		; No
	jsr	sbreak
	jmp	rskp		; Return skip [D.D.]
intc1a: lda	kerchr		; Fetch back the original character
	and	#$7f		; Get rid of the H.O. bit
	cmp	#'?		; Does user need help?
	bne	intch2		; If not, continue
	ldx	#inthlp\	; Get the address of the proper help string
	ldy	#inthlp^
	jsr	prstr		; Print the help stuff
	jmp	intchr		; Get another option character
intch2: cmp	escp		; Is it another connect-escape?
	bne	intch3		; Nope, this is an error
	jsr	telppc		; Stuff the character at the port
	jmp	rskp		; Give skip return
intch3: jsr	bell		; Sound bell at the user
	jmp	rskp		; Go back (skip)

;	Send break


sbreak: nop			;
	nop			;
	nop			;
	nop			;
	nop			;
	nop			;
	lda	dpa2		; Get pa of cia
	and	#$fb		; Zero pa2
	sta	dpa2		;		...
	ldy	#200		; Delay 200 ms.
sbdl1:  ldx	#200		;
sbdl2:  dex			; Inner loop 1 ms.
	bne	sbdl2		;
	dey			; Outer loop
	bne	sbdl1		;
	lda	dpa2		;
	ora	#$04		; Set pa2
	sta	dpa2		;
	rts			;


;
;	Vt52 - will carry out the equivalent of most of the vt52 functions
;	available.
;

vt52:	lda	#off		; First, turn off the escape flag
	sta	escflg
	tya			; Get the character to check
	and	#$7f		; Turn off the H.O. bit
	cmp	#'A		; Is it greater than 'A' and less than
	bmi	vtig		;	or equal to 'Y'????
	cmp	#'Z
	bpl	vtig		; If it isn't, ignore it
	cmp	#'A		; It is, is it an 'A'?
	bne	vt52a		; No, try next character
	jsr	upline		; Go up one line
	rts			; Return
vt52a:  cmp	#'B		; Is it a 'B'?
	bne	vt52b		; Next char
	jsr	lfeed		; Yes, do a line feed
	rts			;	and go back
vt52b:  cmp	#'C		; 'C'?
	bne	vt52c		; Nope
	jsr	advanc		; Yes, go forward one space
	rts			;	and return
vt52c:  cmp	#'D		; 'D'?
	bne	vt52d		; No
	jsr	bsp		; Yes, do a back-space
	rts			; Return
vt52d:  cmp	#'H		; 'H'?
	bne	vt52e		; No, try next character
	jsr	home1		; Home cursor (no clear screen)
	rts			;	then return
vt52e:  cmp	#'I		; 'I'?
	bne	vt52f		; Nope
	lda	cv		; Get the vertical cursor position
	cmp	#$00		; If it is zero
	beq	vt52e1		; Do reverse scrolling
	jsr	upline		; Otherwise, just go up one line
	rts			;	and return
vt52e1: jsr	vrscrl		; Do the reverse scroll
	rts			;	and return
vt52f:  cmp	#'J		; 'J'?
	bne	vt52g		; No
	jsr	clreop		; Clear from where we are to end-of-page
	rts			;	then return
vt52g:  cmp	#'K		; 'K'?
	bne	vt52h		; Try last option
	jsr	clreol		; Clear to end-of-line
	rts			; Return
vt52h:  cmp	#'Y		; 'Y'
	bne	vtig		; Must be an unimplemented function, do vtig
	jsr	vtdca		; Do direct cursor addressing
	rts			;	then return
vtig:	pha			; Save a copy
	lda	#esc		; Get an escape
	jsr	prchr		; Print the special character
	pla			; Fetch the other character back
	cmp	#esc		; Is it a second escape?
	bne	vtig1		; Nope, print it
	lda	#on		; Set escflg on again for next time around
	sta	escflg
	rts			;	and return
vtig1:  jsr	prchr		; Print the character
	rts			;	and return
vrscrl: lda	wndbtm		; Start at bottom of window
	pha			; Save ac
	tax
	jsr	vtabz		; Generate base address
vrsc1:  lda	basl		; Move basl,h to bas2l,h
	sta	bas2l
	lda	bash
	sta	bas2h
	ldy	wndwth		; Init Y to rightmost index
	dey			;	of scrolling window
	pla			; Get window bottom
	sec			; Decrement by one
	sbc	#$01
	cmp	wndtop		; Are we done?
	bcs	vrsc3		; Yup
	pha			; Save new line number
	tax
	jsr	vtabz		; Generate this line's base address
vrsc2:  lda	(basl),y	; Move a character down a line
	sta	(bas2l),y
	dey			; Next char
	bpl	vrsc2		; If not done, do next char
	bmi	vrsc1		; Otherwise, go to next line
vrsc3:  jsr	scrl3		; Clear the entire top line
	rts			; Return

;
vtdca:  jsr	getrs		; check for a character from the port
	cmp	#false		; if we didn't get one
	beq	vtdca		; try again
	and	#$7f		; make sure h.o. bit is off
	sec			; subtract hex 30 (make it num from 0 to 23)
	sbc	#$20		;
	cmp	#$00		; is it less than 0?
	bpl	vtdca1		; no, continue
	clc			; clear carry
	adc	#$20		; add this back in
	jmp	vtig		; now ignore it as a control paramenter
vtdca1: cmp	#24		; is it too large?
	bmi	vtdca2		; no, it is fine, store it away
	clc			; clear carry
	adc	#$20		; add this back in
	jmp	vtig		; ignore it
vtdca2: sta	hcv		; store it as the vertical cursor position
vtdca3: jsr	getrs		; check port for character
	cmp	#false		; if we didn't get one yet
	beq	vtdca3		;	go back and try again
	and	#$7f		; make sure h.o. bit is off
	sec			; subtract hex 20 (make it num from 0 to 23)
	sbc	#$20		;
	cmp	#$00		; is it less than 0?
	bpl	vtdca4		; no, continue
	clc			; clear carry
	adc	#$20		; add this back in
	jmp	vtig		; now ignore it as a control paramenter
vtdca4: cmp	#$28		; is it too large?
	bmi	vtdca5		; no, it is fine, store it away
	clc			; clear carry
	adc	#$20		; add this back in
	jmp	vtig		; ignore it
vtdca5: sta	hch		; store it as the horizontal cursor position
	ldx	hcv		; move this to the real position now
	ldy	hch		; this too
	clc
	jsr	plot		; now place the cursor there
	rts			;	and return

; Convert PETASCI to ASCII [D.D.]

cpt2as:	jmp	cas1

.SBTTL	Exit routine
;
;	This routine exits properly from Kermit-65 and reenters
;	Dos.
;
;		Input:  NONE
;
;		Output: NONE
;
;		Registers destroyed:	A,X
;

exit:
	lda	#cmcfm		; Try to get a confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Give '?not confirmed' message
exit1:
exit2:  jmp	(dos)		; We got it, now restart DOS

.SBTTL	Help routine
;
;	This routine prints help from the current help text
;	area.
;
;		Input:  Cmhptr  - Pointer to the desired text to be printed
;
;		Output: ASCIZ string at Cmhptr is printed on screen
;
;		Registers destroyed:	A,X,Y
;

help:	lda	#cmcfm		; Try to get a confirm
	jsr	comnd		; Go get it
	 jmp	kermt3		; Didn't find one? Give 'not confirmed' message
help2:  ldx	cmhptr		; L.O. byte of current help text address
	ldy	cmhptr+1	; H.O. byte of address
	jsr	prstr		; Print it
	jmp	kermit		; Return to main routine

.SBTTL	Log routine
;
;	This routine logs a session to a disk file.
;
;		Input:  NONE
;
;		Output: NONE
;
;		Registers destroyed:	NONE
;

log:	jmp	kermit

.SBTTL	Bye routine

;
;	This routine terminates the remote server, logs out and terminates
;	the local Kermit.
;

bye:	jsr	prcfm		; Go parse and print the confirm
	jsr	logo		; Tell other Kermit to log out
	 jmp	kermit		; Don't exit if there was an error
	jmp	exit1		; Leave

;
;	Logo - This routine does the actual work to send the logout
;	packet to the remote server
;

logo:	lda	#$00		; Zero the number of tries
	sta	numtry		;		...
	sta	tpak		;	and the total packet number
	sta	tpak+1		;		...
logo1:	lda	numtry		; Fetch the number of tries
	cmp	maxtry		; Have we exceeded Maxtry?
	bmi	logo3		; Not yet, go send the packet
logo2:	ldx	#ermesc\	; Yes, give an error message
	ldy	#ermesc^	;		...
	jsr	prstr		;		...
	jsr	prcrlf		;		...
	rts			;	and return
logo3:	inc	numtry		; Increment the number of tries for packet
	lda	#$00		; Make it packet number 0
	sta	pnum		;		...
	lda	#$01		; Data length is only 1
	sta	pdlen		;		...
	lda	#'L		; The 'Logout' command
	sta	pdbuf		; Put that in first character of buffer
	lda	#'G		; Generic command packet type
	sta	ptype		;		...
	jsr	spak		; Send the packet
	jsr	rpak		; Try to fetch an ACK
	cmp	#true		; Did we receive successfully?
	bne	logo1		; No, try to send the packet again
	lda	ptype		; Get the type
	cmp	#'Y		; An ACK?
	bne	logoce		; No, go check for error
	jmp	rskp		; Yes, skip return
logoce:	cmp	#'E		; Error packet?
	bne	logo1		; Nope, resend packet
	jsr	prcerp		; Go display the error
	rts			;	and return

.SBTTL	Finish routine

;
;	This routine terminates the remote server but does not log
;	it out. It also keeps the local Kermit running.
;

finish:	jsr	prcfm		; Go parse and print the confirm
	lda	#$00		; Zero the number of tries
	sta	numtry		;		...
	sta	tpak		;	and the total packet number
	sta	tpak+1		;		...
finsh1:	lda	numtry		; Fetch the number of tries
	cmp	maxtry		; Have we exceeded Maxtry?
	bmi	finsh3		; Not yet, go send the packet
finsh2:	ldx	#ermesd\	; Yes, give an error message
	ldy	#ermesd^	;		...
	jsr	prstr		;		...
	jsr	prcrlf		;		...
	jmp	kermit		;	and go back for more commands
finsh3:	inc	numtry		; Increment the number of tries for packet
	lda	#$00		; Make it packet number 0
	sta	pnum		;		...
	lda	#$01		; Data length is only 1
	sta	pdlen		;		...
	lda	#'F		; The 'Finish' command
	sta	pdbuf		; Put that in first character of buffer
	lda	#'G		; Generic command packet type
	sta	ptype		;		...
	jsr	spak		; Send the packet
	jsr	rpak		; Try to fetch an ACK
	cmp	#true		; Did we receive successfully?
	bne	finsh1		; No, try to send the packet again
	lda	ptype		; Get the type
	cmp	#'Y		; An ACK?
	bne	fince		; No, go check for error
	jmp	kermit		; Yes, go back for more commands
fince:	cmp	#'E		; Error packet?
	bne	finsh1		; Nope, resend packet
	jsr	prcerp		;; Go display the error
	jmp	kermit		; Go back for more 

.SBTTL	Get routine

;
;	This routine accepts an unquoted string terminated by 
;	<cr>,<lf>,<ff>, or <esc> and tries to fetch the file
;	represented by that string from a remote server Kermit.
;

getfrs:	lda	#yes		; Make KERMIT use file headers
	sta	usehdr		;	for file names
	lda	#mxfnl+1	; The buffer size is one more than max
	sta	kwrk01		;	file name length
	lda	#fcb1\		; Point to the buffer
	sta	kerto		;		...
	lda	#fcb1^		;		...
	sta	kerto+1		;		...
	jsr	kerflm		; Clear the buffer
	lda	#$80		; Reset all break characters
	jsr	rstbrk		;		...
	lda	#cr		;		...
	jsr	setbrk		;		...
	lda	#lf		;		...
	jsr	setbrk		;		...
	lda	#ffd		;		...
	jsr	setbrk		;		...
	lda	#esc		;		...
	jsr	setbrk		;		...
	ldy	#$00		;		...
	lda	#cmtxt		; Parse for text
	jsr	comnd		; Do it
	 jmp	kermta		; Found null string
	cmp	spsiz		; Larger than the set packet size?
	bmi	getf1		; No, continue
	lda	spsiz		; Yes, it will have to be truncated
getf1:	sta	kwrk01		; Store packet size for Kercpy
	sta	pdlen		;	and Spak
	lda	#pdbuf\		; Point to the data buffer as destination
	sta	kerto		;		...
	sta	kerbf1		; Store L.O.B. here for Spak routine
	lda	#pdbuf^		;		...
	sta	kerto+1		;		...
	sta	kerbf1+1	; Store H.O.B. here for Spak routine
	stx	kerfrm		; Point to the atom buffer from Comnd
	sty	kerfrm+1	;	as the source address
	txa			; Save the 'from buffer' pointers for later
	pha			;		...
	tya			;		...
	pha			;		...
	jsr	kercpy		; Copy the string
	pla			; Restore these for the next move
	sta	kerfrm+1	;		...
	pla			;		...
	sta	kerfrm		;		...
	lda	#fcb1\		; Set up the address of the target
	sta	kerto		;		...
	lda	#fcb1^		;		...
	sta	kerto+1		;		...
	jsr	clrfcb		; Clear the fcb first
	jsr	kercpy		; Go move the string
	jsr	prcfm		; Go parse and print the confirm
	lda	#'R		; Packet type is 'Receive-init'
	sta	ptype		;		...
	lda	#$00		; Packet number should be zero
	sta	pnum		;		...
	jsr	spak		; Packet length was set above, 
	jsr	rswt		;	so just call spak and try to receive
	jmp	kermit		; Go back for more commands


.SBTTL	Receve routine
;
;	This routine receives a file from the remote kermit and
;	writes it to a disk file.
;
;		Input:  Filename returned from comnd, if any
;
;		Output: If file transfer is good, file is output to disk
;
;		Registers destroyed:	A,X,Y
;

receve: lda	#on		; Set use file-header switch on in case we
	sta	usehdr		;	don't parse a filename
	lda	#kerehr\	; Point to extra help commands
	sta	cmehpt		;		...
	lda	#kerehr^	;		...
	sta	cmehpt+1	;		...
	ldx	#$0f		; Longest length a filename may be
	ldy	#cmfehf		; Tell Comnd about extra help
	lda	#cmifi		; Load opcode for parsing input files
	jsr	comnd		; Call comnd routine
	 jmp	recev1		; Continue, don't turn file-header switch off
	sta	kwrk01		; Store length of file parsed
	stx	kerfrm		; Save the from address (addr[atmbuf])
	sty	kerfrm+1	;		...
	lda	#fcb1\		; Save the to address (Fcb1)
	sta	kerto		;		...
	lda	#fcb1^		;		...
	sta	kerto+1		;		...
	jsr	clrfcb		; Clear the fcb
	jsr	kercpy		; Copy the string
	lda	#off		; We parsed a filename so we don't need the
	sta	usehdr		;	info from the file-header
recev1: lda	#cmcfm		; Get token for confirm
	jsr	comnd		;	and try to parse that
	 jmp	kermt3		; Failed - give the error
	jsr	rswt		; Perform send-switch routine
	jmp	kermit		; Go back to main routine
rswt:	lda	#'R		; The state is receive-init
	sta	state		; Set that up
	lda	#$00		; Zero the packet sequence number
	sta	n
	sta	numtry		;	Number of tries
	sta	oldtry		;	Old number of tries
	sta	eofinp		;	End of input flag
	sta	errcod		;	Error indicator
	sta	rtot		;	Total received characters
	sta	rtot+1
	sta	stot		;	Total Sent characters
	sta	stot+1
	sta	rchr		;	Received characters, current file
	sta	rchr+1
	sta	schr		;	and Sent characters, current file
	sta	schr+1
	sta	tpak		;	and the total packet number
	sta	tpak+1		;
rswt1:  lda	state		; Fetch the current system state
	cmp	#'D		; Are we trying to receive data?
	bne	rswt2		; If not, try the next one
	jsr	rdat		; Go try for the data packet
	jmp	rswt1		; Go back to the top of the loop
rswt2:  cmp	#'F		; Do we need a file header packet?
	bne	rswt3		; If not, continue checking
	jsr	rfil		; Go get the file-header
	jmp	rswt1		; Return to top of loop
rswt3:  cmp	#'R		; Do we need the init?
	bne	rswt4		; No, try next state
	jsr	rini		; Yes, go get it
	jmp	rswt1		; Go back to top
rswt4:  cmp	#'C		; Have we completed the transfer?
	bne	rswt5		; No, we are out of states, fail
	lda	#true		; Load AC for true return
	rts			; Return
rswt5:  lda	#false		; Set up AC for false return
	rts			; Return
rini:	lda	#pdbuf\		; Point kerbf1 at the packet data buffer
	sta	kerbf1
	lda	#pdbuf^
	sta	kerbf1+1
	lda	numtry		; Get current number of tries
	inc	numtry		; Increment it for next time
	cmp	maxtry		; Have we tried this one enought times
	beq	rini1		; Not yet, go on
	bcs	rini1a		; Yup, go abort this transfer
rini1:  jmp	rini2		; Continue
rini1a: lda	#'A		; Change state to 'abort'
	sta	state
	lda	#errcri		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#erms10\	; Get error message [D.D.]
	sta	lsterr
	lda	#erms10^
	sta	lsterr+1
	lda	#errcri
	sta	errcod
	lda	#false		; Load AC with false status
	rts			;	and return
rini2:  jsr	rpak		; Go try to receive a packet
	sta	rstat		; Store the return status for later
	lda	ptype		; Fetch the packet type we got
	cmp	#'S		; Was it an 'Init'?
	bne	rini2a		; No, check the return status
	jmp	rinici		; Go handle the init case
rini2a: lda	rstat		; Fetch the saved return status
	cmp	#false		; Is it false?
	beq	rini2b		; Yes, just return with same state
	lda	#errcri		; No, fetch the error index
	sta	errcod		;	and store it as the error code
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Abort this transfer
	sta	state		; State is now 'abort'
	lda	#false		; Set return status to 'false'
	rts			; Return
rini2b: lda	n		; Get packet sequence number expected
	sta	pnum		; Stuff that parameter at the Nakit routine
	jsr	nakit		; Go send the Nak
	lda	#false		; Set up failure return status
	rts			;	and go back
rinici: lda	pnum		; Get the packet number we received
	sta	n		; Synchronize our packet numbers with this
	jsr	rpar		; Load in the init stuff from packet buffer
	jsr	spar		; Stuff our init info into the packet buffer
	lda	#'Y		; Store the 'Ack' code into the packet type
	sta	ptype
	lda	n		; Get sequence number
	sta	pnum		; Stuff that parameter
	lda	sebq		; See what we got for an 8-bit quoting
	cmp	#$21		; First check the character range
	bmi	rinicn		; Not in range
	cmp	#$3f
	bmi	rinicy		; Inrange
	cmp	#$60
	bmi	rinicn		; Not in range
	cmp	#$7f
	bmi	rinicy		; Inrange
rinicn: cmp	#'Y		; Does it say he agrees to 8-bit quoting?
	beq	rinicy		; Ok, that's just like an inrange character
	lda	#off		; No, punt 8-bit quoting
	sta	ebqmod
	lda	#$06		; BTW, the data length is now only 6
	jmp	rinic1		; Continue
rinicy: lda	#on		; Make sure everything is on
	sta	ebqmod
	lda	#$07		; Data length for ack-init is 7
rinic1: sta	pdlen		; Store packet data length
	jsr	spak		; Send that packet
	lda	numtry		; Move the number of tries for this packet
	sta	oldtry		;	to prev packet try count
	lda	#$00		; Zero
	sta	numtry		;	the number of tries for current packet
	jsr	incn		; Increment the packet number once
	lda	#'F		; Advance to 'File-header' state
	sta	state
	lda	#true		; Set up return code
	rts			; Return
rfil:	lda	numtry		; Get number of tries for this packet
	inc	numtry		; Increment it for next time around
	cmp	maxtry		; Have we tried too many times?
	beq	rfil1		; Not yet
	bcs	rfil1a		; Yes, go abort the transfer
rfil1:  jmp	rfil2		; Continue transfer
rfil1a: lda	#'A		; Set state of system to 'abort'
	sta	state
	lda	#false		; Return code should be 'false'
	rts			; Return
rfil2:  jsr	rpak		; Try to receive a packet
	sta	rstat		; Save the return status
	lda	ptype		; Get the packet type we found
	cmp	#'S		; Was it an 'init' packet?
	bne	rfil2a		; Nope, try next one
	jmp	rfilci		; Handle the init case
rfil2a: cmp	#'Z		; Is it an 'eof' packet??
	bne	rfil2b		; No, try again
	jmp	rfilce		; Yes, handle that case
rfil2b: cmp	#'F		; Is it a 'file-header' packet???
	bne	rfil2c		; Nope
	jmp	rfilcf		; Handle file-header case
rfil2c: cmp	#'B		; Break packet????
	bne	rfil2d		; Wrong, go get the return status
	jmp	rfilcb		; Handle a break packet
rfil2d: lda	rstat		; Fetch the return status from Rpak
	cmp	#false		; Was it a false return?
	beq	rfil2e		; Yes, Nak it and return
	lda	#errcrf		; No, fetch the error index
	sta	errcod		;	and store it as the error code
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Abort this transfer
	sta	state		;		...
	lda	#false		; Set up failure return code
	rts			;	and return
rfil2e: lda	n		; Move the expected packet number
	sta	pnum		;	into the spot for the parameter
	jsr	nakit		; Nak the packet
	lda	#false		; Do a false return but don't change state
	rts			; Return
rfilci: lda	oldtry		; Get number of tries for prev packet
	inc	oldtry		; Increment it
	cmp	maxtry		; Have we tried this one too much?
	beq	rfili1		; Not quite yet
	bcs	rfili2		; Yes, go abort this transfer
rfili1: jmp	rfili3		; Continue
rfili2:
rfili5: lda	#'A		; Move abort code
	sta	state		;	to system state
	lda	#errcrf		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#erms11\	; Get error message [DD]
	sta	lsterr
	lda	#erms11^
	sta	lsterr+1
	lda	#false		; Prepare failure return
	rts			;	and go back
rfili3: lda	pnum		; See if pnum=n-1
	clc
	adc	#$01
	cmp	n
	beq	rfili4		; If it does, than we are ok
	jmp	rfili5		; Otherwise, abort
rfili4: jsr	spar		; Set up the init parms in the packet buffer
	lda	#'Y		; Set up the code for Ack
	sta	ptype		; Stuff that parm
	lda	#$06		; Packet length for init
	sta	pdlen		; Stuff that also
	jsr	spak		; Send the ack
	lda	#$00		; Clear out
	sta	numtry		;	the number of tries for current packet
	lda	#true		; This is ok, return true with current state
	rts			; Return
rfilce: lda	oldtry		; Get number of tries for previous packet
	inc	oldtry		; Up it for next time we have to do this
	cmp	maxtry		; Too many times for this packet?
	beq	rfile1		; Not yet, continue
	bcs	rfile2		; Yes, go abort it
rfile1: jmp	rfile3
rfile2:
rfile5:	lda	#'A		; Load abort code
	sta	state		;	into current system state
	lda	#errcrf		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		; Prepare failure return
	rts			;	and return
rfile3:	lda	pnum		; First, see if pnum=n-1
	clc
	adc	#$01
	cmp	n
	beq	rfile4		; If so, continue
	jmp	rfile5		; Else, abort it
rfile4: lda	#'Y		; Load 'ack' code
	sta	ptype		; Stuff that in the packet type
	lda	#$00		; This packet will have a packet data length
	sta	pdlen		;	of zero
	jsr	spak		; Send the packet out
	lda	#$00		; Zero number of tries for current packet
	sta	numtry
	lda	#true		; Set up successful return code
	rts			;	and return
rfilcf: lda	pnum		; Does pnum=n?
	cmp	n
	bne	rfilf1		; If not, abort
	jmp	rfilf2		; Else, we can continue
rfilf1:	lda	#'A		; Load the abort code
	sta	state		;	and stuff it as current system state
	lda	#errcrf		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		; Prepare failure return
	rts			;	and go back
rfilf2: jsr	getfil		; Get the filename we are to use
	lda	#fncwrt		; Tell the open routine we want to write
	jsr	openf		; Open up the file
	lda	#'Y		; Stuff code for 'ack'
	sta	ptype		; Into packet type parm
	lda	#$00		; Stuff a zero in as the packet data length
	sta	pdlen
	jsr	spak		; Ack the packet
	lda	numtry		; Move current tries to previous tries
	sta	oldtry
	lda	#$00		; Clear the
	sta	numtry		; Number of tries for current packet
	jsr	incn		; Increment the packet sequence number once
	lda	#'D		; Advance the system state to 'receive-data'
	sta	state
	lda	#true		; Set up success return
	rts			;	and go back
rfilcb: lda	pnum		; Does pnum=n?
	cmp	n
	bne	rfilb1		; If not, abort the transfer process
	jmp	rfilb2		; Otherwise, we can continue
rfilb1:	lda	#'A		; Code for abort
	sta	state		; Stuff that into system state
	lda	#errcrf		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		; Load failure return status
	rts			;	and return
rfilb2: lda	#'Y		; Set up 'ack' packet type
	sta	ptype
	lda	#$00		; Zero out
	sta	pdlen		;	the packet data length
	jsr	spak		; Send out this packet
	lda	#'C		; Advance state to 'complete'
	sta	state		;	since we are now done with the transfer
	lda	#true		; Return a true
	rts

rdat:	lda	numtry		; Get number of tries for current packet
	inc	numtry		; Increment it for next time around
	cmp	maxtry		; Have we gone beyond number of tries allowed?
	beq	rdat1		; Not yet, so continue
	bcs	rdat1a		; Yes, we have, so abort
rdat1:  jmp	rdat2
rdat1a: lda	#'A		; Code for 'abort' state
	sta	state		; Stuff that in system state
	lda	#errcrd		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#erms12\	; get error message [D.D.]
	sta	lsterr
	lda	#erms12^
	sta	lsterr+1
	lda	#false		; Set up failure return code
	rts			;	and go back
rdat2:  jsr	rpak		; Go try to receive a packet
	sta	rstat		; Save the return status for later
	lda	ptype		; Get the type of packet we just picked up
	cmp	#'D		; Was it a data packet?
	bne	rdat2a		; If not, try next type
	jmp	rdatcd		; Handle a data packet
rdat2a: cmp	#'F		; Is it a file-header packet?
	bne	rdat2b		; Nope, try again
	jmp	rdatcf		; Go handle a file-header packet
rdat2b: cmp	#'Z		; Is it an eof packet???
	bne	rdat2c		; If not, go check the return status from rpak
	jmp	rdatce		; It is, go handle eof processing
rdat2c: lda	rstat		; Fetch the return status
	cmp	#false		; Was it a failure return?
	beq	rdat2d		; If it was, Nak it
	lda	#errcrd		; Fetch the error index
	sta	errcod		;	and store it as the error code
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Give up the whole transfer
	sta	state		; Set system state to 'false'
	lda	#false		; Set up a failure return
	rts			;	and go back
rdat2d: lda	n		; Get the expected packet number
	sta	pnum		; Stuff that parameter for Nak routine
	jsr	nakit		; Send a Nak packet
	lda	#false		; Give failure return
	rts			; Go back

rdatcd: lda	pnum		; Is pnum the right sequence number?
	cmp	n
	bne	rdatd1		; If not, try another approach
	jmp	rdatd7		; Otherwise, everything is fine
rdatd1: lda	oldtry		; Get number of tries for previous packet
	inc	oldtry		; Increment it for next time we need it
	cmp	maxtry		; Have we exceeded that limit?
	beq	rdatd2		; Not just yet, continue
	bcs	rdatd3		; Yes, go abort the whole thing
rdatd2: jmp	rdatd4		; Just continue working on the thing
rdatd3:
rdatd6:	lda	#'A		; Load 'abort' code into the
	sta	state		;	current system state
	lda	#errcrd		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		; Make this a failure return
	rts			; Return
rdatd4: lda	pnum		; Is pnum=
	clc			;	the one previous to the currently
	adc	#$01		;	expected packet?
	cmp	n
	beq	rdatd5		; Yes, continue transfer
	jmp	rdatd6		; Nope, abort the whole thing
rdatd5: jsr	spar		; Go set up init data
	lda	#'Y		; Make it look like an ack to a send-init
	sta	ptype
	lda	#$06
	sta	pdlen
	jsr	spak		; Go send the ack
	lda	#$00		; Clear the
	sta	numtry		;	number of tries for current packet
	lda	#true
	rts			; Return (successful!)
rdatd7: jsr	bufemp		; Go empty the packet buffer
	lda	#'Y		; Set up an ack packet
	sta	ptype
	lda	n
	sta	pnum
	lda	#$00		; Don't forget, there is no data
	sta	pdlen
	jsr	spak		; Send it!
	lda	numtry		; Move tries for current packet count to
	sta	oldtry		;	tries for previous packet count
	lda	#$00		; Zero the
	sta	numtry		;	number of tries for current packet
	jsr	incn		; Increment the packet sequence number once
	lda	#'D		; Advance the system state to 'receive-data'
	sta	state
	lda	#true
	rts			; Return (successful)

rdatcf: lda	oldtry		; Fetch number of tries for previous packet
	inc	oldtry		; Increment it for when we need it again
	cmp	maxtry		; Have we exceeded maximum tries allowed?
	beq	rdatf1		; Not yet, go on
	bcs	rdatf2		; Yup, we have to abort this thing
rdatf1: jmp	rdatf3		; Just continue the transfer
rdatf2:
rdatf5:	lda	#'A		; Move 'abort' code to current system state
	sta	state		;		...
	lda	#errcrd		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		;		...
	rts			;	and return false
rdatf3: lda	pnum		; Is this packet the one before the expected
	clc			;	one?
	adc	#$01
	cmp	n
	beq	rdatf4		; If so, we can still ack it
	jmp	rdatf5		; Otherwise, we should abort the transfer
rdatf4: lda	#'Y		; Load 'ack' code
	sta	ptype		; Stuff that parameter
	lda	#$00		; Use zero as the packet data length
	sta	pdlen
	jsr	spak		; Send it!
	lda	#$00		; Zero the number of tries for current packet
	sta	numtry
	lda	#true
	rts			; Return (successful)

rdatce: lda	pnum		; Is this the packet we are expecting?
	cmp	n
	bne	rdate1		; No, we should go abort
	jmp	rdate2		; Yup, go handle it
rdate1:	lda	#'A		; Load 'abort' code into
	sta	state		;	current system state
	lda	#errcrd		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		;		...
	rts			; Return (failure)
rdate2:	lda	#fcb1\		; Get the pointer to the fcb
	sta	kerfcb		;	and store it where the close routine
	lda	#fcb1^		;	can find it
	sta	kerfcb		;		...
	lda	#$00		; Make CLOSEF see there are no errors
	jsr	closef		; We are done with this file, so close it
	jsr	incn		; Increment the packet number
	lda	#'Y		; Get set up for the ack
	sta	ptype		; Stuff the packet type
	lda	n		;	packet number
	sta	pnum		;		...
	lda	#$00		;	and packet data length
	sta	pdlen		;	parameters
	jsr	spak		; Go send it!
	lda	#'F		; Advance system state to 'file-header'
	sta	state		;	incase more files are coming
	lda	#true		;		...
	rts			; Return (successful)

.SBTTL	Send routine
;
;	This routine reads a file from disk and sends packets
;	of data to the remote kermit.
;
;		Input:  Filename returned from Comnd routines
;
;		Output: File is sent over port
;
;		Registers destroyed:	A,X,Y
;

send:	ldx	#$0f		; Longest length a filename may be
	ldy	#$00		; No special flags needed
	lda	#cmifi		; Load opcode for parsing input files
	jsr	comnd		; Call comnd routine
	 jmp	kermt6		; Give the 'missing filespec' error
	sta	kwrk01		; Store length of file parsed
	stx	kerfrm		; Save the from address (addr[atmbuf])
	sty	kerfrm+1	;		...
	lda	#fcb1\		; Save the to address (Fcb1)
	sta	kerto		;		...
	lda	#fcb1^		;		...
	sta	kerto+1		;		...
	jsr	clrfcb		; Clear the fcb
	jsr	kercpy		; Copy the string
	ldy	kwrk01		; Get filename length
	lda	#nul		; Fetch a null character
	sta	(kerto),y	; Stuff a null at end-of-buffer
	jsr	prcfm		; Parse and print a confirm
	jsr	sswt		; Perform send-switch routine
	jmp	kermit		; Go back to main routine

sswt:	lda	#'S		; Set up state variable as
	sta	state		;	Send-init
	lda	#$00		; Clear
	sta	eodind		;	The End-of-Data indicator
	sta	n		;	Packet number
	sta	numtry		;	Number of tries
	sta	oldtry		;	Old number of tries
	sta	eofinp		;	End of input flag
	sta	errcod		;	Error indicator
	sta	rtot		;	Total received characters
	sta	rtot+1
	sta	stot		;	Total Sent characters
	sta	stot+1
	sta	rchr		;	Received characters, current file
	sta	rchr+1
	sta	schr		;	and Sent characters, current file
	sta	schr+1
	sta	tpak		;	and the total packet number
	sta	tpak+1		;
	lda	#pdbuf\		; Set up the address of the packet buffer
	sta	saddr		;	so that we can clear it out
	lda	#pdbuf^		;
	sta	saddr+1
	lda	#$00		; Clear AC
	ldy	#$00		; Clear Y
clpbuf: sta	(saddr),y	; Step through buffer, clearing it out
	iny			; Up the index
	cpy	#mxpack-4	; Done?
	bmi	clpbuf		; No, continue
sswt1:  lda	state		; Fetch state of the system
	cmp	#'D		; Do Send-data?
	bne	sswt2		; No, try next one
	jsr	sdat		; Yes, send a data packet
	jmp	sswt1		; Go to the top of the loop
sswt2:  cmp	#'F		; Do we want to send-file-header?
	bne	sswt3		; No, continue
	jsr	sfil		; Yes, send a file header packet
	jmp	sswt1		; Return to top of loop
sswt3:  cmp	#'Z		; Are we due for an Eof packet?
	bne	sswt4		; Nope, try next state
	jsr	seof		; Yes, do it
	jmp	sswt1		; Return to top of loop
sswt4:  cmp	#'S		; Must we send an init packet
	bne	sswt5		; No, continue
	jsr	sini		; Yes, go do it
	jmp	sswt1		; And continue
sswt5:  cmp	#'B		; Time to break the connection?
	bne	sswt6		; No, try next state
	jsr	sbrk		; Yes, go send a break packet
	jmp	sswt1		; Continue from top of loop
sswt6:  cmp	#'C		; Is the entire transfer complete?
	bne	sswt7		; No, something is wrong, go abort
	lda	#true		; Return true
	rts
sswt7:  lda	#false		; Return false
	rts
sdat:	lda	numtry		; Fetch the number for tries for current packet
	inc	numtry		; Add one to it
	cmp	maxtry		; Is it more than the maximum allowed?
	beq	sdat1		; No, not yet
	bcs	sdat1a		; If it is, go abort
sdat1:  jmp	sdat1b		; Continue
sdat1a: lda	#'A		; Load the 'abort' code
	sta	state		; Stuff that in as current state
	lda	#false		; Enter false return code
	rts			;	and return
sdat1b: lda	#'D		; Packet type will be 'Send-data'
	sta	ptype
	lda	n		; Get packet sequence number
	sta	pnum		; Store that parameter to Spak
	lda	size		; This is the size of the data in the packet
	sta	pdlen		; Store that where it belongs
	jsr	spak		; Go send the packet
sdat2:  jsr	rpak		; Try to get an ack
	sta	rstat		; First, save the return status
	lda	ptype		; Now get the packet type received
	cmp	#'N		; Was it a NAK?
	bne	sdat2a		; No, try for an ACK
	jmp	sdatcn		; Go handle the nak case
sdat2a: cmp	#'Y		; Did we get an ACK?
	bne	sdat2b		; No, try checking the return status
	jmp	sdatca		; Yes, handle the ack
sdat2b: lda	rstat		; Fetch the return status
	cmp	#false		; Failure return?
	beq	sdat2c		; Yes, just return with current state
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Stuff the abort code
	sta	state		;	as the current system state
	lda	#false		; Load failure return code
sdat2c: rts			; Go back
sdatcn: dec	pnum		; Decrement the packet sequence number
	lda	n		; Get the expected packet sequence number
	cmp	pnum		; If n=pnum-1 then this is like an ack
	bne	sdatn1		; No, continue handling the nak
	jmp	sdata2		; Jump to ack bypassing sequence check
sdata1:
sdatn1: lda	#false		; Failure return
	rts
sdatca: lda	n		; First check packet number
	cmp	pnum		; Did he ack the correct packet?
	bne	sdata1		; No, go give failure return
sdata2: lda	#$00		; Zero out number of tries for current packet
	sta	numtry
	jsr	incn		; Increment the packet sequence number
	lda	eofinp		; Load end-of-file indicator
	cmp	#true		; Was this set by Bufill?
	beq	sdatrz		; If so, return state 'Z' ('Send-eof')
	jsr	bufill		; Go fill the packet buffer with data
	sta	size		; Save the data size returned
	jmp	sdatrd		; Otherwise, return state 'D' ('Send-data')
sdatrz:	lda	#$00		; Clear
	sta	eofinp		;	End of input flag
	lda	#fcb1\		; Get the pointer to the fcb
	sta	kerfcb		;	and store it where the close routine
	lda	#fcb1^		;	can find it
	sta	kerfcb		;		...
	lda	#$00		; Make CLOSEF see there are no errors
	jsr	closef		; We are done with this file, so close it
	lda	#'Z		; Load the Eof code
	sta	state		;	and make it the current system state
	lda	#true		; We did succeed, so give a true return
	rts			; Go back
sdatrd: lda	#'D		; Load the Data code
	sta	state		; Set current system state to that
	lda	#true		; Set up successful return
	rts			;	and go back

sfil:;	lda	filmod		; Fetch the file mode
;	beq	sfil0		; If it is a text file, we don't need length
;	lda	#on		; Otherwise, set flag to get length of file
;	sta	fetfl		;	from first sector
sfil0:	lda	numtry		; Fetch the current number of tries
	inc	numtry		; Up it by one
	cmp	maxtry		; See if we went up to too many
	beq	sfil1		; Not yet
	bcs	sfil1a		; Yes, go abort
sfil1:	jmp	sfil1b		; If we are still ok, take this jump
sfil1a:	lda	#'A		; Load code for abort
	sta	state		;	and drop that in as the current state
	lda	#false		; Load false for a return code
	rts			;	and return
sfil1b:	ldy	#$00		; Clear Y
sfil1c:	lda	fcb1,y		; Get a byte from the filename
	cmp	#$00		; Is it a null?
	beq	sfil1d		; No, continue
	cmp	#$20		; <sp>?
	beq	sfil1d		; [DD]
	sta	pdbuf,y		; Move the byte to this buffer
	iny			; Up the index once
	jmp	sfil1c		; Loop and do it again
sfil1d:	sty	pdlen		; This is the length of the filename
	lda	#'F		; Load type ('Send-file')
	sta	ptype		; Stuff that in as the packet type
	lda	n		; Get packet number
	sta	pnum		; Store that in its common area
	jsr	spak		; Go send the packet
sfil2:	jsr	rpak		; Go try to receive an ack
	sta	rstat		; Save the return status
	lda	ptype		; Get the returned packet type
	cmp	#'N		; Is it a NAK?
	bne	sfil2a		; No, try the next packet type
	jmp	sfilcn		; Handle the case of a nak
sfil2a:	cmp	#'Y		; Is it, perhaps, an ACK?
	bne	sfil2b		; If not, go to next test
	jmp	sfilca		; Go and handle the ack case
sfil2b:	lda	rstat		; Get the return status
	cmp	#false		; Is it a failure return?
	bne	sfil2c		; No, just go abort the send
	rts			; Return failure with current state
sfil2c:	;jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Set state to 'abort'
	sta	state		; Stuff it in its place
	lda	#false		; Set up a failure return code
	rts			;	and go back
sfilcn:	dec	pnum		; Decrement the receive packet number once
	lda	pnum		; Load it into the AC
	cmp	n		; Compare that with what we are looking for
	bne	sfiln1		; If n=pnum-1 then this is like an ack, do it
	jmp	sfila2		; This is like an ack
sfila1:	
sfiln1:	lda	#false		; Load failure return code
	rts			;	and return
sfilca:	lda	n		; Get the packet number
	cmp	pnum		; Is that the one that was acked?
	bne	sfila1		; They are not equal
sfila2:	lda	#$00		; Clear AC
	sta	numtry		; Zero the number of tries for current packet
	jsr	incn		; Up the packet sequence number
	lda	#fcb1\		; Load the fcb address into the pointer
	sta	kerfcb		;	for the DOS open routine
	lda	#fcb1^		;		...
	sta	kerfcb+1	;		...
	lda	#fncrea		; Open for input
	jsr	openf		; Open the file
	jsr	bufill		; Go get characters from the file
	sta	size		; Save the returned buffer size
	lda	#'D		; Set state to 'Send-data'
	sta	state		;		...
	lda	#true		; Set up true return code
	rts			;	and return

seof:	lda	numtry		; Get the number of attempts for this packet
	inc	numtry		; Now up it once for next time around
	cmp	maxtry		; Are we over the allowed max?
	beq	seof1		; Not quite yet
	bcs	seof1a		; Yes, go abort
seof1:  jmp	seof1b		; Continue sending packet
seof1a: lda	#'A		; Load 'abort' code
	sta	state		; Make that the state of the system
	lda	#errmrc		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#erms14\	; Get error message [D.D.]
	sta	lsterr
	lda	#erms14\
	sta	lsterr+1
	lda	#false		; Return false
	rts
seof1b: lda	#'Z		; Load the packet type 'Z' ('Send-eof')
	sta	ptype		; Save that as a parm to Spak
	lda	n		; Get the packet sequence number
	sta	pnum		; Copy in that parm
	lda	#$00		; This is our packet data length (0 for EOF)
	sta	pdlen		; Copy it
	jsr	spak		; Go send out the Eof
seof2:  jsr	rpak		; Try to receive an ack for it
	sta	rstat		; Save the return status
	lda	ptype		; Get the received packet type
	cmp	#'N		; Was it a nak?
	bne	seof2a		; If not, try the next packet type
	jmp	seofcn		; Go take care of case nak
seof2a: cmp	#'Y		; Was it an ack
	bne	seof2b		; If it wasn't that, try return status
	jmp	seofca		; Take care of the ack
seof2b: lda	rstat		; Fetch the return status
	cmp	#false		; Was it a failure?
	beq	seof2c		; Yes, just fail return with current state
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; No, abort the whole thing
	sta	state		; Set the state to that
	lda	#false		; Get false return status
seof2c: rts			; Return
seofcn: dec	pnum		; Decrement the received packet sequence number
	lda	n		; Get the expected sequence number
	cmp	pnum		; If it's the same as pnum-1, it is like an ack
	bne	seofn1		; It isn't, continue handling the nak
	jmp	seofa2		; Switch to an ack but bypass sequence check
seofa1:
seofn1: lda	#false		; Load failure return status
	rts			;	and return
seofca: lda	n		; Check sequence number expected against
	cmp	pnum		;	the number we got.
	bne	seofa1		; If not identical, fail and return curr. state
seofa2: lda	#$00		; Clear the number of tries for current packet
	sta	numtry
	jsr	incn		; Up the packet sequence number
	jsr	getnfl		; Call the routine to get the next file
	cmp	#eof		; If it didn't find any more
	beq	seofrb		;	then return state 'B' ('Send-Eot')
	jmp	seofrf		; Otherwise, return 'F' ('Send-file')
seofrb: lda	#'B		; Load Eot state code
	sta	state		; Store that as the current state
	lda	#true		; Give a success on the return
	rts
seofrf: lda	#'F		; Load File-header state code
	sta	state		; Make that the current system state
	lda	#true		; Make success the return status
	rts			;	and return
sini:	lda	#pdbuf\	; Load the pointer to the packet buffer
	sta	kerbf1		;
	lda	#pdbuf^		;
	sta	kerbf1+1	;
	jsr	spar		; Go fill in the send init parms
	lda	numtry		; If numtry > maxtry
	cmp	maxtry
	beq	sini1
	bcs	sini1a		;	then we are in bad shape, go fail
sini1:  jmp	sini1b		; Otherwise, we just continue
sini1a:	lda	#'A		; Set state to 'abort'
	sta	state		;		...
	lda	#errmrc		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#$00		; Set return status (AC) to fail
	rts			; Return
sini1b: inc	numtry		; Increment the number of tries for this packet
	lda	#'S		; Packet type is 'Send-init'
	sta	ptype		; Store that
	lda	ebqmod		; Do we want 8-bit quoting?
	cmp	#on
	beq	sini1c		; If so, data length is 7
	lda	#$06		; Else it is 6
	jmp	sini1d
sini1c: lda	#$07		; The length of data in a send-init is always 7
sini1d: sta	pdlen		; Store that parameter
	lda	n		; Get the packet number
	sta	pnum		; Store that in its common area
	jsr	spak		; Call the routine to ship the packet out
	jsr	rpak		; Now go try to receive a packet
	sta	rstat		; Hold the return status from that last routine
sinics: lda	ptype		; Case statement, get the packet type
	cmp	#'Y		; Was it an ACK?
	bne	sinic1		; If not, try next type
	jmp	sinicy		; Go handle the ack
sinic1: cmp	#'N		; Was it a NAK?
	bne	sinic2		; If not, try next condition
	jmp	sinicn		; Handle a nak
sinic2: lda	rstat		; Fetch the return status
	cmp	#false		; Was this, perhaps false?
	bne	sinic3		; Nope, do the 'otherwise' stuff
	jmp	sinicf		; Just go and return
sinic3:	;jsr	prcerp		; Check for error packet and process it
	lda	#'A		; Set state to 'abort'
	sta	state
sinicn:
sinicf: rts			; Return

sinicy: ldy	#$00		; Clear Y
	lda	n		; Get packet number
	cmp	pnum		; Was the ack for that packet number?
	beq	siniy1		; Yes, continue
	lda	#false		; No, set false return status
	rts			;	and go back
siniy1: jsr	rpar		; Get parms from the ack packet
	lda	sebq		; Check if other Kermit agrees to 8-bit quoting
	cmp	#'Y
	beq	siniy2		; Yes!
	lda	#off		; Shut it off
	sta	ebqmod
siniy2:
siniy3: lda	#'F		; Load code for 'Send-file' into AC
	sta	state		; Make that the new state
	lda	#$00		; Clear AC
	sta	numtry		; Reset numtry to 0 for next send
	jsr	incn		; Up the packet sequence number
	lda	#true		; Return true
	rts

sbrk:	lda	numtry		; Get the number of tries for this packet
	inc	numtry		; Incrment it for next time
	cmp	maxtry		; Have we exceeded the maximum
	beq	sbrk1		; Not yet
	bcs	sbrk1a		; Yes, go abort the whole thing
sbrk1:  jmp	sbrk1b		; Continue send
sbrk1a:	lda	#'A		; Load 'abort' code
	sta	state		; Make that the system state
	lda	#errmrc		; Fetch the error index
	sta	errcod		;	and store it as the error code
	lda	#false		; Load the failure return status
	rts			;	and return
sbrk1b: lda	#'B		; We are sending an Eot packet
	sta	ptype		; Store that as the packet type
	lda	n		; Get the current sequence number
	sta	pnum		; Copy in that parameter
	lda	#$00		; The packet data length will be 0
	sta	pdlen		; Copy that in
	jsr	spak		; Go send the packet
sbrk2:  jsr	rpak		; Try to get an ack
	sta	rstat		; First, save the return status
	lda	ptype		; Get the packet type received
	cmp	#'N		; Was it a NAK?
	bne	sbrk2a		; If not, try for the ack
	jmp	sbrkcn		; Go handle the nak case
sbrk2a: cmp	#'Y		; An ACK?
	bne	sbrk2b		; If not, look at the return status
	jmp	sbrkca		; Go handle the case of an ack
sbrk2b: lda	rstat		; Fetch the return status from Rpak
	cmp	#false		; Was it a failure?
	beq	sbrk2c		; Yes, just return with current state
;	jsr	prcerp		; Check for error packet and process it
	lda	#'A		; No, set up the 'abort' code
	sta	state		;	as the system state
	lda	#false		;	load the false return status
sbrk2c: rts			;	and return
sbrkcn: dec	pnum		; Decrement the received packet number once
	lda	n		; Get the expected sequence number
	cmp	pnum		; If =pnum-1 then this nak is like an ack
	bne	sbrkn1		; No, this was no the case
	jmp	sbrka2		; Yes! Go do the ack, but skip sequence check
sbrka1:
sbrkn1: lda	#false		; Load failure return code
	rts			;	and go back
sbrkca: lda	n		; Get the expected packet sequence number
	cmp	pnum		; Did we get what we expected?
	bne	sbrka1		; No, return failure with current state
sbrka2: lda	#$00		; Yes, clear number of tries for this packet
	sta	numtry
	jsr	incn		; Up the packet sequence number
	lda	#'C		; The transfer is now complete, reflect this
	sta	state		;	in the system state
	lda	#true		; Return success!
	rts

.SBTTL	Setcom routine
;
;	This routine sets Kermit-65 parameters.
;
;		Input:  Parameters from command line
;
;		Output: NONE
;
;		Registers destroyed:	A,X,Y
;

setcom: lda	#setcmd\	; Load the address of the keyword table
	sta	cminf1		;
	lda	#setcmd^	;
	sta	cminf1+1	;
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	lda	#setcmb\	; Get the address of jump table
	sta	jtaddr		;
	lda	#setcmb^	;
	sta	jtaddr+1	;
	txa			; Offset to AC
	jmp	jmpind		; JUMPIND [D.D.]
setcmb: jmp	stesc		; Set escape character
	jmp	stibm		; Set ibm-mode switch
	jmp	stle		; Set local-echo switch
	jmp	strc		; Set receive parameters
	jmp	stsn		; Set send parameters
	jmp	stvt		; Set vt52-emulation switch
	jmp	stfw		; Set file-warning switch
	jmp	steb		; Set Eight-bit quoting character
	jmp	stdb		; Set debugging switch
	jmp	stmod		; Set file-type mode
	jmp	stfbs		; Set the file-byte-size for transfer
	jmp	stccr		; Set rs232 registers [DD]
	jmp	stpari		; Set the parity for communication

stesc:  ldx	#$10		; Base should be hex
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Parse for integer
	jsr	comnd		; Go!
	 jmp	kermt4		; Number is bad
	stx	ksavex		; Hold the number across the next call
	sty	ksavey		;		...
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed
	lda	ksavey		; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	stesc1		; It is, continue
	jmp	kermt4		; Bad number, tell them
stesc1:	lda	ksavex		; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	stesc2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
stesc2: sta	escp		; Stuff it
	jmp	kermit

stibm:  jsr	prson		; Try parsing an 'on' or 'off'
	 jmp	kermt2		; Bad keyword
	stx	ibmmod		; Store value in the mode switch location
	stx	lecho		; Also set local echo accordingly
	ldy	#nparit		; Get ready to set the parity parameter
	cpx	#on		; Setting ibm mode on?
	bne	stibm1		; Nope so set no parity
	ldy	#mparit		; Set mark parity
stibm1:	sty	parity		; Store the value
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit		;

stle:	jsr	prson		; Try parsing an 'on' or 'off'
	 jmp	kermt2		; Bad keyword
	stx	lecho		; Store value in the mode switch location
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

strc:	lda	#$00		; Set srind for receive parms
	sta	srind
	lda	#stscmd\	; Load the address of the keyword table
	sta	cminf1		; Save it for the keyword routine
	lda	#stscmd^	;
	sta	cminf1+1	;
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	lda	#stcct\		; Get addr. of jump table
	sta	jtaddr		;
	lda	#stcct^		;
	sta	jtaddr+1	;
	txa			; Offset to AC
	jmp	jmpind  	; JUMPIND [D.D.]

stsn:	lda	#$01		; Set srind for send parms
	sta	srind
	lda	#stscmd\	; Load the address of the keyword table
	sta	cminf1		; Save it for the keyword routine
	lda	#stscmd^
	sta	cminf1+1
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	lda	#stcct\		; Get addr. of jump table
	sta	jtaddr		;
	lda	#stcct^		;
	sta	jtaddr+1	;
	txa			; offset to AC
	jmp	jmpind		; JUMPIND [D.D.]

stcct:  jmp	stpdc		; Set send/rec padding character
	jmp	stpad		; Set amount of padding on send/rec
	jmp	stebq		; Set send/rec eight-bit-quoting character
	jmp	steol		; Set send/rec end-of-line
	jmp	stpl		; Set send/rec packet length
	jmp	stqc		; Set send/rec quote character
	jmp	sttim		; Set send/rec timeout

stvt:	jsr	prson		; Try parsing an 'on' or 'off'
	 jmp	kermt2		; Bad keyword
	stx	vtmod		; Store value in the mode switch location
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

stfw:	jsr	prson		; Try parsing an 'on' or 'off'
	 jmp	kermt2		; Bad keyword
	stx	filwar		; Store value in the mode switch location
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

steb:	jsr	prson		; Try parsing an 'on' or 'off'
	 jmp	kermt2		; Bad keyword
	stx	ebqmod		; Store value in the mode switch location
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

stdb:	ldx	#debkey\	;  Load the address of the keyword table
	ldy	#debkey^
	stx	cminf1		;  Save it for the keyword routine
	sty	cminf1+1
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	stx	debug		; Stuff returned value into debug switch
	lda	#cmcfm		; Parse for a confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit


stebq:  ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	steb1		; It is, continue
	jmp	kermt4		; Bad number, tell them
steb1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	steb2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
steb2:  cmp	#$21		; First check the character range
	bmi	steb4		; Not in range
	cmp	#$3f
	bmi	steb3		; Inrange
	cmp	#$60
	bmi	steb4		; Not in range
steb3:  ldx	srind		; Get index for receive or send parms
	sta	ebq,x		; Stuff it
	lda	#cmcfm		; Parse for confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit
steb4:  ldx	#ermes5\	; Get error message
	ldy	#ermes5^
	jsr	prstr		; Print the error
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

steol:  ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	steo1		; It is, continue
	jmp	kermt4		; Bad number, tell them
steo1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	steo2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
steo2:  ldx	srind		; Fetch index for receive or send parms
	sta	eol,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

stpad:  ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	stpd1		; It is, continue
	jmp	kermt4		; Bad number, tell them
stpd1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	stpd2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
stpd2:  ldx	srind		; Get index (receive or send)
	sta	pad,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

stpdc:  ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	stpc1		; It is, continue
	jmp	kermt4		; Bad number, tell them
stpc1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	stpc2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
stpc2:  ldx	srind		; Get index for parms
	sta	padch,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

stpl:	ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	stpl1		; It is, continue
	jmp	kermt4		; Bad number, tell them
stpl1:	txa			; Get L.O. byte
	cmp	#mxpack		; It shouldn't be bigger than this
	bmi	stpl2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
stpl2:  ldx	srind		; Get index
	sta	psiz,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

stqc:	ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	stqc1		; It is, continue
	jmp	kermt4		; Bad number, tell them
stqc1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	stqc2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
stqc2:  ldx	srind		; Fetch index for receive or send parms
	sta	quote,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

sttim:  ldx	#$10		; Base for ASCII value
	ldy	#$00		; No special flags needed
	lda	#cmnum		; Code for integer number
	jsr	comnd		; Go do it
	 jmp	kermt4		; The number was bad
	tya			; If this isn't zero
	cmp	#$00		;	it's not an ASCII character
	beq	sttm1		; It is, continue
	jmp	kermt4		; Bad number, tell them
sttm1:	txa			; Get L.O. byte
	cmp	#$7f		; It shouldn't be bigger than this
	bmi	sttm2		; If it's less, it is ok
	jmp	kermt4		; Tell the user it is bad
sttm2:  ldx	srind		; Fetch index for receive or send parms
	sta	time,x		; Stuff it
	jsr	prcfm		; Go parse and print a confirm
	jmp	kermit		; Go back

stmod:	lda	#ftcmd\		; Load the address of the keyword table
	sta	cminf1		;
	lda	#ftcmd^		;
	sta	cminf1+1	;
	lda	#ftcdef\	; Load default address
	sta	cmdptr		;		...
	lda	#ftcdef^	;		...
	sta	cmdptr+1	;		...
	ldy	#cmfdff		; Tell Comnd there is a default
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	stx	filmod		; Save the file-type mode
	lda	#cmcfm		; Parse for a confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

stfbs:	lda	#fbskey\	; Load the address of the keyword table
	sta	cminf1		;
	lda	#fbskey^	;
	sta	cminf1+1	;
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	stx	fbsize		; Stuff the returned value into file-byte-size
	lda	#cmcfm		; Parse for a confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit

; Set rs232 registers [DD]

stccr:  ldx	#$10		; [DD] Base should be hex
	ldy	#$00		;  No special flags needed
	lda	#cmnum		; [DD] Parse for integer
	jsr	comnd		; [DD] Go do it
	 jmp	kermt4		; [DD] The number was bad
stccr1:	stx	ksavex		;  Store it while we confirm
	sty	ksavey		; 
	lda	#cmcfm		;  Set up to parse confirm
	jsr	comnd		;  Do it
	 jmp	kermt3		;  Wasn't properly confirmed
	lda	ksavex		;  Fetch back L.O. byte
	sta	cntrl		; [DD][EL] To rs232 reg 0
	ldy	ksavey		;  Fetch back H.O. byte
	sta	cmmnd		; [DD] To rs232 reg 1
	jmp	kermit		; [DD]

stpari:	lda	#parkey\	; Load the address of the keyword table
	sta	cminf1		; Save it for the keyword routine
	lda	#parkey^	;		...
	sta	cminf1+1	;		...
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Comnd code for parse keyword
	jsr	comnd		; Go get it
	 jmp	kermt2		; Give an error
	stx	parity		; Stuff returned value into parity
	lda	#cmcfm		; Parse for a confirm
	jsr	comnd		; Do it
	 jmp	kermt3		; Not confirmed, tell the user that
	jmp	kermit		;

.SBTTL	Show routine
;
;	This routine shows any of the operational parameters that
;	can be altered with the set command.
;
;		Input:  Parameters from command line
;
;		Output: Display parameter values on screen
;
;		Registers destroyed:	A,X,Y
;

show:	lda	#shocmd\	; Load address of keyword table
	sta	cminf1		;
	lda	#shocmd^	;
	sta	cminf1+1	;
	lda	#shodef\	; Fetch default address
	sta	cmdptr		;		...
	lda	#shodef^	;		...
	sta	cmdptr+1	;		...
	ldy	#cmfdff		; Indicate that there is a default
	lda	#cmkey		; Comnd code to parse keyword
	jsr	comnd		; Go parse the keyword
	 jmp	kermt2		; Bad keyword, go give an error
	lda	#shocmb\ 	; Get addr. of jump table
	sta	jtaddr		;
	lda	#shocmb^	;
	sta	jtaddr+1	;
	txa			; Offset to AC
	jmp	jmpind		; JUMP[D.D.]

shocmb: jsr	prcfm		; Parse for confirm
	jsr	shall		; Show all setable parameters
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shesc		; Show escape character
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shibm		; Show ibm-mode switch
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shle		; Show local-echo switch
	jmp	kermit		; Go to top of main loop
	nop			; We should not parse for confirm
	nop			;	since this routine parses for
	nop			;	a keyword next
	jsr	shrc		; Show receive parameters
	jmp	kermit		; Go to top of main loop
	nop			; We should not parse for confirm
	nop			;	since this routine parses for
	nop			;	a keyword next
	jsr	shsn		; Show send parameters
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shvt		; Show vt52-emulation mode switch
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shfw		; Show file-warning switch
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	sheb		; Show eight-bit-quoting switch
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shdb		; Show debugging mode switch
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shmod		; Show File mode
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm
	jsr	shfbs		; Show the file-byte-size
	jmp	kermit		; Go to top of main loop
	jsr	prcfm		; Parse for confirm [DD]
	jsr	shccr		; Show rs232 regs.  [DD]
	jmp	kermit		; Go to top of main loop [DD]
	jsr	prcfm		; Parse for confirm
	jsr	shpari		; Show Parity
	jmp	kermit		; Go to top of main loop

shall:  jsr	shdb		; Show debugging mode switch
	jsr	shvt		; Show vt52-emulation mode switch
	jsr	shibm		; Show ibm-mode switch
	jsr	shle		; Show local-echo switch
	jsr	shpari		; Show parity setting
	jsr	sheb		; Show eight-bit-quoting switch
	jsr	shfw		; Show file-warning switch
	jsr	shesc		; Show the current escape character
	jsr	shmod		; Show the file-type mode
	jsr	shfbs		; Show the file-byte-size
	jsr	shccr		; Show rs232 regs.  [DD]
	jsr	shrcal		; Show receive parameters
	jsr	shsnal		; Show send parameters
	rts			; Return

shdb:	ldx	#shin00\	; Get address of message for this item
	ldy	#shin00^
	jsr	prstr		; Print that message
	lda	debug		; Get the switch value
	cmp	#$03		; Is it >= 3?
	bmi	shdb1		; If not just get the string and print it
	lda	#$00		; This is index for debug mode we want
shdb1:	tax			; Hold this index
	lda	#kerdms\	; Get the address of the device strings
	sta	kermbs		; And stuff it here for genmad
	lda	#kerdms^	;		...
	sta	kermbs+1	;		...
	lda	#kerdsz		; Get the string length
	pha			; Push that
	txa			; Fetch the index back
	pha			; Push that parm then
	jsr	genmad		;	call genmad
	jsr	prstr		; Print the the string at that address
	jsr	prcrlf		; Print a crelf after it
	rts

shvt:	ldx	#shin01\	; Get address of message for this item
	ldy	#shin01^
	jsr	prstr		; Print that message
	lda	vtmod		; Get the switch value
	jmp	pron		; Go print the 'on' or 'off' string

shibm:  ldx	#shin02\	; Get address of message for this item
	ldy	#shin02^
	jsr	prstr		; Print that message
	lda	ibmmod		; Get the switch value
	jmp	pron		; Go print the 'on' or 'off' string

shle:	ldx	#shin03\	; Get address of message for this item
	ldy	#shin03^
	jsr	prstr		; Print that message
	lda	lecho		; Get the switch value
	jmp	pron		; Go print the 'on' or 'off' string

sheb:	ldx	#shin04\	; Get address of message for this item
	ldy	#shin04^
	jsr	prstr		; Print that message
	lda	ebqmod		; Get the switch value
	jmp	pron		; Go print the 'on' or 'off' string

shfw:	ldx	#shin05\	; Get address of message for this item
	ldy	#shin05^
	jsr	prstr		; Print that message
	lda	filwar		; Get the switch value
	jmp	pron		; Go print the 'on' or 'off' string

shesc:  ldx	#shin06\	; Get address of message
	ldy	#shin06^
	jsr	prstr		; Print message
	lda	escp		; Get the escape character
	jsr	prchr		; Print the special character
	jsr	prcrlf		; Print a crelf
	rts			;	and return

shccr:  ldX	#shin18\	; Print rs232 registers cntrl,cmmnd [DD][EL]
	ldy	#shin18^
	jsr	prstr
	lda	cmmnd		; print rs232 reg 1
	jsr	prbyte
	lda	cntrl		; Print rs232 reg 0
	jsr	prbyte
	jsr	prcrlf		; CRLF
	rts			; [DD]
;

shsn:	lda	#$01		; Set up index to be used later
	sta	srind
	lda	#stscmd\	; Get the set option table address
	sta	cminf1		;
	lda	#stscmd^	;
	sta	cminf1+1	;
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Code for keyword parse
	jsr	comnd		; Try to parse it
	 jmp	kermt2		; Invalid keyword
	stx	kwrk01		; Hold offset into jump table
	jsr	prcfm		; Parse and print a confirm
	lda	#shcmb\  	; Get addr. of jump table
	sta	jtaddr		;
	lda	#shcmb^		;
	sta	jtaddr+1	;
	lda	kwrk01		; Get offset  back
	asl	a		; Double it
	jmp	jmpind  	; JUMP[D.D.]
;
shrc:	lda	#$00		; Set up index to be used later
	sta	srind
	lda	#stscmd\	; Get the set option table address
	sta	cminf1		;
	lda	#stscmd^	;
	sta	cminf1+1	;
	ldy	#$00		; No special flags needed
	lda	#cmkey		; Code for keyword parse
	jsr	comnd		; Try to parse it
	 jmp	kermt2		; Invalid keyword
	stx	kwrk01		; Hold offset into jump table
	jsr	prcfm		; Parse and print a confirm
	lda	#shcmb\		; Get addr. ofl jump table
	sta	jtaddr		;
	lda	#shcmb^		;
	sta	jtaddr+1	;
	lda	kwrk01		; Get offset  back
	asl	a		; Double it
	jmp	jmpind		; JUMP[D.D.]

shcmb:  jsr	shpdc		; Show send/rec padding character
	jmp	kermit		; Go back
	jsr	shpad		; Show amount of padding for send/rec
	jmp	kermit		; Go back
	jsr	shebq		; Show send/rec eight-bit-quoting character
	jmp	kermit		; Go back
	jsr	sheol		; Show send/rec end-of-line character
	jmp	kermit		; Go back
	jsr	shpl		; Show send/rec packet length
	jmp	kermit		; Go back
	jsr	shqc		; Show send/rec quote character
	jmp	kermit		; Go back
	jsr	shtim		; Show send/rec timeout
	jmp	kermit		; Go back

shpdc:  ldx	#shin11\	; Get address of 'pad char' string
	ldy	#shin11^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	padch,x		; If index is 1, this gets spadch
	jsr	prchr		; Print the special character
	jsr	prcrlf		; Print a crelf after it
	rts
shpad:  ldx	#shin12\	; Get address of 'padding amount' string
	ldy	#shin12^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	pad,x		; If index is 1, this gets spad
	jsr	prbyte		; Print the amount of padding
	jsr	prcrlf		; Print a crelf after it
	rts
shebq:  ldx	#shin08\	; Get address of 'eight-bit-quote' string
	ldy	#shin08^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	ebq,x		; If index is 1, this gets sebq
	jsr	prchr		; Print the special character
	jsr	prcrlf		; Print a crelf after it
	rts
sheol:  ldx	#shin09\	; Get address of 'end-of-line' string
	ldy	#shin09^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	eol,x		; If index is 1, this gets seol
	jsr	prchr		; Print the special character
	jsr	prcrlf		; Print a crelf after it
	rts
shpl:	ldx	#shin10\	; Get address of 'packet length' string
	ldy	#shin10^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	psiz,x		; If index is 1, this gets spsiz
	jsr	prbyte		; Print the packet length
	jsr	prcrlf		; Print a crelf after it
	rts			;	and return
shqc:	ldx	#shin13\	; Get address of 'quote-char' string
	ldy	#shin13^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	quote,x		; If index is 1, this gets squote
	jsr	prchr		; Print the special character
	jsr	prcrlf		; Print a crelf after it
	rts
shtim:  ldx	#shin14\	; Get address of 'timeout' string
	ldy	#shin14^
	jsr	prstr		; Print that
	ldx	srind		; Load index so we print correct parm
	lda	time,x		; If index is 1, this gets stime
	jsr	prbyte		; Print the hex value
	jsr	prcrlf		; Print a crelf after it
	rts

shsnal: lda	#$01		; Set up index for show parms
	sta	srind		;	and stuff it here
	ldx	#shin07\	; Get address of 'send' string
	ldy	#shin07^	;
	jsr	prstr		; Print it
	jsr	prcrlf		; Print a crelf
	jsr	shpdc		; Show the padding character
	jsr	shpad		; Show amount of padding
	jsr	shebq		; Show eight-bit-quote character
	jsr	sheol		; Show end-of-line character
	jsr	shpl		; Show packet-length
	jsr	shqc		; Show quote character
	jsr	shtim		; Show timeout length
	rts

shrcal: lda	#$00		; Set up index for show parms
	sta	srind		;	and stuff it here
	ldx	#shin15\	; Get address of 'receive' string
	ldy	#shin15^
	jsr	prstr		; Print it
	jsr	prcrlf		; Print a crelf
	jsr	shpdc		; Show the padding character
	jsr	shpad		; Show amount of padding
	jsr	shebq		; Show eight-bit-quote character
	jsr	sheol		; Show end-of-line character
	jsr	shpl		; Show packet-length
	jsr	shqc		; Show quote character
	jsr	shtim		; Show timeout length
	rts

shmod:  ldx	#shin16\	; Get address of 'timeout' string
	ldy	#shin16^
	jsr	prstr		; Print that
	lda	filmod		; Get the file-type mode
	cmp	#$04		; Is it >= 4?
	bmi	shmod1		; If not just get the string and print it
	lda	#$03		; This is the index to the file-type we want
shmod1: tax			; Hold this index
	lda	#kerftp\	; Get the address if the file type strings
	sta	kermbs		;
	lda	#kerftp^	;
	sta	kermbs+1	;
	lda	#kerfts		; Get the string length
	pha			; Push that
	txa			; Fetch the index back
	pha			; Push that parm then
	jsr	genmad		;	call genmad
	jsr	prstr		; Print the the string at that address
	jsr	prcrlf		; Print a crelf after it
	rts

shfbs:  ldx	#shin17\	; Get address of 'file-byte-size' string
	ldy	#shin17^
	jsr	prstr		; Print that
	lda	fbsize		; Get the file-type mode
	beq	shfbse		; It is in eight-bit mode
	ldx	#shsbit\	; Get address of 'SEVEN-BIT' string
	ldy	#shsbit^	;
	jsr	prstr		; Print that
	jsr	prcrlf		;	then a crelf
	rts			;	and return
shfbse: ldx	#shebit\	; Get the address of 'EIGHT-BIT' string
	ldy	#shebit^	;
	jsr	prstr		; Print the the string at that address
	jsr	prcrlf		; Print a crelf after it
	rts

shpari:	ldx	#shin20\	; Get address of 'parity' string
	ldy	#shin20^	;		...
	jsr	prstr		; Print that
	lda	parity		; Get the parity index
	cmp	#$05		; Is it >= 5?
	bmi	shpar1		; If not just get the string and print it
	lda	#$00		; This is the index to the parity we want
shpar1:	tax			; Hold this index
	lda	#kerprs\	; Get address of the parity strings
	sta	kermbs		; And stuff it here for genmad
	lda	#kerprs^	;		...
	sta	kermbs+1	;		...
	lda	#kerpsl		; Get the string length
	pha			; Push that
	txa			; Fetch the index back
	pha			; Push that parm then
	jsr	genmad		;	call genmad
	jsr	prstr		; Print the the string at that address
	jsr	prcrlf		; Print a crelf after it
	rts

.SBTTL	Status routine
;
;	This routine shows the status of the most recent transmission
;	session.
;
;		Input:  NONE
;
;		Output: Status of last transmission is sent to screen
;
;		Registers destroyed:	A,X,Y
;

status: jsr	prcfm		; Parse and print a confirm

stat01: ldx	#stin00\	; Get address of first line of text
	ldy	#stin00^
	jsr	prstr		; Print that
	lda	schr		; Get low order byte of character count
	tax			; Put that in x
	lda	schr+1		; Get high order byte
	jsr	prntax		; Print that pair in hex
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin01\	; Get address of second line
	ldy	#stin01^
	jsr	prstr		; Print it
	lda	rchr		; Get L.O. byte of char count
	tax			; Stuff it here for the call
	lda	rchr+1		; Get H.O. byte
	jsr	prntax		; Print that count
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin02\	; Get L.O. address of message
	ldy	#stin02^	;
	jsr	prstr		; Print message
	lda	stot		; Get L.O. byte of count
	tax			; Save it
	lda	stot+1		; Get H.O. byte
	jsr	prntax		; Print the count
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin03\	; Get address of next status item message
	ldy	#stin03^
	jsr	prstr		; Print it
	lda	rtot		; Get the proper count (L.O. byte)
	tax			; Hold it here for the call
	lda	rtot+1		; Get H.O. byte
	jsr	prntax		; Print the 16-bit count
	jsr	prcrlf		; Add a crelf at the end
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin04\	; Get address of overhead message
	ldy	#stin04^	;
	jsr	prstr		; Print that message
	sec			; Get ready to calculate overhead amount
	lda	stot		; Get total character count and
	sbc	schr		;	subtract off data character count
	tax			; Stuff that here for printing
	lda	stot+1
	sbc	schr+1
	jsr	prntax		; Print it
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin05\	; Get address of next overhead message
	ldy	#stin05^
	jsr	prstr		; Print that
	sec			; Get ready to calculate overhead amount
	lda	rtot		; Get total character count and
	sbc	rchr		;	subtract off data character count
	tax			; Stuff that here for printing
	lda	rtot+1
	sbc	rchr+1
	jsr	prntax		; Print the count
	jsr	prcrlf		; Add a crelf at the end
	jsr	prcrlf		; Add a crelf at the end
	ldx	#stin06\  	; Get message for 'last error'
	ldy	#stin06^
	jsr	prstr		; Print the message
	jsr	prcrlf		; Print a crelf before the error message
	ldx	#lsterr\
	ldy	#lsterr^
statlf:	jsr	prstr
	jsr	prcrlf
	jsr	prcrlf
	jmp	kermit

;	bit	errcod		; Test for 'Error packet received' bit
;	bvs	statpe		; Go process an error packet
;	lda	#kerems		; Get the error message size
;	pha			; Push it
;	lda	errcod		; Get the error message offset in table
;	bmi	stat02		; If this is a DOS error, do extra adjusting	
;	pha			; Push that
;	lda	#erms0a\	; Put the base address in kermbs
;	sta	kermbs		;		...
;	lda	#erms0a^	;		...
;	sta	kermbs+1	;		...
;	jmp	statle		; Go print the 'last error' encountered
;stat02:	and	#$7f		; Shut off H.O. bit
;	beq	stat03		; If it is zero, we are done adjusting
;	sec			; Decrement by one for the unused error code
;	sbc	#$01		;		...
;stat03:	pha			; Push that parameter
;	lda	#dskers\	; Use 'dskers' as the base address
;	sta	kermbs		;		...
;	lda	#dskers^	;		...
;	sta	kermbs+1	;		...
;statle:	jsr	genmad		; Translate code to address of message
;	jsr	prstr		; Print the text of error message
;	jsr	prcrlf		; Add a crelf at the end
;	jsr	prcrlf		; Add a crelf at the end
;	jmp	kermit
;statpe:	ldx	#errrkm\	; L.O. byte address of remote kermit error
;	ldy	#errrkm^	; H.O. byte address...
;	jsr	prstr		; Print the text from the error packet
;	jsr	prcrlf		; Print an extra crelf
;	jmp	kermit		; Start at the top again


.SBTTL	Packet routines - SPAK - send packet
;
;	This routine forms and sends out a complete packet in the
;	following format:
;
;	<SOH><char(pdlen)><char(pnum)><ptype><data><char(chksum)><eol>
;
;		Input:  kerbf1- Pointer to packet buffer
;			pdlen-  Length of data
;			pnum-	Packet number
;			ptype-  Packet type
;
;		Output: A-	True or False return code
;

spak:	jsr	home		; [DD] Clear screen
	ldx	#snin01\	; Give the user info on what we are doing
	ldy	#snin01^
	jsr	prstr		; Print the information
	lda	tpak+1		; Get the total packets count
	jsr	prbyte		;	and print that
	lda	tpak		;
	jsr	prbyte		;
	jsr	prcrlf		; Output a crelf
	lda	#$00		; Clear packet data index
	sta	pdtind		;
spaknd: lda	spadch		; Get the padding character
	ldx	#$00		; Init counter
spakpd: cpx	spad		; Are we done padding?
	bcs	spakst		;  Yes, start sending packet
	inx			; No, up the index and count by one
	jsr	putplc		; Output a padding character
	jmp	spakpd		; Go around again
spakst: lda	#soh		; Get the start-of-header char into AC
	jsr	putplc		; Send it
	lda	pdlen		; Get the data length
	clc			; Clear the carry
	adc	#$03		; Adjust it
	pha			; Save this to be added into stot
	clc			; Clear carry again
	adc	#sp		; Make the thing a character
	sta	chksum		; First item,  start off chksum with it
	jsr	putplc		; Send the character
	pla			; Fetch the pdlen and add it into the
	clc			;	'total characters sent' counter
	adc	stot
	sta	stot
	lda	stot+1
	adc	#$00
	sta	stot+1
	lda	pnum		; Get the packet number
	clc
	adc	#sp		; Char it
	pha			; Save it in this condition
	clc			; Clear carry
	adc	chksum		; Add this to the checksum
	sta	chksum
	pla			; Restore character
	jsr	putplc		; Send it
	lda	ptype		; Fetch the packet type
	and	#$7f		; Make sure H.O. bit is off for chksum
	pha			; Save it on stack
	clc			; Add to chksum
	adc	chksum
	sta	chksum
	pla			; Get the original character off stack
	jsr	putplc		; Send packet type
	ldy	#$00		; Initialize data count
	sty	datind		; Hold it here
spaklp: ldy	datind		; Get the current index into the data
	cpy	pdlen		; Check against packet data length, done?
	bmi	spakdc		; Not yet, process another character
	jmp	spakch		; Go do chksum calculations
spakdc: lda	(kerbf1),y	; Fetch data from packet buffer
	clc			; Add the character into the chksum
	adc	chksum
	sta	chksum
	lda	(kerbf1),y	; Refetch data from packet buffer
	jsr	putplc		; Send it
	inc	datind		; Up the counter and index
	jmp	spaklp		; Loop to do next character
spakch: lda	chksum		; Now, adjust the chksum to fit in 6 bits
	and	#$c0		; First, take bits 6 and 7
	lsr	a		;	and shift them to the extreme right
	lsr	a		;	side of the AC
	lsr	a
	lsr	a
	lsr	a
	lsr	a
	clc			; Now add in the original chksum byte
	adc	chksum
	and	#$3f		; All this should be mod decimal 64
	clc
	adc	#sp		; Put it in printable range
	jsr	putplc		;	and send it
	lda	seol		; Fetch the eol character
	jsr	putplc		; Send that as the last byte of the packet
	lda	pdtind		; Set the end of buffer pointer
	sta	pdtend		;
	lda	#$00		; Set index to zero
	sta	pdtind		;
	lda	debug		; Is the debug option turned on?
	cmp	#off		;
	beq	spaksp		; Nope, go stuff packet at other kermit
	lda	#$00		; Option 0
	jsr	debg		; Do it
spaksp: lda	#$00		; Zero the index
	sta	pdtind		;
spakdl: ldx	pdtind		; Are we done?
	cpx	pdtend		;
	bpl	spakcd		; Yes, go call debug again
	lda	plnbuf,x	; Get the byte to send
	jsr	telppc		; Ship it out
	inc	pdtind		; Increment the index once
	jmp	spakdl		; Go to top of data send loop
spakcd: lda	debug		; Get debug switch
	cmp	#off		; Do we have to do it?
	beq	spakcr		; Nope, return
	lda	#$01		; Option 1
	jsr	debg		; Do the debug stuff
spakcr: rts			;	and return

.SBTTL	Packet routines - RPAK - receive a packet
;
;	This routine receives a standard Kermit packet and then breaks
;	it apart returning the individuals components in their respective
;	memory locations.
;
;		Input:
;
;		Output: kerbf1- Pointer to data from packet
;			pdlen-  Length of data
;			pnum-	Packet number
;			ptype-  Packet type
;

rpak:	jsr	gobble		; Gobble a line up from the port
	 jmp	rpkfls		; Must have gotten a keyboard interupt, fail
	lda	ibmmod		; Is ibm-mode on?
	cmp	#on		;		...
	bne	rpakst		; If not, start working on the packet
rpakc0:	jsr	getc		; Any characters yet?
	 jmp	rpakst		; Got one from the keyboard
	cmp	#xon		; Is it an XON?
	bne	rpakc0		; Nope, try again
rpakst:	jsr	home		; Clear the screen
	ldx	#rcin01\ 	; Give the user info on what we are doing
	ldy	#rcin01^	;
	jsr	prstr		; Print the information
	lda	tpak+1		; Get the total packets count
	jsr	prbyte		;	and print that
	lda	tpak		;
	jsr	prbyte		;
	jsr	prcrlf		; Output a crelf
	lda	debug		; Is debugging on?
	cmp	#off		; 
	beq	rpaknd		;  Nope, no debugging, continue
	lda	#$02		; Option 2 <reflect the fact we are in rpak>
	jsr	debg		; Do debug stuff
rpaknd: lda	#$00		; Clear the
	sta	chksum		;	chksum
	sta	datind		;	index into packet buffer
	sta	kerchr		;	and the current character input
rpakfs: jsr	getplc		; Get a char, find SOH
	 jmp	rpkfls		; Got a keyboard interupt instead
	sta	kerchr		; Save it
	and	#$7f		; Shut off H.O. bit
	cmp	#soh		; Is it an SOH character?
	bne	rpakfs		; Nope, try again
	lda	#$01		; Set up the switch for receive packet
	sta	fld
rpklp1: lda	fld		; Get switch
	cmp	#$06		; Compare for <= 5
	bmi	rpklp2		; If it still is, continue
	jmp	rpkchk		; Otherwise, do the chksum calcs
rpklp2: cmp	#$05		; Check fld
	bne	rpkif1		; If it is not 5, go check for SOH
	lda	datind		; Fetch the data index
	cmp	#$00		; If the data index is not null
	bne	rpkif1		;	do the same thing
	jmp	rpkif2		; Go process the character
rpkif1: jsr	getplc		; Get a char, find SOH
	 jmp	rpkfls		; Got a keyboard interupt instead
	sta	kerchr		; Save that here
	and	#$7f		; Make sure H.O. bit is off
	cmp	#soh		; Was it another SOH?
	bne	rpkif2		; If not, we don't have to resynch
	lda	#$00		; Yes, resynch
	sta	fld		; Reset the switch
rpkif2: lda	fld		; Get the field switch
	cmp	#$04		; Is it <= 3?
	bpl	rpkswt		; No, go check the different cases now
	lda	kerchr		; Yes, it was, get the character
	clc			;	and add it into the chksum
	adc	chksum
	sta	chksum
rpkswt: lda	fld		; Now check the different cases of fld
	cmp	#$00		; Case 0?
	bne	rpkc1		; Nope, try next one
	lda	#$00		; Yes, zero the chksum
	sta	chksum
	jmp	rpkef		;	and restart the loop
rpkc1:  cmp	#$01		; Is it case 1?
	bne	rpkc2		; No, continue checking
	lda	kerchr		; Yes, get the length of packet
	sec
	sbc	#sp		; Unchar it
	sec
	sbc	#$03		; Adjust it down to data length
	sta	pdlen		; That is the packet data length, put it there
	jmp	rpkef		; Continue on to next item
rpkc2:  cmp	#$02		; Case 2 (packet number)?
	bne	rpkc3		; If not, try case 3
	lda	kerchr		; Fetch the character
	sec
	sbc	#sp		; Take it down to what it really is
	sta	pnum		; That is the packet number, save it
	jmp	rpkef		; On to the next packet item
rpkc3:  cmp	#$03		; Is it case 3 (packet type)?
	bne	rpkc4		; If not, try next one
	lda	kerchr		; Get the character and
	sta	ptype		;	stuff it as is into the packet type
	jmp	rpkef		; Go on to next item
rpkc4:  cmp	#$04		; Is it case 4???
	bne	rpkc5		; No, try last case
	ldy	#$00		; Set up the data index
	sty	datind
rpkchl: ldy	datind		; Make sure datind is in Y
	cpy	pdlen		; Compare to the packet data length, done?
	bmi	rpkif3		; Not yet, process the character as data
	jmp	rpkef		; Yes, go on to last field (chksum)
rpkif3: cpy	#$00		; Is this the first time through the data loop?
	beq	rpkacc		; If so, SOH has been checked, skip it
	jsr	getplc		; Get a char, find SOH
	 jmp	rpkfls		; Got a keyboard interupt instead
	sta	kerchr		; Store it here
	and	#$7f		; Shut H.O. bit
	cmp	#soh		; Is it an SOH again?
	bne	rpkacc		; No, go accumulate chksum
	lda	#$ff		; Yup, SOH, go resynch packet input once again
	sta	fld
	jmp	rpkef
rpkacc: lda	kerchr		; Get the character
	clc
	adc	chksum		; Add it to the chksum
	sta	chksum		;	and save new chksum
	lda	kerchr		; Get the character again
	ldy	datind		; Get our current data index
	sta	(kerbf1),y	; Stuff the current character into the buffer
	inc	datind		; Up the index once
	jmp	rpkchl		; Go back and check if we have to do this again
rpkc5:  cmp	#$05		; Last chance, is it case 5?
	beq	rpkc51		; Ok, continue
	jmp	rpkpe		; Warn user about program error
rpkc51: lda	chksum		; Do chksum calculations
	and	#$c0		; Grab bits 6 and 7
	lsr	a		; Shift them to the right (6 times)
	lsr	a
	lsr	a
	lsr	a
	lsr	a
	lsr	a
	clc			; Clear carry for addition
	adc	chksum		; Add this into original chksum
	and	#$3f		; Make all of this mod decimal 64
	sta	chksum		;	and resave it
rpkef:  inc	fld		; Now increment the field switch
	jmp	rpklp1		; And go check the next item
rpkchk: lda	kerchr		; Get chksum from packet
	sec			; Set carry for subtraction
	sbc	#sp		; Unchar it
	cmp	chksum		; Compare it to the one this Kermit generated
	beq	rpkret		; We were successful, tell the caller that
	lda	#$06		; Store the error code
	sta	errcod
	ldx	#erms15\	; Create pointer to error text
	ldy	#erms15^	;
	stx	lsterr
	sty	lsterr+1
	jsr	prstr		; Print the chksum error
	lda	kerchr		; Print chksum from packet
	jsr	prbyte
	lda	#sp		; Space things out a bit
	jsr	cout
	lda	chksum		; Now get what we calculated
	jsr	prbyte		;	and print that
rpkfls:	lda	#$00		; Zero the index for debug mode
	sta	pdtind		;		...
	lda	debug		; Is debug switch on?
	cmp	#off		; 
	beq	rpkfnd		;  Return doing no debug stuff
	lda	#$03		; Option 3 <we are in rpkfls>
	jsr	debg		; Output debug information
rpkfnd: lda	pdlen		; Get the packet data length
	clc			;	and add it into the
	adc	rtot		;	'total characters received' counter
	sta	rtot
	lda	rtot+1
	adc	#$00
	sta	rtot+1
	lda	#false		; Set up failure return
;	sta	ptype		; Set packet type false [D.D.]
	rts			;	and go back
rpkret:	lda	#$00		; Zero the index for debug mode
	sta	pdtind		;		...
	lda	debug		; Check debug switch
	cmp	#off		; Is it on?
	beq	rpkrnd		; No, return with no debug
	lda	#$04		; Yes, use option 4 <we received a packet>
	jsr	debg		; Print out the debug info
rpkrnd: lda	pdlen		; Get the packet data length
	clc			;	and add it into the
	adc	rtot		;	'total characters received' counter
	sta	rtot
	lda	rtot+1
	adc	#$00
	sta	rtot+1
	lda	#true		; Show a successful return
	rts			;	and return
rpkpe:  ldx	#erms16\	; Set up pointer to error text
	ldy	#erms16^	;
	stx	lsterr
	sty	lsterr+1
	jsr	prstr		; Print the error
	lda	#$07		; Load error code and store in errcod
	sta	errcod
	jmp	rpkfls		; Go give a false return

.SBTTL	DEBG - debugging output routines
;
;	When the debugging option is turned on, these routines periodically
;	display information about what data is being sent or received.
;
;		Input:  A-	Action type
;			Ptype-  Packet type sent or received
;			Pnum-	Packet number sent or received
;			Pdlen-  Packet data length
;
;		Output: Display info on current packet status
;
;		Registers destroyed:	A,X,Y
;

debg:	tax			; Hold the action code here
	sta	debinx		; Save it here
	lda	debug		; Get the debug switch
	cmp	#terse		; Is it terse
	bne	debgvr		; Nope, must be Verbose mode
	jmp	debgtr		; Yes, to terse debug output
debgvr:	lda	state		; Check the current state
	cmp	#$00		; If we just started this thing
	beq	debgrf		;	then we don't need debug output yet
	cmp	#'C		; If the transmission state is 'complete'
	beq	debgrf		;	we don't need debug output either
	lda	#kerrts\	; Get base address of the routine name and
	sta	kermbs		;	action table so that we can calculate
	lda	#kerrts^	;
	sta	kermbs+1	;
	lda	#kerrns		; Load the routine name size
	pha			; Push that
	txa			; Fetch the offset for the one we want
	pha			; And push that parameter
	jsr	genmad		; Go generate the message address
	jsr	prstr		; Now, go print the string
	lda	ptype		; Get the current packet type
	pha			; Save this accross the routine calls
	jsr	cout		; Write that out
	jsr	prcrlf		; Now write a crelf
	pla			; Get back the packet type
	sta	debchk		;	and start the checksum with that
	lda	debinx		; Get the debug action index
	bne	debg1		; If not 'sending', continue
	jsr	debprd		; Yes, go do some extra output
debg1:  cmp	#$04		; Have we just received a packet?
	bne	debgrt		; No, just return
	jsr	debprd		; Print the packet info
debgrt: lda	#true		; Load true return code into AC
	rts			;	and return
debgrf: lda	#false		; Set up failure return
	rts			;	and go back

;
;	Debprd - does special information output including packet number,
;	packet data length, the entire packet buffer, and the checksum
;	of the packet as calculted by this routine.
;

debprd: jsr	prcrlf		; Start by giving us a new line
	ldx	#debms1\	; Get the first info message address
	ldy	#debms1^	;		...
	jsr	prstr		;	and print it
	jsr	prcrlf		; New line
	ldx	#debms3\	; Get address of message text
	ldy	#debms3^	;		...
	jsr	prstr		; Print it
	inc	pdtind		; Pass the SOH
	ldx	pdtind		; Get the index
	lda	plnbuf,x	; Get the data length
	sec			; Uncharacter this value
	sbc	#$20		;		...
	jsr	prbyte		; Print the hex value
	jsr	prcrlf		; New line
	ldx	#debms2\	; Get address of message text
	ldy	#debms2^
	jsr	prstr		; Print it
	inc	pdtind		; Next character is packet number
	ldx	pdtind		;		...
	lda	plnbuf,x	; Load it
	sec			; Uncharacter this value
	sbc	#$20		;		...
	jsr	prbyte		; Print the hex value
	jsr	prcrlf		; New line
	inc	pdtind		; Bypass the packet type
	ldy	#$ff		; Start counter at -1
	sty	kwrk02		; Store it here
debprc:	inc	kwrk02		; Increment the counter
	ldy	kwrk02		; Get counter
	cpy	pdlen		; Are we done printing the packet data?
	bpl	debdon		; If so, go finish up
	inc	pdtind		; Point to next character
	ldx	pdtind		; Fetch the index
	lda	plnbuf,x	; Get next byte from packet
	jsr	prchr		; Go output special character
	lda	#space		; Now print 1 space
	jsr	cout		;		...
	jmp	debprc		; Go check next character
debdon:	jsr	prcrlf		; Next line
	ldx	#debms4\	; Get the address to the 'checksum' message
	ldy	#debms4^	;		...
	jsr	prstr		; Print that message
	inc	pdtind		; Get next byte, this is the checksum
	ldx	pdtind		;		...
	lda	plnbuf,x	;		...
	sec			; Uncharacter this value
	sbc	#$20		;		...
	jsr	prbyte		; Print the hex value of the checksum
	jsr	prcrlf		; Print two(2) crelfs
	jsr	prcrlf		;		...
	rts			;	and return

.SBTTL	Terse debug output

;
;	This routine does brief debug output. It prints only the contents
;	of the packet with no identifying text.
;

debgtr:	txa			; Look at Option
	cmp	#$00		; Sending?
	beq	debgsn		; Yes, output 'SENDING: '
	cmp	#$03		; Failed receive?
	beq	debgrc		; Yes, output 'RECEIVED: '
	cmp	#$04		; Receive?
	beq	debgrc		; Yes, output 'RECEIVED: '
	rts			; Neither, just return
debgsn:	ldx	#sstrng\	; Get ready to print the string
	ldy	#sstrng^	;		...
	jsr	prstr		; Do it!
	jsr	prcrlf		; Print a crelf
	jmp	debgdp		; Go dump the packet
debgrc:	ldx	#rstrng\	; Get ready to print the string
	ldy	#rstrng^	;		...
	jsr	prstr		; Do it!
	jsr	prcrlf		; Print a crelf
debgdp:	ldx	pdtind		; Get index
	cpx	pdtend		; Are we done?
	bpl	debgfn		; Yes, return
	lda	plnbuf,x	; Get the character
	jsr	prchr		; Print it
	lda	#space		; Print a space
	jsr	cout		;		...
	inc	pdtind		; Advance the index
	jmp	debgdp		; Do next character
debgfn:	jsr	prcrlf		; Print a crelf then...
	rts			;	Return

.SBTTL	Dos routines

;
;	These routines handle files and calls to the DOS
;

;
;	Open and Close files
;

openf:  sta	flsrw  		;save mode  w or r
	ldx	#'P
	lda	filmod
	and	#$fe		;if 0 or 1
	bne	opn1		;if >1 p
	ldx	#'S		;s for 0 or 1
opn1:	stx	flssp
opnmfs: ldy  	#0
opnmfn:	lda	fcb1,y 		;get char from file name
	beq  	opnfil  	;end at null
	cmp  	#$20		;or space
	beq  	opnfil
	sta  	primfn,y 	;save in filename
	iny
	bne	opnmfn 		;get more
opnfil: lda	#',  		;add comma
	sta	primfn,y
	lda	flssp  		;add s or p
	iny
	sta	primfn,y
	iny
	lda 	#',  		;add comma
	sta	primfn,y
	iny
	lda	flsrw		;get mode w or r
	sta	primfn,y
	iny
opnfl1: sty	len  		;len of file name
	openm	#15,#8,#15,fcmd,#2  ;open error channel
	openm	#8,#8,#8,primfn,len   ;open file
	jsr	rddsk  		;get disk status
	cmp	#00
	bne  	opfail 		;if nz error
	sta	eodind		;clear end of dat flag
	lda	flssp		; check file type
	cmp	#'P		;if p handle 1st 2 bytes
	bne	opnex		;if s skip this stuff
	lda	flsrw		;get read/write switch
	cmp	#'R
	bne	opwr		;if w
	jsr	fgetc		;if r
	jmp	fatal
	jsr	fgetc		;get 2 bytes
	jmp	fatal
	jmp	opnex
opwr:	lda	#$00		;write 2 bytes
	jsr	fputc
	jmp	fatal
	lda	#$20
	jsr	fputc
	jmp	fatal
opnex:  lda	#true
	rts
opfail: jmp	fatal
	nop
	nop
	nop
	nop
	nop
	rts

closef: lda #8			; Close disk file
	jsr close
	lda #15
	jsr  close  		;close error channel
	lda #true
	rts

;
;	Execute DOS command [D.D.]
;

dosst:	jsr	prcfm		;[EL] first get a confirm!
	jsr	clrchn		; Set default IO channels
	ldx	#dmes\
	ldy	#dmes^
	jsr	prstr		; Print "Dos>"
	jsr	gtlin		; Get a line
	sty	len		; Length of line
	lda	#cr
	jsr	chrout  	; Output cr
	lda	buff		; Get 1st byte
	cmp	#'Q
	beq	dquit		; If q quit
	cmp	#'$
	bne	dos2
	jsr	dirst		; If $ directory
	jmp	dosst
dos2:	jsr	doscmd  	; Else dos command
	jmp	dosst
dquit:  jmp	kermit
	nop
	nop
	nop

; Get directory

dirst:  nop
	nop
	nop
	openm	#8,#8,#0,buff,len 	; Open dir
	bcs	drclos		; Close if error
	ldx	#$08		; Open for input
	jsr	chkin		; Get 3 bytes
	jsr	chrin
	jsr	chrin
drst1:  jsr	chrin		; Get  byte
	jsr	readst		; If eof close
	bne	drclos
	jsr	chrin		; Get 2nd byte
	beq	drclos		;
	jsr	clrchn		; Set input to keybd
	jsr	getin		; Check for space
	cmp	#$20		;
	bne	drskp		; If not space skip
drloop: jsr	getin		; Loop until
	beq	drloop		; Any key pressed
drskp:  ldx	#$08		; Set input to disk
	jsr	chkin		;
	jsr	chrin		; Get a byte
	pha	
	jsr	chrin		; Get a byte
	tay
	pla
	tax
	tya
	jsr	prntax
	lda	#$20
	jsr	chrout		; Print  a space
drprnt: jsr	chrin		; Get byte
	beq	dreol		; If null end of line06
	jsr	chrout		; Print byte
	bne	drprnt		; Loop
dreol:  lda	#$0d		; Print cr
	jsr	chrout
	bne	drst1		; Go back for more
drclos: jsr	clrchn		; Close channels
	lda	#$08		; Close 8
	jsr	close
	rts

; Send dos command to disk

doscmd: lda	#15		; Close channel
	jsr	close
	openm	#15,#8,#15,buff,len
	lda	len		;if length of line
	bne	dosc1		;   =0
	jsr	rddsk		;   get disk status
dosc1:  rts

; Get line from keyboard

gtlin:  ldy	#0
gtln1:  jsr	chrin
	cmp	#cr		;end at cr
	beq	gtln2
	sta	buff,y  	;save in buff
	iny
	bne	gtln1
gtln2:  lda	#0
	sta	buff,Y
	rts

;
;	Fgetc - returns the next character from the file in the AC. It
;	handles all of the low level disk I/O. Whenever it successfully
;	gets a character, it skips on return. If it does not get a
;	character, it doesn't skip.
;

fgetc:	lda	addlf
	cmp	#on
	bne	fgetc1
	lda	#off
	sta	addlf
	lda	#lf
	jmp	fgtgn1
fgetc1: lda	eodind		; check eod flag [DD]
	bne	fgtef1		; set eof [DD]
	ldx	#8
	jsr	chkin
	jsr	getin  		;get a char
	pha			;save it
	jsr	readst 		;get status
	sta	eodind 		;save eof stat for next time
	cmp	#$00  		;if 0 then ok
	beq	fgtexi
	jsr	closef		;eof so close but return
fgtexi: pla			;get back character
fgtgn1:
	jmp	rskp  		;return skip
fgtef1: lda	#0
	rts			;return null
fgtcan: jmp fatal 		;return with error

; Put char in a to file
;
;	Fputc - takes a character passed to it in the AC and writes it
;	to the file being transferred in.
;

fputc:	pha 			;save it
	ldx	#8
	jsr	chkout
	pla  			;get it back
	jsr	chrout
	jsr	readst
	cmp	#00
	beq	fputex
	sta	errcod  		;if error
	ldx	#erms0a\	
	ldy	#erms0a^
	stx	lsterr
	sty	lsterr+1
	jsr	prstr   		;print message
	lda	errcod
	jsr	prbyte  		;and status
	jmp	fatal
fputex: lda	#00
	jmp	rskp	  		;skip return

; Check disk status

rddsk:	ldx	#15
	jsr	chkin
	ldy	#0
rdds1:	jsr	getin
	cmp	#cr
	beq	rdds2
	sta	dskers,y
	iny
	bne	rdds1
rdds2:	lda	#0
	sta	dskers,y
	lda 	dskers 		; Get 1st digit
	sec
	sbc	#$30 		; Convert to bcd
	sta	fmrcod
	asl	a 		;*2
	asl	a 		;*4
	asl 	a		;*8
	asl	a  		;*16
	sta	fmrcod
	beq	rddex		; If first digit is zero exit
	lda	dskers+1 	; Get 2n digit
	sec
	sbc	#$30		; Convert to binary
	clc
	adc	fmrcod
	sta	fmrcod
	beq	rddex		; If error=0 exit
	ldx	#dskers\
	ldy	#dskers^
	stx	lsterr
	sty	lsterr+1
	jsr	prstr
	lda	fmrcod
	ora	#$80		; Set higf hbit
rddex:	sta 	errcod
	rts

;
;	Bufill - takes characters from the file, does any neccesary quoting,
;	and then puts them in the packet data buffer. It returns the size
;	of the data in the AC. If the size is zero and it hit end-of-file,
;	it turns on eofinp.
;

bufill:	lda	#$00		; Zero
	sta	datind		;	the buffer index
bufil1: lda	addlf		; Get the 'add a lf' flag
	cmp	#on		; Is it on?
	bne	bufget		; No, continue with normal processing
	dec	addlf		; Zero the flag first
	lda	#lf		; Get a <lf>
	sta	kerchr
	bne	bufcv2		;[DD] and return that as the next character
bufget:	jsr	fgetc		; Get a character from the file
	 jmp	bffchk		; Go check for actual end-of-file
	sta	kerchr		; Got a character, save it
	lda	filmod		; [DD] Check if conversion necessary
	cmp	#1		;=1
	bne	bufcv1		; [DD]
	jsr	cva2p		; [DD] Convert PETASCI to ASCII
	jmp	bufcv2		; [DD]
bufcv1: cmp	#2		; [DD]=2
	bne	bufcv2		; [DD] No
	jsr	cvs2a		; [DD] Conv. Speedscript to ASCII
bufcv2:
bufceb: lda	ebqmod		; Check if 8-bit quoting is on
	cmp	#on
	beq	bufil2		; If it is, see if we have to use it
	jmp	bffqc		; Otherwise, check normal quoting only
bufil2: lda	kerchr		; Get the character
	and	#$80		; Mask everything off but H.O. bit
	beq	bffqc		; H.O. bit was not on, so continue
	lda	sebq		; H.O. bit was on, get 8-bit quote
	ldy	datind		; Set up the data index
	sta	(kerbf1),y	; Stuff the quote character in buffer
	iny			; Up the data index
	sty	datind		; And save it
	lda	kerchr		; Get the original character saved
	and	#$7f		; Shut H.O. bit, we don't need it
	sta	kerchr
bffqc:  lda	kerchr		; Fetch the character
	and	#$7f		; When checking for quoting, use only 7 bits
bffqc0: cmp	#sp		; Is the character less than a space?
	bpl	bffqc1		; If not, try next possibility
	ldx	filmod		; Get the file-type
	cpx	#3		;[D.D.] IF >= 3
	bcs	bffctl		; If it is not text, ignore <cr> problem
	cmp	#cr		; Do we have a <cr> here?
	bne	bffctl		; Nope, continue processing
	ldx	#on		; Set flag to add a <lf> next time through
	stx	addlf		;
	jmp	bffctl		; This has to be controlified
bffqc1: cmp	#del		; Is the character a del?
	bne	bffqc2		; If not, try something else
	jmp	bffctl		; Controlify it
bffqc2: cmp	squote		; Is it the quote character?
	bne	bffqc3		; If not, continue trying
	jmp	bffstq		; It was, go stuff a quote in buffer
bffqc3: lda	ebqmod		; Is 8-bit quoting turned on?
	cmp	#on		;
	bne	bffstf		; If not, skip this junk
	lda	kerchr		;	otherwise, check for 8-bit quote char.
	cmp	sebq		; Is it an 8-bit quote?
	bne	bffstf		; Nope, just stuff the character itself
	jmp	bffstq		; Go stuff a quote in the buffer
bffctl: lda	kerchr		; Get original character back
	eor	#$40		; Ctl(AC)
	sta	kerchr		; Save the character again
bffstq: lda	squote		; Get the quote character
	ldy	datind		;	and the index into the buffer
	sta	(kerbf1),y	; Store it in the next location
	iny			; Up the data index once
	sty	datind		; Save the index again
bffstf: inc	schr		; Increment the data character count
	bne	bffsdc
	inc	schr+1
bffsdc: lda	kerchr		; Get the saved character
	ldy	datind		;	and the data index
	sta	(kerbf1),y	; This is the actual char we must store
	iny			; Increment the index
	sty	datind		; And resave it
	tya			; Take this index, put it in AC
	clc			; Clear carry for addition
	adc	#$06		; Adjust it so we can see if it
	cmp	spsiz		;	is >= spsiz-6
	bpl	bffret		; If it is, go return
	jmp	bufil1		; Otherwise, go get more characters
bffret: lda	datind		; Get the index, that will be the size
	rts			; Return with the buffer size in AC
bffchk:	lda	#true		;AT EOD  turn on
	sta	eofinp		;	the eofinp flag
	lda	datind		; Get the data index
bffne:  rts			; Return

;
;	Bufemp - takes a full data buffer, handles all quoting transforms
;	and writes the reconstructed data out to the file using calls to
;	FPUTC.
;

bufemp: lda	#$00		; Zero
	sta	datind		;	the data index
bfetol: lda	datind		; Get the data index
	cmp	pdlen		; Is it >= the packet data length?
	bmi	bfemor		; No, there is more to come
	rts			; Yes, we emptied the buffer, return
bfemor: lda	#false		; Reset the H.O.-bit-on flag to false
	sta	chebo
	ldy	datind		; Get the current buffer index
	lda	(kerbf1),y	; Fetch the character in that position
	sta	kerchr		; Save it for the moment
	cmp	rebq		; Is it the 8-bit quote?
	bne	bfeqc		; No, go check for normal quoting
	lda	ebqmod		; Is 8-bit quoting on?
	cmp	#on
	bne	bfeout		; No quoting at all, place char in file
	lda	#true		; Set H.O.-bit-on flag to true
	sta	chebo
	inc	datind		; Increment the data index
	ldy	datind		; Fetch it into Y
	lda	(kerbf1),y	; Get the next character from buffer
	sta	kerchr		; Save it
bfeqc:  cmp	rquote		; Is it the normal quote character
	bne	bfeceb		; No, pass this stuff up
	inc	datind		; Increment the data index
	ldy	datind		;	and fetch it in the Y-reg
	lda	(kerbf1),y	; Get the next character from buffer
	sta	kerchr		; Save it
	and	#$7f		; Check only 7 bits for quote
	cmp	rquote		; Were we quoting a quote?
	beq	bfeceb		; Yes, nothing has to be done
	cmp	rebq		; Check for eight-bit quote char as well
	beq	bfeceb		; Skip the character adjustment
	lda	kerchr		; Fetch back the original character
	eor	#$40		; No, so controlify this again
	sta	kerchr		; Resave it
bfeceb: lda	chebo		; Is the H.O.-bit-on flag lit?
	cmp	#true
	bne	bfeout		; Just output the character to the file
	lda	kerchr		; Fetch the character
	ora	#$80		; Light up the H.O. bit
	sta	kerchr		; Resave it
bfeout: lda	filmod		; Check if this is a text file
	CMP	#3		;FILMOD <3 [D.D.]
	BCS	bfefpc		; If not, continue normal processing
	lda	kerchr		; Get a copy of the character
	and	#$7f		; Make sure we test L.O. 7-bits only
	cmp	#cr		; Do we have a <cr>?
	bne	bfeclf		; No, then check for <lf>
	lda	#on		; Yes, set the 'Delete <lf>' flag
	sta	dellf		;
	jmp	bfefpc		; And then continue
bfeclf: cmp	#lf		; Do we have a <lf>?
	bne	bfenlf		; Nope, We must go shut the Dellf flag.
	lda	dellf		; We have a <lf>, is the flag on?
	cmp	#on		;
	bne	bfefpc		; If not, continue normally
	lda	#off		; Flag is on, <lf> follows <cr>, ignore it
	sta	dellf		; Start by zeroing flag
	jmp	bfeou1		; Now go to end of loop
bfenlf: lda	#off		; Zero Dellf
	sta	dellf		;
bfefpc: lda	filmod		; [DD] Get file type 
	cmp	#1		; [DD] Check PETASCI
	bne	bfefp2		; [DD]
	jsr	cva2p		; [DD] Convert ASCII to PETASCI
	jmp	bfefp3		; [DD]
bfefp2: cmp	#2		; Check Speedscript [D.D.]
	bne	bfefp3		; [DD]
	jsr	cva2s		; [DD] Convert ASCII to Speedscript
bfefp3: lda	kerchr		; Get the character once more
	jsr	fputc		; Go write it to the file
	 jmp	bfeerr		; Check out the error
	inc	rchr		; Increment the 'data characters receive' count
	bne	bfeou1
	inc	rchr+1
bfeou1: inc	datind		; Up the buffer index once
	jmp	bfetol		; Return to the top of the loop
bfeerr: sta	errcod		; Store the erro code where it belongs
	and	#$7f		; Shut off H.O. bit
	lda	#false		; Indicate failure
	rts			;	and return

;
;	Getnfl - returns the next filename to be transferred. Currently
;	it always return Eof to indicate there are no other files to
;	process.
;

getnfl: lda	#eof		; No more files (return eof)
	rts

;
;	Getfil - gets the filename from the receive command if one was
;	parsed. Otherwise, it returns the name in the file header packet.
;

getfil: lda	usehdr		; Get the use-header switch
	cmp	#on		; Is it on
	bne	getfl1		; If not, keep what we have in the fcb
	ldy	#$00		; Initialize the y reg
	lda	pdlen		; Copy the packet data length
	sec			; Now subtract off the overhead
	sbc	#$03
	sta	kwrk02		;	into a work area
getfl0: lda	(kerbf1),y	; Get a character from the packet buffer
	sta	fcb1,y		; Stuff it in the fcb
	iny			; Up the index once
	cpy	pdlen		; Are we finished?
	bmi	getfl0		; Nope, go do next byte
	LDA   #0
	STA    FCB1,Y		;NUL AT END
getfl1: rts
;

.SBTTL	Utility routines
;
;	The following routines are short low-level routines which help
;	shorten the code and make it more readable
;
;
;	Incn - increment the packet sequence number expected by this
;	Kermit. Then take that number Mod $3f.
;

incn:	pha			; Save AC
	lda	n		; Get the packet number
	clc			; Clear the carry flag for the add
	adc	#$01		; Up the number by one
	and	#$3f		; Do this Mod $3f!
	sta	n		; Stuff the number where it belongs
	clc			; Clear carry again
	lda	tpak		; Increment lo byte
	adc	#$01		;	total packet count
	sta	tpak		;		...
	lda	tpak+1		; Do H.O. byte
	adc	#$00		;		...
	sta	tpak+1		;		...
	pla			; Restore the AC
	rts			;	and return

;
;	Prcerp - Process error packet. Moves the Remote Kermit error
;	text into a save area, notes that there was an error received
;	from the remote Kermit in Errcod (set H.O. bit), and displays
;	the text on the screen.
;

prcerp:	lda	ptype		; Reload the packet type
	cmp	#'E		; Is it an error packet?
	beq	prcer1		; Yes, continue processing
	rts			; No, return
prcer1:	lda	#pdbuf\		; Set up from-address
	sta	kerfrm		;		...
	lda	#pdbuf^		;		...
	sta	kerfrm+1	;		...
	lda	#errrkm\	; Set up the to-address
	sta	kerto		;		...
	lda	#errrkm^	;		...
	sta	kerto+1		;		...
	ldy	pdlen		; Get packet data length
	sty	kwrk01		; Store for the copy routine
	lda	#$00		; Start by storing a null at the end
	sta	(kerto),y	;		...
	jsr	kercpy		; Copy the error text
	lda	errcod		; Set the bit in the error code
	ora	#eprflg		;	saying that the remote Kermit sent us
	sta	errcod		;	an error packet.
	ldx	#errrkm\	; Finally, display the error packet
	ldy	#errrkm^	;		...
	jsr	prstr		; Print string
	jsr	prcrlf		; Make it look neat, add a crlf
	rts			; Return to caller

;
;	Gobble - snarfs a line of characters from the port up to
;	the receive end-of-line character. If it sees a keyboard
;	interupt, it punts and does not skip.
;

gobble:	lda	#$00
	sta	pdtend		; Zero the index pointing to end of line buffer
	sta	ndx		; Make sure no unwarranted keyboard intrpt
gobb:	jsr	getc		; Get a character
	 jmp	gobb2		; Got a keyboard interupt
	cmp	#soh		; Is it a start-of-header?
	bne	gobb		; No, flush until first SOH
	jmp	gobbst		; Ok, now we can start
gobb0:	jsr	getc		; Get a character
	 jmp	gobb2		; Got a keyboard interupt
	cmp	#soh		; If this not an SOH
	bne	gobb1		;	continue here
	tax			; Hold the character here
	lda	#$00		; Rezero the index pointing to end of buf
	sta	pdtend		;		...
	txa			; Get the SOH back
	jmp	gobbdb		; Go stuff the character in the buffer
gobb1:	cmp	reol		; Is it the end-of-line character?
	beq	gobb3		; Yes, finish up
gobbst:	ldx	pdtend		; Get the index we need
gobbdb:	sta	plnbuf,x	; Stuff the character at the buffer
	inc	pdtend		; Increment the index once
	jmp	gobb0		; Loop for another character
gobb2:	rts			; Just return, no skip
gobb3:	ldx	pdtend		; Get end pointer again
	sta	plnbuf,x	; Store the End-of-line before we leave
	lda	#$00		; Zero the index, leave eob ptr where it is
	sta	pdtind		;		...
	jmp	rskp		; Return with a skip!

;
;	Getplc - gets a character from the port line buffer and
;	returns it. If the buffer is empty, it returns without
;	skipping.
;

getplc: ldx	pdtind		; Get the current index
	cpx	pdtend		; Less than the end buffer pointer?
	bmi	getpl1		; If so, go return the next character
	rts			; Return without a skip
getpl1: lda	plnbuf,x	; Get the next character from the buffer
	inc	pdtind		; Up the index once
	jmp	rskp		; Return with a skip!

;
;
;	Putplc - puts a character to the port line buffer.
;

putplc: ldx	pdtind		; Get the current index
	inx			; Check if we are at end of buffer
	bne	putpl1		; No, continue
	rts			; Return without a skip
putpl1: dex			; Set index back to what it was
	sta	plnbuf,x	; Get the next character from the buffer
	inc	pdtind		; Up the index once
	rts			; Return

;
;	Getc - skip returns with a character from the port or does
;	a normal return if a key from the keyboard is received first.
;	If it skips, the character from the port is returned in the
;	AC.
;

getc:	jsr	getkey		; No character from keyboard?
	cmp	#false
	beq	getc1		; If not try port
	and	#$7f		; Shut H.O. bit
	cmp	#'Q		; Was it an 'abort' interupt?
	bne	getc0		; Nope, continue
	lda	#$08		; Error code for 'file trans abort'
	sta	errcod		; Stuff it here
	ldx	kerosp		; Get the old stack pointer back
	txs			; Restore it
	jmp	kermit		; Warmstart kermit

getc0:  lda	#$00		; And reset the strobe
	sta	ndx		;
	rts			; Keyboard interupt, return
getc1:  jsr	telcp		; Check the port
	cmp	#false		; If there was no character
	beq	getc		;	go back to the top of the loop
	nop
	nop
	nop
	jmp	rskp		;	and return skip!

;
;	Prson - parses an 'on' or an 'off' keyword and passes
;	the result back to the calling routine in the x-index
;	register. If there is an error, it pops the return
;	address off the stack and transfers control to kermt2
;	to issue the error message.
;

prson:  lda	#oncmd\		; command table address
	sta	cminf1		;
	lda	#oncmd^		;
	sta	cminf1+1	;
	lda	#shon\		; Set up default string for parse
	sta	cmdptr		;		...
	lda	#shon^		;		...
	sta	cmdptr+1	;		...
	ldy	#cmfdff		; Show there is a default
	lda	#cmkey		; Code for keyword
	jsr	comnd		; Go do it
	 rts			; The command was not recognized
	 nop
	 nop
	jmp	rskp		; Good, skip return

;
;	prcfm - parses for a confirm, then transfers control directly
;	to the top of the main loop
;

prcfm:  lda	#cmcfm		; Load token for confirm
	jsr	comnd		; Parse a confirm
	 jmp	kermt3		; No confirm, give an error
	lda	#cr		; Print a crlf
	jsr	cout
	rts			; Return

;
;	Pron - checks the value in the AC and prints either 'ON' or
;	'OFF'. (on=1, off=0).
;

pron:	cmp	#on		; Should we print 'on'?
	bne	pron1		; No, go print 'off'
	ldx	#shon\		; Point to the 'on' string
	ldy	#shon^
pron0:  jsr	prstr		; Print it
	jsr	prcrlf		; Add a crelf at the end
	rts			; And return
pron1:  ldx	#shoff\		; Point to the 'off' string
	ldy	#shoff^
	jmp	pron0		; Go print it

;
;	Nonftl - handles non-fatal DOS errors. When Kermit does its
;	initialization it points the error vector and the basic
;	warmstart vector here.
;

nonftl: lda	fmrcod		; Get the DOS return code
	sta	errcod		; Save that here
	ldx	kerosp		; Get the old stack pointer back
	txs			; Restore it
	jmp	kermit		; Warmstart kermit

;
;	Fatal - closes and deletes a file on which a bad error
;	has occured (most likely a 'disk full' error). It then
;	restores the old stack pointer and warmstarts Kermit.
;

fatal:  ;	lda	fmrcod		; Get the DOS return code
;	ora	#$80		; Set H.O. bit to indicate DOS error
;	sta	errcod		; Store the error code
	lda	#$01		; Make sure 'closef' knows there was an error
	jsr	closef		; Close the file
;	jsr	dosdel		; Now, delete the useless file
	ldx	kerosp		; Get the old stack pointer
	txs			; Restore it
	jmp	kermit		; Warmstart kermit

;
;	Clrfcb - clears the area FCB1 so the filename placed there
;	will not be corrupted.
;

clrfcb:	ldx	#$1f		; Load max filename length
	lda	#space		; We will be filling with spaces
clrfc1:	sta	fcb1,x		; Stuff the space
	dex			; Decrement our pointer
	bpl	clrfc1		; Not done, go back
	rts			; Return

;
;	Kercpy - copies the string pointed to by Kerfrm to the
;	block of memory pointed to by Kerto for Kwrk01 characters.
;

kercpy:	ldy	kwrk01		; Get the length of the string
kerclp:	dey			; One character less
	bmi	kercrt		; If this went negative, we're done
	lda	(kerfrm),y	; Get the next character
	sta	(kerto),y	; And put it where it belongs
	jmp	kerclp		; Go back for next char
kercrt:	rts			; Job is done, return

;
;	Kerflm - fills the buffer pointed to by Kerto with the
;	character in kwrk02 for Kwrk01 characters.
;

kerflm:	ldy	kwrk01		; Get the length of the string
kerflp:	dey			; One character less
	bmi	kerflr		; If this went negative, we're done
	lda	kwrk02		; Get the fill character
	sta	(kerto),y	; And put it in the next position
	jmp	kerflp		; Go back to do next char
kerflr:	rts			; Job is done, return

;
;	Prchr - takes a character from the AC and prints it. It
;	echos control characters as '^<chr>' and escape as '$'.
;

prchr:  and	#$7f		; Make sure it's in range
	cmp	#$20		; Less than escape??
	bpl	prchr1		; If not, continue
	pha			; Hold the character
	lda	#'^		; Load the up-arrow for cntrl characters
	jsr	cout		; Print the character
	pla			; Get the character back
	clc			; Clear carry for add
	adc	#$40		; Put this in the alphabetic range
prchr1: jsr	cout		;	and print it
	rts			; Done, go back

;
;	Genmad - takes a message base, offset and size and calculates
;	the address of the message leaving it in the X and Y registers
;	ready for a call to PRSTR. The size and offset are taken from
;	the stack and the base address is found in kermbs.
;

genmad: pla			; Get return address
	sta	kerrta		;	and save it till later
	pla			;
	sta	kerrta+1	;
	pla			; Get message offset
	tax			; Hold it here for a while
	pla			; Get the message length
	tay			;	and put it here
	lda	#$00		; H.O. byte of message offset for mul16
	pha			;
	txa			; L.O. byte of message offset
	pha			;
	lda	#$00		; H.O. byte of message size for mul16
	pha			;
	tya			; L.O. byte of message size
	pha			;
	jsr	mul16		; Calculate the actual offset in table
	pla			; Get L.O. byte of result
	clc			; Clear the carry for addition
	adc	kermbs		; Add the L.O. byte of the base address
	tax			; Put it in X for the return
	pla			; Get the H.O. byte
	adc	kermbs+1	; Add the H.O. byte of the base address w/carry
	tay			; Stuff it here for the return
	lda	kerrta+1	; Replace the return address on the stack
	pha			;		...
	lda	kerrta		;		...
	pha			;		...
	rts			; Return


;	Some screen routines

home:	lda	#$93		; Cursor home and clear screen
	jsr	cout		;
	rts			;

home1:  lda	#$13		; Cursor home
	jsr	cout		;
	rts			;

scrl3:  ldx	cv		;
	ldy	#0		;
	jsr	clrln1		; Clear curent line
	rts			;

upline: lda	#$91		; Curs up
	jsr 	cout		;
	rts			;
lfeed:	lda	#$11  		; Curs down
	jsr	cout		;
	rts			;

; Do a carriage return

crout:  nop			;
	nop			;
	nop			;
	nop			;
	ldx	cv		;
	ldy	#$00		; Set to column 0
	clc			;
	jsr	plot		;
	rts			;
crout1: lda	#cr		;
	jsr	cout		;
	rts			;
advanc: lda	#$1d  		; Curs right
	jsr	cout		;
	rts			;
bsp:	lda	#$9d  		; Curs left
	jsr	cout		;
	rts			;

; Clear to end of line

clreol: ldx	cv		;
	ldy	ch		;get row,col
clrln1: lda	#sp		;
	sta	(basl),y	;store a space
	iny			;
	cpy	#40		;
	beq	clrlnr		;end if =40
	cpy	#80		;
	bne	clrln1		;end if =80
clrlnr:	rts			;

; Clear to end of screen

clreop: jsr	clreol  	;clear line
	ldx	cv		;get cursor vertical (row)
	stx	hcv		;save it
	ldy	ch		;get cursor horiz. (col)
	sty	hch		;save it
cleop1:	inx			;increment line
	cpx	#25		;stop when =25
	beq	cleopx		;
	ldy	#0		;column 0
	clc			;
	jsr	plot		;set to next line
	jsr	clreol		;clear that line
	ldx	cv		;get line no.
	bne	cleop1		;go back
cleopx:	ldx	hcv		;restore row
	ldy	hch		; and col
	clc			;
	jsr	plot		;position back to hcv,hch
	rts			;

;	Print (X) spaces

prbl2:  stx	savex		; Save X
	lda	#sp		;
	jsr	cout		;
	ldx	savex		;
	dex			;
	bne	prbl2		;
	rts			;

; Print a reg as 2 hex nibbles

prbyte: 			; output byte in hex
by2hx:  pha			;save byte
	lsr	a		;
	lsr	a		;
	lsr	a		;
	lsr	a		;
	jsr	ny2hx	     	;high nyble
	tax		     	; to x
	pla		     	;get back
	and	#$0f	     	; low nyble
	jsr	ny2hx		;
	pha			;
	txa			;
	jsr	cout		;
	pla			;
	jmp	cout		;

; Translate nyble to hex

ny2hx:	clc			;
	adc	#$f6		;
	bcc	ny2h2		;
	adc	#$06		;
ny2h2:  adc	#$3a		;
	rts			;

; Print hex of A,X

prntax: stx	savex		;
	jsr	prbyte		;
	lda	savex		;
	jsr	prbyte		;
	rts			;

;	Print byte to screen

cout:	pha  			;save a-reg
	txa			;
	pha  			;save x-reg
	ldx	#3		;
	jsr	chkout		;
	pla			;
	tax			;restore x
	pla			;restore a
	jsr	chrout		;
	lda	#0		;
	sta	qtsw   		;[EL] clear quote flag
	rts			;

;	Initiate sounds - will be terminated next cursor blink

bell:	pha			;[EL] save the AC
	lda	#$50		;[EL] select high frequency
beep:	sta	freqhi		;[EL]
	lda	#$0f		;[EL] select fast attack, slow decay
	sta	attdec		;[EL]
	lda	#$12		;[EL] select sustain ...
	sta	susrel		;[EL]
	lda	#6		;[EL] select not-too-loud volume
	sta	vol		;[EL]
	lda	#$21		;[EL] select sawtooth wave
	sta	wave		;[EL]
	lda	lpmax		;[EL] reset curs timer for consistent beep time
	sta	lpcnt		;[EL]
	pla			;[EL] restore the AC
	rts			;[EL]

;	Get byte from rs232 port

getrs:	ldx	#2		;
	jsr	chkin		;
	jsr	getin		;
	rts			;

;	Send byte to RS232

putrs:	pha  			;save a-reg
	txa			;
 	pha  			;save x-reg
	ldx	#2		;
	jsr	chkout		;
	pla			;
	tax	 		;restore x
	pla	 		;restore a
	jsr	chrout		;
	rts			;

;	Read keyboard until a byte appears

rdkey:	jsr	getkey		;
	cmp	#00		;
	beq	rdkey		;
	rts			;

;	Get byte from keyboard return 0 if none

getkey: ldx #1			;
	jsr	chkin		;
	jsr	getin		;
	beq	cursor		;[EL] if none , blink cursor
	rts

;	Cursor handling routines

cursor:	jsr	docurs		;[EL]
	rts			;[EL]

docurs:	dec	lpcnt		;[EL] Decrement timer
	beq	blink		;[EL] Expired?
	rts			;[EL] No
blink:	pha			;[EL] Save the AC
	tya			;[EL] 	and Y
	pha			;[EL]		...
b40:	ldy	ch		;[EL] Fetch column displacement of cursor
	lda	(basl),y	;[EL] Fetch screen byte under cursor
	eor	#$80		;[EL] Reverse it's current state
	sta	(basl),y	;[EL] Store back in screen
	clc			;[EL] Compute corresponding color ram address
	lda	basl+1		;[EL] Because c64 "user" is unreliable
	adc	#colram-vidmat4&$ff00^
	sta	saddr+1		;[EL]
	lda	basl		;[EL]
	sta	saddr		;[EL]
	lda	fgbg4		;[EL] get color code for fgnd
	lsr	a		;[EL]
	lsr	a		;[EL]
	lsr	a		;[EL]
	lsr	a		;[EL]
	sta	(saddr),y	;[EL] into color ram

bcom:	lda	lpmax		;[EL] reset timer
	sta	lpcnt		;[EL]
	lda	#0		;[EL] reset sound from beep routine
	sta	wave		;[EL]
	pla			;[EL] restore Y
	tay			;[EL]		...
	pla			;[EL] and the AC
	rts			;[EL]

;	Restore character under cursor to normal

nblink:	pha			; Save the AC
	tya			; and Y
	pha			;
	ldy	ch		;[EL] fetch column displacement of cursor
	lda	(basl),y	;[EL] fetch screen byte under cursor
	and	#$7f		;[EL] ensure non reversed character
	sta	(basl),y	;[EL] store back in screen
	pla			; Restore Y 
	tay			;
	pla			; And the AC
	rts			;[EL]

;	Convert ASCII to PETASCI and viceversa

cva2p:  lda	kerchr
	cmp	#$61		;> lowercase a
	bcc	cva2p1  	;no
	cmp	#$7b		;<lc. z
	bcs	cva2p1  	;no
	and	#$5f		;
	sta	kerchr
	rts
cva2p1: cmp	#$41		; in range a-z
	bcc	cva2p2  	; no
	cmp	#$5b
	bcs	cva2p2  	; no
	ora	#$20
cva2p2: and	#$7f
	sta	kerchr
	rts

; Convert ASCII to PETASCI

cas2pt: cmp	#$61
	bcc	cas1 		; If <a skip
	cmp	#$7b 		; If >z skip
	bcs	cas1
	and	#$5f 		; Conv to u.c.
	rts
cas1:	pha 			; save byte
	lda	$D018
	and	#2 		; lower case enabled?
	beq	cas3 		; if=0 uc only
	pla	 		; retrieve byte
	cmp	#$41 		; if <a
	bcc	cas2 		; skip
	cmp	#$5b 		; if >z
	bcs	cas2 		; skip
	ora	#$20 		; conv to 61-7b
cas2:	pha
cas3:	pla
	and	#$7f 		;zero high bit
	rts

;   Convert ASCII to Speedscript (word processor)

cva2s:  lda	kerchr
	and	#$7f
	cmp	#cr
	bne	cva2s1  	; Check cr
	lda	#$1f
cva2s1: cmp	#$61
	bcc	cva2s2
	cmp	#$7b
	bcs	cva2s2
	and	#$1f		; Convert lower case
cva2s2: cmp	#$5b
	bcc	cva2s3
	cmp	#$5f
	bcs	cva2s3
	and	#$1f
cva2s3: sta	kerchr
	rts

;  Convert Seedscript (word processor) to ASCII

cvs2a:  lda	kerchr
	and	#$7f
cvs2a1: cmp	#$1b
	bcs	cvs2a2  	; If <$1b
	ora	#$60		; Convert to lc
cvs2a2: cmp	#$1f
	bcs	cvs2a3
	ora	#$40
cvs2a3: bne	cvs2a4 		; If =$1f
	lda	#cr		;cr
cvs2a4:	sta	kerchr
	rts

.SBTTL	Spar and Rpar routines

;
;	Spar - This routine loads the data buffer with the init parameters
;	requested for this Kermit.
;
;		Input:  NONE
;
;		Output: @Kerbf1 - Operational parameters
;
;		Registers destroyed:	A,Y
;

spar:	ldy	#$00		; Clear Y
	sty	datind		; Clear datind
	lda	rpsiz		; Fetch receive packet size
	clc			; Clear the carry flag
	adc	#$20		; Characterize it
	sta	(kerbf1),y	; Stuff it in the packet buffer
	iny			; Increment the buffer index
	lda	rtime		; Get the timeout interval
	clc
	adc	#$20		; Make that a printable character
	sta	(kerbf1),y	;	and stuff it in the buffer
	iny			; Advance the index
	lda	rpad		; Get the amount of padding required
	clc
	adc	#$20		; Make that printable
	sta	(kerbf1),y	; Put it in the buffer
	iny			; Advance index
	lda	rpadch		; Get the padding character expected
	eor	#$40		; Controlify it
	sta	(kerbf1),y	; And stuff it
	iny			; Up the packet buffer index
	lda	reol		; Get the end-of-line expected
	clc
	adc	#$20		; Characterize it
	sta	(kerbf1),y	; Place that next in the buffer
	iny			; Advance the index
	lda	rquote		; Get the quote character expected
	sta	(kerbf1),y	; Store it as-is last in the buffer
	iny			; Advance index
	lda	#'Y		;  Send 'Y' - I will support 8-bit quoting
	sta	(kerbf1),y	; Stuff it into the data area
	rts

;
;
;	Rpar - This routine sets operational parameters for the other kermit
;	from the init packet data buffer.
;
;		Input:  @Kerbf1 - Operational parameters
;
;		Output: Operational parameters set
;
;		Registers destroyed:	A,Y
;

rpar:	ldy	#$00		; Start the data index at 0!
	lda	(kerbf1),y	; Start grabbing data from packet buffer
	sec			; Uncharacterize it
	sbc	#$20
	sta	spsiz		; That must be the packet size of other Kermit
	iny			; Increment the buffer index
	lda	(kerbf1),y	; Get the next item
	sec
	sbc	#$20		; Uncharacterize that
	sta	stime		; Other Kermit's timeout interval
	iny			; Up the index once again
	lda	(kerbf1),y	; Get next char
	sec
	sbc	#$20		; Restore to original value
	sta	spad		; This is the amount of padding he wants
	iny			; Advnace index
	lda	(kerbf1),y	; Next item
	eor	#$40		; Uncontrolify this one
	sta	spadch		; That is padding character for other Kermit
	iny			; Advance index
	lda	(kerbf1),y	; Get next item of data
	cmp	#$00		; If it is equal to zero
	beq	rpar2		; Use <cr> as a default
	jmp	rpar3
rpar2:  lda	#cr		; Get value of <cr>
	sta	seol		; That will be the eol character
	jmp	rpar4		; Continue
rpar3:  sec
	sbc	#$20		; unchar the character
	sta	seol		; That is the eol character other Kermit wants
rpar4:  iny			; Advance the buffer index
	lda	(kerbf1),y	; Get quoting character
	cmp	#$00		; If that is zero
	beq	rpar5		; Use # sign as the qoute character
	jmp	rpar6		; Otherwise, give him what he wants
rpar5:  lda	#'#		; Load # sign
rpar6:  sta	squote		; Make that the other Kermit's quote character
	iny			; Advance the index
	lda	pdlen		; Check the data length to see
	cmp	#$09		;	if the 8-bit quote is there
	bmi	rparrt		; If not, return
	lda	(kerbf1),y	; Fetch the 8-bit quote
	cmp	#'N		; Is it 'N'
	beq	rpar8		; Yes, leave.(he doesn't support 8-bit)
	cmp	#'Y		; Does he support 8-bit quoting?
	beq	rpar8		; If so, leave. (we don't need it.)
	cmp	#'!		; Now, it should be a real character
	bmi	rparrt		;	Check if it is in range.
	cmp	#'?		;	If so, we set the 8-bit quote char
	bmi	rpar7		;	and set 8-bit quoting on.
	cmp	#$60		;	If not, just leave.
	bmi	rparrt		;		...
	cmp	#del		;		...
	bpl	rparrt		;		...
rpar7:	sta	sebq		; Stuff the character here
	lda	#on		; Set 8-bit quoting on
	sta	ebqmod		;		...
	rts			; Return
rpar8:	sta	sebq		; Make sure this parm is stored
	lda	#off		;	AND that 8-bit quoting is off.
	sta	ebqmod		;		...
rparrt:	rts			; Return

;
;
;	Nakit - sends a standard NAK packet out to the other Kermit.
;
;		Input:  NONE
;
;		Output: NONE
;

nakit:  lda	#$00		; Zero the packet data length
	sta	pdlen
	lda	#'N		; Set up a nak packet type
	sta	ptype
	jsr	spak		; Now, send it
	rts			; Return


.SBTTL	Message text

versio: .asciz	/c64 kERMIT-65 - vER 1.0, 40 cOLUMN mODE/

.SBTTL	Command tables and help text

kercmd: .byte	$0d		; Table length [DD] [EL]

;	.byte	$0e		; Table length with LOG command installed

	.byte	$03		; 
	.asciz	/BYE/		; 
	.byte	$1E,$1E		; 

	.byte	$07		; KEYWORD LENGTH
	.asciz  /CONNECT/	; KEYWORD TERMINATED WITH A NULL
	.byte	$00,$00		; TWO BYTES OF DATA

	.byte	$03		;[D.D.]
	.asciz  /DOS/
	.byte	$27,$27

	.byte	$04
	.asciz  /EXIT/
	.byte	$03,$03

	.byte	$06		; 
	.asciz	/FINISH/	; 
	.byte	$21,$21		; 

	.byte	$03		; 
	.asciz	/GET/		; 
	.byte	$24,$24		; 

	.byte	$04
	.asciz  /HELP/
	.byte	$06,$06

;	.byte	$03		; NOT IMPLEMENTED YET
;	.asciz  /LOG/
;	.byte	$09,$09

	.byte	$04
	.asciz  /QUIT/
	.byte	$0C,$0C

	.byte	$07
	.asciz  /RECEIVE/
	.byte	$0F,$0F

	.byte	$04
	.asciz  /SEND/
	.byte	$12,$12

	.byte	$03
	.asciz  /SET/
	.byte	$15,$15

	.byte	$04
	.asciz  /SHOW/
	.byte	$18,$18

	.byte	$06
	.asciz  /STATUS/
	.byte	$1B,$1B

setcmd: .byte	$0d		;[DD] [EL]
;	.byte	$0e		; Table length with DEFAULT-DISK option in

	.byte	$09
	.asciz  /DEBUGGING/
	.byte	$18,$18

;	.byte	$0C			; 
;	.asciz	/DEFAULT-DISK/		; 
;	.byte	$27,$27			; 

	.byte	$11
	.asciz  /EIGHT-BIT-QUOTING/
	.byte	$15,$15

	.byte	$06
	.asciz  /ESCAPE/
	.byte	$00,$00

	.byte	$0E
	.asciz  /FILE-BYTE-SIZE/
	.byte	$1E,$1E

	.byte	$09
	.asciz  /FILE-TYPE/
	.byte	$1B,$1B

	.byte	$0C
	.asciz  /FILE-WARNING/
	.byte	$12,$12

	.byte	$03			; 
	.asciz  /IBM/			; 
	.byte	$03,$03			; 

	.byte	$0A
	.asciz  /LOCAL-ECHO/
	.byte	$06,$06

	.byte	$06			; 
	.asciz	/PARITY/		; 
	.byte	$24,$24			; 

	.byte	$07
	.asciz  /RECEIVE/
	.byte	$09,$09

	.byte	$0F			;[DD]
	.asciz  /RS232-REGISTERS/	;[DD]
	.byte	$21,$21			;[DD]

	.byte	$04
	.asciz  /SEND/
	.byte	$0C,$0C

	.byte	$0E
	.asciz  /VT52-EMULATION/
	.byte	$0F,$0F

shocmd: .byte	$0e		;[DD]
;	.byte	$0f		; Table length with DEFAULT-DISK opt included

	.byte	$03
shodef:	.asciz  /ALL/
	.byte	$00,$00

	.byte	$09
	.asciz  /DEBUGGING/
	.byte	$51,$51

;	.byte	$0C
;	.asciz	/DEFAULT-DISK/
;	.byte	$90,$90

	.byte	$11
	.asciz  /EIGHT-BIT-QUOTING/
	.byte	$48,$48

	.byte	$06
	.asciz  /ESCAPE/
	.byte	$09,$09

	.byte	$0E
	.asciz  /FILE-BYTE-SIZE/
	.byte	$63,$63

	.byte	$09
	.asciz  /FILE-TYPE/
	.byte	$5A,$5A

	.byte	$0C
	.asciz  /FILE-WARNING/
	.byte	$3F,$3F

	.byte	$03		; 
	.asciz  /IBM/
	.byte	$12,$12

	.byte	$0A
	.asciz  /LOCAL-ECHO/
	.byte	$1B,$1B

	.byte	$06
	.asciz	/PARITY/
	.byte	$75,$75

	.byte	$07
	.asciz  /RECEIVE/
	.byte	$24,$24

	.byte	$0F			;[DD]
	.asciz  /RS232-REGISTERS/	;[DD]
	.byte	$6C,$6C			;[DD]

	.byte	$04
	.asciz  /SEND/
	.byte	$2D,$2D

	.byte	$0E
	.asciz  /VT52-EMULATION/
	.byte	$36,$36

STSCMD: .byte	$07

	.byte	$14
	.asciz  /EIGHT-BIT-QUOTE-CHAR/
	.byte	$06,$06

	.byte	$0B
	.asciz  /END-OF-LINE/
	.byte	$09,$09

	.byte	$0D
	.asciz  /PACKET-LENGTH/
	.byte	$0C,$0C

	.byte	$08
	.asciz  /PAD-CHAR/
	.byte	$00,$00

	.byte	$07
	.asciz  /PADDING/
	.byte	$03,$03

	.byte	$0A
	.asciz  /QUOTE-CHAR/
	.byte	$0F,$0F

	.byte	$07
	.asciz  /TIMEOUT/
	.byte	$12,$12


FTCMD:  .byte	$04

	.byte	$05
ftcdef:	.asciz  /ASCII/
	.byte	$00,$00

	.byte	$06
	.asciz  /BINARY/
	.byte	$03,$03

	.byte	$07
	.asciz  /PETASCI/
	.byte	$01,$01

	.byte	$06
	.asciz  /SCRIPT/
	.byte	$02,$02

parkey:	.byte	$05		; LENGTH OF THIS TABLE IS 5

	.byte	$04		;
	.asciz	/EVEN/		;
	.byte	$04,$04		;

	.byte	$04		;
	.asciz	/MARK/		;
	.byte	$02,$02		;

	.byte	$04		;
	.asciz	/NONE/		;
	.byte	$00,$00		;

	.byte	$03		;
	.asciz	/ODD/		;
	.byte	$03,$03		;

	.byte	$05		;
	.asciz	/SPACE/		;
	.byte	$01,$01		;

DEBKEY:	.byte	$03		; LENGTH OF THIS TABLE IS 3

	.byte	$03		;
	.asciz	/OFF/		;
	.byte	$00,$00		;

	.byte	$05		;
	.asciz	/TERSE/		;
	.byte	$01,$01		;

	.byte	$07		;
	.asciz	/VERBOSE/	;
	.byte	$02,$02		;

FBSKEY: .byte	$02

	.byte	$09
	.asciz  /EIGHT-BIT/
	.byte	$00,$00

	.byte	$09
	.asciz  /SEVEN-BIT/
	.byte	$01,$01

ONCMD:  .byte	$02

	.byte	$02
	.asciz  /ON/
	.byte	$01,$01

	.byte	$03
	.asciz  /OFF/
	.byte	$00,$00

YESCMD: .byte	$02

	.byte	$02
	.asciz  /NO/
	.byte	$00,$00

	.byte	$03
	.asciz  /YES/
	.byte	$01,$01

;DDSKEY:	.byte	$01

;	.byte	$05
;	.asciz	/DRIVE/
;	.byte	$00,$00

kerehr:	.byte	cmcfm		; tell them they can also confirm
	.byte	nul		; end help command string

kerhlp: .byte	cr
	.ascii	/kermit commands for this version are:/
	.byte	cr
	.byte	cr
	.ascii	/bye       shut  down  and  log  out  a/    ; new command
	.byte	cr					    ;
	.ascii	/          remote  kermit server,  then/    ;
	.byte	cr					    ;
	.ascii	/          exit./			    ;
	.byte	cr
	.byte	cr
	.ascii  /dos       send dos command to disk/ ;[D.D.]
	.byte	cr
	.byte	cr
	.ascii	/exit      exit  from  kermit  back  to/
	.byte	cr
	.ascii	/          the  host operating  system./
	.byte	cr
	.byte	cr
	.ascii	/finish    shut   down  remote   kermit/  ; new command
	.byte	cr					  ;
	.ascii	/          server  but  do not  log out/  ;
	.byte	cr					  ;
	.ascii	/          remote job. do not exit from/  ;
	.byte	cr					    ;
	.ascii	/          local kermit./		    ;
	.byte	cr
	.byte	cr
	.ascii	/get       fetch  a file from a  remote/  ; new command
	.byte	cr					    ;
	.ascii	/          server kermit.  the filename/  ;
	.byte	cr					    ;
	.ascii	/          is  validated by  the remote/  ;
	.byte	cr					    ;
	.ascii	/          server./			    ;
	.byte	cr					    ;
	.byte	cr					    ;
	.ascii	/help      print instructions on/
	.byte	cr
	.ascii	/          various  commands  available/
	.byte	cr
	.ascii	/          in kermit./
	.byte	cr
	.byte	cr
	.ascii	/quit      same as exit./
	.byte	cr
	.byte	cr
	.ascii	/receive   receive a file or file group/
	.byte	cr
	.ascii	/          from the remote host./
	.byte	cr
	.byte	cr
	.ascii	/send      sends a file from the  m6502/
	.byte	cr
	.ascii	/          based computer to the remote/
	.byte	cr
	.ascii	/          host./
	.byte	cr
	.byte	cr
	.ascii	/set       establish various parameters,/
	.byte	cr
	.ascii	/          such as dubbuging mode,  eol/
	.byte	cr
	.ascii	/          character, and  transmission/
	.byte	cr
	.ascii	/          delay./
	.byte	cr
	.byte	cr
	.ascii	/show      display  various  parameters/
	.byte	cr
	.ascii	/          established   by   the   set/
	.byte	cr
	.ascii	/          command./
	.byte	cr
	.byte	cr
	.ascii	/status    give  information about  the/
	.byte	cr
	.ascii	/          last file transfer./
	.byte	cr,nul

inthlp: .ascii	/one of the following:/
	.byte	cr
	.ascii	/     ? - this help message/
	.byte	cr
	.ascii	/     b - send break/
	.byte	cr
	.ascii	/     c - close the connection/
	.byte	cr
	.ascii	/     s - status/
	.byte	cr,nul

.sbttl	message text

ermes1: .byte	cr
	.asciz	/?unrecognized command/
ermes2: .byte	cr
	.asciz	/?illegal character/
ermes3: .byte	cr
	.asciz	/?not confirmed/
ermes4: .byte	cr
	.asciz	/?integer out of range/
ermes5: .byte	cr
	.asciz	/?ascii character is not in proper range/
ermes6: .byte	cr
	.asciz	/?expecting keyword/
ermes7: .byte	cr
	.asciz	/?expecting file spec/
ermes8: .byte	cr
	.asciz	/?expecting integer/
ermes9: .byte	cr
	.asciz	/?expecting switch/
ermesa:	.byte	cr
	.asciz	/?/
ermesb:	.byte	cr
	.asciz	/?null string found while looking for text/
ermesc:	.byte	cr
	.asciz	/?could not send generic logout packet/
ermesd:	.byte	cr
	.asciz	/?could not send generic finish packet/
ermesf:	.byte	cr
	.asciz	/?drive number out of range/

erms0a: .asciz	/file error stat=        /
erms10: .asciz	/cannot receive init     /
erms11: .asciz	/cannot receive file-head/
erms12: .asciz	/cannot receive data     /
erms14: .asciz	/max retry count exceeded/
erms15: .asciz	/bad chksum:pack, actual /
erms16: .asciz	/program error in rpak   /
erms17: .asciz	/8-bit quoting refused   /
erms18: .asciz	/transfer aborted by user/
erms19: .asciz	/cannot alter filename   /
erms1a: .asciz	/file already exists     /

dskers: .blkb	110
dsbind: .byte 	$00

kerftp: .asciz	/ASCII     /
	.asciz	/PETASCI   /
	.asciz	/SCRIPT    /
	.asciz	/BINARY    /

kerprs:	.asciz	/NONE /			; parity strings
	.asciz	/SPACE/			;
	.asciz	/MARK /			;
	.asciz	/ODD  /			;
	.asciz	/EVEN /			;

kerdms:	.asciz	/OFF     /		; debug mode strings
	.asciz	/TERSE   /		;
	.asciz	/VERBOSE /		;

kerrts: .asciz	/SPAK:     SENDING           - /
	.asciz	/SPAKCH:   SEND COMPLETE     - /
	.asciz	/RPAK:     TRYING TO RECEIVE - /
	.asciz	/RPKFLS:   FAILED TO RECEIVE - /
	.asciz	/RPKRET:   RECEIVED          - /

debms1: .asciz	/additional data/
debms2: .asciz	/     seq number           /
debms3: .asciz	/     number of data chars /
debms4: .asciz	/     packet checksum      /

snin01: .asciz	/sending ..packet no. /
rcin01: .asciz	/waiting ..packet no. /

shin00: .asciz	/debugging is                /
shin01: .asciz	/vt52-emulation is           /
shin02: .asciz	/ibm-mode is                 /
shin03: .asciz	/local-echo is               /
shin04: .asciz	/eight-bit-quoting is        /
shin05: .asciz	/file-warning is             /
shin06: .asciz	/escape character is         /
shin07: .asciz	/send/
shin08: .asciz	/     eight-bit-quoting char is   /
shin09: .asciz	/     end-of-line char is         /
shin10: .asciz	/     packet-length is            /
shin11: .asciz	/     padding char is             /
shin12: .asciz	/     amount of padding is        /
shin13: .asciz	/     quote char is               /
shin14: .asciz	/     timeout char is             /
shin15: .asciz	/receive/
shin16: .asciz	/file-type mode is           /
shin17: .asciz	/file-byte-size is           /
shin18: .asciz	/rs232 registers     =      $/
shin19:	.asciz	/foo                         /
shin20:	.asciz	/parity is                   /	;  FOR /SHOW PARITY/
shin22:	.asciz	/default drive is            /

shon:	.asciz	/ON/
shoff:  .asciz	/OFF/

shsbit: .asciz	/SEVEN-BIT/
shebit: .asciz	/EIGHT-BIT/

sstrng:	.asciz	/sending: /			; for terse debug
rstrng:	.asciz	/received: /			;		...

stin00: .asciz	/number of data chars sent is	  /
stin01: .asciz	/number of data chars recv'ed is  /
stin02: .asciz	/total number of chars sent is	  /
stin03: .asciz	/total number of chars recv'ed is /
stin04: .asciz	/overhead for send packets is	  /
stin05: .asciz	/overhead for receive packets is  /
stin06: .asciz	/last error encountered is	  /

inf01a: .asciz	/[connecting to host: type /
inf01b: .asciz	/ c to return]/		; second half of connect message

.SBTTL	End of Kermit-65 Source
	.end

