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