pic16f628a.asm
author Darron Broad <darron@kewl.org>
Tue, 17 Mar 2015 13:14:16 +0000
changeset 4 3cc6dec8e034
parent 3 afdddd3dd093
permissions -rw-r--r--
update license, clean up headers. prepare to add to wiki
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (C) 2013-2015 Darron Broad
; All rights reserved.
; 
; This file is part of PC Pointer
; 
; PC Pointer 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. 
; 
; PC Pointer 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 PC Pointer. If not, see http://www.gnu.org/licenses/
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PIC16F627A/628A/628A PS/2 to Serial protocol mouse converter
;
; TEST MOUSE #1 GENIUS GM-050021 TRAVELER 320 OPTICAL MOUSE
; TEST MOUSE #2 EXCEL AM-1310U+P MINI OPTICAL MOUSE
;
; JUMPERS 1..4
; ------------
;
;  1 RB4 ALGORITHM  0=DIVIDE 1=LIMIT
;    USE DIVIDE MODE FOR TEST MOUSE #1
;    USE LIMIT  MODE FOR TEST MOUSE #2
;    APPLIED IN REAL-TIME
;
;  2 RB5 SCALING    0=1:1 1=2:1
;    THIS SETTING APPEARED TO HAVE NO IMPACT ON THE TEST MICE
;    APPLIED AFTER RESET OR HOST INITIATED REINIT
;
;  3 RB6 RESOLUTION B'00XXXXXX'=1 B'01XXXXXX'=2 counts/millimeter
;  4 RB7 RESOLUTION B'10XXXXXX'=4 B'11XXXXXX'=8 counts/millimeter
;    THIS SETTING APPEARED TO HAVE NO IMPACT ON THE TEST MICE
;    APPLIED AFTER RESET OR HOST INITIATED REINIT
;
; TEST PLATFORMS
; --------------
;
;   WORKING
;   -------
;   MS-DOS MICROSOFT MOUSE 8.20 & 9.01
;   WINDOWS 98SE
;   WINDOWS XP
;   LINUX GPM
;
;   NOT WORKING
;   -----------
;   MS-DOS LOGITECH
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 2048 words Flash (14-bit)
; 224 bytes RAM
; 128 bytes EEPROM
;
; Pinout
; ------
; RA2 AN2   VREF 1----18 RA1 AN1
; RA3 AN3   CMP1 2    17 RA0 AN0
; RA4 T0CKI CMP2 3    16 RA7 OSC1  CLKIN
; RA5 !MCLR VPP  4    15 RA6 OSC2  CLKOUT
; VSS GND        5    14 VDD VCC
; RB0 INT        6    13 RB7 T1OSI PGD
; RB1 RX    DT   7    12 RB6 T1OSO T1CKI PGC
; RB2 TX    CK   8    11 RB5
; RB3 CCP1       9----10 RB4 PGM
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
                LIST    P=PIC16F628A
                ERRORLEVEL -302
#INCLUDE        "p16f628a.inc"
#INCLUDE        "device.inc"                ;DEVICE CONFIG
#INCLUDE        "const.inc"                 ;CONSTANTS
#INCLUDE        "macro.inc"                 ;MACROS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Config
;
  __CONFIG _CP_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Constants
;
                __IDLOCS 0x1234
;
; INTOSC = 4MHz
                CONSTANT CLOCK = 4000000
;
; ASYNC BAUD RATE (BRGH = 0) SPBRG = FOSC / BAUD RATE / 64 - 1
;
; BAUD RATE
                CONSTANT SPEED = CLOCK / 1200 / 64 - 1
;
; MOUSE SAMPLE RATE
                CONSTANT SAMPLERATE = 20    ;20 SAMPLES/SECOND AT 1200 BAUD
;
                CONSTANT PS2OPTIONS = 1     ;ENABLE/DISABLE PS/2 OPTIONS ON RB5/RB6/RB7
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Variables
;
                CBLOCK  0x20                ;RAM 0x20..0x6F
                MOUSESW
                MOUSEDX
                MOUSEDY
                ENDC
