File: cx16-std.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (312 lines) | stat: -rw-r--r-- 9,892 bytes parent folder | download | duplicates (2)
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