⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dongmain.asm

📁 mcs51,2051,x86系列MCU
💻 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 + -