Tachibana
Language: English

Group 11 — Mouse Official

11,1 Move display cursor · 11,2 Set mouse display cursor on/off · 11,3 Get mouse state · 11,4 Test mouse present · 11,5 Select mouse Cursor

The mouse plugs in over USB. The firmware keeps its position in screen pixels, the state of its buttons (bit 0 left, bit 1 right, bit 2 middle) and a wheel counter. Its pointer is drawn by the RP2040 over the screen, hidden at start-up: it is up to the program to show it (11,2).

As long as no mouse is plugged in, 11,3 returns 0 everywhere, even after an 11,1: a program must first check that one is there (11,4).

On the bench, the emulator simulates a mouse plugged in at (100, 80), then, for 11,3, a left click; on the board, plug one in and click yourself.

11,1 Move display cursor Official

Puts the mouse pointer at a point of the screen.

Inputs
BytesTypeMeaning
P0-P1uint16X in pixels
P2-P3uint16Y in pixels

Outputs: none.

The position is the one 11,3 returns; later mouse movements start from there. With no mouse plugged in, 11,3 still returns 0, 0 (checked on the bench). In NeoBASIC, mouse to x, y makes this call.

NeoBASIC keywords that make this call: mouse

Firmware documentation text

Positions the display cursor at Parameters:0,1,Parameters:2,3

C (llvm-mos)
/* Placer le curseur de la souris, puis relire sa position (groupe 11, fonction 1). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
    ControlPort.function = fonction;
    ControlPort.command = groupe;
    while (ControlPort.command)        /* attendre la fin */
        ;
}
static void libre(void) {              /* attendre que la boîte aux lettres soit libre */
    while (ControlPort.command)
        ;
}

