📄 jb8-usb.asm
字号:
MOV #%00000111,UCR3 ; enable EP1,EP2 no STALL
$ENDIF
$IFNOT USB_IPullup
MOV #%00000011,UCR3 ; enable EP1,EP2 no STALL
$ENDIF
*
* --- Init. Variables of Keyboard Report ---------------------------------
MOV V_IF0_Idle,VC_IF0_Idle ; start Kbd idle timeout cntr
MOV V_IF1R1_Idle,VC_IF1R1_Idle ; start ACPI idle timout cntr
MOV V_IF1R2_Idle,VC_IF1R3_Idle ; start Hot Key timout cntr
MOV V_IF1R3_Idle,VC_IF1R3_Idle ; start timout cntr
*
lda #%10100000 ; Tx DATA1 PID, I/F for EP1,
ora #K_IRpt0_Size ; update report size(keyboard),
sta V_EP1_UCR1 ; enable Tx
clr VP_KCode ; reset ptr to Q_NKey
*
; bsr EP1_IN_TRANSACT ; send 1st blank kbd report
*
; bclr b_NIRpt0,V_Dev_Status
; clr V_HK_Status
*
* ------------------------------------------------------------------------
EP1N2I_EXIT:
rts
* --------------------------------------------------------------------- *
* EP1_IN_TRANSACT - prepare for next IN Interrupt Transact at Epnt 1 *
* 1) copy Keyboard Report to Epnt 1 Tx Queue, and *
* 2) prepare Epnt 1 to Tx data(clr TXD1F flag) *
* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . *
* In : QC_IN0_Rpt[0..7] buffer queue for Keyboard Report *
* Out : UD1R0-7 copy QC_IN0_Rpt[0..7] *
* b_TXD1F -0 init. next Epnt Tx *
* Call : <nil> *
* --------------------------------------------------------------------- *
EP1_IN_TRANSACT:
*
* --- Copy QC_IN0_Rpt[0..7] to UD1R[0..7] ---------------------------------
ldx #K_IRpt0_Size
E1IT_AGN:
lda {QC_IN0_Rpt-1},x
sta {UE1D0-1},x
dbnzx E1IT_AGN
*
* --- Prepare Epnt 1 to Tx Data ------------------------------------------
lda V_EP1_UCR1
eor #{1<b_T1SEQ} ; toggle Tx PID
sta V_EP1_UCR1
sta UCR1
*
bset b_TXD1FR,UIR2 ; clr TXD1F flag
mov #K_EP12_T_Out,VC_EP_T_Out ; set time out counter
*
* ------------------------------------------------------------------------
E1IT_EXIT:
rts
* [Embedded Device] --------------------------------------------------- *
* EP2_IN_TRANSACT - prepare for next IN Interrupt Transact at Epnt 2 *
* 1) copy Keyboard Report to Epnt 2 Tx Queue, and *
* 2) prepare Epnt 2 to Tx data(clr TXD1F flag) *
* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . *
* In : ACPI_KEY[0..2] The ACPI report packet *
* Out : UD1R0-3 copy QC_IN0_Rpt[0..3] *
* b_TXD2F =0 init. next Epnt Tx *
* Call : <nil> *
* --------------------------------------------------------------------- *
EP2_IN_TRANSACT:
*
* --- Copy Hot_KEY[0..2] to UD2R[0..7] ---------------------------------
*
ldx #K_H_Rpt_Size
lda V_IF1_Rpt_ID
sta UE2D0
cbeqa #K_ACPI_Rpt_ID,E2ACPI_IT_AGN ; ACPI report ?
cbeqa #K_MMK_Rpt_ID,E2Hot_IT_AGN ; Hot Key report ?
bra E2IT_Exit ; Wrong ID ?
E2ACPI_IT_AGN:
mov V_ACPI_Key,{UE2D1}
ldx #K_ACPI_Rpt_Size
bra Send_EP2_IN
E2Hot_IT_Agn:
lda {V_Hot_Key1-1},x
sta UE2D0,x
dbnzx E2Hot_IT_Agn
ldx #K_MMK_Rpt_Size
Send_EP2_IN:
lda V_EP2_UCR2
eor #{1<b_T2SEQ} ; toggle Tx PID
stx V_Temp_Reg
and #%11110000 ; set transmit size to 0
ora V_Temp_Reg ; get transmit size
sta V_EP2_UCR2
sta UCR2
*
bset b_TXD2FR,UIR2 ; clr TXD2F flag
mov #K_EP12_T_OUT,VC_EP_T_OUT ; Set the time out counter
*
* ------------------------------------------------------------------------
E2IT_EXIT:
rts
* [Embedded Device] --------------------------------------------------- *
* UPDATE_LED - update LEDs status from New OUT report *
* In : VS_LED LED Status of I/F #0(in OUT report) *
* : VS_LED2 LED Status of I/F #1(in OUT report) *
* Out : PTC[2:4] update LED Status to LED o/p at port C *
* Call : <nil> *
* --------------------------------------------------------------------- *
UPDATE_LED:
mov #%11111111,V_LED_PTD
brclr b_RptNum,VS_LED,UNumOff
bclr b_LNum,V_LED_PTD
UNumOff: brclr b_RptCap,VS_LED,UCapOff
bclr b_LCap,V_LED_PTD
UCapOff: brclr b_RptScrl,VS_LED,UScrlOff
bclr b_LScrl,V_LED_PTD
UScrlOff:
mov V_LED_PTD,PTD
; sta PTD ; update LED's
*
* ------------------------------------------------------------------------
UPLED_EXIT:
rts
* --------------------------------------------------------------------- *
* REF_TCH0 - Refresh TIM Ch0 O/P Compare Counter for next OCMP IRQ *
* (i.e. TCNTH:TCNTL + K_Nch0 -> TCH0H:TCH0L) *
* In : TCNTH:TCNTL TIM Counter Reg. *
* K_Nch0 timer counts for TIM ch0 OCMP period *
* Out : TCH0H:TCH0L TIM Ch0 Reg. *
* Call : <nil> *
* Note :- TCNTH reg. should be read before TCNTL reg. *
* - TCH0H reg. should be written before TCH0L reg. *
* --------------------------------------------------------------------- *
REF_TCH0:
; lda TCNTH
; psha ; must load high byte before
; lda TCNTL ; low byte
ldhx TCNTH ; [4]
pshh ; [2]
clrh ; [1]
txa ; [1]
add #{K_Nch0 % 256} ; [2]
tax ; [1]
*
pula ; [1]
adc #{K_Nch0 / 256} ; [2]
sta TCH0H ; [2]
*
stx TCH0L ; [2]
bclr b_CH0F,TSC0 ; [4] clear CH0F
*
* ------------------------------------------------------------------------
RTCH0_EXIT:
rts ; [4]
.PAGE
* ------ Interrupt Service Routines --------------------------------------
* --------------------------------------------------------------------- *
* TCH0_ISR - TIM Ch0 Output Compare ISR *
* In : b_CH0F -1 CH0F interrupt *
* Out : b_Tsus -1 USB I/F suspend timeout(3ms) *
* Call : REF_TCH0 *
* --------------------------------------------------------------------- *
TCH0_ISR:
brclr b_CH0F,TSC0,TCH0I_EXIT ; ~CH0F interrupt ?
*
*
* --- Signal Suspend Timeout ---------------------------------------------
*
bclr b_CH0F,TSC0 ; clear CH0F
*
bset b_Tsus,VS_TIMER ; signal suspend timeout
*
* ------------------------------------------------------------------------
TCH0I_EXIT:
rti
* --------------------------------------------------------------------- *
* TCH1_ISR - TIM Ch1 Output Compare ISR *
* In : b_CH1F -1 CH1F interrupt *
* Out : b_T4MS -1 4ms time tick *
* b_Nkbd -1 new kbd. report available *
* Call : REF_TCH1 *
* --------------------------------------------------------------------- *
TCH1_ISR:
brclr b_CH1F,TSC1,TCH1I_EXIT ; ~CH1F interrupt ?
*
bclr b_CH1F,TSC1 ; clear CH1F
cli
jsr REF_TCH1 ; refresh TIM Ch1 Reg.
*
*
bset b_T4ms,VS_TIMER ; set 4ms time tick flag
*
*
* --- 40ms Time Tick -----------------------------------------------------
TISR_40MS:
dec VC_40ms ; dec. every 4ms
bne TIEND_40MS
MOV #KC_40ms,VC_40ms ; re-init timeout counter
bset b_T40ms,VS_TIMER ; set 40ms time tick flag
TIEND_40MS:
brset b_PS2Sys,V_USBPS2,TCH1I_EXIT ; jmp if PS2 system
*
*
* --- Timeout Keyboard Report Idle Period --------------------------------
TISR_KIDLE:
ldx V_IF0_Idle
beq TIEND_KIDLE ; infinity Idle Rate ?
*
dec VC_IF0_Idle
bne TIEND_KIDLE ; ~Kbd. Idle Period Timeout ?
*
stx VC_IF0_Idle ; reload counter
*
bset b_NIRpt0,V_Dev_Status
TIEND_KIDLE:
jsr Update_LED
*
TISR_IF1_Idle:
ldx V_IF1R1_Idle ; check if idle forever
beq SKIP_RP1_IDLE
*
dec VC_IF1R1_Idle ; decrease counter
bne SKIP_RP1_IDLE
*
stx VC_IF1R1_Idle ; reload counter
*
bset b_ACPI_NRpt,V_HK_Status ; force new ACPI report
Skip_Rp1_Idle:
ldx V_IF1R2_Idle ; check if idle forever?
beq SKIP_RP2_IDLE
dec VC_IF1R2_Idle ; decrease counter
bne SKIP_RP2_IDLE
stx VC_IF1R3_Idle ; reload counter
bset b_Vol_NRpt,V_HK_Status ; Force new report of ID #2
; ...................................................................
SKIP_RP2_IDLE:
ldx V_IF1R3_Idle ; check if idle forever?
beq SKIP_RP3_IDLE
dec VC_IF1R3_Idle ; decrease counter
bne SKIP_RP3_IDLE
stx VC_IF1R3_Idle ; reload counter
bset b_HK_NRpt,V_HK_Status ; Force new report of ID #3
SKIP_RP3_IDLE:
* ------------------------------------------------------------------------
*
Check_Time_Out:
* ------------------------------------------------------------------------
; ldx VC_EP_T_OUT ; Check if EP1&2 time out
; beq SKIP_EP12_TOUT
; dec VC_EP_T_OUT ; decrease counter
SKIP_EP12_TOUT:
* ------------------------------------------------------------------------
TCH1I_EXIT:
rti
* --------------------------------------------------------------------- *
* IRQ_ISR - handle IRQ# interrupt *
* In : <nil> *
* Out : <nil> *
* Call : <nil> *
* --------------------------------------------------------------------- *
IRQ_ISR:
bset b_ACK1,ISCR ; reset IRQF
bset b_IMASK1,ISCR ; disable IRQ# interrupt
*
* ------------------------------------------------------------------------
rti
* --------------------------------------------------------------------- *
* KBD_ISR - Keyboard Interrupt Service Routine *
* In : <nil> *
* Out : <nil> *
* Call : <nil> *
* --------------------------------------------------------------------- *
KBD_ISR:
nop
bset b_ACKK,KBSCR ; clear the keybaord int. flag
*
* ------------------------------------------------------------------------
rti
*
* --------------------------------------------------------------------- *
* DMY_ISR - dummy Interrupt Service Routine(with no operation) *
* In : <nil> *
* Out : <nil> *
* Call : <nil> *
* --------------------------------------------------------------------- *
DMY_ISR:
nop
* ------------------------------------------------------------------------
rti
.PAGE
* ------ Include Files(in EPROM Map) -------------------------------------
$INCLUDE "usb-scan.asm" ; Keyboard Scan Handler Routines
$INCLUDE "usb-key.asm" ; map key location to USB key #
$INCLUDE "jb8-int.asm" ; USB Interrupt Service Routines
$INCLUDE "hid-kbd.asm" ; USB Device Framework Routines
$INCLUDE "usb-kbd.h" ; HID Class(keyboard) Descriptors
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -