; CP4MIT.ASM
;	KERMIT - (Celtic for "FREE")
;
;	This is the CP/M-80 implementation of the Columbia University
;	KERMIT file transfer protocol.
;
;	Version 4.0
;
;	Copyright June 1981,1982,1983,1984,1985
;	Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others. 
;
;	This file contains the system-independent initialization, the main
;	loop, and the commands that don't have any place better to go
;	(BYE, EXIT, HELP, LOG, SET, SHOW, and STATUS).
;
; revision history:
; edit 8: February 6, 1895
;	Add a PORT status/show routine for those machines that have more
;	than one they can talk to. It also required a port storage variable
; 	a la SPEED and the necessary code to handle it in the SET routine.
;	[Hal Hostetler]
;
; edit 7: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
;
;pcc003-pcc005	2-Jan-85	vjc	modules:cp4mit,cp4tt,cp4utl
;	These edits must all be installed together and change the way
;	logging is handled.  The log file spec is moved to a separate
;	fcb, and not opened until an actual CONNECT command is given.
;	This takes care of a NASTY bug that if you used any other file
;	command between the LOG and CONNECT, the log file would get
;	written over the last file used.  This also allows logging to
;	be "permanently" enabled until an CLOSE (new command) for all
;	CONNECT sessions, like most other kermits do.  If a log file
;	already exists, it will be appended to.  Also add two new
;	CONNECT mode commands <esc>Q to suspend logging and <esc>R to
;	resume.  <esc>R means something else during TRANSMIT, but
;	logging is never on then, so there shouldn't be any conflict.
;	I also changed the write code, so that it can handle one more
;	character after the XOFF is send to stop the host.  This allows
;	a little "slop" for systems that don't stop immediately (such
;	as TOPS10), but it didn't help much.

;pcc012	4-Jan-85	vjc	modules:cp4mit,cp4tt,cp4utl
;	Use the big buffer for the log file.  Move the log file back
;	into the common fcb and only save the drive, name, and
;	extension between connects.  Add new routines to cp4utl to
;	create or append to an existing file, and to conditionally
;	advance buffers only if in memory.  Remove edit pcc003 that
;	allows one more character after the xoff, since it didn't
;	really work very well and does not fit in well with the way
;	the buffer advancing routines are set up.  If someone still
;	thinks this would be useful, it could be put back in with a
;	little more work.
;	
;	While testing this edit, I also noticed another bug that
;	the command parsing routines do not limit or check the
;	length of command lines or file specs, trashing what ever
;	comes after them.  Currently because of where the fcb and
;	command buffer are located, this does not usually cause a
;	problem, but could if an extremely long line was typed in,
;	or in the future multiple fcbs defined elsewhere in memory
;	were used.  Maybe this should be put on the bug list
;	somewhere.

;pcc013	8-Jan-85	vjc	modules:cp4mit,cp4utl,cp4typ
;	Replace CLOSE command to cancel session logging to SET
;	LOGGING ON/OFF.  This seems to fit in with the command
;	structure better.  Default the log file to KERMIT.LOG
;	incase no previous LOG command.  Logging is also enabled
;	by LOG command, as before.

; edit 6: September 8, 1984
;	Add VERSION command, to display the internal version strings.
;	Move command tables here from CP4UTL, and translate string
;	lengths in them to decimal (how many fingers do YOU got?).
;	Replace some jump tables with dispatch addresses in tables.
;	Make help text for SET command consistent with top level help text.
;
; edit 5: August 21, 1984
;	Add word at 0100H to allow us to exit cleanly from DDT (shifting
;	entry section by two bytes).
;
; edit 4: August 3, 1984 (CJC)
;	Remove "mover" from entry section, as it now lives in CP4SYS.
;
; edit 3: July 27, 1984 (CJC)
;	Merge LASM support from Toad Hall: most of CP4MIT is now in CP4UTL.
;	When assembling with LASM, CP4MIT is linked by CP4DEF; it links to
;	CP4PKT.  Add SET TACTRAP command.  Separate out display routines so
;	we can eventually do "SHOW <parameter>".  Save both bytes of baud
;	rate in speed, and check both bytes when displaying baud rate.  Move
;	header info to CP4KER.ASM.  Add onoff and chkkey routines to simplify
;	SET command (Toad Hall)
;
; edit 2: June 8, 1984
;	formatting and documentation; delete unreferenced variables and some
;	unnecessary labels; move setpar here from cp4pkt; add module version
;	string; make this version 4.01.
;
; edit 1: May, 1984
;	extracted from CPMBASE.M80 version 3.9; modifications are described
;	in the accompanying .UPD file.

