1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
;
; Ullrich von Bassewitz, 2003-12-28, 2009-09-26
;
; Common functions of the mouse driver API.
;
.import return0, popsreg, incsp2, mouse_libref
.importzp sreg, ptr1, tmp1, tmp2
.interruptor mouse_irq ; Export as IRQ handler
.include "mouse-kernel.inc"
;----------------------------------------------------------------------------
; Variables
.bss
_mouse_drv: .res 2 ; Pointer to driver
_mouse_hidden: .res 1 ; Mouse visibility flag
; Jump table for the driver functions.
.data
mouse_vectors:
mouse_install: jmp return0
mouse_uninstall:jmp return0
mouse_hide: jmp return0
mouse_show: 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_flags: .byte $00
; Driver header signature
.rodata
mouse_sig: .byte $6d, $6f, $75, MOUSE_API_VERSION ; "mou", version
.code
;----------------------------------------------------------------------------
; 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
; Check the driver signature
ldy #.sizeof(mouse_sig)-1
@L0: lda (ptr1),y
cmp mouse_sig,y
bne inv_drv
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 copyjv ; Copy one byte
jsr copyjv ; Copy one byte
cpy #(MOUSE_HDR::JUMPTAB + .sizeof(MOUSE_HDR::JUMPTAB))
bne @L1
; 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
; Call driver install routine and check for errors
@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
jmp incsp2
; Copy one byte from the jump vectors
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 mouse_uninstall (void);
; /* Uninstall the currently loaded driver. Returns an error code. */
_mouse_uninstall:
; 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
; 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
|