;******************************************************
; KEYBOARD SCAN DELAY IS PROVIDED TO INSURE
; KEY INPUT FILTERING PRIOR TO READ STROBE.
; THE ADDRESS OF THESE ROUTINES MUST START AT
; 0F0 FOR PROPER OPERATION.
;*****************************************************
;We're going to define the registers used in the handler here since this is merged-
;in code
;note that these reg's appear in bank 2!
.predefine "ADMPredefs.sr"

;;!!!!!!!!!!!!
;there is an OUTT DATARW to talk to server that is commented out for now!!!!!!
;& someone needs to load ROUT0 before its use too
;ROUT0 seems to be the data that turns on (at the least the ) on-line led
;ONLINE = 03 (also segment E), OFFLINE = 02 (also segment D);;!!!!!!!!!!!!
;***************************************************************
;  BITS 0-6 ARE MULTIPLEXED VIA PORT 1 FOR 1) FRONT
;  PANEL LEDS, 2) SEGMENTS FOR 1S DIGIT, AND 3) SEG-
;  MENTS FOR 10S DIGIT.
;***************************************************************

;These registers are for use in bank 2
	ROW		=	00
	COL		=	01
	DSP		=	02
	KBDREG		=	03
	CPYSEL		=	04;

	DSPTENS		=	05;
	DSPONES		=	06;
	ROUT0		=	07;
	TEMP4		=	08;?????
	TEMP5		=	09;
	TEMP6		=	0A;????
	ZEROFLG		=	0B;???
	ROUT1		=	0C;	MUST BE IN[8..F]
	SAVET		=	0D;
	SR			=	0E;
;Bits
	TENENT		=	01;
	ONEENT		=	00;
	OFFLINE		=	00;??????
	ONLINE		=	01;??????
	BLANK		=	00;
	ZCROSSING	=	05;
	EXTF		=	0C;	External interrupt mask
	LEDRTN		  =	0	
	LEDONE		  =	1
	LEDTEN 		 =	2

;Some Locations
	DATARW		=	08; THE UART
	INPUT1		=	01;INTERRUPT STATUS

;how about some constants, too?
	Bit0		=	00
	Bit1		=	01
	Bit2		=	02
	Bit3		=	03
	Bit4		=	04
	Bit5		=	05
	Bit6		=	06
	Bit7		=	07


.LOC 0
RESTART:
	JMP INTHAND;		POWER ON RESET
	JMP INTHAND;		EXERTNAL INTERRUPT HANDLER

.LOC	0F0

INCOL4: NOP
	INPT 080
	RFS
;
INCOL3:  NOP
	INPT 040
	RFS
;
INCOL2: NOP
	INPT 020
	RFS
;
INCOL1: NOP
	INPT 010
	RFS
	 
;*********************************************
;
;    KEYBOARD READ ROUTINE
;
;*********************************************
;
;	ROW -- ROW INPUT
;	COL -- COLUMN INPUT
;	DSP -- DISPLACEMENT IN KEYBOARD TABLE
;	KBDREG -- DEBOUNCE COUNTER AND ENABLE/DISABLE BITS
;
KEYBRD: 	LPI	2
	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)

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

DECODE: CLB	BIT6;			MAKE SURE KEY FROM LAST
	CMP	KBDREG;			ENTRY HAS BEEN RELEASED
	JCC N	NOTCLR;			IF DEBOUNCE BITS ARE NOT CLEAR
					;WAIT FOR KEY TO BE RELEASED
; DETERMINE ROW
	MOVT 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
	CLB	BIT6;			SET T TO BF
	CMP	KBDREG
	JCC N RECENT;			IF BITS 6 & 7 ARE NOT SET
	RFS;				DEBOUNCE IS NOT COMPLETE

;*******************************************
;
;   KEYBOARD ENTRY RECOGNIZED
;
;*******************************************
;
RECENT: LPI	2
;;;	 MVIT 10
	 MVIT 9
	 CMP	DSP
	 JCC N TabDispatch;		IF DISPLACEMENT IS >= 10
;						ENTRY IS A FUNCTION
;;;	 JGE	NUMBER;		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;		TOENS
	 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 0180 AS THIS DISTINGUISHES
;  FROM NUMERIC KEYS.
;*************************************************************
;
;
;
.LOC 0200
RealDispatch:
	 MOVR DSP;		ACTIVATE FUNCTION KEY
	 JIT

HiAddr = .
;***************************
;   OFF LINE FUNCTION
;   SUBROUTINE
;***************************
OffLineRoutine:	MOV      T,ROUT0
         JT       ONLINE,TESTERKEY
         STB      ONLINE
         IOR      ROUT0,T
TESTERKEY:
         JMP      TESTKEY
;

;************************************
;
;   FUNCTION SWITCH FOUND
;
;************************************

;************************************
;
;   NO ACTION FUNCTION KEY
;
;************************************

