;12 Nov. 1982 2:17 pm PST (Friday)
; Changed communications to Mayflower to be compatible with new spec.

;  In the keyboard dispatch code, we do a get "RavenKeyboard.bca" or
;   .get "GnatKeyboard.bca", depending on the key pad being used.

;Turn on comments when done developing!!
	;;.getnolist "GnatHeader.bca";	comments to leave out of listing for now
	;.get "GnatHeader.bca";	comments to leave out of listing for now
.predefine "ADMPredefs.SR"
	.RDX  16
;	SYSTEM EQUATES
.get "GnatConstants.bca";	constant definitions
	;.getnolist "GnatConstants.bca";	constant definitions

	;.getnolist "GnatPreamble.bca"
.get "GnatPreamble.bca"
.LOC 400
INTHANDLE:
	DIF
	MVDRT	SAVET		;SAVE T REG
	MOVST			;MOVE STATUS REG TO T
	MVDRT	SR		;MOVE T TO SR SAVE REG

	Cal	Input		;refresh inputs so ZCrossing test works later

	LPI	Bank2
	MVIT	01
	ADD	WDTtimeout
	LCJ	WDTtimeout 4 DoChores

	MVI	WDTtimeout 00
	LPI	Bank1
	Movr	Rout3
	BT	WatchDT zeroWDT
	STB	WatchDT
	IOR	Rout3
	JMP	DoChores

zeroWDT:
	Clb	WatchDT
	AND	ROUT3

DoChores:
	LPI	Bank2
	MOVR	ROUT1
	MVI	ROUT1 0F8	;TURN OFF ALL OUTPUT STROBES
	AND	ROUT1		;TO AVOID SHADOWING
	OUT	ROUT1 OUT1 
	BT	0 DO1S
	BT	1 DOTENS	;THIRD BIT SET
DOLEDS:
	STB	LEDRTN		;SET THE FIRST STROBE BIT
	IOR	ROUT1
	MOVR	ROUT0		;GET LED INFO INTO T REG
	JMP	PUTOUTS
DO1S:	STB	LEDONE		;FIRST BIT SET:
	IOR 	ROUT1		;  SET THE SECOND STROBE BIT
	MOVR	DSPONES		;   GET TENS DISPLAY INFO
	JMP	PUTOUTS
DOTENS:
	STB	LEDTEN		;SECOND BIT SET:
	IOR	ROUT1		; SET THE THIRD STROBE BIT
	MOVR	DSPTENS		; GET TENS DISPLAY INFO

PUTOUTS:
	OUTT	OUT0		;OUTPUT THE NEW DISPLAY INFO
	OUT	ROUT1 OUT1	;THEN OUTPUT STROBE TO CHANNEL
	LPI	Bank1
	OUT	ROUT2 OUT2
	OUT	ROUT3 OUT3
	movr	Rout3
	cpl
	bt	Fuser DoKbd
	movr	MoreFlags
	bt	FuserToggle CycleFuser
	stb	FuserToggle			;here to leave fuser on (from rout3)
	ior	MoreFlags			;but remember we left fuser on.
	jmp	DoKbd

CycleFuser:
	clb	FuserToggle			;here to turn fuser off
	and	MoreFlags
	clb	Fuser				;These gymnastics save a scratch
	and	Rout3				; register.  We really wanted to just
	out	Rout3 Out3			; "AND" to the output but this machine
	stb	Fuser				; can't handle that.
	Ior	Rout3

DoKbd:	LPI	Bank2

	CAL	KEYBRD
	JMP	CheckOthers
;*********************************************
;
;    KEYBOARD READ ROUTINE
;
;*********************************************
;
;	ROW -- ROW INPUT
;	COL -- COLUMN INPUT
;	DSP -- DISPLACEMENT IN KEYBOARD TABLE
;	KBDREG -- DEBOUNCE COUNTER AND ENABLE/DISABLE BITS
;
KEYBRD:	Lpi	Bank2
	LCJ	KBDREG 0FF READ;	KBDREG = FF MEANS
	RFS				;KEYBOARD IS DISABLED