int main(void) {
    uint16_t x, y;
    libre();
    ControlPort.params[0] = 200;                /* P0-P1 : X */
    ControlPort.params[1] = 0;
    ControlPort.params[2] = 150;                /* P2-P3 : Y */
    ControlPort.params[3] = 0;
    api(11, 1);                                 /* Move display cursor */
    libre();
    api(11, 3);                                 /* 11,3 : relire l'état de la souris */
    x = ControlPort.params[0] | ControlPort.params[1] << 8;
    y = ControlPort.params[2] | ControlPort.params[3] << 8;
    printf("Position : %u, %u\n", x, y);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Position : 200, 150
Mad Pascal
// Placer le curseur de la souris, puis relire sa position (groupe 11, fonction 1).
program souris1;
uses crt, neo6502;
var x, y: word;
begin
  NeoSetCursorXY(200, 150);                     // Move display cursor
  NeoReadMouse;                                 // 11,3 : relire l'état de la souris
  NeoWaitMessage;
  x := neoMouseX;                               // copiés avant writeln, qui réutilise la boîte aux lettres
  y := neoMouseY;
  writeln('Position : ', x, ', ', y);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Position : 200, 150
NeoBASIC
10 ' Placer le curseur de la souris, puis relire sa position (groupe 11, fonction 1)
20 mouse to 200, 150 : ' Move display cursor
30 b = mouse(x, y) : ' 11,3 : relire l'etat de la souris
40 print "Position : ";x;", ";y
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Position : 200, 150
65C02 assembly (64tass)
; Placer le curseur de la souris, puis relire sa position (groupe 11, fonction 1).
        .cpu "65c02"
        * = $0800
ControlPort    = $FF00             ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage    = $FFF4             ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1             ; affiche le caractère de A

start: lda #<place
        ldx #>place
        jsr envoi
        jsr lire                   ; 11,3 : relire l'état de la souris
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda etat
        ldx etat+1
        jsr decimal16
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda etat+2
        ldx etat+3
        jsr decimal16
        lda #13
        jsr WriteCharacter
        rts

; 11,3 : état de la souris copié dans etat (x, y sur 16 bits, boutons, molette), à l'abri avant d'afficher.
lire:   jsr WaitMessage
        lda #11
        ldx #3                     ; 11,3 : Get mouse state
        jsr appel
        ldx #5
_c:     lda ControlPort+4,x
        sta etat,x
        dex
        bpl _c
        rts
etat:   .fill 6

; Affiche en décimal le nombre de 16 bits A (poids faible) X (poids fort).
decimal16:
        sta n16
        stx n16+1
        ldy #0                     ; nombre de chiffres empilés
_div10: ldx #16                    ; n16 / 10 : quotient dans n16, reste dans A
        lda #0
_bit:   asl n16
        rol n16+1
        rol a
        cmp #10
        bcc _pas
        sbc #10
        inc n16
_pas:   dex
        bne _bit
        pha
        iny
        lda n16
        ora n16+1
        bne _div10
_sort:  pla
        ora #'0'
        jsr WriteCharacter
        dey
        bne _sort
        rts
n16:    .word 0

place:  .byte 11, 1, 4             ; 11,1 : Move display cursor
        .word 200, 150             ; X, Y
t0:     .text "Position : ", 0
t1:     .text ", ", 0

; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi:  sta blk
        stx blk+1
        jsr WaitMessage
        ldy #2
        lda (blk),y                ; nombre de paramètres
        clc
        adc #3
        sta fin
        ldy #3
_copie: cpy fin
        beq _lance
        lda (blk),y
        sta ControlPort+1,y        ; octet 3 du bloc -> P0 ($FF04)...
        iny
        bra _copie
_lance: ldy #1
        lda (blk),y
        tax
        lda (blk)
        jmp appel

; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
        stx ptr+1
        ldy #0
_e:     lda (ptr),y
        beq _f
        jsr WriteCharacter
        iny
        bne _e
_f:     rts

; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
        phx
        phy
        ldx #0
        ldy #100
        jsr _chiffre
        ldy #10
        jsr _chiffre
        ora #'0'
        jsr WriteCharacter
        ply
        plx
        rts
_chiffre:
        sty diviseur
        ldy #0
_div:   cmp diviseur
        bcc _fini
        sbc diviseur
        iny
        bne _div
_fini:  pha
        tya
        bne _ecrit
        cpx #0
        beq _saute
_ecrit: ora #'0'
        jsr WriteCharacter
        ldx #1
_saute: pla
        rts

; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel:  stx ControlPort+1
        sta ControlPort            ; écrit en dernier : lance l'appel
        jmp WaitMessage

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Position : 200, 150

11,2 Set mouse display cursor on/off Changed by Trinity

Shows or hides the mouse pointer.

Inputs
BytesTypeMeaning
P0uint80 hides, any other value shows

Outputs: none.

The pointer is hidden at start-up (Trinity: the program decides). The effect only shows on screen: the API does not read the pointer back, the example only checks that both calls go through. In NeoBASIC, mouse show and mouse hide make this call.

NeoBASIC keywords that make this call: mouse

Firmware documentation text

Shows or hides the mouse cursor depending on the Parameter:0 (hidden at reset : the program decides, bmarty 2026-09-21).

C (llvm-mos)
/* Montrer puis cacher le curseur de la souris (groupe 11, fonction 2). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
    ControlPort.function = fonction;
    ControlPort.command = groupe;
    while (ControlPort.command)        /* attendre la fin */
        ;
}
static void libre(void) {              /* attendre que la boîte aux lettres soit libre */
    while (ControlPort.command)
        ;
}

static uint8_t montrer(uint8_t oui) {           /* Set mouse display cursor on/off */
    libre();
    ControlPort.params[0] = oui;                /* P0 : 0 cache, autre valeur montre */
    api(11, 2);
    return ControlPort.error;
}