;
	ASEG
	ORG	100H

; The CCP invokes programs with a CALL 100H, with the stack pointer set to
; 100H.  When we exit to CP/M, we do so with a RET, avoiding a warm boot.
; Unfortunately, DDT starts programs with a jump, not a call, so when we
; attempt to return to CP/M, we blow the stack and use the word at 100H as
; the new PC.  Put a 0 there so we reboot instead of dying horribly.
; (Fortunately, this happens to be two NOP's).
	dw	0
	jmp	start	; Bypass entry section

;
;	Entry section for system-independent part.  This contains
;	jumps to routines needed by the system support module.
;
entries:
	jmp	kermit		; reentry address
	jmp	nout		; output HL in decimal
entsiz	equ	$-entries	; length of entry section
;
;	End of entry section.  As a consistency check, the expected
;	length of this section is stored by the system-dependent
;	module in the linkage section at the end of Kermit, and
;	tested at initialization.

mitver:	db	'CP4MIT.ASM (8)  6-Feb-85$'	; name, edit number, date
;
;
;	Initialization
;
start:	lxi	h,0		; Clear out hl pair
	dad	sp		; and fetch the system stack pointer
	shld	oldsp		; and save for later restoral
	lxi	sp,stack	; move in our own stack.
	lxi	d,version	; print Kermit version
	call	prtstr		;  before we do too much
	mvi	c,rddrv		;Get our logged in drive
	call	BDOS
	inr	a		;relative 1
	sta	CURDSK		;and save it for later
;
;	Make sure the overlay is in place...
;
	lhld	lnkflg
	mov	a,h
	ora	l		; if lnkflg is still zero,
	jz	start1		;  the configuration overlay is missing.
	lxi	d,-lnksiz	; if it's not equal to lnksiz,
	dad	d		;  we've probably got the wrong
	mov	a,h		;  version of the configuration overlay.
	ora	l
	jnz	start2
	lhld	lnkent		; make sure the overlay knows how long
	lxi	d,-entsiz	; our entry section is, so they don't miss.
	dad	d
	mov	a,h
	ora	l
	jnz	start2
				; might be ok.
	call	sysinit		; do system-dependent initialization
	lxi	d,inms26	; offer some advice on getting help
	call	prtstr
	jmp	kermit		; Start main loop.

start1:	lxi	d,erms20	; "Kermit has not been configured"
	call	prtstr		; print error message
	jmp	exit2		;  and exit.

start2:	lxi	d,erms21	; "Consistency check on configuration failed"
	call	prtstr		; print error message
	jmp	exit2		;  and exit.
;
;This is the main KERMIT loop.  It prompts for and gets the users commands.

kermit:	lxi	sp,stack	; get new stack pointer, old one might be bad.
	call	selcon		; make sure console is selected.
	xra	a
	sta	mfflg1		;reset MFNAME
	sta	mfflg2		;ditto
	lda	curdsk		; update the prompt
	adi	'A'-1
	sta	kerm1
	lxi	d,kerm
	call	prompt		;Prompt the user.
	lxi	d,comtab
	lxi	h,tophlp
	call	keycmd		; Get a keyword
	xchg			; Get result (dispatch address) into HL
	pchl			; Dispatch.

;	here from: log, setcom, read, cfmcmd
kermt3:	lxi	d,ermes3	;"Not confirmed"
	call	prtstr
	jmp	kermit		;Do it again.

;	Structure of command table:
;
;	1) Number of entries.
;	2) Each entry is arranged as follows:
;		a) length of command in bytes.
;		b) 'name of command and $-sign'
;		c) address of routine to process command
;
;	---> Note this command table is in alphabetic order.
;

comtab:	db	17			;[pcc013] 17 entries
	db	3, 'BYE$'
		dw bye
	db	7, 'CONNECT$'
		dw telnet
	db	9, 'DIRECTORY$'
		dw dir
	db	5, 'ERASE$'
		dw era
	db	4, 'EXIT$'
		dw exit
	db	6, 'FINISH$'
		dw finish
	db	3, 'GET$'
		dw read		;Same as RECEIVE
	db	4, 'HELP$'
		dw help
	db	3, 'LOG$'
		dw log
	db	6, 'LOGOUT$'
		dw logout
	db	7, 'RECEIVE$'
		dw read
	db	4, 'SEND$'
		dw send
	db	3, 'SET$'
		dw setcom
	db	4, 'SHOW$'
		dw show
	db	6, 'STATUS$'
		dw status
	db	8, 'TRANSMIT$'
		dw xmit
	db	7, 'VERSION$'
		dw shover