;
; COLUMN 1
READ:	MVI	DSP 0;			SET DISPLACEMENT FOR COLUMN 1
	CAL	INCOL1;			READ ADDRESS OF COLUMN 1
	CAL	MSBMSK;			MASK OFF MSB
	JCC NZ	DECODE;			IF NO ENTRY RECOGNIZED
;					PROCEED TO COLUMN 2
; COLUMN 2
	MVI	DSP 4;			SET DISPLACEMENT FOR COLUMN 2
	CAL	INCOL2;			READ ADDRESS OF COLUMN 2
	CAL	MSBMSK;			MASK OFF MSB
	JCC NZ	DECODE;			IF NO ENTRY RECOGNIZED
					;PROCEED TO COLUMN 3
; COLUMN 3
	MVI	DSP 8			;SET DISPLACEMENT FOR COLUMN 3
	CAL	INCOL3;			READ ADDRESS OF COLUMN 3
	CAL	MSBMSK;			MASK OFF MSB
	JCC NZ	DECODE;			IF NO ENTRY RECOGNIZED
					;PROCEED TO COLUMN 4
; COLUMN 4
	MVI	DSP 12;			SET DISPLACEMENT FOR COLUMN 4
	CAL	INCOL4;;			READ ADDRESS OF COLUMN 4
	CAL	MSBMSK;			MASK OFF MSB
	JCC NZ	DECODE;			IF NO ENTRY RECOGNIZED

; NO ENTRY MADE
	MVIT 03F;				CLEAR DEBOUNCE BITS 6 & 7
	AND	KBDREG;			TO SHOW KEY HAS BEEN RELEASED
NOTCLR: RFS;				RETURN (NO ENTRIES MADE)
INCOL4: NOP
	INPT 080
	RFS
;
INCOL3:  NOP
	INPT 040
	RFS
;
INCOL2: NOP
	INPT 020
	RFS
;
INCOL1: NOP
	INPT 010
	RFS

;*********************************************
;
;   DECODE INPUTTED COLUMN;
;
;*********************************************

DECODE:
	MOVR	KBDREG;			MAKE SURE KEY FROM LAST
					;ENTRY HAS BEEN RELEASED
	BT	Bit7 NOTCLR;			IF DEBOUNCE BITS ARE NOT CLEAR
					;WAIT FOR KEY TO BE RELEASED
; DETERMINE ROW
	MOVR COL;			PUT INPUTTED COLUMN IN COL
	MVI	ROW 0;			SET UP FOR ROW 1
	BT	BIT0 ROWFND;
	MVI	ROW 1;			SET UP FOR ROW 2
	BT	BIT1 ROWFND
	MVI	ROW 2;			SET UP FOR ROW 3
	BT	BIT2 ROWFND
	MVI	ROW 3;			SET UP FOR ROW 4
	BT	BIT3 ROWFND
;
; SHOULD NOT GET HERE
	RFS
;

ROWFND: MOVR ROW
	ADD	DSP;			ADD ROW TO COLUMN DISPLACEMENT
	MVIT  (KBDtblLoc&0FF)
	ADD	DSP;			ADD KEYBOARD TABLE ADDRESS TO DSP
	MOVR DSP
	MPM (HiAddr↑-8);		LOAD ADDRESS OF ENTRY (OR ADDRESS)
	MOVT	DSP;			AND STORE IT IN DSP

; DEBOUNCE
	STB	BIT6;			SET T TO 40 (BIT 6 OF T)
	ADD	KBDREG;			BITS 6 & 7 ARE USED FOR DEBOUNCE
	MOVR KBDREG
	BT BIT7 RECENT;			DEBOUNCE IS COMPLETE if BIT7 is set
	RFS;				otherwise wait for another round

;*******************************************
;
;   KEYBOARD ENTRY RECOGNIZED
;
;*******************************************
;
RECENT: Lpi	Bank2
	 MVIT 9
	 CMP	DSP
	 JCC N TabDispatch;		IF DISPLACEMENT IS >= 10
;						ENTRY IS A FUNCTION
	JMP NUMBER;
TabDispatch: JMP RealDispatch

;*********************************************
;
;   NUMBER ENTRY RECOGNIZED
;
;*********************************************
;
; CHECK FOR FIRST NUMBER ENTERED
;

