2 ; Ullrich von Bassewitz, 24.04.1999
4 ; Routines for the 1351 proportional mouse. Parts of the code are from
5 ; the Commodore 1351 mouse users guide.
8 .export _mouse_init, _mouse_done
9 .export _mouse_hide, _mouse_show
10 .export _mouse_box, _mouse_info
11 .export _mouse_x, _mouse_y
14 .import popa, popsreg, addysp1
23 ; --------------------------------------------------------------------------
25 ; void __fastcall__ mouse_init (unsigned char port, unsigned char sprite, unsigned char type);
29 jsr popa ; Ignore the type, get sprite param
30 tax ; Save sprite number
31 jsr popa ; Get the port number
33 ldy OldIRQ+1 ; Already initialized?
34 bne Done ; Jump if yes
36 stx MouseSprite ; Remember the sprite number
37 sta MousePort ; Remember the port number
39 ; Initialize variables
52 stx YMin+1 ; YMin = 29
55 stx YMax+1 ; YMax = 250
57 stx Visible ; Mouse *not* visible
60 stx XMax+1 ; XMax = 344
62 ; Remember the old IRQ vector
69 ; Set our own IRQ vector
75 ; --------------------------------------------------------------------------
77 ; void mouse_done (void);
81 lda OldIRQ ; Initialized?
85 sty OldIRQ+1 ; Reset the initialized flag
86 SetIRQ: sei ; Disable interrupts
87 sta IRQVec ; Set the new/old vector
89 cli ; Enable interrupts
92 ; --------------------------------------------------------------------------
94 ; void mouse_hide (void);
98 lda Visible ; Get the flag
99 bne @L1 ; Jump if already invisible
100 ldx MouseSprite ; Sprite defined?
103 lda NotMask-1,x ; Get clean mask
105 sei ; Disable interrupts
107 sta VIC_SPR_ENA ; Disable sprite
108 cli ; Enable interrupts
110 @L1: inc Visible ; Set the flag to invisible
113 ; --------------------------------------------------------------------------
115 ; void mouse_show (void);
119 lda Visible ; Mouse already visible?
120 beq @L1 ; Jump if yes
121 dec Visible ; Get the flag
122 bne @L1 ; Jump if still invisible
123 ldx MouseSprite ; Sprite defined?
126 sei ; Disable interrupts
127 jsr MoveSprite1 ; Move the sprite to it's position
129 ldx MouseSprite ; Get sprite number (again)
130 lda BitMask-1,x ; Get bit mask
132 sta VIC_SPR_ENA ; Enable sprite
134 cli ; Enable interrupts
138 ; --------------------------------------------------------------------------
140 ; void __fastcall__ mouse_box (int minx, int miny, int maxx, int maxy);
144 ldy #0 ; Stack offset
147 sei ; Disable interrupts
172 plp ; Enable interrupts
174 jmp addysp1 ; Drop params, return
176 ; --------------------------------------------------------------------------
178 ; int __fastcall__ mouse_x (void);
189 ; --------------------------------------------------------------------------
191 ; int __fastcall__ mouse_y (void);
202 ; --------------------------------------------------------------------------
204 ; void mouse_info (...);
211 ; --------------------------------------------------------------------------
213 ; void __fastcall__ mouse_move (int x, int y);
218 sei ; Disable interrupts
225 stx XPos+1 ; Set new position
227 jsr MoveSprite ; Move the sprite to the mouse pos
229 @L9: cli ; Enable interrupts
232 ; --------------------------------------------------------------------------
234 ; Mouse interrupt handler
239 lda SID_ADConv1 ; Get mouse X movement
241 jsr MoveCheck ; Calculate movement vector
244 ; Calculate the new X coordinate (--> a/y)
247 tay ; Remember low byte
252 ; Limit the X coordinate to the bounding box
270 ; Calculate the Y movement vector
272 lda SID_ADConv2 ; Get mouse Y movement
274 jsr MoveCheck ; Calculate movement
277 ; Calculate the new Y coordinate (--> a/y)
304 ; Move the mouse sprite if it is enabled
306 jsr MoveSprite ; Move the sprite
308 ; Jump to the next IRQ handler
313 ; --------------------------------------------------------------------------
315 ; Move check routine, called for both coordinates.
317 ; Entry: y = old value of pot register
318 ; a = current value of pot register
319 ; Exit: y = value to use for old value
320 ; x/a = delta value for position
328 sub OldValue ; a = mod64 (new - old)
330 cmp #%01000000 ; if (a > 0)
333 beq @L2 ; if (a != 0)
334 ldy NewValue ; y = NewValue
337 @L1: ora #%11000000 ; else or in high order bits
338 cmp #$FF ; if (a != -1)
342 dex ; high byte = -1 (X = $FF)
349 ; --------------------------------------------------------------------------
351 ; Move the mouse sprite to the current mouse position. Must be called
352 ; with interrupts off. MoveSprite1 is an entry without checking and
358 lda Visible ; Mouse visible?
359 bne MoveSpriteDone ; Jump if no
360 ldx MouseSprite ; Sprite defined?
361 beq MoveSpriteDone ; Jump if no
366 lda VIC_SPR_HI_X ; Get high X bits of all sprites
367 and NotMask-1,x ; Mask out sprite bit
368 ldy XPos+1 ; Test Y position
370 ora BitMask-1,x ; Set high X bit
371 @L1: sta VIC_SPR_HI_X ; Set hi X sprite values
379 sta VIC_SPR0_X-2,x ; Set low byte
383 ldy YPos+1 ; Negative or too large?
384 bne MoveSpriteDone ; Jump if yes
386 sta VIC_SPR0_Y-2,x ; Set Y position
393 ; --------------------------------------------------------------------------
398 OldIRQ: .res 2 ; Old IRQ vector
399 MousePort: .res 1 ; Port used for the mouse
400 MouseSprite: .res 1 ; Number of sprite to control
401 OldValue: .res 1 ; Temp for MoveCheck routine
402 NewValue: .res 1 ; Temp for MoveCheck routine
404 Visible: .res 1 ; Is the mouse visible?
405 OldPotX: .res 1 ; Old hw counter values
408 XPos: .res 2 ; Current mouse position, X
409 YPos: .res 2 ; Current mouse position, Y
411 XMin: .res 2 ; X1 value of bounding box
412 YMin: .res 2 ; Y1 value of bounding box
413 XMax: .res 2 ; X2 value of bounding box
414 YMax: .res 2 ; Y2 value of bounding box
418 BitMask: .byte $01, $02, $04, $08, $10, $20, $40, $80
419 NotMask: .byte $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F