; top-level help message. Caps indicate keywords.
; this text is also printed by the HELP command.

tophlp:	db	cr,lf,'BYE to host (LOGOUT) and exit to CP/M'
	db	cr,lf,'CONNECT to host on selected port'
	db	cr,lf,'ERASE a CP/M file'
	db	cr,lf,'EXIT to CP/M'
	db	cr,lf,'FINISH running Kermit on the host'
	db	cr,lf,'HELP by giving this message'
	db	cr,lf,'DIRECTORY of current used Micro-disk'
	db	cr,lf,'LOG the terminal sessions to a file'
	db	cr,lf,'LOGOUT the host'
	db	cr,lf,'RECEIVE file from host'
	db	cr,lf,'SEND file to host'
	db	cr,lf,'SET a parameter'
	db	cr,lf,'SHOW the parameters'
	db	cr,lf,'STATUS of Kermit'
	db	cr,lf,'TRANSMIT file to host (in connect state)'
	db	cr,lf,'VERSION of Kermit running$'		;[pcc005]

;
;	This is the BYE command.  It tells the remote KERSRV to logout,
;	then exits.

bye:	call	cfmcmd
	call	logo		;Tell the main frame to logout.
	 jmp	kermit		;If it fails, don't exit.
	call	sysbye		; success. do system-dependent cleanup
	jmp	exit1		;Exit Kermit.

;	This is the EXIT command.  It leaves KERMIT and returns to CP/M.
;	alternate entries: exit1, from BYE command;
;	exit2, from initialization (if it fails)

exit:	call	cfmcmd		; confirm...
exit1:	call	sysexit		; do system-dependent termination
exit2:	lhld	oldsp		;Get back the system stack
	sphl			;and restore it.
	ret			;Then return to system.

;	This is the HELP command.  It gives a list of the commands.

help:	call	cfmcmd
	lxi	d,tophlp	;The address of the help message.
	call	prtstr
	jmp	kermit
;
;	This is the LOG command.  It logs a session to a file.

log:	mvi	a,cmofi		;[pcc005] Parse an output file spec.
	lxi	d,fcb		;[pcc012] where to put it
	call	comnd
	 jmp	kermt3
	call	cfmcmd
	lxi	h,fcb		;[pcc012] copy file name and ext
	lxi	d,lognam	;[pcc012] to a safe place
	lxi	b,12		;[pcc012] 12 bytes
	call	mover		;[pcc012] zap ...
	mvi	a,1		;[pcc005] set flag for logging
	sta	logflg		;[pcc005]
	jmp	kermit		;[pcc005]

;
; This is the SET command.

setcom:	lxi	d,settab	;Parse a keyword from the set table.
	lxi	h,sethlp
	call	keycmd
	xchg			; Get result (dispatch address) into HL
	pchl			; Dispatch.

settab:	db	16		;[pcc013] 16 entries [Toad Hall]
				; Value is address of processing routine.
	db	 9, 'BAUD-RATE$'
		dw baud
	db	16, 'BLOCK-CHECK-TYPE$'
		dw blkset
	db	 5, 'DEBUG$'
		dw setdbg
	db	12, 'DEFAULT-DISK$'
		dw setdisk
	db	 6, 'ESCAPE$'
		dw escape
	db	 9, 'FILE-MODE$'
		dw setcpm
	db	 3, 'IBM$'
		dw ibmset
	db	10, 'LOCAL-ECHO$'
		dw locall
	db	 7, 'LOGGING$'			;[pcc013]
		dw setlog			;[pcc013]
	db	 6, 'PARITY$'
		dw parset
	db	 4, 'PORT$'
		dw prtset
	db	 7, 'PRINTER$'
		dw setprn
;*	db	 7, 'RECEIVE$'
;*		dw kermt3			;Not implemented yet.
;*	db	 4, 'SEND$'
;*		dw setsnd			;Ditto
	db	 7, 'TACTRAP$'
		dw settac
	db	 5, 'TIMER$'
		dw settim
	db	14, 'VT52-EMULATION$'
		dw vt52em
	db	 7, 'WARNING$'
		dw filwar

; help message for SET command. Caps indicate keywords

