;----------------------------------------------------- ; Author : Chui Wei Leong ; Date : 10/11/97 ; Description : Test program for PS/2 mouse and keyboard solution ; for D11. ; ; - For D11, keyboard with mouse interface on D11 IC. ; - Modified to reduce the bandwidth at each IN token ; Dated 1/10/97 ; - Add Windows Key, 1/10/97 ; - Fix ghost key, 21/10/97 ; - Add buffering ; - corrected byte swap on version number ; - corrected set idle, SET PROTOCOL, ; - CORRECTED GET IDLE, GET PROTOCOL ; - KBMS1_2.ASM CORRECT LED FLICKER ; - KBMS1_4.ASM SHORTEN CODE FOR PS2 READING ; - KBMS1_6.ASM HID DRAFT 4, FLIP ORDER OF READING ; RAM SIZE TO FIT 8051. ;----------------------------------------------------- $MOD652 $INCLUDE(TRANSCTN.TYP) $INCLUDE(H11.CMD) ;------------------------------ ; All Registers ;------------------------------ ;General ;------- STACK_BUF DATA 48H;67H ;Stack Buffer Pointer ;I2C Routines ;------------ BITCNT DATA 10H ;I2C Bit Counter, sends 8 bits BYTE_CNT DATA 11H ;#BYTES TO BE PROCESSED BY I2C TX/RX I2C_FLAG DATA 20H ;I2C SOFTWARE STATUS FLAGS. I2C_FAIL BIT I2C_FLAG.0 ;I2C NO ACKNOWLEDGE FLAG. VALIDATE_FLAG BIT I2C_FLAG.1 ;Comms to H11 ;------------ CNT_BYTE DATA 12H ;NUMBER OF BYTES TO BE TRANSMITTED SLV_ADR DATA 13H ;I2C ADDRESS OF ACTIVE SLAVE. I2C_BUFFER DATA 14H ;I2C TRANSMIT/RECEIVE DATA BUFFER RW_COUNTER DATA 25H;30H ;Function Setup Register ;----------------------- TRANSACTION DATA 26H;31H ; #00000000B FN_FEATURE_SEL DATA 27H;32H ; FEATURE SELECTOR & REPORT TYPE FOR KB CLASS FN_ADDR DATA 28H;33H ; Low 7 bits - address ; 7th bit - set means configured FN_TRANSACTION_END DATA 29H;34H FN_TRANSACTION_INDEX DATA 2AH;35H FN_IDLE_TIME DATA 2BH;36H ; IDLE TIME FOR KEYBOARD FN_DATA_REQUEST_LENGTH DATA 2CH;37H ;Keyboard Registers ;------------------ ROW_NUM DATA 24H X_LO BIT ROW_NUM.3 WIN_KEY BIT ROW_NUM.4 KEY_HIT0 DATA 2EH;3BH KEY_HIT1 DATA 2FH;3CH KEY_HIT2 DATA 30H;48H KEY_HIT3 DATA 31H;49H KEY_HIT4 DATA 32H;4AH KEY_HIT5 DATA 33H;4BH MODIFIER_BYTE DATA 34H;4CH TOTAL_KEYS DATA 35H;4DH LAST_ZERO_SENT DATA 36H;4EH BIT_NUMBER DATA 2DH;38H KEY1 DATA 37H;50H KEY2 DATA 38H;51H KEY3 DATA 39H;52H KEY4 DATA 3AH;53H KEY5 DATA 3BH;54H KEY6 DATA 3CH;55H KEY_MODIFIER DATA 3DH;56H COUNT_ZERO DATA 3EH;57H INTERFACE_STATUS DATA 3FH;58H; BIT 0 - Boot Protocol of keyboard ; BIT 1 - Interface of keyboard ; BIT 2 - Boot Protocol of mouse ; BIT 3 - Interface of mouse LED_STATUS DATA 40H;59H ; Mouse Registers ;----------------- PS1BYTE DATA 41H;60H PS2BYTE DATA 42H;61H PS3BYTE DATA 43H;62H XBYTE DATA 44H;63H YBYTE DATA 45H;64H CLICKBYTE DATA 46H;65H MOUSE_STATUS DATA 47H;66H ;------------------------ ; RS232 ;------------------------ ;BITTIM EQU 31H ;TXD_BITCNT DATA 37H ;------------------------------ ; H11 Commands and Addresses ;------------------------------ ; Addresses ;---------- COMMAND_ADDRESS EQU 36H DATA_READ_ADDR EQU 35H DATA_WRITE_ADDR EQU 34H ; H11A commands ;-------------- SET_MODE EQU 0F3H ; H11 commands ;------------- SET_HUB_ADDRESS_EN EQU 0D0h SET_EMB_ADDRESS_EN EQU 0D1h SET_EPOINT_EN EQU 0D8h SEL_HUB_OUT_ENDPT EQU 000H SEL_HUB_IN_ENDPT EQU 001H SEL_FN_OUT_ENDPT EQU 002H SEL_FN_IN_ENDPT EQU 003H SEL_FN_INT0_ENDPT EQU 004H SEL_FN_INT1_ENDPT EQU 007H EMB_IN_STATUS EQU 083H READ_BUFFER EQU 0F0h WRITE_BUFFER EQU 0F0h CLEAR_BUF EQU 0F2h READ_INT EQU 0F4h VALIDATE_BUF EQU 0FAh ACK_SETUP EQU 0F1H RESUME_DEV EQU 0F6H EMB_ENDPT0_STATUS EQU 042H EMB_ENDPT1_STATUS EQU 043H EMB_INT0_ENDPT_STATUS EQU 044H EMB_INT1_ENDPT_STATUS EQU 047H ;----------------- OFFSET_bmReqTyp EQU 02h OFFSET_bmReq EQU 03h OFFSET_wValue EQU 04h OFFSET_wIndex EQU 06h OFFSET_wLenght EQU 08h ;---------------------------------------- ; Feature Selector ;--------------------------------------- DEVICE_REMOTE_WAKEUP EQU 01h ENDPOINT_STALL EQU 00H ;---------------------------------------- ; IO PORT ;--------------------------------------- ;Hub Usage ;--------- SCLPIN BIT P3.1 SDAPIN BIT P3.0 H11_INT BIT P3.2 SUSPEND BIT P3.3 ;Keyboard Usage ;-------------- LED_ENABLE BIT P3.5 NUM BIT P0.0 SCROLL BIT P0.1 CAPS BIT P0.2 WIN_BIT BIT P3.4 X0 EQU P0 X1 EQU P1 Y0 EQU P2 R4_DIRECT DATA 04H ; DIRECT LOCATION OF R4 ;-------------- ; Mouse Usage ;-------------- PS2_DATA BIT P3.7 PS2_CLK BIT P3.6 ;------------------------------ ; INTERRUPT VECTOR TABLE ;------------------------------ CSEG AT 0000H ORG 0000H AJMP START ;PROGRAM START ORG 0003H AJMP INT0_SERVER ;INT0 SERVICE ROUTINE ORG 000BH AJMP T0_SERVER ;TIMER0 SERVICE ROUTINE ORG 0013H AJMP INT1_SERVER ;INT1 SERVICE ROUTINE ORG 001BH AJMP T1_SERVER ;TIMER1 SERVICE ROUTINE ORG 0023H AJMP UART_SERVER ;UART SERVICE ROUTINE ORG 002BH AJMP I2C_SERVER ;I2C SERVICE ROUTINE ;****************************** INT0_SERVER: ;INT0 SERVICE ROUTINE RETI T0_SERVER: ;TIMER0 SERVICE ROUTINE PUSH ACC MOV TL0, #0E8H ; TL0 AND TH0 MAKES 1 millisec MOV TH0, #03H MOV TCON, #00010000B ; TURNS TIMER0 ON MOV A, FN_IDLE_TIME JZ END_T0_SERVER DEC A MOV FN_IDLE_TIME, A END_T0_SERVER: POP ACC RETI INT1_SERVER: ;INT1 SERVICE ROUTINE T1_SERVER: ;TIMER1 SERVICE ROUTINE UART_SERVER: ;UART SERVICE ROUTINE I2C_SERVER: ;I2C SERVICE ROUTINE RETI ;*************************************** ; PROGRAM START ;*************************************** ORG 0050H START: CLR SUSPEND MOV IE,#00000000B ;ALL INTERRUPT DISABLED MOV SP,#STACK_BUF ;SET STACK POINTER ;----------------------------- ; INITIAL I/O PORT ;----------------------------- MOV P0,#11111111B ; MOV P1,#11111111B MOV P2,#11111111B MOV P3,#11110111B ; suspend remains low CLR LED_ENABLE CLR NUM CLR SCROLL CLR CAPS ;------------------ MOV I2C_BUFFER,#SET_MODE MOV I2C_BUFFER+1,#0AFH ; SET SOFT CONNECT MOV I2C_BUFFER+2,#03H ; SET CLOCK LCALL WRITE_TWO_BYTE MOV I2C_BUFFER,#SET_HUB_ADDRESS_EN MOV I2C_BUFFER+1,#00H ;DISENABLE HUB LCALL WRITE_ONE_BYTE MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN MOV I2C_BUFFER+1,#80H ;ENABLE EMBEDDED FN LCALL WRITE_ONE_BYTE LCALL KEYBOARD_INITIAL MOV IE,#00000000B ;ALL INTERRUPT DISABLED LCALL RESET_PS2 ;SETB LED_ENABLE MOV I2C_BUFFER,#SET_MODE MOV I2C_BUFFER+1,#0FFH ; SET SOFT CONNECT MOV I2C_BUFFER+2,#03H ; SET CLOCK LCALL WRITE_TWO_BYTE MAIN: LCALL WRITE_LED ACALL USB_INTERRUPT JNB EMBED_CONFIG, MAIN LCALL KEYBOARD_ROUTINE SJMP MAIN USB_INTERRUPT: JNB H11_INT, PROCESS_INTERRUPT ;RETURN IF NOT INTERRUPTED RET PROCESS_INTERRUPT: MOV I2C_BUFFER,#READ_INT ;READ INTERRUPT REGISTER LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A,I2C_BUFFER JB ACC.0,HUB_CTRL_OUT_P ; HUB CONTROL OUT ENDPT, INDEX 0 JB ACC.1,HUB_CTRL_IN_P ; HUB CONTROL IN ENDPT , INDEX 1 JB ACC.2,FN_CTRL_OUT_P ; FUNCTION CONTROL OUT ENDPOINT, INDEX 2 JB ACC.3,FN_CTRL_IN_P ; FUNCTION CONTROL IN ENDPOINT, INDEX 3 JB ACC.4,FN_INT0_P ; FUNCTION0 INTERRUPT ENDPOINT (ENDPT 1 IN), INDEX 4 JB ACC.5,NO_ACTION ; FUNCTION0 INTERRUPT ENDPOINT (ENDPT 1 OUT), INDEX 5 JB ACC.6,NO_ACTION ; FUNCTION1 ENDPOINT2 (OUT), INDEX 6 JB ACC.7,FN_INT1_P ; FUNCTION1 ENDPOINT2 (IN), INDEX 7 RESTART_H11: ;SETB NUM ;CLEAR NUM LED ;SETB SCROLL ;CLEAR SCROLL LED ;SETB CAPS ;CLEAR CAPS LED MOV I2C_BUFFER,#SET_HUB_ADDRESS_EN MOV I2C_BUFFER+1,#00H ;DISENABLE HUB LCALL WRITE_ONE_BYTE MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN MOV I2C_BUFFER+1,#80H ;ENABLE EMBEDDED FN LCALL WRITE_ONE_BYTE MOV I2C_BUFFER,#SET_EPOINT_EN ;ENABLE FUNCTION INTERRUPT MOV I2C_BUFFER+1,#02H ;ENDPOINT LCALL WRITE_ONE_BYTE ACALL USB_INITIAL END_USB_INTERRUPT: RET; USB_INTERRUPT NO_ACTION: RET HUB_CTRL_OUT_P: RET HUB_CTRL_IN_P: RET FN_CTRL_OUT_P: AJMP FN_CTRL_OUT FN_CTRL_IN_P: AJMP FN_CTRL_IN FN_INT0_P: AJMP FN_INT0 FN_INT1_P: AJMP FN_INT1 USB_INITIAL: CLR VALIDATE_FLAG MOV TRANSACTION, #NO_TRANSACTION MOV FN_IDLE_TIME, #12H MOV FN_ADDR, #00H MOV HUB_ADDR,#00H MOV EMB_ADDR,#00H MOV EMBED_STATUS0,#01H MOV EMBED_STATUS1,#00H CLR EMBED_CONFIG SETB EMBED_REMOTE_WKUP RET; USB_INITIAL ;======================================== ; FUNCTION CODE ;======================================== FN_CTRL_OUT: MOV I2C_BUFFER,#EMB_ENDPT0_STATUS ;READ INTERRUPT REGISTER LCALL READ_ONE_BYTE ;READ DATA FROM H11 FN_RCV_TXD_OK: MOV I2C_BUFFER,#82H ;READ CURRENT ENDPT STATUS LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, I2C_BUFFER JNB ACC.5, BUFF_NOT_FULL JB ACC.2, FN_SETUP SJMP FN_ACK_DATA_RCV BUFF_NOT_FULL: RET FN_ACK_DATA_RCV: MOV I2C_BUFFER, #SEL_FN_OUT_ENDPT ; SELECT OUT BUFFER LCALL WRITE_COMMAND MOV RW_COUNTER,#0AH ;READ NEXT 10 BTYES MOV I2C_BUFFER,#READ_BUFFER LCALL READ_FROM_FN_OUT MOV A,I2C_BUFFER+1 ;READ TOTAL HOW MANY BYTES JZ FN_ACK_DATA_RCV02 ; check if it is "SET" data from host CJNE A, #01H, FN_ACK_DATA_RCV02 ; SET REPORT IS 1 BYTES MOV A, TRANSACTION MOV TRANSACTION, #NO_TRANSACTION CJNE A,#32H, FN_ACK_DATA_RCV02 ;CHECK FOR SET REPORT MOV LED_STATUS, I2C_BUFFER+2 CHK_NUM: END_SET_REPORT: MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER LCALL WRITE_COMMAND FN_ACK_DATA_RCV01: LCALL SEND_FN_ZERO_PACKET RET FN_ACK_DATA_RCV02: MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER LCALL WRITE_COMMAND RET FN_SETUP: ; Setting up of Ctrl-In is essential MOV I2C_BUFFER, #SEL_FN_IN_ENDPT ; SELECT IN BUFFER LCALL WRITE_COMMAND MOV I2C_BUFFER,#ACK_SETUP ;ACKNOWLEDGE SETUP LCALL WRITE_COMMAND MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER LCALL WRITE_COMMAND MOV I2C_BUFFER, #SEL_FN_OUT_ENDPT ; SELECT OUT BUFFER LCALL WRITE_COMMAND MOV I2C_BUFFER,#ACK_SETUP ;ACKNOWLEDGE SETUP LCALL WRITE_COMMAND ;TO RELEASE THE LOCK ON THE BUFFER MOV RW_COUNTER,#0AH ;READ NEXT 10 BTYES MOV I2C_BUFFER,#READ_BUFFER LCALL READ_FROM_FN_OUT MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER TO RE-ENABLE LCALL WRITE_COMMAND ;ACK MOV A,I2C_BUFFER+1 ;READ TOTAL HOW MANY BYTES CJNE A,#08H, ERROR_SETUP ;NOT CORRECT COMMAND FROM HOST FN_DECODE_REQUEST: MOV R2,I2C_BUFFER+OFFSET_bmReqTyp MOV R3,I2C_BUFFER+OFFSET_bmReq MOV R4,I2C_BUFFER+OFFSET_wValue MOV R7,I2C_BUFFER+OFFSET_wValue+1 MOV R5,I2C_BUFFER+OFFSET_wIndex MOV R6,I2C_BUFFER+OFFSET_wLenght MOV A, I2C_BUFFER+OFFSET_wLenght+1 JZ USE_LOW_BITS MOV FN_DATA_REQUEST_LENGTH, #0FFH SJMP MAXIMUM_LENGTH USE_LOW_BITS: MOV FN_DATA_REQUEST_LENGTH, R6 ; Length of data to send MAXIMUM_LENGTH: MOV A, R3 ; Check if it is less than 16. ANL A, #0F0H ; Standard and class specified requests JNZ ERROR_SETUP ; has only 16 requests MOV A, R2 ; Check if it is a standard or ANL A, #00100000B ; class request CLR C RRC A PUSH ACC MOV A, R3 ANL A, #00001111B MOV TRANSACTION, A POP ACC ORL A, TRANSACTION CLR C RLC A MOV TRANSACTION, A MOV DPTR, #SETUP_FN_ACTION JMP @A+DPTR SETUP_FN_ACTION: ; Standard Requests AJMP STD_FN_GET_STATUS ;0 AJMP STD_FN_CLEAR_FEATURE ;2 AJMP RESERVED ;4 AJMP STD_FN_SET_FEATURE ;6 AJMP RESERVED ;8 AJMP STD_FN_SET_ADDRESS ;A AJMP STD_FN_GET_DESCRIPTOR ;C AJMP STD_FN_SET_DESCRIPTOR ;E AJMP STD_FN_GET_CONFIGURATION;10 AJMP STD_FN_SET_CONFIGURATION;12 AJMP STD_FN_GET_INTERFACE ;14 AJMP STD_FN_SET_INTERFACE ;16 AJMP STD_FN_SYNCH_FRAME ;18 AJMP RESERVED ;1A AJMP RESERVED ;1C AJMP RESERVED ;1E ; Class Requests AJMP RESERVED ;20 AJMP CLSS_FN_GET_REPORT ;22 0x01 AJMP CLSS_FN_GET_IDLE ;24 0x02 AJMP CLSS_FN_GET_PROTOCOL ;26 0x03 AJMP RESERVED ;28 0x04 AJMP RESERVED ;2A 0x05 AJMP RESERVED ;2C 0x06 AJMP RESERVED ;2E 0x07 AJMP RESERVED ;30 0x08 AJMP CLSS_FN_SET_REPORT1 ;32 0x09 AJMP CLSS_FN_SET_IDLE1 ;34 0x0A AJMP CLSS_FN_SET_PROTOCOL1 ;36 0x0B AJMP RESERVED ;38 AJMP RESERVED ;3A AJMP RESERVED ;3C AJMP RESERVED ;3E ERROR_SETUP: ; Should send a stall for unknown Requests LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_STALL_INT0 END_ERROR_SETUP: RET; FN_CTRL_OUT REPLY_RESERVED: AJMP ERROR_SETUP CLSS_FN_SET_REPORT1: AJMP CLSS_FN_SET_REPORT CLSS_FN_SET_IDLE1: AJMP CLSS_FN_SET_IDLE CLSS_FN_SET_PROTOCOL1: AJMP CLSS_FN_SET_PROTOCOL FN_CTRL_IN: MOV I2C_BUFFER,#EMB_ENDPT1_STATUS ;READ INTERRUPT REGISTER LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, TRANSACTION ANL A, #NO_TRANSACTION XRL A, #NO_TRANSACTION JNZ GIVE_FN_REPLY RET ; Return because there's no transaction GIVE_FN_REPLY: MOV A, TRANSACTION CLR ACC.0 ANL A, #00011111B MOV DPTR, #REPLY_FN_ACTION JMP @A+DPTR REPLY_FN_ACTION: ; Standard Requests AJMP REPLY_STD_FN_GET_STATUS AJMP REPLY_STD_FN_CLEAR_FEATURE AJMP REPLY_RESERVED AJMP REPLY_STD_FN_SET_FEATURE AJMP REPLY_RESERVED AJMP REPLY_STD_FN_SET_ADDRESS AJMP REPLY_STD_FN_GET_DESCRIPTOR AJMP REPLY_STD_FN_SET_DESCRIPTOR AJMP REPLY_STD_FN_GET_CONFIGURATION AJMP REPLY_STD_FN_SET_CONFIGURATION AJMP REPLY_STD_FN_GET_INTERFACE AJMP REPLY_STD_FN_SET_INTERFACE AJMP REPLY_STD_FN_SYNCH_FRAME AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED ; Class Requests AJMP REPLY_RESERVED AJMP REPLY_CLSS_FN_GET_REPORT AJMP REPLY_CLSS_FN_GET_IDLE AJMP REPLY_CLSS_FN_GET_PROTOCOL AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_CLSS_FN_SET_REPORT1 AJMP REPLY_CLSS_FN_SET_IDLE1 AJMP REPLY_CLSS_FN_SET_PROTOCOL1 AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED RET; FN_CTRL_IN REPLY_CLSS_FN_SET_REPORT1: AJMP REPLY_CLSS_FN_SET_REPORT REPLY_CLSS_FN_SET_IDLE1: LJMP REPLY_CLSS_FN_SET_IDLE REPLY_CLSS_FN_SET_PROTOCOL1: LJMP REPLY_CLSS_FN_SET_PROTOCOL FN_INT1: ; For mouse interrupt MOV I2C_BUFFER, #EMB_INT1_ENDPT_STATUS LCALL READ_ONE_BYTE MOV I2C_BUFFER,#87H ;READ CURRENT ENDPT STATUS LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, I2C_BUFFER JB ACC.5, END_FN_INT1 ; BUFFER FULL MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #03H MOV I2C_BUFFER+3, CLICKBYTE; Modifier MOV I2C_BUFFER+4, XBYTE MOV I2C_BUFFER+5, YBYTE MOV RW_COUNTER, #05H MOV TOTAL_KEYS, #00H LCALL WRITE_TO_EMB_INT1 MOV XBYTE, #00 MOV YBYTE, #00 END_FN_INT1: RET FN_INT0: MOV I2C_BUFFER, #EMB_INT0_ENDPT_STATUS LCALL READ_ONE_BYTE MOV I2C_BUFFER,#84H ;READ CURRENT ENDPT STATUS LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, I2C_BUFFER JB ACC.5, END_FN_INT0 ; END IF LAST DATA NOT SENT MOV I2C_BUFFER, #EMB_INT0_ENDPT_STATUS LCALL READ_ONE_BYTE MOV A, FN_IDLE_TIME JNZ END_FN_INT0 MOV A, LAST_ZERO_SENT JNZ END_FN_INT0 MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #08H MOV I2C_BUFFER+3, KEY_MODIFIER; Modifier MOV I2C_BUFFER+4, #00H; Reserved MOV I2C_BUFFER+5, KEY1; K1 MOV I2C_BUFFER+6, KEY2; K2 MOV I2C_BUFFER+7, KEY3; K3 MOV I2C_BUFFER+8, KEY4; K4 MOV I2C_BUFFER+9, KEY5; K5 MOV I2C_BUFFER+10, KEY6; K6 MOV RW_COUNTER, #0AH MOV TOTAL_KEYS, #00H LCALL WRITE_TO_EMB_INT0 MOV A, KEY1 JZ DONT_SEND_NEXT0 RET DONT_SEND_NEXT0: MOV A, KEY_MODIFIER JZ DONT_SEND_NEXT2 RET DONT_SEND_NEXT2: MOV LAST_ZERO_SENT, #01H END_FN_INT0: RET; FN_INT ;======================================== ; FUNCTION DESCRIPTOR'S CODE ;======================================== STD_FN_GET_STATUS: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_GET_STATUS2; GOTO DEVICE STATUS DEC A JZ STD_FN_GET_STATUS0; GOTO INTERFACE STATUS DEC A JZ STD_FN_GET_STATUS1; GOTO ENDPOINT STATUS ERROR_FN_GET_STATUS: MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_STALL_INT0 STD_FN_GET_STATUS0: ; Get Interface Status ;--------------------- MOV A, #FN_GET_INTERFACE_STATUS ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 DEC A JZ INTERFACE_STATUS_0 INTERFACE_STATUS_1: MOV A, INTERFACE_STATUS ORL A, #08H ; SET THE MOUSE BIT ANL A, #0FDH ; MASK THE KEYBOARD BIT MOV INTERFACE_STATUS, A RET INTERFACE_STATUS_0: MOV A, INTERFACE_STATUS ORL A, #02H ; SET THE KEYBOARD BIT ANL A, #0F7H ; MASK THE MOUSE BIT MOV INTERFACE_STATUS, A RET STD_FN_GET_STATUS1: ; Get Endpoint Status ;-------------------- MOV A, #FN_GET_ENDPOINT_STATUS ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 ANL A, #0FH SWAP A ORL A, INTERFACE_STATUS MOV INTERFACE_STATUS, A RET STD_FN_GET_STATUS2: ; Get Device Status ;------------------ ;MOV A, R5 ; I2C_BUFFER+OFFSET_wIndex ;JNZ ERROR_FN_GET_STATUS MOV A, #FN_GET_DEVICE_STATUS ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_GET_STATUS: RET; STD_FN_GET_STATUS STD_FN_CLEAR_FEATURE: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_CLEAR_FEATURE0; GOTO DEVICE CLEAR FEATURE DEC A JZ STD_FN_CLEAR_FEATURE1; GOTO INTERFACE CLEAR FEATURE DEC A JZ STD_FN_CLEAR_FEATURE2; GOTO ENDPOINT CLEAR FEATURE ERROR_FN_CLEAR_FEATURE: MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_STALL_INT0 STD_FN_CLEAR_FEATURE0: ; Clear Device Feature ;------------------ MOV A, R4 CJNE A, #DEVICE_REMOTE_WAKEUP, ERROR_FN_CLEAR_FEATURE ;MOV A, R5 ;JNZ ERROR_FN_CLEAR_FEATURE CLR EMBED_REMOTE_WKUP MOV A, #FN_CLEAR_DEVICE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_CLEAR_FEATURE1: ; Clear Interface Feature ;------------------------ AJMP ERROR_FN_CLEAR_FEATURE; NO SUPPORT MOV A, #FN_CLEAR_INTERFACE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_CLEAR_FEATURE2: ; Clear Endpoint Feature ;-------------------- MOV A, R4 CJNE A, #ENDPOINT_STALL, ERROR_FN_CLEAR_FEATURE; NO SUPPORT MOV A, R5 ANL A, #0FH SWAP A ORL A, INTERFACE_STATUS MOV INTERFACE_STATUS, A MOV A, #FN_CLEAR_ENDPOINT_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_CLEAR_FEATURE: RET; STD_FN_CLEAR_FEATURE STD_FN_SET_FEATURE: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_SET_FEATURE0; GOTO DEVICE SET FEATURE DEC A JZ STD_FN_SET_FEATURE1; GOTO INTERFACE SET FEATURE DEC A JZ STD_FN_SET_FEATURE2; GOTO ENDPOINT SET FEATURE ERROR_FN_SET_FEATURE: MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_STALL_INT0 STD_FN_SET_FEATURE0: ; Set Device Feature ;------------------ MOV A, R4 ; wValue CJNE A, #DEVICE_REMOTE_WAKEUP, ERROR_FN_SET_FEATURE ;MOV A, R5 ; wIndex ;JNZ ERROR_FN_SET_FEATURE SETB EMBED_REMOTE_WKUP MOV A, #FN_SET_DEVICE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_FEATURE1: ; Set Interface Feature ;--------------------- AJMP ERROR_FN_SET_FEATURE; NO SUPPORT MOV A, #FN_SET_INTERFACE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_FEATURE2: ; Set Endpoint Feature ;-------------------- MOV A, R4 CJNE A, #ENDPOINT_STALL, ERROR_FN_SET_FEATURE; NO SUPPORT MOV A, R5 ANL A, #0FH SWAP A ORL A, INTERFACE_STATUS MOV INTERFACE_STATUS, A MOV A, #FN_SET_ENDPOINT_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_SET_FEATURE: RET; STD_FN_SET_FEATURE STD_FN_SET_ADDRESS: MOV FN_ADDR, R4 RET; STD_FN_SET_ADDRESS STD_FN_GET_DESCRIPTOR: MOV A, R7 ; wIndex states which item it refers to DEC A JNZ STD_FN_GET_DESCRIPTOR0 ; Get Device Descriptor ;---------------------- MOV A, #FN_GET_DEVICE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR0: DEC A JNZ STD_FN_GET_DESCRIPTOR1 ; Get Configuration Descriptor ;----------------------------- MOV A, #FN_GET_CONFIG_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR1: DEC A JNZ STD_FN_GET_DESCRIPTOR2 ; Get String Descriptor ;---------------------- MOV A, #FN_GET_STRING_DESC ORL A, TRANSACTION MOV TRANSACTION, A STD_FN_GET_DESCRIPTOR2: DEC A JNZ STD_FN_GET_DESCRIPTOR3 ; Set Interface Descriptor ;------------------------- MOV A, #FN_GET_INTERFACE_DESC ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 ; Interface also 0 and 1 JZ INTERFACE_0 INTERFACE_1: MOV A, INTERFACE_STATUS ORL A, #08H ; SET THE MOUSE BIT ANL A, #0FDH ; MASK THE KEYBOARD BIT MOV INTERFACE_STATUS, A RET INTERFACE_0: MOV A, INTERFACE_STATUS ORL A, #02H ; SET THE KEYBOARD BIT ANL A, #0F7H ; MASK THE MOUSE BIT MOV INTERFACE_STATUS, A RET STD_FN_GET_DESCRIPTOR3: DEC A JNZ STD_FN_GET_DESCRIPTOR4 ; Set Endpoint Feature ;--------------------- MOV A, #FN_GET_ENDPOINT_DESC ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 DEC A JZ ENDPOINT_0 ENDPOINT_1: MOV A, INTERFACE_STATUS ORL A, #08H ; SET THE MOUSE BIT ANL A, #0FDH ; MASK THE KEYBOARD BIT MOV INTERFACE_STATUS, A RET ENDPOINT_0: MOV A, INTERFACE_STATUS ORL A, #02H ; SET THE KEYBOARD BIT ANL A, #0F7H ; MASK THE MOUSE BIT MOV INTERFACE_STATUS, A RET STD_FN_GET_DESCRIPTOR4: MOV A, R7 ; wIndex states which item it refers to CJNE A, #21H, STD_FN_GET_DESCRIPTOR5 ; Get HID Descriptor ;---------------------- MOV A, #FN_GET_HID_DESC ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 ; HID also 0 and 1 JZ HID_DESC_0 HID_DESC_1: MOV A, INTERFACE_STATUS ORL A, #08H ; SET THE MOUSE BIT ANL A, #0FDH; MASK THE KEYBOARD BIT MOV INTERFACE_STATUS, A RET HID_DESC_0: MOV A, INTERFACE_STATUS ORL A, #02H ; SET THE KEYBOARD BIT ANL A, #0F7H ; MASK THE MOUSE BIT MOV INTERFACE_STATUS, A RET STD_FN_GET_DESCRIPTOR5: CJNE A, #22H, STD_FN_GET_DESCRIPTOR6 ; Get Report Descriptor ;---------------------- MOV A, #FN_GET_REPORT_DESC ORL A, TRANSACTION MOV TRANSACTION, A MOV A, R5 ; Interface number is 0 and 1 JZ RPT_DESC_0 RPT_DESC_1: MOV A, INTERFACE_STATUS ORL A, #08H ; SET THE MOUSE BIT ANL A, #0FDH ; MASK THE KEYBOARD BIT MOV INTERFACE_STATUS, A RET RPT_DESC_0: MOV A, INTERFACE_STATUS ORL A, #02H ; SET THE KEYBOARD BIT ANL A, #0F7H ; MASK THE MOUSE BIT MOV INTERFACE_STATUS, A RET STD_FN_GET_DESCRIPTOR6: CJNE A, #23H, END_STD_FN_GET_DESCRIPTOR ; Get Physical Descriptor ;------------------------ MOV TRANSACTION, #NO_TRANSACTION RET END_STD_FN_GET_DESCRIPTOR: MOV TRANSACTION, #NO_TRANSACTION RET; STD_FN_GET_DESCRIPTOR STD_FN_SET_DESCRIPTOR: MOV A, R4 ; wIndex states which item it refers to DEC A JNZ STD_FN_SET_DESCRIPTOR0 ; Get Device Descriptor ;---------------------- MOV A, #FN_SET_DEVICE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR0: DEC A JNZ STD_FN_SET_DESCRIPTOR1 ; Get Configuration Descriptor ;----------------------------- MOV A, #FN_SET_CONFIG_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR1: DEC A JNZ STD_FN_SET_DESCRIPTOR2 ; Get String Descriptor ;---------------------- MOV A, #FN_SET_STRING_DESC ORL A, TRANSACTION MOV TRANSACTION, A STD_FN_SET_DESCRIPTOR2: DEC A JNZ STD_FN_SET_DESCRIPTOR3 ; Set Interface Descriptor ;------------------------- MOV A, #FN_SET_INTERFACE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR3: DEC A JNZ END_STD_FN_SET_DESCRIPTOR ; Set Endpoint Feature ;--------------------- MOV A, #FN_SET_ENDPOINT_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_SET_DESCRIPTOR: RET; STD_FN_SET_DESCRIPTOR STD_FN_GET_CONFIGURATION: RET; STD_FN_GET_CONFIGURATION STD_FN_SET_CONFIGURATION: MOV A, R4 JZ DISABLE_EMBED SETB EMBED_CONFIG MOV I2C_BUFFER,#0E8H MOV I2C_BUFFER+1,#F_PORT_POWER LCALL WRITE_ONE_BYTE RET DISABLE_EMBED: CLR EMBED_CONFIG RET; STD_FN_SET_CONFIGURATION STD_FN_GET_INTERFACE: RET; STD_FN_GET_INTERFACE STD_FN_SET_INTERFACE: RET; STD_FN_SET_INTERFACE STD_FN_SYNCH_FRAME: RET; STD_FN_SYNCH_FRAME CLSS_FN_GET_REPORT: MOV TRANSACTION, #NO_TRANSACTION MOV A, R5 DEC A JZ GET_REPORT_0 ; Else get mouse report MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #03H ; 3 bytes to send MOV I2C_BUFFER+3, #00H ; For mouse buttons MOV I2C_BUFFER+4, #00H ; For X MOV I2C_BUFFER+5, #00H; For Y LJMP WRITE_TO_EMB_IN RET GET_REPORT_0: MOV FN_FEATURE_SEL, I2C_BUFFER+OFFSET_wValue+1; REPORT TYPE MOV A, FN_FEATURE_SEL DEC A JZ REPORT_TYPE_INPUT DEC A JZ REPORT_TYPE_OUTPUT ; NO SUPPORT FOR OTHER REPORT TYPES LJMP SEND_FN_STALL_ENDPT1 REPORT_TYPE_INPUT: MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #08H MOV I2C_BUFFER+3, KEY_MODIFIER; Modifier MOV I2C_BUFFER+4, #00H; Reserved MOV I2C_BUFFER+5, KEY1; K1 MOV I2C_BUFFER+6, KEY2; K2 MOV I2C_BUFFER+7, KEY3; K3 MOV I2C_BUFFER+8, KEY4; K4 MOV I2C_BUFFER+9, KEY5; K5 MOV I2C_BUFFER+10,KEY6; K6 MOV RW_COUNTER, #0AH MOV TOTAL_KEYS, #00H LJMP WRITE_TO_EMB_IN REPORT_TYPE_OUTPUT: MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H; Modifier MOV RW_COUNTER, #03H LJMP WRITE_TO_EMB_IN RET; CLSS_FN_GET_REPORT CLSS_FN_GET_IDLE: MOV TRANSACTION, #NO_TRANSACTION ; Don't differentiate MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, FN_IDLE_TIME; Idle Duration MOV RW_COUNTER, #03H LJMP WRITE_TO_EMB_IN RET; CLSS_FN_GET_IDLE CLSS_FN_GET_PROTOCOL: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #01H; BOOT PROTOCOL SELECTION MOV RW_COUNTER, #03H MOV A, R5 JZ GET_PROTOCOL0 GET_PROTOCOL1: MOV A, INTERFACE_STATUS ANL A, #00000100B JZ GET_COMM_PROTOCOL MOV I2C_BUFFER+3, #00H; BOOT PROTOCOL SELECTION SJMP GET_COMM_PROTOCOL GET_PROTOCOL0: MOV A, INTERFACE_STATUS ANL A, #00000001B JZ GET_COMM_PROTOCOL MOV I2C_BUFFER+3, #00H; BOOT PROTOCOL SELECTION GET_COMM_PROTOCOL: MOV A, INTERFACE_STATUS ANL A, #0F5H MOV INTERFACE_STATUS, A LJMP WRITE_TO_EMB_IN CLSS_FN_SET_REPORT: RET; CLSS_FN_SET_REPORT CLSS_FN_SET_IDLE: MOV FN_IDLE_TIME, I2C_BUFFER+OFFSET_wValue+1 ; Don't Differentiate MOV TRANSACTION, #NO_TRANSACTION ; between mouse and kb LCALL SEND_FN_ZERO_PACKET RET; CLSS_FN_SET_IDLE CLSS_FN_SET_PROTOCOL: MOV A, R5 JZ SET_PROTOCOL0 SET_PROTOCOL1: MOV R0, #00000100B SJMP GET_COMM_PROTOCOL SET_PROTOCOL0: MOV R0, #00000001B SET_COMM_PROTOCOL: MOV A, I2C_BUFFER+OFFSET_wValue JZ USE_BOOT_PROTOCOL USE_REPORT_PROTOCOL: MOV A, R0 ORL A, INTERFACE_STATUS MOV INTERFACE_STATUS, A LJMP SEND_FN_ZERO_PACKET USE_BOOT_PROTOCOL: MOV A, R0 CPL A ANL A, INTERFACE_STATUS MOV INTERFACE_STATUS, A LJMP SEND_FN_ZERO_PACKET RESERVED: MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_STALL_INT0 RET; RESERVED ; Standard Requests REPLY_STD_FN_GET_STATUS0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_GET_STATUS: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_STATUS0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_FN_GET_STATUS1 MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #02H MOV I2C_BUFFER+4, #00H JMP @A+DPTR REPLY_STD_FN_GET_STATUS1: AJMP REPLY_FN_GET_DEVICE_STATUS AJMP REPLY_FN_GET_INTERFACE_STATUS AJMP REPLY_FN_GET_ENDPOINT_STATUS REPLY_FN_GET_DEVICE_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV A, #FN_DEVICE_STATUS JB EMBED_REMOTE_WKUP, REMOTE_WAKEUP_STATUS ANL A, #00000001B ; DON'T TOUCH BUS-POWERED REMOTE_WAKEUP_STATUS: MOV I2C_BUFFER+3, A MOV RW_COUNTER, #04H LJMP WRITE_TO_EMB_IN REPLY_FN_GET_INTERFACE_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER+3, #FN_INTERFACE_STATUS MOV RW_COUNTER, #04H MOV A, INTERFACE_STATUS ; No difference in both interface ANL A, #0F5H MOV INTERFACE_STATUS, A LJMP WRITE_TO_EMB_IN REPLY_FN_GET_ENDPOINT_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV A, INTERFACE_STATUS SWAP A ANL A, #0FH JZ REPLY_FN_ENDPOINT0 ; Else endpoint status of others MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #02H MOV I2C_BUFFER+4, #00H MOV I2C_BUFFER+3, #00H CJNE A, #01, NEXT_ENDPOINT2 ;===== Interrupt Endpoint 1 ============ MOV I2C_BUFFER, #084H ;READ ENDPOINT STATUS LCALL READ_ONE_BYTE ;READ DATA FROM H11 REPLY_COMMON: ANL A, #08H ; Check Stall status JZ REPLY_FN_ENDPOINT1 MOV I2C_BUFFER+3, #01H SJMP REPLY_FN_ENDPOINT1 REPLY_FN_ENDPOINT0: MOV A, #00H MOV C, E_PORT_STALL RLC A ORL A, #FN_ENDPOINT0_STATUS MOV I2C_BUFFER+3, A REPLY_FN_ENDPOINT1: MOV RW_COUNTER, #04H LJMP WRITE_TO_EMB_IN NEXT_ENDPOINT2: MOV I2C_BUFFER, #087H ;READ ENDPOINT STATUS LCALL READ_ONE_BYTE ;READ DATA FROM H11 SJMP REPLY_COMMON REPLY_STD_FN_CLEAR_FEATURE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_CLEAR_FEATURE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_CLEAR_FEATURE1 JMP @A+DPTR REPLY_STD_CLEAR_FEATURE1: AJMP REPLY_FN_CLEAR_DEVICE_FEATURE AJMP REPLY_FN_CLEAR_INTERFACE_FEATURE AJMP REPLY_FN_CLEAR_ENDPOINT_FEATURE REPLY_FN_CLEAR_DEVICE_FEATURE: LCALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_CLEAR_INTERFACE_FEATURE: LCALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_CLEAR_ENDPOINT_FEATURE: MOV TRANSACTION, #NO_TRANSACTION MOV A, INTERFACE_STATUS SWAP A ANL A, #0FH JZ REPLY_FN_CLEAR_ENDPOINT0_FEATURE DEC A JZ REPLY_FN_CLEAR_ENDPOINT1_FEATURE DEC A JZ REPLY_FN_CLEAR_ENDPOINT2_FEATURE LCALL SEND_FN_UNSTALL_INT1 LJMP SEND_FN_ZERO_PACKET REPLY_FN_CLEAR_ENDPOINT0_FEATURE: CLR E_PORT_STALL LCALL SEND_FN_UNSTALL_ENDPT0 LCALL SEND_FN_UNSTALL_ENDPT1 LJMP SEND_FN_ZERO_PACKET REPLY_FN_CLEAR_ENDPOINT1_FEATURE: LCALL SEND_FN_UNSTALL_INT0 LJMP SEND_FN_ZERO_PACKET REPLY_FN_CLEAR_ENDPOINT2_FEATURE: LCALL SEND_FN_UNSTALL_INT1 LJMP SEND_FN_ZERO_PACKET REPLY_STD_FN_CLEAR_FEATURE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_FEATURE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_FEATURE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_SET_FEATURE1 JMP @A+DPTR REPLY_STD_SET_FEATURE1: AJMP REPLY_FN_SET_DEVICE_FEATURE AJMP REPLY_FN_SET_INTERFACE_FEATURE AJMP REPLY_FN_SET_ENDPOINT_FEATURE REPLY_FN_SET_DEVICE_FEATURE: LCALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_SET_INTERFACE_FEATURE: LCALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_SET_ENDPOINT_FEATURE: MOV TRANSACTION, #NO_TRANSACTION MOV A, INTERFACE_STATUS SWAP A ANL A, #0FH JZ REPLY_FN_SET_ENDPOINT0 DEC A JZ REPLY_FN_SET_ENDPOINT1 DEC A JZ REPLY_FN_SET_ENDPOINT2 LCALL SEND_FN_STALL_INT1 LJMP SEND_FN_ZERO_PACKET REPLY_FN_SET_ENDPOINT0: SETB E_PORT_STALL LCALL SEND_FN_STALL_ENDPT1 LCALL SEND_FN_STALL_ENDPT0 LJMP SEND_FN_ZERO_PACKET REPLY_FN_SET_ENDPOINT1: LCALL SEND_FN_STALL_INT0 LJMP SEND_FN_ZERO_PACKET REPLY_FN_SET_ENDPOINT2: LCALL SEND_FN_STALL_INT1 LJMP SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_FEATURE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_ADDRESS: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_ADDRESS0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_ZERO_PACKET WAIT_FOR_CHANGE: MOV I2C_BUFFER,#READ_INT ;READ INTERRUPT REGISTER LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A,I2C_BUFFER JNB ACC.3, WAIT_FOR_CHANGE MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN ;WRITE NEW ADDRESS MOV A,FN_ADDR ORL A,#080H MOV I2C_BUFFER+1,A LCALL WRITE_ONE_BYTE RET REPLY_STD_FN_SET_ADDRESS0: ; Routine for every Ctrl-In entry ;MOV TRANSACTION, #NO_TRANSACTION ;MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN ;MOV A,FN_ADDR ;ORL A,#080H ;MOV I2C_BUFFER+1,A ;ENABLE EMBEDDED FN ;ACALL WRITE_ONE_BYTE RET; REPLY_STD_FN_GET_DESCRIPTOR: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_DESC0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV FN_TRANSACTION_INDEX, #00H REPLY_STD_FN_GET_DESC0: ; Routine for every Ctrl-In entry ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_FN_GET_DESC1 JMP @A+DPTR REPLY_STD_FN_GET_DESC1: AJMP REPLY_FN_GET_DEVICE_DESC0 AJMP REPLY_FN_GET_CONFIG_DESC0 AJMP REPLY_FN_GET_STRING_DESC0 AJMP REPLY_FN_GET_INTERFACE_DESC0 AJMP REPLY_FN_GET_ENDPOINT_DESC0 AJMP REPLY_FN_GET_HID_DESC0 AJMP REPLY_FN_GET_REPORT_DESC0 REPLY_FN_GET_DEVICE_DESC0: MOV DPTR, #FN_STAND_DEV_DESC MOV FN_TRANSACTION_END, #12H LJMP SEND_FN_DATA REPLY_FN_GET_CONFIG_DESC0: MOV DPTR, #FN_CONFIG_DESC MOV FN_TRANSACTION_END, #3bH LJMP SEND_FN_DATA REPLY_FN_GET_STRING_DESC0: MOV TRANSACTION, #NO_TRANSACTION LJMP SEND_FN_STALL_ENDPT1 REPLY_FN_GET_INTERFACE_DESC0: MOV A, INTERFACE_STATUS ANL A, #08H ; CHECK FOR MOUSE JNZ REPLY_INTERFACE1_DESC REPLY_INTERFACE0_DESC: ; KEYBOARD INTERFACE DESCRIPTOR MOV DPTR, #FN_INTERFACE0_DESC SJMP REPLY_INTERFACE_COMM_DESC REPLY_INTERFACE1_DESC: ; MOUSE INTERFACE DESCRIPTOR MOV DPTR, #FN_INTERFACE1_DESC REPLY_INTERFACE_COMM_DESC: MOV FN_TRANSACTION_END, #09H LJMP SEND_FN_DATA REPLY_FN_GET_ENDPOINT_DESC0: MOV A, INTERFACE_STATUS ANL A, #08H ; CHECK FOR MOUSE JNZ REPLY_ENDPOINT1_DESC REPLY_ENDPOINT0_DESC: ; KEYBOARD INTERFACE DESCRIPTOR MOV DPTR, #FN_ENDP0_INT_DESC SJMP REPLY_ENDPOINT_COMM_DESC REPLY_ENDPOINT1_DESC: ; MOUSE INTERFACE DESCRIPTOR MOV DPTR, #FN_ENDP1_INT_DESC REPLY_ENDPOINT_COMM_DESC: MOV FN_TRANSACTION_END, #07H LJMP SEND_FN_DATA REPLY_FN_GET_HID_DESC0: MOV A, INTERFACE_STATUS ANL A, #08H ; CHECK FOR MOUSE JNZ REPLY_HID1_DESC REPLY_HID0_DESC: ; KEYBOARD INTERFACE DESCRIPTOR MOV DPTR, #FN_HID0_DESC SJMP REPLY_HID_COMM_DESC REPLY_HID1_DESC: ; MOUSE INTERFACE DESCRIPTOR MOV DPTR, #FN_HID1_DESC REPLY_HID_COMM_DESC: MOV FN_TRANSACTION_END, #09H LJMP SEND_FN_DATA REPLY_FN_GET_REPORT_DESC0: MOV A, INTERFACE_STATUS ANL A, #08H ; CHECK FOR MOUSE JNZ REPLY_REPORT1_DESC REPLY_REPORT0_DESC: ; KEYBOARD INTERFACE DESCRIPTOR MOV DPTR, #FN_REPORT0_DESC MOV FN_TRANSACTION_END, #3FH SJMP REPLY_REPORT_COMM_DESC REPLY_REPORT1_DESC: ; MOUSE INTERFACE DESCRIPTOR MOV DPTR, #FN_REPORT1_DESC MOV FN_TRANSACTION_END, #32H REPLY_REPORT_COMM_DESC: LJMP SEND_FN_DATA REPLY_STD_FN_SET_DESCRIPTOR: ; NOT SUPPORTED ; MOV A, TRANSACTION ; JB ACC.0, REPLY_STD_FN_SET_DESC0 ; Routine for First Ctrl-In entry ; SETB ACC.0 ; MOV TRANSACTION, A REPLY_STD_FN_SET_DESC0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_GET_CONFIGURATION: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_CONFIG0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H MOV TRANSACTION, #NO_TRANSACTION JB EMBED_CONFIG, REPLY_FN_CONFIG REPLY_FN_NO_CONFIG: LJMP WRITE_TO_EMB_IN REPLY_FN_CONFIG: MOV I2C_BUFFER+3, #FN_CONFIGURED_STATUS LJMP WRITE_TO_EMB_IN REPLY_STD_FN_GET_CONFIG0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_CONFIGURATION: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_CONFIG0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION MOV A, FN_ADDR ORL A, #80H MOV FN_ADDR, A LCALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_CONFIG0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_GET_INTERFACE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_INTERFACE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H LJMP WRITE_TO_EMB_IN REPLY_STD_FN_GET_INTERFACE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_INTERFACE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_INTERFACE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_INTERFACE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SYNCH_FRAME: ; NOT SUPPORTED ;MOV A, TRANSACTION ;JB ACC.0, REPLY_STD_FN_SYNCH_FRAME0 ; Routine for First Ctrl-In entry ;SETB ACC.0 ;MOV TRANSACTION, A REPLY_STD_FN_SYNCH_FRAME0: ; Routine for every Ctrl-In entry ;AJMP SEND_FN_DATA RET; ; Class Requests REPLY_CLSS_FN_GET_REPORT: RET; REPLY_CLSS_FN_GET_IDLE: RET; REPLY_CLSS_FN_GET_PROTOCOL: RET; REPLY_CLSS_FN_SET_REPORT: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_REPORT0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_REPORT0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_CLSS_FN_SET_IDLE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_IDLE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION LCALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_IDLE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_CLSS_FN_SET_PROTOCOL: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_PROTOCOL0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION LJMP SEND_FN_STALL_ENDPT1 REPLY_STD_FN_SET_PROTOCOL0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; SEND_FN_DATA: MOV I2C_BUFFER, #EMB_IN_STATUS LCALL READ_ONE_BYTE MOV A, I2C_BUFFER JB ACC.5, END_SEND_FN_DATA MOV I2C_BUFFER,#WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV RW_COUNTER, #00H MOV R0, #I2C_BUFFER+3 MOV R1, #08H FILL_FN_BUFFER: INC RW_COUNTER MOV A, FN_TRANSACTION_INDEX MOVC A, @A+DPTR INC FN_TRANSACTION_INDEX MOV @R0, A INC R0 MOV A, FN_TRANSACTION_INDEX CJNE A, FN_DATA_REQUEST_LENGTH, NEXT_CHECK_LEVEL MOV TRANSACTION, #NO_TRANSACTION LJMP END_FN_DATA NEXT_CHECK_LEVEL: CJNE A, FN_TRANSACTION_END, MORE_FN_DATA MOV TRANSACTION, #NO_TRANSACTION AJMP END_FN_DATA MORE_FN_DATA: DJNZ R1, FILL_FN_BUFFER END_FN_DATA: MOV R0, #I2C_BUFFER+2 MOV @R0, RW_COUNTER INC RW_COUNTER INC RW_COUNTER LCALL WRITE_TO_EMB_IN END_SEND_FN_DATA: RET ;======================================== ; Common H11 commands ;======================================== SEND_FN_ZERO_PACKET: MOV I2C_BUFFER,#SEL_FN_IN_ENDPT LCALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #00H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H LCALL WRITE_DATA MOV I2C_BUFFER,#VALIDATE_BUF LCALL WRITE_COMMAND RET SEND_FN_STALL_ENDPT1: MOV I2C_BUFFER, #EMB_ENDPT1_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_STALL_ENDPT0: MOV I2C_BUFFER, #EMB_ENDPT0_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_STALL_INT0: MOV I2C_BUFFER, #EMB_INT0_ENDPT_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_STALL_INT1: MOV I2C_BUFFER, #EMB_INT1_ENDPT_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_UNSTALL_ENDPT1: MOV I2C_BUFFER, #EMB_ENDPT1_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_UNSTALL_ENDPT0: MOV I2C_BUFFER, #EMB_ENDPT0_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_UNSTALL_INT0: MOV I2C_BUFFER, #EMB_INT0_ENDPT_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA SEND_FN_UNSTALL_INT1: MOV I2C_BUFFER, #EMB_INT1_ENDPT_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H LJMP WRITE_DATA ;======================================== ; Comms to H11 ;======================================== WRITE_ONE_BYTE: MOV RW_COUNTER,#1 AJMP WRITE_DATA WRITE_TWO_BYTE: MOV RW_COUNTER,#2 AJMP WRITE_DATA READ_ONE_BYTE: MOV RW_COUNTER,#1 AJMP READ_DATA ; Read N bytes from the selected Buffer ; N - RW_COUNTER ; DATA - I2C_BUFFER ;--------------------------------------- READ_FROM_HUB_OUT: MOV A, I2C_BUFFER PUSH ACC MOV I2C_BUFFER,#SEL_HUB_OUT_ENDPT ACALL WRITE_COMMAND ACALL READ_ONE_BYTE POP ACC MOV I2C_BUFFER, A SJMP READ_DATA READ_FROM_FN_OUT: MOV A, I2C_BUFFER PUSH ACC MOV A, RW_COUNTER PUSH ACC MOV I2C_BUFFER,#SEL_FN_OUT_ENDPT ACALL WRITE_COMMAND ACALL READ_ONE_BYTE POP ACC MOV RW_COUNTER, A POP ACC MOV I2C_BUFFER, A READ_DATA: MOV SLV_ADR,#COMMAND_ADDRESS ;WRITE COMMAND MOV CNT_BYTE,#1 ;NUMBER OF BYTES TO BE SENT ACALL WRITE_H11_POINT ;WRITE COMMAND MOV SLV_ADR,#DATA_READ_ADDR ;READ DATA MOV CNT_BYTE,RW_COUNTER ACALL READ_H11 RET; READ_FROM_H11 ; Write N bytes into the selected Buffer ; N - RW_COUNTER ; DATA - I2C_BUFFER ;--------------------------------------- WRITE_TO_HUB_IN: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_HUB_IN_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER SJMP WRITE_DATA WRITE_TO_EMB_INT0: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_FN_INT0_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER SJMP WRITE_DATA WRITE_TO_EMB_INT1: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_FN_INT1_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER SJMP WRITE_DATA WRITE_TO_EMB_IN: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_FN_IN_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER WRITE_DATA: ACALL WRITE_COMMAND MOV SLV_ADR,#DATA_WRITE_ADDR ;WRITE DATA MOV CNT_BYTE,RW_COUNTER ACALL WRITE_H11 JNB VALIDATE_FLAG, END_WRITE_TO_H11 MOV I2C_BUFFER,#VALIDATE_BUF ;READY DATA TO SEND ACALL WRITE_COMMAND CLR VALIDATE_FLAG END_WRITE_TO_H11: RET; WRITE_TO_H11 ; Write One Byte to Command Address ;---------------------------------- WRITE_COMMAND: MOV SLV_ADR,#COMMAND_ADDRESS ;WRITE COMMAND MOV CNT_BYTE,#1 ;NUMBER OF BYTES TO BE SENT ACALL WRITE_H11_POINT ;READ 1 BYTES RET; WRITE_COMMAND ; Read From H11: ADDR+DATA ; ADDR = SLR_ADR ; DATA = Pointer at I2C_BUFFER ; #DATA = CNT_Byte ;------------------------ READ_H11: MOV BYTE_CNT,CNT_BYTE ACALL GOMASTER ;ACQUIRE BUS AND SEND SLAVE ADDRESS. JB I2C_FAIL,READ_NOK ;CHECK FOR SLAVE NOT RESPONDING. MOV R0,#I2C_BUFFER ;SET FIRST RECEIVE DATA BUFFER ADDRESS READ_DATA_LOOP: LCALL RCV_BYTE ;RECEIVE DATA BYTE MOV @R0,A ;PUT RECEIVED DATA TO BUFFER INC R0 ;PREPARE NEXT BYTE DJNZ BYTE_CNT,READ_DATA_LOOP ;REPEAT UNTIL ALL BYTES RECEIVED READ_NOK: READ_OK: LCALL SEND_STOP ;DONE, SEND AN I2C STOP. RET; READ_H11 ; WRITE TO H11: ADDR+DATA ; ADDR = SLR_ADR ; DATA = Pointer at I2C_BUFFER ; #DATA = CNT_Byte ;------------------------ WRITE_H11_POINT: MOV R0,#I2C_BUFFER ;SET FIRST RECEIVE DATA BUFFER ADDRESS WRITE_H11: MOV BYTE_CNT,CNT_BYTE ACALL GOMASTER ;ACQUIRE BUS AND SEND SLAVE ADDRESS. JB I2C_FAIL,WRITE_NOK ;CHECK FOR SLAVE NOT RESPONDING.; WRITE_DATA_LOOP: MOV A,@R0 ;GET DATA BYTE FROM BUFFER. LCALL SEND_BYTE ;SEND NEXT DATA BYTE. INC R0 ;ADVANCE BUFFER POINTER. JB I2C_FAIL,WRITE_NOK ;CHECK FOR SLAVE NOT RESPONDING. DJNZ BYTE_CNT,WRITE_DATA_LOOP ;ALL BYTES SENT? WRITE_NOK: WRITE_OK: LCALL SEND_STOP ;DONE, SEND AN I2C STOP. RET; WRITE_H11_POINT ;SEND SLAVE ADDRESS TO H11 ;------------------------- GOMASTER: CLR I2C_FAIL ;CLEAR ERROR STATUS FLAGS. JNB SCLPIN,FAULT ;CHECK FOR BUS CLEAR. JNB SDAPIN,FAULT CLR SDAPIN ;BEGIN I2C START. LCALL BITDLY CLR SCLPIN LCALL BITDLY ;COMPLETE I2C START. MOV A,SLV_ADR ;GET SLAVE ADDRESS. ACALL SEND_BYTE ;SEND SLAVE ADDRESS. RET; GOMASTER FAULT: SETB I2C_FAIL ;SET FAULT STATUS AND EXIT RET ;======================================== ; I2C ROUTINES ;======================================== RCV_BYTE: MOV BITCNT,#8 ;SET BIT COUNT. RCV_LOOP: LCALL SCLHIGH ;READ ONE DATA BIT. LCALL BITDLY MOV C,SDAPIN ;GET DATA BIT FROM PIN. RLC A ;ROTATE BIT INTO RESULT BYTE. CLR SCLPIN LCALL BITDLY DJNZ BITCNT,RCV_LOOP ;REPEAT UNTIL ALL BITS RECEIVED. PUSH ACC ;SAVE ACCUMULATOR MOV A,BYTE_CNT CJNE A,#1,SRBACK ;CHECK FOR LAST BYTE OF FRAME. SETB SDAPIN ;SEND NO ACKNOWLEDGE ON LAST BYTE. SJMP SRBACLK ;NO ACK WHEN IT'S LAST BYTE SRBACK: CLR SDAPIN ;SEND ACKNOWLEDGE BIT. SRBACLK: LCALL SCLHIGH ;SEND ACKNOWLEDGE CLOCK. POP ACC ;RESTORE ACCUMULATOR LCALL BITDLY CLR SCLPIN SETB SDAPIN ;CLEAR ACKNOWLEDGE BIT. LCALL BITDLY RET; RCV_BYTE ;----------------------------------- SEND_BYTE: MOV BITCNT,#8 ;SET BIT COUNT. SBLOOP: RLC A ;SEND ONE DATA BIT. MOV SDAPIN,C ;PUT DATA BIT ON PIN. LCALL SCLHIGH ;SEND CLOCK. LCALL BITDLY CLR SCLPIN LCALL BITDLY DJNZ BITCNT,SBLOOP ;REPEAT UNTIL ALL BITS SENT. SETB SDAPIN ;RELEASE DATA LINE FOR ACKNOWLEDGE. LCALL SCLHIGH ;SEND CLOCK FOR ACKNOWLEDGE. LCALL BITDLY JNB SDAPIN,SBEX ;CHECK FOR VALID ACKNOWLEDGE BIT. SETB I2C_FAIL ;SET STATUS FOR NO ACKNOWLEDGE. SBEX: CLR SCLPIN ;FINISH ACKNOWLEDGE BIT. LCALL BITDLY RET; SEND_BYTE ;----------------------------------- SCLHIGH: SETB SCLPIN ;Set SCL from our end. JNB SCLPIN,$ ;Wait for pin to actually go high. RET; SCLHIGH ;----------------------------------- SEND_STOP: CLR SDAPIN ;Get SDA ready for stop. ACALL SCLHIGH ;SET CLOCK FOR STOP. ACALL BITDLY SETB SDAPIN ;SEND I2C STOP. ACALL BITDLY RET; SEND_STOP ;BUS SHOULD NOW BE RELEASED. ;----------------------------------- BITDLY: ;NOPS TO DELAY 5 MICROSECONDS (MINUS 4 RET; BITDLY ;======================================== ; KEYBOARD'S CODE ;======================================== ;CSEG AT 08FFH KEYBOARD_INITIAL: MOV LAST_ZERO_SENT, #00H MOV ROW_NUM, #00H MOV INTERFACE_STATUS, #05H ; REPORT PROTOCOL ON DEFAULT ; FOR BOTH MOUSE AND KEYBOARD ; Activate Timer0 MOV TL0, #0E8H ; TL0 AND TH0 MAKES 1 millisec MOV TH0, #03H MOV TMOD, #00000000B ; TIMER0 IS SET AT MODE 0 MOV TCON, #00010000B ; TURNS TIMER0 ON MOV IE,#10000010B ;ALL INTERRUPT DISABLED, EXCEPT TIMER AND GLOBAL MOV KEY1, #00H MOV KEY2, #00H MOV KEY3, #00H MOV KEY4, #00H MOV KEY5, #00H MOV KEY6, #00H MOV KEY_MODIFIER, #00H MOV LED_STATUS, #00H CLEAN_KEY_BUFFER: MOV TOTAL_KEYS, #00H MOV KEY_HIT0, #00; K1 MOV KEY_HIT1, #00; K2 MOV KEY_HIT2, #00; K3 MOV KEY_HIT3, #00; K4 MOV KEY_HIT4, #00; K5 MOV KEY_HIT5, #00; K5 MOV MODIFIER_BYTE, #00; K6 RET KEYBOARD_ROUTINE: ; PURPOSE IS TO PULL EACH BIT OF X0 AND X1 SEQUENTIALLY AND ; SEE IF THE STATE OF Y0 HAS CHANGED, THEN OUTPUT THE READ ; VALUE ACALL SCAN_OUT CHECKKEY: MOV A, Y0 CPL A JZ END_KEYBOARD_ROUTINE START_OF_GHOST_ROUTINE: MOV R3, ROW_NUM ; STORE CURRENT ROW_NUM IN R3 MOV R4, Y0 ; Store this somewhere MOV R1, #10H ; TOTAL OF 16 ROWS TO COMPARE AGAINST (17-1) NEXT_CMP_GHOST: JNB WIN_KEY, GOTO_NEXT ; INCREMENT TO NEXT ROW MOV ROW_NUM, #00 ; ROLL OVER TO #00 AGAIN SJMP GOTO_NEXT1 ; IF MAXIMUM ROW_NUM OF #10H GOTO_NEXT: ; IS REACHED INC ROW_NUM ; GOTO_NEXT1: ; ACALL SCAN_OUT ; PULL THE RESPECTIVE ROLL DOWN MOV A, Y0 ; MOVE THE READ KEYSCAN INTO A MOV R2, A ; Store the new key scan MOV R6, #01H ; START bitwise test bit 0 NEXT_BIT_TEST1: MOV A, R4 ; R4 Is the row to test CPL A ; translating it into 1 means keypressed ANL A, R6 ; masking just one bit for testing JZ NEXT_BIT_TEST2 MOV A, R2 ; CHECK IF THE BIT CORRESPONDS TO ANY CPL A ; KEYPRESS ON THE SAME COLUMN ANL A, R6 JZ NEXT_BIT_TEST2 ; JUMP IF NO KEYS ON SAME COLUMN MOV A, R4 ; R4 Is the row to test CPL A ANL A, R6 ; masking just one bit for testing ORL A, R2 CPL A JNZ GHOST_KEY_FOUND NEXT_BIT_TEST2: MOV A, R6 ; PREPARING BITMASK FOR NEXT BIT CLR C ; CLEAR CARRY FOR SHIFTING ZERO INTO LSB RLC A ; SHIFT LEFT TO NEXT BIT JZ GOTO_NEXT2 ; 8 BITS ARE ALL SCANNED, GOTO NEXT ROW ;JZ END_CMP_GHOST MOV R6, A ; STORE THE BITMASK IN R6 SJMP NEXT_BIT_TEST1 GOTO_NEXT2: DJNZ R1, NEXT_CMP_GHOST SJMP END_CMP_GHOST GHOST_KEY_FOUND: MOV ROW_NUM, R3 ACALL FILL_KEY_BUFFER AJMP END_KEYBOARD_ROUTINE END_CMP_GHOST: MOV ROW_NUM, R3 ; RESTORE TO ORIGINAL ACALL SCAN_OUT END_OF_GHOST_ROUTINE: CHECKKEY1: ACALL KEYPRESSED END_KEYBOARD_ROUTINE: JB WIN_KEY, RESET_ZERO INC ROW_NUM RET RESET_ZERO: MOV X1, #0FFH MOV X0, #0FFH SETB WIN_BIT ACALL WRITE_LED MOV ROW_NUM, #00H MOV KEY1, KEY_HIT0 MOV KEY2, KEY_HIT1 MOV KEY3, KEY_HIT2 MOV KEY4, KEY_HIT3 MOV KEY5, KEY_HIT4 MOV KEY6, KEY_HIT5 MOV KEY_MODIFIER, MODIFIER_BYTE ACALL CLEAN_KEY_BUFFER MOV A, MOUSE_STATUS JNZ READ_MOUSE SETB PS2_CLK SETB PS2_DATA ACALL CHECK_MOUSE READ_MOUSE: ACALL PREPARING_PS2_READ RET ; Uses A as temp register and ROW_NUM to pull down appropriate pin SCAN_OUT: SETB LED_ENABLE SETB NUM SETB SCROLL SETB CAPS MOV A, ROW_NUM JB WIN_KEY, WIN_SCAN ACALL SCAN_ROW SETB WIN_BIT JB X_LO, XLO ; JUMP TO XLO IF BIT IS SET XHI: ; Upper byte MOV X1, A MOV X0, #0FFH RET XLO: ; Lower byte MOV X1, #0FFH MOV X0, A RET WIN_SCAN: MOV X1, #0FFH MOV X0, #0FFH CLR WIN_BIT RET FILL_KEY_BUFFER: MOV KEY_HIT0, #01H MOV KEY_HIT1, #01H MOV KEY_HIT2, #01H MOV KEY_HIT3, #01H MOV KEY_HIT4, #01H MOV KEY_HIT5, #01H MOV TOTAL_KEYS, #06H RET ; SET The bit corresponding to ROW NUMBER of A zero ; ------------------------------------------------- SCAN_ROW: MOV A, ROW_NUM ANL A, #07H MOV DPTR, #SCAN_ROW_MATRIX MOVC A, @A+DPTR RET; SCAN_ROW ; Processing of keypressed ; ------------------------ KEYPRESSED: MOV A, Y0 MOV BIT_NUMBER, #08H CLR C NEXT_KEY1: RLC A JC NEXT_KEY2 ACALL SEND_MAKE_CODE NEXT_KEY2: DJNZ BIT_NUMBER, NEXT_KEY1 RET ; Send make code ; -------------- SEND_MAKE_CODE: DEC BIT_NUMBER ; Because BIT_NUMBER ranges from 1 - 8 PUSH ACC MOV DPTR, #KEYS_LUT MOV A, ROW_NUM RL A RL A RL A ANL A, #0f8H ORL A, BIT_NUMBER MOVC A, @A+DPTR JZ END_SEND_MAKE_CODE MOV R4_DIRECT, A ; STORE IN R4 MOV DPTR, #SPECIAL_KEYS MOV R5, #8 CHECK_SPECIAL: MOV A, R5 MOVC A, @A+DPTR CJNE A, R4_DIRECT, CHECK_SPECIAL_1 MOV A, R5 ADD A, #8 MOVC A, @A+DPTR ORL MODIFIER_BYTE, A MOV LAST_ZERO_SENT, #00H AJMP END_SEND_MAKE_CODE CHECK_SPECIAL_1: DJNZ R5, CHECK_SPECIAL MOV A, #06 ; Check if total keys stored is over 6 CJNE A, TOTAL_KEYS, ADD_KEY MAX_KEY_HIT: ACALL FILL_KEY_BUFFER SJMP END_SEND_MAKE_CODE ADD_KEY: MOV LAST_ZERO_SENT, #00H MOV A, R1 PUSH ACC MOV A, R4 ; Key Code pushed onto stack PUSH ACC MOV A, #KEY_HIT0 ADD A, TOTAL_KEYS MOV R1, A ; Put location of keyhit in R1 POP ACC MOV @R1, A POP ACC MOV R1, A INC TOTAL_KEYS END_SEND_MAKE_CODE: JNB SUSPEND, FINISH_SEND_MAKE_CODE ;JNB EMBED_CONFIG, FINISH_SEND_MAKE_CODE JNB EMBED_REMOTE_WKUP, FINISH_SEND_MAKE_CODE ; ONLY SEND RESUME IF IT IS CONFIGURED AND SUSPENDED MOV A, R0 ; SAFE KEEPING PUSH ACC MOV A, R2 ; SAFE KEEPING PUSH ACC MOV I2C_BUFFER,#RESUME_DEV MOV I2C_BUFFER+1,#00H ;DISENABLE HUB LCALL WRITE_ONE_BYTE POP ACC MOV R2, A POP ACC MOV R0, A FINISH_SEND_MAKE_CODE: POP ACC INC BIT_NUMBER RET RESET_PS2: SETB PS2_DATA SETB PS2_CLK MOV CLICKBYTE, #00H MOV MOUSE_STATUS, #00H RET CHECK_MOUSE: ; Writing #0F5H to disable the mouse ;---------------------------------- MOV A, #0F5H; ACALL WRITE_PS2_BYTE JNC NO_MOUSE_ATTACHED ACALL READ_PS2_BYTE XRL A, #0FAH JNZ NO_MOUSE_ATTACHED SJMP RESET_MOUSE NO_MOUSE_ATTACHED: RET RESET_MOUSE: ; Writing #0F6H to set Default for the mouse ;---------------------------------------------- MOV A, #0F6H; ACALL WRITE_PS2_BYTE ACALL READ_PS2_BYTE XRL A, #0FAH JNZ RESET_PS2_FAIL ; Writing #0E7H to set Resolution for the mouse ;---------------------------------------------- MOV A, #0E7H; ACALL WRITE_PS2_BYTE ACALL READ_PS2_BYTE XRL A, #0FAH JNZ RESET_PS2_FAIL ; Writing #0E8H to set Resolution for the mouse ;---------------------------------------------- MOV A, #0E8H; ACALL WRITE_PS2_BYTE ACALL READ_PS2_BYTE XRL A, #0FAH JNZ RESET_PS2_FAIL ; Writing #03H to set Resolution to 8 counts/mm for the mouse ;------------------------------------------------------------ MOV A, #03H; ACALL WRITE_PS2_BYTE ACALL READ_PS2_BYTE XRL A, #0FAH JNZ RESET_PS2_FAIL ; Writing #0F4H to enable the mouse ;---------------------------------- MOV A, #0F4H; ACALL WRITE_PS2_BYTE ACALL READ_PS2_BYTE XRL A, #0FAH JNZ RESET_PS2_FAIL MOV MOUSE_STATUS, #0FFH RESET_PS2_FAIL: RET ;---------- WAITING -------------------- WAIT_90US: ; To wait abt 90 usec MOV A, #030 SJMP WASTE_TIME WAIT_15US: ; To wait abt 90 usec MOV A, #05 SJMP WASTE_TIME WAIT_45US: ; To wait abt 45 usec MOV A, #015 SJMP WASTE_TIME WAIT_100US: MOV A, #33 SJMP WASTE_TIME WAIT_768US: ; To wait abt 768 usec MOV A, #0FFH WASTE_TIME: DEC A ; 1 cycle JNZ WASTE_TIME ; 2 cycles RET ;-------------------------------------- DELAY_255MS: MOV R7, #0FFH SJMP DELAY_1MS DELAY_20MS: MOV R7,#20 ;---- DELAY_1MS: MOV A,#165 ;(165*3+2+1)*1=498us DY: NOP NOP NOP DEC A JNZ DY DJNZ R7,DELAY_1MS RET ;================================================== ; Function : Preparing_PS2_Read ; Read 3 bytes from the mouse ;================================================== PREPARING_PS2_READ: SETB PS2_CLK READ_START_BIT: JNB PS2_CLK, $ ; WAIT FOR CLK TO FLOAT ACALL READ_PS2_BYTE JNC FAILED_PS2_COMMS MOV PS1BYTE, A ACALL READ_PS2_BYTE JNC FAILED_PS2_COMMS MOV PS2BYTE, A ACALL READ_PS2_BYTE JNC FAILED_PS2_COMMS MOV PS3BYTE, A SLEEPING_PS2: CLR PS2_CLK MOV XBYTE, PS2BYTE MOV A, PS3BYTE CPL A INC A MOV YBYTE, A MOV A, PS1BYTE JNB ACC.0, LEFT_BUTTON_NOT_PRESSED LEFT_BUTTON_PRESSED: ORL CLICKBYTE, #01H SJMP NEXT_BUTTON_TEST1 LEFT_BUTTON_NOT_PRESSED: ANL CLICKBYTE, #0FEH NEXT_BUTTON_TEST1: JNB ACC.1, RIGHT_BUTTON_NOT_PRESSED RIGHT_BUTTON_PRESSED: ORL CLICKBYTE, #02H RET RIGHT_BUTTON_NOT_PRESSED: ANL CLICKBYTE, #0FDH ; LOAD_TO_D11: ; ; MOV I2C_BUFFER, #EMB_INT1_ENDPT_STATUS ; LCALL READ_ONE_BYTE ; ; MOV I2C_BUFFER,#87H ;READ CURRENT ENDPT STATUS ; LCALL READ_ONE_BYTE ;READ DATA FROM H11 ; ; MOV A, I2C_BUFFER ; JB ACC.5, END_LOAD_TO_D11 ; BUFFER FULL ; ; MOV I2C_BUFFER, #WRITE_BUFFER ; MOV I2C_BUFFER+1, #00H ; MOV I2C_BUFFER+2, #03H ; MOV I2C_BUFFER+3, CLICKBYTE; Modifier ; MOV I2C_BUFFER+4, XBYTE ; MOV I2C_BUFFER+5, YBYTE ; MOV RW_COUNTER, #05H ; MOV TOTAL_KEYS, #00H ; LCALL WRITE_TO_EMB_INT1 ; MOV XBYTE, #00 ; MOV YBYTE, #00 ; END_LOAD_TO_D11: RET FAILED_PS2_COMMS: MOV A, MOUSE_STATUS DEC A MOV MOUSE_STATUS, A CLR PS2_CLK SETB PS2_DATA RET ;================================================== ; Function : Wait_Falling_Clk ; Check for falling edge ; On Success, Set C ; On Fail, Clr C (Timeout = 1.2 msec) ; Assumes Clk line is already High ;================================================== WAIT_FALLING_CLK: PUSH ACC MOV A, #0FFH CLR C NEXT_CLK_HI_SAMPLE: DEC A JZ END_WAIT_FALLING_CLK JB PS2_CLK, NEXT_CLK_HI_SAMPLE SETB C END_WAIT_FALLING_CLK: POP ACC RET ;================================================== ; Function : Wait_Rising_Clk ; Check for Rising edge ; On Success, Set C ; On Fail, Clr C (Timeout = 1.2 msec) ; Assumes Clk line is already Low ;================================================== WAIT_RISING_CLK: PUSH ACC MOV A, #0FFH ; 5 cycles * 255 = 1.2 msec CLR C NEXT_CLK_LO_SAMPLE: DEC A ; 1 cycles JZ END_WAIT_RISING_CLK ; 2 cycles JNB PS2_CLK, NEXT_CLK_LO_SAMPLE ;2 cycles SETB C END_WAIT_RISING_CLK: POP ACC RET ;================================================== ; Function : Write_PS2_Byte ; ; Store the PS2 byte in A ; Byte is sent out in the following format ; ; Bit Function ; --- -------- ; Start Bit Always 0 ; B0 Data (LSB) ; B1~B6 Data ; B7 Data (MSB) ; Parity Bit Odd Parity ; Stop Bit Always 1 ; ; Uses : R0 as a temp register ; R1 as a register for Parity Check ; On Success : Set C ; On Fail : Clr C ;================================================== WRITE_PS2_BYTE: SETB PS2_DATA CLR PS2_CLK ; CLK line must be held low for ; some time MOV R1, #00 MOV R0, #20 WAIT_FOR_RESPOND1: NOP NOP NOP NOP DJNZ R0, WAIT_FOR_RESPOND1 CLR PS2_DATA ; Start Bit MOV R0, #20 WAIT_FOR_RESPOND2: NOP NOP NOP NOP DJNZ R0, WAIT_FOR_RESPOND2 SETB PS2_CLK MOV R0, #8 ; 8 bits to shift JB PS2_CLK, END_START_BIT ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT END_START_BIT: ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT NEXT_PS2_BIT: RRC A MOV PS2_DATA, C JNC WAIT_CLK INC R1 WAIT_CLK: ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT DJNZ R0, NEXT_PS2_BIT MOV A, R1 RRC A CPL C MOV PS2_DATA, C ; Parity_Bit ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT SETB PS2_DATA ; Stop Bit ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT SETB PS2_DATA SETB C END_WRITE_PS2_BYTE: SETB PS2_DATA SETB PS2_CLK RET ;================================================== ; Function : Read_PS2_Byte ; ; Store the PS2 byte in A ; Byte is read out in the following format ; ; Bit Function ; --- -------- ; Start Bit Always 0 ; B0 Data (LSB) ; B1~B6 Data ; B7 Data (MSB) ; Parity Bit Odd Parity ; Stop Bit Always 1 ; ; A = B0 ~ B7 ; Mouse Should reply in 300 usecs ; ; Uses : R0 as a temp register ; ; On Success : Set C ; On Fail : Clr C ;================================================== READ_PS2_BYTE: MOV R0, #8 ; 8 bits to shift ACALL WAIT_FALLING_CLK JNC END_READ_PS2_BYTE; TIMED-OUT ACALL WAIT_RISING_CLK JNC END_READ_PS2_BYTE; TIMED-OUT JB PS2_DATA, END_READ_PS2_BYTE ; Start Bit must be Zero READ_NEXT_PS2_BIT: ACALL WAIT_FALLING_CLK JNC END_READ_PS2_BYTE; TIMED-OUT ACALL WAIT_RISING_CLK JNC END_READ_PS2_BYTE; TIMED-OUT MOV C, PS2_DATA RRC A DJNZ R0, READ_NEXT_PS2_BIT ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_FALLING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT ACALL WAIT_RISING_CLK JNC END_WRITE_PS2_BYTE; TIMED-OUT SETB C END_READ_PS2_BYTE: SETB PS2_DATA RET WRITE_LED: MOV A, LED_STATUS CPL A RRC A MOV NUM, C RRC A MOV CAPS, C RRC A MOV SCROLL, C CLR LED_ENABLE RET ASCII: DB '0123456789ABCDEF' SPECIAL_KEYS: DB 00H ; DUMMY DB 0E1H ; LEFT SHIFT DB 0E5H ; RIGHT SHIFT DB 0E0H ; LEFT CONTROL DB 0E4H ; RIGHT CONTROL DB 0E2H ; LEFT ALT DB 0E6H ; RIGHT ALT DB 0E3H ; KEYBOARD LEFT GUI DB 0E7H ; KEYBOARD RIGHT GUI MODIFIER_SPECIAL_KEYS: DB 00000010B ; LEFT SHIFT DB 00100000B ; RIGHT SHIFT DB 00000001B ; LEFT CONTROL DB 00010000B ; RIGHT CONTROL DB 00000100B ; LEFT ALT DB 01000000B ; RIGHT ALT DB 10000000B ; KEYBOARD LEFT GUI DB 10000000B ; KEYBOARD RIGHT GUI ;============================================= ; EMBEDDED FUNCTION STANDARD DEVICE DESCRIPTOR ;============================================= FN_STAND_DEV_DESC: DB 12h ;0 bLength DB 01h ;1 bDescriptorType DB 00h ; DB 01h ;2-3 version 1.00 USB spec Word DB 00h ;4 Class DB 00h ;5 bDeviceSubClass DB 00h ;6 bDeviceProtocol DB 08h ;7 bMaxPacketSize0 DW 7104h ;8-9 idVendor DW 0203h ;a-b idProduct product 02 version 05 -Fast Stack!!- DW 0001h ;c-d bcdDevice DB 00h ;e iManufacturer DB 00h ;f iProduct DB 00h ;10 iSerialNumber DB 01h ;11 bNumConfigurations FN_CONFIG_DESC: DB 09h ;0 DB 02h ;1 DW 3b00h ;2-3 DB 02h ;4 Two interfaces DB 01h ;5 Argument to set config DB 00h ;6 DB 0A0h ;7 bus powered and remote wakeup DB 05h ;8 FN_INTERFACE0_DESC: ; interface descriptor for keyboard DB 09h ;0 DB 04h ;1 DB 00h ;2 Interface 0 DB 00h ;3 DB 01h ;4 DB 03h ;5 DB 01h ;6 DB 01h ;7 DB 00h ;8 FN_HID0_DESC: ; HID descriptor for keyboard DB 09H DB 21H DB 00H DB 01H DB 00H DB 01H DB 22H DB 3FH DB 00H FN_ENDP0_INT_DESC: ; endpoint descriptor for keyboard DB 07h ;0 DB 05h ;1 DB 81h ;2 DB 03h ;3 DW 0800h ;4-5 DB 012h ;6 polling time FN_INTERFACE1_DESC: ; interface descriptor for mouse DB 09h ;0 DB 04h ;1 DB 01h ;2 Interface #1 DB 00h ;3 DB 01h ;4 DB 03h ;5 DB 01h ;6 DB 02h ;7 DB 00h ;8 FN_HID1_DESC: ; HID descriptor for mouse DB 09H DB 21H DB 00H DB 01H DB 00H DB 01H DB 22H DB 32H DB 00H FN_ENDP1_INT_DESC: ; Endpoint Descriptor for mouse DB 07h ;0 DB 05h ;1 DB 82h ;2 DB 03h ;3 DW 0800h ;4-5 DB 012h ;6 polling time FN_REPORT0_DESC: ; Report Descriptor for keyboard DB 005H DB 001H DB 009H DB 006H DB 0A1H DB 001H DB 005H DB 007H DB 019H DB 0E0H DB 029H DB 0E7H DB 015H DB 000H DB 025H DB 001H DB 075H DB 001H DB 095H DB 008H DB 081H DB 002H DB 095H DB 001H DB 075H DB 008H DB 081H DB 001H DB 095H DB 005H DB 075H DB 001H DB 005H DB 008H DB 019H DB 001H DB 029H DB 005H DB 091H DB 002H DB 095H DB 001H DB 075H DB 003H DB 091H DB 001H DB 095H DB 006H DB 075H DB 008H DB 015H DB 000H DB 025H DB 065H DB 005H DB 007H DB 019H DB 000H DB 029H DB 065H DB 081H DB 000H DB 0C0H FN_REPORT1_DESC: ; Report Descriptor for Mouse DB 005H DB 001H DB 009H DB 002H DB 0A1H DB 001H DB 009H DB 001H DB 0A1H DB 000H DB 005H DB 009H DB 019H DB 001H DB 029H DB 003H DB 015H DB 000H DB 025H DB 001H DB 095H DB 003H DB 075H DB 001H DB 081H DB 002H DB 095H DB 001H DB 075H DB 005H DB 081H DB 001H DB 005H DB 001H DB 009H DB 030H DB 009H DB 031H DB 015H DB 081H DB 025H DB 07FH DB 075H DB 008H DB 095H DB 002H DB 081H DB 006H DB 0C0H DB 0C0H ;********* END OF EMBEDDED FUNCTION DESCRIPTOR ****** SCAN_ROW_MATRIX: DB 0FEH DB 0FDH DB 0FBH DB 0F7H DB 0EFH DB 0DFH DB 0BFH DB 07FH ;_______________________________________________ ; Keys corresponding to X and Y ;_______________________________________________ KEYS_LUT: ; DB 00H, 0E2H, 00H, 00H, 47H, 0E6H, 00H, 46H ; DB 53H, 2CH, 59H, 5CH, 5FH, 51H, 4CH, 00H ; DB 55H, 63H, 5BH, 5EH, 61H, 56H, 4BH, 4EH ; DB 00H, 52H, 58H, 00H, 57H, 50H, 4AH, 4DH ; DB 00H, 00H, 0E5H, 0E1H, 00H, 00H, 00H, 00H ; DB 1BH, 00H, 16H, 39H, 1AH, 00H, 3AH, 1FH ; DB 1DH, 29H, 04H, 2BH, 14H, 00H, 35H, 1EH ; DB 0E4H, 00H, 00H, 00H, 00H, 00H, 0E0H, 00H ; DB 06H, 3DH, 07H, 03CH, 08H, 00H, 3BH, 20H ; ; DB 19H, 0AH, 09H, 17H, 15H, 05H, 22H, 21H ; DB 10H, 0BH, 0DH, 1CH, 18H, 11H, 23H, 24H ; ; DB 36H, 3FH, 0EH, 30H, 0CH, 00H, 2EH, 25H ; DB 37H, 00H, 0FH, 40H, 12H, 65H, 41H, 26H ; DB 00H, 34H, 33H, 2FH, 13H, 38H, 2DH, 27H ; DB 28H, 44H, 31H, 2AH, 00H, 45H, 42H, 43H ; DB 54H, 62H, 5AH, 5DH, 60H, 4FH, 49H, 00H ; DB 00H, 00H, 0E7H,0E3H, 00H, 00H, 00H, 00H $include(h11a_mat.txt) END