NUMBER: MOVR	KBDREG
	BT	TENENT NOENT
	BT	ONEENT TRYTENS;	IF ONES ENTRY ALREADY MADE
	STB	ONEENT;		TRY FOR TENS ENTRY
	IOR	KBDREG;		ELSE
	CAL	ENTER0;		SET ONES ENTRY FLAG
	MVIT	0F0;		SET IST ZERO ENTRY FLAG
	AND	CPYSEL;		SEND KEY INFO TO SERVER
	JMP	DSPNUM;		IF OFF LINE
	 			;DISPLAY KEY ENTRY
; SECOND NUMBER
TRYTENS: STB	ONEENT;		DISABLE ONES ENTRY
	 IOR	KBDREG
	 CAL	ENTER0;		SET 2ND ZERO ENTRY FLAG
	 MOVR CPYSEL
	 ADD	CPYSEL
	 MOVR CPYSEL;		START SHIFTING ONES ENTRY
	 ADD	CPYSEL;		TO TENS
	 MOVR CPYSEL
	 ADD	CPYSEL
	 MOVR CPYSEL
	 ADD	CPYSEL
DSPNUM: MOVR DSP
	 IOR	CPYSEL;		DISPLAY KEY ENTRY
	 CAL	KEYCODE;	SEND KEY INFO TO SERVER
	 CAL	SELDSP;		DISPLAY IT TOO
NOENT:  RFS

MSBMSK: CPL;			RETURNED IN T (0 = ON)
	 MVI	COL 00F;
	 AND	COL;		MASK OFF BITS 4 THRU 7
	 RFS

;*************************************************************
; MACHINE FUNCTIONS  JUMPED TO FROM KEYBOARD
; SCAN IF THE RESPECTIVE FUNCTION SWITCH IS MADE
;  NOTE THAT ALL KYBD FUNCTION LABELS MUST START
;  AFTER ADDRESS 50FX to distinguish from numbers.
;*************************************************************
.Loc 0500
;the following instr (JIT) should be on same page as
;routines stop, test, onlineroutine, clear and noproutine
HiAddr = .
RealDispatch:
	 MOVR DSP;		ACTIVATE FUNCTION KEY
	 JIT

;*****************************************************
; KEYBOARD DECODE TABLE
; FUNCTIONS ARE ADDRESS INFORMATION, AND DIGITS ARE
; SEGMENT INFORMATION.
;*****************************************************

	;;;.get "RavenKeyboard.bca"
.get "GnatKeyboard.bca"	;use this for non-3300 kbd.

DspTblLoc = .
DSPTBL:	3F			;DIGIT 0
	06			;DIGIT 1
	5B			;DIGIT 2
	4F			;DIGIT 3
	66			;DIGIT 4
	6D			;DIGIT 5
	7D			;DIGIT 6
	07			;DIGIT 7
	7F			;DIGIT 8
	67			;DIGIT 9
	9E			;DIGIT J
	38			;DIGIT L
	39			;DIGIT C
	5E			;DIGIT D
	79			;DIGIT E
	71			;DIGIT F
;************************************
;
;   FUNCTION SWITCH FOUND
;
;************************************
OffLineRoutine:
	STB	OFFLINE		;set the off-line led
	IOR	ROUT0
	CLB	ONLINE		;deactivate the on-line led
	AND	ROUT0
	Clb	Diagnostics
	And	Rout0
NopRoutine:
	RFS
Clear:	Movr	Rout0		;Only allow clear switch to work when in Off-line
	cpl			;mode.
	BT	OFFLINE SendClear
	Mvi	CPYSEL 00		;two blanks.
	Cal	SelDsp		;display it.
	RFS;
SendClear:
	Lpi	Bank1
	Mvi	UartStat ClearKey	;send an "Clear" to the controller
	Stb	StatBit		;when the user hits the test key.
	IOR	Uflag
	Lpi	Bank2
	RFS
DiagnosticRoutine:
OnLineRoutine:
	STB	ONLINE		;set the on-line led
	IOR	ROUT0
	CLB	OFFLINE		;deactivate the off-line led
	AND	ROUT0
	Clb	Diagnostics
	And	Rout0
	RFS;
TEST:	Movr	Rout0		;only allow print switch to work when in Off-line
	cpl			;mode.
	BT	OFFLINE SendTest
	Clb	NtestSW
	And	Buttons
	RFS;
SendTest:
	Lpi	Bank1
	Mvi	UartStat EnterKey	;send an "Enter" to the controller
	Stb	StatBit			;when the user hits the test key.
	IOR	Uflag
	Lpi	Bank2
	RFS
STOP:	Lpi	Bank0
	Stb	02		;this is the coincidence flag
	IOR	Flg1		;the effect is to head for cycle down
	Lpi	Bank2
	RFS;
;************************************
;    KEYBOARD ENTRY IS DECODED      *
;    HERE FOR KEY STATUS TRANS-     *
;    MISSION TO SERVER.             *
;************************************
KEYCODE:
	lpi	bank1
	movr	uflag
	bt	DontTransmit Retn	;we don't want to send to uart
	Lpi	Bank2
	MOVR	ROUT0
	CPL
	BT	OnLine KEYRET
	MOVR	DSP
	MVI	TEMP6 030	;DECODE KEY INFO
	IOR	TEMP6
	MOVR	TEMP6
	Lpi	Bank1
	Movt	UartStat
	Stb	StatBit		; &TRANSMIT IT TO SERVER
	Ior	Uflag
KEYRET:
RETN:	Lpi	Bank2
	RFS
;*************************************
;    SUBROUTINE FOR DISPLAYING NUMERIC KEY ENTRY
;*************************************
SELDSP:
;;	Lpi	Bank2
;;	MOVR	ROUT0
;;	BT	OFFLINE RETN

DisplayIt:	Lpi	Bank2
	MOVR CPYSEL	;DISPLAY KEY ENTRY

	MOVT	TEMP4           ;SAVE CHARACTERS
	MOVT	TEMP5

	MVIT	00F           	;ISOLATE LOW ORDER CHARACTER
	AND	TEMP4
	MVIT	0F0
	AND	TEMP5
;T wants the within-256-byte displacement within the "page"
	MVIT	(DspTblLoc&0FF)	;GET SEGMENT PATTERN FOR
	ADD	TEMP4		;LOW ORDER CHARACTER
	MOVR	TEMP4		;i.e., T←Temp4
	MPM	(HIADDR↑-8)	;the "page number" of code
	MOVT	DSPONES
SF0:	MOVR TEMP5		;(we understand this better)
	CPL			;move high nibble of Temp5 to
	BT Bit7 TryBit6		; the low nibble
	Stb	Bit3
	IOR TEMP5
TryBit6:	MOVR TEMP5
	CPL
	BT Bit6 TryBit5
	Stb	Bit2
	IOR TEMP5
TryBit5:	MOVR TEMP5
	CPL
	BT Bit5 TryBit4
	Stb	Bit1
	IOR TEMP5
TryBit4:	MOVR TEMP5
	CPL
	BT Bit4 MskTmp
	Stb	Bit0
	IOR TEMP5
MskTmp:
	MVIT 0f
	AND TEMP5
SF1:	LPI	Bank2
	MVIT	(DspTblLoc&0FF)
	ADD	TEMP5
	MOVR	TEMP5		;GET SEGMENT PATTERN
	MPM	(HIADDR↑-8)	;FOR 10S DIGIT
	MOVT	DSPTENS

	MVIT 03F		;SURPRESS LEADING 0S
	CMP	DSPTENS
	JCC NZ OK
	MOVR ZEROFLG
	BT	1 OK
	MVI	DSPTENS BLANK
OK:	RFS

ENTER0:
	MOVR	ZEROFLG	;SET 1ST & 2ND ZERO ENTRY FLAGS
	BT	0 SECOND0		;IF FIRST BIT SET,
	STB	0
	IOR	ZEROFLG
	RFS
SECOND0:
	STB	1			;SET THE SECOND BIT
	IOR	ZEROFLG
	RFS
;We're jumped to here from DoChores Code after the keyboard is handled
CheckOthers:
	LPI	Bank1
	movr	uflag
	bt	prntbit save	;if online printing, forget test.
	movr	uflag2
	cpl
	bt	patternbit save	;test the copier print flag
	Lpi	Bank1		; output test pattern by leaving ros on for
	stb	0		;   'rosconstant' number of cycles
	add	testcounter
	mvit	rosconstant
	cmp	testcounter
	bt	n toggle		;go to 'toggle' if the counter has gone negative

