📄 dongmain.asm
字号:
TITLE "DONGMAIN.ASM"
COMMENT /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(C) Copyright Intel Corp., 1996
File: dongmain.asm
Legacy keyboard & mouse interface code
Description: Converts legacy keyboard & mouse signals to USB.
This main program does the keyboard and mouse
initialization. Also residing here is an independent
function (TIMER0_ISR) that is described below.
Other files used: externs.inc, donconst.inc, kbdisr.asm,
mouseisr.asm, reports.asm, lite_frm.asm
Revision History
---------------------------------------------
0.1 8-2-96 Steve Roberts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
include 82930.INC
include DONCONST.INC
extern SEND_KBD_REPORT_EP2:CODE
public DONGLE_INITIALIZATION
public SET_LED_STATUS
public KBD_BUFFER_START,KBD_BUFFER_END,MOUSE_BUFFER
public MOUSE_BUFFER_WOFFSETL,MOUSE_BUFFER_WOFFSETH
public MOUSE_BUFFER_ROFFSETL,MOUSE_BUFFER_ROFFSETH
public MOUSE_DATA_COUNTL,MOUSE_DATA_COUNTH
public DATA_TO_KBD,DATA_FROM_KBD,KBD_MODE,BIT_COUNT,MASK_BIT
public KEY_CODE_INDEX,KEY_CODE_TABLE,BREAK_CODE_MODE,KBD_COMMAND
public ERROR_ROLLOVER_STATE
public REPORT_ID,USB_PROTOCOL,LED_STATUS,IDLE_RATE,IDLE_MODE
public TIMER0_4MS
;***************************
; "EDATA" Space variables
;***************************
define MOUSE_DATA,SPACE=EDATA, ORG=00:1000h ;Critical position
segment MOUSE_DATA ;for report generation
;code in "rpreqisr.asm"
MOUSE_BUFFER: ds 800h
MOUSE_BUFFER_ROFFSETL: ds 1
MOUSE_BUFFER_ROFFSETH: ds 1
MOUSE_BUFFER_WOFFSETL: ds 1
MOUSE_BUFFER_WOFFSETH: ds 1
MOUSE_DATA_COUNTL: ds 1
MOUSE_DATA_COUNTH: ds 1
;*************************
; "DATA" SPACE VARIABLES
;*************************
define STEVES_DATA,SPACE=DATA
segment STEVES_DATA
KBD_BUFFER_START: ds 7
KBD_BUFFER_END: ds 1
DATA_TO_KBD: ds 1
DATA_FROM_KBD: ds 1
KBD_MODE: ds 1
BIT_COUNT: ds 1
BYTE_COUNT: ds 1
MASK_BIT: ds 1
KEY_CODE_INDEX: ds 1
BREAK_CODE_MODE: ds 1
KBD_COMMAND: ds 1
ERROR_ROLLOVER_STATE: ds 1
LED_STATUS: ds 1
REPORT_ID: ds 1
USB_PROTOCOL: ds 1
IDLE_RATE: ds 1
IDLE_MODE: ds 1
TIMER0_4MS: ds 1
;***************************
; "CODE" Space Constants
;***************************
define KEY_TABLE,SPACE=CODE
segment KEY_TABLE
KEY_CODE_TABLE:
db 00H,00H,00H,00H,1CH,32H,21H,23H,24H,2BH,34H,33H,43H,3BH,42H,4BH
db 3AH,31H,44H,4DH,15H,2DH,1BH,2CH,3CH,2AH,1DH,22H,35H,1AH,16H,1EH
db 26H,25H,2EH,36H,3DH,3EH,46H,45H,5AH,08H,66H,0DH,29H,4EH,55H,54H
db 5BH,5CH,00H,4CH,52H,0EH,41H,49H,4AH,14H,07H,0FH,17H,1FH,27H,2FH
db 37H,3FH,47H,4FH,56H,5EH,57H,5FH,62H,67H,6EH,6FH,64H,65H,6DH,6AH
db 61H,60H,63H,76H,77H,7EH,84H,7CH,79H,69H,72H,7AH,6BH,73H,74H,6CH
db 75H,7DH,70H,71H,53H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 11H,12H,19H,00H,58H,59H,39H,00H,00H
define TIMER0_ISR_VECTOR,SPACE=CODE, ORG=00400Bh ; For DEBUGGER
segment TIMER0_ISR_VECTOR
ejmp TIMER0_ISR
;define TIMER0_ISR_VECTOR,SPACE=CODE, ORG=FF000Bh ; For burning FLASH
;segment TIMER0_ISR_VECTOR
; ejmp TIMER0_ISR
DEFINE MAIN_CODE, SPACE=CODE
SEGMENT MAIN_CODE
DONGLE_INITIALIZATION:
;-------------------------------------------------------------------
;Function : INIT_MOUSE
;Description : Does all necessary initialization for mouse commun.
;-------------------------------------------------------------------
INIT_MOUSE:
mov R0, #00h
mov MOUSE_BUFFER_ROFFSETL, R0
mov MOUSE_BUFFER_ROFFSETH, R0
mov MOUSE_BUFFER_WOFFSETL, R0
mov MOUSE_BUFFER_WOFFSETH, R0
mov MOUSE_DATA_COUNTL, R0
mov MOUSE_DATA_COUNTH, R0
; Code to use Timer 2 as baud rate generator
;********************************************************
mov T2CON, #00110000B ; Timer 2 mode Baud Rate Gen.
mov RCAP2H, #0FDh ; set timer 2 reload value to get
mov RCAP2L, #08Fh ; 1200 BAUD at 24MEG (2X the xtal freq)
setb T2CON.2 ; start timer
mov SCON, #01010000B ; Set serial port to Mode 1
;*********************************************************
mov EPCON3, #03H ; Enable EP3 xmit
mov TXCON3, #84h ; Clear TXFIFO3 & put in auto mode
setb IE0.7 ; Global interrupt enable
setb IE0.4 ; Serial port interrupt enable
setb IE_USB.3 ; Enables EP3 interrupts (IE1.3)
setb SBIE.6 ; Enables TXD3 int
;---------------------------------------------------------------
; Function: INIT_KBD
; Description: Initializes all kbd variables and sends kbd
; the initial setup info
;---------------------------------------------------------------
INIT_KBD:
mov BIT_COUNT, #0Ah ; For kbdisr data processing
mov BREAK_CODE_MODE, #0 ; For kbdisr break code processing
mov KBD_COMMAND, #0
mov KEY_CODE_INDEX, #0
mov ERROR_ROLLOVER_STATE, #0
mov LED_STATUS, #0
mov USB_PROTOCOL, #1 ; For BOOT/ITEM Protocol setting/checking
; 0=BOOT ; 1=ITEM
mov IDLE_RATE, #0
mov IDLE_MODE, #0
mov TIMER0_4MS, #0
mov WR16, #KBD_BUFFER_START
mov WR18, #KBD_BUFFER_END
mov R0, #1
mov @WR16, R0 ; This writes the Report ID byte
inc WR16, #1
mov R0, #0
INIT_KBD_BUFFER: ; Writes 0 to all other kbd buffer locs.
mov @WR16, R0
inc WR16, #1
cmp WR16, WR18
jle INIT_KBD_BUFFER
setb IE0.2 ; Enables INT1
orl TCON, #04h ; Sets up INT1 to be edge triggered
setb IPH0.2 ; Sets INT1 to highest priority level
setb IPL0.2
setb IPH0.0
setb IPL0.0
mov EPCON2, #03H ; Enable EP2 xmit
mov TXCON2, #84h ; Clear TXFIFO2 & put in auto mode
setb IE_USB.2 ; Enables EP2 interrupts (IE1.2)
setb SBIE.4 ; Enables TXD2 int
;**********************
; send "ECHO" to kbd ; This is to sense if kbd is connected.
;********************** ; In no response - skip other kbd sends
ECHO:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #0EEh
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
mov R1, #0FFh
mov R2, #0FFh
CHECK_AGAIN0:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je ECHO
djnz R1, CHECK_AGAIN0
djnz R2, CHECK_AGAIN0
mov R0, #0EEh
cmp R0, KBD_COMMAND
je RESET
ljmp EXIT_DONGLE_INITIALIZATION
;*********************
; send "RESET" to kbd
;*********************
RESET:
mov KBD_MODE, #0 ;0 means send to kbd mode
mov DATA_TO_KBD, #0FFh
lcall WAIT
clr P3.4 ;P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN1:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je RESET
mov R0, #KBD_ACK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN1
setb P3.3 ; Set CLK & DATA lines high as ACK
setb P3.4 ; acknowledge
CHECK_AGAIN1B:
mov R0, #KBD_SELFTEST_FAIL
cmp R0, KBD_COMMAND ; Send a RESET if self test fails
je RESET
mov R0, #KBD_SELFTEST_OK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN1B
;**********************
; send "ENABLE" to kbd
;**********************
ENABLE:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #0F4h
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN2:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je ENABLE
mov R0, #KBD_ACK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN2
;*******************************
; send "SELECT SCAN SET" to kbd
;*******************************
SELECT_SCAN_SET:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #0F0h
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN3:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je SELECT_SCAN_SET
mov R0, #KBD_ACK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN3
;********************************
; send "SCAN SET REQUEST" to kbd
;********************************
SCAN_SET_REQUEST:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #003h
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN4:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je SCAN_SET_REQUEST
mov R0, #KBD_ACK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN4
;************************************************
; send "ALL KEYS MAKE-BREAK/NO TYPEMATIC" to kbd
;************************************************
MAKE_BREAK_ONLY:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #0F8h
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN5:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je MAKE_BREAK_ONLY
mov R0, #KBD_ACK
cmp R0, KBD_COMMAND
jne CHECK_AGAIN5
lcall SET_LED_STATUS ;**TEMP - Ken's code will call this
jmp SEND_INITIAL_KBD_REPORT
WAIT:
mov R0, BIT_COUNT
cmp R0, #0Ah
jne WAIT
ret
;-------------------------------------------------------------
SEND_INITIAL_KBD_REPORT:
lcall SEND_KBD_REPORT_EP2
EXIT_DONGLE_INITIALIZATION:
ret
;-------------------------------------------------------------------
;Function name : SET_LED_STATUS
;Brief Description : Sends a report to the kbd to tell it which LED's
; should be on. This info is obtained from the host
; through a "SET_REPORT(Output)" request.
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------
SET_LED_STATUS:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, #0EDh ; ED hex tells kbd to expect LED byte next
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN6:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je SET_LED_STATUS
mov R0, #KBD_ACK ; Wait for ACK from kbd
cmp R0, KBD_COMMAND
jne CHECK_AGAIN6
SEND_LED_STATUS:
mov KBD_COMMAND, #0 ; Clears last ACK
mov KBD_MODE, #0 ; 0 means send to kbd mode
mov DATA_TO_KBD, LED_STATUS ; Takes LED info from USB code
; BIT0 = Scroll Lock
; BIT1 = Num Lock
; BIT2 = Caps Lock
; All other bits = 0
lcall WAIT
clr P3.4 ; P3.4 (DATA line) low tells kbd to rcv
CHECK_AGAIN7:
mov R0, #KBD_RESEND
cmp R0, KBD_COMMAND ; Does kbd want a resend?
je SEND_LED_STATUS
mov R0, #KBD_ACK ; Wait for ACK from kbd
cmp R0, KBD_COMMAND
jne CHECK_AGAIN7
ret
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Function name : TIMER0_ISR
;Brief Description : Tallies number of times T0 has overflowed and
; compares this value with the desired duration
; of the IDLE set bu the USB host. NOTE: T0 is
; loaded so that an interrupt occurs every 4msec.
;Regs preserved : All used
;--------------------------------------------------------------------
TIMER0_ISR:
push R0
mov TH0, #0E0h ; Reset timer value
mov TL0, #0BFh
mov R0, TIMER0_4MS ; Total time elapsed is 4ms x (TIMER0_4MS)
inc R0
mov TIMER0_4MS, R0
cmp R0, IDLE_RATE ; IDLE_RATE is set by the USB host
je CALL_SEND_KBD_REPORT_EP2
pop R0
reti
CALL_SEND_KBD_REPORT_EP2:
lcall SEND_KBD_REPORT_EP2
mov TIMER0_4MS, #0 ; Reset elapsed time count
pop R0
reti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -