]> git.sur5r.net Git - cc65/blob - libsrc/c64/mouse.s
Started debugging the mouse routines
[cc65] / libsrc / c64 / mouse.s
1 ;
2 ; Ullrich von Bassewitz, 24.04.1999
3 ;
4 ; Routines for the 1351 proportional mouse. Parts of the code are from
5 ; the Commodore 1351 mouse users guide.
6 ;
7
8         .export         _mouse_init, _mouse_done
9         .export         _mouse_hide, _mouse_show
10         .export         _mouse_box, _mouse_info
11         .export         _mouse_x, _mouse_y
12         .export         _mouse_move
13
14         .import         popa, popsreg, addysp1
15         .importzp       sp, sreg
16
17         .include        "c64.inc"
18
19 .code
20
21 ; --------------------------------------------------------------------------
22 ;
23 ; void __fastcall__ mouse_init (unsigned char port, unsigned char sprite);
24 ;
25
26 _mouse_init:
27         tax                             ; Save sprite number
28         jsr     popa                    ; Get the port number
29
30         ldy     OldIRQ+1                ; Already initialized?
31         bne     Done                    ; Jump if yes
32
33         stx     MouseSprite             ; Remember the sprite number
34         sta     MousePort               ; Remember the port number
35
36 ; Initialize variables
37
38         ldx     #0
39         stx     XPos
40         stx     XPos+1
41         stx     YPos
42         stx     YPos+1
43         stx     OldPotX
44         stx     OldPotY
45         stx     XMin
46         stx     XMin+1
47         stx     YMin
48         stx     YMin+1
49         stx     YMax+1
50         inx                             ; X = 1
51         stx     Visible                 ; Mouse *not* visible
52         stx     XMax+1                  ; >320
53         ldx     #<320
54         stx     XMax
55         ldx     #200
56         stx     YMax
57
58 ; Remember the old IRQ vector
59
60         lda     IRQVec
61         sta     OldIRQ
62         lda     IRQVec+1
63         sta     OldIRQ+1
64
65 ; Set our own IRQ vector
66
67         lda     #<MouseIRQ
68         ldx     #>MouseIRQ
69         bne     SetIRQ
70
71 ; --------------------------------------------------------------------------
72 ;
73 ; void mouse_done (void);
74 ;
75
76 _mouse_done:
77         lda     OldIRQ                  ; Initialized?
78         ldx     OldIRQ+1
79         beq     Done                    ; Jump if no
80         ldy     #0
81         sty     OldIRQ+1                ; Reset the initialized flag
82 SetIRQ: sei                             ; Disable interrupts
83         sta     IRQVec                  ; Set the new/old vector
84         stx     IRQVec+1
85         cli                             ; Enable interrupts
86 Done:   rts
87
88 ; --------------------------------------------------------------------------
89 ;
90 ; void mouse_hide (void);
91 ;
92
93 _mouse_hide:
94         lda     Visible                 ; Get the flag
95         bne     @L1                     ; Jump if already invisible
96         ldx     MouseSprite             ; Sprite defined?
97         beq     @L1                     ; Jump if no
98
99         lda     NotMask-1,x             ; Get clean mask
100
101         sei                             ; Disable interrupts
102         and     VIC_SPR_ENA
103         sta     VIC_SPR_ENA             ; Disable sprite
104         cli                             ; Enable interrupts
105
106 @L1:    inc     Visible                 ; Set the flag to invisible
107         rts
108
109 ; --------------------------------------------------------------------------
110 ;
111 ; void mouse_show (void);
112 ;
113
114 _mouse_show:
115         lda     Visible                 ; Mouse already visible?
116         beq     @L1                     ; Jump if yes
117         dec     Visible                 ; Get the flag
118         bne     @L1                     ; Jump if still invisible
119         ldx     MouseSprite             ; Sprite defined?          
120         beq     @L1                     ; Jump if no
121
122         sei                             ; Disable interrupts
123         jsr     MoveSprite1             ; Move the sprite to it's position
124
125         ldx     MouseSprite             ; Get sprite number (again)
126         lda     BitMask-1,x             ; Get bit mask
127         ora     VIC_SPR_ENA
128         sta     VIC_SPR_ENA             ; Enable sprite
129
130         cli                             ; Enable interrupts
131
132 @L1:    rts
133
134 ; --------------------------------------------------------------------------
135 ;
136 ; void __fastcall__ mouse_box (int minx, int miny, int maxx, int maxy);
137 ;
138
139 _mouse_box:
140         ldy     #0                      ; Stack offset
141
142         php
143         sei                             ; Disable interrupts
144
145         sta     YMax
146         stx     YMax+1                  ; maxy
147
148         lda     (sp),y
149         sta     XMax
150         iny
151         lda     (sp),y
152         sta     XMax+1                  ; maxx
153
154         iny
155         lda     (sp),y
156         sta     YMin
157         iny
158         lda     (sp),y
159         sta     YMin+1                  ; miny
160
161         iny
162         lda     (sp),y
163         sta     XMin
164         iny
165         lda     (sp),y
166         sta     XMin+1                  ; minx
167
168         plp                             ; Enable interrupts
169
170         jmp     addysp1                 ; Drop params, return
171
172 ; --------------------------------------------------------------------------
173 ;
174 ; int __fastcall__ mouse_x (void);
175 ;
176
177 _mouse_x:
178         php
179         sei
180         lda     XPos
181         ldx     XPos+1
182         plp
183         rts
184
185 ; --------------------------------------------------------------------------
186 ;
187 ; int __fastcall__ mouse_y (void);
188 ;
189
190 _mouse_y:
191         php
192         sei
193         lda     YPos
194         ldx     YPos+1
195         plp
196         rts
197
198 ; --------------------------------------------------------------------------
199 ;
200 ; void mouse_info (...);
201 ;
202
203 _mouse_info:
204         rts
205
206
207 ; --------------------------------------------------------------------------
208 ;
209 ; void __fastcall__ mouse_move (int x, int y);
210 ;
211
212 _mouse_move:
213         jsr     popsreg                 ; Get X
214         sei                             ; Disable interrupts
215
216         sta     YPos
217         stx     YPos+1
218         lda     sreg
219         ldx     sreg+1
220         sta     XPos
221         stx     XPos+1                  ; Set new position
222
223         jsr     MoveSprite              ; Move the sprite to the mouse pos
224
225 @L9:    cli                             ; Enable interrupts
226         rts
227
228 ; --------------------------------------------------------------------------
229 ;
230 ; Mouse interrupt handler
231 ;
232
233 MouseIRQ:
234         cld
235         lda     SID_ADConv1             ; Get mouse X movement
236         ldy     OldPotX
237         jsr     MoveCheck               ; Calculate movement vector
238         sty     OldPotX
239
240 ; Calculate the new X coordinate (--> a/y)
241
242         clc
243         adc     XPos
244         tay                             ; Remember low byte
245         txa
246         adc     XPos+1
247         tax
248
249 ; Limit the X coordinate to the bounding box
250
251         cpy     XMin
252         sbc     XMin+1
253         bpl     @L1
254         ldy     XMin
255         ldx     XMin+1
256         jmp     @L2
257 @L1:    txa
258
259         cpy     XMax
260         sbc     XMax+1
261         bmi     @L2
262         ldy     XMax
263         ldx     XMax+1
264 @L2:    sty     XPos
265         stx     XPos+1
266
267 ; Calculate the Y movement vector
268
269         lda     SID_ADConv2             ; Get mouse Y movement
270         ldy     OldPotY
271         jsr     MoveCheck               ; Calculate movement
272         sty     OldPotY
273
274 ; Calculate the new Y coordinate (--> a/y)
275
276         clc
277         adc     YPos
278         tay                             ; Remember low byte
279         txa
280         adc     YPos+1
281
282         cpy     YMin
283         sbc     YMin+1
284         bpl     @L3
285         ldy     YMin
286         ldx     YMin+1
287         jmp     @L4
288 @L3:    txa
289
290         cpy     YMax
291         sbc     YMax+1
292         bmi     @L4
293         ldy     YMax
294         ldx     YMax+1
295 @L4:    sty     YPos
296         stx     YPos+1
297
298 ; Move the mouse sprite if it is enabled
299
300         jsr     MoveSprite              ; Move the sprite
301
302 ; Jump to the next IRQ handler
303
304         jmp     (OldIRQ)
305
306
307 ; --------------------------------------------------------------------------
308 ;
309 ; Move check routine, called for both coordinates.
310 ;
311 ; Entry:        y = old value of pot register
312 ;               a = current value of pot register
313 ; Exit:         y = value to use for old value
314 ;               x/a = delta value for position
315 ;
316
317 MoveCheck:
318         sty     OldValue
319         sta     NewValue
320         ldx     #$00
321
322         sec                             ; a = mod64 (new - old)
323         sbc     OldValue
324         and     #%01111111
325         cmp     #%01000000              ; if (a > 0)
326         bcs     @L1                     ;
327         lsr     a                       ;   a /= 2;
328         beq     @L2                     ;   if (a != 0)
329         ldy     NewValue                ;     y = NewValue
330         rts                             ;   return
331
332 @L1:    ora     #%11000000              ; else or in high order bits
333         cmp     #$FF                    ; if (a != -1)
334         beq     @L2
335         sec
336         ror     a                       ;   a /= 2
337         ldx     #$FF                    ;   high byte = -1
338         ldy     NewValue
339         rts
340
341 @L2:    lda     #0
342         rts
343
344 ; --------------------------------------------------------------------------
345 ;
346 ; Move the mouse sprite to the current mouse position. Must be called
347 ; with interrupts off. MoveSprite1 is an entry without checking and
348 ; loading X
349 ;
350
351 MoveSprite:
352
353         lda     Visible                 ; Mouse visible?
354         bne     MoveSpriteDone          ; Jump if no
355         ldx     MouseSprite             ; Sprite defined?
356         beq     MoveSpriteDone          ; Jump if no
357
358 ; Set the high X bit
359
360 MoveSprite1:
361         lda     VIC_SPR_HI_X            ; Get high X bits of all sprites
362         and     NotMask-1,x             ; Mask out sprite bit
363         ldy     XPos+1                  ; Test Y position
364         beq     @L1
365         ora     BitMask-1,x             ; Set high X bit
366 @L1:    sta     VIC_SPR_HI_X            ; Set hi X sprite values
367
368 ; Set the low X byte
369
370         txa
371         asl     a                       ; Index*2
372         tax
373         lda     XPos
374         sta     VIC_SPR0_X-2,x          ; Set low byte
375
376 ; Set the Y position
377
378         ldy     YPos+1                  ; Negative or too large?
379         bne     MoveSpriteDone          ; Jump if yes
380         lda     YPos
381         sta     VIC_SPR0_Y-2,x          ; Set Y position
382
383 ; Done
384
385 MoveSpriteDone:
386         rts
387
388 ; --------------------------------------------------------------------------
389 ; Data
390
391 .bss
392
393 OldIRQ:         .res    2               ; Old IRQ vector
394 MousePort:      .res    1               ; Port used for the mouse
395 MouseSprite:    .res    1               ; Number of sprite to control
396 OldValue:       .res    1               ; Temp for MoveCheck routine
397 NewValue:       .res    1               ; Temp for MoveCheck routine
398
399 Visible:        .res    1               ; Is the mouse visible?
400 OldPotX:        .res    1               ; Old hw counter values
401 OldPotY:        .res    1
402
403 XPos:           .res    2               ; Current mouse position, X
404 YPos:           .res    2               ; Current mouse position, Y
405
406 XMin:           .res    2               ; X1 value of bounding box
407 YMin:           .res    2               ; Y1 value of bounding box
408 XMax:           .res    2               ; X2 value of bounding box
409 YMax:           .res    2               ; Y2 value of bounding box
410
411 .data
412
413 BitMask:        .byte   $01, $02, $04, $08, $10, $20, $40, $80
414 NotMask:        .byte   $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F
415
416
417
418
419