]> git.sur5r.net Git - cc65/blob - libsrc/atari/mouse.s
bf108ce6d4bd27877ed250ef6629abd26a31ab7c
[cc65] / libsrc / atari / mouse.s
1 ;--------------------------------------------------------------------
2 ; Atari 8-bit mouse routines -- 05/07/2000 Freddy Offenga
3 ; Some changes by Christian Groessler, Ullrich von Bassewitz
4 ;
5 ; The following devices are supported:
6 ; - Atari trak-ball
7 ; - ST mouse
8 ; - Amiga mouse
9 ;
10 ; Mouse checks are done in the timer 1 IRQ and the mouse arrow is
11 ; drawn in player 0 during the vertical blank
12 ;--------------------------------------------------------------------
13
14         .export         _mouse_init, _mouse_done, _mouse_box
15         .export         _mouse_show, _mouse_hide, _mouse_move
16         .export         _mouse_buttons, _mouse_pos, _mouse_info
17         .constructor    initmouse,27
18
19         .import         popa,popax
20         .importzp       ptr1
21
22         .include "atari.inc"
23
24 TRAK_BALL       = 0     ; device Atari trak-ball
25 ST_MOUSE        = 1     ; device ST mouse
26 AMIGA_MOUSE     = 2     ; device Amiga mouse
27 MAX_TYPE        = 3     ; first illegal device type
28
29 ; the default values force the mouse cursor inside the test screen (no access to border)
30 defxmin = 48            ; default x minimum
31 defymin = 32            ; default y minimum
32 defxmax = 204           ; default x maximum
33 defymax = 211           ; default y maximum
34
35 pmsize  = 16            ; y size pm shape
36
37 xinit   = defxmin       ; init. x pos.
38 yinit   = defymin       ; init. y pos.
39
40 ;--------------------------------------------------------------------
41 ; reserve memory for the mouse pointer
42
43 initmouse:
44         lda     APPMHI+1
45         and     #%11111000      ; make 2k aligned
46         sec
47         sbc     #%00001000      ; reserve 2k
48         tax
49         adc     #3              ; add 4 (C = 1)
50         sta     mouse_pm0
51         lda     #0
52         sta     APPMHI
53         stx     APPMHI+1
54         rts
55
56
57 ;--------------------------------------------------------------------
58 ; Initialize mouse routines
59 ; void __fastcall__ mouse_init (unsigned char port, unsigned char sprite, unsigned char type);
60
61 _mouse_init:
62         pha                     ; remember mouse type
63         jsr     popa            ; ignore sprite / pm for now
64         jsr     popa
65         sta     port_nr
66         pla                     ; get mouse type again
67
68         cmp     #MAX_TYPE+1
69         bcc     setup
70
71 ifail:  lda     #0              ; init. failed
72         tax
73         rts
74
75 setup:  tax
76         lda     lvectab,x
77         sta     mouse_vec+1
78         lda     hvectab,x
79         sta     mouse_vec+2
80
81         jsr     pminit
82
83         lda     VTIMR1
84         sta     old_t1
85         lda     VTIMR1+1
86         sta     old_t1+1
87
88         lda     #<t1_vec
89         sta     VTIMR1
90         lda     #>t1_vec
91         sta     VTIMR1+1
92
93         lda     #%00000001
94         sta     AUDCTL
95
96         lda     #0
97         sta     AUDC1
98
99         lda     #15
100         sta     AUDF1
101         sta     STIMER
102
103         sei
104         lda     POKMSK
105         ora     #%00000001              ; timer 1 enable
106         sta     POKMSK
107         sta     IRQEN
108         cli
109
110         lda     VVBLKI
111         sta     vbi_jmp+1
112         lda     VVBLKI+1
113         sta     vbi_jmp+2
114
115         lda     #6
116         ldy     #<vbi
117         ldx     #>vbi
118         jsr     SETVBV
119
120         lda     #$C0
121         sta     NMIEN
122
123         ldx     #0
124         lda     #1
125         stx     mouse_on
126         rts
127
128 ;--------------------------------------------------------------------
129 ; Finish mouse routines
130 ; void mouse_done(void)
131
132 _mouse_done:
133         sei
134         lda     POKMSK
135         and     #%11111110              ; timer 1 disable
136         sta     IRQEN
137         sta     POKMSK
138         cli
139
140         lda     old_t1
141         sta     VTIMR1
142         lda     old_t1+1
143         sta     VTIMR1+1
144
145         lda     #$40
146         sta     NMIEN
147
148         lda     #6
149         ldy     vbi_jmp+1
150         ldx     vbi_jmp+2
151         jsr     SETVBV
152
153         lda     #0
154         sta     GRACTL
155         sta     HPOSP0
156         sta     mouse_on
157         rts
158
159 ;--------------------------------------------------------------------
160 ; Set mouse limits
161 ; void __fastcall__ mouse_box(int xmin, int ymin, int xmax, int ymax)
162
163 _mouse_box:
164         sta     ymax
165         jsr     popax           ; always ignore high byte
166         sta     xmax
167         jsr     popax
168         sta     ymin
169         jsr     popax
170         sta     xmin
171         rts
172
173 ;--------------------------------------------------------------------
174 ; Set mouse position
175 ; void __fastcall__ mouse_move(int xpos, int ypos)
176
177 _mouse_move:
178         sta     mousey          ; always ignore high byte
179         jsr     popax
180         sta     mousex
181         rts
182
183 ;--------------------------------------------------------------------
184 ; Show mouse arrow
185 ; void mouse_show(void)
186
187 _mouse_show:
188         inc     mouse_on
189         rts
190
191 ;--------------------------------------------------------------------
192 ; Hide mouse arrow
193 ; void mouse_hide(void)
194
195 _mouse_hide:
196         lda     mouse_on
197         beq     @L1
198         dec     mouse_on
199 @L1:    rts
200
201 ;--------------------------------------------------------------------
202 ; Ask mouse button
203 ; unsigned char mouse_buttons(void)
204
205 _mouse_buttons:
206         ldx     port_nr
207         lda     STRIG0,x
208         bne     nobut
209 ;       lda     #14
210 ;???    sta     COLOR1
211         ldx     #0
212         lda     #1
213         rts
214 nobut:  ldx     #0
215         txa
216         rts
217
218 ;--------------------------------------------------------------------
219 ; Get the mouse position
220 ; void mouse_pos (struct mouse_pos* pos);
221
222 _mouse_pos:
223         sta     ptr1
224         stx     ptr1+1                  ; Store argument pointer
225         ldy     #0
226         lda     mousex                  ; X position
227         sta     (ptr1),y
228         lda     #0
229         iny
230         sta     (ptr1),y
231         lda     mousey                  ; Y position
232         iny
233         sta     (ptr1),y
234         lda     #0
235         iny
236         sta     (ptr1),y
237         rts
238
239 ;--------------------------------------------------------------------
240 ; Get the mouse position and button information
241 ; void mouse_info (struct mouse_info* info);
242
243 _mouse_info:
244
245 ; We're cheating here to keep the code smaller: The first fields of the
246 ; mouse_info struct are identical to the mouse_pos struct, so we will just
247 ; call _mouse_pos to initialize the struct pointer and fill the position
248 ; fields.
249
250         jsr     _mouse_pos
251
252 ; Fill in the button state
253
254         jsr     _mouse_buttons          ; Will not touch ptr1
255         ldy     #4
256         sta     (ptr1),y
257
258         rts
259
260 ;--------------------------------------------------------------------
261 ; Atari trak-ball check, A,Y = 4-bit port value
262
263 trak_check:
264         eor     oldval
265         and     #%00001000
266         beq     horiz
267
268         tya
269         and     #%00000100
270         beq     mmup
271
272         inc     mousey
273         bne     horiz
274
275 mmup:   dec     mousey
276
277 horiz:  tya
278         eor     oldval
279         and     #%00000010
280         beq     mmexit
281
282         tya
283         and     #%00000001
284         beq     mmleft
285
286         inc     mousex
287         bne     mmexit
288
289 mmleft: dec     mousex
290
291 mmexit: sty     oldval
292         rts
293
294 ;--------------------------------------------------------------------
295 ; ST mouse check, A,Y = 4-bit port value
296
297 st_check:
298         and     #%00000011
299         ora     dumx
300         tax
301         lda     sttab,x
302         bmi     nxst
303
304         beq     xist
305         dec     mousex              ; 1 = left
306         bne     nxst
307 xist:   inc     mousex              ; 0 = right
308
309 nxst:   tya
310         and     #%00001100
311         ora     dumy
312         tax
313         lda     sttab,x
314         bmi     nyst
315
316         bne     yst
317         dec     mousey              ; 0 = up
318         bne     nyst
319 yst:    inc     mousey              ; 1 = down
320
321 ; store old readings
322
323 nyst:   tya
324         and     #%00000011
325         asl
326         asl
327         sta     dumx
328         tya
329         and     #%00001100
330         lsr
331         lsr
332         sta     dumy
333         rts
334
335 ;--------------------------------------------------------------------
336 ; Amiga mouse check, A,Y = 4-bit port value
337
338 amiga_check:
339
340         lsr
341         and     #%00000101
342         ora     dumx
343         tax
344         lda     amitab,x
345         bmi     nxami
346
347         bne     xiami
348         dec     mousex              ; 0 = left
349         bne     nxami
350 xiami:  inc     mousex              ; 1 = right
351
352 nxami:  tya
353
354         and     #%00000101
355         ora     dumy
356         tax
357         lda     amitab,x
358         bmi     nyami
359
360         bne     yiami
361         dec     mousey              ; 0 =  up
362         bne     nyami
363 yiami:  inc     mousey              ; 1 = down
364
365 ; store old readings
366
367 nyami:  tya
368         and     #%00001010
369         sta     dumx
370         tya
371         and     #%00000101
372         asl
373         sta     dumy
374         rts
375
376 ;--------------------------------------------------------------------
377 ; timer 1 IRQ routine - check mouse
378
379 t1_vec: tya
380         pha
381         txa
382         pha
383
384 .ifdef DEBUG
385         lda     RANDOM
386         sta     COLBK           ; debug
387 .endif
388
389         lda     port_nr
390         lsr                     ; even number 0/2
391         tay
392         lda     PORTA,y
393         ldy     port_nr
394         cpy     #0
395         beq     oddp
396         cpy     #2
397         beq     oddp
398
399         lsr
400         lsr
401         lsr
402         lsr
403 oddp:   tay
404
405 mouse_vec:
406         jsr     st_check        ; will be modified; won't be ROMmable
407
408         pla
409         tax
410         pla
411         tay
412         pla
413         rti
414
415 ;--------------------------------------------------------------------
416 ; VBI - check mouse limits and display mouse arrow
417
418 vbi:    lda     mousex
419         cmp     xmin
420         bcs     ok1             ; xmin <= mousex
421         lda     xmin
422         sta     mousex
423
424 ok1:    lda     mousey
425         cmp     ymin
426         bcs     ok2             ; ymin <= mousey
427         lda     ymin
428         sta     mousey
429
430 ok2:    lda     xmax
431         cmp     mousex
432         bcs     ok3             ; xmax >= mousex
433         lda     xmax
434         sta     mousex
435
436 ok3:    lda     ymax
437         cmp     mousey
438         bcs     ok4             ; ymax >= mousey
439         lda     ymax
440         sta     mousey
441
442 ok4:    jsr     clrpm
443
444         lda     mouse_on
445         bne     mon
446         lda     #0
447         sta     HPOSP0
448         beq     moff
449
450 mon:    jsr     drwpm
451         lda     mousey
452         sta     omy
453
454         lda     #3
455 moff:   sta     GRACTL
456
457 vbi_jmp:
458         jmp     SYSVBV          ; will be modified; won't be ROMmable
459
460 ;--------------------------------------------------------------------
461 ; initialize mouse pm
462
463 pminit: lda     mouse_pm0
464         sta     mpatch1+2
465         sta     mpatch2+2
466         sta     mpatch3+2
467
468         ldx     #0
469         txa
470 mpatch1:
471 clpm:   sta     $1000,x         ; will be patched
472         inx
473         bne     clpm
474
475         lda     mouse_pm0
476         sec
477         sbc     #4
478         sta     PMBASE
479
480         lda     #62
481         sta     SDMCTL
482
483         lda     #1
484         sta     GPRIOR
485
486         lda     #0
487         sta     PCOLR0
488         sta     SIZEP0
489         rts
490
491 ;--------------------------------------------------------------------
492 ; draw new mouse pm
493
494 drwpm:  lda     mousex
495         sta     HPOSP0
496
497         lda     mousey
498         tax
499
500         ldy     #0
501 fmp2:   lda     mskpm,y
502 mpatch2:
503         sta     $1000,x         ; will be patched
504         inx
505         iny
506         cpy     #pmsize
507         bne     fmp2
508         rts
509
510 ;--------------------------------------------------------------------
511 ; clear old mouse pm
512
513 clrpm:  lda     omy
514         tax
515
516         ldy     #0
517         tya
518 mpatch3:
519 fmp1:   sta     $1000,x         ; will be patched
520         inx
521         iny
522         cpy     #pmsize
523         bne     fmp1
524         rts
525
526 ;--------------------------------------------------------------------
527         .rodata
528
529 ; mouse arrow - pm shape
530
531 mskpm:  .byte %00000000
532         .byte %10000000
533         .byte %11000000
534         .byte %11000000
535
536         .byte %11100000
537         .byte %11100000
538         .byte %11110000
539         .byte %11100000
540
541         .byte %11100000
542         .byte %00100000
543         .byte %00100000
544         .byte %00110000
545
546         .byte %00110000
547         .byte %00000000
548         .byte %00000000
549         .byte %00000000
550
551 ; ST mouse lookup table
552
553 sttab:  .byte $FF,$01,$00,$01
554         .byte $00,$FF,$00,$01
555         .byte $01,$00,$FF,$00
556         .byte $01,$00,$01,$FF
557
558 ; Amiga mouse lookup table
559
560 amitab: .byte $FF,$01,$00,$FF
561         .byte $00,$FF,$FF,$01
562         .byte $01,$FF,$FF,$00
563         .byte $FF,$00,$01,$FF
564
565 ; Device vectors
566
567 lvectab:
568         .byte <trak_check, <st_check, <amiga_check
569 hvectab:
570         .byte >trak_check, >st_check, >amiga_check
571
572 ; default values
573
574 xmin:   .byte   defxmin
575 ymin:   .byte   defymin
576 xmax:   .byte   defxmax
577 ymax:   .byte   defymax
578
579 mousex: .byte   xinit
580 mousey: .byte   yinit
581
582 ;--------------------------------------------------------------------
583         .bss
584
585 ; Misc. vars
586
587 old_t1: .res 2          ; old timer interrupt vector
588 oldval: .res 1          ; used by trakball routines
589 dumx:   .res 1
590 dumy:   .res 1
591 omy:    .res 1          ; old y pos
592
593 mouse_on:
594         .res 1
595 port_nr:
596         .res 1
597 mouse_pm0:
598         .res 1