;LBSETKI/ASM - Set Keyboard Parameters
	TITLE	<SETKI - LS-DOS 6.2>
;
OFFSET	EQU	4		;Length: end of name to data area
DELAY	EQU	OFFSET+2
RPEAT	EQU	OFFSET+3
DMIN	EQU	10
RMIN	EQU	1
DDFALT	EQU	22
RDFALT	EQU	2
ETX	EQU	03H
CR	EQU	0DH
LF	EQU	0AH
PAR_ERR	EQU	44		;Parameter Error
;
FLAG	EQU	01000000B
ABB	EQU	00010000B
NUM	EQU	10000000B
;
*GET	SVCMAC:3		;SVC Macro equivalents
;
	ORG	2400H
;
BEGIN	EQU	$
	LD	(SAVESP+1),SP
	CALL	PGRM		;Exit via RET
;
;	Set exit conditions 
;
$EXIT	LD	HL,0		;Init to no error
SAVESP	LD	SP,$-$		;P/u original SP
	@@CKBRKC		;Clear any <BREAK>
	RET
$ABORT	LD	HL,-1		;Set abort code
	JR	SAVESP
;
$DSP	@@DSP			;Display a character
	RET	Z		;Back if good
	JR	IOERR
$DSPLY	@@DSPLY			;Display a line
	RET	Z		;Back if good
	DB	21H		;Skip LD A,##
PRMERR	LD	A,PAR_ERR	;Parameter Error
;
;	I/O Error Processing
;
IOERR	LD	H,0
	LD	L,A		;Save error #
	OR	0C0H
	LD	C,A	
	@@ERROR			;Display message
	JR	SAVESP		;Exit
;
;	PGRM - Set Keyboard Parameters
;
PGRM	PUSH	HL		;Save cmdline ptr
	LD	DE,MDNAME	;Name of keyboard driver
	@@GTMOD			;Find module header
	LD	A,8		;Device not available
	JP	NZ,IOERR	;Exit if not found
	PUSH	DE		;Point to next byte
	POP	IX		;  after module name
;
	POP	HL		;=>cmd line
	CALL	SKSP		;Move to non-space
	LD	A,(HL)		;Char fm cmd line
	CP	'('		;Any params?
	JP	Z,GETNEW	;Get/set new values
;
;	Display old values
;
	CALL	SETMSG		;Move old values for dsply
	LD	HL,DMSG		;Pt to dsply string
	JP	$DSPLY		;Dsply and exit
;
;	Set up values in string
;
SETMSG	LD	A,(IX+DELAY)	;P/u old Wait value
	LD	DE,DDELAY	;=>buffer to receive
	CALL	HEXDEC		;Convert to ASCII decimal
	LD	A,(IX+RPEAT)	;P/u old Rate value
	LD	DE,DRPEAT	;Pt to dsply area
	JP	HEXDEC		;Convert to decimal ASCII
;
GETNEW	LD	DE,PRMTBL$	;Check user parameters
	@@PARAM
	JP	NZ,PRMERR	;Go on "Parm error
	LD	DE,$-$		;P/u D parm
DFPARM	EQU	$-2
	LD	A,D		;Default setting wanted?
	OR	E
	JR	Z,SETSTR	;Keep existing if not
	LD	(IX+DELAY),DDFALT	;Stuff defaults
	LD	(IX+RPEAT),RDFALT
SETSTR	CALL	SETMSG		;Put numbers in string
QCHK	LD	DE,$-$
QPARM	EQU	$-2		;Query parm used?
	LD	A,D
	OR	E
	JR	Z,CKPARM	;Go if not
;
	LD	A,(WRESP)	;P/u Wait response byte
	AND	NUM		;If a "W" number given,
	JR	NZ,CKR		;  then ask for R only
GETD	LD	HL,DMSG		;Pt to Wait prompt msg
	CALL	SHOW		;Ask for W time
	CALL	GETIT		;Get it (in DE)
	JR	Z,CKR		;Don't change if CR only
	CALL	DCHECK		;Check if good value
	JR	NZ,GETD		;Don't change if not
	LD	(IX+DELAY),A	;Store new Wait
;
CKR	LD	A,(RRESP)	;P/u Rate resopnse byte
	AND	NUM		;  and go if Rate
	JR	NZ,CKPARM	;  entered on cmdline
	LD	HL,RMSG		;Pt to Rate prompt msg
	CALL	SHOW
	CALL	GETIT		;Get new Rate
	JR	Z,CKPARM	;Don't change if CR only
	CALL	RCHECK		;Check range & don't
	JR	NZ,CKR		;  change if out of range
	LD	(IX+RPEAT),A	;Store new Rate
;
;	Check entries given on cmd line
;
CKPARM	LD	A,(WRESP)
	AND	NUM		;W parm response
	JR	Z,CKRP		;Go if not entered
	LD	DE,$-$		;P/u Wait value
WPARM	EQU	$-2
	CALL	DCHECK		;Check value
	JP	NZ,PRMERR	;Go if bad
	LD	(IX+DELAY),A	;  else store it
;
CKRP	LD	A,(RRESP)	;Rate response
	AND	NUM
	RET	Z		;Done if none
	LD	DE,$-$		;P/u Rate value
RPARM	EQU	$-2
	CALL	RCHECK		;Check value
	JP	NZ,PRMERR	;  and go if bad
	LD	(IX+RPEAT),A	;  else store it
	RET			;Done
