From 661203a89abbbe0c3e6b7fc13e3b1d28d6707a8a Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Thu, 10 Apr 2014 02:31:28 +0200 Subject: [PATCH 1/4] initial version of a P/M mouse callback --- libsrc/atari/mcbpm.s | 204 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 libsrc/atari/mcbpm.s diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s new file mode 100644 index 000000000..c7a350d05 --- /dev/null +++ b/libsrc/atari/mcbpm.s @@ -0,0 +1,204 @@ +; +; 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 + From 526b440b2493629a36b3499fc51ea0df8ecf4ee2 Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Fri, 11 Apr 2014 23:46:53 +0200 Subject: [PATCH 2/4] - always use page 6 for P/M mouse cursor - make cursor character of text mode callback configurable - change default cursor character of text mode callback from 'plus' to 'diamond' - set P/M callback as default --- libsrc/atari/mcbdefault.s | 126 +--------------------- libsrc/atari/mcbpm-shape.s | 32 ++++++ libsrc/atari/mcbpm.s | 185 ++++++++++++++++----------------- libsrc/atari/mcbtxtchar-char.s | 9 ++ libsrc/atari/mcbtxtchar.s | 125 ++++++++++++++++++++++ 5 files changed, 257 insertions(+), 220 deletions(-) create mode 100644 libsrc/atari/mcbpm-shape.s create mode 100644 libsrc/atari/mcbtxtchar-char.s create mode 100644 libsrc/atari/mcbtxtchar.s 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..baf8c0020 --- /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 : absolute + .export mouse_pm_hotspot_x : absolute + .export mouse_pm_hotspot_y : absolute + + + .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 index c7a350d05..b431ac414 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -1,42 +1,48 @@ ; ; P/M mouse callbacks for the Ataris ; -; Christian Groessler, 07.04.2014 +; 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 + .importzp sp + .export _mouse_pm_callbacks .constructor pm_init,27 .destructor pm_down,7 - .export _mouse_pm_callbacks + +; get mouse shape data + .import mouse_pm_bits + .import mouse_pm_height + .import mouse_pm_hotspot_x + .import mouse_pm_hotspot_y ; 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 +MOUSE_PM_NUM = 2 ; P/M used for the mouse +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 -.macro set_mouse_x - ; assume CF = 0 - sta HPOSM3 - adc #2 - sta HPOSM2 - adc #2 - sta HPOSM1 - adc #2 - sta HPOSM0 +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 +MOUSE_PM_RAW = MOUSE_PM_NUM + 1 +.macro set_mouse_x + sta HPOSP0 + MOUSE_PM_NUM .endmacro .endif @@ -57,7 +63,8 @@ _mouse_pm_callbacks: .bss -omy: .res 1 ; Old Mouse Y position +omy: .res 1 ; old Mouse Y position +colhlp: .res 1 ; helper variable to set P/M color ; ------------------------------------------------------------------------ @@ -72,7 +79,7 @@ pm_base:.res 2 ; Hide the mouse cursor. hide: lda #0 sta GRACTL - rts + rts ; Show the mouse cursor. show: @@ -82,88 +89,100 @@ show: lda #1 .endif sta GRACTL - ;rts + ;rts ; optimized out 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 +movex: cpx #1 + ror a + clc + adc #48 + sbc #<(mouse_pm_hotspot_x - 1) + set_mouse_x + jmp update_colors ; Move the mouse cursor y position to the value in A/X. movey: clc - adc #32 - pha + adc #32 + sbc #<(mouse_pm_hotspot_y - 1) + 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_bits' +; Set P/M data from 'mouse_pm_bits' set_pm: tay ldx #0 -set_l: lda mouse_bits,x +set_l: lda mouse_pm_bits,x sta (MOUSE_PM_BASE),y inx iny - cpx #mouse_height + beq set_end + cpx # Date: Tue, 15 Apr 2014 11:36:27 +0200 Subject: [PATCH 3/4] address issue raised in the pull request; add support to not use page 6 again --- libsrc/atari/mcbpm-shape.s | 6 +-- libsrc/atari/mcbpm.s | 72 ++++++++++++++++++++++++++++------ libsrc/atari/mcbtxtchar-char.s | 4 +- libsrc/atari/mcbtxtchar.s | 6 +-- 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/libsrc/atari/mcbpm-shape.s b/libsrc/atari/mcbpm-shape.s index baf8c0020..3a001b561 100644 --- a/libsrc/atari/mcbpm-shape.s +++ b/libsrc/atari/mcbpm-shape.s @@ -9,9 +9,9 @@ ; .export mouse_pm_bits - .export mouse_pm_height : absolute - .export mouse_pm_hotspot_x : absolute - .export mouse_pm_hotspot_y : absolute + .export mouse_pm_height : zeropage + .export mouse_pm_hotspot_x : zeropage + .export mouse_pm_hotspot_y : zeropage .data diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s index b431ac414..52a396d9e 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -7,6 +7,8 @@ ; be called from an interrupt handler ; +USE_PAGE6 = 1 + .include "atari.inc" .importzp sp .export _mouse_pm_callbacks @@ -14,17 +16,28 @@ .destructor pm_down,7 ; get mouse shape data - .import mouse_pm_bits - .import mouse_pm_height - .import mouse_pm_hotspot_x - .import mouse_pm_hotspot_y + .import mouse_pm_bits + .importzp mouse_pm_height + .importzp mouse_pm_hotspot_x + .importzp mouse_pm_hotspot_y -; 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. +; 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. +.if 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 @@ -100,14 +113,14 @@ movex: cpx #1 ror a clc adc #48 - sbc #<(mouse_pm_hotspot_x - 1) + 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) + sbc #(mouse_pm_hotspot_y - 1) & $FF pha lda omy jsr clr_pm ; remove player at old position @@ -125,12 +138,12 @@ set_l: lda mouse_pm_bits,x inx iny beq set_end - cpx # Date: Mon, 21 Apr 2014 11:39:46 +0200 Subject: [PATCH 4/4] Selection whether to use page 6 for mouse P/M data is not done in Makefile.inc, like the other compile-time options. Small fix in the P/M mouse "show" routine: adapt mouse cursor colors to current screen colors. --- libsrc/atari/Makefile.inc | 4 ++++ libsrc/atari/mcbpm.s | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) 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/mcbpm.s b/libsrc/atari/mcbpm.s index 52a396d9e..b546faced 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -7,8 +7,6 @@ ; be called from an interrupt handler ; -USE_PAGE6 = 1 - .include "atari.inc" .importzp sp .export _mouse_pm_callbacks @@ -26,7 +24,7 @@ USE_PAGE6 = 1 ; 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. -.if USE_PAGE6 +.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 @@ -102,7 +100,7 @@ show: lda #1 .endif sta GRACTL - ;rts ; optimized out + jmp update_colors prep: draw: @@ -187,7 +185,7 @@ update_colors: pm_init: lda #0 -.if USE_PAGE6 +.ifdef USE_PAGE6 sta MOUSE_PM_BASE ldx #6 ; page 6 @@ -224,7 +222,7 @@ pm_init: iny bne @iniloo -.if ! USE_PAGE6 +.ifndef USE_PAGE6 lda MOUSE_PM_BASE+1 and #$F8 .endif