sethlp:	db	cr,lf,'BAUD-RATE'
	db	cr,lf,'BLOCK-CHECK-TYPE for error detection'
	db	cr,lf,'DEBUG message control'
	db	cr,lf,'DEFAULT-DISK to receive data'
	db	cr,lf,'ESCAPE character during CONNECT'
	db	cr,lf,'FILE-MODE for outgoing files'
	db	cr,lf,'IBM mode: parity and turn around handling'
	db	cr,lf,'LOCAL-ECHO (half-duplex)'
	db	cr,lf,'LOGGING of terminal sessions'	;[pcc013]
	db	cr,lf,'PARITY for communication line'
	db	cr,lf,'PORT to communicate on'
	db	cr,lf,'PRINTER copy control'
;*	db	cr,lf,'RECEIVE parameters'	;Not currently implemented
;*	db	cr,lf,'SEND parameters'		;Ditto
	db	cr,lf,'TAC interface support'
	db	cr,lf,'TIMER control'
	db	cr,lf,'VT52-EMULATION'
	db	cr,lf,'WARNING for filename conflicts'
	db	'$'

;
;SET BLOCK-CHECK-TYPE command.

blkset:	lxi	d,blktab	;Get the address of the block-check table
	lxi	h,blkhlp	;And the address of the help text
	call	chkkey		;Go check input (val returns in A).
	sta	chktyp		;Save desired checksum type
	jmp	kermit		;Go get another command

blktab:	db	3		;Three entries.
	db	20, '1-CHARACTER-CHECKSUM$',	'1','1'
	db	20, '2-CHARACTER-CHECKSUM$',	'2','2'
	db	21, '3-CHARACTER-CRC-CCITT$',	'3','3'

blkhlp:	db	cr,lf,'1-CHARACTER-CHECKSUM'
	db	cr,lf,'2-CHARACTER-CHECKSUM'
	db	cr,lf,'3-CHARACTER-CRC-CCITT$'

;SET DEFAULT DISK command

setdisk:lxi	d,fcb
	mvi	a,cmifin	;get "file-spec" silently
	call	comnd
	 jmp	setdi1
setdi1:	lda	fcb
	ora	a		;Was a drive specified? (if zero, no)
	jnz	setdi2		;he typed a drive-spec
	lda	curdsk		;he didn't - give him default
setdi2:	sta	curdsk
	mvi	c,inbdos	;reset disks
	call	bdos
	lda	curdsk
	dcr	a		;LOGDSK is relative 0
	mov 	e,a
	mvi	c,logdsk
	call	bdos		;and "LOG" it
	jmp	kermit		;all done
;
;SET SEND command. (not supported yet)

setsnd:	lxi	d,stsntb	;Parse a keyword from the set send table.
	lxi	h,stshlp
	call	keycmd
	xchg			; Get dispatch address into HL
	pchl			; Go for it.

stsntb:	db	2		;Two entries.
	db	8, 'PAD-CHAR$'
		dw stpdch
	db	7, 'PADDING$'
		dw stpad

stshlp:	db	cr,lf,'PAD-CHAR'
	db	cr,lf,'PADDING$'

; SET SEND PADDING command. does nothing.
stpad:	call	cfmcmd
	jmp	kermit

; SET SEND PAD-CHAR command. does nothing.
stpdch:	call	cfmcmd
	jmp	kermit

;[pcc013]
;	This is the SET LOGGING ON/OFF subcommand

setlog:	call	onoff		;[pcc013] Get on/off
	sta	logflg		;[pcc013] Store flag
	jmp	kermit
;
;	This is the SET ESCAPE character subcommand.

escape:	call	cfmcmd
	lxi	d,escmes	;Get the address of the escape message.
	call	prtstr
	mvi	c,conin		;Get the char.
	call	bdos
	sta	escchr		;Store the new escape character.
	jmp	kermit

;	This is the SET LOCAL-ECHO subcommand.

locall:	call	onoff		;Get on/off setting [Toad Hall]
	sta	ecoflg		;Store local echo flag.
	jmp	kermit

;	This is the SET PRINTER ON/OFF subcommand

setprn:	call	onoff		;Get on/off setting [Toad Hall]
	sta	prnflg		;Store printer flag
	jmp	kermit

;	This is the SET DEBUG ON/OFF subcommand

setdbg:	call	onoff		;Get on/off setting [Toad Hall]
	sta	dbgflg		;Store debug flag
	jmp	kermit

;[jd] this is the SET TIMER subcommand

