;*********************************************************************
;                           Mouse.asm
;           PC mouse to Atari mouse converter by Tom Kirk Nov/Dec 1998
;*********************************************************************
;
;          Enables a PC mouse to be used with an Atari computer using
;          the circuit in pcstmous.bmp with a PIC16C84 micrcontroller.


;************************ Input output usage ********************

; RA0 RXD Serial i/p
; RA1 Not Used
; RA2 Not used
; RA3 RTS o/p
; RA4 Not used

; RB0 XA o/p
; RB1 XB o/p
; RB2 YA o/p
; RB3 YB o/p
; RB4 Left button o/p
; RB5 Right button o/p
; RB6 Not used
; RB7 Not used
;*******************************************************************

;********* Register equates ************

indo    equ     00
rtcc    equ     01
pcl     equ     02
status  equ     03
fsr     equ     04
porta   equ     05
portb   equ     06
eedata  equ     08
eeadr   equ     09
pclath  equ     0ah
intcon  equ     0bh
opt     equ     01
trisa   equ     05
trisb   equ     06
eecon1  equ     08


;********** status bit equates ************

c       equ     0
dc      equ     1
z       equ     2
rp0     equ     5
rp1     equ     6
irp     equ     7


;********** I/O port equates **************

rxd	equ	0
rts	equ	3


;********** User register equates *********

temp    equ     0ch     ;Temporary storage
byte1	equ	0dh	;Byte 1 store
byte2	equ	0eh	;Byte 2 store
byte3	equ	0fh	;Byte 3 store
xinc	equ	010h	;last x increment read
yinc	equ	011h	;last y increment read
xlow	equ	012h	;low byte of 16 bit x counter
xhigh	equ	013h	;high byte of 16 bit x counter
ylow	equ	014h	;low byte of 16 bit y counter
yhigh	equ	015h	;high byte of 16 bit y counter
xpat	equ	016h	;x pattern position
ypat	equ	017h	;y pattern position
bcnt    equ     018h    ;bit counter
brec    equ     019h    ;rs232 byte received

;*****************************************************************************************

;***** initialise program *******

start   clrwdt
        bcf     status,rp0      ;set page0
        clrf    intcon          ;disable interupts
        bsf     status,rp0
        movlw   084h            ;set rtcc to int clk,prescale/32
        movwf   opt
        bcf     status,rp0
        clrf    porta           ;all porta outputs will be low when enabled
        movwf   porta
        movlw   030h            ;set atari mouse buttons and x y start levels
        movwf   portb
        bsf     status,rp0
        movlw   01h             ;set porta bit 0 as an input
        movwf   trisa
        movlw   0               ;set portb to all outputs
        movwf   trisb
        bcf     status,rp0

        clrf    byte1
        clrf    byte2
        clrf    byte3
        clrf    xinc
        clrf    yinc
        clrf    xlow
        clrf    xhigh
        clrf    ylow
        clrf    yhigh
        clrf    xpat
        clrf    ypat


;100 mS pulse on rts to reset mouse

	bsf	porta,rts	;set rts on rs232 low
        movlw   080h            ;wait for 100 mS
	movwf	temp
rwait   movlw   026h
        subwf   rtcc,w
        btfss   status,z
        goto    rwait           ;not done so jump
        clrf    rtcc            ;delay complete so restart rtcc
	decfsz	temp
	goto	rwait
        bcf     porta,rts       ;set rts on rs232 high


;****** main program loop ******


;get serial data

main    call    rs232           ;get byte from rs232
fbyte   btfss   brec,6          ;is it first byte?
        goto    main            ;no so do again
        movf    brec,w          ;yes so store byte
        movwf   byte1
        call    rs232           ;get second byte from rs232
        btfsc   brec,6          ;is it the first byte?
        goto    fbyte           ;yes so jump
        movf    brec,w          ;no so store byte
        movwf   byte2
        call    rs232           ;get third byte from rs232
        btfsc   brec,6          ;is it the first byte?
        goto    fbyte           ;yes so jump
        movf    brec,w          ;no so store byte
        movwf   byte3

;extract x increment

	movf	byte2,w		;mask low 6 bits of byte 2
	andlw	03fh
	movwf	xinc		;store in xinc
	movf	byte1,w		;rotate byte 1 low 2 bits into high 2 bits
	movwf	temp
	rrf	temp,f
	rrf	temp,f
	rrf	temp,w		
	andlw	0c0h		;mask the 2 high bits
	iorwf	xinc,f		;and merge with low 6 bits of byte 2

;extract y increment

	movf	byte3,w		;mask low 6 bits of byte 3
	andlw	03fh
	movwf	yinc		;store in yinc
	movf	byte1,w		;swap high and low nibbles of byte 1
	movwf	temp
	swapf	temp,w		
	andlw	0c0h		;mask the 2 high bits
	iorwf	yinc,f		;and merge with low 6 bits of byte 3

;adjust the 16 bit x counter

	clrf	temp		;use temp as high byte		
	btfsc	xinc,7		;extend sign bit into high byte
	decf	temp,f
	
	movf	xinc,w		;add low bytes
	addwf	xlow,f
	btfsc	status,c	;add carry to high
	incf	xhigh,f
	movf	temp,w		;add high bytes
	addwf	xhigh,f	

;adjust the 16 bit y counter

	clrf	temp		;use temp as high byte		
	btfsc	yinc,7		;extend sign bit into high byte
	decf	temp,f
	
	movf	yinc,w		;add low bytes
	addwf	ylow,f
	btfsc	status,c	;add carry to high
	incf	yhigh,f
	movf	temp,w		;add high bytes
	addwf	yhigh,f