int main(void) {
    uint8_t a = montrer(1);
    uint8_t b = montrer(0);                     /* caché au départ : on le rend tel qu'on l'a trouvé */
    printf("Montre : erreur %u, cache : erreur %u\n", a, b);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Montre : erreur 0, cache : erreur 0
Mad Pascal
// Montrer puis cacher le curseur de la souris (groupe 11, fonction 2).
program souris2;
uses crt, neo6502;
var a, b: byte;

function montrer(oui: byte): byte;              // Set mouse display cursor on/off
begin
  NeoShowCursor(oui);                           // 0 cache, autre valeur montre
  NeoWaitMessage;
  result := NeoMessage.error;
end;

begin
  a := montrer(1);
  b := montrer(0);                              // caché au départ : on le rend tel qu'on l'a trouvé
  writeln('Montre : erreur ', a, ', cache : erreur ', b);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Montre : erreur 0, cache : erreur 0
NeoBASIC
10 ' Montrer puis cacher le curseur de la souris (groupe 11, fonction 2)
20 mouse show : a = peek($ff02) : ' Set mouse display cursor on/off, puis l'indicateur d'erreur
30 mouse hide : b = peek($ff02) : ' cache au depart : on le rend tel qu'on l'a trouve
40 print "Montre : erreur ";a;", cache : erreur ";b
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Montre : erreur 0, cache : erreur 0
65C02 assembly (64tass)
; Montrer puis cacher le curseur de la souris (groupe 11, fonction 2).
        .cpu "65c02"
        * = $0800
ControlPort    = $FF00             ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage    = $FFF4             ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1             ; affiche le caractère de A

start: lda #<montre
        ldx #>montre
        jsr envoi
        lda ControlPort+2
        sta a
        lda #<cache
        ldx #>cache
        jsr envoi
        lda ControlPort+2
        sta b
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda a
        jsr decimal
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda b
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

montre: .byte 11, 2, 1, 1          ; 11,2 : P0 non nul, le curseur est montré
cache:  .byte 11, 2, 1, 0          ; P0 = 0 : caché (état de départ, on le rend tel qu'on l'a trouvé)
t0:     .text "Montre : erreur ", 0
t1:     .text ", cache : erreur ", 0
a:      .byte 0
b:      .byte 0

; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi:  sta blk
        stx blk+1
        jsr WaitMessage
        ldy #2
        lda (blk),y                ; nombre de paramètres
        clc
        adc #3
        sta fin
        ldy #3
_copie: cpy fin
        beq _lance
        lda (blk),y
        sta ControlPort+1,y        ; octet 3 du bloc -> P0 ($FF04)...
        iny
        bra _copie
_lance: ldy #1
        lda (blk),y
        tax
        lda (blk)
        jmp appel

; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
        stx ptr+1
        ldy #0
_e:     lda (ptr),y
        beq _f
        jsr WriteCharacter
        iny
        bne _e
_f:     rts

; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
        phx
        phy
        ldx #0
        ldy #100
        jsr _chiffre
        ldy #10
        jsr _chiffre
        ora #'0'
        jsr WriteCharacter
        ply
        plx
        rts
_chiffre:
        sty diviseur
        ldy #0
_div:   cmp diviseur
        bcc _fini
        sbc diviseur
        iny
        bne _div
_fini:  pha
        tya
        bne _ecrit
        cpx #0
        beq _saute
_ecrit: ora #'0'
        jsr WriteCharacter
        ldx #1
_saute: pla
        rts

; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel:  stx ControlPort+1
        sta ControlPort            ; écrit en dernier : lance l'appel
        jmp WaitMessage

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Montre : erreur 0, cache : erreur 0

11,3 Get mouse state Official

Gives the mouse position, the state of its buttons and its wheel counter.

Inputs: none.

Outputs
BytesTypeMeaning
P0-P1uint16X in pixels
P2-P3uint16Y in pixels
P4uint8buttons pressed: bit 0 left, bit 1 right, bit 2 middle
P5uint8wheel counter (goes up or down at each notch, modulo 256)

Everything is 0 as long as no mouse is plugged in. The wheel is a counter, not a state: compare two readings. The example waits for a click. In NeoBASIC, b = mouse(x, y [, w]) makes this call: it returns the buttons and stores the position (and the wheel) in the variables.

NeoBASIC keywords that make this call: mouse()

Firmware documentation text

Returns the mouse position (screen pixel, unsigned) in x Parameters:0,1 and y Parameters:2,3, buttonstate in Parameter:4 (button 1 is 0x1, button 2 0x2 etc., set when pressed), scrollwheelstate in Parameter:5 as uint8 which changes according to scrolls.

C (llvm-mos)
/* Attendre un clic et lire l'état de la souris (groupe 11, fonction 3). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
    ControlPort.function = fonction;
    ControlPort.command = groupe;
    while (ControlPort.command)        /* attendre la fin */
        ;
}
static void libre(void) {              /* attendre que la boîte aux lettres soit libre */
    while (ControlPort.command)
        ;
}

