📄 access15-
字号:
;---------------------------------------------------------------------------------------------
; CLOCK/TIMING INFORMATION:
;-------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------
; HEADER:
;---------------------------------------------------------------------------------------------
TITLE "PS/2 Mouse Emulator"
SUBTITLE "Copyright 2001, Adam Chapweske"
LIST P=16F84
INCLUDE "p16f84.inc"
RADIX DEC
ERRORLEVEL -224, 1
__CONFIG _CP_OFF & _WDT_OFF & _RC_OSC
;---------------------------------------------------------------------------------------------
; The following may be assigned to any pin on PORTB. Weak pullups are enabled and inputs
; are active low.
;---------------------------------------------------------------------------------------------
#DEFINE DATA PORTB, 7
#DEFINE CLOCK PORTB, 6
#DEFINE PS2_Br PORTB, 5
#DEFINE PS2_Bl PORTB, 2
#DEFINE PS2_Yp PORTB, 3
#DEFINE PS2_Yn PORTB, 1
#DEFINE PS2_Xp PORTB, 4
#DEFINE PS2_Xn PORTB, 0
;---------------------------------------------------------------------------------------------
; The following may be assigned to any pin on PORTA. "ADJ1" is a 1k variable resistor that
; controls cursor speed. It is connected between PORTA<n> and Vcc. A 0.1 uF capacitor is
; connected between PORTA<n> and Gnd. "LED" is a status indicator LED connected between PORTA
; and Vcc.
;---------------------------------------------------------------------------------------------
#DEFINE ADJ1 PORTA, 2
#DEFINE LED PORTA, 1
;---------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------
#DEFINE MINPER 28 ;4.61MHz +/- 25% (160 reads/sec +/- 25%)
;#DEFINE MINPER 20 ;4.00MHz (200 reads/sec)
;---------------------------------------------------------------------------------------------
; RAM ALLOCATION:
;---------------------------------------------------------------------------------------------
cblock 0x0C
TEMP0, TEMP1
RECEIVE, PARITY, COUNTER ;Used in I/O routines
REPORT_RATE, RESOLUTION ;Used for responses to status requests
FLAGS, XY_FLAGS
SPEED_VAL
dBUTTONS ;"Previous button states" and "delta button states"
X_COUNTER
Y_COUNTER
endc
;---------------------------------------------------------------------------------------------
;FLAGS:
; bit 7 -- Always 0
; bit 6 -- Stream(0)/Remote(1) mode
; bit 5 -- Disable(0)/Enable(1) reporting
; bit 4 -- 1:1(0)/2:1(1) Scaling
; bit 3 -- Always 0
; bit 2 -- Always 0
; bit 1 -- Always 0
; bit 0 -- Always 0
MODE equ 6
ENABLE equ 5
SCALE equ 4
;---------------------------------------------------------------------------------------------
;XY_FLAGS:
; bit 7 -- Y Counter overflow
; bit 6 -- X Counter overflow
; bit 5 -- Y counter sign bit
; bit 4 -- X counter sign bit
; bit 3 -- Always 1
; bit 2 -- Always 0 (middle button)
; bit 1 -- Previous right button state
; bit 0 -- Previous left button state
yOVF equ 7
xOVF equ 6
ySIGN equ 5
xSIGN equ 4
;dBUTTONS
; bit 7 -- Always 0
; bit 6 -- Always 0
; bit 5 -- Always 0
; bit 4 -- Always 0
; bit 3 -- Always 0
; bit 2 -- Always 0
; bit 1 -- Change in right buton state
; bit 0 -- Change in left button state
;---------------------------------------------------------------------------------------------
cblock ;Contains to-be-sent packet and last packet sent
LENGTH
SEND1
SEND2
SEND3
endc
;---------------------------------------------------------------------------------------------
; MACROS:
;---------------------------------------------------------------------------------------------
;Delay "Cycles" instruction cycles
Delay macro Time
if (Time==1)
nop
exitm
endif
if (Time==2)
goto $ + 1
exitm
endif
if (Time==3)
nop
goto $ + 1
exitm
endif
if (Time==4)
goto $ + 1
goto $ + 1
exitm
endif
if (Time==5)
goto $ + 1
goto $ + 1
nop
exitm
endif
if (Time==6)
goto $ + 1
goto $ + 1
goto $ + 1
exitm
endif
if (Time==7)
goto $ + 1
goto $ + 1
goto $ + 1
nop
exitm
endif
if (Time%4==0)
movlw (Time-4)/4
call Delay_us
exitm
endif
if (Time%4==1)
movlw (Time-5)/4
call Delay_us
nop
exitm
endif
if (Time%4==2)
movlw (Time-6)/4
call Delay_us
goto $ + 1
exitm
endif
if (Time%4==3)
movlw (Time-7)/4
call Delay_us
goto $ + 1
nop
exitm
endif
endm
;---------------------------------------------------------------------------------------------
; ORG 0x000:
;---------------------------------------------------------------------------------------------
org 0x000
goto Start
;---------------------------------------------------------------------------------------------
; HANDLE COMMAND:
;---------------------------------------------------------------------------------------------
if (high Table1End != 0)
ERROR "Command handler table must be in low memory page"
endif
Command movlw 0x04
subwf RECEIVE, w
bnc SetResolution
movlw 0xC8
subwf RECEIVE, w
bnc SetReportRate
movlw 0xE6
subwf RECEIVE, w
bnc MainLoop
HandlerTable addwf PCL, f
goto Mouse_E6
goto Mouse_E7
goto MainLoop
goto Mouse_E9
goto Mouse_EA
goto Report
goto MainLoop
goto MainLoop
goto WrapMode
goto MainLoop
goto Mouse_F0
goto MainLoop
goto Mouse_F2
goto MainLoop
goto Mouse_F4
goto Mouse_F5
goto Mouse_F6
goto MainLoop
goto MainLoop
goto MainLoop
goto MainLoop
goto MainLoop
goto MainLoop
goto MainLoop
goto PacketOut
Table1End goto Reset
;---------------------------------------------------------------------------------------------
; START:
;---------------------------------------------------------------------------------------------
Start clrf PORTA
clrf PORTB
bsf STATUS, RP0
clrf TRISA
movlw 0x57
movwf OPTION_REG
bcf STATUS, RP0
movlw 0x08
movwf XY_FLAGS
clrf SPEED_VAL
; goto Reset
;---------------------------------------------------------------------------------------------
; Reset Mode:
;---------------------------------------------------------------------------------------------
Reset movlw 0xAA
movwf SEND1
call LoadDefaults
clrf SEND2
movlw 0x02
movwf LENGTH
call BATdelay
bsf LED
goto PacketOut
;---------------------------------------------------------------------------------------------
; Stream/Remote Mode:
;---------------------------------------------------------------------------------------------
MainLoop clrf X_COUNTER
clrf Y_COUNTER
MainLoop1 btfss DATA
goto PacketIn
movf SPEED_VAL, w
subwf TMR0, w
btfss STATUS, C
goto MainLoop1
clrf TMR0
call ReadADJ1
call ReadInputs
btfsc FLAGS, MODE
goto MainLoop1
btfss FLAGS, ENABLE
goto MainLoop1
movf X_COUNTER, w
iorwf Y_COUNTER, w
iorwf dBUTTONS, w
bz MainLoop1
; goto Report
;---------------------------------------------------------------------------------------------
; REPORT:
;---------------------------------------------------------------------------------------------
Report movf dBUTTONS, w
xorwf XY_FLAGS, f
movf XY_FLAGS, w
movwf SEND1
movf X_COUNTER, w
movwf SEND2
movf Y_COUNTER, w
movwf SEND3
movlw 0x03
movwf LENGTH
; goto PacketOut
;---------------------------------------------------------------------------------------------
; OUTPUT PACKET
;---------------------------------------------------------------------------------------------
PacketOut movlw SEND1
movwf FSR
movf LENGTH, w
movwf TEMP1
PacketOutLoop movf INDF, w
call ByteOut
xorlw 0xFF
bz PacketIn
xorlw 0xFE ^ 0xFF
bz PacketOut
incf FSR, f
decfsz TEMP1, f
goto PacketOutLoop
goto MainLoop
;---------------------------------------------------------------------------------------------
; READ PACKET
;---------------------------------------------------------------------------------------------
PacketIn call ByteIn
xorlw 0xFF
bz Mouse_ERR
xorlw 0xFE ^ 0xFF
bz MainLoop1
movlw 0xFE
xorwf RECEIVE, w
bz PacketOut
Acknowledge movlw 0xFA
call ByteOut
goto Command
;---------------------------------------------------------------------------------------------
; READ INPUTS:
;---------------------------------------------------------------------------------------------
ReadInputs swapf SPEED_VAL, w
movwf TEMP0
rrf TEMP0, f
rrf TEMP0, w
andlw 0x03
sublw 0x05
btfss PS2_Xp
addwf X_COUNTER, f
btfss PS2_Yp
addwf Y_COUNTER, f
btfss PS2_Xn
subwf X_COUNTER, f
btfss PS2_Yn
subwf Y_COUNTER, f
bcf XY_FLAGS, xSIGN
btfsc X_COUNTER, 7
bsf XY_FLAGS, xSIGN
bcf XY_FLAGS, ySIGN
btfsc Y_COUNTER, 7
bsf XY_FLAGS, ySIGN
movf XY_FLAGS, w
andlw b'00000111'
btfss PS2_Bl ;
xorlw b'00000001'
btfss PS2_Br
xorlw b'00000010'
movwf dBUTTONS
retlw 0x00
;---------------------------------------------------------------------------------------------
; READ SPEED CONTROL POTENTIOMETER:
;---------------------------------------------------------------------------------------------
ReadADJ1 movlw 0x00
bsf STATUS, RP0
bsf ADJ1
bcf STATUS, RP0
addlw 1
btfss ADJ1
goto $ - 2
bsf STATUS, RP0
bcf ADJ1
bcf STATUS, RP0
bcf ADJ1
addlw MINPER
addwf SPEED_VAL, f
rrf SPEED_VAL, f
retlw 0x00
;---------------------------------------------------------------------------------------------
; WRAP MODE:
;---------------------------------------------------------------------------------------------
WrapMode btfsc DATA
goto WrapMode
call ByteIn
xorlw 0xFE
bz WrapMode
movf RECEIVE, w
xorlw 0xFF
bz Acknowledge
xorlw 0xFF^0xEC
bz Acknowledge
xorlw 0xEC
call ByteOut
goto WrapMode
;---------------------------------------------------------------------------------------------
; LOAD DEFAULT VALUES:
;---------------------------------------------------------------------------------------------
LoadDefaults movlw 100
movwf REPORT_RATE
movlw 0x02
movwf RESOLUTION
clrf FLAGS
retlw 0x00
;---------------------------------------------------------------------------------------------
; EMULATE BAT:
;---------------------------------------------------------------------------------------------
BATdelay clrf TEMP0
clrf TEMP1
DelayLoop Delay 6
decfsz TEMP0, f
goto DelayLoop
decfsz TEMP1, f
goto DelayLoop
retlw 0x00
;---------------------------------------------------------------------------------------------
; HANDLE COMMANDS:
;---------------------------------------------------------------------------------------------
SetResolution movf RECEIVE, w
movwf RESOLUTION
goto MainLoop
SetReportRate movf RECEIVE, w
movwf REPORT_RATE
goto MainLoop
;0xE6 - Set Scaling 1:1
Mouse_E6 bcf FLAGS, SCALE
goto MainLoop
;0xE7 - Set Scaling 2:1
Mouse_E7 bsf FLAGS, SCALE
goto MainLoop
;0xE9 - Status Request
Mouse_E9 movf FLAGS, w
btfss PS2_Bl
iorlw 0x04
btfss PS2_Br
iorlw 0x01
movwf SEND1
movf RESOLUTION, w
movwf SEND2
movf REPORT_RATE, w
movwf SEND3
movlw 0x03
movwf LENGTH
goto PacketOut
;0xEA - Set Stream Mode
Mouse_EA bcf FLAGS, MODE
goto MainLoop
;0xF0 - Set Remote Mode
Mouse_F0 bsf FLAGS, MODE
goto MainLoop
;0xF2 - Get Device ID
Mouse_F2 clrf SEND1
movlw 0x01
movwf LENGTH
goto PacketOut
;0xF4 - Enable Reporting
Mouse_F4 bsf FLAGS, ENABLE
bcf LED
goto MainLoop
;0xF5 - Disable Reporting
Mouse_F5 bcf FLAGS, ENABLE
bsf LED
goto MainLoop
;0xF6 - Set Default
Mouse_F6 call LoadDefaults
bsf LED
goto MainLoop
;Invalid command
Mouse_ERR movlw 0xFE
call ByteOut
goto MainLoop
;---------------------------------------------------------------------------------------------
; OUTPUT ONE BYTE: - TIMING IS CRITICAL!!!
;---------------------------------------------------------------------------------------------
ByteOut movwf TEMP0
InhibitLoop btfss CLOCK
goto InhibitLoop
Delay 100
btfss CLOCK
goto InhibitLoop
btfss DATA
retlw 0xFF
clrf PARITY
movlw 0x08
movwf COUNTER
movlw 0x00
call BitOut
btfss CLOCK
goto ByteOutEnd
Delay 4
ByteOutLoop movf TEMP0, w
xorwf PARITY, f
call BitOut
btfss CLOCK
goto ByteOutEnd
rrf TEMP0, f
decfsz COUNTER, f
goto ByteOutLoop
Delay 2
comf PARITY, w
call BitOut
btfss CLOCK
goto ByteOutEnd
Delay 5
movlw 0xFF
call BitOut
Delay 48
retlw 0x00
ByteOutEnd bsf STATUS, RP0
bsf DATA
bsf CLOCK
bcf STATUS, RP0
retlw 0xFE
BitOut bsf STATUS, RP0
andlw 0x01
btfss STATUS, Z
bsf DATA
btfsc STATUS, Z
bcf DATA
Delay 21
bcf CLOCK
Delay 45
bsf CLOCK
bcf STATUS, RP0
Delay 5
return
;---------------------------------------------------------------------------------------------
; READ ONE BYTE: (Takes about 1ms) - TIMING IS CRITICAL!!!
;---------------------------------------------------------------------------------------------
ByteIn btfss CLOCK
retlw 0xFE
btfsc DATA
retlw 0xFE
movlw 0x08
movwf COUNTER
clrf PARITY
Delay 28
ByteInLoop call BitIn
btfss CLOCK
retlw 0xFE
bcf STATUS, C
rrf RECEIVE, f
iorwf RECEIVE, f
xorwf PARITY,f
decfsz COUNTER, f
goto ByteInLoop
Delay 1
call BitIn
btfss CLOCK
retlw 0xFE
xorwf PARITY, f
Delay 5
ByteInLoop1 Delay 1
call BitIn
btfss CLOCK
retlw 0xFE
xorlw 0x00
btfsc STATUS, Z
clrf PARITY
btfsc STATUS, Z
goto ByteInLoop1
bsf STATUS, RP0
bcf DATA
Delay 11
bcf CLOCK
Delay 45
bsf CLOCK
Delay 7
bsf DATA
bcf STATUS, RP0
btfss PARITY, 7
retlw 0xFF
Delay 45
retlw 0x00
BitIn Delay 8
bsf STATUS, RP0
bcf CLOCK
Delay 45
bsf CLOCK
bcf STATUS, RP0
Delay 21
btfsc DATA
retlw 0x80
retlw 0x00
;---------------------------------------------------------------------------------------------
; DELAY:
;---------------------------------------------------------------------------------------------
;Delays 4w+4 cycles (including call,return, and movlw) (0=256)
Delay_us addlw -1 ;Precise delays used in I/O
btfss STATUS, Z
goto Delay_us
return
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -