Mouse enable and clear mouse pointer for X16 (cc65 example with inline asm)

For posting library code and examples.
Post Reply
Xiphod
Posts: 600
Joined: Thu Apr 15, 2021 8:05 am

Mouse enable and clear mouse pointer for X16 (cc65 example with inline asm)

Post by Xiphod »

Example of getting the mouse cursor position, button state, scroll status, and clearing the mouse pointer.

I forget how I learned that the current mouse pointer is at VRAM 1,$3000 (I don't see it mentioned in the X16 Tech Ref, similar that the current font is at VRAM 1,$F000; where is this "memory map" of the upper VRAM portion?)

If you just want mouse wheel and button results without showing the mouse cursor, you can "clear" the current mouse pointer by writing to VRAM. The clear function below is an example of doing that.

Code: Select all

unsigned int g_mouse_x = 0;  // column (0-N)
unsigned int g_mouse_y = 0;  // row (0-N)
char g_mouse_buttons = 0;
signed char g_mouse_wheel = 0;

void enable_mouse()
{
  __asm__("lda #$01");  // enable default cursor (0 = off, 1 = on, -1/255 = on, but don't configure cursor/pointer
  __asm__("ldx #0");  // keep current resolution
  __asm__("ldy #0");  // keep current resolution
  __asm__("jsr $FF68");  // mouse_config	
}

void get_mouse_textmode()  // "textmode" just cause the final x/y are divided by 8
{
  __asm__("ldx #$70");  // where in zeropage to store mouse x/y
  __asm__("jsr $FF6B");  // mouse_get
  __asm__("sta %v", g_mouse_buttons);
  __asm__("stx %v", g_mouse_wheel);  

  g_mouse_x = (((unsigned int)PEEK(0x0071) << 8) | (unsigned int)PEEK(0x0070)) >> 3;  // >>3 for /8, textmode 
  g_mouse_y = (((unsigned int)PEEK(0x0073) << 8) | (unsigned int)PEEK(0x0072)) >> 3;  // >>3 for /8, textmode   
}

void clear_mouse_cursor()
{
	__asm__("lda #$11");   // enable 1x auto-increment when write to $9F23, and set high address bit to 1
	__asm__("sta $9F22");
	
	__asm__("lda #$30");   // prepare to write starting at VRAM 1,$3000
	__asm__("sta $9F21");
	
	__asm__("lda #$00");   // low-order of the write address
	__asm__("sta $9F20");
	
	// write 0's to the mouse pointer address at VRAM 1,$3000
	//__asm__("lda #$00");  // regA is already set to $00
	
	// proceed to clear the mouse pointer icon at VRAM 1,$3000 (using auto increment)
	// ---------------------------------------------- row 1
	__asm__("sta $9F23");  // $3000
	__asm__("sta $9F23");  // $3001
	__asm__("sta $9F23");  // $3002
	__asm__("sta $9F23");  // $3003
	__asm__("sta $9F23");  // $3004
	__asm__("sta $9F23");  // $3005
	__asm__("sta $9F23");  // $3006
	__asm__("sta $9F23");  // $3007

	__asm__("sta $9F23");  // $3008
	__asm__("sta $9F23");  // $3009
	__asm__("sta $9F23");  // $300a
	__asm__("sta $9F23");  // $300b
	__asm__("sta $9F23");  // $300c
	__asm__("sta $9F23");  // $300d
	__asm__("sta $9F23");  // $300e
	__asm__("sta $9F23");  // $300f
    // ---------------------------------------------- 
	
	// ---------------------------------------------- row 2
	__asm__("sta $9F23");  // $3010
	__asm__("sta $9F23");  // $3011
	__asm__("sta $9F23");  // $3012
	__asm__("sta $9F23");  // $3013
	__asm__("sta $9F23");  // $3014
	__asm__("sta $9F23");  // $3015
	__asm__("sta $9F23");  // $3016
	__asm__("sta $9F23");  // $3017

	__asm__("sta $9F23");  // $3018
	__asm__("sta $9F23");  // $3019
	__asm__("sta $9F23");  // $301a
	__asm__("sta $9F23");  // $301b
	__asm__("sta $9F23");  // $301c
	__asm__("sta $9F23");  // $301d
	__asm__("sta $9F23");  // $301e
	__asm__("sta $9F23");  // $301f
    // ---------------------------------------------- 

	// ---------------------------------------------- row 3
	__asm__("sta $9F23");  // $3020
	__asm__("sta $9F23");  // $3021
	__asm__("sta $9F23");  // $3022
	__asm__("sta $9F23");  // $3023
	__asm__("sta $9F23");  // $3024
	__asm__("sta $9F23");  // $3025
	__asm__("sta $9F23");  // $3026
	__asm__("sta $9F23");  // $3027

	__asm__("sta $9F23");  // $3028
	__asm__("sta $9F23");  // $3029
	__asm__("sta $9F23");  // $302a
	__asm__("sta $9F23");  // $302b
	__asm__("sta $9F23");  // $302c
	__asm__("sta $9F23");  // $302d
	__asm__("sta $9F23");  // $302e
	__asm__("sta $9F23");  // $302f
    // ----------------------------------------------

	// ---------------------------------------------- row 4
	__asm__("sta $9F23");  // $3030
	__asm__("sta $9F23");  // $3031
	__asm__("sta $9F23");  // $3032
	__asm__("sta $9F23");  // $3033
	__asm__("sta $9F23");  // $3034
	__asm__("sta $9F23");  // $3035
	__asm__("sta $9F23");  // $3036
	__asm__("sta $9F23");  // $3037

	__asm__("sta $9F23");  // $3038
	__asm__("sta $9F23");  // $3039
	__asm__("sta $9F23");  // $303a
	__asm__("sta $9F23");  // $303b
	__asm__("sta $9F23");  // $303c
	__asm__("sta $9F23");  // $303d
	__asm__("sta $9F23");  // $303e
	__asm__("sta $9F23");  // $303f
    // ----------------------------------------------

	// ---------------------------------------------- row 5
	__asm__("sta $9F23");  // $3040
	__asm__("sta $9F23");  // $3041
	__asm__("sta $9F23");  // $3042
	__asm__("sta $9F23");  // $3043
	__asm__("sta $9F23");  // $3044
	__asm__("sta $9F23");  // $3045
	__asm__("sta $9F23");  // $3046
	__asm__("sta $9F23");  // $3047

	__asm__("sta $9F23");  // $3048
	__asm__("sta $9F23");  // $3049
	__asm__("sta $9F23");  // $304a
	__asm__("sta $9F23");  // $304b
	__asm__("sta $9F23");  // $304c
	__asm__("sta $9F23");  // $304d
	__asm__("sta $9F23");  // $304e
	__asm__("sta $9F23");  // $304f
    // ----------------------------------------------

	// ---------------------------------------------- row 6
	__asm__("sta $9F23");  // $3050
	__asm__("sta $9F23");  // $3051
	__asm__("sta $9F23");  // $3052
	__asm__("sta $9F23");  // $3053
	__asm__("sta $9F23");  // $3054
	__asm__("sta $9F23");  // $3055
	__asm__("sta $9F23");  // $3056
	__asm__("sta $9F23");  // $3057

	__asm__("sta $9F23");  // $3058
	__asm__("sta $9F23");  // $3059
	__asm__("sta $9F23");  // $305a
	__asm__("sta $9F23");  // $305b
	__asm__("sta $9F23");  // $305c
	__asm__("sta $9F23");  // $305d
	__asm__("sta $9F23");  // $305e
	__asm__("sta $9F23");  // $305f
    // ----------------------------------------------

	// ---------------------------------------------- row 7
	__asm__("sta $9F23");  // $3060
	__asm__("sta $9F23");  // $3061
	__asm__("sta $9F23");  // $3062
	__asm__("sta $9F23");  // $3063
	__asm__("sta $9F23");  // $3064
	__asm__("sta $9F23");  // $3065
	__asm__("sta $9F23");  // $3066
	__asm__("sta $9F23");  // $3067

	__asm__("sta $9F23");  // $3068
	__asm__("sta $9F23");  // $3069
	__asm__("sta $9F23");  // $306a
	__asm__("sta $9F23");  // $306b
	__asm__("sta $9F23");  // $306c
	__asm__("sta $9F23");  // $306d
	__asm__("sta $9F23");  // $306e
	__asm__("sta $9F23");  // $306f
    // ----------------------------------------------

	// ---------------------------------------------- row 8
	__asm__("sta $9F23");  // $3070
	__asm__("sta $9F23");  // $3071
	__asm__("sta $9F23");  // $3072
	__asm__("sta $9F23");  // $3073
	__asm__("sta $9F23");  // $3074
	__asm__("sta $9F23");  // $3075
	__asm__("sta $9F23");  // $3076
	__asm__("sta $9F23");  // $3077

	__asm__("sta $9F23");  // $3078
	__asm__("sta $9F23");  // $3079
	__asm__("sta $9F23");  // $307a
	__asm__("sta $9F23");  // $307b
	__asm__("sta $9F23");  // $307c
	__asm__("sta $9F23");  // $307d
	__asm__("sta $9F23");  // $307e
	__asm__("sta $9F23");  // $307f
    // ----------------------------------------------

	// ---------------------------------------------- row 9
	__asm__("sta $9F23");  // $3080
	__asm__("sta $9F23");  // $3081
	__asm__("sta $9F23");  // $3082
	__asm__("sta $9F23");  // $3083
	__asm__("sta $9F23");  // $3084
	__asm__("sta $9F23");  // $3085
	__asm__("sta $9F23");  // $3086
	__asm__("sta $9F23");  // $3087

	__asm__("sta $9F23");  // $3088
	__asm__("sta $9F23");  // $3089
	__asm__("sta $9F23");  // $308a
	__asm__("sta $9F23");  // $308b
	__asm__("sta $9F23");  // $308c
	__asm__("sta $9F23");  // $308d
	__asm__("sta $9F23");  // $308e
	__asm__("sta $9F23");  // $308f
    // ---------------------------------------------- 
	
	// ---------------------------------------------- row 10
	__asm__("sta $9F23");  // $3090
	__asm__("sta $9F23");  // $3091
	__asm__("sta $9F23");  // $3092
	__asm__("sta $9F23");  // $3093
	__asm__("sta $9F23");  // $3094
	__asm__("sta $9F23");  // $3095
	__asm__("sta $9F23");  // $3096
	__asm__("sta $9F23");  // $3097

	__asm__("sta $9F23");  // $3098
	__asm__("sta $9F23");  // $3099
	__asm__("sta $9F23");  // $309a
	__asm__("sta $9F23");  // $309b
	__asm__("sta $9F23");  // $309c
	__asm__("sta $9F23");  // $309d
	__asm__("sta $9F23");  // $309e
	__asm__("sta $9F23");  // $309f
    // ---------------------------------------------- 

	// ---------------------------------------------- row 11
	__asm__("sta $9F23");  // $30a0
	__asm__("sta $9F23");  // $30a1
	__asm__("sta $9F23");  // $30a2
	__asm__("sta $9F23");  // $30a3
	__asm__("sta $9F23");  // $30a4
	__asm__("sta $9F23");  // $30a5
	__asm__("sta $9F23");  // $30a6
	__asm__("sta $9F23");  // $30a7

	__asm__("sta $9F23");  // $30a8
	__asm__("sta $9F23");  // $30a9
	__asm__("sta $9F23");  // $30aa
	__asm__("sta $9F23");  // $30ab
	__asm__("sta $9F23");  // $30ac
	__asm__("sta $9F23");  // $30ad
	__asm__("sta $9F23");  // $30ae
	__asm__("sta $9F23");  // $30af
    // ----------------------------------------------

	// ---------------------------------------------- row 12
	__asm__("sta $9F23");  // $30b0
	__asm__("sta $9F23");  // $30b1
	__asm__("sta $9F23");  // $30b2
	__asm__("sta $9F23");  // $30b3
	__asm__("sta $9F23");  // $30b4
	__asm__("sta $9F23");  // $30b5
	__asm__("sta $9F23");  // $30b6
	__asm__("sta $9F23");  // $30b7

	__asm__("sta $9F23");  // $30b8
	__asm__("sta $9F23");  // $30b9
	__asm__("sta $9F23");  // $30ba
	__asm__("sta $9F23");  // $30bb
	__asm__("sta $9F23");  // $30bc
	__asm__("sta $9F23");  // $30bd
	__asm__("sta $9F23");  // $30be
	__asm__("sta $9F23");  // $30bf
    // ----------------------------------------------

	// ---------------------------------------------- row 13
	__asm__("sta $9F23");  // $30c0
	__asm__("sta $9F23");  // $30c1
	__asm__("sta $9F23");  // $30c2
	__asm__("sta $9F23");  // $30c3
	__asm__("sta $9F23");  // $30c4
	__asm__("sta $9F23");  // $30c5
	__asm__("sta $9F23");  // $30c6
	__asm__("sta $9F23");  // $30c7

	__asm__("sta $9F23");  // $30c8
	__asm__("sta $9F23");  // $30c9
	__asm__("sta $9F23");  // $30ca
	__asm__("sta $9F23");  // $30cb
	__asm__("sta $9F23");  // $30cc
	__asm__("sta $9F23");  // $30cd
	__asm__("sta $9F23");  // $30ce
	__asm__("sta $9F23");  // $30cf
    // ----------------------------------------------

	// ---------------------------------------------- row 14
	__asm__("sta $9F23");  // $30d0
	__asm__("sta $9F23");  // $30d1
	__asm__("sta $9F23");  // $30d2
	__asm__("sta $9F23");  // $30d3
	__asm__("sta $9F23");  // $30d4
	__asm__("sta $9F23");  // $30d5
	__asm__("sta $9F23");  // $30d6
	__asm__("sta $9F23");  // $30d7

	__asm__("sta $9F23");  // $30d8
	__asm__("sta $9F23");  // $30d9
	__asm__("sta $9F23");  // $30da
	__asm__("sta $9F23");  // $30db
	__asm__("sta $9F23");  // $30dc
	__asm__("sta $9F23");  // $30dd
	__asm__("sta $9F23");  // $30de
	__asm__("sta $9F23");  // $30df
    // ----------------------------------------------

	// ---------------------------------------------- row 15
	__asm__("sta $9F23");  // $30e0
	__asm__("sta $9F23");  // $30e1
	__asm__("sta $9F23");  // $30e2
	__asm__("sta $9F23");  // $30e3
	__asm__("sta $9F23");  // $30e4
	__asm__("sta $9F23");  // $30e5
	__asm__("sta $9F23");  // $30e6
	__asm__("sta $9F23");  // $30e7

	__asm__("sta $9F23");  // $30e8
	__asm__("sta $9F23");  // $30e9
	__asm__("sta $9F23");  // $30ea
	__asm__("sta $9F23");  // $30eb
	__asm__("sta $9F23");  // $30ec
	__asm__("sta $9F23");  // $30ed
	__asm__("sta $9F23");  // $30ee
	__asm__("sta $9F23");  // $30ef
    // ----------------------------------------------

	// ---------------------------------------------- row 16
	__asm__("sta $9F23");  // $30f0
	__asm__("sta $9F23");  // $30f1
	__asm__("sta $9F23");  // $30f2
	__asm__("sta $9F23");  // $30f3
	__asm__("sta $9F23");  // $30f4
	__asm__("sta $9F23");  // $30f5
	__asm__("sta $9F23");  // $30f6
	__asm__("sta $9F23");  // $30f7

	__asm__("sta $9F23");  // $30f8
	__asm__("sta $9F23");  // $30f9
	__asm__("sta $9F23");  // $30fa
	__asm__("sta $9F23");  // $30fb
	__asm__("sta $9F23");  // $30fc
	__asm__("sta $9F23");  // $30fd
	__asm__("sta $9F23");  // $30fe
	__asm__("sta $9F23");  // $30ff
    // ----------------------------------------------	
}
You can inline these function calls to avoid the overhead of the function-call itself (or change these into #define's).

Open to a better way to clear the mouse pointer. The STA $9F23 becomes "8D 23 9F" machine code, which seems unfortunate to waste time/space on repeating $9F23 over and over. One alternative is syscall $FFD5 with reg.A == 3, which would load a cursor-icon file into VRAM (but just be shorter code, not necessarily faster).
User avatar
JimmyDansbo
Posts: 493
Joined: Sun Apr 26, 2020 8:10 pm
Location: Denmark
Contact:

Re: Mouse enable and clear mouse pointer for X16 (cc65 example with inline asm)

Post by JimmyDansbo »

Xiphod wrote: Thu Mar 20, 2025 5:27 pm ----X snip X----
I forget how I learned that the current mouse pointer is at VRAM 1,$3000 (I don't see it mentioned in the X16 Tech Ref, similar that the current font is at VRAM 1,$F000; where is this "memory map" of the upper VRAM portion?)
----X snip X----
You find the information en the VERA Programmer's Reference.
https://github.com/X16Community/x16-doc ... ace-layout
It tells you that the charset/font is located at $1:F000-$1:F7FF
It also tells you that sprite image data is located at $1:3000-$1:AFFF

The default mouse cursor is sprite 0 (I have been unable to find it documented anywhere)
Visit my Github repo
or my personal site with CX16/C64/6502 related information.
Feel free to contact me regarding any of my projects or even about meeting up somewhere near Denmark
User avatar
JimmyDansbo
Posts: 493
Joined: Sun Apr 26, 2020 8:10 pm
Location: Denmark
Contact:

Re: Mouse enable and clear mouse pointer for X16 (cc65 example with inline asm)

Post by JimmyDansbo »

I have just added pull request 253 to the X16 documentation project, trying to clarify where mouse pointer sprite attributes and data is stored.
Visit my Github repo
or my personal site with CX16/C64/6502 related information.
Feel free to contact me regarding any of my projects or even about meeting up somewhere near Denmark
DragWx
Posts: 394
Joined: Tue Mar 07, 2023 9:07 pm

Re: Mouse enable and clear mouse pointer for X16 (cc65 example with inline asm)

Post by DragWx »

This issue from a year ago is related to the documentation not mentioning the cursor is sprite 0.
Post Reply