1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-25 02:29:52 +00:00
cc65/libsrc/atari/mouse.s_
Oliver Schmidt 56b6dcf814 Brought back mouse driver source code.
The mouse driver source code in question was removed two years
ago with commit 6cbbe66c87.
It seems however desirable to have it around visible in the source
code tree for reference purposes.
2013-05-28 22:07:04 +02:00

577 lines
9.2 KiB
Plaintext

;--------------------------------------------------------------------
; 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