PS2 Mouse Interpreter


Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Aug 2003
    Posts
    985

    Default PS2 Mouse Interpreter

    Hi Guys
    I’ve been playing with this PS2 Mouse to Amiga mouse port translator,
    so I thought I might as well wrap it in BASIC to compile it, and it can be used if needed.

    It’s essentially still assembler in the manner DT’s Elapsed Timer code is.
    You can still access variables from PBP code.
    It receives packets from the mouse, converts to pulses for vintage Commodore Amiga computers.
    The PS2 (3 byte packets) are easy enough to interpret, but I have left the Amiga output code as well.
    The Amiga expects mouse buttons to be individual pins, so it physically converts back to individual button signals.



    There are some important notes to go with this:
    1. The schematic is correct other than portB.2 is used for hardware serial out.
    2. The Amiga mouse port connector need not be connected for use with PBP, other than the circuit needs power of course.
    3. The PS2 main routine should become a subroutine which will only be practical in a real time cyclic program.
    You can’t neglect to repeditively call the code, or the mouse will not be responsive.
    4. Timing is important for the PS2 reading routine. I have not even tried a 4MHz crystal.
    5. Configuration for the demo I will show later are: WDT OFF, BOD OFF, XT Clock, Powerup delay ENABLE.
    6. Decoded PS2 serial packets are re-encoded to 2400 8N1 and passed out the hardware serial port.
    7. The middle button is disabled if present. Instead, while the middle button is held, the left & right
    buttons provide two additional outputs.
    8. Blocking HPWM (multiple bytes send in one command) loses mouse responsiveness.
    It’s just a cool way to demonstrate, and is easy to set up and look at with a serial terminal program
    and real mouse port for viewing both outputs on one screen at the same time!

    Enjoy

    Cheers, Art.
    Last edited by Art; - 3rd December 2015 at 13:05.

  2. #2
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: PS2 Mouse Interpreter

    Code...

    YouTube video demo to follow shortly, where the code was compiled with PBP.

    Code:
    '
    '***********************************************************************************
    '*                                                                                 *
    '*                           PS2 Mouse Interpreter                                 *
    '*                                                                                 *
    '*                       Microchip Pic 16F628 @ 3.57MHz                            *
    '*                                                                                 *
    '***********************************************************************************
    '
    '
    DEFINE OSC 3								'
    DEFINE NO_CLRWDT							' watchdog is cleared manually
    '				
    DEFINE HSER_RCSTA 90h	' enable hardware serial receiver
    DEFINE HSER_TXSTA 20h	' enable hardware serial transmitter (24h)	
    DEFINE HSER_BAUD 2400	'
    
    '
    ' -------------------------------------
    '  PS/2 Mouse to Amiga Mouse Converter
    '  v1.0 (30-Jun-2001)
    ‘  ported to 16F628A Brek Martin 2015.
    ' -------------------------------------
    
    '  Copyright 2001 Nevenko Baricevic
    
    
    '  This program is free software: you can redistribute it and/or modify
    '  it under the terms of the GNU General Public License as published by
    '  the Free Software Foundation, either version 3 of the License, or
    '  (at your option) any later version.
    
    '  This program is distributed in the hope that it will be useful,
    '  but WITHOUT ANY WARRANTY; without even the implied warranty of
    '  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    '  GNU General Public License for more details.
    
    '  You should have received a copy of the GNU General Public License
    '  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ‘
    ‘
    ‘ *** Pic Basic / Pro users don’t declare any variables before these
    ‘ *** to ensure the assembler variables are all placed in Bank 0.
    ‘
    ' ---------- registers definition -----------
    
    bytebuf var byte'            ; byte to receive or send
    parity var byte'             ; parity bit is held here
    parcnt var byte'             ; counter for calculating parity
    roller var byte'             ; help for 8 data bits to byte conversion
    pack1 var byte'              ; 1st byte of mouse data packet
    pack2 var byte'              ; 2nd byte of mouse data packet
    pack3 var byte'              ; 3rd byte of mouse data packet
    xrot var byte'               ; rotation byte for H and HQ
    yrot var byte'               ; rotation byte for V and VQ
    delcnt var byte'             ; delay counter
    serbufa var byte'			 ; serial output buffer
    serbufb var byte
    serbufc var byte
    
    ‘ --------- main routine -----------
    
    main:
    @   movlw	0x07
    @   movwf	CMCON
    @	bsf     STATUS,RP0      ; page 1
    @ 	bcf		TRISA,3			; new mouse output
    @   bsf     TRISA,2         ; port A, bit 2 is input
    @   bsf     TRISA,1         ; port A, bit 1 is input
    @   bcf		TRISA,0			; port A, bit 0 is output to LED
    @   clrf    TRISB           ; port B is all outputs
    @   bcf     STATUS,RP0      ; page 0
    @	bsf		PORTA,0
    @        movlw   0xff			; was ff
    @        movwf   PORTB           ; port B all pins to 1
    @        movlw   0x2d            ; put b'00101101' to xrot and yrot
    @        movwf   _xrot
    @        movwf   _yrot
    @        call    _REC             ; receive byte from mouse
    @        call    _INHIB           ; pull CLK low to inhibit furhter sending
    @        movf    _bytebuf,W
    @        xorlw   0xaa            ; if it's $AA mouse self test passed
    @        btfss   STATUS,Z
    @        goto    _IERROR
    @        call    _REL             ; release CLK (allow mouse to send)
    @        call    _REC             ; receive byte from mouse
    @        call    _INHIB
    @        movf    _bytebuf,W
    @        xorlw   0x00            ; mouse ID code should be $00
    @        btfss   STATUS,Z
    @        goto    _IERROR
    @        movlw   0xf4            ; "Enable Data Reporting" command to mouse
    @        movwf   _bytebuf
    @        call    _NEWPAR          ; get parity for $F4
    @        call    _REL
    @        call    _DEL200
    @        call    _SEND            ; send command to mouse
    @        call    _REC             ; receive acknowledge ($FA) from mouse)
    @        call    _INHIB
    @        movf    _bytebuf,W
    @        xorlw   0xfa
    @        btfss   STATUS,Z
    @        goto    _IERROR
    @        call    _REL
    CHK:
    @		 call    _REC             ; receive byte1 from mouse packet
    @        call    _INHIB
    @        movf    _bytebuf,W
    @        movwf   _pack1
    @        call    _REL
    @        call    _REC             ; receive byte2 from mouse packet
    @        call    _INHIB
    @        movf    _bytebuf,W
    @        movwf   _pack2
    @        call    _REL
    @        call    _REC             ; receive byte3 from mouse packet
    @        call    _INHIB
    @        movf    _bytebuf,W
    @        movwf   _pack3
    @        call    _CONV
    @        call    _REL
    @        goto    _CHK             ; receive another packet
    
    ' --------------------------------------------------------
    
    PERROR:
    @ nop
    RERROR:
    @ nop
    IERROR:
    @ nop
    E_LOOP:
    @ goto    _E_LOOP
    
    ' --------------------------------------------------------
    
    DEL10:
    @  nop                     ; delay 10us
    @  return
    DEL200:
    @	movlw   0x32            ; delay 200us
    @   movwf   _delcnt
    DEL2:
    @   decfsz  _delcnt
    @   goto    _DEL2
    @   return
    
    ' --------- byte receiving subroutine -------------
    
    REC:
    @    btfsc   PORTA,2         ; wait clock (start bit)
    @        goto    _REC
    RL1:
    @    btfss   PORTA,2
    @        goto    _RL1
    @        call    _RECBIT          ; receive 8 data bits
    @        call    _RECBIT
    @        call    _RECBIT
    @        call    _RECBIT
    @        call    _RECBIT
    @        call    _RECBIT
    @        call    _RECBIT
    @        call    _RECBIT
    RL2:
    @    btfsc   PORTA,2         ; receive parity bit
    @        goto    _RL2
    @        btfsc   PORTA,1
    @        goto    _RL3
    @        bcf     _parity,0
    RL4:
    @    btfss   PORTA,2         ; receive stop bit
    @        goto    _RL4
    STP:
    @    btfsc   PORTA,2
    @        goto    _STP
    @        btfss   PORTA,1
    @        goto    _RERROR
    RL8:
    @    btfss   PORTA,2
    @        goto    _RL8
    @        return
    RL3:
    @    bsf     _parity,0
    @        goto    _RL4
    
    ' ---------- bit receiving subroutine ------------
    
    RECBIT:
    @ btfsc   PORTA,2
    @        goto    _RECBIT
    @        movf    PORTA,W
    @        movwf   _roller
    @        rrf     _roller
    @        rrf     _roller
    @        rrf     _bytebuf
    RL5:
    @    	 btfss   PORTA,2
    @        goto    _RL5
    @        return
    
    ' ---------- subroutines -----------------
    
    INHIB:
    @		 call   _CLKLO           ; inhibit mouse sending (CLK low)
    @        call    _DEL200
    @        return
    REL:
    @    call    _CLKHI           ; allow mouse to send data
    @        return
    CLKLO:
    @  bsf     STATUS,RP0      ; CLK low
    @        bcf     TRISA,2
    @        bcf     STATUS,RP0
    @        bcf     PORTA,2
    @        return
    CLKHI:
    @  bsf     STATUS,RP0      ; CLK high
    @        bsf     TRISA,2
    @        bcf     STATUS,RP0
    @        return
    DATLO:
    @  bsf     STATUS,RP0      ; DATA low
    @        bcf     TRISA,1
    @        bcf     STATUS,RP0
    @        bcf     PORTA,1
    @        return
    DATHI:
    @  bsf     STATUS,RP0      ; DATA high
    @        bsf     TRISA,1
    @        bcf     STATUS,RP0
    @        return
    
    ' ------------- send to mouse --------------
    
    SEND:
    @  		 call    _INHIB           ; CLK low
    @        call    _DEL10
    @        call    _DATLO           ; DATA low
    @        call    _DEL10
    @        call    _REL             ; CLK high
    SL1:
    @    	 btfsc   PORTA,2         ; wait for CLK
    @        goto    _SL1
    @        call    _SNDBIT          ; send 8 data bits
    SS1:
    @    btfss   PORTA,2
    @        goto    _SS1
    SS2:
    @    btfsc   PORTA,2
    @        goto    _SS2
    @        call    _SNDBIT
    SS3:
    @    btfss   PORTA,2
    @        goto    _SS3
    SS4:
    @    btfsc   PORTA,2
    @        goto    _SS4
    @        call    _SNDBIT
    SS5:
    @    btfss   PORTA,2
    @        goto    _SS5
    SS6:
    @    btfsc   PORTA,2
    @        goto    _SS6
    @        call    _SNDBIT
    SS7:
    @    btfss   PORTA,2
    @        goto    _SS7
    SS8:
    @    btfsc   PORTA,2
    @        goto    _SS8
    @        call    _SNDBIT
    SS9:
    @    btfss   PORTA,2
    @        goto    _SS9
    SS10:
    @   btfsc   PORTA,2
    @        goto    _SS10
    @        call    _SNDBIT
    SS11:
    @   btfss   PORTA,2
    @        goto    _SS11
    SS12:
    @   btfsc   PORTA,2
    @        goto    _SS12
    @        call    _SNDBIT
    SS13:
    @   btfss   PORTA,2
    @        goto    _SS13
    SS14:
    @   btfsc   PORTA,2
    @        goto    _SS14
    @        call    _SNDBIT
    SS15:
    @   btfss   PORTA,2
    @        goto    _SS15
    SS16:
    @   btfsc   PORTA,2
    @        goto    _SS16
    @        call    _SNDPAR          ; send parity bit
    SS17:
    @   btfss   PORTA,2
    @        goto    _SS17
    SS18:
    @   btfsc   PORTA,2
    @        goto    _SS18
    @        call    _DATHI           ; release bus
    SL4:
    @	    btfss   PORTA,2
    @        goto    _SL4
    SL5:
    @	    btfsc   PORTA,2
    @        goto    _SL5
    @        btfsc   PORTA,1
    @        goto    _RERROR
    SL7:
    @		 btfss   PORTA,2
    @        goto    _SL7
    SL8:
    @	  	 btfss   PORTA,1
    @        goto    _SL8
    @        return
    
    ' -------------- subroutines --------------
    
    SNDBIT:
    @ 		 rrf     _bytebuf            ; send data bit
    @        btfsc   STATUS,C
    @        goto    _DHIGH
    @        call    _DATLO
    SL2:
    @   	 return
    DHIGH:
    @  		 call    _DATHI
    @        goto    _SL2
    SNDPAR:
    @		 btfsc   _parity,0        ; send parity bit
    @        goto    _PHIGH
    @        call    _DATLO
    SP1:
    @		 return
    PHIGH:
    @		 call    _DATHI
    @        goto    _SP1
    CLCPAR:
    @		 movlw   0               ; calculate parity bit
    @        movwf   _parcnt
    @        btfsc   _bytebuf,0
    @        incf    _parcnt
    @        btfsc   _bytebuf,1
    @        incf    _parcnt
    @        btfsc   _bytebuf,2
    @        incf    _parcnt
    @        btfsc   _bytebuf,3
    @        incf    _parcnt
    @        btfsc   _bytebuf,4
    @        incf    _parcnt
    @        btfsc   _bytebuf,5
    @        incf    _parcnt
    @        btfsc   _bytebuf,6
    @        incf    _parcnt
    @        btfsc   _bytebuf,7
    @        incf    _parcnt
    @        return
    NEWPAR:
    @		 call    _CLCPAR
    @        btfss   _parcnt,0
    @        goto    _PARONE
    @        bcf     _parity,0
    @        return
    PARONE:
    @		 bsf     _parity,0
    @        return
    CHKPAR:
    @		 call    _CLCPAR          ; check parity
    @        movf    _parcnt,W
    @        andlw   0x01
    @        movwf   _parcnt
    @        movf    _parity,W
    @        xorwf   _parcnt
    @        btfss   STATUS,Z
    @        return
    @        call    _PERROR
    @        return
    
    ' --------------- conversion to Amiga format --------------
    
    CONV:
    @		 btfsc   _pack1,0         ; left button
    @        goto    _LPRESS
    @        bsf     PORTB,6
    @		bsf PORTB,7
    CON1:
    @		 btfsc   _pack1,1         ; right button
    @        goto    _RPRESS
    @        bsf     PORTB,0
    @		bsf PORTA,0
    CON2:
    @		 btfsc   _pack1,2         ; middle button
    @        goto    _MPRESS
    @        bsf     PORTB,1
    
    MOVE:
    ‘ Pic BASIC / Pro code to send serial here
    serbufa = pack1'
    serbufb = pack2'
    serbufc = pack3'
    HSEROUT [" : ",BIN8 serbufa," ",BIN8 serbufb," ",BIN8 serbufc,13,10]
    ‘
    
    @		 movf    _pack2,W         ; movement conversion
    @        andlw   0xff
    @        btfss   STATUS,Z
    @        call    _MOVEX
    @        movf    _pack3,W
    @        andlw   0xff
    @        btfss   STATUS,Z
    @        call    _MOVEY
    @        return
    
    
    LPRESS: 
    @	bcf     PORTB,6
    @	btfsc _pack1,2
    @	bcf PORTB,7
    @        goto    _CON1
    
    RPRESS:
    @	bcf     PORTB,0
    @	btfsc _pack1,2
    @	bcf PORTA,0
    @        goto    _CON2
    
    
    MPRESS:
    @ bcf     PORTB,1
    @        goto    _MOVE
    MOVEX:
    @  btfss   _pack1,4
    @        goto    _LEFT
    @        goto    _RIGHT
    MOVEY:
    @  btfss   _pack1,5
    @        goto    _DOWN
    @        goto    _UP
    LEFT:
    @   call    _DEL200          ; send H and HQ for left movement
    @        rlf     _xrot
    @        btfss   STATUS,C
    @        goto    _LH0
    @        goto    _LH1
    LH0:
    @    bcf     _xrot,0
    @        bcf     PORTB,4
    @        goto    _LHQ
    LH1:
    @    bsf     _xrot,0
    @        bsf     PORTB,4
    LHQ:
    @    rlf     _xrot
    @        btfss   STATUS,C
    @        goto    _LHQ0
    @        goto    _LHQ1
    LHQ0:
    @   bcf     _xrot,0
    @        bcf     PORTA,3
    @        goto    _LONE
    LHQ1:
    @   bsf     _xrot,0
    @        bsf     PORTA,3
    LONE:
    @   decfsz  _pack2
    @        goto    _LEFT
    @        return
    RIGHT:
    @  call    _DEL200          ; send H and HQ for right movement
    @        rrf     _xrot
    @        btfss   STATUS,C
    @        goto    _RHQ0
    @        goto    _RHQ1
    RHQ0:
    @   bcf     _xrot,7
    @        bcf     PORTA,3
    @        goto    _RH
    RHQ1:
    @   bsf     _xrot,7
    @        bsf     PORTA,3
    RH:
    @     rrf     _xrot
    @        btfss   STATUS,C
    @        goto    _RH0
    @        goto    _RH1
    RH0:
    @    bcf     _xrot,7
    @        bcf     PORTB,4
    @        goto    _RONE
    RH1:
    @    bsf     _xrot,7
    @        bsf     PORTB,4
    RONE:
    @   incfsz  _pack2
    @        goto    _RIGHT
    @        return
    UP:
    @     call    _DEL200          ; send V and VQ for up movement
    @        rlf     _yrot
    @        btfss   STATUS,C
    @        goto    _UV0
    @        goto    _UV1
    UV0:
    @	    bcf     _yrot,0
    @        bcf     PORTB,5
    @        goto    _UVQ
    UV1:
    @	    bsf     _yrot,0
    @        bsf     PORTB,5
    UVQ:
    @	    rlf     _yrot
    @        btfss   STATUS,C
    @        goto    _UVQ0
    @        goto    _UVQ1
    UVQ0:
    @	   bcf     _yrot,0
    @        bcf     PORTB,3
    @        goto    _UONE
    UVQ1:
    @   bsf     _yrot,0
    @        bsf     PORTB,3
    UONE:
    @   incfsz  _pack3
    @        goto    _UP
    @        return
    DOWN:
    @   call    _DEL200          ; send V and VQ for down movement
    @        rrf     _yrot
    @        btfss   STATUS,C
    @        goto    _DVQ0
    @        goto    _DVQ1
    DVQ0:
    @   bcf     _yrot,7
    @        bcf     PORTB,3
    @        goto    _DV
    DVQ1:
    @   bsf     _yrot,7
    @        bsf     PORTB,3
    DV:
    @     rrf     _yrot
    @        btfss   STATUS,C
    @        goto    _DV0
    @        goto    _DV1
    DV0:
    @    bcf     _yrot,7
    @        bcf     PORTB,5
    @        goto    _DONE
    DV1:
    @    bsf     _yrot,7
    @        bsf     PORTB,5
    DONE:
    @   decfsz  _pack3
    @        goto    _DOWN
    @        return
    @        end
    ' --------------------------------------------------------
    Cheers, Art.

  3. #3
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: PS2 Mouse Interpreter

    Here is the YouTube example of it running (this was compiled within PBP).
    It’s slow to respond because the pic program isn’t looking at the mouse while sending
    31 or so serial bytes in a row at 2400 baud for every mouse movement.
    Without this it’s very responsive, which can be seen in previous videos.


Similar Threads

  1. PS2 wireless gamepad
    By ndalisay in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 17th August 2009, 03:46
  2. AT/PS2 Keybord - PIC Interface?
    By Kamikaze47 in forum Code Examples
    Replies: 73
    Last Post: - 9th August 2009, 17:10
  3. reducing shiftout clock freq and PS2/PC interfacing ....
    By wireless magic in forum mel PIC BASIC Pro
    Replies: 18
    Last Post: - 26th February 2008, 21:15
  4. PS2 Keyboard not funny !!
    By Jųan in forum General
    Replies: 1
    Last Post: - 20th December 2007, 23:13
  5. PS2 keyboard emulator
    By robertg in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 5th July 2007, 21:40

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts