;
-; Driver for a potentiometer "mouse" e.g. Koala Pad
+; Driver for a potentiometer "mouse", e.g. Koala Pad
;
-; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
-; Stefan Haubenthal, 2006-08-20
+; 2006-08-20, Stefan Haubenthal
+; 2009-09-26, Ullrich von Bassewitz
+; 2014-04-26, Christian Groessler
+; 2014-05-05, Greg King
;
.include "zeropage.inc"
.include "c128.inc"
.macpack generic
+ .macpack module
+
; ------------------------------------------------------------------------
; Header. Includes jump table
-.segment "JUMPTABLE"
+ module_header _c128_pot_mou
HEADER:
; Library reference
- .addr $0000
+libref: .addr $0000
; Jump table
.addr IOCTL
.addr IRQ
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
; Callback table, set by the kernel before INSTALL is called
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
+CPREP: jmp $0000 ; Prepare to move the cursor
+CDRAW: jmp $0000 ; Draw the cursor
CMOVEX: jmp $0000 ; Move the cursor to X coord
CMOVEY: jmp $0000 ; Move the cursor to Y coord
YMax: .res 2 ; Y2 value of bounding box
Buttons: .res 1 ; Button mask
-; Temporary value used in the int handler
+INIT_save: .res 1
-Temp: .res 1
+; Keyboard buffer fill level at start of interrupt
-; Default values for above variables
+old_key_count: .res 1
+
+; Original IRQ vector
+
+old_irq: .res 2
.rodata
+; Default values for above variables
+; (We use ".proc" because we want to define both a label and a scope.)
+
.proc DefVars
.word SCREEN_HEIGHT/2 ; YPos
.word SCREEN_WIDTH/2 ; XPos
.word 0 ; XMin
.word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
+ .word SCREEN_WIDTH - 1 ; XMax
+ .word SCREEN_HEIGHT - 1 ; YMax
.byte 0 ; Buttons
.endproc
INSTALL:
+; Disable the BASIC interpreter's interrupt-driven sprite-motion code.
+; That allows direct access to the VIC-IIe's sprite registers.
+
+ lda INIT_STATUS
+ sta INIT_save
+ lda #%11000000
+ sta INIT_STATUS
+
; Initialize variables. Just copy the default stuff over
ldx #.sizeof(DefVars)-1
lda YPos
ldx YPos+1
jsr CMOVEY
+
+; Initiate our IRQ magic.
+
+ ; Remember the ROM IRQ continuation address.
+ ldx IRQInd+2
+ lda IRQInd+1
+ stx old_irq+1
+ sta old_irq
+
+ lda libref
+ ldx libref+1
+ sta ptr3
+ stx ptr3+1
+
+ ; Set the ROM IRQ continuation address to point to the provided routine.
+ ldy #2
+ lda (ptr3),y
+ sta IRQInd+1
+ iny
+ lda (ptr3),y
+ sta IRQInd+2
+
+ ; Set the address of our IRQ callback routine.
+ ; Because it's called via "rts", we must use "address-1".
+ iny
+ lda #<(callback-1)
+ sta (ptr3),y
+ iny
+ lda #>(callback-1)
+ sta (ptr3),y
+
+ ; Set the ROM entry-point vector.
+ ; Because it's called via "rts", we must decrement it by one.
+ iny
+ lda old_irq
+ sub #<1
+ sta (ptr3),y
+ iny
+ lda old_irq+1
+ sbc #>1
+ sta (ptr3),y
cli
; Done, return zero (= MOUSE_ERR_OK)
; UNINSTALL routine. Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
-UNINSTALL = HIDE ; Hide cursor on exit
+UNINSTALL:
+ lda old_irq
+ ldx old_irq+1
+ sei
+ sta IRQInd+1
+ stx IRQInd+2
+ ;cli ; This will be done at end of HIDE
+
+ jsr HIDE ; Hide cursor on exit
+ lda INIT_save
+ sta INIT_STATUS
+ rts
;----------------------------------------------------------------------------
; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
BUTTONS:
lda Buttons
ldx #$00
+
+; Make the buttons look like a 1351 mouse.
+
+ and #JOY::LEFT | JOY::RIGHT
+ lsr a
+ lsr a
+ ;clc ; ("lsr" shifted zero into carry flag)
+ adc #%00001110 ; Shift bit 1 over to bit 4
+ and #MOUSE_BTN_LEFT | MOUSE_BTN_RIGHT
rts
;----------------------------------------------------------------------------
; Fill in the button state
- lda Buttons
+ jsr BUTTONS
ldy #MOUSE_INFO::BUTTONS
sta (ptr1),y
; Must return an error code in a/x.
;
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls for now
ldx #>MOUSE_ERR_INV_IOCTL
rts
; (so be careful).
;
-IRQ: lda #$7F
+IRQ: jsr CPREP
+ lda KEY_COUNT
+ sta old_key_count
+ lda #$7F
sta CIA1_PRA
lda CIA1_PRB ; Read port #1
- and #%00001100
- eor #%00001100 ; Make all bits active high
- asl
- sta Buttons
- lsr
- lsr
- lsr
- and #%00000001
- ora Buttons
+ eor #%11111111 ; Make all bits active high
sta Buttons
- ldx #%01000000
+
+ ldx #%01000000 ; Read port 1 paddles
stx CIA1_PRA
- ldy #0
+ ldy #<256
: dey
bne :-
ldx SID_ADConv1
; Move the mouse pointer to the new X pos
tya
- jmp CMOVEY
+ jsr CMOVEY
+ jsr CDRAW
+ clc ; Interrupt not "handled"
+ rts
+
+.define OLD_BUTTONS Buttons ; Tells callback.inc where the old port status is stored
+.include "callback.inc"