]> git.sur5r.net Git - cc65/blob - libsrc/atari/mou/atrst.s
Adapt to new mouse driver interface ('prep' and 'draw')
[cc65] / libsrc / atari / mou / atrst.s
1 ;
2 ; Mouse driver for ST & Amiga mouses and Atari trakball.
3 ;
4 ; Original access routines: 05/07/2000 Freddy Offenga
5 ; Converted to driver: Christian Groessler, 2014-01-04
6 ;
7 ; Defines:
8 ;       AMIGA_MOUSE     -       builds Amiga mouse version
9 ;       TRAK_MOUSE      -       builds trakball version
10 ; If none of these defines are active, the ST mouse version
11 ; is being built.
12 ;
13
14         .include        "zeropage.inc"
15         .include        "mouse-kernel.inc"
16         .include        "atari.inc"
17
18         .macpack        generic
19
20 .if .not ( .defined (AMIGA_MOUSE) .or .defined (TRAK_MOUSE))
21         ST_MOUSE = 1
22 .endif
23
24 ; ------------------------------------------------------------------------
25 ; Header. Includes jump table
26
27 .segment        "JUMPTABLE"
28
29 HEADER:
30
31 ; Driver signature
32
33         .byte   $6d, $6f, $75           ; "mou"
34         .byte   MOUSE_API_VERSION       ; Mouse driver API version number
35
36 ; Library reference
37
38 libref: .addr   $0000
39
40 ; Jump table
41
42         .addr   INSTALL
43         .addr   UNINSTALL
44         .addr   HIDE
45         .addr   SHOW
46         .addr   SETBOX
47         .addr   GETBOX
48         .addr   MOVE
49         .addr   BUTTONS
50         .addr   POS
51         .addr   INFO
52         .addr   IOCTL
53         .addr   IRQ
54
55 ; Mouse driver flags
56
57         .byte   MOUSE_FLAG_LATE_IRQ
58
59 ; Callback table, set by the kernel before INSTALL is called
60
61 CHIDE:  jmp     $0000                   ; Hide the cursor
62 CSHOW:  jmp     $0000                   ; Show the cursor
63 CPREP:  jmp     $0000                   ; Prepare to move the cursor
64 CDRAW:  jmp     $0000                   ; Draw the cursor
65 CMOVEX: jmp     $0000                   ; Move the cursor to X coord
66 CMOVEY: jmp     $0000                   ; Move the cursor to Y coord
67
68
69 ;----------------------------------------------------------------------------
70 ; Constants
71
72 SCREEN_HEIGHT   = 191
73 SCREEN_WIDTH    = 319
74
75 .enum   JOY
76         UP      = $01
77         DOWN    = $02
78         LEFT    = $04
79         RIGHT   = $08
80 .endenum
81
82 ;----------------------------------------------------------------------------
83 ; Global variables. The bounding box values are sorted so that they can be
84 ; written with the least effort in the SETBOX and GETBOX routines, so don't
85 ; reorder them.
86
87 .bss
88
89 Vars:
90 YPos:           .res    2               ; Current mouse position, Y
91 XPos:           .res    2               ; Current mouse position, X
92 XMin:           .res    2               ; X1 value of bounding box
93 YMin:           .res    2               ; Y1 value of bounding box
94 XMax:           .res    2               ; X2 value of bounding box
95 YMax:           .res    2               ; Y2 value of bounding box
96 Buttons:        .res    1               ; Button mask
97
98 XPosWrk:        .res    2
99 YPosWrk:        .res    2
100
101 .if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE)
102 dumx:           .res    1
103 dumy:           .res    1
104 .endif
105
106 .ifdef TRAK_MOUSE
107 oldval:         .res    1
108 .endif
109
110 .ifndef __ATARIXL__
111 OldT1:          .res    2
112 .else
113
114 .data
115 set_VTIMR1_handler:
116                 .byte   $4C, 0, 0
117 .endif
118
119 .rodata
120
121 ; Default values for some of the above variables
122 ; (We use ".proc" because we want to define both a label and a scope.)
123
124 .proc   DefVars
125         .word   (SCREEN_HEIGHT+1)/2     ; YPos
126         .word   (SCREEN_WIDTH+1)/2      ; XPos
127         .word   0                       ; XMin
128         .word   0                       ; YMin
129         .word   SCREEN_WIDTH            ; XMax
130         .word   SCREEN_HEIGHT           ; YMax
131         .byte   0                       ; Buttons
132 .endproc
133
134 .ifdef ST_MOUSE
135
136 ; ST mouse lookup table
137
138 STTab:  .byte $FF,$01,$00,$01
139         .byte $00,$FF,$00,$01
140         .byte $01,$00,$FF,$00
141         .byte $01,$00,$01,$FF
142
143 .endif
144
145 .ifdef AMIGA_MOUSE
146
147 ; Amiga mouse lookup table
148
149 AmiTab: .byte $FF,$01,$00,$FF
150         .byte $00,$FF,$FF,$01
151         .byte $01,$FF,$FF,$00
152         .byte $FF,$00,$01,$FF
153
154 .endif
155
156 .code
157
158 ;----------------------------------------------------------------------------
159 ; INSTALL routine. Is called after the driver is loaded into memory. If
160 ; possible, check if the hardware is present.
161 ; Must return an MOUSE_ERR_xx code in a/x.
162
163 INSTALL:
164
165 ; Initialize variables. Just copy the default stuff over
166
167         ldx     #.sizeof(DefVars)-1
168 @L1:    lda     DefVars,x
169         sta     Vars,x
170         dex
171         bpl     @L1
172
173 ; Make sure the mouse cursor is at the default location.
174
175         lda     XPos
176         sta     XPosWrk
177         ldx     XPos+1
178         stx     XPosWrk+1
179         jsr     CMOVEX
180         lda     YPos
181         sta     YPosWrk
182         ldx     YPos+1
183         stx     YPosWrk+1
184         jsr     CMOVEY
185
186 ; Install timer irq routine to poll mouse.
187
188 .ifdef __ATARIXL__
189
190         ; Setup pointer to wrapper install/deinstall function.
191         lda     libref
192         sta     set_VTIMR1_handler+1
193         lda     libref+1
194         sta     set_VTIMR1_handler+2
195
196         ; Install my handler.
197         sec
198         lda     #<T1Han
199         ldx     #>T1Han
200         jsr     set_VTIMR1_handler
201
202 .else
203
204         lda     VTIMR1
205         sta     OldT1
206         lda     VTIMR1+1
207         sta     OldT1+1
208
209         php
210         sei
211         lda     #<T1Han
212         sta     VTIMR1
213         lda     #>T1Han
214         sta     VTIMR1+1
215         plp
216
217 .endif
218
219         lda     #%00000001
220         sta     AUDCTL
221
222         lda     #0
223         sta     AUDC1
224
225         lda     #15
226         sta     AUDF1
227         sta     STIMER
228
229         lda     POKMSK
230         ora     #%00000001              ; timer 1 enable
231         sta     POKMSK
232         sta     IRQEN
233
234 ; Done, return zero (= MOUSE_ERR_OK)
235
236         ldx     #$00
237         txa
238         rts
239
240 ;----------------------------------------------------------------------------
241 ; UNINSTALL routine. Is called before the driver is removed from memory.
242 ; No return code required (the driver is removed from memory on return).
243
244 UNINSTALL:
245
246 ; uninstall timer irq routine
247
248         lda     POKMSK
249         and     #%11111110              ; timer 1 disable
250         sta     IRQEN
251         sta     POKMSK
252
253 .ifdef __ATARIXL__
254
255         clc
256         jsr     set_VTIMR1_handler
257
258 .else
259
260         php
261         sei
262         lda     OldT1
263         sta     VTIMR1
264         lda     OldT1+1
265         sta     VTIMR1+1
266         plp
267
268 .endif
269         ; fall thru...
270
271 ;----------------------------------------------------------------------------
272 ; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
273 ; a counter for calls to show/hide, and the driver entry point is only called
274 ; if the mouse is currently visible and should get hidden. For most drivers,
275 ; no special action is required besides hiding the mouse cursor.
276 ; No return code required.
277
278 HIDE:   php
279         sei
280         jsr     CHIDE
281         plp
282         rts
283
284 ;----------------------------------------------------------------------------
285 ; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
286 ; a counter for calls to show/hide, and the driver entry point is only called
287 ; if the mouse is currently hidden and should become visible. For most drivers,
288 ; no special action is required besides enabling the mouse cursor.
289 ; No return code required.
290
291 SHOW:   php
292         sei
293         jsr     CSHOW
294         plp
295         rts
296
297 ;----------------------------------------------------------------------------
298 ; SETBOX: Set the mouse bounding box. The parameters are passed as they come
299 ; from the C program, that is, a pointer to a mouse_box struct in a/x.
300 ; No checks are done if the mouse is currently inside the box, this is the job
301 ; of the caller. It is not necessary to validate the parameters, trust the
302 ; caller and save some code here. No return code required.
303
304 SETBOX: sta     ptr1
305         stx     ptr1+1                  ; Save data pointer
306
307         ldy     #.sizeof (MOUSE_BOX)-1
308         php
309         sei
310
311 @L1:    lda     (ptr1),y
312         sta     XMin,y
313         dey
314         bpl     @L1
315
316         plp
317         rts
318
319 ;----------------------------------------------------------------------------
320 ; GETBOX: Return the mouse bounding box. The parameters are passed as they
321 ; come from the C program, that is, a pointer to a mouse_box struct in a/x.
322
323 GETBOX: sta     ptr1
324         stx     ptr1+1                  ; Save data pointer
325
326         ldy     #.sizeof (MOUSE_BOX)-1
327         php
328         sei
329
330 @L1:    lda     XMin,y
331         sta     (ptr1),y
332         dey
333         bpl     @L1
334
335         plp
336         rts
337
338 ;----------------------------------------------------------------------------
339 ; MOVE: Move the mouse to a new position. The position is passed as it comes
340 ; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
341 ; remove the parameter from the stack on return.
342 ; No checks are done if the new position is valid (within the bounding box or
343 ; the screen). No return code required.
344 ;
345
346 MOVE:   php
347         sei                             ; No interrupts
348
349         pha
350         txa
351         pha
352         jsr     CPREP
353         pla
354         tax
355         pla
356
357         sta     YPos
358         sta     YPosWrk
359         stx     YPos+1                  ; New Y position
360         stx     YPosWrk+1
361         jsr     CMOVEY                  ; Set it
362
363         ldy     #$01
364         lda     (sp),y
365         sta     XPos+1
366         sta     XPosWrk+1
367         tax
368         dey
369         lda     (sp),y
370         sta     XPos                    ; New X position
371         sta     XPosWrk
372         jsr     CMOVEX                  ; Move the cursor
373
374         jsr     CDRAW
375
376         plp                             ; Restore interrupt flag
377         rts
378
379 ;----------------------------------------------------------------------------
380 ; BUTTONS: Return the button mask in a/x.
381
382 BUTTONS:
383         lda     Buttons
384         ldx     #$00
385         rts
386
387 ;----------------------------------------------------------------------------
388 ; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
389 ; No return code required.
390
391 POS:    ldy     #MOUSE_POS::XCOORD      ; Structure offset
392
393         php
394         sei                             ; Disable interrupts
395         lda     XPos                    ; Transfer the position
396         sta     (ptr1),y
397         lda     XPos+1
398         iny
399         sta     (ptr1),y
400         lda     YPos
401         iny
402         sta     (ptr1),y
403         lda     YPos+1
404         plp                             ; Restore interrupt flag
405
406         iny
407         sta     (ptr1),y                ; Store last byte
408
409         rts                             ; Done
410
411 ;----------------------------------------------------------------------------
412 ; INFO: Returns mouse position and current button mask in the MOUSE_INFO
413 ; struct pointed to by ptr1. No return code required.
414 ;
415 ; We're cheating here to keep the code smaller: The first fields of the
416 ; mouse_info struct are identical to the mouse_pos struct, so we will just
417 ; call _mouse_pos to initialize the struct pointer and fill the position
418 ; fields.
419
420 INFO:   jsr     POS
421
422 ; Fill in the button state
423
424         lda     Buttons
425         ldy     #MOUSE_INFO::BUTTONS
426         sta     (ptr1),y
427
428         rts
429
430 ;----------------------------------------------------------------------------
431 ; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
432 ; specific data in ptr1, and the ioctl code in A.
433 ; Must return an error code in a/x.
434 ;
435
436 IOCTL:  lda     #<MOUSE_ERR_INV_IOCTL     ; We don't support ioclts for now
437         ldx     #>MOUSE_ERR_INV_IOCTL
438         rts
439
440 ;----------------------------------------------------------------------------
441 ; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
442 ; (so be careful). The routine MUST return carry set if the interrupt has been
443 ; 'handled' - which means that the interrupt source is gone. Otherwise it
444 ; MUST return carry clear.
445 ;
446
447 IRQ:
448
449 ; Check for a pressed button and place the result into Buttons
450
451         ldx     #0
452         lda     TRIG0                   ; joystick #0 trigger
453         bne     @L0                     ; not pressed
454         ldx     #MOUSE_BTN_LEFT
455 @L0:    stx     Buttons
456
457         jsr     CPREP
458
459 ; Limit the X coordinate to the bounding box
460
461         lda     XPosWrk+1
462         ldy     XPosWrk
463         tax
464         cpy     XMin
465         sbc     XMin+1
466         bpl     @L2
467         ldy     XMin
468         ldx     XMin+1
469         jmp     @L3
470 @L2:    txa
471
472         cpy     XMax
473         sbc     XMax+1
474         bmi     @L3
475         ldy     XMax
476         ldx     XMax+1
477 @L3:    sty     XPos
478         stx     XPos+1
479
480         tya
481         jsr     CMOVEX
482
483 ; Limit the Y coordinate to the bounding box
484
485         lda     YPosWrk+1
486         ldy     YPosWrk
487         tax
488         cpy     YMin
489         sbc     YMin+1
490         bpl     @L4
491         ldy     YMin
492         ldx     YMin+1
493         jmp     @L5
494 @L4:    txa
495
496         cpy     YMax
497         sbc     YMax+1
498         bmi     @L5
499         ldy     YMax
500         ldx     YMax+1
501 @L5:    sty     YPos
502         stx     YPos+1
503
504         tya
505         jsr     CMOVEY
506
507         jsr     CDRAW
508
509         clc
510         rts
511
512
513 ;----------------------------------------------------------------------------
514 ; T1Han: Local IRQ routine to poll mouse
515 ;
516
517 T1Han:  tya
518         pha
519         txa
520         pha
521
522 .ifdef DEBUG
523         lda     RANDOM
524         sta     COLBK
525 .endif
526
527         lda     PORTA
528         tay
529
530 .ifdef ST_MOUSE
531
532 ; ST mouse version
533
534         and     #%00000011
535         ora     dumx
536         tax
537         lda     STTab,x
538         bmi     nxst
539
540         beq     xist
541
542         dec     XPosWrk
543         lda     XPosWrk
544         cmp     #255
545         bne     nxst
546         dec     XPosWrk+1
547         jmp     nxst
548
549 xist:   inc     XPosWrk
550         bne     nxst
551         inc     XPosWrk+1
552
553 nxst:   tya
554         and     #%00001100
555         ora     dumy
556         tax
557         lda     STTab,x
558         bmi     nyst
559
560         bne     yst
561
562         dec     YPosWrk
563         lda     YPosWrk
564         cmp     #255
565         bne     nyst
566         dec     YPosWrk+1
567         jmp     nyst
568
569 yst:    inc     YPosWrk
570         bne     nyst
571         inc     YPosWrk+1
572
573 ; store old readings
574
575 nyst:   tya
576         and     #%00000011
577         asl
578         asl
579         sta     dumx
580         tya
581         and     #%00001100
582         lsr
583         lsr
584         sta     dumy
585
586 .elseif .defined (AMIGA_MOUSE)
587
588 ; Amiga mouse version
589
590         lsr
591         and     #%00000101
592         ora     dumx
593         tax
594         lda     AmiTab,x
595         bmi     nxami
596
597         bne     xiami
598
599         dec     XPosWrk
600         lda     XPosWrk
601         cmp     #255
602         bne     nxami
603         dec     XPosWrk+1
604         jmp     nxami
605
606 xiami:  inc     XPosWrk
607         bne     nxami
608         inc     XPosWrk+1
609
610 nxami:  tya
611
612         and     #%00000101
613         ora     dumy
614         tax
615         lda     AmiTab,x
616         bmi     nyami
617
618         bne     yiami
619
620         dec     YPosWrk
621         lda     YPosWrk
622         cmp     #255
623         bne     nyami
624         dec     YPosWrk+1
625         jmp     nyami
626
627 yiami:  inc     YPosWrk
628         bne     nyami
629         inc     YPosWrk+1
630
631 ; store old readings
632
633 nyami:  tya
634         and     #%00001010
635         sta     dumx
636         tya
637         and     #%00000101
638         asl
639         sta     dumy
640
641 .elseif .defined (TRAK_MOUSE)
642
643 ; trakball version
644
645         eor     oldval
646         and     #%00001000
647         beq     horiz
648
649         tya
650         and     #%00000100
651         beq     mmup
652
653         inc     YPosWrk
654         bne     horiz
655         inc     YPosWrk+1
656         bne     horiz
657
658 mmup:   dec     YPosWrk
659         lda     YPosWrk
660         cmp     #255
661         bne     horiz
662         dec     YPosWrk+1
663
664 horiz:  tya
665         eor     oldval
666         and     #%00000010
667         beq     mmexit
668
669         tya
670         and     #%00000001
671         beq     mmleft
672
673         inc     XPosWrk
674         bne     mmexit
675         inc     XPosWrk+1
676         bne     mmexit
677
678 mmleft: dec     XPosWrk
679         lda     XPosWrk
680         cmp     #255
681         bne     mmexit
682         dec     XPosWrk+1
683
684 mmexit: sty     oldval
685
686 .endif
687
688         pla
689         tax
690         pla
691         tay
692 .ifdef  __ATARIXL__
693         rts
694 .else
695         pla
696         rti
697 .endif