?? ps2main.asm
字號:
call ps2_wait_byte ;get rate/delay byte
cmp A,0EDh ;is it another command?
jnc ps2_start_command ;yes, go process it
cmp A,80h ;if out of range
jc .l0
call ps2_invalid_command ;tell the host and
jmp .strd0 ;wait for another try
.l0:
push A
push A
rrc ;otherwise, get bits 5 and 6
rrc
rrc
rrc
rrc
and A,3
index ps2_typematic_delay_table ;get delay
mov [ps2key_type_delay],A ;save it
pop A ;get original parameter
and A,1fh ;use only 5 ls bits
index ps2_typematic_rate_table ;get rate
mov [ps2key_type_period],A ;save it
call ps2_ack_byte ;ack byte
pop A
call check_device_id ;check for id
jmp endswitch
;========================================================================
; FUNCTION: check_device_id
;
; Checks for the presence of the sequence of commands:
; F3 7C F3 00 F3 01
;
;========================================================================
XPAGEOFF
SEND_ID: equ 4
id_table: db 01h,00h,07ch
end_id_table:
kbd1_tbl: db 041h,0e1h,010h,0e1h
end_kbd1_table:
kbd2_tbl: db 042h,0e1h,010h,0e1h
XPAGEON
ID_TABLE_LEN: EQU (end_id_table - id_table)
KBD_TABLE_LEN: EQU (end_kbd1_table - kbd1_tbl)
check_device_id:
push A ;save A and X
push X ;
mov [ps2_temp1],A ;save typematic parameter
cmp A,07ch ;if == first in sequence,
mov A,ID_TABLE_LEN-2
jz .exit ; get out with proper state set
mov A,[ps2_id_state] ;get current state of id
index id_table ;retrieve byte we are expecting
cmp A,[ps2_temp1] ;compare it with one we got
mov A,ID_TABLE_LEN-1
jnz .exit ;if it compares,
mov A,[ps2_id_state]
dec A
jnc .exit
mov a,[ps2key_key_count] ;see if theres room for 4 bytes
;in key buffer
cmp a,BUFFER_LEN-4
jc .xmt
call put_error ;no, put error code instead
jmp .exit1 ;and quit
.xmt: ;else yes,
mov X,KBD_TABLE_LEN-1 ;prepare to send id bytes
.loop:
mov A,[dual_ifc_option] ;depending upon the keyboard
and A,KEYBOARD_ID_BIT
mov A,X
jz .kbd1
.kbd2:
index kbd2_tbl ;send kbd #2 id
jmp .send
.kbd1:
index kbd1_tbl ;or send kbd #1 id
.send:
call putch ;put it into the key queue
dec X ;decrement ptr
jnc .loop
.exit1:
mov A,ID_TABLE_LEN-1
.exit:
mov [ps2_id_state],A ;update id state
pop X
pop A
ret
;========================================================================
; FUNCTION: ps2_enable
;
;
; enables keyboard scanning
;
;
;========================================================================
ps2_enable:
SETBIT PS2_SCAN_KBD,ps2_flags ;enable scanning
call ps2_ack_byte ;ack the byte
jmp endswitch
;========================================================================
; FUNCTION: ps2_default_disable
;
;
; disables keyboard scanning
;
;
;========================================================================
ps2_default_disable:
;
; CLRBIT PS2_SCAN_KBD,ps2_flags ;disable scanning
ps2_set_default:
call ps2key_set_default_key_types
call ps2_ack_byte ;ack the byte
jmp endswitch
IFDEF SCANSET3
;========================================================================
; FUNCTION: ps2_set_keys
;
;
; sets all the key types to a common type
;
; Returns:
;
; C: 0 command can't fail
;
;
;========================================================================
ps2_set_keys:
mov A,X ;the X register contains the zero-based
;command.
sub A,(0f7h-0edh) ;derive key type (0,1,or2) from this
push A ;save it
mov A,AT101KB_PAUSE ;fetch current pause key setting
call ps2key_at101_2_ss3 ;get scan set 3 code for it
call ps2key_get_key_type ;it's returned in X
pop A ;restore key type into A
push X ;save pause key setting
call ps2key_set_all_keys ;set all key types now
mov A,AT101KB_PAUSE ;get scan code for pause key
call ps2key_at101_2_ss3 ;get scan set 3 code for it
; pop X ;restore setting for pause key into X
call ps2key_save_key_type ;and set it
call ps2_ack_byte ;ack the byte
jmp endswitch
ENDIF
;========================================================================
; FUNCTION: ps2_resend
;
;
; sets resend bit
;
; Returns:
; C: 0
;
;========================================================================
ps2_resend:
mov A,[ps2_last_xmit] ;get last byte sent
call ps2_put_byte ;queue it for retransmission
jmp endswitch
;========================================================================
; FUNCTION: ps2_reset
;
;
; performs a reset
;
; Returns: C= 0 if command aborted due to host transmit request
;
;========================================================================
ps2_reset:
call ps2_ack_byte ;queue an ACK
.rloop: ;loop until the ack is successfully transmitted or the host aborts
iowr WATCHDOG_REG
iord PS2_PORT
and A,PS2_DATA_BIT ;check data line
jz .exit ;if host xmit request, abort Reset
TSTBIT PS2_XMIT,ps2_flags ;ACK still pending?
jz .r2 ;if not, we're done
call ps2_send_byte
jmp .rloop
.r2:
CLRBIT PS2_RESET_FLAG,ck_flags
; jmp Start ;soft restart
.exit:
jmp endswitch
IFDEF SCANSET3
;========================================================================
; FUNCTION: ps2_set_key_type
;
;
; sets individual key types to the values indicated
;
;
;========================================================================
ps2_set_key_type:
mov A,X ;zero-based command is in X, get it in A
sub A,(0fbh - 0edH) ;derive key type (0,1,2,or3)
push A ;save it
call ps2_ack_byte ;ack the byte
.l1:
call ps2_wait_byte ;wait for keycode
cmp A,LAST_SCAN3_CODE+1 ;if valid
jnc .error
or A,0
jz .error
pop X ;get key type
push X ;save it again
call ps2key_save_key_type ;set it
call ps2_ack_byte ;ack the byte
jmp .l1 ;continue doing this until we can't recognize
;a scan code
.error:
pop X ;restore stack level,return with offending
;byte in A
jmp endswitch
ENDIF
;========================================================================
; FUNCTION: ps2_ack_byte
;
;
; Sends an ACK byte
;
;
;========================================================================
ps2_ack_byte:
mov A,PS2_ACK
call ps2_put_byte
ret
;========================================================================
; FUNCTION: ps2_BAT
;
; Performs BAT assurance test. For now, this test does nothing
; but delay for 350 msec before returning.
;
;
; Returns:
;
; C: 0
; A: BAT_PASS
;
;
;
;========================================================================
ps2_BAT:
;upon entry to this routine, ps2_delay contains the count, in 2msec increments,
;of time we should spend in the BAT routine.
mov A,[ps2_delay] ;get time remaining for BAT test (2msec per bit)
cmp A,0 ;if time has expired
jz .exit ;bag it now
;leds on
mov A,(CAPS_LOCK_LED + SCROLL_LOCK_LED + NUM_LOCK_LED)
call ksc_writeLED
mov A,[dual_ifc_1ms] ;get 1msec counter
add A,[ps2_delay] ;advance it by the amount in ps2_delay
.l1:
iowr WATCHDOG_REG
cmp A,[dual_ifc_1ms] ;consume time
jnz .l1
add A,[ps2_delay] ;half the required time has expired, so re-init
.l2: ; and consume time again
iowr WATCHDOG_REG
cmp A,[dual_ifc_1ms]
jnz .l2
mov A,0
call ksc_writeLED
.exit:
mov A,BAT_PASS
ret
;========================================================================
; FUNCTION: ps2_put_byte
; Queue a new byte for transmission
;
;========================================================================
ps2_put_byte:
push X ;save X
mov X,A ;save the byte to X
mov A,ps2_xmt_buf ;A = buffer base
add A,[ps2_xmt_in] ;add index
swap A,X ;x = ram pointer, a = data
mov [X+0],a ;save new byte
inc [ps2_xmt_in] ;increment index
SETBIT PS2_XMIT,ps2_flags ;set bit to indicate transmission necessary
pop X ;pop X register
ret
;========================================================================
; FUNCTION: ps2_send_byte
; Try to transmit the next byte in the xmt queue.
;
;========================================================================
ps2_send_byte:
push A ;save A
TSTBIT PS2_XMIT,ps2_flags ;anything to send?
jz .exit ;if not, exit
mov A,[ps2_xmt_out] ;A = out pointer
add a,ps2_xmt_buf ;add buffer base
push X ;save X
mov X,A ;X --> buffer
mov A,[X+0] ;A <-- data byte
pop X ;done with X
IFDEF CombiKB
DI
ENDIF
call ps2_send ;try to send one
IFDEF CombiKB
EI
ENDIF
jc .exit ;return if unsuccessful
cmp A,PS2_RSND
jz .sb0 ;don't save it if it was a Resend
mov [ps2_last_xmit],A ;else, save last transmitted byte
.sb0: inc [ps2_xmt_out] ;increment pointer
mov A,[ps2_xmt_out] ;get it in A
cmp A,[ps2_xmt_in] ;buffer empty?
jnz .sb1 ;if not, continue
call ps2_xmt_flush ;else, reinit pointers
jmp .sb1 ;be done
.sb1: mov A,PS2_SEND_INTERVAL
mov [ps2_send_timeout],A ;reset the timeout counter
.exit:
pop A ;restore A
ret
;========================================================================
; FUNCTION: ps2_xmt_flush
; Flush ps2 transmit queue
;
;========================================================================
ps2_xmt_flush:
push A ;save A
mov A,0
mov [ps2_xmt_in],A ;init pointers
mov [ps2_xmt_out],A
CLRBIT PS2_XMIT,ps2_flags ;init transmit pending flag
pop A ;restore A
ret ;that's it
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -