; ; P/M mouse callbacks for the Ataris ; ; Christian Groessler, 07.04.2014 ; ; All functions in this module should be interrupt safe, because they may ; be called from an interrupt handler ; .include "atari.inc" .importzp sp .constructor pm_init,27 .destructor pm_down,7 .export _mouse_pm_callbacks ; P/M definitions. The first value can be changed to adjust the number ; of the P/M used for the mouse. All others depend on this value. ; Valid P/M numbers are 0 to 4. When 4 is used, the missiles are used ; as a player. MOUSE_PM_NUM = 4 ; P/M used for the mouse MOUSE_PM_BASE = pm_base .if MOUSE_PM_NUM = 4 MOUSE_PM_RAW = 0 .macro set_mouse_x ; assume CF = 0 sta HPOSM3 adc #2 sta HPOSM2 adc #2 sta HPOSM1 adc #2 sta HPOSM0 .endmacro .else MOUSE_PM_RAW = MOUSE_PM_NUM + 1 .macro set_mouse_x sta HPOSP0 + MOUSE_PM_NUM .endmacro .endif ; ------------------------------------------------------------------------ .rodata ; Callback structure _mouse_pm_callbacks: .addr hide .addr show .addr prep .addr draw .addr movex .addr movey ; ------------------------------------------------------------------------ .bss omy: .res 1 ; Old Mouse Y position ; ------------------------------------------------------------------------ .segment "EXTZP" : zeropage pm_base:.res 2 ; ------------------------------------------------------------------------ .code ; Hide the mouse cursor. hide: lda #0 sta GRACTL rts ; Show the mouse cursor. show: .if MOUSE_PM_NUM < 4 lda #2 .else lda #1 .endif sta GRACTL ;rts prep: draw: rts ; Move the mouse cursor x position to the value in A/X. movex: cpx #1 ror a clc adc #48 set_mouse_x rts ; Move the mouse cursor y position to the value in A/X. movey: clc adc #32 pha lda omy jsr clr_pm ; remove player at old position pla sta omy ;jmp set_pm ; put player to new position ; Set P/M data from 'mouse_bits' set_pm: tay ldx #0 set_l: lda mouse_bits,x sta (MOUSE_PM_BASE),y inx iny cpx #mouse_height bcc set_l rts ; Clear (zero) P/M data clr_pm: ldx #mouse_height tay lda #0 clr_l: sta (MOUSE_PM_BASE),y iny dex bne clr_l rts pm_down = hide ; ------------------------------------------------------------------------ .segment "INIT" pm_init:lda #0 sta sp sta MOUSE_PM_BASE lda sp+1 and #7 ; offset within 2K cmp #3 + MOUSE_PM_RAW + 1 ; can we use it? bcc @decr ; no lda sp+1 and #$F8 @set: adc #3 + MOUSE_PM_RAW - 1 ; CF is set, so adding MOUSE_PM_RAW + 3 sta MOUSE_PM_BASE+1 sta sp+1 bne @cont @decr: lda sp+1 and #$F8 sbc #8 - 1 ; CF is clear, subtracts 8 bcs @set ; jump always @cont: lda #0 tay @iniloo:sta (MOUSE_PM_BASE),y iny bne @iniloo lda MOUSE_PM_BASE+1 and #$F8 sta PMBASE lda #62 sta SDMCTL lda #1 + 16 sta GPRIOR lda #0 .if MOUSE_PM_NUM = 4 sta PCOLR0 sta PCOLR1 sta PCOLR2 sta PCOLR3 sta SIZEM .else sta PCOLR0 + MOUSE_PM_NUM sta SIZEP0 + MOUSE_PM_NUM .endif rts ; ------------------------------------------------------------------------ .data mouse_bits: .byte %11110000 .byte %11000000 .byte %10100000 .byte %10010000 .byte %10001000 .byte %00000100 .byte %00000010 ; .byte %00000000 mouse_height = * - mouse_bits