int main(void) {
    uint16_t x, y;
    uint8_t b, m;
    printf("Cliquez\n");
    do {
        libre();
        api(11, 3);                             /* Get mouse state */
        b = ControlPort.params[4];              /* boutons : bit 0 gauche, bit 1 droit... */
    } while (b == 0);
    x = ControlPort.params[0] | ControlPort.params[1] << 8;
    y = ControlPort.params[2] | ControlPort.params[3] << 8;
    m = ControlPort.params[5];                  /* molette */
    printf("Clic en %u, %u : boutons %u, molette %u\n", x, y, b, m);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cliquez
Clic en 100, 80 : boutons 1, molette 0
Mad Pascal
// Attendre un clic et lire l'état de la souris (groupe 11, fonction 3).
program souris3;
uses crt, neo6502;
var x, y: word;
    b, m: byte;
begin
  writeln('Cliquez');
  repeat
    NeoReadMouse;                               // Get mouse state
    NeoWaitMessage;
    b := neoMouseButtons;                       // bit 0 gauche, bit 1 droit...
  until b <> 0;
  x := neoMouseX;
  y := neoMouseY;
  m := neoMouseWheel;                           // molette
  writeln('Clic en ', x, ', ', y, ' : boutons ', b, ', molette ', m);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cliquez
Clic en 100, 80 : boutons 1, molette 0
NeoBASIC
10 ' Attendre un clic et lire l'etat de la souris (groupe 11, fonction 3)
20 print "Cliquez"
30 repeat : b = mouse(x, y, m) : until b <> 0 : ' Get mouse state : boutons, puis x, y et molette
40 print "Clic en ";x;", ";y;" : boutons ";b;", molette ";m
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cliquez
Clic en 100, 80 : boutons 1, molette 0
65C02 assembly (64tass)
; Attendre un clic et lire l'état de la souris (groupe 11, fonction 3).
        .cpu "65c02"
        * = $0800
ControlPort    = $FF00             ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage    = $FFF4             ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1             ; affiche le caractère de A

start:   lda #<t0
        ldx #>t0
        jsr ecrire
_att:   jsr lire                   ; Get mouse state
        lda etat+4                 ; boutons : bit 0 gauche, bit 1 droit...
        beq _att
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda etat
        ldx etat+1
        jsr decimal16
        lda #<t2
        ldx #>t2
        jsr ecrire
        lda etat+2
        ldx etat+3
        jsr decimal16
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda etat+4
        jsr decimal
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda etat+5
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

; 11,3 : état de la souris copié dans etat (x, y sur 16 bits, boutons, molette), à l'abri avant d'afficher.
lire:   jsr WaitMessage
        lda #11
        ldx #3                     ; 11,3 : Get mouse state
        jsr appel
        ldx #5
_c:     lda ControlPort+4,x
        sta etat,x
        dex
        bpl _c
        rts
etat:   .fill 6

; Affiche en décimal le nombre de 16 bits A (poids faible) X (poids fort).
decimal16:
        sta n16
        stx n16+1
        ldy #0                     ; nombre de chiffres empilés
_div10: ldx #16                    ; n16 / 10 : quotient dans n16, reste dans A
        lda #0
_bit:   asl n16
        rol n16+1
        rol a
        cmp #10
        bcc _pas
        sbc #10
        inc n16
_pas:   dex
        bne _bit
        pha
        iny
        lda n16
        ora n16+1
        bne _div10
_sort:  pla
        ora #'0'
        jsr WriteCharacter
        dey
        bne _sort
        rts
n16:    .word 0

t0:     .text "Cliquez", 13, 0
t1:     .text "Clic en ", 0
t2:     .text ", ", 0
t3:     .text " : boutons ", 0
t4:     .text ", molette ", 0

; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi:  sta blk
        stx blk+1
        jsr WaitMessage
        ldy #2
        lda (blk),y                ; nombre de paramètres
        clc
        adc #3
        sta fin
        ldy #3
_copie: cpy fin
        beq _lance
        lda (blk),y
        sta ControlPort+1,y        ; octet 3 du bloc -> P0 ($FF04)...
        iny
        bra _copie
_lance: ldy #1
        lda (blk),y
        tax
        lda (blk)
        jmp appel

; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
        stx ptr+1
        ldy #0
_e:     lda (ptr),y
        beq _f
        jsr WriteCharacter
        iny
        bne _e
_f:     rts

; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
        phx
        phy
        ldx #0
        ldy #100
        jsr _chiffre
        ldy #10
        jsr _chiffre
        ora #'0'
        jsr WriteCharacter
        ply
        plx
        rts
_chiffre:
        sty diviseur
        ldy #0
_div:   cmp diviseur
        bcc _fini
        sbc diviseur
        iny
        bne _div
_fini:  pha
        tya
        bne _ecrit
        cpx #0
        beq _saute
_ecrit: ora #'0'
        jsr WriteCharacter
        ldx #1
_saute: pla
        rts

; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel:  stx ControlPort+1
        sta ControlPort            ; écrit en dernier : lance l'appel
        jmp WaitMessage

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cliquez
Clic en 100, 80 : boutons 1, molette 0

11,4 Test mouse present Official

Tells whether a mouse is plugged in.

Inputs: none.

Outputs
BytesTypeMeaning
P0uint81 if a mouse is plugged in, 0 otherwise

Call it before 11,3, which returns 0 without a mouse. Without a simulated mouse, the example prints "absente" (checked on the bench). In NeoBASIC, havemouse() makes this call.

NeoBASIC keywords that make this call: havemouse()

Firmware documentation text

Returns non zero if a mouse is plugged in in Parameter:0

C (llvm-mos)
/* Savoir si une souris est branchée (groupe 11, fonction 4). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
    ControlPort.function = fonction;
    ControlPort.command = groupe;
    while (ControlPort.command)        /* attendre la fin */
        ;
}
static void libre(void) {              /* attendre que la boîte aux lettres soit libre */
    while (ControlPort.command)
        ;
}

