TITLE 'MT-70 KEYBOARD FIRMWARE USING 8048 (Rev 3.4 13_Dec_84)' ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; ;---------------------------------------------------------------------- ; Index (13_Dec_84) ;------------------ ; ; UpDate Log ; Port Information ; System Equates ; System Ram Definitions ; ; POWER Power Up Routine ; MAIN Main Section of Code ; RCV RECEIVE DATA FROM HOST ; DPR DATA PROCESSOR ; SENDID SEND ID NUMBER ; ENCLK ENABLE KEY CLICK ; DISCLK DISABLE KEY CLICK ; ENCAP ENABLE CAPS LOCKED ; DISCAP DISABLE CAPS LOCKED ; ENRPT ENABLE AUTO REPEAT ; DISRPT DISABLE AUTO REPEAT ; ENOFF ENABLE KEY PAD LED ; DSOFF DISABLE KEY PAD LED ; ENLCK ENABLE KEYBOARD LOCK ; DISLCK DISABLE KEYBOARD LOCK ; GOBELL GO RING BELL ; RINGBL RING BELL ; ; KBSCAN KEYBOARD SCAN ; INCCNT Increment Counter ; CLRCNT Clear the Counter Value ; GETCNT Get the Counter Value ; BMPY BINARY MULTIPLY ; LOWUP CONVERT FROM LOWER CASE TO UPPER CASE ; TOCTL CONVERT TO CONTROL CHARACTER ; PROC PROCESS KEY ; XMT TRANSMIT DATA TO HOST ; KEYCLK KEY CLICK ; FFCLK1 Flip-Flop Clock (Turns the Led On/Off) ; FFCLK0 Flip-Flop Clock (Pulses the Flip-Flop Clock) ; ; TBSHT TABLE UPPER CASE ; TBLOW TABLE LOWER CASE ; TBLOWT LOWER CASE TABLE ; TBSHTT UPPER CASE TABLE PAGE 60 ;---------------------------------------------------------------------- ; Update Log ;----------- ; Giora Bar-Hai March 18,1984 ; Howard Fullmer May 16,1984 ; Howard Fullmer June 19,1984 ; John Zalabak December 13 1984 ; ;---------------------------------------------------------------------- ; Port Information ;----------------- ; ; PORT 1 (0-5) RECEIVES THE 6 BIT RESULT FROM THE KEYBOARD SCAN ; PORT 1.6 IS USED AS A CLOCK FOR THE 74LS175 (D-FF) ; PORT 1.7 IS USED TO COMMUNICATE TO THE HOST. (OUTPUT). ; PORT 2 RECEIVES INPUTS FROM CONTROL & SHIFT KEYS (P2.2,P2.3) ; IT OUTPUTS TO CONTROL THE LED INDICATORS & ENABLE THE BELL ; IT ALSO OUTPUTS THE 4 BIT ENCODED VALUE TO SCAN THE KEYBOARD ; (P2.4-P2.7). PAGE ;---------------------------------------------------------------------- ; Equates ;-------- ; ;KEYBOARD IDENTIFICATION NUMBER IDNUM EQU 10011000B ;FORM OF NUMBER IS 10011xxx ;CONSTANTS TRUE EQU 0FFH FALSE EQU 00H ;REPEAT CONSTANTS INITDLY EQU 120 ;~450MS. INITIAL DELAY BEFORE REPEAT MINRPT EQU 26 ;~100MS. MINIMUM REPEAT SPEED MAXRPT EQU 7 ;~30MS. MAXIMUM REPEAT SPEED ;DEBOUNCE CONSTANTS (In units of ~3.5 ms.) UPBOUNC EQU 7 ;24.5ms key release delay DNBOUNC EQU 4 ;14ms key assert delay ;DEFINE BITS WITHIN LEDSTA CAPLKF EQU 10000000B ;CAPS LOCKED FLAG (0=LOCKED) BELLF EQU 01000000B ;BELL FLAG (1=RINGING BELL) KPMF EQU 00100000B ;KEY PAD MODE FLAG (0=LED ON) CLICKF EQU 00010000B ;KEY CLICK FLAG (1=ENABLED) SHFTON EQU 00001000B ;SHIFT IS DOWN FLAG (0=DOWN) CNTLON EQU 00000100B ;CONTROL IS DOWN FLAG (0=DOWN) REPTF EQU 00000010B ;AUTO REPEAT FLAG (1=REPEAT) LOCKF EQU 00000001B ;KEYBOARD LOCKED FLAG (1=LOCKED) ;MASK WORDS CONTM EQU 00000100B ;MASK FOR CONTROL KEY SHFTM EQU 00001000B ;MASK FOR SHIFT KEY OUT0M EQU 01111111B ;MASK OUT GOING DATA LOW OUT1M EQU 10000000B ;MASK OUT GOING DATA HIGH KPM0M EQU 11011111B ;KEY PAD MODE LOW KPM1M EQU 00100000B ;KEY PAD MODE HIGH CAPS0M EQU 01111111B ;CAPS LOCKED OUTPUT LOW CAPS1M EQU 10000000B ;CAPS LOCKED OUTPUT HIGH BELL0M EQU 10111111B ;BELL OUTPUT LOW BELL1M EQU 01000000B ;BELL OUTPUT HIGH FFCK0M EQU 10111111B ;D-FF CLK LOW FFCK1M EQU 01000000B ;D-FF CLK HIGH PAGE ;---------------------------------------------------------------------- ; FORMAT OF DATA SENT ;-------------------- ; a = SEVEN BIT ASCII DATA ; s = SHIFT KEY STATUS (1 = DEPRESSED) ; c = CONTROL KEY STATUS (1 = DEPRESSED) ; X = DATA ; B = BINARY ; ; 0aaaaaaaB ;ASCII DATA FROM KEYS ; NULL EQU 00000000B ;NULL BELL EQU 00000111B ;BELL BS EQU 00001000B ;BACKSPACE LF EQU 00001010B ;LINE FEED CR EQU 00001101B ;CARRIAGE RETURN ESC EQU 00011011B ;ESCAPE DEL EQU 01111111B ;DELETE ; ALL KEYS THAT NEED AN ACCESS CODE HAVE BIT 6 SET IN THE MATRIX. ; ALL KEYS NOT TO BE AUTO REPEATED HAVE BIT 5 SET IN THE MATRIX. ; ; 1scXXXXXB ; OTHER DATA TO BE DEFINED ; UPA EQU 10000000B ;UP ARROW DWNA EQU 10000001B ;DOWN ARROW LFTA EQU 10000010B ;LEFT ARROW RGHTA EQU 10000011B ;RIGHT ARROW HOMECLR EQU 10000100B ;HOME CLEAR ERASE EQU 10000101B ;ERASE KEY (NOT USED) HELP EQU 10000110B ;HELP KEY SCROLL EQU 10000111B ;NO SCROLL KEY SETUP EQU 10101000B ;SET UP KEY BREAK EQU 10001001B ;BREAK KEY (NOT USED) CAPLCK EQU 10101010B ;CAPS LOCK KEY TAB EQU 10001011B ;TAB KEY SPACE EQU 10001100B ;SPACE BAR POWERUP EQU 10001111B ;KEYBOARD POWER UP KP0 EQU 10010000B ;KEYPAD 0 KP1 EQU 10010001B ;KEYPAD IL/1 KP2 EQU 10010010B ;KEYPAD 2 KP3 EQU 10010011B ;KEYPAD DL/3 KP4 EQU 10010100B ;KEYPAD 4 KP5 EQU 10010101B ;KEYPAD 5 KP6 EQU 10010110B ;KEYPAD 6 KP7 EQU 10010111B ;KEYPAD IC/7 KP8 EQU 10011000B ;KEYPAD 8 KP9 EQU 10011001B ;KEYPAD DC/9 KPDEC EQU 10011010B ;KEYPAD DECIMAL POINT KPENT EQU 10011011B ;KEYPAD ENTER KPDASH EQU 10011100B ;KEYPAD DASH KPCOM EQU 10011101B ;KEYPAD COMMA ACCESS EQU 10011111B ;ACCESS CODE FN1 EQU 11000000B ;FUNCTION KEY #1 FN2 EQU 11000001B ;FUNCTION KEY #2 FN3 EQU 11000010B ;FUNCTION KEY #3 FN4 EQU 11000011B ;FUNCTION KEY #4 FN5 EQU 11000100B ;FUNCTION KEY #5 FN6 EQU 11000101B ;FUNCTION KEY #6 FN7 EQU 11000110B ;FUNCTION KEY #7 FN8 EQU 11000111B ;FUNCTION KEY #8 FN9 EQU 11001000B ;FUNCTION KEY #9 FN10 EQU 11001001B ;FUNCTION KEY #10 FA EQU 11001010B ;FUNCTION KEY FA FB EQU 11001011B ;FUNCTION KEY FB FC EQU 11001100B ;FUNCTION KEY FC FD EQU 11001101B ;FUNCTION KEY FD ; 11011XXXB ;ID NUMBER (ACTUALLY 10011XXXB) ;---------------------------------------------------------------------- ; FORMAT OF DATA RECEIVED ;------------------------ ; XSNDID EQU 10000000B ;SEND ID NUMBER XRNGBL EQU 10000001B ;RING BELL XENCLK EQU 10000010B ;ENABLE KEY CLICK XDSCLK EQU 10000011B ;DISABLE KEY CLICK XENCAP EQU 10000100B ;ENTER CAPS LOCKED MODE XDSCAP EQU 10000101B ;EXIT CAPS LOCKED MODE XENRPT EQU 10000110B ;ENTER AUTO REPEAT MODE XDSRPT EQU 10000111B ;EXIT AUTO REPEAT MODE XENLCK EQU 10001000B ;ENTER KEYBOARD LOCKED MODE XDSLCK EQU 10001001B ;EXIT KEYBOARD LOCKED MODE XENOFF EQU 10001010B ;ENTER OFF LINE MODE XDSOFF EQU 10001011B ;EXIT OFF LINE MODE PAGE ORG 20H ;---------------------------------------------------------------------- ; DEFINE INTERNAL RAM (13_Dec_84) ;-------------------------------- ; 1) *>>>> WARNING <<<<* there are 16 locations used by the keyboard ; scan routine located just below BITMAP. This means that your stack ; space has been cut in half (i.e. a 4 level stack NOT 8). ; BITMAP: DS 16 ;BITMAP FOR KEYBOARD KBOLD: DS 1 ;LAST KEY PRESSED ON KEYBOARD KBDLY: DS 1 ;DELAY COUNT FOR KEYBOARD KBRLD: DS 1 ;RELOAD VALUE FOR AUTO REPEAT KBENC: DS 1 ;KEYBOARD ENCODED VALUE TEMP1: DS 1 ;TEMPORARY #1 ROWNUM: DS 1 ;KEYBOARD ROW NUMBER LEDSTA: DS 1 ;LED & OTHER STATUS BELCNT: DS 1 ;BELL DELAY COUNT TEMP2: DS 1 ;TEMPORARY LOCATION USED IN XMT ROUTINE PAGE ORG 0000H ;====================================================================== ; Power Up Routine ;================= ; THIS SECTION OF CODE IS EXECUTED WHENEVER THE KEYBOARD IS ; POWERED UP OR RESET. THE BELL IS TURNED OFF, ALL LEDS ARE ; TURNED OFF, ALL OF RAM IS CLEARED, ALL FLAGS ARE SET, AND ; THE HOST IS SIGNALED THAT THE KEYBOARD JUST RESET. ; POWER: MOV A, #00111111B OUTL P1, A ;INIT PORT 1 FIRST MOST IMPORTANT CLR A ;CLEAR ALL OF RAM MOV R0, #16 ;FIRST LOCATION. MOV R1, #48 ;48 BYTES OF MEMORY. POWER3: MOV @R0, A ;CLEAR IT INC R0 ;NEXT LOCATION DJNZ R1, POWER3 ;UNTIL DONE MOV R0, #LEDSTA ;LED STATUS MOV A, #10111110B MOV @R0, A ;STORE LED STATUS OUTL P2, A ;INIT PORT 2 CALL FFCLK ;PULSE FLIP-FLOP MOV R1, #20 ;DELAY A GOOD 50 MSEC POWER1: MOV R0, #0 POWER2: DJNZ R0, POWER2 DJNZ R1, POWER1 MOV R0, #TEMP1 MOV @R0, #POWERUP CALL XMT ;SIGNAL POWERUP PAGE ;====================================================================== ; Main Section of Code ;===================== ; THIS MAIN LOOP CHECKS FOR ANY DATA FROM THE HOST. IF THERE ; IS DATA THEN IT IS PROCESSED. IF THE KEYBOARD IS NOT LOCKED ; THEN IT IS SCANNED DOING ALL N-KEY ROLL OVER, AUTO REPEAT, AND ; ANY OTHER SPECIAL FUNCTIONS. ALL KEYS TO BE TRANSMITTED ARE ; PROCESSED BY THE SCAN ROUTINE. IF THE BELL IS CURRENTLY ; RINGING THEN A CHECK TO STOP THE BELL IS MADE. ; MAIN: CALL RCV ;RECEIVE ANY MESSAGE FROM HOST JC MAIN1 ;IF DATA THEN CALL DPR ;PROCESS DATA MAIN1: MOV R0, #LEDSTA ;GET STATUS BYTE MOV A, @R0 JB0 MAIN2 ;IF KEYBOARD LOCKED THEN JUMP CALL KBSCAN ;SCAN KEYBOARD AND PROCESS KEYS MAIN2: MOV R0, #LEDSTA ;GET STATUS FLAG MOV A, @R0 XRL A, #BELLF ;INVERT BELL FLAG JB6 MAIN ;IF NOT RINGING BELL THEN JUMP CALL GOBELL ;DO THE BELL STUFF MAIN3: JMP MAIN PAGE ;====================================================================== ; RCV - RECEIVE DATA FROM HOST ;============================= ; TAKES DATA FROM THE HOST AND PROCESSES IT IF AVAILABLE ; ; ENTRY NONE ; EXIT (A) = BYTE RECEIVED IF AVAILABLE ; 'C' = SET IF NO DATA, CLEAR OTHERWISE ; USES ALL ; RCV: JT1 RCV1 ;IF NO DATA THEN CLR C CPL C ;SET CARRY AND RETURN RET RCV1: CLR A ;INITIALIZE RECEIVING BYTE MOV R1, #8 ;INDEX COUNTER FOR 8 BITS RCVLP: ORL P1, #OUT1M ;REQUEST DATA BY SETTING HIGH CALL RCVDLY ;DELAY 500 USEC CLR C ;INIT CARRY LOW JT1 RCV2 ;IF INPUT IS LOW THEN CPL C ;SET CARRY RCV2: RRC A ;ROTATE DATA IN ANL P1, #OUT0M ;DATA RECEIVED BY SETTING LOW CALL RCVDLY ;DELAY 500 USEC DJNZ R1, RCVLP ;UNTIL ALL 8 BITS CALL RCVDLY ;WAIT FOR HOST TO FINISH CLR C ;FLAG OK AND RETURN RET RCVDLY: MOV R4, #50 RCVDL1: DJNZ R4, RCVDL1 ;DELAY AT LEAST 500 USEC RET PAGE ;====================================================================== ; DPR - DATA PROCESSOR ;===================== ; PROCESSES ALL DATA FROM THE HOST. ; ; ENTRY (A) = BYTE FROM HOST ; EXIT NONE ; USES ALL ; DPR: MOV R0, #TEMP1 ; SAVE VALUE TO PROCESS MOV @R0, A MOV R1,#LEDSTA ;POINTER TO STATUS BYTE ADD A, #-(XSNDID) JZ SENDID ; IF SEND ID NUMBER MOV A, @R0 ADD A, #-(XRNGBL) JZ RINGBL ;ELSE IF RING BELL MOV A, @R0 ADD A, #-(XENCLK) JZ ENCLK ;ELSE IF ENABLE KEY CLICK MOV A, @R0 ADD A, #-(XDSCLK) JZ DISCLK ;ELSE IF DISABLE KEY CLICK MOV A, @R0 ADD A, #-(XENCAP) JZ ENCAP ;ELSE IF ENABLE CAPS LOCKED MOV A, @R0 ADD A, #-(XDSCAP) ;ELSE IF DISABLE CAPS LOCKED JZ DISCAP MOV A, @R0 ADD A, #-(XENRPT) JZ ENRPT ;ELSE IF ENABLE REPEAT FUNCTION MOV A, @R0 ADD A, #-(XDSRPT) JZ DISRPT ;ELSE IF DISABLE REPEAT FUNCTION MOV A, @R0 ADD A, #-(XENOFF) JZ ENOFF ;ELSE IF ENABLE KEY PAD MODE MOV A, @R0 ADD A, #-(XDSOFF) JZ DISOFF ;ELSE IF DISABLE KEY PAD MODE MOV A, @R0 ADD A, #-(XENLCK) JZ ENLCK ;ELSE IF ENABLE KEYBOARD LOCK MOV A, @R0 ADD A, #-(XDSLCK) JZ DISLCK ;ELSE IF DISABLE KEYBOARD LOCK RET ;ELSE RETURN ;---------------------------------------------------------------------- ; SENDID - SEND ID NUMBER ;------------------------ ; SENDS THE ID NUMBER OF THIS KEYBOARD. THIS COULD ; BE USEFUL FOR LATER TERMINALS TO DETERMINE WHAT FUNCTIONS ; ARE AVAILABLE ON THE KEYBOARD. ; SENDID: MOV R0, #TEMP1 MOV A, #ACCESS MOV @R0, A CALL XMT ;OUTPUT THE ACCESS CODE MOV A, #IDNUM MOV @R0, A JMP XMT ;OUTPUT ID NUMBER AND RETURN ;---------------------------------------------------------------------- ; RINGBL - RING BELL ;------------------- ; STARTS THE BELL RINGING IN BACKGROUND SO THAT ; KEYBOARD SCANNING MAY STILL TAKE PLACE. IT USES THE TIMER ; AND TIMER OVERFLOW FLAG TO DO THIS. ; RINGBL: MOV A, #BELL1M ;START BELL RINGING CALL FFCLK1 ;PULSE THE FLIP FLOP MOV R0, #BELCNT MOV @R0, #8 ;SET BELL COUNT MOV A, #-255 MOV T, A ;SET TIMER DELAY STRT T ;AND START TIMER RET PAGE ;---------------------------------------------------------------------- ; ENCLK - ENABLE KEY CLICK ;------------------------- ; ENABLES KEY CLICK BY SETTING A FLAG FOR LATER USE BY BACKGROUND JOBS. ; ENCLK: MOV A, @R1 ORL A,#CLICKF ;FLAG KEY CLICK TRUE MOV @R1, A RET ;---------------------------------------------------------------------- ; DISCLK - DISABLE KEY CLICK ;--------------------------- ; DISABLE KEY CLICK BY SETTING A FLAG FOR LATER USE BY BACKGROUND JOBS. ; DISCLK: MOV A, @R1 ANL A,#(NOT CLICKF) ;FLAG KEY CLICK FALSE MOV @R1, A RET ;---------------------------------------------------------------------- ; ENCAP - ENABLE CAPS LOCKED ;--------------------------- ; ENABLES CAPS LOCKED MODE BY SETTING A FLAG FOR LATER ; USE BY BACKGROUND JOBS. ; ENCAP: MOV A, #CAPS0M ;LIGHT CAPS LOCKED LED JMP FFCLK0 ;PULSE FLIP-FLOP & RETURN ;---------------------------------------------------------------------- ; DISCAP - DISABLE CAPS LOCKED ;----------------------------- ; DISABLES CAPS LOCKED MODE BY SETTING A FLAG FOR LATER ; USE BY THE BACKGROUND JOBS. ; DISCAP: MOV A, #CAPS1M ;TURN OFF CAPS LOCKED LED JMP FFCLK1 ;PULSE FLIP-FLOP & RETURN. PAGE ;---------------------------------------------------------------------- ; ENRPT - ENABLE AUTO REPEAT ;--------------------------- ; ENABLES AUTO REPEAT BY SETTING A FLAG FOR LATER ; USE BY THE BACKGROUND JOBS. ; ENRPT: MOV A, @R1 ORL A, #REPTF ;ENABLE AUTO REPEAT FLAG MOV @R1, A RET ;---------------------------------------------------------------------- ; DISRPT - DISABLE AUTO REPEAT ;----------------------------- ; DISABLES AUTO REPEAT BY SETTING A FLAG FOR LATER ; USE BY THE BACKGROUND JOBS. ; DISRPT: MOV A, @R1 ANL A, #(NOT REPTF) ;DISABLE AUTO REPEAT FLAG MOV @R1, A RET ;---------------------------------------------------------------------- ; ENOFF - ENABLE KEY PAD LED ;--------------------------- ; ENOFF: MOV A, #KPM0M ;TURN ON KEY PAD LED JMP FFCLK0 ;PULSE FLIP-FLOP & RETURN. ;---------------------------------------------------------------------- ; DSOFF - DISABLE KEY PAD LED ;---------------------------- ; DISOFF: MOV A, #KPM1M ;TURN OFF KEY PAD LED JMP FFCLK1 ; PULSE FLIP-FLOP & RETURN PAGE ;---------------------------------------------------------------------- ; ENLCK - ENABLE KEYBOARD LOCK ;----------------------------- ; TURNS OFF ANY KEYBOARD SCANNING AND TURNS OFF THE ; KEYBOARD LOCKED LED. ; ENLCK: MOV A, @R1 ORL A, #LOCKF ;FLAG THAT KEYBOARD IS LOCKED MOV @R1, A RET ;---------------------------------------------------------------------- ; DISLCK - DISABLE KEYBOARD LOCK ;------------------------------- ; TURNS OFF THE KEYBOARD LOCKED FEATURE ; DISLCK: MOV A, @R1 ANL A, #(NOT LOCKF) ;FLAG KEYBOARD NOT LOCKED MOV @R1, A RET ;====================================================================== ; GOBELL - GO RING BELL ;====================== ; CHECKS THE BELL FROM THE BACKGROUND JOB. IF THE ; TIMER HAS OVERFLOWED THEN IT IS KNOWN THAT THE BELL SHOULD BE DONE. ; GOBELL: JTF GOBEL1 ;IT TIME IS NOT UP THEN RET ;RETURN GOBEL1: MOV A, #-255 ;LOAD NEW DELAY TIME MOV T, A MOV R0, #BELCNT MOV A, @R0 DEC A ;DECREMENT BELL DELAY COUNT MOV @R0, A JNZ GOBRET ;IF DONE RINGING THEN STOP TCNT ;STOP TIMER MOV A, #BELL0M ;STOP BELL FROM RINGING JMP FFCLK0 ;PULSE THE FF & RETURN GOBRET: RET PAGE ORG 0100H ; *** NEW PAGE BOUNDRY *** ;====================================================================== ; KBSCAN - KEYBOARD SCAN ;======================= ; AUTO REPEAT, AND N-KEY ROLL OVER. IF A KEY SHOULD BE OUTPUTED ; IT IS SENT TO THE HOST ; ; ; ENTRY NONE ; EXIT NONE ; USES R0 GENERAL WORK POINTER ; R1 POINTER TO KEYBOARD BIT MAP ; R2 SCAN ROW NUMBER ; R3 SCAN COLUMN NUMBER ; R4 TEMPORARY VARIABLE #1 ; R5 TEMPORARY VARIABLE #2 ; R6 FLAG IF ANY KEY IS DOWN ; R7 FLAG IF SAME KEY IS DOWN ; ;SETUP FOR SCAN LOOP KBSCAN: MOV R6, #FALSE ;ASSUME AND SET NO KEY IS DOWN MOV R7, #TRUE ;ASSUME AND SET SAME KEY IS DOWN MOV A, #00001111B ;INITIALIZE SCAN ROW NUMBER OUTL P2,A MOV R0, #ROWNUM MOV @R0, #0 MOVX @R0,A ;WR PULSE TO STROBE 14515 DECODER ;(NOT USED WHEN 74159 IS CONNECTED) MOV R1, #BITMAP ; SET POINTER TO KB BIT MAP ADDRESS MOV R2, #16 ; SET INDEX COUNTER TO 16 COLUMNS ;MAIN KEYBOARD SCAN LOOP KBLP1: ORL P2, #(CONTM + SHFTM) IN A, P2 ;READ FOR SHIFT KEY & CONTROL KEY ANL A, #(SHFTM + CONTM) MOV R4, A ;MASK FOR SHIFT & CONTROL KEY MOV R0, #LEDSTA MOV A, @R0 ANL A, #NOT(SHFTM + CONTM) ORL A, R4 MOV @R0, A ;SET SHIFT & CONTROL DOWN FLAGS IN A, P1 ;READ KEYBOARD MATRIX ORL A, #11000000B ;CHECK BITS 0-5 ONLY CPL A MOV R5,A ;SAVE SCAN INFO JZ NOKEY MOV R6, #TRUE ;FLAG THAT A KEY IS DOWN NOKEY: MOV A,@R1 ;GET KB BIT MASK ANL A,#0C0H ;MASK OUT BOUNCE BITS JZ NOUP ;JUMP IF NO BOUNCE BITS CALL INCCNT ;INCREMENT ROW BOUNCE COUNT MOV A, @R1 ;GET OLD KB BIT MAP XRL A,#40H ;INVERT BIT 6 JB6 NODOWN ;JUMP IF NO DOWN BOUNCE MOV A,R4 ;GET BOUNCE COUNT ADD A,#-DNBOUNC ;SUBTRACT DOWN BOUNCE JNZ NODOWN ;JUMP IF COUNT NOT DOWN YET MOV A,@R1 ;CLEAR DOWN BOUNCE FLAG ANL A,#0BFH MOV @R1,A NODOWN: MOV A,@R1 XRL A,#80H ;INVERT BIT 7 JB7 NOUP ;JUMP IF NO UP BOUNCE MOV A,R4 ;GET BOUNCE COUNT ADD A,#-UPBOUNC ;SUBTRACT UP BOUNCE JNZ NOUP ;JUMP IF COUNT NOT DONE YET MOV A,R5 ;UPDATE CHANGES ORL A,#01000000B ;AND CLEAR UP BOUNCE FLAG ANL A,@R1 MOV @R1,A NOUP: MOV A,@R1 ;SEE IF ANY CHANGES ANL A,#3FH XRL A,R5 JZ NOCHNG ;JUMP IF NO CHANGES MOV R4,A ;SAVE CHANGES MOV A,@R1 JB6 DNOFF ;JUMP IF DOWN IS OFF MOV A,R4 ;GET CHANGES ANL A,R5 ;LOOK FOR DOWN CHANGES JZ DNOFF ;JUMP IF NO DOWN CHANGES MOV R3, A ;SAVE DOWN CHANGES ORL A,@R1 ;UPDATE KB BIT MAP ORL A,#01000000B ;SET DOWN BOUNCE FLAG MOV @R1,A CALL CLRCNT ;CLEAR BOUNCE COUNT DNOFF: MOV A,@R1 JB7 UPOFF ;JUMP IF UP IS OFF MOV A,R5 ;LOOK FOR UP CHANGES CPL A ANL A,R4 JZ UPOFF CALL CLRCNT MOV A,@R1 ;SET UP BOUNCE FLAG ORL A,#10000000B MOV @R1,A UPOFF: MOV A,R3 JZ NOCHNG ;INNER KEYBOARD SCAN LOOP MOV R7,#FALSE MOV R3, #6 ;SET INDEX COUNTER TO 6 BITS KBLP2: RRC A ;ROTATE BIT INTO CARRY JNC KBSKP2 ;IF THIS KEY IS DOWN THEN BEGIN MOV R5, A ;SAVE SHIFTED VALUE TO RESTORE LATER MOV A, R2 SEL RB1 ;SELECT RB #1 TO SAVE REGISTERS MOV R2, A MOV R1, #6 ;TO MULTIPLY BY 6 CALL BMPY ;MULTIPLY R2 BY 6 SEL RB0 ;RETURN TO THE ORIGINAL RB ADD A, R3 ;ADD IN COLUMN OFFSET ADD A, #-6 ;SUBTRACT BIAS MOV R0, #KBENC MOV @R0, A ;SAVE NUMBER REPRESENTATION OF KEY ORL P2, #(CONTM + SHFTM) IN A, P2 ;READ FOR SHIFT KEY & CONTROL KEY ANL A, #(SHFTM + CONTM) ORL A, #11110011B ;MASK FOR SHIFT & CONTROL KEY MOV R4, A MOV R0, #LEDSTA MOV A, @R0 ANL A, R4 MOV @R0, A ;SET SHIFT & CONTROL DOWN FLAGS JB3 KBSCN4 CALL TBSHT ;GET KEY VALUE FROM SHIFT TABLE JMP KBSCN5 KBSCN4: CALL TBLOW ;ELSE GET KEY VALUE FROM REGULAR TABLE KBSCN5: MOV R4, A ;SAVE KEY VALUE MOV R0, #LEDSTA MOV A, @R0 ;GET CAPS LOCKED FLAG JB7 KBSCN6 ;IF CAPS LOCKED THEN BEGIN CALL LOWUP ;CONVERT LOWER CASE TO UPPER CASE KBSCN6: MOV R0, #LEDSTA MOV A, @R0 JB2 KBSCN7 ;IF THE CONTROL KEY IS DOWN THEN BEGIN CALL TOCTL ;CONVERT TO CONTROL CODE KBSCN7: MOV R0, #KBOLD MOV A, R4 MOV @R0, A MOV R0, #KBDLY MOV @R0, #INITDLY ;SET AUTO REPEAT DELAY COUNT MOV R0, #KBRLD MOV @R0, #MINRPT ;SET REPEAT RELOAD VALUE SEL RB1 ;SELECT RB #1 TO SAVE REGISTERS CALL PROC ;*** PROCESS THE KEY *** SEL RB0 ;RESTORE ORIGINAL REGISTERS MOV A, R5 ;RESTORE SHIFTED VALUE KBSKP2: DJNZ R3, KBLP2 ;UNTIL SCAN COLUMN NUMBER = 0 NOCHNG: MOV R0, #LEDSTA ;LED STATUS MOV A,@R0 MOV R0, #ROWNUM INC @R0 ;INCREMENT ROW NUMBER ANL A, #0FH ;SAVE BITS 0-3 SWAP A ORL A, @R0 SWAP A OUTL P2, A ;BUMP SCAN ROW NUMBER TO NEXT ROW MOVX @R0,A ;WR PULSE TO STROBE 14515 DECODER ;(NOT USED WHEN 74159 IS CONNECTED) INC R1 ;BUMP KB BIT MAP POINTER DJNZ R2, KBLP1 ;UNTIL SCAN ROW NUMBER = 0 ;SCANNING IS ALL DONE NOW, CHECK WHAT HAPPENED MOV A, R6 ;GET KEY DOWN FLAG JNZ KBDWN ;IF NO KEY IS DOWN THEN BEGIN KBEXIT: RET ;RETURN KBDWN: MOV A, R7 ;GET SAME KEY DOWN FLAG JZ KBEXIT ;IF SAME KEY IS DOWN THEN BEGIN MOV R0, #KBDLY MOV A, @R0 DEC A MOV @R0, A ;DECREMENT THE DELAY COUNT JNZ KBEXIT ;IF DELAY TIME IS UP THEN BEGIN MOV R0, #KBRLD MOV A, @R0 ;GET RELOAD VALUE ADD A, #-MAXRPT JZ KBDWN1 ;IF OK TO REDUCE DELAY THEN MOV A, @R0 DEC A ;REDUCE DELAY MOV @R0, A ;AND SAVE IT KBDWN1: MOV A, @R0 ;ELSE GET FINAL RELOAD VALUE MOV R0, #KBDLY MOV @R0, A ;RESET THE DELAY COUNT MOV R0, #LEDSTA MOV A, @R0 XRL A, #REPTF ;INVERT REPEAT FLAG JB1 KBEXIT ;IF AUTO REPEAT ENABLED THEN MOV R0, #KBOLD MOV A, @R0 ;GET KEY VALUE RLC A JNC KBDWN2 ;IF ASCII OR RLC A RLC A JC KBEXIT ;NON-ASCII & AUTO REPEAT ALLOWED THEN KBDWN2: JMP PROC ;*** PROCESS OLD KEY *** PAGE ORG 0200H ;*** NEW PAGE BOUNDRY *** ;---------------------------------------------------------------------- ; Increment Counter ;------------------ ; INCCNT: CALL GETCNT JNC NOSWAP0 SWAP A NOSWAP0:INC A MOV R4,A JNC NOSWAP1 SWAP A NOSWAP1:MOV @R0,A MOV A,#0FH ANL A,R4 MOV R4,A RET ;---------------------------------------------------------------------- ; Clear the Counter Value ;------------------------ ; CLRCNT: CALL GETCNT JNC NOSWAP2 SWAP A NOSWAP2:ANL A,#0F0H JNC NOSWAP3 SWAP A NOSWAP3:MOV @R0,A RET ;---------------------------------------------------------------------- ; Get the Counter Value ;---------------------- ; GETCNT: MOV A,R1 CLR C RRC A MOV R0,A MOV A,@R0 RET PAGE ;---------------------------------------------------------------------- ; BMPY - BINARY MULTIPLY ;----------------------- ; *BMPY* MULTIPLIES ONE-BYTE MULTIPLIER AND A ONE-BYTE ; MULTIPLICAND. ; ; ENTRY - R1-MULTIPLIER ; R2-MULTIPLICAND ; EXIT - A -LS BYTE OF RESULT ; R1-MS BYTE OF RESULT ; USES - A,R1,R2,R3 (R3 IS A LOOP COUNTER(=8)) ; BMPY: MOV R3, #8 ;SET COUNTER TO 8 CLR A CLR C BMP1: RRC A ;DOUBLE SHIFT RIGHT ACC & R1 XCH A, R1 ;INTO CARRY RRC A XCH A, R1 JNC BMP2 ;IF CARRY=1 ADD, OTHERWISE DON'T ADD A, R2 ;ADD MULTIPLICAND TO ACCUMULATOR BMP2: DJNZ R3, BMP1 ;DEC COUNTER & LOOP IF 0 RRC A ;DO A FINAL RIGHT SHIFT AT THE XCH A, R1 ;END OF THE ROUTINE RRC A RET PAGE ;---------------------------------------------------------------------- ; LOWUP - CONVERT FROM LOWER CASE TO UPPER CASE ;---------------------------------------------- ; CONVERTS THE ASCII CHARACTERS FROM 'a' TO 'z' ; TO THEIR UPPER CASE VALUES. ; ; ENTRY (R4) = ASCII VALUE TO CONVERT ; EXIT (A) = CONVERTED BYTE IF NEEDED ; USES A, R0 ; LOWUP: MOV A, R4 ;GET CHARACTER TO CONVERT ADD A, #-('a') JNC LOWUP1 ;IF CHARACTER >= 'a' MOV A, R4 ADD A, #-('z'+1) JC LOWUP1 ;AND IF CHARACTER <= 'z' THEN MOV A, R4 ADD A, #-('a'-'A') ;CONVERT TO UPPER CASE MOV R4, A LOWUP1: RET ;---------------------------------------------------------------------- ; TOCTL - CONVERT TO CONTROL CHARACTER ;------------------------------------- ; CONVERTS THE ASCII CHARACTER INTO A CONTROL CHARACTER ; ; ENTRY (R4) = ASCII VALUE TO CONVERT ; EXIT (A) = CONVERTED BYTE ; USES A, R0, TEMP1 ; TOCTL: CALL LOWUP ;CONVERT TO UPPER CASE MOV A, R4 ADD A, #-('@') JNC TOCTL1 ;IF INSIDE LOWER RANGE MOV A, R4 ADD A, #-(60H) JC TOCTL1 ;AND INSIDE UPPER RANGE THEN MOV A, R4 ADD A, #-('@') ;CONVERT TO CONTROL CHARACTER MOV R4, A TOCTL1: RET PAGE ;---------------------------------------------------------------------- ; PROC - PROCESS KEY ;------------------- ; TAKES THE ASCII VALUE OR SPECIAL VALUE AND SENDS IT ; TO THE HOST SENDING AN ACCESS CODE IF NEEDED AND MASKING ; IN THE SHIFT AND CONTROL VALUES IF NEEDED. ; ; ENTRY (KBOLD) = BYTE TO PROCESS ; EXIT NONE ; USES ALL ; PROC: MOV R0, #KBOLD MOV A, @R0 ;GET KEY TO SEND RLC A JNC PROC3 ;IF ASCII CHARACTER THEN SKIP RLC A JNC PROC1 ;IF ACCESS CODE NEEDED THEN BEGIN MOV R0, #TEMP1 MOV @R0, #ACCESS CALL XMT ;OUTPUT ACCESS CODE PROC1: MOV R0, #KBOLD MOV A, @R0 ;GET VALUE TO OUTPUT ANL A, #10011111B ;CLEAR SHIFT/CONTROL AREAS MOV R0, #TEMP1 MOV @R0, A ;SAVE NEW VALUE MOV R1, #LEDSTA MOV A, @R1 JB3 PROC2 ;IF SHIFT KEY DEPRESSED THEN MOV A, @R0 ORL A, #01000000B ;MASK IN SHIFT CODE MOV @R0, A PROC2: MOV R1, #LEDSTA MOV A, @R1 JB2 PROC3 ;IF CONTROL KEY DEPRESSED THEN MOV A, @R0 ORL A, #00100000B ;MASK IN CONTROL CODE MOV @R0, A PROC3: CALL XMT ;OUTPUT CHARACTER POINTED BY @R0 MOV R0, #LEDSTA MOV A, @R0 JB4 KEYCLK ;IF KEY CLICK ENABLED THEN RET PAGE ;---------------------------------------------------------------------- ; XMT - TRANSMIT DATA TO HOST (13_Dec_84) ;---------------------------------------- ; OUTPUTS BYTES TO THE HOST USING A SPECIAL HANDSHAKE. ; ; ENTRY (@R0) = BYTE TO OUTPUT ; EXIT NONE ; USES ALL ; XMT: ANL P1,#OUT0M ;(Set Request Attention Low -- Precautionary) MOV A,@R0 ;Get the Byte to Send XMLP1: JNT1 XMSK1 ;While (The Host is Requesting Attention) MOV R0,#TEMP2 MOV @R0,A ; Save the Value to Output CALL RCV ; Recieve the Incomming Data JC XMSK0 ; If (The Data was Recieved) CALL DPR ; Process it XMSK0: MOV R0,#TEMP2 MOV A,@R0 ; Restore the Entry Value JMP XMLP1 XMSK1: MOV R1,#8 ;Initialize Index for 8 Bits ORL P1,#OUT1M ;Set Request Attention XMLP2: JNT1 XMLP2 ;Repeat Wait for Request Data Signal RRC A ; Rotate Data into Accm JNC XMSK2 ; If (High Bit to be Sent) ORL P1,#OUT1M ; Set the Bit High JMP XMLP3 XMSK2: ANL P1,#OUT0M ; Else Set the Bit Low XMLP3: JT1 XMLP3 ; Wait for Data Recieved Signal DJNZ R1,XMLP2 ;Until (All 8 Bits have been Recieved) ANL P1,#OUT0M ;Pull Output Low RET ;Return PAGE ;---------------------------------------------------------------------- ; KEYCLK - KEY CLICK ;------------------- ; CLICKS THE BELL ON THE KEYBOARD. IF BELL IS RINGING THEN THE ; BELL IS NOT DISTERBED. ; ; ENTRY NONE ; EXIT NONE ; USES A, R0 ; KEYCLK: JB6 KEYCL2 ;IF BELL RINGING THEN JUMP MOV A, #BELL1M ;PULL BELL HIGH CALL FFCLK1 ;PULSE FLIP-FLOP CLOCK MOV R0, #255 KEYCL1: NOP NOP DJNZ R0, KEYCL1 ;Delay about 5ms MOV A, #BELL0M ;PULL BELL LOW CALL FFCLK0 ;PULSE FLIP-FLOP CLOCK KEYCL2: RET ;---------------------------------------------------------------------- ; Flip-Flop Clock ;---------------- ; 1) 1 - TURNS THE LED ON/OFF; 0 - PULSES THE FLIP-FLOP CLOCK ; 2) ENTRY - A-MASK BYTE ; FFCLK1: MOV R0, #LEDSTA ORL A, @R0 JMP FFCLK01 FFCLK0: MOV R0, #LEDSTA ANL A, @R0 FFCLK01:MOV @R0, A ;SAVE LEDs NEW STATUS OUTL P2, A ;OUTPUT TO PORT 2 FFCLK: ORL P1, #FFCK1M ;CLOCK HIGH ANL P1, #FFCK0M ;CLOCK LOW RET PAGE ORG 0300H ; *** NEW PAGE BOUNDARY *** ;---------------------------------------------------------------------- ; TBSHT - TABLE UPPER CASE ;------------------------- ; ; *TBSHT* DOES THE TABLE LOOKUP FOR THE UPPER CASE LETTERS ; ; ENTRY (KBENC) = KEY NUMBER ; EXIT (A) = ASCII VALUE OR SPECIAL VALUE ; USES A, R0 ; TBSHT: MOV R0,#KBENC MOV A,#LOW (TBSHTT - 1) ADD A,@R0 ;ADD OFFSET AND CONSTANT INTO TABLE MOVP A,@A ;GET VALUE RET ;---------------------------------------------------------------------- ; TBLOW - TABLE LOWER CASE ;------------------------- ; *TBLOW* DOES THE TABLE LOOKUP FOR THE LOWER CASE LETTERS ; ; ENTRY (KBENC) = KEY NUMBER ; EXIT (A) = ASCII VALUE OR SPECIAL VALUE ; USES A, R0 ; TBLOW: MOV R0, #KBENC MOV A, #LOW (TBLOWT - 1) ADD A, @R0 ;ADD OFFSET AND CONSTANT INTO TABLE MOVP A, @A ;GET VALUE RET PAGE ;---------------------------------------------------------------------- ; TBLOWT - LOWER CASE TABLE ;-------------------------- ; TBLOWT: DB FC, FD ; S15 BITS 5,4 DB SETUP, NULL, NULL, NULL ; S15 BITS 7,6,5,4 DB FB, FA ; S14 BITS 5,4 DB FN10, FN9, FN8, FN7 ; S14 BITS 7,6,5,4 DB FN6, FN5 ; S13 BITS 5,4 DB FN4, FN3, FN2, FN1 ; S13 BITS 3,2,1,0 DB BS, LF ; S12 BITS 5,4 DB KPDASH, KPENT, CR, SPACE ; S12 BITS 3,2,1,0 DB '/', TAB ; S11 BITS 5,4 DB KPDEC, '.', 'i', 'v' ; S11 BITS 3,2,1,0 DB LFTA, ESC ; S10 BITS 5,4 DB KPCOM, ',', 'u', 'c' ; S10 BITS 3,2,1,0 DB RGHTA, '1' ; S9 DB KP1, '\', 'y', 'x' ; S9 DB DWNA, '2' ; S8 DB KP2, 'o', 't', 'z' ; S8 DB UPA, '3' ; S7 DB KP3, 'p', 'h', 'a' ; S7 DB DEL, '4' ; S6 DB KP4, ''', 'j', 's' ; S6 DB CAPLCK, '5' ; S5 DB KP5, '`', 'k', 'd' ; S5 DB SCROLL, '6' ; S4 DB KP6, '=', 'l', 'f' ; S4 DB NULL, '7' ; S3 DB KP7, '-', 'm', 'r' ; S3 DB HOMECLR,'8' ; S2 DB KP8, '[', 'n', 'e' ; S2 DB HELP, '9' ; S1 DB KP9, ']', 'b', 'w' ; S1 DB ERASE, '0' ; S0 DB KP0, ';', 'g', 'q' ; S0 PAGE ;---------------------------------------------------------------------- ; TBSHTT - UPPER CASE TABLE ;-------------------------- ; TBSHTT: DB FC, FD ; S15 BITS 5,4 DB SETUP, NULL, NULL, NULL ; S15 BITS 3,2,1,0 DB FB, FA ; S14 BITS 5,4 DB FN10, FN9, FN8, FN7 ; S14 BITS 3,2,1,0 DB FN6, FN5 ; S13 HIGH DB FN4, FN3, FN2, FN1 ; S13 LOW DB BS, LF ; S12 HIGH DB KPDASH, KPENT, CR, SPACE ; S12 LOW DB '?', TAB ; S11 HIGH DB KPDEC, '>', 'I', 'V' ; S11 LOW DB LFTA, ESC ; S10 HIGH DB KPCOM, '<', 'U', 'C' ; S10 LOW DB RGHTA, '!' ; S9 HIGH DB KP1, '|', 'Y', 'X' ; S9 LOW DB DWNA, '@' ; S8 HIGH DB KP2, 'O', 'T', 'Z' ; S8 LOW DB UPA, '#' ; S7 HIGH DB KP3, 'P', 'H', 'A' ; S7 LOW DB DEL, '$' ; S6 HIGH DB KP4, '"', 'J', 'S' ; S6 LOW DB CAPLCK, '%' ; S5 HIGH DB KP5, '~', 'K', 'D' ; S5 LOW DB SCROLL, '^' ; S4 HIGH DB KP6, '+', 'L', 'F' ; S4 LOW DB NULL, '&' ; S3 HIGH DB KP7, '_', 'M', 'R' ; S3 LOW DB HOMECLR,'*' ; S2 HIGH DB KP8, '{', 'N', 'E' ; S2 LOW DB HELP, '(' ; S1 HIGH DB KP9, '}', 'B', 'W' ; S1 LOW DB ERASE, ')' ; S0 HIGH DB KP0, ':', 'G', 'Q' ; S0 LOW END