settim:	call	onoff		;Get on/off setting [Toad Hall]
	sta	timflg		;Store timer flag value
	jmp	kermit

;This is the SET FILE-WARNING subcommand

filwar:	call	onoff		;Get on/off setting [Toad Hall]
	sta	flwflg		;Store file-warning flag.
	jmp	kermit

;	This is the SET IBM command.

ibmset:	call	onoff		;Get on/off setting [Toad Hall]
	sta	ibmflg		;Store IBM flag.
	ora	a		;Is it turned on?
	jz	ibmst1		;If not, set parity to the default.
	mvi	a,ibmpar	;Get the IBM parity.
	mvi	b,1		;Set local echo on.
	jmp	ibmst2
ibmst1:	mvi	a,defpar
	mvi	b,0		;Set local echo off.
ibmst2:	sta	parity		;Save them.
	mov	a,b
	sta	ecoflg
	sta	timflg		;[jd] timer is same as local echo
	jmp	kermit

;
;	SET FILE-MODE command.

setcpm:	lxi	d,typtab
	lxi	h,typhlp
	call	chkkey		;Get and confirm keyword, or die trying
	sta	cpmflg		;Set the CPM flag.
	jmp	kermit

typtab:	db	3		;Three entries
	db	5, 'ASCII$',	01H,01H
	db	6, 'BINARY$',	02H,02H
	db	7, 'DEFAULT$',	00H,00H

typhlp: db	cr,lf,'ASCII	BINARY	DEFAULT$'

;	This is the SET PARITY subcommand.

parset:	lxi	d,partab
	lxi	h,parhlp
	call	chkkey		;Get and confirm keyword, or die trying
	sta	parity		;Set the parity flag.
	jmp	kermit

partab:	db	5		;Five entries.
	db	4, 'EVEN$',	parevn,parevn
	db	4, 'MARK$',	parmrk,parmrk
	db	4, 'NONE$',	parnon,parnon
	db	3, 'ODD$',	parodd,parodd
	db	5, 'SPACE$',	parspc,parspc

parhlp:	db	cr,lf,'EVEN	MARK	NONE	ODD	SPACE$'

;	This is the SET TACTRAP subcommand.
;	options are ON, OFF, or CHARACTER.  (for CHARACTER, we request the
;	new TAC Intercept character, and turn the TACtrap on)

settac:	lxi	d,tactab
	lxi	h,tachlp
	call	chkkey		;Get and confirm keyword
	ora	a		;Was it "OFF" (zero)?
	jz	settc2		;If so, go disable TACtrap.
	cpi	1		;Was it "ON"?
	jz	settc1		;If so, go enable TACtrap.
	lxi	d,tacmes	;"CHARACTER". request new TAC Intercept char.
	call	prtstr
	mvi	c,conin		;Get the char.
	call	bdos
	sta	tacchr		;Store the new TAC Intercept character.
settc1:	lda	tacchr		;Copy tacchr to tacflg to enable TACtrap.
settc2:	sta	tacflg		;Enable/disable TACtrap
	jmp	kermit

tactab:	db	3		;Three entries.
	db	9,	'CHARACTER$',	02H,02H
	db	3,	'OFF$',		00H,00H
	db	2,	'ON$',		01H,01H

tachlp:	db	cr,lf,'ON to enable TAC trap'
	db	cr,lf,'OFF to disable TAC trap'
	db	cr,lf,'CHARACTER to enable TAC trap and'
	db	' specify intercept character$'

;	This is the SET VT52-EMULATION subcommand.

vt52em:	lda	vtflg		;get the flag value
	cpi	0ffH		;0ffH means not allowed -
	jz	notimp		; say it's not implemented.
	call	onoff		;Get keyword (ON or OFF)
	sta	vtflg		;Set the VT52 emulation flag.
	jmp	kermit
;
;	Note:  For the SET BAUD and SET PORT commands, which might not be
;	supported for the current system, the command tables are stored in
;	the overlay.  We locate them through pointers in the linkage area:
;	spdtab for SET BAUD, prttab for SET PORT.  The contents of spdtab
;	(or prttab) is the address of the beginning of the table (the table
;	does NOT begin at spdtab).  If the address is zero, the command is
;	not supported.  If the table address is nonzero, then there is a
;	corresponding help message pointed to by (NOT starting at) spdhlp
;	or prthlp.

;	This is the SET BAUD command

