home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Exec 5
/
CD_Magazyn_EXEC_nr_5.iso
/
Recent
/
hard
/
hack
/
ps2m.lha
/
PIC_source
/
ps2m.asm
< prev
Wrap
Assembly Source File
|
2001-06-03
|
9KB
|
626 lines
; $VER: 1.4 (03.06.01)
; COPYRIGHT (C) 2001 RDC SOFTWARE
; Distributed under GPL license - see gpl.txt
; This is a part of ps2m package,
; you can obtain latest version at Aminet:
; ftp://ftp.wustl.edu/pub/aminet/hard/hack/ps2m.lha
; ftp://ftp.wustl.edu/pub/aminet/hard/hack/ps2m.readme
; Use picasm by Timo Rossi to compile.
; Amiga version of picasm is included in devpic package:
; ftp://ftp.wustl.edu/pub/aminet/dev/cross/devpic.lha
; ftp://ftp.wustl.edu/pub/aminet/dev/cross/devpic.readme
; For any questions: rdc@cyberlan.mtu-net.ru
device pic16f876
include "16f876.i"
include "macros.i"
POWER equ 0
SPEED equ 42 ;42 for 4MHz, 52 for 5MHz
; ---------
; variables
; ---------
org 0x20
memstart
count ds 1
recvb ds 1
recvc ds 1
recvd ds 2
recvdt ds 1
sendata ds 1
sendetc ds 1
intw ds 1
ints ds 1
wdtp ds 1
wdtm ds 2
temp1 ds 1
currbyte ds 1
xdif ds 1
ydif ds 1
xdir ds 1
ydir ds 1
xspeed ds 2
yspeed ds 2
xcount ds 1
ycount ds 1
xtemp ds 1
ytemp ds 1
flags ds 1
extflags ds 1
byte1 ds 1
byte2 ds 1
byte3 ds 1
byte4 ds 1
zdif ds 1
zcount ds 1
mem_end org 0x000
; ---------------
; bit definitions
; ---------------
fpkt1 equ 0
fpkt2 equ 1
fpkt3 equ 2
fbyte equ 3
fnores equ 4
fnofps equ 5
fon equ 6
fwheel equ 7
ext200 equ 0
extime equ 1
if POWER-1
extbut equ 2
endif
; ----------------
; init PIC & mouse
; ----------------
start clrf INTCON
if POWER
movlw b'10000001'
else
movlw b'00000001'
endif
option
goto start_a
; -----------------
; interrupt handler
; -----------------
int local
bcf INTCON,1
movwf intw
swapfw STATUS
movwf ints
bcf recvd+1,2
btfsc PORTB,1
bsf recvd+1,2
rrf recvd+1
rrf recvd
bsf wdtp,5 ;clear packet bit shift watchdog
loop =a,recvc
movlf 11,recvc
bsf flags,fbyte
movff recvd,recvdt
=a swapfw ints
movwf STATUS
swapf intw
swapfw intw
retfie
endlocal
; ----------------------------
; init PIC & mouse - continued
; ----------------------------
start_a local
movlf 0xff,0x1f
clrf PORTA
clrf PORTB
movlw b'11111111'
tris PORTA
tris PORTB
endlocal
; clear RAM
movlf memstart,FSR
sublw mem_end
clearam clrf INDF
incf FSR
addlw 0xff
bnz clearam
movlf TRISB+0x80,FSR
; init variables
movlf 24,wdtm
movlf 11,recvc
; delay before turn mouse on
local
callw delayms,0
if POWER
movlw b'00001111' ;turn on mouse
tris PORTA
callw delayms,100
movlw b'00000001' ;enable pull-up
option
movlf 8,temp1
=a callw delayms,0
loop =a,temp1
endif
; wait for mouse
bcf INDF,0 ;inhibit I/O
bsf INDF,1
callw delayms,50
call testms ;i.m.explorer compatible?
bz =h ;yes
sublw 1 ;intellimouse compatible?
bnz =i ;no
bsf extflags,ext200
call testms ;i.m.explorer compatible?
skipnz
=h bsf extflags,extime ;i.m.explorer compatible
bsf flags,fwheel ;intellimouse compatible
=i callw send,0xe8 ;set resolution
callw send,3 ;8/mm
callw send,0xe6 ;scaling 1:1
callw send,0xf3 ;set 200fps
callw send,200
callw send,0xf4 ;enable mouse in streaming mode
call cpoff
endlocal
; -----------
; check mouse
; -----------
m_check callw send,0xE9
bc start ;no response? init mouse again
sublw 0xFA ;ACK?
bnz start ;no ACK - init mouse again...
call bwait ;receive status byte
bc start
andlw b'01100000' ;leave only stream & enable flags
sublw b'00100000' ;must be stream and enabled
bnz start
btfsc flags,fnores
goto p_init
call bwait ;receive resolution (value ignored)
bc nores ;no resolution...
btfsc flags,fnofps
goto p_init
call bwait ;receive reports per second
bc nofps ;no fps
goto p_init
; no resolution & fps report
nores bsf flags,fnores
nofps bsf flags,fnofps
; ---------------------
; sync serial port init
; ---------------------
p_init local
movlf 3,recvb
btfsc flags,fwheel
incf recvb
clrf currbyte
movfw INDF
xorfw PORTB
andlw b'00000100'
bz =a
bcf flags,fon ;mouse off
if POWER
movlw b'11101111' ;XxYy off, power on
tris PORTA
movlw b'11111111' ;buttons and wheels off
else
movlw b'11111111' ;buttons, wheels, XxYy off
tris PORTA
endif
tris PORTB
=a bsf INTCON,7 ;global interrupt enable
bsf INTCON,4 ;enable RB0 interrupt
endlocal
; check shift flag - byte received
schk btfss flags,fbyte
goto pchk1
bcf flags,fbyte
movfw currbyte
addlw byte1
movwf FSR
movff recvdt,INDF
movlf PORTB+0x80,FSR
incf currbyte
loop tchk,recvb
movlf 3,recvb
btfsc flags,fwheel
incf recvb
clrf currbyte
bsf flags,fpkt1
movlf 24,wdtm
goto tchk
; check packet flag - packet received
pchk1 btfss flags,fpkt1
goto pchk2
bcf flags,fpkt1
bsf flags,fpkt2
clrf xdir
movlw 1
btfsc byte1,4
movlw 255
movf byte2
btfss STATUS,Z
movwf xdir
movfw byte2
btfsc byte1,4
sublw 0
addfw xdif
btfsc STATUS,C
movlw 255
movwf xdif
movwf xspeed
addwf xspeed
skipc
addwf xspeed
skipc
goto tchk
movlf 255,xspeed
goto tchk
pchk2 btfss flags,fpkt2
goto pchk3
bcf flags,fpkt2
bsf flags,fpkt3
clrf ydir
movlw 1
btfsc byte1,5
movlw 255
movf byte3
btfss STATUS,Z
movwf ydir
movfw byte3
btfsc byte1,5
sublw 0
addfw ydif
btfsc STATUS,C
movlw 255
movwf ydif
movwf yspeed
addwf yspeed
skipc
addwf yspeed
skipc
goto tchk
movlf 255,yspeed
goto tchk
pchk3 btfss flags,fpkt3
goto tchk
bcf flags,fpkt3
rlfw byte1
movwf temp1
rlf temp1
comfw temp1
andlw b'00011100'
local
movwf temp1
sublw b'00011100'
skipz
call cpoff
btfss flags,fon
goto =c
movfw INDF
andlw b'11100011'
iorfw temp1
movwf INDF
btfss flags,fwheel
goto =c
movfw byte4
btfss extflags,extime
goto =b
if POWER
andlw b'00110000'
skipz
bcf INDF,5
skipnz
bsf INDF,5
movfw byte4
else
btfsc byte4,5
bcf INDF,5
btfss byte4,5
bsf INDF,5
bcf extflags,extbut
btfsc byte4,4
bsf extflags,extbut
endif
andlw b'00001111'
btfsc byte4,3
iorlw b'11110000'
=b addwf zdif
=c ;....
endlocal
; check time to move
tchk btfss RTCC,7
goto schk
sublf SPEED,RTCC
; CPU watchdog
clrwdt
; check mouse
mchk loop xchk,wdtm+1
loop xchk,wdtm
movlf 24,wdtm
bcf INTCON,4 ;disable RB0 interrupt
movfw recvb
btfsc flags,fwheel
addlw 255
sublw 3 ;packet receive started?
btfss STATUS,Z
goto mchk_e ;yes
movfw recvc
sublw 11 ;byte receive started?
btfss STATUS,Z
goto mchk_e ;yes
btfsc PORTB,0 ;bit receive started?
goto m_check ;no
mchk_e bsf INTCON,4 ;enable RB0 interrupt
; check X movement
xchk movfw xspeed
addwf xspeed+1
btfss STATUS,C
goto ychk
movf xdif
btfsc STATUS,Z
goto ychk
decf xdif
movfw xdir
subwf xcount
rrfw xcount
andlw 1
xorfw xcount
andlw 3
movwf xtemp
; check Y movement
ychk movfw yspeed
addwf yspeed+1
btfss STATUS,C
goto zchk
movf ydif
btfsc STATUS,Z
goto zchk
decf ydif
movfw ydir
addwf ycount
rrfw ycount
andlw 1
xorfw ycount
andlw 3
movwf ytemp
; check wheel movement
zchk local
if POWER
btfsc PORTB,5
goto =a
btfss INDF,5
goto =a
else
btfsc PORTA,4
goto =a
decf FSR
movfw INDF
incf FSR
andlw b'00010000'
btfsc STATUS,Z
goto =a
endif
movlf 2,zcount
bsf INDF,6
bsf INDF,7
clrf zdif
=a movf zdif
bz xyout
movlw 1
btfss zdif,7
sublw 0
addwf zdif
addwf zcount
rrfw zcount
andlw 1
xorfw zcount
movwf temp1
movfw INDF
andlw b'00111111'
btfsc temp1,0
iorlw b'01000000'
btfsc temp1,1
iorlw b'10000000'
btfsc flags,fon
movwf INDF
endlocal
; XY movement out
xyout bcf STATUS,C
rlfw xtemp
addfw xtemp
addfw xtemp
iorfw ytemp
if POWER-1
btfsc extflags,extime
btfss extflags,extbut
iorlw b'00010000'
endif
btfsc flags,fon
tris PORTA
; packet bit shift watchdog
wchk local
loop schk,wdtp
bcf INTCON,4 ;disable RB0 interrupt
movf wdtp
btfss STATUS,Z
goto =a
movlf 11,recvc
bsf wdtp,5
goto p_init
=a bsf INTCON,4 ;enable RB0 interrupt
goto schk
endlocal
; check power off
cpoff btfsc flags,fon
return
comfw PORTA
andlw b'00001111'
btfsc STATUS,Z
btfss PORTB,2
return
bsf flags,fon
movlf 3,xtemp
movwf ytemp
movlf 2,xcount
movwf ycount
movwf zcount
return
; try to switch to MS-like wheel mode
testms callw send,0xf3
callw send,200
callw send,0xf3
movlw 100
btfsc extflags,ext200
movlw 200
call send
callw send,0xf3
callw send,80
callw send,0xF2 ;read mouse ID
call bwait
sublw 4
return
; ------------------
; send byte to mouse
; ------------------
send local
clrf INTCON
movwf temp1
movwf sendata
clrf sendetc
comf sendetc
bcf INDF,0 ;inhibit I/O
callw delayus,100
movlf 8,count
movlw 1
=a rrf temp1 ;calculate parity
skipnc
xorwf sendetc
loop =a,count
movlf 11,count
bsf INDF,0
bcf INDF,1 ;initiate send
=b clrwdt
clrw
=c addlw 1
bz start ;timeout? reset mouse
btfsc PORTB,0 ;wait for 0
goto =c
rrf sendetc
rrf sendata
btfss STATUS,C
bcf INDF,1
btfsc STATUS,C
bsf INDF,1
clrw
=d addlw 1
btfsc STATUS,Z ;timeout?
goto start ;reset mouse
btfss PORTB,0 ;wait for 1
goto =d
loop =b,count
clrf INTCON
endlocal
; to be continued
; -----------------------
; receive byte from mouse
; -----------------------
bwait local
bsf INTCON,7 ;global interrupt enable
bsf INTCON,4 ;enable RB0 interrupt
movlf 40,count
=a clrwdt
callw delayus,100
btfss flags,fbyte
goto =b
bcf flags,fbyte
movfw recvdt
bcf STATUS,C
return
=b loop =a,count
setc
return
endlocal
; ------
; delays
; ------
delayms local
movwf count
=a clrwdt
movlw 249
=b addlw 0xff
bnz =b
loop =a,count
return
endlocal
delayus addlw 0xff
bnz delayus
return
end