]> git.sur5r.net Git - cc65/blob - libsrc/c128/mou/c128-pot.s
Renamed JUMPTABLE and cleaned up module.cfg.
[cc65] / libsrc / c128 / mou / c128-pot.s
1 ;
2 ; Driver for a potentiometer "mouse", e.g. Koala Pad
3 ;
4 ; 2006-08-20, Stefan Haubenthal
5 ; 2009-09-26, Ullrich von Bassewitz
6 ; 2014-03-17, Greg King
7 ;
8
9         .include        "zeropage.inc"
10         .include        "mouse-kernel.inc"
11         .include        "c128.inc"
12
13         .macpack        generic
14
15 ; ------------------------------------------------------------------------
16 ; Header. Includes jump table
17
18 .segment        "HEADER"
19
20 HEADER:
21
22 ; Driver signature
23
24         .byte   $6d, $6f, $75           ; "mou"
25         .byte   MOUSE_API_VERSION       ; Mouse driver API version number
26
27 ; Library reference
28
29         .addr   $0000
30
31 ; Jump table
32
33         .addr   INSTALL
34         .addr   UNINSTALL
35         .addr   HIDE
36         .addr   SHOW
37         .addr   SETBOX
38         .addr   GETBOX
39         .addr   MOVE
40         .addr   BUTTONS
41         .addr   POS
42         .addr   INFO
43         .addr   IOCTL
44         .addr   IRQ
45
46 ; Callback table, set by the kernel before INSTALL is called
47
48 CHIDE:  jmp     $0000                   ; Hide the cursor
49 CSHOW:  jmp     $0000                   ; Show the cursor
50 CPREP:  jmp     $0000                   ; Prepare to move the cursor
51 CDRAW:  jmp     $0000                   ; Draw the cursor
52 CMOVEX: jmp     $0000                   ; Move the cursor to X coord
53 CMOVEY: jmp     $0000                   ; Move the cursor to Y coord
54
55
56 ;----------------------------------------------------------------------------
57 ; Constants
58
59 SCREEN_HEIGHT   = 200
60 SCREEN_WIDTH    = 320
61
62 .enum   JOY
63         UP      = $01
64         DOWN    = $02
65         LEFT    = $04
66         RIGHT   = $08
67         FIRE    = $10
68 .endenum
69
70 ;----------------------------------------------------------------------------
71 ; Global variables. The bounding box values are sorted so that they can be
72 ; written with the least effort in the SETBOX and GETBOX routines, so don't
73 ; reorder them.
74
75 .bss
76
77 Vars:
78 YPos:           .res    2               ; Current mouse position, Y
79 XPos:           .res    2               ; Current mouse position, X
80 XMin:           .res    2               ; X1 value of bounding box
81 YMin:           .res    2               ; Y1 value of bounding box
82 XMax:           .res    2               ; X2 value of bounding box
83 YMax:           .res    2               ; Y2 value of bounding box
84 Buttons:        .res    1               ; Button mask
85
86 INIT_save:      .res    1
87
88 ; Temporary value used in the int handler
89
90 Temp:           .res    1
91
92 .rodata
93
94 ; Default values for above variables
95 ; (We use ".proc" because we want to define both a label and a scope.)
96
97 .proc   DefVars
98         .word   SCREEN_HEIGHT/2         ; YPos
99         .word   SCREEN_WIDTH/2          ; XPos
100         .word   0                       ; XMin
101         .word   0                       ; YMin
102         .word   SCREEN_WIDTH - 1        ; XMax
103         .word   SCREEN_HEIGHT - 1       ; YMax
104         .byte   0                       ; Buttons
105 .endproc
106
107 .code
108
109 ;----------------------------------------------------------------------------
110 ; INSTALL routine. Is called after the driver is loaded into memory. If
111 ; possible, check if the hardware is present.
112 ; Must return an MOUSE_ERR_xx code in a/x.
113
114 INSTALL:
115
116 ; Disable the BASIC interpreter's interrupt-driven sprite-motion code.
117 ; That allows direct access to the VIC-IIe's sprite registers.
118
119         lda     INIT_STATUS
120         sta     INIT_save
121         lda     #%11000000
122         sta     INIT_STATUS
123
124 ; Initialize variables. Just copy the default stuff over
125
126         ldx     #.sizeof(DefVars)-1
127 @L1:    lda     DefVars,x
128         sta     Vars,x
129         dex
130         bpl     @L1
131
132 ; Be sure the mouse cursor is invisible and at the default location. We
133 ; need to do that here, because our mouse interrupt handler doesn't set the
134 ; mouse position if it hasn't changed.
135
136         sei
137         jsr     CHIDE
138         lda     XPos
139         ldx     XPos+1
140         jsr     CMOVEX
141         lda     YPos
142         ldx     YPos+1
143         jsr     CMOVEY
144         cli
145
146 ; Done, return zero (= MOUSE_ERR_OK)
147
148         ldx     #$00
149         txa
150         rts
151
152 ;----------------------------------------------------------------------------
153 ; UNINSTALL routine. Is called before the driver is removed from memory.
154 ; No return code required (the driver is removed from memory on return).
155
156 UNINSTALL:
157         jsr     HIDE                    ; Hide cursor on exit
158         lda     INIT_save
159         sta     INIT_STATUS
160         rts
161
162 ;----------------------------------------------------------------------------
163 ; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
164 ; a counter for calls to show/hide, and the driver entry point is only called
165 ; if the mouse is currently visible and should get hidden. For most drivers,
166 ; no special action is required besides hiding the mouse cursor.
167 ; No return code required.
168
169 HIDE:   sei
170         jsr     CHIDE
171         cli
172         rts
173
174 ;----------------------------------------------------------------------------
175 ; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
176 ; a counter for calls to show/hide, and the driver entry point is only called
177 ; if the mouse is currently hidden and should become visible. For most drivers,
178 ; no special action is required besides enabling the mouse cursor.
179 ; No return code required.
180
181 SHOW:   sei
182         jsr     CSHOW
183         cli
184         rts
185
186 ;----------------------------------------------------------------------------
187 ; SETBOX: Set the mouse bounding box. The parameters are passed as they come
188 ; from the C program, that is, a pointer to a mouse_box struct in a/x.
189 ; No checks are done if the mouse is currently inside the box, this is the job
190 ; of the caller. It is not necessary to validate the parameters, trust the
191 ; caller and save some code here. No return code required.
192
193 SETBOX: sta     ptr1
194         stx     ptr1+1                  ; Save data pointer
195
196         ldy     #.sizeof (MOUSE_BOX)-1
197         sei
198
199 @L1:    lda     (ptr1),y
200         sta     XMin,y
201         dey
202         bpl     @L1
203
204         cli
205         rts
206
207 ;----------------------------------------------------------------------------
208 ; GETBOX: Return the mouse bounding box. The parameters are passed as they
209 ; come from the C program, that is, a pointer to a mouse_box struct in a/x.
210
211 GETBOX: sta     ptr1
212         stx     ptr1+1                  ; Save data pointer
213
214         ldy     #.sizeof (MOUSE_BOX)-1
215         sei
216
217 @L1:    lda     XMin,y
218         sta     (ptr1),y
219         dey
220         bpl     @L1
221
222         cli
223         rts
224
225 ;----------------------------------------------------------------------------
226 ; MOVE: Move the mouse to a new position. The position is passed as it comes
227 ; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
228 ; remove the parameter from the stack on return.
229 ; No checks are done if the new position is valid (within the bounding box or
230 ; the screen). No return code required.
231 ;
232
233 MOVE:   sei                             ; No interrupts
234
235         sta     YPos
236         stx     YPos+1                  ; New Y position
237         jsr     CMOVEY                  ; Set it
238
239         ldy     #$01
240         lda     (sp),y
241         sta     XPos+1
242         tax
243         dey
244         lda     (sp),y
245         sta     XPos                    ; New X position
246
247         jsr     CMOVEX                  ; Move the cursor
248
249         cli                             ; Allow interrupts
250         rts
251
252 ;----------------------------------------------------------------------------
253 ; BUTTONS: Return the button mask in a/x.
254
255 BUTTONS:
256         lda     Buttons
257         ldx     #$00
258         rts
259
260 ;----------------------------------------------------------------------------
261 ; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
262 ; No return code required.
263
264 POS:    ldy     #MOUSE_POS::XCOORD      ; Structure offset
265
266         sei                             ; Disable interrupts
267         lda     XPos                    ; Transfer the position
268         sta     (ptr1),y
269         lda     XPos+1
270         iny
271         sta     (ptr1),y
272         lda     YPos
273         iny
274         sta     (ptr1),y
275         lda     YPos+1
276         cli                             ; Enable interrupts
277
278         iny
279         sta     (ptr1),y                ; Store last byte
280
281         rts                             ; Done
282
283 ;----------------------------------------------------------------------------
284 ; INFO: Returns mouse position and current button mask in the MOUSE_INFO
285 ; struct pointed to by ptr1. No return code required.
286 ;
287 ; We're cheating here to keep the code smaller: The first fields of the
288 ; mouse_info struct are identical to the mouse_pos struct, so we will just
289 ; call _mouse_pos to initialize the struct pointer and fill the position
290 ; fields.
291
292 INFO:   jsr     POS
293
294 ; Fill in the button state
295
296         lda     Buttons
297         ldy     #MOUSE_INFO::BUTTONS
298         sta     (ptr1),y
299
300         rts
301
302 ;----------------------------------------------------------------------------
303 ; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
304 ; specific data in ptr1, and the ioctl code in A.
305 ; Must return an error code in a/x.
306 ;
307
308 IOCTL:  lda     #<MOUSE_ERR_INV_IOCTL     ; We don't support ioclts for now
309         ldx     #>MOUSE_ERR_INV_IOCTL
310         rts
311
312 ;----------------------------------------------------------------------------
313 ; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
314 ; (so be careful).
315 ;
316
317 IRQ:    jsr     CPREP
318         lda     #$7F
319         sta     CIA1_PRA
320         lda     CIA1_PRB                ; Read port #1
321         and     #%00001100
322         eor     #%00001100              ; Make all bits active high
323         asl
324         sta     Buttons
325         lsr
326         lsr
327         lsr
328         and     #%00000001
329         ora     Buttons
330         sta     Buttons
331         ldx     #%01000000
332         stx     CIA1_PRA
333         ldy     #0
334 :       dey
335         bne     :-
336         ldx     SID_ADConv1
337         stx     XPos
338         ldx     SID_ADConv2
339         stx     YPos
340
341         lda     #$FF
342         tax
343         bne     @AddX                   ; Branch always
344         lda     #$01
345         ldx     #$00
346
347 ; Calculate the new X coordinate (--> a/y)
348
349 @AddX:  add     XPos
350         tay                             ; Remember low byte
351         txa
352         adc     XPos+1
353         tax
354
355 ; Limit the X coordinate to the bounding box
356
357         cpy     XMin
358         sbc     XMin+1
359         bpl     @L1
360         ldy     XMin
361         ldx     XMin+1
362         jmp     @L2
363 @L1:    txa
364
365         cpy     XMax
366         sbc     XMax+1
367         bmi     @L2
368         ldy     XMax
369         ldx     XMax+1
370 @L2:    sty     XPos
371         stx     XPos+1
372
373 ; Move the mouse pointer to the new X pos
374
375         tya
376         jsr     CMOVEX
377
378         lda     #$FF
379         tax
380         bne     @AddY
381 @Down:  lda     #$01
382         ldx     #$00
383
384 ; Calculate the new Y coordinate (--> a/y)
385
386 @AddY:  add     YPos
387         tay                             ; Remember low byte
388         txa
389         adc     YPos+1
390         tax
391
392 ; Limit the Y coordinate to the bounding box
393
394         cpy     YMin
395         sbc     YMin+1
396         bpl     @L3
397         ldy     YMin
398         ldx     YMin+1
399         jmp     @L4
400 @L3:    txa
401
402         cpy     YMax
403         sbc     YMax+1
404         bmi     @L4
405         ldy     YMax
406         ldx     YMax+1
407 @L4:    sty     YPos
408         stx     YPos+1
409
410 ; Move the mouse pointer to the new X pos
411
412         tya
413         jsr     CMOVEY
414         jsr     CDRAW
415         clc                             ; Interrupt not "handled"
416         rts