save:	Lpi	Bank0
	Movr	IN1		;input the interupt register
	bt	ZCrossing lineintBranch
	lpi	Bank1
	Jmp	ruart

lineintBranch:
	jmp	lineint		;get to next page

TOGGLE:	movr ROUT2
	bt	LaserBeam complement
	stb	LaserBeam
	ior	ROUT2

toggle1:	clr
	movt	testcounter
	jmp	save

complement:	clb LaserBeam
	and	ROUT2
	jmp	toggle1

;****************************************************
;*****  Watch the following .LOC closely !!!!!!!!!!!!!
;****************************************************
.LOC 600
lineint:	Lpi	Bank0
	MVI	WDT 01		;SET WDT FLAG UPON INTERUPT 
				;RESET WATCH DOG TIMER.
	Lpi	Bank1
	movr	uflag
	outt	Trace4		;*** debugging
	bt	statbit suart
	bt	parbit cont
	bt	badcmdbit badcmd
	Inpt	Cmduart			;let's check to see if the uart has any info
	Bt	RXReady ruart	;receiver ready?
	JMP	RESTORE		;nope

suart:	out	uartstat datauart	;send status to uart
	clb	statbit		; clear status bit of uart flag
	and	uflag
	movr	uartstat		;**** debugging
	outt	Trace3		;***  debugging
	JMP	RESTORE

badcmd:	mvi	uartstat comrejun
	CLB	BADCMDBIT
	AND	UFLAG
	jmp	suart

cont:	mvi	uartstat comrejp
	mvit	050		;Do a soft reset and clear error flags
	outt	CmdUart
	mvit	05A		;Set the mode register to async, odd parity,
	outt	CmdUart	; parity enabled, 7 bits, 1 stop bit, baud rate X16.
	mvit	035		;set RTS flag, clear error flg, enable receiver,
	outt	CmdUart	; enable transmitter.
	inpt	DataUart	;dummy read.
	out	uartstat datauart
	jmp	restore

ruart:	INPT	CMDUART
	bt	RXReady DoRead	;see if there is data pending
	Jmp	restore	;false interrupt
DoRead:	inp	uartcom datauart 	 ;read uart data and store in uart com reg
	BT	PARITY parerr
	jmp	filterCmds	;returns to filterCmdsRet


RESTORE:
IntReturn:
	Lpi	Bank3		;this will be overridden with the MOVRS
	MOVR	SavetRel
	MOVRS	SaverRel	;MOVE REGISTER TO STATUS REGISTER
	EXI			;enable external interrupts
	RFS			;enable interrupts in background

filterCmdsRet:

;;;	IOR	uflag		don't do this here anymore
;;;	MOVR	UFLAG
	Movr	UartCom		;******debugging
	Outt	Trace2		;******debugging

	JMP	RESTORE

	
filterCmds:	
	Movr	UartCom		;******debugging
	Outt	Trace1		;******debugging

	clb	07
	and	uartcom
	mvit	FEEDBOT
	cmp	uartcom
	bt	nz filterCmds1
	stb	combit
	IOR	uflag
	jmp	filterCmdsRet

filterCmds1:	mvit	READSTAT
	cmp	uartcom
	bt	nz filterCmds2
	stb	combit
	IOR	uflag
	jmp	filterCmdsRet

filterCmds2:	mvit	FEEDTOP
	cmp	uartcom
	bt	nz filterCmds3
	mvi	uartcom FeedBot	;This gnat has only one paper tray
	stb	combit		; Change this logic if that changes.
	IOR	uflag
	jmp	filterCmdsRet

filterCmds3:	mvit	ISTACK	;Leave this undefined for now
	cmp	uartcom
	bt	nz filterCmds4
	jmp	filterCmdsRet

filterCmds4:	mvit	FEEDTOPSK
	cmp	uartcom
	bt	nz filterCmds5
	mvi	uartcom FeedBot	;This gnat has only one paper tray
	stb	combit		; Change this logic if that changes.
	IOR	uflag
	jmp	filterCmdsRet

