]> git.sur5r.net Git - cc65/blobdiff - libsrc/c128/mou/c128-pot.s
Merge pull request #249 from polluks/master
[cc65] / libsrc / c128 / mou / c128-pot.s
index ab69228968c655c075b89dfe133a520aba0d4d14..f61f88d5d78684e81b906f20c549edc517d2b8f5 100644 (file)
@@ -1,8 +1,10 @@
 ;
-; 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:
 
@@ -25,7 +29,7 @@ HEADER:
 
 ; Library reference
 
-        .addr   $0000
+libref: .addr   $0000
 
 ; Jump table
 
@@ -42,10 +46,16 @@ HEADER:
         .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
 
@@ -80,21 +90,28 @@ XMax:           .res    2               ; X2 value of bounding box
 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
 
@@ -107,6 +124,14 @@ Temp:           .res    1
 
 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
@@ -127,6 +152,47 @@ INSTALL:
         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)
@@ -139,7 +205,18 @@ INSTALL:
 ; 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
@@ -237,6 +314,15 @@ MOVE:   sei                             ; No interrupts
 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
 
 ;----------------------------------------------------------------------------
@@ -275,7 +361,7 @@ INFO:   jsr     POS
 
 ; Fill in the button state
 
-        lda     Buttons
+        jsr     BUTTONS
         ldy     #MOUSE_INFO::BUTTONS
         sta     (ptr1),y
 
@@ -287,7 +373,7 @@ INFO:   jsr     POS
 ; 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
 
@@ -296,22 +382,18 @@ IOCTL:  lda     #<MOUSE_ERR_INV_IOCTL     ; We don't support ioclts for now
 ; (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
@@ -391,4 +473,10 @@ IRQ:    lda     #$7F
 ; 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"