#INCLUDE        "shadow.inc"
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Begin
;
; INTEDG takes a branch to REINIT and there is no return from interrupt.
; Stack overflow is unimportant.
;
                ORG     0x0000
                GOTO    INIT                ;RESET
                ORG     0x0004
                GOTO    REINIT              ;INTEDG
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PS/2 mouse support
;
#INCLUDE        "delay.inc"                 ;DELAY COUNTERS
#INCLUDE        "ps2.inc"                   ;PS/2 PROTOCOL
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Initialise
;
INIT            BANKSEL BANK0

                MOVLW   B'10101000'
                MOVWF   LATA                ;INIT PORT A SHADOW
                MOVWF   PORTA               ;INIT PORT A

REINIT          BANKSEL BANK0

                MOVLW   5                   ;5ms PAUSE ON RESET/REINIT
                CALL    DELAYM

                MOVF    LATA,W              ;TOGGLE TEST LED(S)
                XORLW   B'11111100'
                MOVWF   LATA
                MOVWF   PORTA

                MOVLW   B'00000000'
                MOVWF   LATB                ;INIT PORT B SHADOW
                MOVWF   PORTB               ;INIT PORT B

                CLRF    INTCON              ;DISABLE INTERRUPTS
                CLRF    PIR1                ;CLEAR INTERRRUPT FLAGS

                MOVLW   B'00000111'         ;DISABLE COMPARATORS
                MOVWF   CMCON

                BANKSEL BANK1

                CLRF    PIE1                ;DISABLE PERIPHERAL INTERRUPTS

                MOVLW   B'00001111'         ;ENABLE PULL-UPS & INIT INTEDG FALLING
                MOVWF   OPTION_REG

                MOVLW   B'00000011'         ;PORT A RA0/RA1 PS/2 INPUT OTHERS TEST LED O/P
                MOVWF   TRISA               ;INIT TRISA

                MOVLW   B'11111111'         ;PORT B ALL I/P
                MOVWF   TRISB               ;INIT TRISB
;UART
                MOVLW   LOW SPEED           ;BAUD RATE GENERATOR SPEED
                MOVWF   SPBRG

                MOVLW   1<<TXEN             ;TX ENABLE
                MOVWF   TXSTA

                BANKSEL BANK0

                MOVLW   1<<SPEN | 1<<CREN   ;UART ENABLE + CONTINUOUS RX
                MOVWF   RCSTA

                MOVF    RCREG,W             ;DISCARD
                MOVF    RCREG,W             ;DISCARD
;INT
                MOVLW   B'10010000'         ;INTEDG ENABLED
                MOVWF   INTCON
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Send serial mouse identification
; 
                MOVLW   'M'                 ;I'M A SERIAL MOUSE
                CALL    TRANSMIT
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PS/2 Init
; 
PS2INIT
;STOP!
                MOVLW   PS2_CMD_RESET_DIS
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
;RESET
                MOVLW   PS2_CMD_RESET_BAT
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
                CALL    PS2RECEIVE          ;AA
                BTFGS   STATUS,C,PS2INIT
                CALL    PS2RECEIVE          ;00
                BTFGS   STATUS,C,PS2INIT
;SET SAMPLE RATE
                MOVLW   PS2_CMD_SETRATE
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
                MOVLW   SAMPLERATE
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
#IF PS2OPTIONS == 1
;SET RESOLUTION
                MOVLW   PS2_CMD_SETRES
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
                MOVLW   0
                BTFSC   PORTB,6
                IORLW   1
                BTFSC   PORTB,7
                IORLW   2
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
;SET SCALING
                MOVLW   PS2_CMD_SETSCALE11
                BTFSC   PORTB,5
                MOVLW   PS2_CMD_SETSCALE21
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
#ENDIF
;GO!
                MOVLW   PS2_CMD_ENABLE
                CALL    PS2SEND             ;FA
                BTFGS   STATUS,C,PS2INIT
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Main loop
;
MAINLOOP
;GET PS/2 PACKET
                CALL    PS2RECEIVE          ;SWITCHES
                BTFGS   STATUS,C,MAINLOOP
                MOVF    BUFFER,W
                MOVWF   MOUSESW

                CALL    PS2RECEIVE          ;DX
                BTFGS   STATUS,C,PS2INIT
                MOVF    BUFFER,W
                MOVWF   MOUSEDX

                CALL    PS2RECEIVE          ;DY
                BTFGS   STATUS,C,PS2INIT
                MOVF    BUFFER,W
                MOVWF   MOUSEDY
