FETVEC := $2AA ; Vector patch location for FETCH
STASH := $2AF ; Stash routine in RAM
STAVEC := $2B9 ; Vector patch location for STASH
+IRQInd := $2FD ; JMP $0000 -- used as indirect IRQ vector
PALFLAG := $A03 ; $FF=PAL, $00=NTSC
INIT_STATUS := $A04 ; Flags: Reset/Restore initiation status
FKEY_LEN := $1000 ; Function key lengths
.include "c128.inc"
-IRQInd = $2FD ; JMP $0000 - used as indirect IRQ vector
-
; ------------------------------------------------------------------------
.segment "INIT"
;
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
;
-; 2013-07-01, Greg King
+; 2014-04-26, Christian Groessler
+; 2014-05-01, Greg King
;
.include "zeropage.inc"
; Library reference
-LIBREF: .addr $0000
+libref: .addr $0000
; Jump table
INIT_save: .res 1
+; Keyboard buffer fill level at start of interrupt
+
+old_key_count: .res 1
+
+; Original IRQ vector
+
+old_irq: .res 2
+
.data
; Default Inkwell calibration.
lda #%11000000
sta INIT_STATUS
-; Initiate variables. Just copy the default stuff over.
+; Initiate some variables. Just copy the default stuff over.
ldx #.sizeof (DefVars) - 1
@L0: lda DefVars,x
stx OldPenX
sty OldPenY
+; 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 ; Point to mouse_adjuster
+ stx ptr3+1
+
+ ; Set the ROM IRQ continuation address to point to the provided routine.
+ ldy #2
+ lda (ptr3),y
+ iny
+ sei
+ sta IRQInd+1
+ 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
+
; Call a calibration function through the library-reference.
- lda LIBREF
- ldx LIBREF+1
- sta ptr1 ; Point to mouse_adjuster
- stx ptr1+1
ldy #1
- lda (ptr1),y
+ lda (ptr3),y
bze @L1 ; Don't call pointer if it's NULL
sta Calibrate+2 ; Point to function
dey
- lda (ptr1),y
+ lda (ptr3),y
sta Calibrate+1
lda #<XOffset ; Function will set this variable
ldx #>XOffset
; No return code required (the driver is removed from memory on return).
UNINSTALL:
+ lda old_irq
+ ldx old_irq+1
+ sei
+ sta IRQInd+1
+ stx IRQInd+2
+ ;cli
+
jsr HIDE ; Hide cursor on exit
lda INIT_save
sta INIT_STATUS
;
IRQ: jsr CPREP
+ lda KEY_COUNT
+ sta old_key_count
; Record the state of the buttons.
; Try to avoid crosstalk between the keyboard and the lightpen.
ldy #%00000000 ; Set ports A and B to input
sty CIA1_DDRB
sty CIA1_DDRA ; Keyboard won't look like buttons
- lda CIA1_PRB ; Read Control-Port 1
+ ;lda #%01111111
+ ;sta CIA1_PRA
+ lda CIA1_PRB ; Read Control Port 1
dec CIA1_DDRA ; Set port A back to output
eor #%11111111 ; Bit goes up when button goes down
sta Buttons
- bze @L0
- lda #%11101111 ; (Don't change bit that feeds VIC-II)
- sta CIA1_DDRB ; Buttons won't look like keyboard
- sty CIA1_PRB ; Set "all keys pushed"
; Read the VIC-II lightpen registers.
-@L0: lda VIC_LPEN_Y
+ lda VIC_LPEN_Y
cmp OldPenY
; Skip processing if nothing has changed.
MoveX: sta XPos
stx XPos+1
jmp CMOVEX
+
+.define OLD_BUTTONS Buttons ; Tells callback.inc where the old port status is stored
+.include "callback.inc"
;
; 2006-08-20, Stefan Haubenthal
; 2009-09-26, Ullrich von Bassewitz
+; 2014-04-26, Christian Groessler
; 2014-05-05, Greg King
;
; Library reference
- .addr $0000
+libref: .addr $0000
; Jump table
INIT_save: .res 1
-; Temporary value used in the int handler
+; Keyboard buffer fill level at start of interrupt
-Temp: .res 1
+old_key_count: .res 1
+
+; Original IRQ vector
+
+old_irq: .res 2
.rodata
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)
; No return code required (the driver is removed from memory on return).
UNINSTALL:
+ lda old_irq
+ ldx old_irq+1
+ sei
+ sta IRQInd+1
+ stx IRQInd+2
+ ;cli
+
jsr HIDE ; Hide cursor on exit
lda INIT_save
sta INIT_STATUS
BUTTONS:
lda Buttons
ldx #$00
+
+; Make the buttons look like a 1351 mouse.
+
+ and #JOY::LEFT | JOY::RIGHT
+ lsr a
+ lsr a
+ ;clc
+ adc #%00001110
+ 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
;
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
jsr CDRAW
clc ; Interrupt not "handled"
rts
+
+.define OLD_BUTTONS Buttons ; Tells callback.inc where the old port status is stored
+.include "callback.inc"