📄 mouse.asm
字号:
;--------------------------------------------------------------------------------------------
; This was written for the PIC16F84 with an RC oscillator @ 20pF/5kohm
; (will work with any oscillator between 3.50 MHz - 5.76 MHz)
;---------------------------------------------------------------------------------------------
; CLOCK/TIMING INFORMATION:
;---------------------------------------------------------------------------------------------
;
; PS/2 bus clock low time = 40 us +/- 25% (30 us - 50 us)
; PS/2 bus clock high time = 40 us +/- 25% (30 us - 50 us)
; RC osc @ 20pF/5k = 4.61 MHz +/- 25% (3.50 MHz - 5.76 MHz)
; 1 instruction cycle @ 4.61 MHz (RC) = 0.87 us +/- 25% (0.65 us - 1.09 us)
; Optimum PS/2 bus clock low time @4.61MHz = 45.97 instruction cycles
; Actual PS/2 bus clock low time = 46 instruction cycles
; Actual PS/2 bus clock low time @4.61MHz (RC) = 40.0us +/- 25% (30us-50us)
; Actual PS/2 bus clock frequency @461MHz (RC) = 12.5 kHz +/- 25% (10.0kHz-16.7kHz)
;---------------------------------------------------------------------------------------------
; 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 & _XT_OSC
;---------------------------------------------------------------------------------------------
; DEFINES:
;---------------------------------------------------------------------------------------------
#DEFINE DATA PORTA, 2 ;May be assigned to any I/O pin
#DEFINE CLOCK PORTA, 3 ;May be assigned to any I/O pin
#DEFINE PS2_Yp PORTB, 0 ;May be assigned to any I/O pin
#DEFINE PS2_Yn PORTB, 1 ;May be assigned to any I/O pin
#DEFINE PS2_Xp PORTB, 2 ;May be assigned to any I/O pin
#DEFINE PS2_Xn PORTB, 3 ;May be assigned to any I/O pin
#DEFINE PS2_Bl PORTB, 4 ;May be assigned to any I/O pin
#DEFINE PS2_Br PORTB, 5 ;May be assigned to any I/O pin
#DEFINE PERIOD 20 ;Time between reading of inputs. Min=(osc frequency)/204800
#DEFINE DISTANCE 2 ;Amount by which X/Y counters are incremented/decremented
;---------------------------------------------------------------------------------------------
; 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
dBUTTONS ;"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 ;Test for a resolution value
subwf RECEIVE, w
bnc SetResolution
movlw 0xC8 ;Test for report rate value
subwf RECEIVE, w
bnc SetReportRate
movlw 0xE6 ;0xE6 is lowest code
subwf RECEIVE, w
bnc MainLoop
HandlerTable addwf PCL, f ;Add offset
goto Mouse_E6 ;0xE6 - Set Scaling 1:1
goto Mouse_E7 ;0xE7 - Set Scaling 2:1
goto MainLoop ;0xE8 - Set Resolution
goto Mouse_E9 ;0xE9 - Status Request
goto Mouse_EA ;0xEA - Set Stream Mode
goto Report ;0xEB - Read Data
goto MainLoop ;0xEC - Reset Wrap Mode
goto MainLoop ;0xED -
goto WrapMode ;0xEE - Set Wrap Mode
goto MainLoop ;0xEF
goto Mouse_F0 ;0xF0 - Set Remote Mode
goto MainLoop ;0xF1
goto Mouse_F2 ;0xF2 - Read Device Type
goto MainLoop ;0xF3 - Set Report Rate
goto Mouse_F4 ;0xF4 - Enable
goto Mouse_F5 ;0xF5 - Disable
goto Mouse_F6 ;0xF6 - Set Default
goto MainLoop ;0xF7
goto MainLoop ;0xF8
goto MainLoop ;0xF9
goto MainLoop ;0xFA
goto MainLoop ;0xFB
goto MainLoop ;0xFC
goto MainLoop ;0xFD
goto PacketOut ;0xFE - Resend
Table1End goto Reset ;0xFF - Reset
;---------------------------------------------------------------------------------------------
; START:
;---------------------------------------------------------------------------------------------
Start clrf PORTA
clrf PORTB
bsf STATUS, RP0 ;(TRISA=TRISB=0xFF by default)
movlw 0x57 ;Timer mode, assign max. prescaler, enable pullups
movwf OPTION_REG
bcf STATUS, RP0
movlw 0x08 ;Bit 3 always = 1, clear previous button states
movwf XY_FLAGS
; goto Reset
;---------------------------------------------------------------------------------------------
; Reset Mode:
;---------------------------------------------------------------------------------------------
Reset movlw 0xAA
movwf SEND1 ;Load BAT completion code
call LoadDefaults
clrf SEND2 ;Load Device ID (0x00)
movlw 0x02
movwf LENGTH
call BATdelay
goto PacketOut ;Output 2-byte "completion-code, device ID" packet
;---------------------------------------------------------------------------------------------
; Stream/Remote Mode:
;---------------------------------------------------------------------------------------------
MainLoop clrf X_COUNTER ;Clear movement counters
clrf Y_COUNTER
MainLoop1 btfss DATA ;Check for host request-to-send
goto PacketIn
movlw PERIOD ;Report period
subwf TMR0, w
btfss STATUS, C ;TMR0=report period?
goto MainLoop1 ; No--loop
clrf TMR0 ; Yes--reset TMR0, then read inputs...
call ReadInputs
btfsc FLAGS, MODE ;Stream(0)/Remote(1) mode
goto MainLoop1
btfss FLAGS, ENABLE ;Disable(0)/Enable(1) reporting
goto MainLoop1
movf X_COUNTER, w ;Test for X-movement
iorwf Y_COUNTER, w ;Test for Y-movement
iorwf dBUTTONS, w ;Test for change in button states
bz MainLoop1
; goto Report
;---------------------------------------------------------------------------------------------
; REPORT:
;---------------------------------------------------------------------------------------------
Report movf dBUTTONS, w
xorwf XY_FLAGS, f ;Find current button state
movf XY_FLAGS, w
movwf SEND1
movf X_COUNTER, w
movwf SEND2
movf Y_COUNTER, w
movwf SEND3
movlw 0x03 ;Movement data report length
movwf LENGTH
; goto PacketOut
;---------------------------------------------------------------------------------------------
; OUTPUT PACKET
;---------------------------------------------------------------------------------------------
PacketOut movlw SEND1 ;First byte of packet
movwf FSR
movf LENGTH, w ;Length of packet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -