;	1351 proportional mouse driver for the c128
;
;	commodore business machines, inc.   27oct86
;		by hedley davis and fred bowen

iirq	= $0314
vic	= $d000
sid	= $d400
cia	= $dc00
cia.ddr	= $dc02
potx	= sid+$19
poty	= sid+$1a

active	= $117e		;basic7.0 active sprite flag (0=inactive)

vicdata	= $11d6		;basic7.0 copy of vic register image
xpos	= vicdata+$00	;x position (lsb)
ypos	= vicdata+$01	;y position
xposmsb	= vicdata+$10	;x position (msb)

	*=$18f0

iirq2		*=*+2
opotx		*=*+1
opoty		*=*+1
newvalue	*=*+1
oldvalue	*=*+1
ciasave		*=*+1


	* = $1800

	jmp install.1	;install mouse in port 1
	jmp install.2	;install mouse in port 2
	jmp remove	;remove mouse wedge


install.1	ldx #0		;port 1 mouse
		.byte $2c

install.2	ldx #2		;port 2 mouse

	lda iirq+1	;install irq wedge
	cmp #>mirq.1
	beq 90$		;...branch if already installed!
	php
	sei

	lda iirq	;save current irq indirect for our exit
	sta iirq2
	lda iirq+1
	sta iirq2+1

	lda port,x	;point irq indirect to mouse driver
	sta iirq
	lda port+1,x
	sta iirq+1
	plp
90$	rts

port	.word mirq.1
	.word mirq.2


remove	lda iirq+1	;remove irq wedge
	cmp #>mirq.1
	bne 90$		;...branch if already removed!
	php
	sei
	lda iirq2	;restore saved indirect
	sta iirq
	lda iirq2+1
	sta iirq+1
	plp
90$	rts



mirq.2	lda #$80	;port2 mouse scan
	.byte $2c

mirq.1	lda #$40	;port1 mouse scan

	jsr setpot	;configure cia per .a
	bne 90$		;...oops- basic in control

	lda potx	;get delta values for x
	ldy opotx
	jsr movchk
	sty opotx

	clc		;modify low order xposition
	adc xpos
	sta xpos
	txa
	adc #$00
	and #%00000001
	eor xposmsb
	sta xposmsb

	lda poty	;get delta value for y
	ldy opoty
	jsr movchk
	sty opoty

	sec		;modify y position (decrease y for increase in pot)
	eor #$ff
	adc ypos
	sta ypos

	ldx ciasave	;restore keyboard
	stx cia

90$	jmp (iirq2)	;continue w/ irq operation



; movchk
;	entry	y = old value of pot register
;		a = currrent value of pot register
;	exit	y = value to use for old value
;		x,a = delta value for position
;

movchk	sty oldvalue	;save old & new values
	sta newvalue
	ldx #0		;preload x w/ 0

	sec		;a = mod64(new-old)
	sbc oldvalue
	and #%01111111	
	cmp #%01000000	;if a > 0
	bcs 50$
	lsr a		;   then a = a/2
	beq 80$		;      if a <> 0
	ldy newvalue	;         then y = newvalue
	rts		;              return

50$	ora #%11000000	;   else or-in high order bits
	cmp #$ff	;      if a <> -1
	beq 80$
	sec		;         then a = a/2
	ror a
	ldx #$ff	;              x = -1
	ldy newvalue	;              y = newvalue
	rts		;              return

80$	lda #0		;a = 0
	rts		;return w/ y = old value



setpot	ldx active	;is basic moving sprite 1?
	bne 20$		;...yes, we'll leave it alone (why not?)

	ldx cia		;save keyboard lines
	stx ciasave

	sta cia		;connect appropriate port to sid

	ldx #4
	ldy #$c7	;delay 4ms to let lines settle & get sync-ed
10$	dey 
	bne 10$
	dex
	bne 10$
20$	rts

	.end
