📄 kb_mouse.asm
字号:
;*****
;*****
; Transmit - State T2 - Start bit
; The mouse has clocked our start bit. Drive data bit 0; Transition to T3.
;*****
ps2_ST_T2:
SETFLAG ps2_parity_flagC ;seed parity with 1 (odd parity)
jmp ps2_ST_tdata ;branch to data-bit handling
;*****
; Transmit - States T3 ~ T9 - Data bits 0 ~ 6
; Drive next data bit as mouse clocks each one. Keep track of parity. Increment
; state variable. State T2 branches to this data-bit handling code, as well.
;*****
ps2_ST_tdata:
mov a,[mouse_dataV] ;a <- transmit data byte
rrc ;shift data bit 0 into C
mov [mouse_dataV],a ;save shifted data byte
jnc ST_td0 ;branch if data bit=0
;* data bit = 1
CPLFLAG ps2_parity_flagC ;Toggle parity
mov a,ps2_Data1C ;set up to drive a '1'
jmp ps2_data_state ;drive data and increment state
;* data bit = 0
ST_td0:
mov a,ps2_Data0C ;set up to drive a '0'
jmp ps2_data_state ;drive data and increment to next state
;*****
; Transmit - State T10 - Data bit 7
; The mouse has clocked in data bit 7. Drive parity. Transition to T11.
;*****
ps2_ST_T10:
CHKFLAG ps2_parity_flagC ;check parity
jz ST_t10a ;branch if 0
mov a,ps2_Data1C ;parity = 1
jmp ps2_data_state ;drive parity = 1 and increment state
ST_t10a:
mov a,ps2_Data0C ;parity = 0
jmp ps2_data_state ;drive parity and increment state
;*****
; Transmit - State 11 - Parity
; The mouse has clocked our parity bit. Drive the stop bit. Transition to T12
;*****
ps2_ST_T11:
mov a,ps2_Data1C ;stop bit is a '1'
jmp ps2_data_state ;drive data and increment state
;*****
; Transmit - State 12 - Stop bit
; The mouse has clocked our stop bit. Check for mouse-driven line control (data=0).
; Wait for clock high. Transition to Idle.
;
; If Line Control fails, transmission fails.
;*****
ps2_ST_T12:
iord IO_mouse_port ;read mouse port
and a,ps2_dataC ;isolate data bit
jz st_T12a ;branch if line control asserted
SETFLAG ps2_tfail_flagC ;else, assert transmit fail flag
SETFLAG ps2_tx_flagC ;clear active flag
jmp st_T12b
st_T12a:
iord IO_mouse_port ;read mouse port
and a,ps2_clkC ;isolate clock bit
jz st_T12a ;wait for mouse to release clock
;* This transmission is complete
st_T12b:
SETFLAG ps2_tx_flagC ;clear active flag
call ps2_bus_inhibit ;go to inhibit 'til mouse_machine sees what we did
jmp ps2_end_state
;********** End of Transmit Sequence
;********** Receive Sequence
; The receiver is activated when the mouse drives a start bit, and drives
; the clock low on an idle bus. The receive sequence clocks in eight data bits,
; parity and a stop bit on sequential falling edges of the mouse's clock. The
; resultant receive data byte is held in "mouse_dataV", and is flagged by
; mouse_rcv_flagC in the flags byte. The bus is then inhibited until the application
; has an opportunity to deal with the new byte.
;
; If an error occurs during reception, the bus is placed in inhibit, and the error
; is flagged by ps2_rfail_flagC.
;
; In either event, function "ps2_bus_idle" must be called to release the bus.
;**********
;*****
; Receive - State R0 - Idle
; This code is entered when the mouse drives the clock line low from an idle bus
; state, assumedly issuing the start bit of a new transmission.
;
; If PS/2 data = 0, ==> state R1 (Rcv data bits)
; If PS/2 data = 1, ==> Error
;*****
ps2_ST_Idle:
iord IO_mouse_port ;read mouse port
and a,ps2_dataC ;isolate data bit
jnz prerr ;error if no start bit
mov a,ps2_timeoutC ;init timeout counter
mov [mouse_mScntV],a
CLRFLAG ps2_parity_flagC ;init parity flag
mov a,ps2_ST_rdC ;jump into recv state machine
mov [ps2_stateV],a
jmp ps2_end_state
;*****
; Receive - States R1~R8 - Data bits 0 ~ 7
; This code is entered for each received data bit.
;
;*****
ps2_ST_rdata:
iord IO_mouse_port ;read mouse port
and a,ps2_dataC ;isolate data bit (AND clears C-bit)
jz prd0 ;branch if data = 0
;* new data bit is a '1'
CPLFLAG ps2_parity_flagC ;toggle parity
SETC
prd0: mov a,[mouse_dataV] ;get data byte under construction
rrc ;shift in new data bit
mov [mouse_dataV],a ;save data byte
jmp ps2_next_state ;to next state
;*****
; Receive - State R9 - Parity
; The mouse is driving parity.
;
;*****
ps2_ST_R9:
iord IO_mouse_port ;read mouse port
and a,ps2_dataC ;isolate parity bit
jz prp0 ;branch if 0
CPLFLAG ps2_parity_flagC ;else, toggle parity
prp0: CHKFLAG ps2_parity_flagC ;check parity
jz prerr ;parity should be odd
jmp ps2_next_state ;to next state
;*****
; Receive - State R10 - Stop bit
; The mouse is driving its stop bit.
;
;*****
ps2_ST_R10:
iord IO_mouse_port ;read mouse port
and a,ps2_dataC ;isolate data bit
jz prerr ;error if no stop bit
prsb0:
iord IO_mouse_port ;read mouse port
and a,ps2_clkC ;isolate clock bit
jz prsb0 ;wait for mouse to release clock
SETFLAG mouse_rcv_flagC ;flag received data
call ps2_bus_inhibit ;inhibit bus 'til mouse_machine gets the new byte
jmp ps2_end_state ;exit
;*****
; Receive - State R11 - Inhibited
; Mouse is held in inhibit after failed reception. State R11 may be
; entered as a result of the inhibit condition being driven. Inhibit will
; result at the end of any byte transmission or reception, successful or
; unsuccessful. The inhibit state allows time for mouse_machine to recognize
; byte-level state changes before proceeding to its next state.
;*****
ps2_ST_R11:
jmp ps2_end_state ;stay stuck in this state until ps2_bus_idle
;or ps2_xmit gets us out
;*****
; Receive Error - prerr
; Inhibit ps/2 bus and flag error
;*****
prerr:
call ps2_bus_inhibit
SETFLAG ps2_rfail_flagC ;set receive fail flag
jmp ps2_end_state ;leave
;*****
;***
;*** General purpose state completion code:
; ps2_data_state: loads new mouse port data from a, increments state and exits
; ps2_next_state: increments state and exits
; ps2_end_state: just exits
ps2_data_state:
; iowr IO_mouse_port ;drive mouse port with new data
PS2_WR_PORT3 ;macro that does port 3 writes
ps2_next_state:
inc [ps2_stateV] ;increment state
ps2_end_state:
mov a,ps2_timeoutC ;reset timeout count
mov [mouse_mScntV],a
pop a ;restore a
ret
;##
;##### END Module kb_mouse #####
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -