Thanks to Jinx
;emouse.pic - electronic mouse
;stand-alone 16F84 program to generate mouse data
;joecolquitt@clear.net.nz
; org 21.12.98
; rev 31.12.98
; rev 09.01.99
;Microsoft Mouse, 3 byte data stream
;1200 bps, 7 data bits, 1 stop bit, no parity
;1200 bps = 833.3us / bit = 8333 instruction cycles
;bit 7 6 5 4 3 2 1 0
;
;Byte 1 0 0 L R Y7 Y6 X7 X6
;Byte 2 0 0 Y5 Y4 Y3 Y2 Y1 Y0
;Byte 3 0 0 X5 X4 X3 X2 X1 X0
;
;X7 = 1 = left X7 = 0 = right
;Y7 = 1 = up Y7 = 0 = down
; L = 1 = left button
; R = 1 = right
;
;Other bits are speed
;
;First 20 movement instructions are for 1 pixel, after that
;4 pixels. Counter is reset when pushbutton is released
status equ 03h
carry equ status.0
zero equ status.2
porta equ 05h
portb equ 06h
option equ 81h
trisa equ 85h
trisb equ 86h
ram equ 0ch
lin equ portb.0 ;pushbutton for left
rin equ portb.1 ; right
uin equ portb.2 ; up
din equ portb.3 ; down
bin equ portb.4 ; left button
comm equ portb.5 ;data to PC
start equ 00h
w equ 0 ;instruction suffix = w = accumulator
f equ 1 ; = f = register
orgdata ram
data rb ;byte to send
bit equ data.7 ;bit to send
bcnt rb ;bit counter
tdc1 rb ;time delay counter
move rb ;pixel movement counter
pixel rb ;movement rate counter
pflags rb ;change movement rate flags
lfl equ pflags.0
rfl equ pflags.1
ufl equ pflags.2
dfl equ pflags.3
config 0f2h ;10MHz crystal xxxx xx10
;watchdog timer disabled xxxx x0xx
;power-up timer enabled xxxx 0xxx
;code not protected xxx1 xxxx
org start
goto entry
entry movlw 00h ;Porta unused o/p
tris porta
movlw 1fh ;Portb = oooi iiii
tris portb
clrf porta ;clear data latches
clrf portb
movlw 80h ;Portb pull-ups off
option
bsf comm ;idle
;---- main loop
main btfss lin ;look for direction pushbuttons
goto left
btfss rin
goto right
btfss uin
goto up
btfss din
goto down
movlw 14h ;reset movement counter
movwf pixel
clrf pflags ;reset rate change flags
btfss bin ;mouse button
goto button
goto main
;---- data output setups
left btfsc lfl ;if high-rate is set then 4pixel move
goto left4
decfsz pixel,f ;else decrement counter until 0
goto left1
bsf lfl ;then set flag
goto left4
left1 movlw 9eh ;1001 1110
call send
movlw 20h ;0010 0000 (24)
call send
movlw 4fh ;0100 1111
call send
movlw 0f0h ;1111 0000
call send
goto main
right btfsc rfl
goto right4
decfsz pixel,f
goto right1
bsf rfl
goto right4
right1 movlw 0feh ;1111 1110
call send
movlw 2fh ;0010 1111 (2b)
call send
movlw 0cfh ;1100 1111
call send
movlw 0f0h ;1111 0000
call send
goto main
up btfsc ufl
goto up4
decfsz pixel,f
goto up1
bsf ufl
goto up4
up1 movlw 0e6h ;1110 0110
call send
movlw 3fh ;0011 1111
call send
movlw 0c8h ;1100 1000 (c9)
call send
movlw 10h ;0001 0000
call send
goto main
down btfsc dfl
goto down4
decfsz pixel,f
goto down1
bsf dfl
goto down4
down1 movlw 0feh ;1111 1110
call send
movlw 3fh ;0011 1111
call send
movlw 0cbh ;1100 1011 (ca)
call send
movlw 0f0h ;1111 0000
call send
goto main
left4 movlw 9eh ;1001 1110
call send
movlw 24h ;0010 0100 (20)
call send
movlw 4fh ;0100 1111
call send
movlw 0f0h ;1111 0000
call send
goto main
right4 movlw 0feh ;1111 1110
call send
movlw 2bh ;0010 1011 (2f)
call send
movlw 0cfh ;1100 1111
call send
movlw 0f0h ;1111 0000
call send
goto main
up4 movlw 0e6h ;1110 0110
call send
movlw 3fh ;0011 1111
call send
movlw 0c9h ;1100 1001 (c8)
call send
movlw 10h ;0001 0000
call send
goto main
down4 movlw 0feh ;1111 1110
call send
movlw 3fh ;0011 1111
call send
movlw 0cah ;1100 1010 (cb)
call send
movlw 0f0h ;1111 0000
call send
goto main
button movlw 0fch ;1111 1100
call send
movlw 3fh ;0011 1111
call send
movlw 0cfh ;1100 1111
call send
movlw 0f0h ;1111 0000
call send
bhold btfss bin ;wait for button release
goto bhold
out movlw 0feh ;1111 1110
call send
movlw 3fh ;0011 1111
call send
movlw 0cfh ;1100 1111
call send
movlw 0f0h ;1111 0000
call send
goto main
;---- ouput data bits
send movwf data
movlw 08h
movwf bcnt
sbit btfss bit ;test
goto b0
b1 bcf comm ;'1'
call bitdel
goto newbit
b0 bsf comm ;'0'
call bitdel
newbit rlf data,f
decfsz bcnt,f
goto sbit
return
;---- comms timing delay
bitdel movlw 00h ;bit-length delay
movwf tdc1
lp1 decfsz tdc1,f
goto lp1
movlw 00h
movwf tdc1
lp2 decfsz tdc1,f
goto lp2
movlw 0ach
movwf tdc1
lp3 decfsz tdc1,f
goto lp3
return