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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
|
;
; Driver for the Commander X16 Kernal's mouse driver.
;
; 2019-12-25, Greg King
;
.include "zeropage.inc"
.include "mouse-kernel.inc"
.include "cx16.inc"
.include "cbm_kernal.inc"
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _cx16_std_mou
HEADER:
; Driver signature
.byte $6d, $6f, $75 ; ASCII "mou"
.byte MOUSE_API_VERSION ; Mouse driver API version number
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr HIDE
.addr SHOW
.addr SETBOX
.addr GETBOX
.addr MOVE
.addr BUTTONS
.addr POS
.addr INFO
.addr IOCTL
.addr IRQ
; Mouse driver flags
.byte $00 ; Don't need interrupts
; Callback table, set by the mouse kernel before INSTALL is called
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
CPREP: jmp $0000 ; Prepare to move the cursor
CDRAW: jmp $0000 ; Draw the cursor
CMOVEX: jmp $0000 ; Move the cursor to X coord
CMOVEY: jmp $0000 ; Move the cursor to Y coord
;----------------------------------------------------------------------------
; Constants
SCREEN_WIDTH = 640 - 1 ; (origin is zero)
SCREEN_HEIGHT = 480 - 1
;----------------------------------------------------------------------------
; Global variables.
XPos := ptr3 ; Current mouse position, X
YPos := ptr4 ; Current mouse position, Y
.bss
Box:
XMin: .res 2 ; X1 value of bounding box
XMax: .res 2 ; X2 value of bounding box
YMin: .res 2 ; Y1 value of bounding box
YMax: .res 2 ; Y2 value of bounding box
.rodata
; Default values for above variables
; (We use ".proc" because we want to define both a label and a scope.)
.proc DefBox
.word 0 ; XMin
.word SCREEN_WIDTH ; XMax
.word 0 ; YMin
.word SCREEN_HEIGHT ; YMax
.endproc
; These button masks are compatible with the CBM 1351 and the CMD SmartMouse.
ButtMask:
.byte %00000000 ; No buttons
.byte %00010000 ; Left
.byte %00000001 ; Right
.byte %00010001 ; Left, right
.byte %00000010 ; Middle
.byte %00010010 ; Left, middle
.byte %00000011 ; Middle, right
.byte %00010011 ; Left, middle, right
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory.
; If possible, check if the hardware is present.
; Must return a MOUSE_ERR_xx code in .XA .
INSTALL:
; Initialize variables. Just copy the default stuff over.
ldx #.sizeof(DefBox) - 1
@L1: lda DefBox,x
sta Box,x
dex
bpl @L1
ldx #$00 ; Don't change sprite's scale
lda #$01 ; Create sprite
jsr MOUSE_CONFIG
; Be sure the mouse cursor is invisible, and at the default location. We
; need to do that here, because the mouse interrupt handler might not set
; the mouse position if it hasn't changed.
jsr CHIDE
.if 0
lda XPos
ldx XPos+1
jsr CMOVEX
lda YPos
ldx YPos+1
jsr CMOVEY
.endif
; Done, return zero
ldx #>MOUSE_ERR_OK
txa
rts
;----------------------------------------------------------------------------
; UNINSTALL routine -- is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
UNINSTALL: ; Disable mouse on exit
lda #$00
tax
jmp MOUSE_CONFIG
;----------------------------------------------------------------------------
; HIDE routine -- is called to hide the mouse pointer. The mouse kernel manages
; a counter for calls to show/hide, and the driver entry point is called only
; if the mouse currently is visible, and should get hidden. For most drivers,
; no special action is required besides disabling the mouse cursor.
; No return code required.
HIDE: jmp CHIDE
;----------------------------------------------------------------------------
; SHOW routine -- is called to show the mouse pointer. The mouse kernel manages
; a counter for calls to show/hide, and the driver entry point is called only
; if the mouse currently is hidden, and should become visible. For most drivers,
; no special action is required besides enabling the mouse cursor.
; No return code required.
SHOW: jmp CSHOW
;----------------------------------------------------------------------------
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
; from the C program, that is, a pointer to a mouse_box struct in .XA .
; No checks are done if the mouse is currently inside the box, that is the job
; of the caller. It is not necessary to validate the parameters, trust the
; caller, and save some code here. No return code required.
SETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
lda (ptr1)
ldy #$01
php
sei
sta XMin
lda (ptr1),y
sta YMin
iny
lda (ptr1),y
sta XMax
iny
lda (ptr1),y
sta YMax
plp
rts
;; Note: SETBOX and GETBOX currently have no effect!
;----------------------------------------------------------------------------
; GETBOX: Return the mouse bounding box. The parameters are passed as they
; come from the C program, that is, a pointer to a mouse_box struct in .XA .
GETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
lda XMin
sta (ptr1)
ldy #$01
lda YMin
sta (ptr1),y
iny
lda XMax
sta (ptr1),y
iny
lda YMax
sta (ptr1),y
rts
;----------------------------------------------------------------------------
; MOVE: Put the mouse at a new position. That position is passed as it comes
; from the C program, that is: X on the stack and Y in .XA . The C wrapper
; will remove the parameter from the stack, on return.
; No checks are done to see if the new position is valid (within
; the bounding box or the screen). No return code required.
;; Note: This function currently has no effect!
MOVE: php
sei ; No interrupts
sta YPos
stx YPos+1 ; New Y position
jsr CMOVEY ; Set it
ldy #$01
lda (sp),y
sta XPos+1
tax
dey
lda (sp),y
sta XPos ; New X position
jsr CMOVEX ; Move the cursor
plp ; Allow interrupts
rts
;----------------------------------------------------------------------------
; BUTTONS: Return the CBM 1351 button mask in .XA .
BUTTONS:
ldx #XPos
jsr MOUSE_GET
and #%00000111
tax
lda ButtMask,x
ldx #>$0000
rts
;----------------------------------------------------------------------------
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
; No return code required.
POS: jsr BUTTONS
POS1: ldy #MOUSE_POS::XCOORD ; Structure offset
lda XPos ; Transfer the position
sta (ptr1),y
lda XPos+1
iny
sta (ptr1),y
lda YPos
iny
sta (ptr1),y
lda YPos+1
iny
sta (ptr1),y ; Store last byte
rts ; Done
;----------------------------------------------------------------------------
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
; struct pointed to by ptr1. No return code required.
;
; We're cheating here to keep the code smaller: The first fields of the
; mouse_info struct are identical to the mouse_pos struct; so, we just will
; call mouse_pos to initialize the struct pointer, and fill the position
; fields.
INFO: jsr BUTTONS ; Will not touch ptr1
ldy #MOUSE_INFO::BUTTONS
sta (ptr1),y
jmp POS1
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in .XA .
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now
ldx #>MOUSE_ERR_INV_IOCTL
; rts ; Fall through
;----------------------------------------------------------------------------
; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
; (so be careful). The routine MUST return carry set if the interrupt has been
; 'handled' -- which means that the interrupt source is gone. Otherwise, it
; MUST return carry clear.
IRQ: rts ; Kernal ROM does this routine's job
|