]> git.sur5r.net Git - cc65/blob - libsrc/c128/mou/c128-pot.s
Used a library-reference method to calibrate lightpen drivers.
[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 ; Default values for above variables
88
89 .rodata
90
91 .proc   DefVars
92         .word   SCREEN_HEIGHT/2         ; YPos
93         .word   SCREEN_WIDTH/2          ; XPos
94         .word   0                       ; XMin
95         .word   0                       ; YMin
96         .word   SCREEN_WIDTH            ; XMax
97         .word   SCREEN_HEIGHT           ; YMax
98         .byte   0                       ; Buttons
99 .endproc
100
101 .code
102
103 ;----------------------------------------------------------------------------
104 ; INSTALL routine. Is called after the driver is loaded into memory. If
105 ; possible, check if the hardware is present.
106 ; Must return an MOUSE_ERR_xx code in a/x.
107
108 INSTALL:
109
110 ; Initialize variables. Just copy the default stuff over
111
112         ldx     #.sizeof(DefVars)-1
113 @L1:    lda     DefVars,x
114         sta     Vars,x
115         dex
116         bpl     @L1
117
118 ; Be sure the mouse cursor is invisible and at the default location. We
119 ; need to do that here, because our mouse interrupt handler doesn't set the
120 ; mouse position if it hasn't changed.
121
122         sei
123         jsr     CHIDE
124         lda     XPos
125         ldx     XPos+1
126         jsr     CMOVEX
127         lda     YPos
128         ldx     YPos+1
129         jsr     CMOVEY
130         cli
131
132 ; Done, return zero (= MOUSE_ERR_OK)
133
134         ldx     #$00
135         txa
136         rts
137
138 ;----------------------------------------------------------------------------
139 ; UNINSTALL routine. Is called before the driver is removed from memory.
140 ; No return code required (the driver is removed from memory on return).
141
142 UNINSTALL       = HIDE                  ; Hide cursor on exit
143
144 ;----------------------------------------------------------------------------
145 ; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
146 ; a counter for calls to show/hide, and the driver entry point is only called
147 ; if the mouse is currently visible and should get hidden. For most drivers,
148 ; no special action is required besides hiding the mouse cursor.
149 ; No return code required.
150
151 HIDE:   sei
152         jsr     CHIDE
153         cli
154         rts
155
156 ;----------------------------------------------------------------------------
157 ; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
158 ; a counter for calls to show/hide, and the driver entry point is only called
159 ; if the mouse is currently hidden and should become visible. For most drivers,
160 ; no special action is required besides enabling the mouse cursor.
161 ; No return code required.
162
163 SHOW:   sei
164         jsr     CSHOW
165         cli
166         rts
167
168 ;----------------------------------------------------------------------------
169 ; SETBOX: Set the mouse bounding box. The parameters are passed as they come
170 ; from the C program, that is, a pointer to a mouse_box struct in a/x.
171 ; No checks are done if the mouse is currently inside the box, this is the job
172 ; of the caller. It is not necessary to validate the parameters, trust the
173 ; caller and save some code here. No return code required.
174
175 SETBOX: sta     ptr1
176         stx     ptr1+1                  ; Save data pointer
177
178         ldy     #.sizeof (MOUSE_BOX)-1
179         sei
180
181 @L1:    lda     (ptr1),y
182         sta     XMin,y
183         dey
184         bpl     @L1
185
186         cli
187         rts
188
189 ;----------------------------------------------------------------------------
190 ; GETBOX: Return the mouse bounding box. The parameters are passed as they
191 ; come from the C program, that is, a pointer to a mouse_box struct in a/x.
192
193 GETBOX: sta     ptr1
194         stx     ptr1+1                  ; Save data pointer
195
196         ldy     #.sizeof (MOUSE_BOX)-1
197         sei
198
199 @L1:    lda     XMin,y
200         sta     (ptr1),y
201         dey
202         bpl     @L1
203
204         cli
205         rts
206
207 ;----------------------------------------------------------------------------
208 ; MOVE: Move the mouse to a new position. The position is passed as it comes
209 ; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
210 ; remove the parameter from the stack on return.
211 ; No checks are done if the new position is valid (within the bounding box or
212 ; the screen). No return code required.
213 ;
214
215 MOVE:   sei                             ; No interrupts
216
217         sta     YPos
218         stx     YPos+1                  ; New Y position
219         jsr     CMOVEY                  ; Set it
220
221         ldy     #$01
222         lda     (sp),y
223         sta     XPos+1
224         tax
225         dey
226         lda     (sp),y
227         sta     XPos                    ; New X position
228
229         jsr     CMOVEX                  ; Move the cursor
230
231         cli                             ; Allow interrupts
232         rts
233
234 ;----------------------------------------------------------------------------
235 ; BUTTONS: Return the button mask in a/x.
236
237 BUTTONS:
238         lda     Buttons
239         ldx     #$00
240         rts
241
242 ;----------------------------------------------------------------------------
243 ; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
244 ; No return code required.
245
246 POS:    ldy     #MOUSE_POS::XCOORD      ; Structure offset
247
248         sei                             ; Disable interrupts
249         lda     XPos                    ; Transfer the position
250         sta     (ptr1),y
251         lda     XPos+1
252         iny
253         sta     (ptr1),y
254         lda     YPos
255         iny
256         sta     (ptr1),y
257         lda     YPos+1
258         cli                             ; Enable interrupts
259
260         iny
261         sta     (ptr1),y                ; Store last byte
262
263         rts                             ; Done
264
265 ;----------------------------------------------------------------------------
266 ; INFO: Returns mouse position and current button mask in the MOUSE_INFO
267 ; struct pointed to by ptr1. No return code required.
268 ;
269 ; We're cheating here to keep the code smaller: The first fields of the
270 ; mouse_info struct are identical to the mouse_pos struct, so we will just
271 ; call _mouse_pos to initialize the struct pointer and fill the position
272 ; fields.
273
274 INFO:   jsr     POS
275
276 ; Fill in the button state
277
278         lda     Buttons
279         ldy     #MOUSE_INFO::BUTTONS
280         sta     (ptr1),y
281
282         rts
283
284 ;----------------------------------------------------------------------------
285 ; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
286 ; specific data in ptr1, and the ioctl code in A.
287 ; Must return an error code in a/x.
288 ;
289
290 IOCTL:  lda     #<MOUSE_ERR_INV_IOCTL     ; We don't support ioclts for now
291         ldx     #>MOUSE_ERR_INV_IOCTL
292         rts
293
294 ;----------------------------------------------------------------------------
295 ; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
296 ; (so be careful).
297 ;
298
299 IRQ:    lda     #$7F
300         sta     CIA1_PRA
301         lda     CIA1_PRB                ; Read port #1
302         and     #%00001100
303         eor     #%00001100              ; Make all bits active high
304         asl
305         sta     Buttons
306         lsr
307         lsr
308         lsr
309         and     #%00000001
310         ora     Buttons
311         sta     Buttons
312         ldx     #%01000000
313         stx     CIA1_PRA
314         ldy     #0
315 :       dey
316         bne     :-
317         ldx     SID_ADConv1
318         stx     XPos
319         ldx     SID_ADConv2
320         stx     YPos
321
322         lda     #$FF
323         tax
324         bne     @AddX                   ; Branch always
325         lda     #$01
326         ldx     #$00
327
328 ; Calculate the new X coordinate (--> a/y)
329
330 @AddX:  add     XPos
331         tay                             ; Remember low byte
332         txa
333         adc     XPos+1
334         tax
335
336 ; Limit the X coordinate to the bounding box
337
338         cpy     XMin
339         sbc     XMin+1
340         bpl     @L1
341         ldy     XMin
342         ldx     XMin+1
343         jmp     @L2
344 @L1:    txa
345
346         cpy     XMax
347         sbc     XMax+1
348         bmi     @L2
349         ldy     XMax
350         ldx     XMax+1
351 @L2:    sty     XPos
352         stx     XPos+1
353
354 ; Move the mouse pointer to the new X pos
355
356         tya
357         jsr     CMOVEX
358
359         lda     #$FF
360         tax
361         bne     @AddY
362 @Down:  lda     #$01
363         ldx     #$00
364
365 ; Calculate the new Y coordinate (--> a/y)
366
367 @AddY:  add     YPos
368         tay                             ; Remember low byte
369         txa
370         adc     YPos+1
371         tax
372
373 ; Limit the Y coordinate to the bounding box
374
375         cpy     YMin
376         sbc     YMin+1
377         bpl     @L3
378         ldy     YMin
379         ldx     YMin+1
380         jmp     @L4
381 @L3:    txa
382
383         cpy     YMax
384         sbc     YMax+1
385         bmi     @L4
386         ldy     YMax
387         ldx     YMax+1
388 @L4:    sty     YPos
389         stx     YPos+1
390
391 ; Move the mouse pointer to the new X pos
392
393         tya
394         jmp     CMOVEY