;
SHOW	LD	B,12		;Col posn
SH2	LD	C,(HL)		;Get char in C
	CALL	$DSP		;Print byte fm string
	DEC	B		;Dec chars to print
	INC	HL		;Bump string ptr
	LD	A,'='
	CP	C
	JR	NZ,SH2		;Display up to =
	LD	C,' '		;Then space
	CALL	$DSP
	CALL	SKSP		;Move to number
	LD	C,'{'
	CALL	$DSP		;Dsply opening brace
SH3	LD	C,(HL)		;P/u character
	LD	A,'0'-1		;Check C for numeric value
	CP	C
	JR	NC,SH4		;Go if not
	CALL	$DSP		;  else dsply,
	DEC	B		;  dec chars remaining,
	INC	HL		;  pt to next char in string
	JR	SH3		;  and loop
SH4	LD	C,'}'		;Display closing brace
	CALL	$DSP
	LD	C,' '
SH5	CALL	$DSP		;Tab remaining distance
	DJNZ	SH5
	LD	HL,ENDSTR	;Print "?"
	JP	$DSPLY
;
SKSP	LD	A,' '		;Bypass all leading spaces
SKP2	CP	(HL)
	RET	NZ
	INC	HL
	JR	SKP2
;
;
;
DMSG	DB	'Wait   = '
DDELAY	DB	'   , '
RMSG	DB	'Rate   = '
DRPEAT	DB	'   ',CR
MDNAME	DB	'$KI',ETX
ENDSTR	DB	'? ',ETX
;
PRMTBL$	DB	80H
;
	DB	FLAG!ABB!7
	DB	'DEFAULT'
	DB	0
	DW	DFPARM
;
	DB	ABB!NUM!4
	DB	'RATE'		;Repeat key rate
RRESP	DB	0
	DW	RPARM	
;
	DB	ABB!NUM!4
	DB	'WAIT'		;Delay before repeat
WRESP	DB	0
	DW	WPARM
;
	DB	ABB!FLAG!5
	DB	'QUERY'
	DB	0
	DW	QPARM
;
	NOP			;Note end of parm table
;
;
;	HEXDEC - Convert Hex Number to Decimal ASCII
;	A => 8-bit Hex Number to Convert
;	DE => Destination of ASCII characters
;
;
HEXDEC	PUSH	BC		;Save regs
	PUSH	HL
	PUSH	AF
;
;	Xfer number to HL
;
	LD	H,0		;Set HL = #
	LD	L,A
;
	LD	A,' '		;Character if leading 0
	LD	BC,100		;Set 10's power
	CALL	CVD1		;Convert to ASCII
	LD	BC,10
	CALL	CVD1
	LD	A,L		;Get remainder
	ADD	A,'0'		;Make ASCII and
	LD	(DE),A		;  stuff in buffer
;
	POP	AF		;Recover #
	POP	HL		;And other regs
	POP	BC
	RET
;
CVD1	PUSH	DE		;Save user buffer
	LD	E,A		;Save pad character
	LD	D,0FFH		;Init digit count to -1
	XOR	A
CVD2	INC	D		;Inc digit count and
	SBC	HL,BC		;  sub 10' power untill
	JR	NC,CVD2		;  underflow
	ADD	HL,BC		;Add back last sub
	LD	A,E		;Recover pad char
	LD	B,D		;Count to B
	POP	DE		;Recover buffer ptr
	LD	(DE),A		;Tempy store pad char
	INC	B		;See if char a 0
	DEC	B
	JR	Z,CVD3		;Go if so
	LD	A,B		;  else make digit ASCII
	ADD	A,'0'
	LD	(DE),A		;  and put in buffer
	LD	A,'0'		;Change the pad char
CVD3	INC	DE		;Bump buffer
	RET
;
RCHECK	LD	D,RMIN		;Rate minimum value
	JR	CHECK
DCHECK	LD	D,DMIN		;Wait minimum value
CHECK	LD	A,E		;Get number
	AND	7FH		;Keep positive
	CP	D		;Lowest allowed
	RET	C		;Too low
	CP	A		;Set Z if good value
	RET
;
GETIT	LD	HL,INBUF	;Key buffer
	LD	BC,3<8		;3 chars max
	@@KEYIN
	JP	C,$ABORT	;Quit if Break
;
;	DECHEX - Decimal ASCII to Hex
;	DE <= returns the Hex num
;	HL => points to the start of Dec asc string
;	A <= # of characters converted
;
;
DECHEX	LD	B,0		;Init counter to 0
	LD	D,B		;Init ret valu to 0
	LD	E,B
CVDEC	LD	A,(HL)		;P/u a character
	SUB	30H		;Make binary
	CP	10
	JR	NC,DONECON	;Leave when non-decimal found
	PUSH	HL
	LD	H,D
	LD	L,E		;Prev. total to HL
	ADD	HL,HL		;X2
	ADD	HL,HL		;X4
	ADD	HL,DE		;X5
	ADD	HL,HL		;X10
	EX	DE,HL		;Result back to DE
	ADD	A,E		;Add in newest digit
	LD	E,A
	LD	A,0
	ADC	A,D
	LD	D,A
	POP	HL		;Get buffer posn
	INC	HL
	INC	B		;Inc chars found
	JR	CVDEC		;  and continue next
;
DONECON	LD	A,B
	OR	A
	RET
INBUF	EQU	$
;
	END	BEGIN
