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

📄 kbusb.asm

📁 用cy7c66113开发的HUB
💻 ASM
字号:
;========================================================================
;   FILE: usbkey.asm
;
;   This file contains the code that implements the usb-specific
;   routines to handle key scans.
;========================================================================

USB_NO_REPORT:      equ 0
USB_REPORT_ERROR:   equ 1
USB_REPORT_KEY:     equ 2

;========================================================================
; Send keyboard report to host
;========================================================================
;========================================================================
; Send keyboard report to host
;========================================================================
Send_Keyboard_Report:
    mov     A,[usb_tx_required]
	cmp		A,0								; if nothing to report 
    jz		.idle							; check idle status
    
    cmp		A,USB_REPORT_ERROR				; else if we've got to send an error report
    jnz		.send

    cmp		A,[last_key_report]				; and the last one sent was not an error
    jnz		.send							; we can send this one too

.idle:										; else check idle status 
	mov		A, [kbd_idle_period_ctr]		; if idle_period is zero, then we only send
	cmp		A, 0							; reports on change
	jz		.exit							; exit task

    dec     A
    mov     [kbd_idle_period_ctr],A			; decrement idle period

    jnz     .exit							; and exit if idle period not expired
      
    mov      A,[last_key_report]			; otherwize get type of last report


.send:										;ok, we're REALLY  going to send a new report
 	push	A

	iord	EP_A1_Mode						; are we currently transmitting a report?
	and		A, USB_MODE_MASK
	cmp		A, ACKIN
    pop		A								; pop current request into A
	jz		.out           					; yes, then exit (so we don't mess up
											; the current transmission)
											; 
    mov		[last_key_report],A
    mov     A,0
    mov     [usb_tx_required],A
	call	Copy_report_buffer_to_EP1		; copy report buffer to EP1 FIFO
	call	Enable_EP1_Transmission			; enable EP1 transmission
.out: 
    mov		A,[kbd_idle_period]
    mov		[kbd_idle_period_ctr],A			;reset idle period
.exit:
	ret



;========================================================================
; Copy report_buffer contents to EP1 FIFO
;========================================================================
Copy_report_buffer_to_EP1:
	push	A						        ; save registers on stack
	push	X
	mov		X, 7                            ;count 8 of the darn things
copy_report_buffer_loop:
    mov      A,[last_key_report]             
    cmp      A,USB_REPORT_ERROR
    jz      .error
 	mov		A, [X + usb_report_buffer]      ;assume we're sending a key stroke
    jmp      .next 
.error:                          
    mov     A,X
    index   key_error_buffer                ;else get error code byte
.next:
	mov		[X + KBBuffer], A             ;put it into ep0 fifo
	dec		X
	jnc		copy_report_buffer_loop         ;do next one

	pop		X						        ; restore registers from stack
	pop		A

	ret

XPAGEOFF	
key_error_buffer:
    db      00,00,01,01,01,01,01,01
XPAGEON	

;========================================================================
; Enable transmission from EP1 FIFO
;========================================================================
Enable_EP1_Transmission:
	push	A								; save accumulator on stack
	iord	EP_A1_Counter              
      and	A, DATATOGGLE					; keep data toggle setting
	or		A, 8h                           ; packet size
	iowr	EP_A1_Counter

	mov		A, ACKIN						; enable packet transmission 
	iowr	EP_A1_Mode

	pop		A                               ; restore accumulator
	ret										; return
	
;========================================================================
; FUNCTION:usb_scan_keys
;
;   This is the main entry point for the start of key scanning.
;   This function calls the key scanner, which will generate calls to
;   usbkey_putkey from the internal scanning loop of the key scanner.
;
;
;
;========================================================================
usbkey_scan_keys:
    call    ksc_scan_keys                           ; scan the keys
    jc      .send_error                             ; phantom situation,send error to host
    
	mov     A, [usb_key_count]                      ; are there more than 6 keys pressed?
	cmp     A, 7
	jnc    .send_error                              ; yes, then send error to host
	
    mov     A,0                                     ; no errors, clear the error byte
    mov     [usb_current_state],A                   ; and return
    jmp     .exit
                                                    
.send_error:                                     
    mov     A,USB_REPORT_ERROR                      ; there's currently an error,
    mov     [usb_tx_required],A
    mov     [usb_current_state],A                   ; mark as such
.exit:
    ret


;========================================================================
; FUNCTION:usbkey_putkey 
;
;handles key presses in usb environment.
;
; This function is called from within the key scanning loop, each time a
; valid key event has been recognized.  A key event is defined as whenever 
; an individual key changes state, either up or down.  the key is 
; identified by a unique number in the accumulator  from 1 to XXX, 
; where XXX is GENERALLY the corresponding AT101 keyboard number, with
; few execptions (see at101.inc).
;========================================================================


usbkey_putkey:
;   call    usb_power_key
;   jc     .done_putkey
    
    call    ksc_modifier                           ;check for a modifier
    jnc      .non_modifiers
    
 	mov		A, USB_REPORT_KEY                      ; show that a report is required
	mov		[usb_tx_required], A
    mov     A,[ksc_mod0]
    mov     [usb_last_mod],A
    jmp     .done_putkey

.non_modifiers:
    index   usb_usage_table
	push	X                                       ; save X on stack
	push	A                                       ; save key code on stack

	mov		A, USB_REPORT_KEY                       ; show that a report is required
	mov		[usb_tx_required], A

	mov		A, [ksc_down_up]
	cmp		A, 0
	jnz		.add_key_to_buffer				        ; key down
													; otherwise, key is up


