;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