;SEND MS MOUSE CONVERSION
                CALL    MSM
;REPEAT
                GOTO    MAINLOOP
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; RS-232 transmit
;
TRANSMIT        BTFSS   PIR1,TXIF           ;WAIT FOR TX
                GOTO    TRANSMIT
                MOVWF   TXREG               ;SEND DATA
                RETURN
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Microsoft mouse conversion
;
MSM             BTFSC   PORTB,4             ;0=DIVIDE 1=LIMIT
                GOTO    LIMIT
DIVIDE
;ARITHMETIC SHIFT RIGHT X
                BCF     STATUS,C
                BTFSC   MOUSESW,4           ;SIGN X
                BSF     STATUS,C
                RRF     MOUSEDX,F
;ARITHMETIC SHIFT RIGHT Y
                BCF     STATUS,C
                BTFSC   MOUSESW,5           ;SIGN Y
                BSF     STATUS,C
                RRF     MOUSEDY,F
                GOTO    COMDY
LIMIT
;IF X < -128
;   LET X = -128
;ELSE IF X > 127 
;   LET X = 127
;ENDIF
                MOVLW   0xFF
                BTFSC   MOUSESW,4           ;SIGN X
                XORWF   MOUSEDX,F           ;INVERT X
                MOVLW   0x7F
                BTFSC   MOUSEDX,7
                MOVWF   MOUSEDX             ;LIMIT X
                MOVLW   0xFF
                BTFSC   MOUSESW,4           ;SIGN X
                XORWF   MOUSEDX,F           ;INVERT X
;IF Y < -128
;   LET Y = -128
;ELSE IF Y > 127 
;   LET Y = 127
;ENDIF
                MOVLW   0xFF
                BTFSC   MOUSESW,5           ;SIGN Y
                XORWF   MOUSEDY,F           ;INVERT Y
                MOVLW   0x7F
                BTFSC   MOUSEDY,7
                MOVWF   MOUSEDY             ;LIMIT Y
                MOVLW   0xFF
                BTFSC   MOUSESW,5           ;SIGN Y
                XORWF   MOUSEDY,F           ;INVERT Y
COMDY
;IF Y == -128
;   LET Y = 127
;ELSE
;   LET Y = !Y + 1
;ENDIF
                MOVF    MOUSEDY,W
                XORLW   0x80
                BNZ     COMDY1 

                MOVLW   0x7F                ;Y = 127
                MOVWF   MOUSEDY
                GOTO    COMDY2
COMDY1
                MOVLW   0xFF                ;Y = !Y + 1
                XORWF   MOUSEDY,F
                INCF    MOUSEDY,F
COMDY2
                MOVLW   B'11000000'         ;D6=1 D7=1=STOP BIT
                BTFSC   MOUSESW,0           ;LEFT BUTTON PRESSED
                IORLW   B'00100000'
                BTFSC   MOUSESW,1           ;RIGHT BUTTON PRESSED
                IORLW   B'00010000'

                BTFSC   MOUSEDX,6           ;X6
                IORLW   B'00000001'
                BTFSC   MOUSEDX,7           ;X7
                IORLW   B'00000010'
                BTFSC   MOUSEDY,6           ;Y6
                IORLW   B'00000100'
                BTFSC   MOUSEDY,7           ;Y7
                IORLW   B'00001000'
                CALL    TRANSMIT            ;SEND

                MOVF    MOUSEDX,W           ;X0..X5
                ANDLW   B'00111111'         ;D6=0
                IORLW   B'10000000'         ;D7=1=STOP BIT
                CALL    TRANSMIT            ;SEND

                MOVF    MOUSEDY,W           ;Y0..Y5
                ANDLW   B'00111111'         ;D6=0
                IORLW   B'10000000'         ;D7=1=STOP BIT
                GOTO    TRANSMIT            ;SEND
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; vim: shiftwidth=4 tabstop=4 softtabstop=4 expandtab
;