From 608dbc2cec5e9cc7e9e9b96c139d838837c7df3b Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Tue, 22 Apr 2014 15:48:49 +0200 Subject: [PATCH 1/4] Workaround for "phantom" key presses in the C128 "joystick" mouse driver. --- libsrc/c128/mou/c128-joy.s | 79 ++++++++++++++++++++++++++++++++++++++ libsrc/c128/mouseref.s | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index be0cf227b..fb087c8fc 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -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 #@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 From 4406307c2fee0e3e2369d03e38bf8c118c2393ac Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Thu, 24 Apr 2014 00:27:06 +0200 Subject: [PATCH 2/4] Make the hooking and unhooking of the interrupt interrupt safe. --- libsrc/c128/mou/c128-joy.s | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index fb087c8fc..339fdc836 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -160,7 +160,6 @@ INSTALL: lda YPos ldx YPos+1 jsr CMOVEY - cli ; Initialize our IRQ magic @@ -190,6 +189,7 @@ INSTALL: iny lda #>(chainIRQ-1) sta (ptr3),y + cli ; Done, return zero (= MOUSE_ERR_OK) @@ -202,11 +202,12 @@ INSTALL: ; No return code required (the driver is removed from memory on return). UNINSTALL: - lda chainIRQ+1 + sei sta IRQInd+1 lda chainIRQ+2 sta IRQInd+2 + cli jsr HIDE ; Hide cursor on exit lda INIT_save From 54be6de9bc0afa61b4f15e1f651832a614176852 Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Fri, 25 Apr 2014 00:21:41 +0200 Subject: [PATCH 3/4] Workaround for "phantom" key presses in the C128 "1351" mouse driver. --- libsrc/c128/mou/c128-1351.s | 74 ++++++++++++++++++++++++++++++++---- libsrc/c128/mou/c128-joy.s | 27 +------------ libsrc/c128/mou/callback.inc | 29 ++++++++++++++ 3 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 libsrc/c128/mou/callback.inc diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index 8aec3b7b7..c81ad04d0 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -12,6 +12,8 @@ .macpack generic +IRQInd = $2FD + ; ------------------------------------------------------------------------ ; Header. Includes jump table @@ -26,6 +28,7 @@ HEADER: ; Library reference +libref: .addr $0000 ; Jump table @@ -63,6 +66,15 @@ CMOVEY: jmp $0000 ; Move the cursor to Y coord SCREEN_HEIGHT = 200 SCREEN_WIDTH = 320 +;---------------------------------------------------------------------------- +; 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 @@ -85,6 +97,11 @@ OldValue: .res 1 ; Temp for MoveCheck routine NewValue: .res 1 ; Temp for MoveCheck routine INIT_save: .res 1 +Buttons: .res 1 ; Button mask + +; Keyboard buffer fill level at start of interrupt + +old_key_count: .res 1 .rodata @@ -138,6 +155,35 @@ INSTALL: lda YPos ldx YPos+1 jsr CMOVEY + +; 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 cli ; Done, return zero (= MOUSE_ERR_OK) @@ -151,6 +197,13 @@ INSTALL: ; No return code required (the driver is removed from memory on return). UNINSTALL: + lda chainIRQ+1 + sei + sta IRQInd+1 + lda chainIRQ+2 + sta IRQInd+2 + cli + jsr HIDE ; Hide cursor on exit lda INIT_save sta INIT_STATUS @@ -250,14 +303,8 @@ MOVE: sei ; No interrupts ; BUTTONS: Return the button mask in a/x. BUTTONS: - lda #$7F - sei - sta CIA1_PRA - lda CIA1_PRB ; Read joystick #0 - cli - ldx #0 - and #$1F - eor #$1F + lda Buttons + ldx #$00 rts ;---------------------------------------------------------------------------- @@ -320,6 +367,15 @@ IOCTL: lda # Date: Sat, 26 Apr 2014 11:55:24 +0200 Subject: [PATCH 4/4] Correctly map out ROM when needed in the "phantom keys" workaround. --- libsrc/c128/mou/c128-1351.s | 40 ++++++++++++++++++++++--------------- libsrc/c128/mou/c128-joy.s | 40 ++++++++++++++++++++++--------------- libsrc/c128/mouseref.s | 8 +++++++- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index c81ad04d0..e55c1d01b 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -66,15 +66,6 @@ CMOVEY: jmp $0000 ; Move the cursor to Y coord SCREEN_HEIGHT = 200 SCREEN_WIDTH = 320 -;---------------------------------------------------------------------------- -; 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 @@ -103,6 +94,10 @@ Buttons: .res 1 ; Button mask old_key_count: .res 1 +; original IRQ vector + +old_irq: .res 2 + .rodata ; Default values for above variables @@ -158,20 +153,27 @@ INSTALL: ; Initialize our IRQ magic - lda IRQInd+1 - sta chainIRQ+1 + ; remember ROM IRQ continuation address lda IRQInd+2 - sta chainIRQ+2 + sta old_irq+1 + lda IRQInd+1 + sta old_irq + lda libref sta ptr3 lda libref+1 sta ptr3+1 + + ; set 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 address of our IRQ callback routine + ; since it's called via "rts" we have to use "address-1" iny lda #<(callback-1) sta (ptr3),y @@ -179,10 +181,16 @@ INSTALL: lda #>(callback-1) sta (ptr3),y iny - lda #<(chainIRQ-1) + + ; set ROM entry point vector + ; since it's called via "rts" we have to decrement it by one + lda old_irq + sec + sbc #1 sta (ptr3),y iny - lda #>(chainIRQ-1) + lda old_irq+1 + sbc #0 sta (ptr3),y cli @@ -197,10 +205,10 @@ INSTALL: ; No return code required (the driver is removed from memory on return). UNINSTALL: - lda chainIRQ+1 + lda old_irq sei sta IRQInd+1 - lda chainIRQ+2 + lda old_irq+1 sta IRQInd+2 cli diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index 83255b64e..c1dc2e019 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -73,15 +73,6 @@ 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 @@ -108,6 +99,10 @@ Temp: .res 1 old_key_count: .res 1 +; original IRQ vector + +old_irq: .res 2 + .rodata ; Default values for above variables @@ -163,20 +158,27 @@ INSTALL: ; Initialize our IRQ magic - lda IRQInd+1 - sta chainIRQ+1 + ; remember ROM IRQ continuation address lda IRQInd+2 - sta chainIRQ+2 + sta old_irq+1 + lda IRQInd+1 + sta old_irq + lda libref sta ptr3 lda libref+1 sta ptr3+1 + + ; set 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 address of our IRQ callback routine + ; since it's called via "rts" we have to use "address-1" iny lda #<(callback-1) sta (ptr3),y @@ -184,10 +186,16 @@ INSTALL: lda #>(callback-1) sta (ptr3),y iny - lda #<(chainIRQ-1) + + ; set ROM entry point vector + ; since it's called via "rts" we have to decrement it by one + lda old_irq + sec + sbc #1 sta (ptr3),y iny - lda #>(chainIRQ-1) + lda old_irq+1 + sbc #0 sta (ptr3),y cli @@ -202,10 +210,10 @@ INSTALL: ; No return code required (the driver is removed from memory on return). UNINSTALL: - lda chainIRQ+1 + lda old_irq sei sta IRQInd+1 - lda chainIRQ+2 + lda old_irq+1 sta IRQInd+2 cli diff --git a/libsrc/c128/mouseref.s b/libsrc/c128/mouseref.s index 290303075..630ff573f 100644 --- a/libsrc/c128/mouseref.s +++ b/libsrc/c128/mouseref.s @@ -26,7 +26,7 @@ _pen_adjuster: .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 +jmp_rom_hdlr: ; original ROM indirect IRQ handler address .addr $0000 ; (filled in by mouse driver) @@ -54,11 +54,17 @@ IRQStub2: lda #MMU_CFG_CC65 ; MMU configuration which will be active after the ROM handler returns pha + ; map out ROM + ldy MMU_CR + sta MMU_CR + ; push address of ROM handler on stack and jump to it lda jmp_rom_hdlr+1 pha lda jmp_rom_hdlr pha + + sty MMU_CR ; map in ROM rts ; jump to ROM handler ; our MMU configuration byte we pushed on the stack before (MMU_CFG_CC65) is now active