baud:	lhld	spdtab		; get pointer to speed table
	mov	a,h
	ora	l		; test for NULL (zero)
	jz	notimp		; if so, say it's not implemented
	xchg			; move speed table address to DE
	lhld	spdhlp		; get pointer to speed help text
	call	keycmd
	push	d		; save selected speed
	call	cfmcmd		; confirm...
	pop	h		; restore speed to HL
	shld	speed		; save all 16 bits of speed value
	xchg			; move speed to DE
	call	sysspd		; do system-dependent speed setting.
	jmp	kermit		; return to command level

;	This is the SET PORT command

prtset:	lhld	prttab		; get pointer to port table
	mov	a,h
	ora	l		; test for NULL
	jz	notimp		; not supported if pointer was null.
	xchg			; move port table address to DE
	lhld	prthlp		; get pointer to port help text
	call	keycmd
	push	d		; save selected port entry
	call	cfmcmd		; confirm...
	pop	h		; restore table address to HL
	shld	port		;[hh] save all 16 bits of port value
	call	sysprt		; go do port stuff
	jmp	kermit
;
;	Subroutines for SET subcommands

;	ontab - command table for onoff.
;	onhlp - help text for onoff.
;	onoff - accept "ON" or "OFF" keyword.
;	returns:
;	    success: value in A (non-zero = ON)
;	    error: no return to caller. print error message and return to
;		main loop.
ontab:	db	2		;Two entries.
	db	3, 'OFF$',	00H,00H
	db	2, 'ON$',	01H,01H

onhlp:	db	cr,lf,'OFF	ON$'

onoff:	lxi	d,ontab
	lxi	h,onhlp
	;Fall through to check input.  [Toad Hall]

