diff --git a/libsrc/atari/Makefile.inc b/libsrc/atari/Makefile.inc index af5a17e59..4488ddf22 100644 --- a/libsrc/atari/Makefile.inc +++ b/libsrc/atari/Makefile.inc @@ -31,3 +31,7 @@ CA65FLAGS += -D NUMDRVS=4 -D LINEBUF=80 -D UCASE_FILENAME=1 -D DEFAULT_DEVICE=1 # Disabled by default, you should enable it if the linker script relocates the # character generator (like atarixl-largehimem.cfg). #CA65FLAGS += -D CHARGEN_RELOC -D USEWSYNC + +# Disable if you don't want to use page 6 for mouse P/M data. +# If disabled, top of the RAM is used for P/M data. +CA65FLAGS += -D USE_PAGE6 diff --git a/libsrc/atari/mcbdefault.s b/libsrc/atari/mcbdefault.s index ac5056cf9..75a7c74bc 100644 --- a/libsrc/atari/mcbdefault.s +++ b/libsrc/atari/mcbdefault.s @@ -1,126 +1,8 @@ ; -; Default mouse callbacks for the Ataris -; -; Christian Groessler, 03.01.2014 -; -; derived from Apple2 version by -; Oliver Schmidt, 22.09.2005 -; -; All functions in this module should be interrupt safe, because they may -; be called from an interrupt handler +; This file defines the default mouse callback ; - .export _mouse_def_callbacks - .importzp tmp4 - .import mul40,loc_tmp +.import _mouse_pm_callbacks +.export _mouse_def_callbacks - .include "atari.inc" - -; ------------------------------------------------------------------------ - - .bss - -backup: .res 1 -visible:.res 1 - -; ------------------------------------------------------------------------ - - .segment "EXTZP" : zeropage -scrptr: .res 2 - -; ------------------------------------------------------------------------ - - - .rodata - - ; Callback structure -_mouse_def_callbacks: - .addr hide - .addr show - .addr prep - .addr draw - .addr movex - .addr movey - -; ------------------------------------------------------------------------ - - .data - -cursor = 11 ; '+' screen code' - -; setcursor - -getcursor: -column: ldy #$00 ; Patched at runtime - lda (scrptr),y - rts - -setcursor: -column2:ldy #$00 ; Patched at runtime - sta (scrptr),y - rts - -; ------------------------------------------------------------------------ - - .code - -done: - rts - -; Hide the mouse cursor. -hide: - dec visible - -prep: - jsr getcursor ; Get character at cursor position - cmp #cursor ; "mouse" character - bne overwr ; no, probably program has overwritten it - lda backup ; - jmp setcursor ; Draw character -overwr: sta backup - rts - -; Show the mouse cursor. -show: - inc visible - -draw: - lda visible - beq done - jsr getcursor ; Cursor visible at current position? - sta backup ; Save character at cursor position - lda #cursor - jmp setcursor ; Draw cursor - - -; Move the mouse cursor x position to the value in A/X. -movex: - cpx #1 - ror a - lsr a ; convert to character position - lsr a - sta column+1 - sta column2+1 - rts - -; Move the mouse cursor y position to the value in A/X. -movey: - tax - ldy tmp4 ; mul40 uses tmp4 - lda loc_tmp ; and this local variable - pha - txa ; get parameter back - lsr a ; convert y position to character line - lsr a - lsr a - jsr mul40 - clc - adc SAVMSC - sta scrptr - txa - adc SAVMSC+1 - sta scrptr+1 - pla - sta loc_tmp - sty tmp4 - rts +_mouse_def_callbacks := _mouse_pm_callbacks diff --git a/libsrc/atari/mcbpm-shape.s b/libsrc/atari/mcbpm-shape.s new file mode 100644 index 000000000..3a001b561 --- /dev/null +++ b/libsrc/atari/mcbpm-shape.s @@ -0,0 +1,32 @@ +; +; P/M mouse shape default definition +; +; Christian Groessler, 11.04.2014 +; +; Note that the height of the mouse cursor must not exceed 32 +; lines, otherwise the display routines won't do The Right +; Thing(tm). +; + + .export mouse_pm_bits + .export mouse_pm_height : zeropage + .export mouse_pm_hotspot_x : zeropage + .export mouse_pm_hotspot_y : zeropage + + + .data + +mouse_pm_bits: + .byte %11110000 + .byte %11000000 + .byte %10100000 + .byte %10010000 + .byte %10001000 + .byte %00000100 + .byte %00000010 + +mouse_pm_height = * - mouse_pm_bits + +; hot spot is upper left corner +mouse_pm_hotspot_x = 0 +mouse_pm_hotspot_y = 0 diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s new file mode 100644 index 000000000..b546faced --- /dev/null +++ b/libsrc/atari/mcbpm.s @@ -0,0 +1,237 @@ +; +; P/M mouse callbacks for the Ataris +; +; Christian Groessler, 11.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 + .export _mouse_pm_callbacks + .constructor pm_init,27 + .destructor pm_down,7 + +; get mouse shape data + .import mouse_pm_bits + .importzp mouse_pm_height + .importzp mouse_pm_hotspot_x + .importzp mouse_pm_hotspot_y + + +; P/M definitions. The MOUSE_PM_NUM 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. +.ifdef USE_PAGE6 +MOUSE_PM_NUM = 2 ; P/M used for the mouse + ; This cannot be changed since only player #2 uses the memory at $600. +.else +MOUSE_PM_NUM = 4 ; P/M used for the mouse + ; Using player #4 (missiles) wastes the least amount of memory on the + ; atari target, since top of memory is typically at $xC20, and the + ; missiles use the space at $xB00-$xBFF. + ; On the atarixl target this configuration (not using page 6) is not + ; really satisfying since the top of memory typically lies beneath + ; the ROM and there is flickering visible while the ROM is banked in. +.endif +MOUSE_PM_BASE = pm_base ; ZP location pointing to the hw area used by the selected P/M + +.if MOUSE_PM_NUM = 4 +MOUSE_PM_RAW = 0 ; MOUSE_PM_RAW is the hardware P/M number for MOUSE_PM_NUM +.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 +colhlp: .res 1 ; helper variable to set P/M color + +; ------------------------------------------------------------------------ + + .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 + jmp update_colors + +prep: +draw: + rts + +; Move the mouse cursor x position to the value in A/X. +movex: cpx #1 + ror a + clc + adc #48 + sbc #(mouse_pm_hotspot_x - 1) & $FF + set_mouse_x + jmp update_colors + +; Move the mouse cursor y position to the value in A/X. +movey: clc + adc #32 + sbc #(mouse_pm_hotspot_y - 1) & $FF + pha + lda omy + jsr clr_pm ; remove player at old position + jsr update_colors + pla + sta omy + ;jmp set_pm ; put player to new position + ; fall thru + +; Set P/M data from 'mouse_pm_bits' +set_pm: tay + ldx #0 +set_l: lda mouse_pm_bits,x + sta (MOUSE_PM_BASE),y + inx + iny + beq set_end + cpx #mouse_pm_height + bcc set_l +set_end:rts + +; Clear (zero) P/M data +clr_pm: ldx #mouse_pm_height + tay + lda #0 +clr_l: sta (MOUSE_PM_BASE),y + iny + beq clr_end + dex + bne clr_l +clr_end:rts + + +pm_down = hide + + +; this assumes a GRAPHICS 0 screen +update_colors: + lda COLOR2 ; get background color + and #$F0 + sta colhlp + lda COLOR1 + and #$0F + ora colhlp + +.if MOUSE_PM_NUM = 4 + sta PCOLR0 + sta PCOLR1 + sta PCOLR2 + sta PCOLR3 + lda #0 + sta SIZEM +.else + sta PCOLR0 + MOUSE_PM_NUM + lda #0 + sta SIZEP0 + MOUSE_PM_NUM +.endif + rts + +; ------------------------------------------------------------------------ + + .segment "INIT" + +pm_init: + lda #0 + +.ifdef USE_PAGE6 + + sta MOUSE_PM_BASE + ldx #6 ; page 6 + stx MOUSE_PM_BASE+1 + +.else + +; use top of memory and lower sp accordingly + 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 ; jump always + +@decr: lda sp+1 + and #$F8 + sbc #8 - 1 ; CF is clear, subtracts 8 + bcs @set ; jump always + +@cont: lda #0 + +.endif + + tay +@iniloo:sta (MOUSE_PM_BASE),y + iny + bne @iniloo + +.ifndef USE_PAGE6 + lda MOUSE_PM_BASE+1 + and #$F8 +.endif + sta PMBASE + + lda #62 + sta SDMCTL + + lda #1 + sta GPRIOR + + jmp update_colors diff --git a/libsrc/atari/mcbtxtchar-char.s b/libsrc/atari/mcbtxtchar-char.s new file mode 100644 index 000000000..1f0862129 --- /dev/null +++ b/libsrc/atari/mcbtxtchar-char.s @@ -0,0 +1,7 @@ +; +; Default text mode mouse cursor character +; +; Christian Groessler, 11.04.2014 +; + + .export mouse_txt_char : zp = 96 ; 'diamond' screen code diff --git a/libsrc/atari/mcbtxtchar.s b/libsrc/atari/mcbtxtchar.s new file mode 100644 index 000000000..90a25f673 --- /dev/null +++ b/libsrc/atari/mcbtxtchar.s @@ -0,0 +1,125 @@ +; +; Text mode character mouse callbacks for the Ataris +; +; Christian Groessler, 03.01.2014 +; +; derived from Apple2 version by +; Oliver Schmidt, 22.09.2005 +; +; All functions in this module should be interrupt safe, because they may +; be called from an interrupt handler +; + + .export _mouse_txt_callbacks + .importzp tmp4 + .import mul40,loc_tmp + .importzp mouse_txt_char ; screen code of mouse cursor + + .include "atari.inc" + +; ------------------------------------------------------------------------ + + .bss + +backup: .res 1 +visible:.res 1 + +; ------------------------------------------------------------------------ + + .segment "EXTZP" : zeropage +scrptr: .res 2 + +; ------------------------------------------------------------------------ + + + .rodata + + ; Callback structure +_mouse_txt_callbacks: + .addr hide + .addr show + .addr prep + .addr draw + .addr movex + .addr movey + +; ------------------------------------------------------------------------ + + .data + +; setcursor + +getcursor: +column: ldy #$00 ; Patched at runtime + lda (scrptr),y + rts + +setcursor: +column2:ldy #$00 ; Patched at runtime + sta (scrptr),y + rts + +; ------------------------------------------------------------------------ + + .code + +done: + rts + +; Hide the mouse cursor. +hide: + dec visible + +prep: + jsr getcursor ; Get character at cursor position + cmp #mouse_txt_char ; "mouse" character + bne overwr ; no, probably program has overwritten it + lda backup ; + jmp setcursor ; Draw character +overwr: sta backup + rts + +; Show the mouse cursor. +show: + inc visible + +draw: + lda visible + beq done + jsr getcursor ; Cursor visible at current position? + sta backup ; Save character at cursor position + lda #mouse_txt_char + jmp setcursor ; Draw cursor + + +; Move the mouse cursor x position to the value in A/X. +movex: + cpx #1 + ror a + lsr a ; convert to character position + lsr a + sta column+1 + sta column2+1 + rts + +; Move the mouse cursor y position to the value in A/X. +movey: + tax + ldy tmp4 ; mul40 uses tmp4 + lda loc_tmp ; and this local variable + pha + txa ; get parameter back + lsr a ; convert y position to character line + lsr a + lsr a + jsr mul40 + clc + adc SAVMSC + sta scrptr + txa + adc SAVMSC+1 + sta scrptr+1 + pla + sta loc_tmp + sty tmp4 + rts