791 lines
12 KiB
NASM
791 lines
12 KiB
NASM
;page 1
|
|
; filename: mouseps2.asm
|
|
;
|
|
;
|
|
; receives data in a serial way from a
|
|
; PS/2 mouse;
|
|
; lines used are two: clock and data.
|
|
|
|
; As these lines should be open collector,
|
|
; according to the PS/2 protocol,
|
|
; RA2 (Clock) and RA3 (Data) are used as
|
|
; LOW output when it's to the host to drive
|
|
; them, while when they must be HIGH or
|
|
; when they have to be driven by the mouse
|
|
; they are set as inputs.
|
|
|
|
; RA0 (Clock) and RA1 (Data) are used
|
|
; as inputs to test Clock and Data lines.
|
|
|
|
; RB0 is used (as output) for giving the user
|
|
; informations about the communication
|
|
; status and about reception errors (as an example, with a LED)
|
|
|
|
PROCESSOR 16F84
|
|
|
|
RADIX DEC
|
|
|
|
__CONFIG 3FF1H
|
|
|
|
; XT
|
|
; /PWRO enable
|
|
; WDT disable
|
|
|
|
INCLUDE "P16F84.INC"
|
|
|
|
TOCS EQU 05H
|
|
|
|
CIN EQU 0
|
|
DIN EQU 1
|
|
COUT EQU 2
|
|
DOUT EQU 3
|
|
STBIT EQU 0
|
|
ENDBIT EQU 1
|
|
|
|
|
|
RA0 EQU 0
|
|
RA1 EQU 1
|
|
RA2 EQU 2
|
|
RA3 EQU 3
|
|
RA4 EQU 4
|
|
RB0 EQU 0
|
|
RB1 EQU 1
|
|
RB2 EQU 2
|
|
RB3 EQU 3
|
|
RB4 EQU 4
|
|
RB5 EQU 5
|
|
RB6 EQU 6
|
|
RB7 EQU 7
|
|
|
|
|
|
ORG 0CH
|
|
|
|
|
|
count RES 1
|
|
cbit RES 1
|
|
cbyte RES 1
|
|
delay1 RES 1
|
|
delay2 RES 1
|
|
delay3 RES 1
|
|
byteo RES 1
|
|
byteio RES 1
|
|
bytein RES 1
|
|
parbit RES 1
|
|
byte1 RES 1
|
|
byte2 RES 1
|
|
byte3 RES 1
|
|
byte4 RES 1
|
|
serv RES 1
|
|
|
|
|
|
hexd0 RES 1
|
|
hexd1 RES 1
|
|
hexd2 RES 1
|
|
decd0 RES 1
|
|
decd1 RES 1
|
|
decd2 RES 1
|
|
currd RES 1
|
|
|
|
|
|
number RES 1
|
|
workdi RES 1
|
|
servst RES 1
|
|
servw RES 1
|
|
servir RES 1
|
|
|
|
|
|
; WARNING: always keep at 0 the RP0 bit
|
|
; of the STATUS register ( selection of bank 0)
|
|
; to read the TMR0, set that bit just when needed
|
|
; and then set it again to 0
|
|
|
|
ORG 00H
|
|
goto start
|
|
|
|
ORG 50H
|
|
start:
|
|
bsf STATUS,RP0
|
|
; RB1-7: INPUT
|
|
; RB0: INPUT
|
|
movlw 11111111B
|
|
movwf TRISB
|
|
; RA4 :INPUT (unused)
|
|
; RA3, RA2 : INPUT
|
|
; RA1, RA0 : INPUT
|
|
movlw 11111111B
|
|
movwf TRISA
|
|
bcf STATUS,RP0
|
|
; disables Clock and Data
|
|
movlw 11111111B
|
|
movwf PORTA
|
|
movlw 11111111B
|
|
movwf PORTB
|
|
bsf STATUS,RP0
|
|
; assigns fosc/4 to TMR0
|
|
bcf OPTION_REG,TOCS
|
|
; assigns the prescaler to TMR0 with value 256
|
|
; (111)
|
|
; bsf OPTION_REG,PSA
|
|
; bsf OPTION_REG,PS2
|
|
; bsf OPTION_REG,PS1
|
|
; bsf OPTION_REG,PS0
|
|
bcf STATUS,RP0
|
|
; movlw 00H
|
|
; movwf hexd2
|
|
; movwf hexd1
|
|
; movwf hexd0
|
|
; movwf decd2
|
|
; movwf decd1
|
|
; movwf decd0
|
|
; movwf number
|
|
; movwf servst
|
|
; movwf servw
|
|
; movwf serv
|
|
; movlw 00H
|
|
; movwf currd
|
|
; movwf workdi
|
|
; movlw 00H
|
|
; movwf count
|
|
movlw 00H
|
|
movwf TMR0
|
|
; waits 1 s
|
|
call del1s
|
|
; signals three times "sent command"
|
|
; to indicate the start of operations
|
|
call cmdsnt
|
|
call cmdsnt
|
|
call cmdsnt
|
|
; sends RESET command (FFH)
|
|
movlw 0FFH
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
; waits 1s
|
|
call del1s
|
|
; sends ENABLE command (F4H)
|
|
movlw 0F4H
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
; waits 1 s
|
|
call del1s
|
|
; sends DEFAULT SETTINGS command
|
|
; (F6H)
|
|
movlw 0F6H
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
call del1s
|
|
; requests data transmission (EBH)
|
|
movlw 0EBH
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
call del1s
|
|
; requests data transmission (EBH)
|
|
movlw 0EBH
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
call del1s
|
|
; sets stream mode (EAH)
|
|
movlw 0EAH
|
|
movwf byteo
|
|
movwf byteio
|
|
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
call del1s
|
|
; requests data transmission (EBH) after
|
|
; stream mode setting
|
|
movlw 0EBH
|
|
movwf byteo
|
|
movwf byteio
|
|
call cmdts
|
|
call sendby
|
|
call cmdsnt
|
|
call del1s
|
|
; continuous data reception (every 100 ms)
|
|
datain
|
|
call del.1s
|
|
; requests data transmission (EBH)
|
|
movlw 0EBH
|
|
movwf byteo
|
|
movwf byteio
|
|
call sendby
|
|
call recby
|
|
movf byteio,W
|
|
xorlw 0FFH
|
|
btfsc STATUS,Z
|
|
goto datain
|
|
movf bytein,W
|
|
movwf byte4
|
|
call recby
|
|
movf byteio,W
|
|
xorlw 0FFH
|
|
btfsc STATUS,Z
|
|
goto datain
|
|
movf bytein,W
|
|
movwf byte3
|
|
call recby
|
|
movf byteio,W
|
|
xorlw 0FFH
|
|
btfsc STATUS,Z
|
|
goto datain
|
|
movf bytein,W
|
|
movwf byte2
|
|
call recby
|
|
movf byteio,W
|
|
xorlw 0FFH
|
|
btfsc STATUS,Z
|
|
goto datain
|
|
movf bytein,W
|
|
movwf byte1
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
bsf PORTB,RB0
|
|
call del10m
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
bcf PORTB,RB0
|
|
goto datain
|
|
goto fine
|
|
|
|
recby:
|
|
; data reception - returns the received byte in
|
|
; bytein; if an error of any kind
|
|
; has occurred, returns
|
|
; byteio=11111111B, otherwise byteio=0
|
|
movlw 00H
|
|
movwf bytein
|
|
movlw 08H
|
|
movwf cbit
|
|
|
|
waitst:
|
|
; waits for the clock to go to 0 and inserts
|
|
; as bit number 0 of byteio
|
|
; the bit on RA1 (Data)
|
|
; waits start bit (RA1 pin)
|
|
movf PORTA,W
|
|
btfsc PORTA,RA0
|
|
goto waitst
|
|
|
|
; sets high RB0 pin when
|
|
; reception starts
|
|
bsf STATUS,RP0
|
|
bcf TRISB,0
|
|
bcf STATUS,RP0
|
|
bsf PORTB,RB0
|
|
movwf serv
|
|
rrf serv,W
|
|
andlw 00000001B
|
|
xorlw STBIT
|
|
andlw 00000001B
|
|
call wcup
|
|
|
|
; if start bit is different from STBIT signals
|
|
; an error
|
|
btfsc STATUS,Z
|
|
goto stbok
|
|
call estb
|
|
movlw 0FFH
|
|
movwf byteio
|
|
goto endrec
|
|
|
|
stbok:
|
|
movlw 08H
|
|
movwf cbit
|
|
movlw 00H
|
|
movwf byteio
|
|
|
|
; riceve gli 8 bit
|
|
waitb:
|
|
movf PORTA,W
|
|
btfsc PORTA,RA0
|
|
goto waitb
|
|
movwf serv
|
|
rrf serv,W
|
|
andlw 00000001B
|
|
btfsc STATUS,Z
|
|
goto carry0
|
|
|
|
carry1:
|
|
bsf STATUS,C
|
|
goto storeb
|
|
|
|
carry0:
|
|
bcf STATUS,C
|
|
|
|
storeb:
|
|
rrf byteio,F
|
|
call wcup
|
|
decfsz cbit
|
|
goto waitb
|
|
movf byteio,W
|
|
movwf bytein
|
|
|
|
; receives parity bit
|
|
waitpy:
|
|
movf PORTA,W
|
|
btfsc PORTA,RA0
|
|
goto waitpy
|
|
movwf serv
|
|
call wcup
|
|
; calculates the parity of the byte in byteio
|
|
; and returns it in parbit
|
|
call pargen
|
|
rrf serv,W
|
|
andlw 00000001B
|
|
xorwf parbit,W
|
|
btfss W,0
|
|
goto pbok
|
|
call eparb
|
|
movlw 0FFH
|
|
movwf byteio
|
|
goto endrec
|
|
pbok:
|
|
nop
|
|
|
|
; waits for the stop bit
|
|
waitsb:
|
|
movf PORTA,W
|
|
btfsc PORTA,RA0
|
|
goto waitsb
|
|
movwf serv
|
|
rrf serv,W
|
|
andlw 00000001B
|
|
xorlw ENDBIT
|
|
andlw 00000001B
|
|
call wcup
|
|
; if the stop bit is different from ENDBITsignals
|
|
; an error
|
|
btfsc STATUS,Z
|
|
goto ebok
|
|
call eendb
|
|
movlw 0FFH
|
|
movwf byteio
|
|
goto endrec
|
|
|
|
ebok:
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
bsf PORTB,RB0
|
|
; if byteio = FFH it means that an error
|
|
; has occurred; if the programs arrives here
|
|
; it means that the byte (anyway put in bytein)
|
|
; has been correctly received
|
|
movlw 00H
|
|
movwf byteio
|
|
|
|
endrec:
|
|
return
|
|
|
|
; not necessary
|
|
goto fine
|
|
|
|
; calculates the parity of the byte in byteio
|
|
; and returns it in parbit
|
|
pargen:
|
|
movlw 08H
|
|
movwf cbit
|
|
movlw 00H
|
|
|
|
pcycle:
|
|
xorwf byteio,W
|
|
bcf STATUS,C
|
|
rrf byteio,F
|
|
decfsz cbit
|
|
goto pcycle
|
|
andlw 00000001B
|
|
movwf parbit
|
|
return
|
|
|
|
; sends on PORTA,DOUT the L.S.bit
|
|
; of the w register: if a 0 has to be set,
|
|
; puts it on PORTA,DOUT and sets that
|
|
; pin as an output;
|
|
; if a 1 has to be set, puts it on porta
|
|
; (but it's not need) and sets that pin
|
|
; as an input
|
|
outbit:
|
|
andlw 1H
|
|
btfsc STATUS,Z
|
|
goto outz
|
|
goto outuno
|
|
|
|
outz:
|
|
bcf STATUS,RP0
|
|
bcf PORTA,DOUT
|
|
bsf STATUS,RP0
|
|
bcf TRISA,DOUT
|
|
bcf STATUS,RP0
|
|
goto endss
|
|
|
|
outuno:
|
|
bsf STATUS,RP0
|
|
bsf TRISA,DOUT
|
|
bcf STATUS,RP0
|
|
bsf PORTA,DOUT
|
|
|
|
endss:
|
|
return
|
|
|
|
; waits for the clock (PORTA,CIN) to change from
|
|
; low to high
|
|
wcup:
|
|
btfss PORTA,CIN
|
|
goto wcup
|
|
return
|
|
|
|
; waits for the clock (PORTA,CIN) to change from
|
|
; high to low
|
|
wcdown:
|
|
btfsc PORTA,CIN
|
|
goto wcdown
|
|
return
|
|
|
|
; waits for data (PORTA,DIN) to change
|
|
; from low to high
|
|
wdup:
|
|
btfss PORTA,DIN
|
|
goto wdup
|
|
return
|
|
|
|
; waits for data (PORTA,DIN) to change
|
|
; from high to low
|
|
wddown:
|
|
btfsc PORTA,DIN
|
|
goto wddown
|
|
return
|
|
|
|
; error in start bit reception (difference from
|
|
; STBIT constant)
|
|
; sets alternately 1 and 0 on RB0 8 times, with a period
|
|
; of about 0.2 sec, about 1 sec in the whole
|
|
estb:
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
movlw 08H
|
|
movwf count
|
|
|
|
cycle2:
|
|
movlw 00H
|
|
movwf delay1
|
|
movwf delay2
|
|
btfss count,0
|
|
goto ozero
|
|
goto ouno
|
|
|
|
ozero:
|
|
bcf PORTB,RB0
|
|
goto cycle3
|
|
|
|
ouno:
|
|
bsf PORTB,RB0
|
|
|
|
cycle3:
|
|
decfsz delay1
|
|
goto cycle3
|
|
decfsz delay2
|
|
goto cycle3
|
|
decfsz count
|
|
goto cycle2
|
|
bcf PORTB,RB0
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
return
|
|
|
|
; error in start bit reception (difference from
|
|
; STBIT constant)
|
|
; sets alternately 1 and 0 on RB0 16 times, with a period
|
|
; of about 0.1 sec, about 1.5 sec in the whole
|
|
eparb:
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
movlw 10H
|
|
movwf count
|
|
|
|
cycle4:
|
|
movlw 00H
|
|
movwf delay1
|
|
movlw 80H
|
|
movwf delay2
|
|
btfss count,0
|
|
goto ozero1
|
|
goto ouno1
|
|
|
|
ozero1:
|
|
bcf PORTB,RB0
|
|
goto cycle5
|
|
|
|
ouno1:
|
|
bsf PORTB,RB0
|
|
|
|
cycle5:
|
|
decfsz delay1
|
|
goto cycle5
|
|
decfsz delay2
|
|
goto cycle5
|
|
decfsz count
|
|
goto cycle5
|
|
bcf PORTB,RB0
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
return
|
|
|
|
; error in stop bit reception (difference from
|
|
; ENDBIT constant);
|
|
; sets alternately 1 and 0 on RB0 32 times, with a period
|
|
; of about 0.05 sec, about 1.5 sec in the whole
|
|
eendb:
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
movlw 20H
|
|
movwf count
|
|
|
|
cycle6:
|
|
movlw 00H
|
|
movwf delay1
|
|
movlw 40H
|
|
movwf delay2
|
|
btfss count,0
|
|
goto ozero2
|
|
goto ouno2
|
|
|
|
ozero2:
|
|
bcf PORTB,RB0
|
|
goto cycle7
|
|
|
|
ouno2:
|
|
bsf PORTB,RB0
|
|
|
|
cycle7:
|
|
decfsz delay1
|
|
goto cycle7
|
|
decfsz delay2
|
|
goto cycle7
|
|
decfsz count
|
|
goto cycle6
|
|
bcf PORTB,RB0
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
return
|
|
|
|
; command sent - sets alternately 1 and 0 on RB0 2 times,
|
|
; with a period of
|
|
; about 0.5 sec, about 1 sec in the whole
|
|
cmdsnt:
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
movlw 02H
|
|
movwf count
|
|
|
|
cycle8:
|
|
movlw 00H
|
|
movwf delay1
|
|
movlw 00H
|
|
movwf delay2
|
|
movlw 02H
|
|
movwf delay3
|
|
btfsc count,0
|
|
goto ozero3
|
|
goto ouno3
|
|
|
|
ozero3:
|
|
bcf PORTB,RB0
|
|
goto cycle9
|
|
|
|
ouno3:
|
|
bsf PORTB,RB0
|
|
|
|
cycle9:
|
|
decfsz delay1
|
|
goto cycle9
|
|
decfsz delay2
|
|
goto cycle9
|
|
decfsz delay3
|
|
goto cycle9
|
|
decfsz count
|
|
goto cycle8
|
|
bcf PORTB,RB0
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
return
|
|
|
|
; receives in byteo and byteio the byte to send
|
|
sendby:
|
|
bcf STATUS,RP0
|
|
bsf PORTB,0
|
|
bsf STATUS,RP0
|
|
bcf TRISB,0
|
|
bcf STATUS,RP0
|
|
; forces clock to 0 and waits about 200 us
|
|
; in order to do this, sets to 0 and configures
|
|
; the pin PORTA,COUT as an output
|
|
bcf STATUS,RP0
|
|
bcf PORTA,COUT
|
|
bsf STATUS,RP0
|
|
bcf TRISA,COUT
|
|
bcf STATUS,RP0
|
|
; puts 42H in delay1 (about 200 us)
|
|
movlw 42H
|
|
movwf delay1
|
|
|
|
cycle1:
|
|
decfsz delay1
|
|
goto cycle1
|
|
movlw STBIT
|
|
call outbit
|
|
; releases clock
|
|
bsf STATUS,RP0
|
|
bsf TRISA,COUT
|
|
bcf STATUS,RP0
|
|
bsf PORTA,COUT
|
|
call wcup
|
|
call wcdown
|
|
movlw 08H
|
|
movwf cbit
|
|
|
|
detbit:
|
|
bcf STATUS,C
|
|
rrf byteo,F
|
|
btfss STATUS,C
|
|
goto bitz
|
|
goto bituno
|
|
|
|
bitz:
|
|
movlw 00H
|
|
goto callob
|
|
|
|
bituno:
|
|
movlw 01H
|
|
callob
|
|
call outbit
|
|
call wcup
|
|
call wcdown
|
|
decfsz cbit
|
|
goto detbit
|
|
call pargen
|
|
movf parbit,W
|
|
; TESTS PARITY INVERSION
|
|
xorlw 00000001B
|
|
call outbit
|
|
call wcup
|
|
call wcdown
|
|
movlw ENDBIT
|
|
call outbit
|
|
call wddown
|
|
call wcdown
|
|
call wdup
|
|
call wcup
|
|
return
|
|
|
|
; delay routine of about 1 ms
|
|
del1ms:
|
|
movlw 02H
|
|
movwf delay2
|
|
movlw 0A0H
|
|
movwf delay1
|
|
|
|
cyc21:
|
|
decfsz delay1
|
|
goto cyc21
|
|
decfsz delay2
|
|
goto cyc21
|
|
return
|
|
|
|
; delay routine of about 10 ms
|
|
del10m:
|
|
movlw 0DH
|
|
movwf delay2
|
|
movlw 00H
|
|
movwf delay1
|
|
|
|
cyc51:
|
|
decfsz delay1
|
|
goto cyc51
|
|
decfsz delay2
|
|
goto cyc51
|
|
return
|
|
|
|
; delay routine of about 100 ms
|
|
del.1s:
|
|
movlw 0A0H
|
|
movwf delay2
|
|
movlw 00H
|
|
movwf delay1
|
|
|
|
cyc41:
|
|
decfsz delay1
|
|
goto cyc41
|
|
decfsz delay2
|
|
goto cyc41
|
|
return
|
|
|
|
; delay routine of about 1 s
|
|
del1s:
|
|
movlw 05H
|
|
movwf delay3
|
|
movlw 00H
|
|
movwf delay2
|
|
movwf delay1
|
|
|
|
cyc11:
|
|
decfsz delay1
|
|
goto cyc11
|
|
decfsz delay2
|
|
goto cyc11
|
|
decfsz delay3
|
|
goto cyc11
|
|
return
|
|
|
|
; indicates that a command is about to be sent - sets RB0
|
|
; to 1 with a pulse of about 0.1 sec and then
|
|
; 0 for 0.1 sec
|
|
cmdts:
|
|
bsf STATUS,RP0
|
|
bcf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
bsf PORTB,RB0
|
|
movlw 00H
|
|
movwf delay1
|
|
movlw 00H
|
|
movwf delay2
|
|
|
|
cyc31:
|
|
decfsz delay1
|
|
goto cyc31
|
|
decfsz delay2
|
|
goto cyc31
|
|
bcf PORTB,RB0
|
|
bsf STATUS,RP0
|
|
bsf TRISB,RB0
|
|
bcf STATUS,RP0
|
|
call del.1s
|
|
return
|
|
|
|
fine:
|
|
END
|