;SYSTEM NOTES: ; Configuration switch to be fixed in artwork. ; EL panel to be controlled by DISP.2 ; Power Fail presently ignored. ; Add CTL-ALT-DEL detection ; ; * * * A T T E N T I O N * * * ; ; Temp patches keyed with $$$ ; TITLE "MORROW DESIGNS PIVOT - KEYBOARD PROCESSOR FIRMWARE" SBTTL "REVISION 2/20/85 6:44 PM 3.35" WIDTH 96 ; ; BANK 0 REGISTER UTILIZATION ; ; KB RED DELTA CODE SEND ; -------------------------------------------------------------- ; R0 ; R1 KEY-ARRAY KEY-ARRAY KEY-ARRAY KEY-ARRAY ; R2 ROW CNT ROW CNT ROW CNT ROW-CNT ; R3 DELTA DELTA DELTA ; R4 ROTATE ROTATE ; R5 PWR-STAT PWR-STAT PWR-STAT PWR-STAT ; R6 BIT-CNT BIT-CNT ; R7 DEBOUNCE DEBOUNCE DEBOUNCE DEBOUNCE ; ; BANK 1 REGISTER UTILIZATION ; ; R0 WORKING INDEX REGISTER ; R1 6845 ADDRESS REGISTER ; R2 FIFO INPUT POINTER ; R3 FIFO OUTPUT POINTER ; R4 NMI STATUS ; R5 DISPLAY STATUS ; B7 Curser Updated ; B5 Blink Enabled ; R6 SAVED ACCUMULATOR ; R7 DISP CTL SHADOW ; ; F0 NO CURSER UPDATE ; F1 NOT END-FRAME ; ; PORT 1 KEYBOARD SCAN CODES TO 8255 ; PORT 2 STROBE OUTPUT PORT ; ; ; PORT 2 BIT ASSIGNMENTS ; KBDAV.P: EQU 10000000B ;SET DAV LATCH PACK.P: EQU 01000000B ;PROCESSOR ACKNOWLEDGE NMIRQ.P: EQU 00100000B ;ASSERT PROCESSOR NMI KBCLK.P: EQU 00010000B ;KB CLK HANDSHAKE TO 8255 ; ; DATA BUS 8084 LOCAL BUS FACILITIES ; KB.STB EQU 00H ;Key Board Strobe PD.STB EQU 01H ;Processor Data Strobe SW.STB EQU 02H ;Switch Register Strobe DS.STB EQU 03H ;Display Strobe PD.ENA EQU 00H ;Processor Data Enable KB.ENA EQU 01H ;Key Board Enable PA.ENA EQU 02H ;Processor Address Enable AUX.ENA EQU 03H ;Extra Port Enable ; SW.DFLT EQU 79H ;DEFAULT SWITCH REG VALUE DSP.DFLT EQU 0A5H ;DEFAULT DISPLAY CONTROL ; ; DATA MEMORY MAP ; 20 - 35H 22 Registers of 6845 ; 36H SAVE1 ; 37H SAVE2 ; 38H BLINK ; 39H SWITCH ; 3AH DEBOUNCE ; 3BH REPEAT ; ; 40 - 57 24 Bytes of Key-Array ; 60 - 7FH 32 Bytes of FIFO ; CRT.REG: EQU 20H ;START OF 6845 REGISTERS SAVE1: EQU 36H ;OP SYS ADDR SAVE SAVE2: EQU 37H ;NMI ADDR SAVE BLINK: EQU 38H ;BLINK COUNTER SWITCH: EQU 39H ;SWITCH PORT SHADOW BOUNCE: EQU 3AH ;DEBOUNCE VARIABLE REPEAT: EQU 3BH ;REPEAT REGISTER KARRAY: EQU 40H ;KB DATA ARRAY FIFO: EQU 0E0H ;FIFO - 20H BYTES TO END RAM ; ;BUF.LEN: EQU 20h ;FIFO LENGTH ; ;CUR.REG EQU 0EH ;CURSER REGISTER PAIR ;DISPLAY BLINK CONSTANTS K.BLINK: EQU 40 ;75/40 CYCLES PER SECOND BLINK.B: EQU 20H ;BLINK BIT OF DISP CTL ;DEBOUNCE CONSTANTS KBDB.S: EQU 2H ;SHORT - 2 FRAME TIMES KBDB.L: EQU 4H ;LONG - 4 FRAME TIMES ;NMI STATUS CODES BAT2.NMI: EQU 2 ;LO BATT 2 CUR.NMI: EQU 4 ;CURSER UPDATED BAT1.NMI: EQU 6 ;LO BATT 1 CHANGED AC.NMI: EQU 18 ;AC-ON CHANGED X00: EQU XX00 OR 80H X01: EQU XX01 OR 80H X02: EQU XX02 OR 80H X03: EQU XX03 OR 80H X04: EQU XX04 OR 80H X05: EQU XX05 OR 80H X06: EQU XX06 OR 80H X07: EQU XX07 OR 80H X08: EQU XX08 OR 80H X09: EQU XX09 OR 80H X0A: EQU XX0A OR 80H X0B: EQU XX0B OR 80H X0C: EQU XX0C OR 80H X0D: EQU XX0D OR 80H X0E: EQU XX0E OR 80H X0F: EQU XX0F OR 80H X10: EQU XX10 OR 80H X11: EQU XX11 OR 80H X12: EQU XX12 OR 80H X13: EQU XX13 OR 80H X14: EQU XX14 OR 80H X15: EQU XX15 OR 80H X16: EQU XX16 OR 80H X17: EQU XX17 OR 80H X18: EQU XX18 OR 80H X19: EQU XX19 OR 80H X1A: EQU XX1A OR 80H X1B: EQU XX1B OR 80H X1C: EQU XX1C OR 80H ROM.ORG: EQU 00H ;FOR SIMULATION ORG ROM.ORG ;RESET ADDRESS ; ; RESET - The 80C39 vectors here following a reset. ; RESET: JMP COLD ;RESET ENTRY NOP JMP STALL ;INT INTERRUPT NOP NOP JMP TIMER ;TIMER INTERRUPT ; ; COLD - Code executed one time at reset. ; COLD: ;STROBES OFF ANL P2,#0 ;CLEAR ALL STROBES ;INITIALIZE DISPLAY SEL RB1 ;BANK 1 REGISTERS MOV A,#DSP.DFLT ;DEFAULT DISP CTL MOV R0,#DS.STB ;SET NDX TO DISP MOVX @R0,A ;AND SET THE PORT MOV R7,A ;COPY TO SHADOW REG ;INITIALIZE SWITCH AND FDC-OFF SEL RB0 ;BANK 0 REGISTERS MOV A,#SW.DFLT ;DEFAULT SWITCH VALUE MOV R0,#SW.STB ;SET NDX TO SW PORT MOVX @R0,A ;SET SW AND FDC-OFF MOV R0,#SWITCH ;SET NDX TO SW SAVE MOV @R0,A ;AND COPY NEW VALUE ;INITIALIZE KEYBOARD DATA ARRAY MOV R0,#KARRAY ;SET NDX TO ARRAY MOV R1,#24 ;LENGTH OF ARRAY CLR A ;KEYS OPEN COLD1: MOV @R0,A ;CLEAR BYTE INC R0 ;BUMP INDEX DJNZ R1,COLD1 ;DCR CNT UNTIL ZERO ;INITIALIZE BANK 0 REGISTERS MOV R0,A ;WORKING MOV R1,A ;KEY ARRAY POINTER MOV R2,A ;ROW CNT MOV R3,A ;DELTA DATA MOV R4,A ;ROTATED DATA MOV R5,A ;PWR-STATUS MOV R6,A ;BIT COUNT MOV R7,A ;KB STATE ;INITIALIZE BLINK MOV R0,#BLINK ;SET NDX TO CNTR MOV @R0,#K.BLINK ;AND LOAD INIT VALUE ;INITIALIZE BANK 1 REGISTERS ;INITIALIZE THE FIFO SEL RB1 ;BANK 1 REGISTERS MOV R2,#FIFO ;CLR FIFO-IN MOV R3,#FIFO ;CLR FIFO-OUT MOV R0,#FIFO ;SET NDX TO FIFO-OUT MOV @R0,#80H ;STUFF A BREAK CODE ;INITIALIZE NMI STATUS MOV R4,#0FFH ;TURN ON NMI STATUS ;BLINK ENABLED MOV R5,#20H ;ENABLE BLINK ;OTHER BANK 1 REGISTERS CLR A ;ZERO MOV R1,A ;6845 ADDR REG MOV R6,A ;ACCUM SAVE ;SETUP THE FLAGS CPL F1 ;CLR END OF FRAME CPL F0 ;CLR CURSER UPDATE ;SETUP THE EVENT COUNTER MOV A,#0FFH ;OVFL LESS ONE MOV T,A ;TO EVENT CNTR STRT CNT ;ENABLE CNTR ;ENABLE INTERRUPTS EN TCNTI ;ENABLE TIMER INT EN I ;ENABLE STALL INT ; ; THE MAIN LOOP ; ; WHILE NOT END OF FRAME ; 1. SEND OUT scan codes in FIFO ; 2. Poll Low Batt 1 or Low Batt 2 for change ; ; AT END OF FRAME: ; 1. Clear end of frame flag. ; 2. Update blink ; 3. NMI if curser updated ; 4. Scan keyboard ; MAIN: JF1 SENDOUT ;SKIP IF NOT END FRAME CPL F1 ;CLR END FRAME FLAG JMP FRAME1 ;EXECUTE END FRAME CODE ; ; SEND OUT - If the 8255 is not already busy, and if the FIFO ; is not empty, the next scan code in the buffer is sent to ; the 8255, the keyboard data available latch is set, and the ; output pointer is advanced. If the end of the FIFO is reached, ; the address is wraped forming a ring buffer. If either the ; FIFO is empty, or the 8255 is busy, this routine simply returns. ; ; Bank 1 Register Usage: ; R2 = FIFO Input Pointer ; R3 = FIFO Output Pointer - Updated ; Bank 0 Register Usage: ; R0 = Data is lost ; SENDOUT: JT0 PWRFAIL ;IF 8255 BUSY SEL RB1 ;BANK 1 REGISTERS MOV A,R3 ;FETCH FIFO-OUT XRL A,R2 ;CMPR FIFO-IN JZ PWRFAIL ;SKIP IF FIFO EMPTY MOV A,R3 ;FETCH IT AGAIN INC A ;AND BUMP IT JNZ SENDOUT1 ;SKIP IF NO OVFL MOV A,#FIFO ;WRAP THE FIFO SENDOUT1: MOV R3,A ;RESTORE THE PTR SEL RB0 ;BANK ZERO MOV R0,A ;TO NDX VIA A MOV A,@R0 ;READ BUF TO A OUTL P1,A ;AND THEN TO 8255 ORL P2,#KBDAV.P ;ASSERT CPU INT1 ANL P2,#0 ;NEGATE STROBES ; ; POWER FAIL - Test the extra port for Low Batt 2 and ; send a status 2 NMI if true. Test for changes in ; Lo Batt 1 and send status 6 NMI if different. Test ; for changes in AC On and send a status 18 NMI if ; different. Otherwise, return to the main poll loop. ; PWRFAIL: SEL RB0 ;BANK 0 REGISTERS JMP MAIN ;$$$ just for now MOV R0,#AUX.ENA ;SET NDX TO EXTRA PORT MOVX A,@R0 ;READ IN THE PORT JB1 PWRFAIL4 ;SKIP IF LOW BATT 2 XCH A,R5 ;SWAP NEW WITH OLD XRL A,R5 ;FIND CHANGES ANL A,#5 ;LOBAT1 OR ACON ? JZ PWRFAIL3 ;SKIP IF NEITHER JB2 PWRFAIL1 ;SKIP IF LOW BATT 1 MOV A,#AC.NMI ;LOAD NMI STATUS CODE JMP PWRFAIL2 ;EXECUTE NMI PWRFAIL1: MOV A,#BAT1.NMI ;LOAD STATUS FOR NMI PWRFAIL2: CALL NMI ;SEND THE NMI PWRFAIL3: JMP MAIN ;END OF POLLED FUNCTIONS PWRFAIL4: MOV A,#BAT2.NMI ;LOAD NMI STATUS CODE CALL NMI ;SET STATUS AND PULSE NMI PWRFAIL5: DIS I ;DISABLE EXT INTERRUPT DIS TCNTI ;DISABLE CNTR INTERRUPT JMP PWRFAIL5 ;HANG FOREVER ; ; TIMER INTERRUPT - A sync pulse has been received from ; the LCD display causing the event counter to overflow ; and generate an interrupt. Reset the counter to -1 ; and re-arm the timer interrupt. Clear F1 to indicate ; that end of frame has been reached. ; ; F1 Cleared ; TIMER: ;TIMER INT 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 ; ; NMI - Place the NMI status code from A into the NMI ; status register and pulse the CPU's NMI line. Poll ; the NMI status register until cleared. The polling ; and acknowledgement of the NMI status register by the ; CPU will be handled by the STALL interrupt routine. ; ; If NMI is already set, do not pulse CPU or wait. ; Return original code in A. If NMI is false on ; entry, load new code, pulse CPU and wait for ; an NMI acknowledge. Return a zero in A. ; ; A = NMI Status Code ; NMI: SEL RB1 ;IN REGISTER BANK 0 XCH A,R4 ;SWAP NEW & OLD JB7 NMI2 ;IF ALREADY NMI ON ORL P2,#NMIRQ.P ;ASSERT NMI REQUEST NMI1: MOV A,R4 ;FETCH NMI STATUS JNZ NMI1 ;LOOP UNTIL CLEARED ANL P2,#0 ;NEGATE STROBES RET NMI2: XCH A,R4 ;RESTORE OLD CODE RET ; ; AUTO REPEAT - SENDSCAN clears REPEAT. This ; routine will increment repeat. Once bit 7 ; is set, it latches 6 & 7. Based on the MSBs: ; 00 Delay - No Output ; 01 Repeat - 5 cps ; 10 Repeat - 10 cps ; 11 Repeat - 15 cps ; The output rate is controlled by the LSBs: ; 0000 5 cps ; d000 10 cps ; dd00 20 cps ; The character at FIFO-IN is sent unless ; it is a break code. ; FRAME4: MOV R0,#REPEAT ;SET NDX TO CNTR MOV A,@R0 ;AND FETCH IT JB7 RPT2 ;SPEED 2 OR 3 JB6 RPT1 ;SPEED 1 INC A ;DELAYING MOV @R0,A ;RESTORE JMP MAIN ;DONE FOR NOW ;SPEED 1 RPT1: MOV R6,#07H ;FOR 10 CPS JMP RPT4 ; RPT2: JB6 RPT3 ;IF SPEED 3 ;SPEED 2 MOV R6,#03H ;FOR 20 CPS JMP RPT4 ; ;SPEED 3 RPT3: MOV R6,#01H ;FOR 40 CPS INC A ;BUMP ORL A,#0F0H ;LATCH HI BITS JMP RPT5 ;CONT RPT4: INC A ;BUMP RPT5: MOV @R0,A ;RESTORE ANL A,R6 ;MASK LSBS JNZ RPT6 ;NOT TIME YET SEL RB1 ;TO FIFO BANK MOV A,R2 ;FETCH FIFO-OUT SEL RB0 ;RESTORE BANK MOV R0,A ;ADDR TO NDX MOV A,@R0 ;LAST SCAN CODE JB7 RPT6 ;EXIT IF BREAK MOV R0,A ;HOLD IN R0 CALL SENDSCAN ;REPEAT IT SEL RB0 ;RESTORE BANK XCH A,R0 ;SWAP ADDR & DATA MOV @R0,A ;SEND DATA TO FIFO RPT6: JMP MAIN ;AND DONE PAGE ; ; START OF SECOND PAGE ; ORG ROM.ORG+100H ; ; STALL INTERRUPT - This interrupt is invoked whenever the ; CPU accesses an I/O port in the range reserved for the ; IBM Color / Graphics adapter. The hardware features of ; these boards which will be emulated by this code inlcude ; the 6845, the MODE register, and the STATUS register. ; Accesses of the SELECT register and the light pen latch ; will be ignored. The interrupt response time must be ; minimized as the CPU is held in a wait state inhibiting ; refresh cycles until it is released. The interrupt ; response time for a port write operation is 18 cycles. ; ; ; THE PORT TABLE: ; The least significant four bits of the CPU address ; and the state of the IORS (I/O Read Status) line are ; read through a port and a 32 entry table is then used ; to call potentially unique routines for reading or ; writing any of the sixteen port addresses associated ; with the color graphics boars. ; ; Processor Address Port: A2 /IOR A3 A1 A0 ; ; The table will dispatch the code to: ; EXIT Illegal or Ignored Access ; WCRTADDR Write 6845 address register ; RCRTDATA Read 6845 data register ; WCRTDATA Write 6845 data register ; WMODE Write MODE register ; RSTAT Read STATUS register ; PORT.TBL: 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 COLOR SELECT DB EXIT ;WA WRITE STATUS DB EXIT ;WB LIGHT PEN CLEAR DB EXIT ;R4 READ 6845 ADDR DB RCRTDATA ;R5 READ 6845 DATA DB EXIT ;R6 READ 6845 ADDR DB RCRTDATA ;R7 READ 6845 DATA DB EXIT ;RC READ MODE REG DB EXIT ;RD READ SELECT DB EXIT ;RE READ STATUS DB EXIT ;RF LIGHT PEN CLEAR DB WCRTADDR ;W4 WRITE 6845 ADDR DB WCRTDATA ;W5 WRITE 6845 DATA DB WCRTADDR ;W6 WRITE 6845 ADDR DB WCRTDATA ;W7 WRITE 6845 DATA DB EXIT ;WC LIGHT PEN SET DB EXIT ;WD NOT USED DB EXIT ;WE NOT USED DB EXIT ;WF NOT USED ; ; 6845 ADDRESS TABLE: ; The 6845 requires only two addresses in its ; interface while its internal structure proivides ; eighteen bytes of registers. The first accessable ; address is a pointer register used to select which ; of the internal registers is to be accessable through ; the second. This table is used to dispatch on the ; data which the CPU is attempting to write to the ; 6845's address register. ; ; A number of hardware features unique to the PIVOT have ; been concealed in registers added to the emulated 6845. ; Since these features may be accessed by the operating ; system or within an NMI, and the accesses requires a ; pair of cycles (one to set the address register and ; one to access the data register), mechanisms are ; provided for preserving address pointers of lower ; levels as higher levels are accessed. ; ; This table will dispatch to: ; WADDR Load Addres ; EXIT Ignore Address - Illegal ; NMIADR Push to SAVE2 - Load ; TRANADR Push to SAVE1 - Load ; ADDR.TBLº DB WADDR ;A0 DB WADDR ;A1 DB WADDR ;A2 DB WADDR ;A3 DB WADDR ;A4 DB WADDR ;A5 DB WADDR ;A6 DB WADDR ;A7 DB WADDR ;A8 DB WADDR ;A9 DB WADDR ;A10 DB WADDR ;A11 DB WADDR ;A12 DB WADDR ;A13 DB WADDR ;A14 DB WADDR ;A15 DB WADDR ;A16 DB WADDR ;A17 DB NMIADR ;A18 DB TRANADR ;A19 DB TRANADR ;A20 DB TRANADR ;A21 DB EXIT ;A22 DB EXIT ;A23 DB EXIT ;A24 DB EXIT ;A25 DB EXIT ;A26 DB EXIT ;A27 DB EXIT ;A28 DB EXIT ;A29 DB EXIT ;A30 DB EXIT ;A31 ; ; 6845 DATA REGISTER TABLE: ; The routines which this table passed execution to ; will normally read or write the 6845 register ; indicated by the current value in the address ; register. ; ; There are two types of accesses permitted to the ; added registers. Operating system accesses of ; registers 19-21 make transient use of the address ; register in that its value prior to selection of ; one of these registers is restored (from SAVE1) ; following the next data register access. Setting ; the address register to R18 indicates the start ; of an NMI routine causing the current state of ; the address register to be saved in SAVE2. Any ; write to R18 will clear the NMI state and restore ; the address register from SAVE2. Within an NMI, ; any number of other address or data accesses may ; be made. ; ; This table will dispatch to: ; RD.REG Read Register ; WR.REG Write Register ; EXIT Return FFh - Illegal ; RD.18 Return NMI status code ; RD.21 Return Extra, Pop SAVE1* ; WR.18 End NMI, Pop SAVE2 ; WR.19 Write Switch, Pop SAVE1* ; WR.20 Write Display, Pop SAVE1* ; WR.21 Write FDC ON, Pop SAVE1* ; ; * SAVE1 is popped only if NMI is off ; RD.TBL DB RD.REG ;R0 DB RD.REG ;R1 DB RD.REG ;R2 DB RD.REG ;R3 DB RD.REG ;R4 DB RD.REG ;R5 DB RD.REG ;R6 DB RD.REG ;R7 DB RD.REG ;R8 DB RD.REG ;R9 DB RD.REG ;R10 DB RD.REG ;R11 DB RD.REG ;R12 DB RD.REG ;R13 DB RD.REG ;R14 DB RD.REG ;R15 DB RD.REG ;R16 DB RD.REG ;R17 DB RD.18 ;R18 DB EXIT ;R19 DB EXIT ;R20 DB RD.21 ;R21 DB EXIT ;R22 DB EXIT ;R23 DB EXIT ;R24 DB EXIT ;R25 DB EXIT ;R26 DB EXIT ;R27 DB EXIT ;R28 DB EXIT ;R29 DB EXIT ;R30 DB EXIT ;R31 STALL: SEL RB1 ;BANK 1 REGISTERS MOV R6,A ;SAVE A IN R6 MOV R0,#PA.ENA ;PROC ADDR TO NDX MOVX A,@R0 ;ADDR TO A ANL A,#1FH ;MASK TO 5 BITS ; ADD A,#PORT.TBL AND 0FFH ;TABLE ADDR IS ZERO JMPP @A ;JUMP THROUGH TABLE EXIT: ORL P2,#PACK.P ;RELEASE HOST PROC ANL P2,#0 ;NEGATE STROBE EXIT1: MOV A,R6 ;RESTORE A RETR ;AND RETURN WDATA: MOV R0,#PD.ENA ;DATA ADDR TO NDX MOVX A,@R0 ;DATA TO ACC ORL P2,#PACK.P ;RELEASE HOST PROC ANL P2,#0 ;NEGATE STROBE RET WMODE: CALL WDATA ;ACCEPT THE DATA MOV R0,A ;HOLD IN R0 ANL A,#20H ;EXTRACT BLINK XCH A,R5 ;SWAP WITH DISP STAT ANL A,#0DFH ;MASK OUT BLINK ORL A,R5 ;MERGE NEW VALUE MOV R5,A ;RESTORE STATUS MOV A,R0 ;RECALL NEW DATA ANL A,#00010010B ;MASK GRAPH & HIRES MOV R0,A ;HOLD IN R0 MOV A,R7 ;FETCH SHADOW ANL A,#11101101B ;KEEP THE REST ORL A,R0 ;MERGE THE BITS MOV R7,A ;UPDATE SHADOW MOV R0,#DS.STB ;SET NDX TO DISP MOVX @R0,A ;UPDATE DISP CTL REG MOV A,R6 ;RESTORE A RETR ;AND DONE RSTAT: MOV A,R5 ;STATUS REG TO A CALL RDATA ;REL CPU WITH DATA XRL A,#09H ;TGL SYNC & ENABLE MOV R5,A ;RESTORE STATUS MOV A,R6 ;RESTORE A RETR ;END OF INTERRUPT RDATA: MOV R0,#PD.STB ;SET NDX TO CPU DATA MOVX @R0,A ;AND OUTPUT THE DATA ORL P2,#PACK.P ;RELEASE HOST PROC ANL P2,#0 ;NEGATE STROBE RET WCRTADDR: CALL WDATA ;FETCH THE CPU DATA ANL A,#1FH ;MASK TO FIVE BITS MOV R0,A ;HOLD COPY IN R0 ADD A,#ADDR.TBL AND 0FFH ;OFST TO TABLE BASE JMPP @A ;JMP INDIRECT WADDR: MOV A,R0 ;MOVE VIA A MOV R1,A ;TO R1 MOV A,R6 ;RESTORE A RETR ;AND DONE NMIADR: MOV A,R4 ;FETCH NMI STATUS JB7 WADDR ;SKIP IF NMI SET ORL A,#80H ;IF NOT, SET IT MOV R4,A ;RESTORE NMI STATUS MOV A,R0 ;RECALL NEW ADDR XCH A,R1 ;SWAP WITH OLD MOV R0,#SAVE2 ;SET NDX TO SAVE2 MOV @R0,A ;PUSH OLD R1 MOV A,R6 ;RESTORE A RETR ;AND DONE TRANADR: MOV A,R4 ;FETCH NMI STATUS JB7 WADDR ;SKIP IF NMI SET MOV A,R0 ;RECALL NEW ADDR XCH A,R1 ;SWAP OLD WITH NEW MOV R0,#SAVE1 ;SET NDX TO SAVE1 TRANADR1: MOV @R0,A ;PUSH OLD R1 MOV A,R6 ;RESTORE A RETR ;AND DONE WCRTDATA: JMP WCRTDAT1 ;CHANGE PAGES RCRTDATA: MOV A,R1 ;FETCH THE ADDR ADD A,#RD.TBL AND 0FFH ;READ DATA TABLE JMPP @A ;INDIRECT THRU TABLE RD.REG: MOV A,R1 ;FETCH REG NUMBER ADD A,#CRT.REG ;ADD RAM OFST MOV R0,A ;COPY TO NDX MOV A,@R0 ;AND READ DATA CALL RDATA ;SEND DATA AND REL CPU JMP EXIT1 ;AND END INTERRUPT RD.18: MOV A,R4 ;FETCH NMI STATUS ANL A,#7FH ;MASK ACTIVE FLAG CALL RDATA ;RETURN DATA JMP EXIT1 ;AND END INTERRUPT RD.21: MOV R0,#AUX.ENA ;SET NDX TO AUX PORT MOVX A,@R0 ;AND READ PORT CALL RDATA ;DATA TO CPU JMP WR.EXIT ;USE WRITE'S EXIT PAGE ; ; START OF THIRD PAGE OF ROM ; ORG ROM.ORG+200H ; ; 6845 DATA REGISTER TABLE: ; The routines which this table passed execution to ; will normally read or write the 6845 register ; indicated by the current value in the address ; register. ; ; There are two types of accesses permitted to the ; added registers. Operating system accesses of ; registers 19-21 make transient use of the address ; register in that its value prior to selection of ; one of these registers is restored (from SAVE1) ; following the next data register access. Setting ; the address register to R18 indicates the start ; of an NMI routine causing the current state of ; the address register to be saved in SAVE2. Any ; write to R18 will clear the NMI state and restore ; the address register from SAVE2. Within an NMI, ; any number of other address or data accesses may ; be made. ; ; This table will dispatch to: ; WR.REG Write Register ; WEXIT Return FFh - Illegal ; WR.18 End NMI, Pop SAVE2 ; WR.19 Write Switch, Pop SAVE1* ; WR.20 Write Display, Pop SAVE1* ; WR.21 Write FDC ON, Pop SAVE1* ; ; * SAVE1 is popped only if NMI is off ; WR.TBL DB WR.REG ;W0 DB WR.REG ;W1 DB WR.REG ;W2 DB WR.REG ;W3 DB WR.REG ;W4 DB WR.REG ;W5 DB WR.REG ;W6 DB WR.REG ;W7 DB WR.REG ;W8 DB WR.REG ;W9 DB WR.REG ;W10 DB WR.REG ;W11 DB WR.REG ;W12 DB WR.REG ;W13 DB WR.CUR ;W14 DB WR.CUR ;W15 DB WR.REG ;W16 DB WR.REG ;W17 DB WR.18 ;W18 DB WR.19 ;W19 DB WR.20 ;W20 DB WR.21 ;W21 DB WEXIT ;W22 DB WEXIT ;W23 DB WEXIT ;W24 DB WEXIT ;W25 DB WEXIT ;W26 DB WEXIT ;W27 DB WEXIT ;W28 DB WEXIT ;W29 DB WEXIT ;W30 DB WEXIT ;W31 WEXIT: ORL P2,#PACK.P ;RELEASE HOST PROC ANL P2,#0 ;NEGATE STROBE WEXIT1: MOV A,R6 ;RESTORE A RETR ;AND RETURN WCRTDAT1: MOV R0,#PD.ENA ;DATA ADDR TO NDX MOVX A,@R0 ;DATA TO ACC ORL P2,#PACK.P ;RELEASE HOST PROC ANL P2,#0 ;NEGATE STROBE MOV R0,A ;HOLD IN R0 MOV A,R1 ;FETCH THE ADDR ; ADD A,#WR.TBL AND 0FFH ;WRITE DATA TABLE JMPP @A ;INDIRECT THRU TABLE WR.CUR: MOV A,R5 ;FETCH DISPLAY STATUS ORL A,#80H ;TURN ON CURSER UPDATE MOV R5,A ;RESTORE DISP STAT WR.REG: MOV A,R1 ;FETCH REG NUMBER ADD A,#CRT.REG ;ADD BASE ADDR XCH A,R0 ;SWAP ADDR & DATA MOV @R0,A ;STORE DATA TO ADDR MOV A,R6 ;RESTORE A RETR ;AND DONE ;WRITE NMI STATUS REGISTER WR.18: MOV R4,#0 ;CLR NMI STATUS MOV R0,#SAVE2 ;SET NDX TO SAVE2 MOV A,@R0 ;AND RESTORE MOV R1,A ;VIA A MOV A,R6 ;RESTORE A RETR ;AND DONE ;WRITE SWITCH REGISTER WR.19: SEL RB0 ;FROM BANK 0 MOV A,R5 ;FETCH PWR-STAT JB3 WR1.19 ;AND TEST FDC ON MOV A,#SW.STB ;SWITCH W/FDC-OFF JMP WR2.19 ; WR1.19 MOV A,#SW.STB+40H ;SWITCH W/FDC-ON WR2.19 SEL RB1 ;BACK TO BANK 1 XCH A,R0 ;SWAP ADDR & DATA MOVX @R0,A ;AND WRITE SWITCH MOV R0,#SWITCH ;SET NDX TO SHADOW MOV @R0,A ;AND SAVE A COPY JMP WR.EXIT ;TRANSIENT EXIT ;WRITE DISPLAY CONTROL PORT WR.20: MOV A,#11001101B ;NEW BIT MASK ANL A,R0 ;ON NEW DATA XRL A,#80H ;TOGGLE CUR ENA MOV R0,A ;BACK ON HOLD MOV A,#00110010B ;OLD BIT MASK ANL A,R7 ;ON OLD DATA ORL A,R0 ;MERGE BITS MOV R7,A ;UPDATE SHADOW MOV R0,#DS.STB ;SET NDX TO DISP MOVX @R0,A ;AND UPDATE DISP JMP WR.EXIT ;TRANSIENT EXIT ;WRITE FDC-ON WR.21: MOV A,R0 ;RECALL NEW DATA CLR F0 ;ASSUME MOTOR ON JB3 WR1.21 ;TEST FDC-ON CPL F0 ;SET MOTOR OFF WR1.21: MOV R0,#SWITCH ;SET NDX TO SWITCH MOV A,@R0 ;AND LOAD VALUE MOV R0,A ;HOLD DATA IN R0 MOV A,#SW.STB ;LOAD SW PORT ADDR JF0 WR2.21 ;SKIP IF FDC-OFF ADD A,#40H ;SET FDC-ON BIT WR2.21: XCH A,R0 ;SWAP ADDR & DATA MOVX @R0,A ;AND WRITE THE PORT WR.EXIT: MOV A,R4 ;FETCH NMI STATUS JB7 WR.EXIT1 ;SKIP IF NMI SET MOV R0,#SAVE1 ;SET NDX TO SAVE1 MOV A,@R0 ;AND RESTORE R1 MOV R1,A ;VIA A WR.EXIT1: MOV A,R6 ;RESTORE A RETR ;AND DONE ; ; SEND SCAN - This routine will return the address of ; the next available FIFO-IN location. If the FIFO is ; full, this location will be the same as the previous ; location and the pointer will not be incremented. ; ; Called By SCANCODE and REPEAT, Returns in RB0 ; ; Bank 1 Register Usage: ; R2 = FIFO Input Pointer - Updated ; R3 = FIFO Output Pointer ; Bank 0 Register Usage: ; SENDSCAN: SEL RB1 ;BANK 1 REGISTERS MOV A,R2 ;FETCH FIFO-IN INC A ;BUMP PTR JNZ SNDSCAN1 ;SKIP IF NOT OVFL MOV A,#FIFO ;WRAP THE FIFO SNDSCAN1: XRL A,R3 ;CMP FIFO-OUT JZ SNDSCAN2 ;SKIP IF BUF FULL XRL A,R3 ;RESTORE ADDR MOV R2,A ;UPDATE FIFO-IN RET ;AND DONE SNDSCAN2: MOV A,R2 ;FETCH OLD VALUE RET PAGE ; ; START OF FOURTH PAGE OF ROM ; ; ; LOOKUP SCAN CODE - A scan code is looked up for each ; bit set in the accumulator assuming that R1 indicates ; the matrix row from which the data was obtained. If ; bit 7 is set in the located code, an NMI is generated ; using the balance of the code as a status. Otherwise, ; 80H is added to the locaed code if F0 was set and the ; result is placed in the FIFO. ; ; Bank 0 Register Usage: ; A = Image of Changed Keys ; R2 = 13 - Matrix Row Number ; F0 = Generate Break Codes ; ; A = Scan Code or NMI Status ; R4 = Save Rotated Delta ; R6 = Save Bit Counter ; R7 = Current Keyboard State ; ORG ROM.ORG+300H ;TABLE AT X00 ; BIT 0 1 2 3 4 5 6 7 SCANTBL: DB 3BH,3DH,3FH,42H,44H,X09,X07,00H ;ROW12 DB 3CH,3EH,40H,41H,43H,X0A,X08,00H ;ROW11 DB 0EH,X1C,X05,X12,X0F,X0C,X13,X14 ;ROW10 DB X06,1CH,X0D,X11,X0E,X0B,X10,32H ;ROW9 DB 1AH,00H,X15,07H,15H,23H,19H,31H ;ROW8 DB X03,2BH,X16,06H,14H,22H,X17,30H ;ROW7 DB 0FH,X19,0CH,04H,12H,20H,0BH,2EH ;ROW6 DB X04,1BH,X1B,03H,11H,1FH,X18,2DH ;ROW5 DB 3AH,X00,00H,05H,13H,21H,39H,2FH ;ROW4 DB 01H,00H,X01,02H,10H,1EH,X1A,2CH ;ROW3 DB 00H,00H,00H,00H,00H,00H,00H,X02 ;ROW2 DB 00H,00H,00H,00H,00H,00H,00H,38H ;ROW1 SCANCODE: MOV R6,#8 ;INITIATE CNT SC1: RLC A ;NEXT BIT TO CRY JNC SC8 ;SKIP IF NOT SET MOV R4,A ;SAVE ROTATED DELTA MOV A,R2 ;GET ROW INDEX DEC A ;ADJUST TO 11-0 RL A ;AND SHIFT UP - 1 RL A ; - 2 RL A ; - 3 ADD A,R6 ;MERGE THE BIT NUMBER DEC A ;DECR FOR 8-1 TO 7-0 MOVP A,@A ;AND FETCH THE CODE JB7 SC.CONV ;SKIP IF EXEC CODE JF0 SC.BRK ;SKIP IF BREAK MOV R0,A ;HOLD DATA IN R0 CALL SENDSCAN ;GET AN ADDR SEL RB0 ;RESTORE BANK XCH A,R0 ;SWAP DATA & ADDR MOV @R0,A ;AND STORE DATA SC5: MOV R0,#BOUNCE ;SET NDX TO BOUNCE MOV A,R2 ;GET ROW NUMBER ADD A,#-3 ;LOOP CNT > 2 ? JNC SC6 ;YES, USE SHORT DLY MOV @R0,#KBDB.S ;LOAD SHORT DELAY JMP SC7 ;AND CONT SC6: MOV @R0,#KBDB.L ;LOAD LONG DELAY SC7: MOV A,R4 ;RESTORE ROTATED DATA SC8: DJNZ R6,SC1 ;REPEAT FOR 8 BITS MOV R0,#REPEAT ;SET NDX TO RERPEAT MOV @R0,#0 ;AND RESET IT RET ;AND DONE SC.CONV: CALL CONVERT ;SKIP TO NEXT PAGE JF0 SC7 ;NO DEBOUNCE ON BREAK JMP SC5 ;SET DEBOUNCE SC.BRK: ORL A,#80H ;ADD BREAK BIT MOV R0,A ;HOLD DATA IN R0 CALL SENDSCAN ;SEND CODE SEL RB0 ;RESTORE BANK XCH A,R0 ;SWAP ADDR & DATA MOV @R0,A ;STORE DATA JMP SC7 ;NO DEBOUNCE ; ; FRAME1 - Generate CPU NMI is curser register has ; been updated since the last end of frame. ; FRAME1: SEL RB1 ;BANK1 REGISTERS MOV A,R5 ;FETCH DISPLAY STATUS ANL A,#80H ;MASK CURSER UPDATE JZ FRAME2 ;SKIP IF NOT SET XRL A,R5 ;CLR UPDATE BIT MOV R5,A ;AND RESTORE STATUS MOV A,#CUR.NMI ;LOAD NMI STATUS CODE CALL NMI ;AND SEND NMI ; ; BLINK - Skip out if Blink is disabled. Otherwise ; bump the blinkin count. Reset the count and ; toggle the blink bit of the display control ; register on overflow. ; FRAME2: MOV A,R5 ;FETCH DISPLAY STATUS JB5 FRAME21 ;SKIP IF BLINK ENABLED MOV A,R7 ;FETCH DISP CTL ANL A,#0DFH ;CLR BLINK BIT JMP FRAME23 ;AND UPDATE FRAME21: MOV R0,#BLINK ;SET NDX TO BLINK MOV A,@R0 ;FETCH THE VARIABLE INC A ;AND BUMP IT JZ FRAME22 ;SKIP IF ZERO MOV @R0,A ;RESTORE THE CNTR JMP FRAME3 ;AND GO ON FRAME22: MOV @R0,#-K.BLINK ;RE INIT CNTR MOV A,R7 ;FETCH CONTROL BYTE XRL A,#BLINK.B ;TOGGLE BLINK BIT FRAME23: MOV R0,#DS.STB ;POINT TO DISP REG MOVX @R0,A ;AND MOVE OUT ACC MOV R7,A ;RESTORE TO REG ;********************************************************** ;* KEYBOARD SCAN - The following code sequence will ;* scan the key matrix for changes once per frame ;* time of the LCD display. Key operations are ;* translated into scan codes and loaded into the ;* FIFO for tranmission to the CPU. ICON keys ;* assert NMI and present status codes. Detection ;* of the simultaneous assertion of CTL, ALT and DEL ;* will result in a RESET of the CPU. ;********************************************************** FRAME3: ; ; DEBOUNCE - If there is debounce time remaining, ; decrement the time and skip reading the keyboard ; for this frame time of the display. ; SEL RB0 ;BANK ZERO REGISTERS MOV R0,#BOUNCE ;SET NDX TO BOUNCE MOV A,@R0 ;FETCH DEBOUNCE JZ KBSCAN1 ;SKIP IF ZERO DEC A ;DECR BALANCE MOV @R0,A ;AND RESTORE JMP MAIN ;TILL NEXT FRAME ; ; READ KEY MATRIX - The twelve rows of the key matrix ; are read into the corresponding even byte locations ; in the 24 byte structure KEY-ARRAY. ; KBSCAN1: MOV R0,#4 ;FIRST KB ROW MOV R1,#KARRAY ;FIRST KEY ARRAY BYTE MOV R2,#12 ;FOR TWELVE ROWS KBSCAN2: MOVX @R0,A ;SELECT KB ROW INC R0 ;MOVE TO KB DATA MOVX A,@R0 ;READ KB ROW DATA MOV @R1,A ;AND SAVE IN ARRAY INC R0 ;ADVANCE KB ROW INC R0 ;BY THREE MORE TO INC R0 ;NEXT KB ROW INC R1 ;ADVANCE BY TWO TO INC R1 ;NEXT NEW ARRAY ENTRY DJNZ R2,KBSCAN2 ;DECR ROW CNT ; ; LOCATE CHANGED KEYS - The current state of the ; key matrix is compared with the previous state. ; Changes are processed. ; KBSCAN3: MOV R1,#KARRAY ;START OF KARRAY MOV R2,#12 ;FOR EACH ROW KBSCAN4: MOV A,@R1 ;FETCH NEW DATA INC R1 ;NDX TO OLD DATA XCH A,@R1 ;XCHG NEW WITH OLD XRL A,@R1 ;LOCATE CHANGES JZ KBSCAN6 ;SKIP IF NONE CLR F0 ;SET KEY MAKE MOV R3,A ;SAVE A COPY ANL A,@R1 ;FIND THE MAKES JZ KBSCAN5 ;SKIP IF NONE CALL SCANCODE ;PROCESS MAKES KBSCAN5: MOV A,@R1 ;XOR COMPLEMENT CPL A ;OF NEW DATA WITH ANL A,R3 ;WITH CHANGES TO JZ KBSCAN6 ;FIND BREAKS - ANY? CPL F0 ;INDICATE BREAKS CALL SCANCODE ;PROCESS BREAKS KBSCAN6: INC R1 ;BUMP TO NEXT NEW DJNZ R2,KBSCAN4 ;LOOP FOR ALL ROWS JMP FRAME4 ;TO CHANGE PAGE ; ; START OF FIFTH PAGE OF ROM ; ; ; CONVERT - The SCANCODE routine will convert keyboard ; column/row information to either a PC equivalent scan ; code or to a special conversion code which will be ; indicated by bit 7 being a 1. This routine will ; further decode this information. ; ; A = Output of scan code table with B7 = 1 ; ; F0 = 1 for break, 0 for make. ; ; The keyboard state is held in R7 of bank 0: ; ; b7 b6 b5 b4 b3 b2 ; ls rs ctl num ins scroll ; ; The Rom Bios will handle: ; ; Left Arrow / Home ; Right Arrow / End ; Up Arrow / Page Up ; Down Arrow / Page Down ; Print Screen ; ORG ROM.ORG+400H ;TABLE AT X00 XX00: DB CONV.LS ;LEFT SHIFT KEY, 4.1 DB 02AH DB 0 XX01: DB CONV.RS ;RIGHT SHIFT KEY, 3.2 DB 036H DB 0 XX02: DB CONV.CTL ;CONTROL KEY, 2.7 DB 01DH DB 01DH XX03: DB CONV.LCK ;LOCK KEY, 7.0 DB 045H ;NUM LOCK DB 046H ;SCROLL LOCK XX04: DB CONV.DEL ;DELETE KEY, 5.0 DB 053H ;DELETE DB 052H ;INSERT XX05: DB CTLKEYS ;BREAK, 4.4 DB 00DH ;= DB 046H ;SCROLL LOCK XX06: DB CTLKEYS ;PRINTER ON, 9.0 DB 028H ;' DB 019H ;^P XX07: DB ICONS ;CLOCK ICON, 12.6 DB 10 ;NMI STATUS CODE DB 0 XX08: DB ICONS ;PHONE ICON, 11.6 DB 12 DB 0 XX09: DB ICONS ;DISK ICON, 12.5 DB 14 DB 0 XX0A: DB ICONS ;CALCULATOR ICON, 11.5 DB 16 DB 0 XX0B: DB NUMPAD ;FUNCTION OF NUM LOCK, 9.5 DB 024H ;J - Alpha Key Board DB 04FH ;1 - Numeric Key Pad XX0C: DB NUMPAD ; 10.5 DB 025H ;K DB 050H ;2 XX0D: DB NUMPAD ; 9.2 DB 026H ;L DB 051H ;3 XX0E: DB NUMPAD ; 9.4 DB 016H ;U DB 04BH ;4 XX0F: DB NUMPAD ; 10.4 DB 017H ;I DB 04CH ;5 XX10: DB NUMPAD ; 9.6 DB 018H ;O DB 04DH ;6 XX11: DB NUMPAD ; 9.3 DB 008H ;7 DB 047H ;7 XX12: DB NUMPAD ; 10.3 DB 009H ;8 DB 048H ;8 XX13: DB NUMPAD ; 10.6 DB 00AH ;9 DB 049H ;9 XX14: DB NUMPAD ; 10.7 DB 033H ;, DB 052H ;0 XX15: DB NUMPAD ; 8.2 DB 035H ;/ DB 04EH ;+ XX16: DB NUMPAD ; 7.2 DB 027H ;; DB 04AH ;- XX17: DB NUMPAD ; 7.6 DB 34H ;. DB 53H ;. XX18: DB ARROW ;FUNCTION OF SHIFT, 5.6 DB 4BH ;< DB 47H ;Home XX19: DB ARROW ; 6.1 DB 4DH ;> DB 4FH ;End XX1A: DB ARROW ; 3.6 DB 48H ;^ DB 49H ;Page Up XX1B: DB ARROW ; 5.2 DB 50H ;V DB 51H ;Page Down XX1C: DB CTLKEYS ;Print Screen, 10.1 DB 29H ;` DB 37H ;* CONVERT: ANL A,#7FH ;MASK BIT 7 JMPP @A ;INDIRECT THRU TBL ; ; STATE KEYS - This routine will maintain the states ; of LS, RS, CTL and NUM LOCK. ; CONV.LS: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JF0 CONV.LS1 ;SKIP IF BREAK ORL A,#80H ;SET LS BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;AND SEND FIRST ARG CONV.LS1: ANL A,#7FH ;CLR LS BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;AND SEND FIRST ARG CONV.RS: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JF0 CONV.RS1 ;SKIP IF BREAK ORL A,#40H ;SET RS BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;AND SEND FIRST ARG CONV.RS1: ANL A,#0BFH ;CLR RS BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;AND SEND FIRST ARG CONV.CTL: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JF0 CNV.CTL1 ;SKIP IF BREAK ORL A,#20H ;SET CTL BIT MOV R7,A ;RESTOEE STATE JMP ARG1 ;AND SEND FIRST ARG CNV.CTL1: ANL A,#0DFH ;CLR CTL BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;AND SEND FIRST ARG CONV.LCK: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JB5 ARG1 ;SND NUM LOCK IF CTL JF0 CNV.LCK2 ;SKIP IF BREAK JB7 CNV.LCK1 ;SEND SCROLL LOCK JB6 CNV.LCK1 ; IF EITHER SHIFT ANL A,#0FBH ;CLR SCROLL BIT XRL A,#10H ;TOGGLE NUM LOCK MOV R7,A ;RESTORE STATE JMP ARG1 ;SEND NUM LOCK CNV.LCK1: ORL A,#04H ;SET SCROLL BIT MOV R7,A ;RESTORE STATE JMP ARG2 ;SEND SCROLL CNV.LCK2: JB2 ARG2 ;BREAK SCROLL LOCK JMP ARG1 ;BREAK NUM LOCKLOCK CONV.DEL: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JF0 CNV.DEL2 ;SKIP IF BREAK JB7 CNV.DEL1 ;SEND INSERT IF JB6 CNV.DEL1 ; EITHER SHIFT ANL A,#0F7H ;CLR INS BIT MOV R7,A ;RESTORE STATE JMP ARG1 ;SEND DELETE CNV.DEL1: ORL A,#08H ;SET INS BIT MOV R7,A ;RESTORE STATE JMP ARG2 ;SEND INSERT CNV.DEL2: JB3 ARG2 ;BREAK INSERT JMP ARG1 ;BREAK DELETE ; ; CONTROL FUNCTIONS - This routine handles "Prt On" ; which will send a CTL-P, and "Break" which will send a ; CTL-SCROLL LOCK. "Pause" is handled by CONV.LOCK: ; CTLKEYS: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JB5 ARG2 ;SKP IF CTL TO 2ND ARG JMP ARG1 ;JMP TO FIRST ARG ; ; NUMERIC KEYPAD - Keys in the range of the numeric ; keypad will come through here. If NUM LOCK is false ; the normal key function will be transmitted. If NUM LOCK ; is true, the numeric keypad equivalent will be transmitted. ; NUMPAD: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JB4 ARG2 ;SKIP IF NUM LOCK ARG1: MOV A,R0 ;RECALL ENTRY INC A ;ADDR FIRST ARG JMP ARGS ;AND CONTINUE ARG2: MOV A,R0 ;RECALL ENTRY ADD A,#2 ;ADDR SECOND ART ARGS: MOVP A,@A ;FETCH THE ARG JF0 ARGS2 ;SKIP IF KEY BREAK JMP ARGS3 ; ARGS2: ADD A,#80H ;ADD BREAK BIT ARGS3: MOV R0,A ;HOLD DATA IN R0 CALL SENDSCAN ;SEND THE BREAK SEL RB0 ;RESTORE BANK XCH A,R0 ;SWAP ADDR & DATA MOV @R0,A ;STORE THE DATA RET ;AND DONE ; ; ARROW KEYS - If NUM LOCK is active, these keys ; send the arrow key scan code. If not, they ; send either the arrow key or function key ; depending on the shift stat. ; ARROW: MOV R0,A ;HOLD ENTRY IN R0 MOV A,R7 ;FETCH STATE JB4 ARG1 ;IF NUM LOCK JB7 ARG2 ;IF LEFT SHIFT JB6 ARG2 ;IF RIGHT SHIFT JMP ARG1 ;IF UN-SHIFTED ; ; ICON KEYS - Icon keys will execute this code. If ; processing a key make, the NMI status code for the ; key will be transmitted by the NMI routine. ; ICONS: JF0 ICONS1 ;SKIP IF BREAK INC A ;FIRST ARG MOVP A,@A ;FETCH NMI STATUS CALL NMI ;AND SEND CODE SEL RB0 ;RESTORE REG BANK ICONS1: RET ;AND DONE END CPÕ <--¾ KEYBOARÄ PROCESSOÒ COMMUNICATIONÓ (21_Jan_85) Iî  additioî  tï  keyboarä  scanning¬  thå  keyboarä  processoò provideó á numbeò oæ otheò systeí functionó includinç  simulatioî oæ  thå softwarå accessablå featureó oæ thå PC'ó  coloò  graphicó boarä  anä  providinç accesó tï thå hardwarå featureó  whicè  arå uniquå ôï thió machine® Coloò  Graphicó Adapteò Hardwarå ­ Iæ thå CPÕ accesseó  aî  I/Ï porô  iî  thå rangå reserveä foò thå coloò graphicó  adapter¬  iô wilì bå helä (usinç thå Readù line© untiì thå keyboarä  processoò caî accepô oò supplù thå requireä data® Thå followinç  functionó arå supported: 684µ Addresó Registeò ­ WO 684µ  Datá  Registeró  ­ R/× ­ Alì 1¸  oæ  thå  6845'ó  datá      registeró  arå  implementeä usinç raí  withiî  thå  keyboarä      processor® Updatinç eitheò oæ thå curseò registeró (R1´  oò      R15©  wilì  causå aî NMÉ tï bå generateä aô thå enä  oæ  thå      currenô   frame®   Seå  NMÉ  codeó  below®   Iæ   thå   mosô      significanô  bytå oæ thå STARÔ ADDRESÓ registeò  ió  writteî      (R12)¬ biô ´ whicè correspondó tï A1² wilì bå useä tï selecô      thå  seconä banë oæ alphá-numeriã displaù datá beginninç  4Ë      abovå thå starô oæ thå displaù ram.      MODÅ  Registeò ­ WÏ ­ Thå followinç MODÅ registeò  functionó      arå implemented:       Biô Function       -------------------       · na       ¶ na       µ ná (Coulä disablå blink)       ´ Hé Resolution       ³ na       ² na       ± Graphics/Alpha       ° na      STATUÓ  Registeò  ­  RÏ ­ Biô 3¬ thå SYNÃ biô  ió  thå  onlù      significanô biô iî thió register® Thå biô wilì togglå  eacè      timå iô ió read. .pa ŠThå  simulateä 684µ ió aî enhanceä versioî witè  somå  additionaì registers®     Theså   registeró   providå   á   mechanisí    foò communicationó  betweeî  thå CPÕ anä keyboarä  processor®   Theiò functionó arå defineä aó follows: R1¸  ­  NMÉ  Statuó Registeò ­ Thå  keyboarä  processoò  maù      asserô  thå CPU'ó NMÉ line® Thå NMÉ Statuó Registeò maù  bå      polleä  tï determinå thå reasoî foò thå NMI® Oncå  thå  NMÉ      haó  beeî processed¬ iô shoulä bå acknowledgeä bù writinç  á *    zerï  tï  thió register® Acknowledginç thå  interrupô  wilì      restorå thå prå-NMÉ valuå oæ thå addresó register® Thå  NMÉ      servicå routinå neeä noô bå rå-entranô becauså thå  keyboarä      processoò wilì noô generatå anotheò NMÉ untiì thå firsô  onå      haó beeî acknowledged® Alì NMÉ codeó wilì bå eveî  integeró      sï  thaô  thå NMÉ routinå maù dispatcè usinç á  jumð  table®      Thå assigneä codeó arå aó follows: ² Lï÷ Batterù 2       ´ Curseò Updated       ¶ Lo÷ Batterù 1       ¸ EÌ Paneì       1° Icoî ­ Clock       1² Icoî ­ Phone       1´ Icoî ­ Disk       1¶ Icoî ­ Calculator      R1¹  ­  Configuratioî Switcè Registeò ­ Readinç  thå  systeí      configuratioî switcheó througè thå 825µ returnó thå valuå oæ      á  registeò whicè maù bå writteî bù thå keyboarä  processor®      Thå  CPÕ  maù  direcô thå keyboarä  processoò  tï  seô  thió      registeò bù writinç á bytå oæ datá tï R19® Bitó ° througè ·      wilì  appeaò  iî switcheó ± througè ¸ respectively®   Á  biô      valuå oæ zerï wilì causeó thå switcè tï appeaò tï bå ON.      R2°  ­  Displaù  Controì Registeò ­ Thió  ió  á  writå  onlù      registeò witè fouò significanô bits® Unuseä bitó shoulä  bå      writteî witè zeroes® Thå bitó arå assigneä aó follows:             ¶ Enablå memorù anä I/Ï writeó tï externaì display.       ³ Softwarå reseô oæ CPU.       ² Enablå poweò tï EÌ panel.       ° Writå enablå non-volatilå raí anä clock.      R2±  ­  Systeí  Statuó  Registeò  ­  Registeò  2±  haó  fouò      significanô  bitó  oæ  whicè threå  arå  reaä  only®   Theiò      functionó arå aó follows: ³ R/× Floppù Disë Enable       ² RÏ Lï Batô 1       ± RÏ Lï Batô 2       ° RÏ AÃ On Š* Selectioî  oæ portó 1¹ througè 2± ió transient®   Accesó  tï      thå  specifieä  datá registeò wilì bå obtaineä oî  thå  nexô      cyclå onlù afteò whicè thå addresó registeò wilì bå restoreä      tï iô previouó value. FILEº KB3.DOC DATEº 1/23/85 DISKº C: ; Author: Michael Stolowitz ; ; ; ; 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 0 ; 6 SW4 1 ; 5 SW7 1 ; 4 SW3 1 ; 3 SW6 1 ; 2 SW2 0 ; 1 SW5 0 ; 0 SW1 0 ; ; Port 2 Should Be Changed To: ; ----------------------------------------- ; 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 * ; ; VIRTUAL REGISTERS ; ----------------------------------------- ; R18 NMI ; R19 Configuration Switch ; R20 Display Control ; R21 Floppy Disk ; ; * * * * * ; ; ; REQUIRED CHANGES FROM PREVIOUS REVISION ; ; 1. Keyboard row addressing is now memory mapped. ; ; 2. The keyboard input port has been swapped with ; the processor data enable port. ; ; 3. A diode isolated keyboard will be used allowing ; an N-key rollover algorithm to be used. ; ; 4. ICON key operation must be transmitted as an NMI ; instead of through the FIFO. ; ; 5. A switch register output port has been added ; with the floppy disk controller enable mapped onto ; one of its address bits. ; ; 6. A number of control outputs have been added to ; the display port including Color Adapter Board, ; LCD Display Enable, Real Time Clock enable and ; CPU reset. ; ; 7. The processor address port has been expanded ; to include another address line. ; ; 8. An extran port has been added which includes ; AC ON, LO BATT1, LO BATT2 and FDC ON. ; ; 9. On reset, an AA should be stuffed into the FIFO ; ; MINIMAL CHANGE SUBSET: ; ; Assuming that the initial debug will use the Zenith ; rom which is not aware of the Morrow hardware features ; and that a diode isolated keyboard will not be immediately ; available, the following subset of changes should be ; implemented first: ; ; Items 1 & 2 from above must be addressed in order to ; obtain keyboard function. Assume display on for now. ; ; Make required changes for processor address port. ; ; Default Display Control Register Value = 05H ; ; 7 0 A/N Bank 0 ; 6 0 No CAB ; 5 d Blink ; 4 0 Mode Hi Res ; 3 0 Reset CPU ; 2 1 LCD Enable ; 1 0 Mode Graphic ; 0 1 Non-Volatile Enable ; ; Default Configuration Switch Setting ; ; SW8 0 2 FLOPPY DRIVES ; SW7 1 ; SW6 1 COLOR 80 X 25 (BW MODE) ; SW5 0 ; SW4 1 256K ON SYSTEM BOARD ; SW3 1 ; SW2 0 NO COPROCESSOR ; SW1 0 NO DIAGNOSTIC LOOP ; ; Configuration Switch Port Value = 78H ; ; DB7 SW8 0