; 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
;	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 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 (6)  8-Sep-84$'	; 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			; 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 session 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)$'


;
;	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		;Parse an input file spec.
	lxi	d,fcb
	call	comnd
	 jmp	kermt3
	call	cfmcmd
	lxi	h,logflg
	mvi	m,0FFH		;Set the log flag.
	lxi	h,buff
	shld	bufpnt
	mvi	c,delf		;Delete the file if it exists.
	lxi	d,fcb
	call	bdos
	xra	a
	sta	fcb+0CH		;Zero the extent.
	sta	fcb+0EH		;Must be zero for MAKEF or OPENF.
	sta	fcb+20H		;Zero the current record.
	mvi	c,makef		;Now create it.
	lxi	d,fcb
	call	bdos
	cpi	0FFH		;Is the disk full?
	jnz	kermit		;
	lxi	d,erms17	;If so tell the user
	call	prtstr
	jmp	kermit
;
; 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	15		; 15 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	 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,'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
;
;	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
	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
;
;	This is the SHOW command.

show:	call	cfmcmd
;* Reconcile this and status.
	call	stat01		;For now just cop out.
	jmp	kermit

;	This is the STATUS command.

status:	call	cfmcmd
	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	stapar		; Tell about parity
	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 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.

;	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