.remove_key_from_buffer:                            ; key is up, so remove if from buffer
	mov		A, [usb_key_count]
	cmp		A, 0                                    ; decrement key count (unless it's 0)
	jz		.skip_decrement_key_count
	dec		[usb_key_count]
.skip_decrement_key_count:
	mov		X, 2
.find_key_in_buffer:                                ; find the key in the report buffer
	pop		A
	push	A
	cmp		A, [X + usb_report_buffer]
	jz		.clear_buffer_position
	inc		X
	mov		A, X
	cmp		A, 8
	jc		.find_key_in_buffer
	pop		A
	jmp		.non_modifiers_done                     ; done search

.clear_buffer_position:                             ; key found in buffer, so clear position
	pop		A
	mov		A, 0
	mov		[X + usb_report_buffer], A
	jmp		.non_modifiers_done

	
.add_key_to_buffer:                                 ; key went down, so put it in the buffer
	mov		A, [usb_key_count]
	cmp		A, FFh                                  ; increment key count (unless it's 255)
	jz		.skip_increment_key_count
	inc		[usb_key_count]
.skip_increment_key_count:
	mov		X, 2
.find_free_buffer_position:                         ; find a free buffer position
	mov		A, 0
	cmp		A, [X + usb_report_buffer]
	jz .put_key_in_buffer_position
	inc		X
	mov		A, X
	cmp		A, 8
	jc		.find_free_buffer_position
	pop		A
	jmp		.non_modifiers_done                     ; could not find a free position
						                            ; more than 6 keys pressed

.put_key_in_buffer_position:                        ; found a free buffer position, so put key code there
	pop		A
	mov		[X + usb_report_buffer], A

.non_modifiers_done:
	pop		X  

.done_putkey:
    ret  


;    XPAGEOFF
;power_key_table:
;    db      AT101KB_POWER,AT101KB_SLEEP,AT101KB_WAKE
;power_bit_table:
;    db      1,2,4
;
;    XPAGEON

NUM_POWER_KEYS: equ 3

;========================================================================
; FUNCTION:usb_power_key 
;
;handles power, sleep, and wake key presses in usb environment.
;
; This function was invented to trap the power, sleep, and wake key presses
; and maintain a single byte whose format is as follows:
;
; bit 1:  1 = power key pressed
; bit 2:  1 = sleep key pressed
; bit 3   1 = wake key pressed
;
; if any of these three keys changes state, the corresponding bit in the
; bit field is modified and the usb_power_flag is set to indicate that the
; state of the power keys has changed.
;========================================================================


;usb_power_key:
;
;    push	X
;    push    A
;	
;    mov		X,usb_power_keys
;
;.lp0:
;    mov     [ksc_work],A                            ;store key in work byte
;    mov     A,(NUM_POWER_KEYS - 1)                   ;initialize A to number of power keys
;.lp1:
;    push    A                                       ;save index
;    index   power_key_table                           ;get lookup
;    cmp     A,[ksc_work]                            ;compare to key
;    pop     A                                       ;restore index
;    jz      .lp2                                    ;compare was a success, key found
;    dec      A          
;    jc      .non_modifier                           ;index < 0, non-power key
;    jmp     .lp1
;
;.lp2:
;    index   power_bit_table                           ;now index into bit to set/clear
;	push	A										; clear or set bit
;	mov		A, [ksc_down_up]                      ; depending on if key went
;	cmp		A, 00h                                  ; up or down
;	pop		A                                       ; restore bit pattern
;	jz		.mod0_up                                ; key went down
;	or		[X + 0], A                              ; set bit
;	jmp		.done_putkey
;.mod0_up:									        ; else, key went up
;	cpl                                             ; so clear bit
;	and		[X + 0], A       
;.done_putkey:                                       ;set carry indicating key found
;    mov     A,0ffh
;    mov     [usb_power_flag],A
;    SETC    
;.exit:
;    pop     A                                       ;restore A,X
;	pop		X
;	ret
;
;.non_modifier:                                      ;clear carry indicating no key found
;    CLEARC                  
;    jmp     .exit
;
    

;usb_init_keyscan:
;;   CLEARRAM    usbkey_ram_base,USBKEY_RAM_SIZE
;    mov A,POWER_REPORT_ID
;    mov [usb_power_id],A
;    ret

    XPAGEOFF

usb_usage_table:
	db			000h,035h,01eh,01fh,020h,021h,022h,023h	;0-7
	db			024h,025h,026h,027h,02dh,02eh,000h,02ah	;8-15
	db			02bh,014h,01ah,008h,015h,017h,01ch,018h	;16-23
	db			00ch,012h,013h,2fh,030h,031h,039h,004h	;24-31
	db			016h,007h,009h,00ah,00bh,00dh,00eh,00fh ;32-39
	db			033h,034h,032h,028h,0e1h,064h,01dh,01bh	;40-47
	db			006h,019h,005h,011h,010h,036h,037h,038h	;48-55
	db			000h,0e5h,0e0h,000h,0e2h,02ch,0e6h,000h	;56-63
	db			0e4h,000h,000h,000h,000h,000h,000h,000h ;64-71
	db			000h,000h,000h,049h,04ch,000h,000h,050h ;72-79
	db			04ah,04dh,000h,052h,051h,04bh,04eh,000h	;80-87
	db			000h,04fh,053h,05fh,05ch,059h,000h,054h	;88-95
	db			060h,05dh,05ah,062h,055h,061h,05eh,05bh	;96-103
	db			063h,056h,057h,000h,058h,000h,029h,000h	;104-111
	db			03ah,03bh,03ch,03dh,03eh,03fh,040h,041h	;112-119
	db			042h,043h,044h,045h,046h,047h,048h,0e3h	;120-127
	db			0e7h,065h,066h,067h,068h,000h,000h,000h	;128-235

    XPAGEON

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -