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