int main(void) {
    libre();
    api(11, 4);                                 /* Test mouse present */
    printf("Souris : %s\n", ControlPort.params[0] ? "presente" : "absente");
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Souris : presente
Mad Pascal
// Savoir si une souris est branchée (groupe 11, fonction 4).
program souris4;
uses crt, neo6502;
begin
  if NeoIsMousePresent then                     // Test mouse present
    writeln('Souris : presente')
  else
    writeln('Souris : absente');
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Souris : presente
NeoBASIC
10 ' Savoir si une souris est branchee (groupe 11, fonction 4)
20 s$ = "absente" : if havemouse() then s$ = "presente" : ' Test mouse present
30 print "Souris : ";s$
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Souris : presente
65C02 assembly (64tass)
; Savoir si une souris est branchée (groupe 11, fonction 4).
        .cpu "65c02"
        * = $0800
ControlPort    = $FF00             ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage    = $FFF4             ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1             ; affiche le caractère de A

start: lda #<test
        ldx #>test
        jsr envoi
        lda ControlPort+4          ; non nul : souris branchée
        bne _oui
        lda #<ta
        ldx #>ta
        jsr ecrire
        rts
_oui:   lda #<tp
        ldx #>tp
        jsr ecrire
        rts

test:   .byte 11, 4, 0             ; 11,4 : Test mouse present
ta:     .text "Souris : absente", 13, 0
tp:     .text "Souris : presente", 13, 0

; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi:  sta blk
        stx blk+1
        jsr WaitMessage
        ldy #2
        lda (blk),y                ; nombre de paramètres
        clc
        adc #3
        sta fin
        ldy #3
_copie: cpy fin
        beq _lance
        lda (blk),y
        sta ControlPort+1,y        ; octet 3 du bloc -> P0 ($FF04)...
        iny
        bra _copie
_lance: ldy #1
        lda (blk),y
        tax
        lda (blk)
        jmp appel

; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
        stx ptr+1
        ldy #0
_e:     lda (ptr),y
        beq _f
        jsr WriteCharacter
        iny
        bne _e
_f:     rts

; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
        phx
        phy
        ldx #0
        ldy #100
        jsr _chiffre
        ldy #10
        jsr _chiffre
        ora #'0'
        jsr WriteCharacter
        ply
        plx
        rts
_chiffre:
        sty diviseur
        ldy #0
_div:   cmp diviseur
        bcc _fini
        sbc diviseur
        iny
        bne _div
_fini:  pha
        tya
        bne _ecrit
        cpx #0
        beq _saute
_ecrit: ora #'0'
        jsr WriteCharacter
        ldx #1
_saute: pla
        rts

; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel:  stx ControlPort+1
        sta ControlPort            ; écrit en dernier : lance l'appel
        jmp WaitMessage

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Souris : presente

11,5 Select mouse Cursor Official

Chooses the mouse pointer image among 39 (0 to 38).

Inputs
BytesTypeMeaning
P0uint8image number, 0 to 38
Outputs
BytesTypeMeaning
erreuruint81 if the number is above 38

An invalid number does not leave the pointer as it was: it puts image 0 back, on top of the error. In NeoBASIC, mouse cursor n makes this call and raises a range error if n is invalid; the NeoBASIC example writes the mailbox to show the error.

NeoBASIC keywords that make this call: mouse

Firmware documentation text

Select a mouse cursor in Parameter:0 ; returns error status if the cursor is not available.

C (llvm-mos)
/* Choisir l'image du curseur de la souris (groupe 11, fonction 5). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
    ControlPort.function = fonction;
    ControlPort.command = groupe;
    while (ControlPort.command)        /* attendre la fin */
        ;
}
static void libre(void) {              /* attendre que la boîte aux lettres soit libre */
    while (ControlPort.command)
        ;
}