NOACTN:	RFS
Clear:	RFS;
OnLineRoutine:	RFS;
TEST:	RFS;
;*****************************************************
; KEYBOARD DECODE TABLE
; FUNCTIONS ARE ADDRESS INFORMATION, AND DIGITS ARE
; SEGMENT INFORMATION.
;*****************************************************
KBDtblLoc = .
KBDTBL:	08			;EIGHT
	05			;FIVE
	Clear-HiAddr		;CLEAR
	OffLineRoutine-HiAddr	;OFFLINE - SPARE
	07			;SEVEN
	04			;FOUR
	00			;ZERO
	OnLineRoutine-HiAddr	;ON LINE
	06			;SIX
	03			;THREE
	09			;NINE
	TEST-HiAddr		;TEST
	01			;ONE
	02			;TWO
	OffLineRoutine-HiAddr	;OFF LINE
	OffLineRoutine-HiAddr	;OFF LINE

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

;***********************************
; Start a new story here
;***********************************
;************************************
;
;    KEYBOARD ENTRY IS DECODED      *
;    HERE FOR KEY STATUS TRANS-     *
;    MISSION TO SERVER.             *
;                                   *
;************************************
KEYCODE:
;;;	LPI	1
	MOVR	ROUT0
	BT	OFFLINE KEYRET	;IF ON-LINE MODE
;;;;	LPI	00
	MVI	CPYSEL 00	;DO NOT STORE KEY INFO
	MOVR	DSP
	LPI	2
	MVI	TEMP6 030	;DECODE KEY INFO
	IOR	TEMP6
	MOVR	TEMP6
;;	OUTT	DATARW		; &TRANSMIT IT TO SERVER
KEYRET:;;;;	LPI	0
RETN:	RFS			;ELSE

;*************************************
;
;    SUBROUTINE FOR DISPLAYING
;    NUMERIC KEY ENTRY DURING
;    OFF LINE TEST 1 MODE
;*************************************
;
SELDSP: ;;;;;	LPI	1
	 MOVR	ROUT0
	 BT	ONLINE RETN
;;;;;	 LPI	0	;IF OFF LINE ACTIVE
	 MOVR CPYSEL	;DISPLAY KEY ENTRY
;;	JMP	DSPLY
;**************************************************************
;********ROUTINE TO PUT A CHARACTER ON THE DISPLAY*************
;**************************************************************
;
DSPLY:
	LPI	0
	MOVT	TEMP4           ;SAVE CHARACTERS
	MOVT	TEMP5

	MVIT	00F           	;ISOLATE LOW ORDER CHARACTER
	AND      TEMP4

	CPL				;ISOLATE HIGH ORDER
	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

SFO:	MVIT 00F			;SET UP LOOP
	CMP      TEMP5	;TO COUNTER #
;this machine doesn't have a JGE instr, so simulate it.
	JCC N SF0A		;IN HIGH ORDER
	JMP SF1 

SF0A:	MVIT 0F0		;a -16 in 2's compliment
	ADD	TEMP5		;ACCUMMULATE #
	STB	0			;IN LOW ORDER
	ADD	TEMP5
	JMP	SFO

SF1:	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

;**************************************************************
;*****  INTERRUPT HANDLER ROUTINE, RIGHT NOW ONLY CARES ABOUT *
;**************** ZERO-CROSSING CASE  *************************
INTHAND:
	MOVDT	SAVET		;SAVE T REG
	MOVST			;MOVE STATUS REG TO T
	MOVT	SR		;MOVE T TO SR SAVE REG
	LPI	2
	INPT	INPUT1
	BT ZCROSSING ZeroCrossing;
INTRETURN:
	LPI	2
	MOVR	SAVET
	MOVRS	SR		;MOVE REGISTER TO STATUS REGISTER
	RFI

ZeroCrossing:
	DIM	EXTF			;disable external interrupts
	MOVR	ROUT1
	MVI	ROUT1 0F8		;TURN OFF ALL OUTPUT STROBES
	AND	ROUT1			;TO AVOID SHADOWING
	OUT	OUT1 ROUT1
	BT	0 DO1S		;CASE
	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	DSPTONES		;   ELSE:  GET TENS DISPLAY INFO
	JMP	PUTOUTS
DOTENS:
	STB	LEDTEN		;SECOND BIT SET:
	IOR	ROUT1			;  SET THE THIRD STROBE BIT
	MOVR	DSPTENS		;  ELSE: GET TENS DISPLAY INFO

PUTOUTS:				;RESTORE T
	OUTT	OUT0			;OUTPUT THE NEW DISPLAY INFO
	OUT	OUT1 ROUT1		;THEN OUTPUT STROBE TO CHANNEL
;;;	OUT	OUT2 ROUT2;	IN ORIGINAL CODE, NOT HERE

	CAL	KEYBRD
RESTORE:
	JMP INTRETURN
;******************************************************
;**   END OF INTERRUPT CODE ***
;******************************************************
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