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