.macpack generic
+IRQInd = $2FD
+
; ------------------------------------------------------------------------
; Header. Includes jump table
; Library reference
+libref:
.addr $0000
; Jump table
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
Temp: .res 1
+; Keyboard buffer fill level at start of interrupt
+
+old_key_count: .res 1
+
.rodata
; Default values for above variables
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
; 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
;
IRQ: jsr CPREP
+ lda KEY_COUNT
+ sta old_key_count
lda #$7F
sta CIA1_PRA
lda CIA1_PRB ; Read joystick #0
@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
; 2013-07-25, Greg King
;
+ .include "c128.inc"
+
.export mouse_libref, _pen_adjuster
.data
;
_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