;routines to exchange data with an AT style keyboard ; ;routine to initiate sending a command and optional parameter to the keyboard ;this routine has several entry points, depending on desired result ;KB_SetLED - send parameter in *b* to LED register of keyboard ;Entry b = LED flags, bit 0 = Scroll Lock ; bit 1 = Num Lock ; bit 2 = Caps Lock ;Exit registers A and b destroyed ;Uses A, b ;Calls KB_CmdPrm (fall through) KB_SetLED: mov a,#0EDh ;set/reset status LEDs command ;KB_CmdPrm - send command in *a* with parameter in *b* ;Entry A = command code ; b = parameter ;Exit registers A and b destroyed ;Uses A, b ;Calls KB_cmd (fall through) KB_CmdPrm: mov KB_SD2,b ;store the parameter for later setb KB_2B ;set 2-byte flag ;KB_Send - send byte in *a* ;Entry A = byte to send ;Exit registers A and b destroyed ;Uses A, b ;Calls none KB_Send: mov KB_SD1,a ;store the byte jb KB_F2,$ ;wait if rcv is beyond parity bit clr KB_F1 ;next int treated as receive data clr KB_clk ;interrupt keyboard (causes int to us) mov KB_cnt,#10 ;setup send state mov c,psw.0 ;parity bit cpl c mov KB_PB,c mov KB_ASM,a ;byte to send setb KB_SM ;set send mode clr KB_F1 mov b,#35 ;wait 60uS djnz b,$ clr KB_data ;request to send setb KB_clk ;release clock line ret ;The interrupt handler will do the rest of the work to send the byte ;however the keyboard response (ACK or RESEND) must be processed by ;the normal keyboard upstream process, also initiating transfer of the ;second byte if KB_2B is set as follows: ; mov a,KB_buf ; cjne a,#0FAh,NoAck ;check for ACK ; jnb KB_2B,done ;if last byte ; clr KB_2B ; mov a,KB_SD2 ; acall KB_Send ; sjmp done ;NoAck: cjne a,#0FEh,done ;check for resend (optional) ; mov a,KB_SD1 ; acall KB_Send ;Done: $EJECT ;This is the interrupt handler for the AT style keyboard KBI: push psw push acc mov a,KB_ASM ;initially all ones jb KB_SM,KBO ;if in send mode mov c,KB_data ;newest bit jnb KB_F1,KBI2 ;if within data bits ;expecting either parity or stop jb KB_F2,KBI1 ;if beyond parity setb KB_F2 ;stop bit next mov KB_PB,c ;parity bit received mov c,psw.0 mov KB_PR,c ;parity of received byte sjmp KBIx ;expecting stop (1) bit KBI1: jc KBI3 ;stop bit OK clr KB_F2 mov c,KB_PB ;insert the "parity" bit rrc a clr c ;insert 0 for "stop" bit KBI2: rrc a ;shift in new bit and test for full mov KB_ASM,a cpl c ;1 if start bit just shifted out mov KB_F1,c sjmp KBIx ;reception complete KBI3: mov KB_BUF,a ;buffer the received byte setb KB_ready ;data received flag KBI4: mov KB_ASM,#0FFh ;setup for next byte clr KB_F1 clr KB_F2 KBIx: pop acc pop psw reti ;Send mode - 8 data, 1 parity, and 1 stop bit sent via interupt handler KBO: jnb KB_F1,KBO1 ;if not waiting for ack jb KB_data,KBIx ;if not here yet clr KB_SM jmp KBI4 ;prepare to receive KBO1: djnz KB_CNT,KBO2 ;if in data or parity portion setb KB_F1 ;wait for ack setb KB_data ;stop bit setb p1.2 ;scope sync sjmp KBIx ;send data or parity. Parity is preset in KB_PB and used to fill KB_ASM KBO2: clr p1.2 ;scope sync mov c,KB_PB rrc a mov KB_ASM,a mov KB_data,c sjmp KBIx