]> git.sur5r.net Git - cc65/commitdiff
Workaround for "phantom" key presses in the C128 "joystick" mouse driver.
authorChristian Groessler <chris@groessler.org>
Tue, 22 Apr 2014 13:48:49 +0000 (15:48 +0200)
committerChristian Groessler <chris@groessler.org>
Tue, 22 Apr 2014 13:49:48 +0000 (15:49 +0200)
libsrc/c128/mou/c128-joy.s
libsrc/c128/mouseref.s

index be0cf227beb989530f396261762a37b74bacb9e6..fb087c8fc98a9b3536e7ec6d9fe333453f447d31 100644 (file)
@@ -11,6 +11,8 @@
 
         .macpack        generic
 
+IRQInd  = $2FD
+
 ; ------------------------------------------------------------------------
 ; Header. Includes jump table
 
@@ -25,6 +27,7 @@ HEADER:
 
 ; Library reference
 
+libref:
         .addr   $0000
 
 ; Jump table
@@ -70,6 +73,15 @@ SCREEN_WIDTH    = 320
         FIRE    = $10
 .endenum
 
+;----------------------------------------------------------------------------
+; data segment
+
+.data
+
+chainIRQ:
+        .byte   $4c                     ; JMP opcode
+        .word   0                       ; pointer to ROM IRQ handler (will be set at runtime)
+
 ;----------------------------------------------------------------------------
 ; Global variables. The bounding box values are sorted so that they can be
 ; written with the least effort in the SETBOX and GETBOX routines, so don't
@@ -92,6 +104,10 @@ INIT_save:      .res    1
 
 Temp:           .res    1
 
+; Keyboard buffer fill level at start of interrupt
+
+old_key_count:  .res    1
+
 .rodata
 
 ; Default values for above variables
@@ -146,6 +162,35 @@ INSTALL:
         jsr     CMOVEY
         cli
 
+; Initialize our IRQ magic
+
+        lda     IRQInd+1
+        sta     chainIRQ+1
+        lda     IRQInd+2
+        sta     chainIRQ+2
+        lda     libref
+        sta     ptr3
+        lda     libref+1
+        sta     ptr3+1
+        ldy     #2
+        lda     (ptr3),y
+        sta     IRQInd+1
+        iny
+        lda     (ptr3),y
+        sta     IRQInd+2
+        iny
+        lda     #<(callback-1)
+        sta     (ptr3),y
+        iny
+        lda     #>(callback-1)
+        sta     (ptr3),y
+        iny
+        lda     #<(chainIRQ-1)
+        sta     (ptr3),y
+        iny
+        lda     #>(chainIRQ-1)
+        sta     (ptr3),y
+
 ; Done, return zero (= MOUSE_ERR_OK)
 
         ldx     #$00
@@ -157,6 +202,12 @@ INSTALL:
 ; No return code required (the driver is removed from memory on return).
 
 UNINSTALL:
+
+        lda     chainIRQ+1
+        sta     IRQInd+1
+        lda     chainIRQ+2
+        sta     IRQInd+2
+
         jsr     HIDE                    ; Hide cursor on exit
         lda     INIT_save
         sta     INIT_STATUS
@@ -320,6 +371,8 @@ IOCTL:  lda     #<MOUSE_ERR_INV_IOCTL     ; We don't support ioclts for now
 ;
 
 IRQ:    jsr     CPREP
+        lda     KEY_COUNT
+        sta     old_key_count
         lda     #$7F
         sta     CIA1_PRA
         lda     CIA1_PRB                ; Read joystick #0
@@ -436,3 +489,29 @@ IRQ:    jsr     CPREP
 @SkipY: jsr     CDRAW
         clc                             ; Interrupt not "handled"
         rts
+
+;----------------------------------------------------------------------------
+; Called after ROM IRQ handler has been run.
+; Check if there was joystick activity before and/or after the ROM handler.
+; If there was activity, discard the key presses since they are most
+; probably "phantom" key presses.
+
+callback:
+        ldx     old_key_count
+        cpx     KEY_COUNT
+        beq     @nokey
+
+        lda     Temp                    ; keypress before?
+        bne     @discard_key            ; yes, discard key
+
+        lda     #$7F
+        sta     CIA1_PRA
+        lda     CIA1_PRB                ; Read joystick #0
+        and     #$1F
+        eor     #$1F                    ; keypress after
+        beq     @nokey                  ; no, probably a real key press
+
+@discard_key:
+        stx     KEY_COUNT               ; set old keyboard buffer fill level
+
+@nokey: rts
index 90aeedf3abdb3e44b613e498d9b1a33672a128b4..29030307573972a7ed566941ff3eb09f5142ed8b 100644 (file)
@@ -4,6 +4,8 @@
 ; 2013-07-25, Greg King
 ;
 
+        .include        "c128.inc"
+
         .export         mouse_libref, _pen_adjuster
 
         .data
@@ -21,3 +23,70 @@ mouse_libref:                   ; generic label for mouse-kernel
 ;
 _pen_adjuster:
         .addr   $0000
+        .addr   IRQStub2
+callback:                       ; callback into mouse driver after ROM IRQ handler has been run
+        .addr   $0000           ; (filled in by mouse driver)
+jmp_rom_hdlr:                   ; "trampoline" to jump to ROM IRQ handler
+        .addr   $0000           ; (filled in by mouse driver)
+
+
+.segment        "LOWCODE"
+
+; Called from irq.s when it thinks it chains to the original handler.
+; ROM is banked in again. In order to call the callback we have to
+; bank it out one more time.
+
+IRQStub2:
+
+; Call ROM handler and prepare stack so that it will return to us.
+
+        ; setup fake IRQ stack frame which will return to "IRQCont"
+        lda     #>@IRQCont
+        pha
+        lda     #<@IRQCont
+        pha
+        php
+
+        ; mimic the contents saved on the stack by the ROM IRQ entry handler
+        pha                     ; A
+        pha                     ; X
+        pha                     ; Y
+        lda     #MMU_CFG_CC65   ; MMU configuration which will be active after the ROM handler returns
+        pha
+
+        ; push address of ROM handler on stack and jump to it
+        lda     jmp_rom_hdlr+1
+        pha
+        lda     jmp_rom_hdlr
+        pha
+        rts                     ; jump to ROM handler
+
+        ; our MMU configuration byte we pushed on the stack before (MMU_CFG_CC65) is now active
+
+@IRQCont:
+
+        ; call mouse driver callback routine
+        lda     #>(@IRQCont2-1)
+        pha
+        lda     #<(@IRQCont2-1)
+        pha
+        lda     callback+1
+        pha
+        lda     callback
+        pha
+        rts                     ; jump to callback routine
+
+@IRQCont2:
+        
+        ; return from interrupt
+        ; We could just jump to $FF33, but since I don't know whether this address is valid in all
+        ; ROM versions, duplicate that code here.
+
+        pla
+        sta     MMU_CR          ; MMU configuration register
+        pla
+        tay
+        pla
+        tax
+        pla
+        rti