diff --git a/libsrc/atari/mouse.s_ b/libsrc/atari/mouse.s_ new file mode 100644 index 000000000..9c722b49c --- /dev/null +++ b/libsrc/atari/mouse.s_ @@ -0,0 +1,576 @@ +;-------------------------------------------------------------------- +; 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+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 + 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 + +; 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