filterCmds5:	mvit	FEEDBOTSK
	cmp	uartcom
	bt	nz filterCmds6
	mvi	uartcom FeedBot	;This gnat has only one paper tray
	stb	combit		; Change this logic if that changes.
	IOR	uflag
	jmp	filterCmdsRet

filterCmds6:	mvit	DisplayBlank	;PUT A BLANK ON THE DISPLAY.
	cmp	uartcom
	bt	nz filterCmds7
	mvit	Blank
	jmp	DisplayByte

filterCmds7:	mvit	DisplayF	;Display an 'F'.
	cmp	uartcom
	bt	nz filterCmds8
	mvit	0F
	jmp	DisplayByte

filterCmds8:
	Movr	UartCom
	Movt	UartTemp		;don't smash UartCom
	MVIT	0F0
	AND	UartTemp
	MVIT	30
	CMP	UartTemp
	BT	NZ IllegCmd
	Mvit	0F			;Save low 4 bits and replace the low
	And	UartCom		; order four bits of CPYSEL with them.
	Movr	UartCom		;This is implementing the Display Status

DisplayByte:
	Lpi	Bank2
	Movt	DSP			;Let the formatting routines shift if
	LPI	Bank1			; necessary.
	Stb	DontTransmit
	IOR	Uflag
	Lpi	Bank2
	Cal	Number
	LPI	Bank1
	Clb	DontTransmit
	And	Uflag
	Mvi	UartStat StatDisplayed	;tell server we did it.
	Stb	StatBit
	Ior	Uflag			;Cause the output routine to send it to
	Jmp	FilterCmdsRet	; Uart.

IllegCmd:
	STB	BADCMDBIT	;(UartCom AND F0) > 40
	IOR	UFLAG		; means it is a bad command.
	JMP	FILTERCMDSRET
	
PARERR:
	bt	statbit setpar	;do we want to send status to Server?
	jmp	Cont		;since there was no status pending for server,
				; tell the server of bad parity immediately.


setpar:	stb	parbit		;send status to server then on next time
	ior	uflag		; through the loop, send "Bad Parity"
	jmp	suart		;send the pending command for server 

;******************************************************
;**   END OF INTERRUPT CODE ***
;******************************************************
.loc	700
CHKPRNT:
	Lpi	Bank1
	MOVR	UFLAG			;GET UART FLAGS
	BT	COMBIT CHKCOM		; TEST COM FLAG
	Lpi	Bank0			;IF TRUE THEN GO CHKCOM
	RFS

CHKCOM:	CLB	07
	AND	UARTCOM
	MVIT	FEEDBOT			;TEST PRINT COMMAND
	CMP	UARTCOM
	BT	Z SETPRNT		;TRUE, GO SETPRNT
	MVIT	READSTAT
	CMP	UARTCOM
	BT	Z SENDSTAT
	Lpi	Bank0
	RFS

SENDSTAT:	Lpi	Bank0
	movr	IN0
	cpl
	bt	ZapTherm SENDWARMUP	;testing for warmup
	movr	flg1
	bt	03 SENDPRINTING		;JUST MEANS 'COPIER' IS printing
	Lpi	Bank1
	mvi	uartstat ready
	stb	statbit
	ior	uflag
	jmp	clrcomb			;enough with the commands

SENDWARMUP:
	Lpi	Bank1
	mvi	uartstat WARMUP
	stb	statbit
	ior	uflag
	jmp	clrcomb

;here if in test mode or printing a file
SENDPRINTING:
	Lpi	Bank1
	mvi	uartstat rntredy	;not ready for another feed command!
	stb	statbit
	ior	uflag
	jmp	clrcomb			;enough with the commands

SETPRNT:
	movr	uflag
	bt	prntbit onmulti
	STB	PRNTBIT			;SET PRNTBIT FLAG
	IOR	UFLAG

clrcomb:
	CLB	COMBIT			;CLEAR COM FLAG
	AND	UFLAG
	Lpi	Bank0
	RFS

ONMULTI:
	stb	multibit
	ior	uflag
	jmp	clrcomb
TimerInterrupt:
	RFI;

.END;