: Labeling for configuration switch mux ? ; ALS version of the oscillator ? ; Download handshake if scan code on bus and interrupt set ? TITLE "MORROW DESIGNS PIVOT - KEYBOARD PROCESSOR FIRMWARE" SBTTL "REVISION 1/7/85 2.00" WIDTH 80 ; Author: Michael Stolowitz ; ; This firmware shall include the following functions: ; ; KEYBOARD SCANNING - The firmware shall pole an 8 x 12 keyboard ; matrix consisting of two rows of membrane function switches and ; ten rows of diode isolated mechanical switches. IBM PC equivalent ; make and break codes shall be generated for all detected activity. ke rollove shal b implemente fo th diode isolated keys. ; Scan codes will be stored in a FIFO to host transmission. The ; keyboard will be scanned at the frame rate of the LCD display ; when the display is enabled and at an interval determined by the ; processor's internal real time clock when the display is off. ; ; SCAN CODE TRANSMISSION TO THE HOST - As a background task, the ; firmware shall poll the FIFO and the host's 8255 status, uploading ; scan codes whenever posssible. ; ; COLOR GRAPHICS BOARD SIMULATION - This firmware will respond to ; interrupts caused by CPU access of the non-existent Color Graphics ; board. This firmware will analyze the state of the ready line ; held CPU and release the processor with an appropriate response ; simulating the 6845, the MODE register, and the STATUS register ; as required. Changes to the MODE register will invoke similar ; states of the LCD display when available. Updating the 6845's ; curser register will result in a CPU NMI interrupt at end of frame ; so that the LCD's software controlled curser may be updated. ; ; HARDWARE CONTROL FUNCTIONS - The firmware shall implement a down ; load procedure for data from the CPU via the 8255 on the keyboard ; data bus. Using this mechanism, the CPU will control/monitor ; hardware not found on a standard IBM PC. This includes control ; of the LCD display, the non-volatile ram & clock, and the floppy ; disk motors. It will also be able to enable and disable access ; to the LCD display, write the virtual configuration switch and ; monitor the state of the low battery and ac on detectors. ; ; ; INTERNAL PORT MAPPED FUNCTIONS ; ; Port 1 8255 Keyboard Data Bus ; ----------------------------------------- ; P17 PA7 ; P16 PA6 ; P15 PA5 ; P14 PA4 ; P13 PA3 ; P12 PA2 ; P11 PA1 ; P10 PA0 ; ; Port 2 Program Memory Address / Misc Strobes ; ----------------------------------------- ; P27 Set Keyboard Interrupt ; P26 Acknowledge CPU LCD Access ; P25 Assert CPU NMI ; P24 Keyboard Clock - 8255 Handshake ; P23 PAD11 - Not Used ; P22 PAD10 ; P21 PAD9 ; P20 PAD8 ; ; ; EXTERNAL MEMORY MAPPED FUNCTIONS ; ; WRITE PORTS ; ; Port 0 Keyboard Column Strobe ; ----------------------------------------- ; Addr 5 ROW3 ; 4 ROW2 ; 3 ROW1 ; 2 ROW0 ; ; Port 1 Processor Data Strobe ; ----------------------------------------- ; Data 7 AD7 ; 6 AD6 ; 5 AD5 ; 4 AD4 ; 3 AD3 ; 2 AD2 ; 1 AD1 ; 0 AD0 ; ; Port 2 Switch Register Strobe ; --------------------------------------- ; Addr 6 FDC ENA ; Data 7 SW8 ; 6 SW7 ; 5 SW6 ; 4 SW5 ; 3 SW4 ; 2 SW3 ; 1 SW2 ; 0 SW1 ; ; Port 3 Display Strobe ; ----------------------------------------- ; 7 A/N Bank 0 ; 6 Color Adapater Board Installed ; 5 Blink ; 4 High Resolution Graphics ; 3 Reset the CPU ; 2 LCD Display Enable ; 1 Graphics/Alpha-Numeric ; 0 Non-Volitile Ram & Clock Enable ; ; READ PORTS ; ; Port 0 Processor Data Enable ; ----------------------------------------- ; Data 7 AD7 ; 6 AD6 ; 5 AD5 ; 4 AD4 ; 3 AD3 ; 2 AD2 ; 1 AD1 ; 0 AD0 ; ; Port 1 Keyboard Data Enable ; ----------------------------------------- ; Data 7 COL8 ; 6 COL7 ; 5 COL6 ; 4 COL5 ; 3 COL4 ; 2 COL3 ; 1 COL2 ; 0 COL1 ; ; Port 2 Processor Address Enable ; ----------------------------------------- ; Data 4 IOR* ; 3 A3 ; 2 A2 ; 1 A1 ; 0 A0 ; ; Port 3 Extra Port Enable ; ----------------------------------------- ; Data 3 FDC ENA * ; 2 LO BATT1 * ; 1 LO BATT2 * ; 0 AC ON * ; * * * * * ; ; BANK 0 REGISTER UTILIZATION ; ; R0 WORKING INDEX REGISTER ; R1 DISPLAY ADDR 1..12 ; R2 CURRENT ROW 1..12 OR 0 IF NO ACTIVE KEY ; R3 CURRENT KEY KEYBOARD DATA IF R2 <> 0 ; R4 CURRENT CTL 00 OR 80H ; R5 CURRENT ALT 00 OR 80H ; R6 CURRENT LSRS 00 OR 02H ; R7 DEBOUNCE DELAY ; ; BANK 1 REGISTER UTILIZATION ; ; R0 WORKING INDEX REGISTER ; R1 6845 ADDRESS REGISTER ; R2 FIFO INPUT POINTER ; R3 FIFO OUTPUT POINTER ; R4 BLINK COUNTER ; R5 DISPLAY STATUS REGISTER ; R6 HOLD A DURING INT ROUTINE ; R7 DISP CTL SHADOW ; ; F1 NOT END-FRAME ; ; PORT 1 KEYBOARD SCAN CODES TO 8255 ; ; PORT 2 STROBE OUTPUT PORT - BIT ASSIGNMENTS ; KBDAV.P: EQU 10000000B ;SET DAV LATCH CRQC.N: EQU 01000000B ;RELEASE PROCESSOR NMIRQ.P: EQU 00100000B ;ASSERT PROCESSOR NMI ; ; DATA BUS 8084 LOCAL BUS FACILITIES ; KB.STB EQU 00H ;Key Board Strobe PD.STB EQU 01H ;Processor Data Strobe DS.STB EQU 03H ;Display Strobe ; KB.ENA EQU 00H ;Key Board Enable PD.ENA EQU 01H ;Processor Data Enable PA.ENA EQU 02H ;Processor Address Enable ; ; DATA MEMORY MAP ; 20 - 31H 18 REGISTERS OF 6845 ; 32 - 3FG 14 BYTES OF FIFO ; CRT.REG EQU 20H ;6845 DATA REG BASE CUR.REG EQU 0EH ;CURSER REGISTER PAIR FIFO EQU 0F2H ;FIFO BASE ADDR ;DISPLAY BLINK CONSTANTS K.BLINK EQU 10 ;75/20 CYCLES PER SECOND BLINK.B EQU 20H ;BLINK BIT OF DISP CTL ;SCAN CODES SCAN.ALT: EQU 56 SCAN.CTL: EQU 29 SCAN.LS: EQU 42 SCAN.RS: EQU 54 ;DEBOUNCE CONSTA ; ; WHILE NOT END OF FRAME - UNLOAD THE FIFO ; ; AT END OF FRAME: ; 1. CLEAR END FRAME FLAG ; 2. SEND NMI TO HOST IF CURSER MOVED ; 3. UPDATE BLINK ; 4. SCAN KEYBOARD ; MAIN: JF1 SENDOUT ;SKIP IF NOT END FRAME CPL F1 ;CLR END FRAME FLG MAIN1: SEL RB1 ;BANK1 REGISTERS MOV A,R5 ;FETCH DISPLAY STATUS ANL A,#80H ;MASK CURSER UPDATE JZ MAIN2 ;SKIP IF NOT SET XRL A,R5 ;CLR UPDATE BIT MOV R5,A ;AND RESTORE STATUS ORL P2,#NMIRQ.P ;ASSERT PROC NMI ANL P2,#NOT NMIRQ.P ;NEGATE PROC NMI MAIN2: DJNZ R4,MAIN3 ;BUMP BLINK, AND TEST MOV A,R7 ;FETCH CONTROL BYTE MOV R0,#DS.STB ;POINT TO DISP REG MOVX @R0,A ;AND MOVE OUT ACC XRL A,#BLINK.B ;TOGGLE BLINK BIT MOV R7,A ;RESTORE TO REG MOV R4,#K.BLINK ;RESET COUNTER ; ; KEYBOARD SCAN ROUTINE ; MAIN3: SEL RB0 ;SELECT BANK 0 MOV A,R7 ;FETCH DEBOUNCE JZ TESTCTL ;SKIP IF ZERO DEC R7 ;ELSE DECR DELAY JMP MAIN ;WAIT ANOTHER FRAME TESTCTL: MOV R1,#1 ;MATRIX ROW 1 CALL KBOUTIN ;OUT ROW / IN DATA XRL A,R4 ;COMPARE NEW/OLD JZ TESTALT ;SKIP IF NO CHANGE XRL A,R4 ;RESTORE DATA XCH A,R4 ;SWAP NEW WITH OLD ADD A,#SCAN.CTL ;ADD CTL SCAN CODE JMP SENDSCAN ;SEND SCAN CODE TESTALT: INC R1 ;MAXTRIX ROW 2 CALL KBOUTIN ;OUT ROW / IN DATA XRL A,R5 ;COMPARE NEW/OLD JZ TESTOLD ;IF NO CHANGE XRL A,R5 ;RESTORE DATA XCH A,R5 ;SWAP NEW WITH OLD ADD A,#SCAN.ALT ;ADD ALT SCAN CODE JMP SENDSCAN ;SEND SCAN CODE TESTOLD: MOV A,R2 ;GET CURRENT ROW JZ TESTSHTR ;NO CURRENT KEY MOV R1,A ;COPY TO ROW POINTER CALL KBOUTIN ;OUT ROW / IN DATA ANL A,R3 ;MASK TO OLD BIT JNZ MAIN ;STILL DOWN MOV R2,A ;CLEAR CURRENT ROW XCH A,R3 ;SWAP ZERO WITH DATA CALL SCANCODE ;GET SCAN CODE ORL A,#80H ;ADD BREAK BIT JMP SENDSCAN ;SEND BREAK CODE TESTSHTR: MOV R1,#3 ;KB ROW 3 CALL KBOUTIN ;OUT ROW / IN DATA XRL A,R6 ;COMPARE WITH CURRENT ANL A,#RS.BIT ;MASK TO RIGHT SHIFT JZ TESTSHTL ;SKIP IF UNCHANGED MOV A,R6 ;COPY R6 TO ACC JB2 TESTSR1 ;SKIP IF KEY BREAK ORL A,#RS.BIT ;SET RS BIT MOV R6,A ;AND REPLACE R6 CLR A ;NO BREAK BIT JMP TESTSR2 ;AND SKIP TESTSR1: ANL A,#NOT RS.BIT ;CLR RS BIT MOV R6,A ;AND REPLACE R6 MOV A,#80H ;SET BREAK BIT TESTSR2: ADD A,#SCAN.RS ;OR SCAN CODE JMP SENDSCAN ;AND SEND TESTSHTL: INC R1 ;KB ROW 4 CALL KBOUTIN ;OUT ROW / IN DATA XRL A,R6 ;COMPARE WITH CURRENT ANL A,#LS.BIT ;MASK TO RIGHT SHIFT JZ SCAN ;SKIP IF UNCHANGED MOV A,R6 ;COPY R6 TO ACC JB1 TESTSL1 ;SKIP IF KEY BREAK ORL A,#LS.BIT ;SET LS BIT MOV R6,A ;AND REPLACE R6 CLR A ;NO BREAK BIT JMP TESTSL2 ;AND SKIP TESTSL1: ANL A,#NOT LS.BIT ;CLR LS BIT MOV R6,A ;AND REPLACE R6 MOV A,#80H ;SET BREAK BIT TESTSL2: ADD A,#SCAN.LS ;OR SCAN CODE JMP SENDSCAN ;AND SEND SCAN: MOV R1,#3 ;START WITH ROW 3 CALL KBOUTIN ;KB ADDR OUT / DATA IN ANL A,#NOT RS.BIT ;MASK OUT RSBIT JNZ SCAN2 ;SKIP IF KEY FOUND INC R1 ;STEP TO ROW 4 CALL KBOUTIN ;KB ADDR OUT / DATA IN ANL A,#NOT LS.BIT ;MASK OUT LSBIT JNZ SCAN2 ;SKIP IF KEY FOUND MOV R3,#8 ;INIT CNT FOR TEN ROWS SCAN1: INC R1 ;BUMP ROW NUMBER CALL KBOUTIN ;KB ADDR OUT / DATA IN JNZ SCAN2 ;JUMP IF KEY FOUND DJNZ R3,SCAN1 ;CONTINUE IF CNT > 0 JMP MAIN ;ELSE DONE SCAN2: MOV R3,A ;SAVE AS CURRENT KEY MOV A,R1 ;GET ROW ADDR ADDR MOV R2,A ;AND SAVE AS CURRENT ROW MOV A,R3 ;RECALL THE DATA CALL SCANCODE ;GET SCAN CODE JMP SENDSCAN ;SEND SCAN CODE ; ; FIFO BUFFER UNLOAD ROUTINE ; SENDOUT: JT0 MAIN ;IF 8255 BUSY SEL RB1 ;BANK 1 REGISTERS MOV A,R3 ;FETCH FIFO OUT PTR MOV R0,A ;COPY TO INDEX REG XRL A,R2 ;COMPARE WITH FIFO IN JZ MAIN ;RETURN IF FIFO EMPTY MOV A,@R0 ;FETCH DATA FROM BUF OUTL P1,A ;OUTPUT TO 8255 ORL P2,#KBDAV.P ;ASSERT DAV SET ANL P2,#NOT KBDAV.P ;NEGATE THE SET MOV A,R3 ;FETCH THE PTR ADD A,#1 ;BUMP IT JNC SNDOUT1 ;SKIP IF NO OVFL MOV A,#FIFO ;OTHERWISE RESET SNDOUT1: MOV R3,A ;RESTORE OUT PTR SEL RB0 ;AND BANK 0 JMP MAIN ; ; KEYBOARD WRITE ADDRESS / READ DATA ; ; R1 = ROW ADDRESS ; A = RETURNED DATA ; KBOUTIN: MOV R0,#KB.STB ;KB STB TO NDX MOV A,R1 ;ROW TO A MOVX @R0,A ;AND A TO KB MOVX A,@R0 ;KB DATA TO A RET ;AND RETURN DATA ; ; SCAN CODE - CONVERT KEY ADDRESS TO PC SCAN CODE ; ; ENTRY: ; A = KEYBOARD DATA ; R0 = TEMP ; R1 = ROW NUMBER ; ; EXIT: ; A = SCAN CODE ; ORG ROM.ORG+100H ;TABLE AT X00 SCANTBL: DB 1,0,0,2,16,30,72,44 DB 255,0,0,5,19,33,57,47 DB 43,27,80,3,17,31,75,45 DB 15,77,12,4,18,32,11,46 DB 255,43,39,6,20,34,52,48 DB 26,0,53,7,21,35,25,49 DB 40,28,38,8,22,36,24,50 DB 14,41,13,9,23,37,10,51 DB 60,62,64,65,67,0,0,0 DB 59,61,63,66,68,0,0,0 SCANCODE: MOV R0,#8 ;INITIATE CNT SC1: DEC R0 ;DECR BIT POS RLC A ;ROTATE NEXT BIT TO CRY JNC SC1 ;REPEAT IF ZERO BIT MOV A,R1 ;GET ROW NUMBER ADD A,#-3 ;ADJUST TO 0-9 RL A ;AND SHIFT LEFT RL A ;THREE RL A ;BITS ORL A,R0 ;OR THE DATA BIT NUMBER MOVP A,@A ;AND FETCH FROM TABLE RET ; ; FIFO BUFFER LOAD ROUTINE ; ; A = SCAN CODE ; SENDSCAN: SEL RB1 ;BANK 1 REGISTERS MOV R0,A ;HOLD DATA IN R0 MOV A,R2 ;FETCH FIFO IN PTR XCH A,R0 ;SWAP DATA AND ADDR MOV @R0,A ;DATA TO FIFO MOV A,R0 ;RESTORE THE ADDR ADD A,#01H ;BUMP THE PTR JNC SNDSCAN1 ;SKIP IF NO OVFL MOV A,#FIFO ;WRAP THE RING SNDSCAN1: XRL A,R3 ;COMPARE FIFO OUT JZ SNDSCAN2 ;SKIP IF BUF FULL XRL A,R3 ;RESTORE NEW VALUE MOV R2,A ;UPDATE FIFO IN SNDSCAN2: MOV A,@R0 ;RECALL SCAN CODE SEL RB0 ;BANK 0 JB7 SNDSCAN4 ;SKIP TO MAIN IF BREAK MOV A,#-11 ;IF ROW => 11 ADD A,R1 ;THEN CARRY WILL SET JC SNDSCAN3 ;SKIP IF 11 OR 12 MOV R7,#KBDB.S ;ELSE DEBOUNCE SHORT JMP MAIN ;AND DONE SNDSCAN3: MOV R7,#KBDB.L ;SET DEBOUNCE LONG SNDSCAN4: JMP MAIN ;AND DONE ; ; STALL INTERRUPT ; PROC ACCESSING COLOR GRAPHICS BOARD ; ; PROC ADDR = /IOR A3 A1 A0 ; ; ROUTINE FUNCTION (DECODES THRU JUMP TABLE): ; A. ILLEGAL READS OR WRITES REL PROC ; B. WRITES ACCEPT DATA AND REL PROC ; 1. 6845 ADDR SETS R1 ; 2. 6845 DATA GOES TO RAM @R1 ; A. CURSER REG CLRS F0 ; 3. MODE SETS R7 AND DISP CTL PORT ; 4. SELECT AND LIGHT PEN IGNORED ; C. READ OF 6845 RETURNS RAM VALUE @R1 ; D. READ OF STATUS RETURNS R5 ; 1. VSYNC IS TOGGLED AFTER READ ; ORG ROM.ORG+200H ; TABLE: DB EXIT ;R0 READ 6845 ADDR DB RCRTDATA ;R1 READ 6845 DATA DB EXIT ;R2 READ 6845 ADDR DB RCRTDATA ;R3 READ 6845 DATA DB EXIT ;R8 READ MODE REG DB EXIT ;R9 READ SELECT DB RSTAT ;RA READ STATUS DB EXIT ;RB LIGHT PEN CLEAR DB WCRTADDR ;W0 WRITE 6845 ADDR DB WCRTDATA ;W1 WRITE 6845 DATA DB WCRTADDR ;W2 WRITE 6845 ADDR DB WCRTDATA ;W3 WRITE 6845 DATA DB WMODE ;W8 WRITE MODE REG DB EXIT ;W9 WRITE SELECT DB EXIT ;WA WRITE STATUS DB EXIT ;WB LIGHT PEN CLEAR STALL: SEL RB1 ;B @    UPDATE BIT MOV R5,A ;AND REPLACE STATUS WRCRT1: MOV A,R6 ;RESTORE A RETR ;AND DONE WMODE: CALL WDATA ;ACCEPT THE DATA MOV R7,A ;SAVE MODE IN R7 ANL A,#01101010B ;BITS 6, 5, 3, AND 1 XCH A,R7 ;SAV BITS - GET MODE JB1 WMODE2 ;WILL NOT NEED BIT 0 JB0 WMODE1 ;BIT 0 SHOULD BE 0 INC R7 ;SET BIT 0 WMODE1: MOV A,R7 ;GET THE DISP BYTE MOV R0,#DS.STB ;DISP ADDR TO NDX MOVX @R0,A ;A TO DISP MOV A,R6 ;RESTORE A RETR ;AND DONE WMODE2: JB4 WMODE3 ;SKIP TO SET BIT 4 JMP WMODE1 ;BIT 4 NOT NEEDED WMODE3: MOV A,#10H ;MASK FOR BIT 4 ADD A,R7 ;ADD DISP CTL BYTE MOV R7,A ;COPY BACK TO SAVE JMP WMODE1+1 ;GO SET THE LATCH RCRTDATA: MOV A,@R1 ;FETCH ADDRESSED DATA JMP RSTAT1 ;AND RETURN TO PROC RSTAT: MOV A,R5 ;STATUS REG TO A RSTAT1: MOV R0,#PD.STB ;PROC DATA ADDR TO NDX MOVX @R0,A ;A TO PROC DATA ANL P2,#NOT CRQC.N ;RELEASE PROCESSOR ORL P2,#CRQC.N ;NEGATE RELEASE XRL A,#08H ;TOGGLE VERT SYNC MOV R5,A ;RESTORE STATUS MOV A,R6 ;RESTORE A RETR ;END OF INTERRUPT ; ; TIMER INTERRUPT - SYNC PULSE FROM DISPLAY ON T1 ; ; CLEARS F1 ENABLING END OF FRAME PROCESSING ; TIMER: CLR F1 ;ENABLE END OF FRAME SEL RB1 ;FOR CORRECT R6 MOV R6,A ;SAVE A IN R6 MOV A,#0FFH ;ONE SHORT OF OVFL MOV T,A ;TO RE-ARM THE TIMER MOV A,R6 ;RESTORE A RETR ;AND DONE END The Pivot Keyboard Matrix Address\data 7 6 5 4 3 2 1 0 ct n n n n n n nc al n n n n n n nc 3 rs nc 4 nc ls 5 6 7 8 9 10 11 function keys ------------------------------------- 12 function keys ------------------------------------- Not tha CT an AL ar unique R an L ar not Th sca algorith mus handl key overlappe wit SHIFT Whe lookin fo key w mus no sto i th closur foun i th shift W coul tes bot shifts the mas the of o additiona tests.