--- /dev/null
+;
+; Mouse driver for ST & Amiga mouses and Atari trakball.
+;
+; Original access routines: 05/07/2000 Freddy Offenga
+; Converted to driver: Christian Groessler, 2014-01-04
+;
+; Defines:
+; AMIGA_MOUSE - builds Amiga mouse version
+; TRAK_MOUSE - builds trakball version
+; If none of these defines are active, the ST mouse version
+; is being built.
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "atari.inc"
+
+ .macpack generic
+
+.if .not ( .defined (AMIGA_MOUSE) .or .defined (TRAK_MOUSE))
+ ST_MOUSE = 1
+.endif
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Library reference
+
+ .addr $0000
+
+; Jump table
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 191
+SCREEN_WIDTH = 319
+
+.enum JOY
+ UP = $01
+ DOWN = $02
+ LEFT = $04
+ RIGHT = $08
+.endenum
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; Button mask
+
+XPosWrk: .res 2
+YPosWrk: .res 2
+
+OldT1: .res 2
+visible: .res 1
+
+.if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE)
+dumx: .res 1
+dumy: .res 1
+.endif
+
+.ifdef TRAK_MOUSE
+oldval: .res 1
+.endif
+
+
+; Default values for some of the above variables
+
+.rodata
+
+.proc DefVars
+ .word (SCREEN_HEIGHT+1)/2 ; YPos
+ .word (SCREEN_WIDTH+1)/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte 0 ; Buttons
+.endproc
+
+.ifdef ST_MOUSE
+
+; ST mouse lookup table
+
+STTab: .byte $FF,$01,$00,$01
+ .byte $00,$FF,$00,$01
+ .byte $01,$00,$FF,$00
+ .byte $01,$00,$01,$FF
+
+.endif
+
+.ifdef AMIGA_MOUSE
+
+; Amiga mouse lookup table
+
+AmiTab: .byte $FF,$01,$00,$FF
+ .byte $00,$FF,$FF,$01
+ .byte $01,$FF,$FF,$00
+ .byte $FF,$00,$01,$FF
+
+.endif
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ sta XPosWrk
+ ldx XPos+1
+ stx XPosWrk+1
+ jsr CMOVEX
+ lda YPos
+ sta YPosWrk
+ ldx YPos+1
+ stx YPosWrk+1
+ jsr CMOVEY
+ cli
+
+; install timer irq routine to poll mouse
+
+ lda VTIMR1
+ sta OldT1
+ lda VTIMR1+1
+ sta OldT1+1
+
+ php
+ sei
+ lda #<T1Han
+ sta VTIMR1
+ lda #>T1Han
+ sta VTIMR1+1
+ plp
+
+ lda #%00000001
+ sta AUDCTL
+
+ lda #0
+ sta AUDC1
+
+ lda #15
+ sta AUDF1
+ sta STIMER
+
+ lda POKMSK
+ ora #%00000001 ; timer 1 enable
+ sta POKMSK
+ sta IRQEN
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL:
+
+; uninstall timer irq routine
+
+ lda POKMSK
+ and #%11111110 ; timer 1 disable
+ sta IRQEN
+ sta POKMSK
+
+ php
+ sei
+ lda OldT1
+ sta VTIMR1
+ lda OldT1+1
+ sta VTIMR1+1
+ plp
+
+ ; fall thru...
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: dec visible
+ php
+ sei
+ jsr CHIDE
+ plp
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: inc visible
+ php
+ sei
+ jsr CSHOW
+ plp
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ php
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ plp
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ php
+ sei
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ plp
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: php
+ sei ; No interrupts
+
+ pha
+ txa
+ pha
+
+ lda visible
+ beq @L01
+
+ jsr CHIDE
+
+@L01: pla
+ tax
+ pla
+
+ sta YPos
+ sta YPosWrk
+ stx YPos+1 ; New Y position
+ stx YPosWrk+1
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ sta XPosWrk+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+ sta XPosWrk
+
+ jsr CMOVEX ; Move the cursor
+
+ lda visible
+ beq @Ret
+
+ jsr CSHOW
+
+@Ret: plp ; Restore interrupt flag
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #$00
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ php
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ plp ; Restore interrupt flag
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ lda Buttons
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful). The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+;
+
+IRQ:
+
+; Check for a pressed button and place the result into Buttons
+
+ ldx #0
+ lda TRIG0 ; joystick #0 trigger
+ bne @L0 ; not pressed
+ ldx #MOUSE_BTN_LEFT
+@L0: stx Buttons
+
+; Update coordinates if needed
+
+ lda XPosWrk
+ cmp XPos
+ bne @Update
+ lda XPosWrk+1
+ cmp XPos+1
+ bne @Update
+ lda YPosWrk
+ cmp YPos
+ bne @Update
+ lda YPosWrk+1
+ cmp YPos+1
+ beq @Done
+
+@Update:ldx visible
+ beq @L1
+ jsr CHIDE
+
+; Limit the X coordinate to the bounding box
+
+@L1: lda XPosWrk+1
+ ldy XPosWrk
+ tax
+ cpy XMin
+ sbc XMin+1
+ bpl @L2
+ ldy XMin
+ ldx XMin+1
+ jmp @L3
+@L2: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L3
+ ldy XMax
+ ldx XMax+1
+@L3: sty XPos
+ stx XPos+1
+
+ tya
+ jsr CMOVEX
+
+; Limit the Y coordinate to the bounding box
+
+ lda YPosWrk+1
+ ldy YPosWrk
+ tax
+ cpy YMin
+ sbc YMin+1
+ bpl @L4
+ ldy YMin
+ ldx YMin+1
+ jmp @L5
+@L4: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L5
+ ldy YMax
+ ldx YMax+1
+@L5: sty YPos
+ stx YPos+1
+
+ tya
+ jsr CMOVEY
+
+ ldx visible
+ beq @Done
+
+ jsr CSHOW
+
+@Done: clc
+ rts
+
+;----------------------------------------------------------------------------
+; T1Han: Local IRQ routine to poll mouse
+;
+
+T1Han: tya
+ pha
+ txa
+ pha
+
+.ifdef DEBUG
+ lda RANDOM
+ sta COLBK
+.endif
+
+ lda PORTA
+ tay
+
+.ifdef ST_MOUSE
+
+; ST mouse version
+
+ and #%00000011
+ ora dumx
+ tax
+ lda STTab,x
+ bmi nxst
+
+ beq xist
+
+ dec XPosWrk
+ lda XPosWrk
+ cmp #255
+ bne nxst
+ dec XPosWrk+1
+ jmp nxst
+
+xist: inc XPosWrk
+ bne nxst
+ inc XPosWrk+1
+
+nxst: tya
+ and #%00001100
+ ora dumy
+ tax
+ lda STTab,x
+ bmi nyst
+
+ bne yst
+
+ dec YPosWrk
+ lda YPosWrk
+ cmp #255
+ bne nyst
+ dec YPosWrk+1
+ jmp nyst
+
+yst: inc YPosWrk
+ bne nyst
+ inc YPosWrk+1
+
+; store old readings
+
+nyst: tya
+ and #%00000011
+ asl
+ asl
+ sta dumx
+ tya
+ and #%00001100
+ lsr
+ lsr
+ sta dumy
+
+.elseif .defined (AMIGA_MOUSE)
+
+; Amiga mouse version
+
+ lsr
+ and #%00000101
+ ora dumx
+ tax
+ lda AmiTab,x
+ bmi nxami
+
+ bne xiami
+
+ dec XPosWrk
+ lda XPosWrk
+ cmp #255
+ bne nxami
+ dec XPosWrk+1
+ jmp nxami
+
+xiami: inc XPosWrk
+ bne nxami
+ inc XPosWrk+1
+
+nxami: tya
+
+ and #%00000101
+ ora dumy
+ tax
+ lda AmiTab,x
+ bmi nyami
+
+ bne yiami
+
+ dec YPosWrk
+ lda YPosWrk
+ cmp #255
+ bne nyami
+ dec YPosWrk+1
+ jmp nyami
+
+yiami: inc YPosWrk
+ bne nyami
+ inc YPosWrk+1
+
+; store old readings
+
+nyami: tya
+ and #%00001010
+ sta dumx
+ tya
+ and #%00000101
+ asl
+ sta dumy
+
+.elseif .defined (TRAK_MOUSE)
+
+; trakball version
+
+ eor oldval
+ and #%00001000
+ beq horiz
+
+ tya
+ and #%00000100
+ beq mmup
+
+ inc YPosWrk
+ bne horiz
+ inc YPosWrk+1
+ bne horiz
+
+mmup: dec YPosWrk
+ lda YPosWrk
+ cmp #255
+ bne horiz
+ dec YPosWrk+1
+
+horiz: tya
+ eor oldval
+ and #%00000010
+ beq mmexit
+
+ tya
+ and #%00000001
+ beq mmleft
+
+ inc XPosWrk
+ bne mmexit
+ inc XPosWrk+1
+ bne mmexit
+
+mmleft: dec XPosWrk
+ lda XPosWrk
+ cmp #255
+ bne mmexit
+ dec XPosWrk+1
+
+mmexit: sty oldval
+
+.endif
+
+ pla
+ tax
+ pla
+ tay
+ pla
+ rti
+
+++ /dev/null
-;--------------------------------------------------------------------
-; Atari 8-bit mouse routines -- 05/07/2000 Freddy Offenga
-; Some changes by Christian Groessler, Ullrich von Bassewitz
-;
-; The following devices are supported:
-; - Atari trak-ball
-; - ST mouse
-; - Amiga mouse
-;
-; Mouse checks are done in the timer 1 IRQ and the mouse arrow is
-; drawn in player 0 during the vertical blank
-;--------------------------------------------------------------------
-
- .export _mouse_init, _mouse_done, _mouse_box
- .export _mouse_show, _mouse_hide, _mouse_move
- .export _mouse_buttons, _mouse_pos, _mouse_info
- .constructor initmouse,27
-
- .import popax
- .importzp ptr1
-
- .include "atari.inc"
-
-TRAK_BALL = 0 ; device Atari trak-ball
-ST_MOUSE = 1 ; device ST mouse
-AMIGA_MOUSE = 2 ; device Amiga mouse
-MAX_TYPE = 3 ; first illegal device type
-
-; the default values force the mouse cursor inside the test screen (no access to border)
-defxmin = 48 ; default x minimum
-defymin = 31 ; default y minimum
-defxmax = 204 ; default x maximum
-defymax = 211 ; default y maximum
-
-pmsize = 16 ; y size pm shape
-
-xinit = defxmin ; init. x pos.
-yinit = defymin ; init. y pos.
-
-;--------------------------------------------------------------------
-; reserve memory for the mouse pointer
-
-initmouse:
- lda APPMHI+1
- and #%11111000 ; make 2k aligned
- sec
- sbc #%00001000 ; reserve 2k
- tax
- adc #3 ; add 4 (C = 1)
- sta mouse_pm0
- lda #0
- sta APPMHI
- stx APPMHI+1
- rts
-
-
-;--------------------------------------------------------------------
-; Initialize mouse routines
-; void __fastcall__ mouse_init (unsigned char type);
-
-_mouse_init:
- cmp #MAX_TYPE+1 ; Check for a valid type
- bcc setup
-
-ifail: lda #0 ; init. failed
- tax
- rts
-
-setup: tax
- lda lvectab,x
- sta mouse_vec+1
- lda hvectab,x
- sta mouse_vec+2
-
- jsr pminit
-
- lda VTIMR1
- sta old_t1
- lda VTIMR1+1
- sta old_t1+1
-
- lda #<t1_vec
- sta VTIMR1
- lda #>t1_vec
- sta VTIMR1+1
-
- lda #%00000001
- sta AUDCTL
-
- lda #0
- sta AUDC1
-
- lda #15
- sta AUDF1
- sta STIMER
-
- sei
- lda POKMSK
- ora #%00000001 ; timer 1 enable
- sta POKMSK
- sta IRQEN
- cli
-
- lda VVBLKI
- sta vbi_jmp+1
- lda VVBLKI+1
- sta vbi_jmp+2
-
- lda #6
- ldy #<vbi
- ldx #>vbi
- jsr SETVBV
-
- lda #$C0
- sta NMIEN
-
- ldx #0
- lda #1
- sta mouse_off
- rts
-
-;--------------------------------------------------------------------
-; Finish mouse routines
-; void mouse_done(void)
-
-_mouse_done:
- sei
- lda POKMSK
- and #%11111110 ; timer 1 disable
- sta IRQEN
- sta POKMSK
- cli
-
- lda old_t1
- sta VTIMR1
- lda old_t1+1
- sta VTIMR1+1
-
- lda #$40
- sta NMIEN
-
- lda #6
- ldy vbi_jmp+1
- ldx vbi_jmp+2
- jsr SETVBV
-
- ldx #0
- stx GRACTL
- stx HPOSP0
- inx
- stx mouse_off
- rts
-
-;--------------------------------------------------------------------
-; Set mouse limits
-; void __fastcall__ mouse_box(int xmin, int ymin, int xmax, int ymax)
-
-_mouse_box:
- sta ymax
- jsr popax ; always ignore high byte
- sta xmax
- jsr popax
- sta ymin
- jsr popax
- sta xmin
- rts
-
-;--------------------------------------------------------------------
-; Set mouse position
-; void __fastcall__ mouse_move(int xpos, int ypos)
-
-_mouse_move:
- sta mousey ; always ignore high byte
- jsr popax
- sta mousex
- rts
-
-;--------------------------------------------------------------------
-; Show mouse arrow
-; void mouse_show(void)
-
-_mouse_show:
- lda mouse_off ; Already on?
- beq @L1
- dec mouse_off
-@L1: rts
-
-;--------------------------------------------------------------------
-; Hide mouse arrow
-; void mouse_hide(void)
-
-_mouse_hide:
- inc mouse_off
- rts
-
-;--------------------------------------------------------------------
-; Ask mouse button
-; unsigned char mouse_buttons(void)
-
-_mouse_buttons:
- ldx #0
- lda STRIG0
- bne nobut
-; lda #14
-;??? sta COLOR1
- lda #1
- rts
-nobut: txa
- rts
-
-;--------------------------------------------------------------------
-; Get the mouse position
-; void mouse_pos (struct mouse_pos* pos);
-
-_mouse_pos:
- sta ptr1
- stx ptr1+1 ; Store argument pointer
- ldy #0
- lda mousex ; X position
- sta (ptr1),y
- lda #0
- iny
- sta (ptr1),y
- lda mousey ; Y position
- iny
- sta (ptr1),y
- lda #0
- iny
- sta (ptr1),y
- rts
-
-;--------------------------------------------------------------------
-; Get the mouse position and button information
-; void mouse_info (struct mouse_info* info);
-
-_mouse_info:
-
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
- jsr _mouse_pos
-
-; Fill in the button state
-
- jsr _mouse_buttons ; Will not touch ptr1
- ldy #4
- sta (ptr1),y
-
- rts
-
-;--------------------------------------------------------------------
-; Atari trak-ball check, A,Y = 4-bit port value
-
-trak_check:
- eor oldval
- and #%00001000
- beq horiz
-
- tya
- and #%00000100
- beq mmup
-
- inc mousey
- bne horiz
-
-mmup: dec mousey
-
-horiz: tya
- eor oldval
- and #%00000010
- beq mmexit
-
- tya
- and #%00000001
- beq mmleft
-
- inc mousex
- bne mmexit
-
-mmleft: dec mousex
-
-mmexit: sty oldval
- rts
-
-;--------------------------------------------------------------------
-; ST mouse check, A,Y = 4-bit port value
-
-st_check:
- and #%00000011
- ora dumx
- tax
- lda sttab,x
- bmi nxst
-
- beq xist
- dec mousex ; 1 = left
- bne nxst
-xist: inc mousex ; 0 = right
-
-nxst: tya
- and #%00001100
- ora dumy
- tax
- lda sttab,x
- bmi nyst
-
- bne yst
- dec mousey ; 0 = up
- bne nyst
-yst: inc mousey ; 1 = down
-
-; store old readings
-
-nyst: tya
- and #%00000011
- asl
- asl
- sta dumx
- tya
- and #%00001100
- lsr
- lsr
- sta dumy
- rts
-
-;--------------------------------------------------------------------
-; Amiga mouse check, A,Y = 4-bit port value
-
-amiga_check:
-
- lsr
- and #%00000101
- ora dumx
- tax
- lda amitab,x
- bmi nxami
-
- bne xiami
- dec mousex ; 0 = left
- bne nxami
-xiami: inc mousex ; 1 = right
-
-nxami: tya
-
- and #%00000101
- ora dumy
- tax
- lda amitab,x
- bmi nyami
-
- bne yiami
- dec mousey ; 0 = up
- bne nyami
-yiami: inc mousey ; 1 = down
-
-; store old readings
-
-nyami: tya
- and #%00001010
- sta dumx
- tya
- and #%00000101
- asl
- sta dumy
- rts
-
-;--------------------------------------------------------------------
-; timer 1 IRQ routine - check mouse
-
-t1_vec: tya
- pha
- txa
- pha
-
-.ifdef DEBUG
- lda RANDOM
- sta COLBK ; debug
-.endif
-
- lda PORTA
- tay
-
-mouse_vec:
- jsr st_check ; will be modified; won't be ROMmable
-
- pla
- tax
- pla
- tay
- pla
- rti
-
-;--------------------------------------------------------------------
-; VBI - check mouse limits and display mouse arrow
-
-vbi: lda mousex
- cmp xmin
- bcs ok1 ; xmin <= mousex
- lda xmin
- sta mousex
-
-ok1: lda mousey
- cmp ymin
- bcs ok2 ; ymin <= mousey
- lda ymin
- sta mousey
-
-ok2: lda xmax
- cmp mousex
- bcs ok3 ; xmax >= mousex
- lda xmax
- sta mousex
-
-ok3: lda ymax
- cmp mousey
- bcs ok4 ; ymax >= mousey
- lda ymax
- sta mousey
-
-ok4: jsr clrpm
-
- lda mouse_off
- beq mon
- lda #0
- sta HPOSP0
- beq moff
-
-mon: jsr drwpm
- lda mousey
- sta omy
-
- lda #3
-moff: sta GRACTL
-
-vbi_jmp:
- jmp SYSVBV ; will be modified; won't be ROMmable
-
-;--------------------------------------------------------------------
-; initialize mouse pm
-
-pminit: lda mouse_pm0
- sta mpatch1+2
- sta mpatch2+2
- sta mpatch3+2
-
- ldx #0
- txa
-mpatch1:
-clpm: sta $1000,x ; will be patched
- inx
- bne clpm
-
- lda mouse_pm0
- sec
- sbc #4
- sta PMBASE
-
- lda #62
- sta SDMCTL
-
- lda #1
- sta GPRIOR
-
- lda #0
- sta PCOLR0
- sta SIZEP0
- rts
-
-;--------------------------------------------------------------------
-; draw new mouse pm
-
-drwpm: lda mousex
- sta HPOSP0
-
- lda mousey
- tax
-
- ldy #0
-fmp2: lda mskpm,y
-mpatch2:
- sta $1000,x ; will be patched
- inx
- iny
- cpy #pmsize
- bne fmp2
- rts
-
-;--------------------------------------------------------------------
-; clear old mouse pm
-
-clrpm: lda omy
- tax
-
- ldy #0
- tya
-mpatch3:
-fmp1: sta $1000,x ; will be patched
- inx
- iny
- cpy #pmsize
- bne fmp1
- rts
-
-;--------------------------------------------------------------------
- .rodata
-
-; mouse arrow - pm shape
-
-mskpm: .byte %00000000
- .byte %10000000
- .byte %11000000
- .byte %11000000
-
- .byte %11100000
- .byte %11100000
- .byte %11110000
- .byte %11100000
-
- .byte %11100000
- .byte %00100000
- .byte %00100000
- .byte %00110000
-
- .byte %00110000
- .byte %00000000
- .byte %00000000
- .byte %00000000
-
-; ST mouse lookup table
-
-sttab: .byte $FF,$01,$00,$01
- .byte $00,$FF,$00,$01
- .byte $01,$00,$FF,$00
- .byte $01,$00,$01,$FF
-
-; Amiga mouse lookup table
-
-amitab: .byte $FF,$01,$00,$FF
- .byte $00,$FF,$FF,$01
- .byte $01,$FF,$FF,$00
- .byte $FF,$00,$01,$FF
-
-; Device vectors
-
-lvectab:
- .byte <trak_check, <st_check, <amiga_check
-hvectab:
- .byte >trak_check, >st_check, >amiga_check
-
-; default values
-
-xmin: .byte defxmin
-ymin: .byte defymin
-xmax: .byte defxmax
-ymax: .byte defymax
-
-mousex: .byte xinit
-mousey: .byte yinit
-
-;--------------------------------------------------------------------
- .bss
-
-; Misc. vars
-
-old_t1: .res 2 ; old timer interrupt vector
-oldval: .res 1 ; used by trakball routines
-dumx: .res 1
-dumy: .res 1
-omy: .res 1 ; old y pos
-
-mouse_off:
- .res 1
-mouse_pm0:
- .res 1