;	chkkey - parse and confirm keyword.
;	called with:
;	    DE/ address of keyword table
;	    HL/ address of help text
;	returns:
;	    success: low byte of keyword value (from table) in A.
;	    error: no return to caller.  print error message and return to
;		main loop.  (Since the main loop reloads the stack pointer,
;		we don't have to attempt to clean up the stack here)

chkkey:	call	keycmd		; Parse a keyword (might not return)
	sta	temp1		; Save the parsed value
	call	cfmcmd		; Request confirmation (might not return)
	lda	temp1		; Get saved value
	ret			; Return

;[hh] 	fndkyw - find a keyword string from a table using 
;		 it's associated value
;	called with:
;	    HL/ address of keyword table
;	     A/ value associated with keyword string
;	returns:
;	    success: HL points to first byte of keyword string
;		     CY flag is cleared
;	    error:   HL points to error string (?Not found)
;		     CY flag is set

fndkyw:	mov	d,m		;get count of entries
	inx	h		;advance over count value
fndkw1:	mov	b,m		;get string length
	inr	b		;account for $
	inx	h		;advance over length value
	shld	temp1		;save string pointer
fndkw2:	inx	h		;loop over string
	dcr	b
	jnz	fndkw2
	mov	c,m		;get keyword value from table
	cmp	c		;do they match?
	jz	fndkw3		;Yup
	inx	h		;bump to next keyword
	inx	h		;
	dcr	d		;decrement entry count
	jnz	fndkw1		;check the remaining keywords
	lxi	h,kywdnf	;point to not found message
	stc			;give calling routine a not found flag
	ret
fndkw3:	ora	a		;clear CY to tell caller we succeeded
	lhld	temp1		;restore the saved string pointer
	ret

kywdnf:	db	cr,lf,'?Not found$'	;not found message

;
;	This is the SHOW command.

show:	call	cfmcmd
;* Reconcile this and status.
	call	clrtop		;[hh] Clear screen first
	call	stat01		;For now just cop out.
	jmp	kermit

;	This is the STATUS command.

status:	call	cfmcmd
	call	clrtop		;[hh] Clear screen first
	call	stat01
	jmp	kermit

;	processor for SHOW, STATUS and <escape>S commands
;	called by: show, status, intchr

stat01:	lda	fileio		;Are we in transmit?
	ora	a
	jz	sta01b		;No
	lxi	d,xmtst		;Yes,say so
	call	prtstr
sta01b:	call	staeco		; Tell about local echo flag
	lda	vtflg		; Get the VT52 emulation flag
	cpi	0ffH		; Supported for this terminal?
	cnz	stavt		; If so, tell whether it's on or off.
	call	stafil		; Tell about file type
	call	staibm		; Tell about IBM flag
	call	stawrn		; Tell about file-warning flag
	call	stalpt		; Tell about printer copy flag
	call	stalog		; [pcc003] Tell about log file status
	call	stapar		; Tell about parity
	lhld	prttab		;[hh] Got a port table? (is pointer nonzero?)
	mov	a,h		;[hh]
	ora	l		;[hh]
	cnz	stapor		;[hh] If so, tell which port we're using
	lhld	spdtab		; Got a speed table? (is pointer nonzero?)
	mov	a,h
	ora	l
	cnz	staspd		; If so, tell what speed we're running.
	call	stabcc		; Tell current block check type
	call	staesc		; Tell current escape character
	call	statim		; Tell about timer flag
	call	statac		; Tell about TAC flag/intercept character.
	ret

;	Show the value of the LOCAL-ECHO flag (On or Off).

staeco:	lxi	d,locst		;Get the address of the local echo string.
	call	prtstr
	lda	ecoflg		;Get the local echo flag.
	jmp	staton		;Say ON or OFF, and return

;	Show the value of the VT52-EMULATION flag (On, Off, or Not Supported).

stavt:	lxi	d,vtemst	; Get the address of the VT52 emulation string.
	call	prtstr
	lda	vtflg		; Get the VT52 emulation flag.
	cpi	0ffH		; Is it supported?
	jnz	staton		; If so, say ON or OFF, and return
	jmp	notimp		; Not supported.  print appropriate message.

;	Show the value of the FILE-MODE flag (ASCII, Binary, or Default).

stafil:	lxi	d,cpmst		; Get the address of the file mode message.
	call	prtstr
	lda	cpmflg		; Get the file mode flag.
	lxi	d,defstr	; Assume Default (0).
	ora	a		; Is it?
	jz	prtstr		; If so, say so, and return.
	lxi	d,ascstr	; Not default, assume ASCII
	cpi	1		; Is it ASCII?
	jz	prtstr		; Say ASCII, and return
	lxi	d,binstr	; Not default or ASCII, must be binary
	jmp	prtstr		; Print type, and return.

;	Show the value of the IBM-MODE flag (On or Off).

staibm:	lxi	d,ibmst		;IBM string.
	call	prtstr
	lda	ibmflg		; Get IBM flag.
	jmp	staton		; Print its value and return

;	Show the value of the FILE-WARNING flag (On or Off).

stawrn:	lxi	d,filst		; File warning string.
	call	prtstr
	lda	flwflg		; File warning flag.
	jmp	staton		; Say ON or OFF

;	Show the value of the PRINTER flag (On or Off).

stalpt:	lxi	d,prst		;Printer copy string
	call	prtstr
	lda	prnflg		;Printer ON/OFF flag
	jmp	staton		; Say ON or OFF

;	Show status of log file
stalog:	lxi	d,logst		;[pcc003] Logging
	call	prtstr		;[pcc003]
	lda	logflg		;[pcc003] get the flag
	ani	7FH		;[pcc003] ignore open flag
	cpi	2		;[pcc003] is it suspended?
	jnz	staton		;[pcc003] no, must be on or off
	lxi	d,susstr	;[pcc003] suspended
	jp	prtstr		;[pcc003] print and return

;	Show the value of the PARITY flag (Odd, Even, Mark, Space, or None).

stapar:	lxi	d,parst		;Parity string.
	call	prtstr
	lda	parity		;Get the parity setting.
	lxi	d,pnonst	;Assume parity is NONE
	cpi	parnon		;Were we right?
	jz	prtstr		;Yep, go say None, and return
	lxi	d,pmrkst	;Get ready to say Mark
	cpi	parmrk		;Is it mark?
	jz	prtstr		;Yep, go say Mark, and return
	lxi	d,pspcst	;Get ready to say Space
	cpi	parspc		;Is it space?
	jz	prtstr		;Yep, go say Space, and return
	lxi	d,poddst	;Get ready to say Odd
	cpi	parodd		;Is it odd?
	jz	prtstr		;Yep, go say Odd, and return
	lxi	d,pevnst	;Must be Even.
	jmp	prtstr		;Say Even, and return.

;[hh]	Show the current port (if known).

stapor:	lxi	d,porst		;[hh]
	call	prtstr		;[hh]
	lda	port		;[hh] Get current port value
	lxi	h,spdust	;[hh] Assume undefined (this error msg is fine)
	cpi	0FFH		;[hh] Is it?
	jz	stat73		;[hh] Yup. Say so
	lhld	prttab		;[hh] Address of port keyword table
	call	fndkyw		;[hh] Look for correct keyword string
	jnc	stpr1		;[hh] Found a match
	lxi	h,spdust	;[hh] No match found - say it's undefined
stpr1:	jmp	stat73		;[hh] Print it and return

;	Show the current line speed (if known).

staspd:	lxi	d,spdst
	call	prtstr
	lda	speed		;Get current speed.
	lxi	h,spdust	;Assume undefined.
	cpi	0FFH		;Is it?
	jz	stat73		;Yes.
	lhld	spdtab		;Start scanning keyword table.
	mov	d,m		; get count of entries
	inx	h		; advance over it.
stat70:	mov	b,m		;Get string length.
	inr	b		;Account for $.
	inx	h
	shld	temp1		;Save string pointer.
stat71:	inx	h		;Loop over string.
	dcr	b
	jnz	stat71
	mov	c,m		;Get speed value
	cmp	c		;Match?
	jz	stat72		;Yes.
	inx	h		;Bump to next keyword.
	inx	h
	dcr	d		; decrement entry count
	jnz	stat70		; if more left, check them.
	lxi	h,spdust	; can't find it. say it's undefined.
	jmp	stat73		; print the message.

stat72:	lhld	temp1		;Restore saved string pointer.
stat73:	xchg			;Set into DE for display.
	jmp	prtstr		; print it, and return.

;	Show the current BLOCK-CHECK-TYPE (1-, 2-, or 3-character).

stabcc:	lxi	d,bckst		;Get the string
	call	prtstr		;Print "Block check type: "
	lda	chktyp		;Get the type (character 1, 2, or 3)
	mov	e,a		;Put into E
	mvi	c,conout	;Want to print it
	call	BDOS		;Do so
	lxi	d,bckst1	;Get rest of text ("-character")
	jmp	prtstr		;Print it and return

;	Print the current escape character

staesc:	lxi	d,escst		;Escape string.
	call	prtstr
	call	escpr		;Print the escape char.
	jmp	prcrlf		;Print CR/LF and return  [Toad Hall]

;	Show the value of the TIMER flag
statim:	lxi	d,timmsg	;[jd] 
	call	prtstr		;[jd] 
	lda	timflg
	jmp	staton		;Tell whether it's on or off.

;	Show internal versions (edit strings)
shover:	call	cfmcmd
	call	prcrlf
	lxi	h,vertab	; Get address of version list
shovr1:	mov	e,m		; Get next word from list
	inx	h
	mov	d,m		; Next version string is in DE
	inx	h
	mov	a,d		; Test for zero (end of list)
	ora	e
	jz	shovr2		; Done with list if zero
	push	h		; Save position in list
	call	prtstr		; Not zero.  Print it.
	call	prcrlf		; Follow with crlf
	pop	h		; Restore position in list
	jmp	shovr1		;  and go see if there are any more.

shovr2:	lhld	ovlver		; Get overlay version string
	xchg			;  into DE
	call	prtstr		; Print it
	call	prcrlf		; Output crlf
	jmp	kermit		; Return to main loop.

; table of pointers to version strings.
vertab:	dw	mitver		; CP4MIT
	dw	pktver		; CP4PKT
	dw	ttver		; CP4TT
	dw	cpmver		; CP4CPM
	dw	wldver		; CP4WLD
	dw	cmdver		; CP4CMD
	dw	utlver		; CP4UTL
	dw	0		; end of list

;	Show TACTrap status (On or Off, and intercept character)
statac:	lxi	d,tacst		;"Current TACTrap status/char: "
	call	prtstr
	lxi	d,offstr	;Assume set off
	lda	tacflg		;Get the TACTrap char/flag
	ora	a		;Is it off?
	jz	prtstr		;Yep, go print OFF...
	mvi	c,conout	;Display...
	mov	e,a		;...the current intercept char
	call	bdos
	jmp	prcrlf

;	Display current state of a boolean flag.
;	called with A/ value (zero = Off, non-zero = On)

staton:	lxi	d,onstr		; Assume it's on.
	ora	a		; Is it on?
	jnz	prtstr		; If so, say so, then return.
	lxi	d,offstr	; No, say off.
	jmp	prtstr		; Print the string, then return.

;	Print "(not implemented)".
;	here from vt52em, baud, prtset, stavt

notimp:	lxi	d,inms12	; Say it's not implemented.
	call	prtstr
	jmp	kermit		; Return to main loop.

IF lasm				; If using LASM, chain to the next file.
	LINK	CP4PKT
ENDIF;lasm