static uint8_t curseur(uint8_t n) {             /* Select mouse Cursor : rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = n;
    api(11, 5);
    return ControlPort.error;
}

int main(void) {
    uint8_t a = curseur(5);
    uint8_t b = curseur(39);                    /* 39 curseurs : 0 à 38 */
    printf("Curseur 5 : erreur %u, curseur 39 : erreur %u\n", a, b);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Curseur 5 : erreur 0, curseur 39 : erreur 1
Mad Pascal
// Choisir l'image du curseur de la souris (groupe 11, fonction 5).
program souris5;
uses crt, neo6502;
var a, b: byte;

function curseur(n: byte): byte;                // Select mouse Cursor : rend l'indicateur d'erreur
begin
  NeoSelectCursor(n);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

begin
  a := curseur(5);
  b := curseur(39);                             // 39 curseurs : 0 à 38
  writeln('Curseur 5 : erreur ', a, ', curseur 39 : erreur ', b);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Curseur 5 : erreur 0, curseur 39 : erreur 1
NeoBASIC
10 ' Choisir l'image du curseur de la souris (groupe 11, fonction 5)
20 c = 5 : gosub 1000 : a = e
30 c = 39 : gosub 1000 : b = e : ' 39 curseurs : 0 a 38
40 print "Curseur 5 : erreur ";a;", curseur 39 : erreur ";b
50 end
1000 ' Select mouse Cursor : curseur c, erreur dans e (mouse cursor c leve une erreur de plage)
1010 while peek($ff00) : wend : poke $ff04, c : poke $ff01, 5 : poke $ff00, 11
1020 while peek($ff00) : wend : e = peek($ff02)
1030 return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Curseur 5 : erreur 0, curseur 39 : erreur 1
65C02 assembly (64tass)
; Choisir l'image du curseur de la souris (groupe 11, fonction 5).
        .cpu "65c02"
        * = $0800
ControlPort    = $FF00             ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage    = $FFF4             ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1             ; affiche le caractère de A

start: lda #<c5
        ldx #>c5
        jsr envoi
        lda ControlPort+2
        sta a
        lda #<c39
        ldx #>c39
        jsr envoi
        lda ControlPort+2
        sta b
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda a
        jsr decimal
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda b
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

c5:     .byte 11, 5, 1, 5          ; 11,5 : Select mouse Cursor, curseur 5
c39:    .byte 11, 5, 1, 39         ; 39 curseurs : 0 à 38
t0:     .text "Curseur 5 : erreur ", 0
t1:     .text ", curseur 39 : erreur ", 0
a:      .byte 0
b:      .byte 0

; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi:  sta blk
        stx blk+1
        jsr WaitMessage
        ldy #2
        lda (blk),y                ; nombre de paramètres
        clc
        adc #3
        sta fin
        ldy #3
_copie: cpy fin
        beq _lance
        lda (blk),y
        sta ControlPort+1,y        ; octet 3 du bloc -> P0 ($FF04)...
        iny
        bra _copie
_lance: ldy #1
        lda (blk),y
        tax
        lda (blk)
        jmp appel

; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
        stx ptr+1
        ldy #0
_e:     lda (ptr),y
        beq _f
        jsr WriteCharacter
        iny
        bne _e
_f:     rts

; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
        phx
        phy
        ldx #0
        ldy #100
        jsr _chiffre
        ldy #10
        jsr _chiffre
        ora #'0'
        jsr WriteCharacter
        ply
        plx
        rts
_chiffre:
        sty diviseur
        ldy #0
_div:   cmp diviseur
        bcc _fini
        sbc diviseur
        iny
        bne _div
_fini:  pha
        tya
        bne _ecrit
        cpx #0
        beq _saute
_ecrit: ora #'0'
        jsr WriteCharacter
        ldx #1
_saute: pla
        rts

; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel:  stx ControlPort+1
        sta ControlPort            ; écrit en dernier : lance l'appel
        jmp WaitMessage

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Curseur 5 : erreur 0, curseur 39 : erreur 1

← The Neo6502 API