;set the buttons

	btfss	byte1,5		;is the left pc mouse button pressed
	goto	lbutt		;no so jump
	bcf	portb,4		;set left atari button as pressed
	goto	nbutt
lbutt	bsf	portb,4		;set left atari button as not pressed

nbutt	btfss	byte1,4		;is the right pc mouse button pressed
	goto	rbutt		;no so jump
	bcf	portb,5		;set right atari button as pressed
        goto    main
rbutt	bsf	portb,5		;set right atari button as not pressed
        goto    main


;************************** subs *****************************************

;******* read rs232 data from pc mouse *****************************

rs232   btfss   porta,rxd       ;start bit from pc mouse ?
        goto    st1             ;yes so start reading data
        call    trans           ;no so do atari mouse move
        clrf    rtcc            ;clear rtcc before delay

oned    btfss   porta,rxd       ;start bit from pc mouse ?
        goto    st1             ;yes so sart reading data
        movlw   020h            ;1ms delay between mouse moves
        subwf   rtcc,w
        btfss   status,z
        goto    oned            ;not done so jump
        goto    rs232           ;check again

st1     clrf    rtcc            ;restart rtcc for delays
        call    waitb           ;wait for 1 bit time
        call    waith           ;wait for half bit time

        movlw   8               ;do 8 data bits
        movwf   bcnt

nbit    call    trans
        bcf     status,c        ;clear carry bit
        btfsc   porta,rxd       ;data bit set ?
        bsf     status,c        ;yes so set carry bit
        rrf     brec,f          ;shift carry into destination

        call    waitb           ;wait for 1 bit time
        decfsz  bcnt,f          ;finished the 8 bits?
        goto    nbit            ;no so do again
        retlw   0               ;yes so return

;********* atari mouse move ***************************

;move the mouse by one step in the x direction if needed  

trans   movf    xlow,w          ;is the x counter zero?
	iorwf	xhigh,w
	btfsc	status,z
	goto	ymove		;no so jump to y direction
	
	btfsc	xhigh,7		;is the x counter positive or negative?
	goto	xneg		;jump if negative
	
	incf	xpat,f		;increment the pattern list position
	movlw	04h		;test if end of pattern list
	subwf	xpat,w
	btfsc	status,z
	clrf	xpat		;end of pattern list so reset
	movlw	0ffh		;subtract 1 from the 16 bit counter by adding ffffh
	addwf	xlow,f
	btfsc	status,c	;add carry to high byte
	incf	xhigh,f			 
	addwf	xhigh,f
	goto	ymove		;exit to y direction

xneg	decf	xpat,f		;decrement the pattern list position
	movlw	0ffh		;test if end of pattern list
	subwf	xpat,w
	btfss	status,z
	goto	xno	
	movlw	03h		;end of pattern list so reset
	movwf	xpat
xno	movlw	01h		;add 1 to the 16 bit counter
	addwf	xlow,f
	btfsc	status,c	;add carry to high byte
	incf	xhigh,f			 

;move the mouse by one step in the y direction if needed  
	
ymove	movf	ylow,w		;is the y counter zero? 
	iorwf	yhigh,w
	btfsc	status,z
	goto	out		;no so jump to output pattern
	
	btfsc	yhigh,7		;is the y counter positive or negative?
	goto	yneg		;jump if negative
	
        decf    ypat,f          ;decrement the pattern list position
	movlw	0ffh		;test if end of pattern list
	subwf	ypat,w
	btfss	status,z
	goto	yno	
	movlw	03h		;end of pattern list so reset
	movwf	ypat
yno     movlw   0ffh            ;subtract 1 from the 16 bit counter by adding ffffh
	addwf	ylow,f
	btfsc	status,c	;add carry to high byte
	incf	yhigh,f			 
	addwf	yhigh,f
	goto	out		;exit to output pattern

yneg    incf    ypat,f          ;increment the pattern list position
	movlw	04h		;test if end of pattern list
	subwf	ypat,w
	btfsc	status,z
	clrf	ypat		;end of pattern list so reset
        movlw   01h             ;add 1 to the 16 bit counter
	addwf	ylow,f
	btfsc	status,c	;add carry to high byte
	incf	yhigh,f		

;output new x and y patterns to atari 	

out	movf	xpat,w		;get the x pattern bits
	call	pattx
	movwf	temp		;store the pattern in temp
	movf	ypat,w		;get the y pattern bits
	call	patty
	iorwf	temp		;store the pattern in temp
	
	movf	portb,w		;read port b
        andlw   0f0h            ;keep button state
	iorwf	temp,w		;merge with new x and y patterns
	movwf	portb		;ouput patterns to atari

        retlw   0


;********** delay timer ******************

waitb   movlw   01ah            ;wait for 1 bit time at 1200 baud
        movwf   temp            ;01ah (26) gives 0.832 mS
        goto    delay

waith   movlw   0dh             ;wait for 1/2 bit time at 1200 baud
        movwf   temp            ;0dh (13) gives 0.416 mS
delay   movf    temp,w          ;delay until rtcc equals temp
        subwf   rtcc,w
        btfss   status,z
        goto    delay           ;not done so jump
        clrf    rtcc            ;delay complete so restart rtcc

	retlw	0


;*************** pattern lists **************

pattx	addwf	pcl,f
	retlw	0
	retlw	1
	retlw	3
	retlw	2

patty	addwf	pcl,f
        retlw   0
        retlw   4
        retlw   0ch
        retlw   8
	


;*******************************************************************************

	END


