;
-; Ullrich von Bassewitz, 2003-12-28
+; Ullrich von Bassewitz, 2003-12-28, 2009-09-26
;
; Common functions of the mouse driver API.
;
- .import return0
- .importzp ptr1
- .condes mouse_irq, 2 ; Export as IRQ handler
+ .import return0, popsreg, incsp2, mouse_libref
+ .importzp sreg, ptr1, tmp1, tmp2
+ .interruptor mouse_irq ; Export as IRQ handler
.include "mouse-kernel.inc"
.bss
-_mouse_drv: .res 2 ; Pointer to driver
+_mouse_drv: .res 2 ; Pointer to driver
+
+_mouse_hidden: .res 1 ; Mouse visibility flag
; Jump table for the driver functions.
.data
mouse_uninstall:jmp return0
mouse_hide: jmp return0
mouse_show: jmp return0
-mouse_box: jmp return0
+mouse_setbox: jmp return0
+mouse_getbox: jmp return0
mouse_move: jmp return0
mouse_buttons: jmp return0
mouse_pos: jmp return0
mouse_info: jmp return0
mouse_ioctl: jmp return0
-mouse_irq: .byte $60, $00, $00 ; RTS plus two dummy bytes
+mouse_irq: .byte $60, $00, $00 ; RTS plus two dummy bytes
+mouse_flags: .byte $00
; Driver header signature
.rodata
mouse_sig: .byte $6d, $6f, $75, MOUSE_API_VERSION ; "mou", version
+.code
;----------------------------------------------------------------------------
-; unsigned char __fastcall__ mouse_install (void* driver);
+; unsigned char __fastcall__ mouse_install (const struct mouse_callbacks* c,
+; void* driver);
; /* Install an already loaded driver. Returns an error code. */
-
-
_mouse_install:
- sta _mouse_drv
- sta ptr1
- stx _mouse_drv+1
- stx ptr1+1
+ sta _mouse_drv
+ sta ptr1
+ stx _mouse_drv+1
+ stx ptr1+1
; Check the driver signature
dey
bpl @L0
+; Set the library reference
+
+ ldy #MOUSE_HDR::LIBREF
+ lda #<mouse_libref
+ sta (ptr1),y
+ iny
+ lda #>mouse_libref
+ sta (ptr1),y
+
+; Reset flags
+
+ lda #1
+ sta _mouse_hidden
+
; Copy the jump vectors
ldy #MOUSE_HDR::JUMPTAB
ldx #0
@L1: inx ; Skip the JMP opcode
- jsr copy ; Copy one byte
- jsr copy ; Copy one byte
+ jsr copyjv ; Copy one byte
+ jsr copyjv ; Copy one byte
cpy #(MOUSE_HDR::JUMPTAB + .sizeof(MOUSE_HDR::JUMPTAB))
bne @L1
- jmp mouse_install ; Call driver install routine
+; Copy the flags byte. It is located directly behind the jump vectors, so Y
+; is already correct when we come here. To save code, we use copyjv - crude
+; but effective.
+
+ jsr copyjv
+
+; Copy the callback vectors into the driver space
+
+ jsr popsreg
+ ldy #(MOUSE_HDR::CALLBACKS + .sizeof(MOUSE_HDR::CALLBACKS) - 1)
+ sty tmp2
+ ldy #.sizeof(MOUSE_CALLBACKS)-1
+ sty tmp1
+
+@L2: jsr copycb
+ ldy tmp1
+ jsr copycb
+ dec tmp2 ; Skip opcode byte
+ ldy tmp1
+ bpl @L2
+
+; Install the IRQ vector if the driver needs it
+
+ bit mouse_flags ; Test MOUSE_FLAG_EARLY_IRQ
+ bvc @L3 ; Jump if no interrupts at this time
+ jsr install_irq ; Activate IRQ routine
- ldy mouse_irq+2 ; Check high byte of IRQ vector
- beq @L2 ; Jump if vector invalid
- ldy #$4C ; Jump opcode
- sty mouse_irq ; Activate IRQ routine
-@L2: rts
+; Call driver install routine and check for errors
-; Driver signature invalid
+@L3: jsr mouse_install
+ tay ; Test error code
+ bne uninstall_irq ; Jump on error
+
+; No errors on INSTALL. If the driver needs late IRQs, enable them now. Be
+; careful not to use A/X since these registers contain the error code from
+; INSTALL.
+
+ bit mouse_flags ; Test MOUSE_FLAG_LATE_IRQ
+ bpl Exit ; Jump if vector not needed
+install_irq:
+ ldy #$4C ; Jump opcode
+ sty mouse_irq ; Activate IRQ routine
+Exit: rts
+
+; Uninstall IRQ vector if install routine had errors. A/X may contain the
+; error code from mouse_install, so don't use it.
+
+uninstall_irq:
+ ldy #$60 ; RTS opcode
+ sty mouse_irq ; Disable IRQ entry point
+ rts
+
+; Driver signature invalid. One word is still on the stack
inv_drv:
lda #MOUSE_ERR_INV_DRIVER
ldx #0
- rts
+ jmp incsp2
; Copy one byte from the jump vectors
-copy: lda (ptr1),y
+copyjv: lda (ptr1),y
sta mouse_vectors,x
iny
inx
rts
+; Copy one byte from the callback vectors
+
+copycb: lda (sreg),y
+ dec tmp1
+ ldy tmp2
+ sta (ptr1),y
+ dec tmp2
+ rts
+
;----------------------------------------------------------------------------
-; unsigned char __fastcall__ mouse_uninstall (void);
+; unsigned char mouse_uninstall (void);
; /* Uninstall the currently loaded driver. Returns an error code. */
_mouse_uninstall:
- jsr mouse_uninstall ; Call driver routine
- lda #$60 ; RTS opcode
- sta mouse_irq ; Disable IRQ entry point
+; Depending on the late/early IRQ flag, we will disable IRQs before or after
+; calling the driver mouse_uninstall routine.
+
+ bit mouse_flags ; Test MOUSE_FLAG_LATE_IRQ
+ bpl @L1 ; Don't disable interrupts now
+ jsr uninstall_irq ; Disable driver interrupts
+@L1: jsr mouse_uninstall ; Call driver routine
-mouse_clear_ptr: ; External entry point
+; We don't check the flag a second time here, since disabling IRQs twice,
+; or disabling them if they weren't enabled will do no harm, and the missing
+; check will save a few bytes.
+
+ jsr uninstall_irq ; Disable driver interrupts
+
+_mouse_clear_ptr: ; External entry point
lda #0
sta _mouse_drv
sta _mouse_drv+1 ; Clear the driver pointer
tax
rts ; Return zero
-