Tachibana
Langue : français

Groupe 2 — Console Officiel

2,0 Write Character · 2,1 Read Character · 2,2 Console Status · 2,3 Read Line · 2,4 Define Hotkey · 2,5 Define Character · 2,6 Write Character · 2,7 Set Cursor Pos · 2,8 List Hotkeys · 2,9 Screen Size · 2,10 Insert Line · 2,11 Delete Line · 2,12 Clear Screen · 2,13 Cursor Position · 2,14 Clear Region · 2,15 Set Text Color · 2,16 Cursor Inverse · 2,17 Tab() implementation · 2,18 Read Ink/Paper Colours · 2,19 Show/Hide Cursor Reversing · 2,20 Console Debug Echo · 2,21 Set Console Font · 2,22 Get Media Key · 2,23 Get Lock Keys

2,0 Write Character Officiel

Écrit un caractère à la position du curseur. Doublon de la fonction 2,6, conservé pour la compatibilité.

Entrées
OctetsTypeRôle
P0charle caractère (ou un code de contrôle, voir 2,6)

Sorties : aucune.

Préférer la fonction 2,6, qui fait la même chose.

Texte de la documentation du firmware (anglais)

Console out (duplicate of Function 6 for backward compatibility).

C (llvm-mos)
/* Écrire un texte caractère par caractère (groupe 2, fonction 0). */
#include <neo6502.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) {
    const char *texte = "Bonjour\r";
    while (*texte) {
        libre();
        ControlPort.params[0] = *texte++;
        api(2, 0);                              /* Write Character */
    }
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Mad Pascal
// Écrire un texte caractère par caractère (groupe 2, fonction 0).
program ecrire0;
uses crt, neo6502;
var texte: string[16];
    i: byte;
begin
  texte := 'Bonjour';
  for i := 1 to length(texte) do
  begin
    NeoWaitMessage;
    NeoMessage.params[0] := ord(texte[i]);
    NeoSendMessage(2, 0);                       // Write Character
  end;
  NeoWaitMessage;
  NeoMessage.params[0] := 13;                   // retour à la ligne
  NeoSendMessage(2, 0);
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
NeoBASIC
10 ' Ecrire un texte caractere par caractere (groupe 2, fonction 0)
20 t$ = "Bonjour" + chr$(13)
30 for i = 1 to len(t$)
40 while peek($ff00) : wend
50 poke $ff04, asc(mid$(t$, i, 1)) : poke $ff01, 0 : poke $ff00, 2
60 next i
70 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Assembleur 65C02 (64tass)
; Écrire un texte caractère par caractère (groupe 2, fonction 0).
        .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:  ldx #0
_suiv:  lda texte,x
        beq _fin
        jsr WaitMessage
        sta ControlPort+4          ; P0 : le caractère
        phx
        lda #2
        ldx #0                     ; fonction 0 : Write Character
        jsr appel
        plx
        inx
        bne _suiv
_fin:   rts

; 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
diviseur: .byte 0

texte:  .text "Bonjour", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour

2,1 Read Character Officiel

Retire la touche la plus ancienne de la file du clavier et donne son code ASCII ; 0 si la file est vide.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0charcode ASCII de la touche, 0 si aucune

Faite pour la saisie de texte. Pour un jeu, lire l'état des touches (1,2 ou 7,1) : la file ne dit pas si une touche est encore enfoncée. En NeoBASIC, inkey$() fait le même appel.

Mots-clés NeoBASIC qui font cet appel : inkey$()

Texte de la documentation du firmware (anglais)

Read and remove a key press from the keyboard queue into Parameter:0. This is the ASCII value of the keystroke. If there are no key presses in the queue, Parameter:0 will be zero.

Note that this Function is best for text input, but not for games. Function 7,1 is more optimal for games, as this only detects key presses, you cannot check whether the key is currently down or not.

C (llvm-mos)
/* Attendre une touche et l'afficher (groupe 2, fonction 1). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    char c;
    printf("Appuyez sur une touche\n");
    while ((c = neo_console_read_char()) == 0)  /* 0 : file vide */
        ;
    printf("Touche : %c\n", c);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Touche : A
Mad Pascal
// Attendre une touche et l'afficher (groupe 2, fonction 1).
program lecture;
uses crt, neo6502;
var c: byte;
begin
  writeln('Appuyez sur une touche');
  repeat
    NeoSendMessage(2, 1);                       // Read Character
    NeoWaitMessage;
    c := NeoMessage.params[0];
  until c <> 0;                                 // 0 : file vide
  writeln('Touche : ', chr(c));
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Touche : A
NeoBASIC
10 ' Attendre une touche et l'afficher (groupe 2, fonction 1)
20 print "Appuyez sur une touche"
30 repeat : k$ = inkey$() : until k$ <> ""
40 print "Touche : ";k$
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Touche : A
Assembleur 65C02 (64tass)
; Attendre une touche et l'afficher (groupe 2, 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 #<invite
        ldx #>invite
        jsr ecrire
_att:   jsr WaitMessage
        lda #2
        ldx #1                     ; fonction 1 : Read Character
        jsr appel
        lda ControlPort+4          ; P0 : la touche, 0 si aucune
        beq _att
        pha
        lda #<message
        ldx #>message
        jsr ecrire
        pla
        jsr WriteCharacter
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

invite:  .text "Appuyez sur une touche", 13, 0
message: .text "Touche : ", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Touche : A

2,2 Console Status Officiel

Indique si la file du clavier est vide, sans rien en retirer.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8$FF si la file est vide, 0 si une touche attend

Attention au sens : $FF signifie « rien à lire ».

Texte de la documentation du firmware (anglais)

Check to see if the keyboard queue is empty. If it is, Parameter:0 will be $FF, otherwise it will be $00

C (llvm-mos)
/* Attendre qu'une touche soit dans la file, sans la retirer (groupe 2, fonction 2). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    printf("Appuyez sur une touche\n");
    while (neo_console_status() == 0xFF)        /* $FF : file vide */
        ;
    printf("Une touche attend\n");
    neo_console_read_char();                    /* la retirer de la file */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Une touche attend
Mad Pascal
// Attendre qu'une touche soit dans la file, sans la retirer (groupe 2, fonction 2).
program statut;
uses crt, neo6502;
begin
  writeln('Appuyez sur une touche');
  repeat
    NeoSendMessage(2, 2);                       // Console Status
    NeoWaitMessage;
  until NeoMessage.params[0] <> $FF;            // $FF : file vide
  writeln('Une touche attend');
  NeoSendMessage(2, 1);                         // la retirer de la file
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Une touche attend
NeoBASIC
10 ' Attendre qu'une touche soit dans la file, sans la retirer (groupe 2, fonction 2)
20 print "Appuyez sur une touche"
30 repeat
40 while peek($ff00) : wend
50 poke $ff01, 2 : poke $ff00, 2
60 while peek($ff00) : wend : v = peek($ff04)
70 until v <> 255
80 print "Une touche attend"
90 k$ = inkey$()
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Une touche attend
A
Assembleur 65C02 (64tass)
; Attendre qu'une touche soit dans la file, sans la retirer (groupe 2, 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 #<invite
        ldx #>invite
        jsr ecrire
_att:   jsr WaitMessage
        lda #2
        ldx #2                     ; fonction 2 : Console Status
        jsr appel
        lda ControlPort+4          ; $FF : file vide
        cmp #$FF
        beq _att
        lda #<message
        ldx #>message
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #1                     ; retirer la touche (2,1)
        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
diviseur: .byte 0

invite:  .text "Appuyez sur une touche", 13, 0
message: .text "Une touche attend", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Appuyez sur une touche
Une touche attend

2,3 Read Line Officiel

Relit le texte de la ligne de l'écran où se trouve le curseur (une ligne logique, éventuellement sur plusieurs lignes d'écran), puis place le curseur au début de la ligne suivante.

Entrées
OctetsTypeRôle
P0-P1addradresse d'un tampon de 256 octets qui reçoit la ligne (longueur, puis texte)
Sorties
OctetsTypeRôle
tamponstringla ligne, sans les espaces de fin

Rien n'est attendu au clavier : la fonction lit ce qui est déjà affiché. C'est ainsi qu'un éditeur plein écran récupère la ligne sur laquelle on a appuyé sur Entrée. Pour une vraie saisie, le noyau offre ReadLine ($FFEB).

Texte de la documentation du firmware (anglais)

Input the current line below the cursor into Parameters:0,1 as a length-prefixed string; and move the cursor to the line below. Handles multiple-line input.

C (llvm-mos)
/* Relire une ligne déjà affichée à l'écran (groupe 2, fonction 3). */
#include <stdio.h>
#include <neo6502.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 tampon[256];                     /* longueur, puis le texte */

int main(void) {
    printf("Bonjour tout le monde\n");
    libre();
    api(2, 13);                                 /* Cursor Position */
    uint8_t y = ControlPort.params[1];
    libre();
    ControlPort.params[0] = 0;                  /* remonter sur la ligne affichée */
    ControlPort.params[1] = y - 1;
    api(2, 7);                                  /* Set Cursor Pos */
    libre();
    ControlPort.params[0] = (uint16_t)tampon & 0xFF;
    ControlPort.params[1] = (uint16_t)tampon >> 8;
    api(2, 3);                                  /* Read Line */
    printf("Relu : %.*s\n", tampon[0], tampon + 1);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour tout le monde
Relu : Bonjour tout le monde
Mad Pascal
// Relire une ligne déjà affichée à l'écran (groupe 2, fonction 3).
program relire;
uses crt, neo6502;
var tampon: string[255];                        // longueur, puis le texte
    x, y: byte;
begin
  writeln('Bonjour tout le monde');
  NeoGetCursorPos(x, y);
  NeoWaitMessage;
  NeoMessage.params[0] := 0;                    // remonter sur la ligne affichée
  NeoMessage.params[1] := y - 1;
  NeoSendMessage(2, 7);                         // Set Cursor Pos
  NeoWaitMessage;
  wordParams[0] := word(@tampon);
  NeoSendMessage(2, 3);                         // Read Line
  NeoWaitMessage;
  writeln('Relu : ', tampon);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour tout le monde
Relu : Bonjour tout le monde
NeoBASIC
10 ' Relire une ligne deja affichee a l'ecran (groupe 2, fonction 3)
20 a = alloc(256)
30 print "Bonjour tout le monde"
40 while peek($ff00) : wend
50 poke $ff01, 13 : poke $ff00, 2
60 while peek($ff00) : wend : y = peek($ff05)
70 poke $ff04, 0 : poke $ff05, y - 1 : poke $ff01, 7 : poke $ff00, 2
80 while peek($ff00) : wend
90 poke $ff04, a & 255 : poke $ff05, a >> 8 : poke $ff01, 3 : poke $ff00, 2
100 while peek($ff00) : wend
110 r$ = "" : for i = 1 to peek(a) : r$ = r$ + chr$(peek(a + i)) : next i
120 print "Relu : ";r$
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour tout le monde
Relu : Bonjour tout le monde
Assembleur 65C02 (64tass)
; Relire une ligne déjà affichée à l'écran (groupe 2, 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 #<ligne
        ldx #>ligne
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #13                    ; Cursor Position
        jsr appel
        ldy ControlPort+5          ; ligne du curseur
        dey                        ; remonter sur la ligne affichée
        jsr WaitMessage
        stz ControlPort+4
        sty ControlPort+5
        lda #2
        ldx #7                     ; Set Cursor Pos
        jsr appel
        jsr WaitMessage
        lda #<tampon
        sta ControlPort+4          ; P0-P1 : tampon de 256 octets
        lda #>tampon
        sta ControlPort+5
        lda #2
        ldx #3                     ; fonction 3 : Read Line
        jsr appel
        lda #<relu
        ldx #>relu
        jsr ecrire
        ldx #0
_txt:   cpx tampon                 ; longueur
        beq _fin
        lda tampon+1,x
        jsr WriteCharacter
        inx
        bne _txt
_fin:   lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

ligne:  .text "Bonjour tout le monde", 13, 0
relu:   .text "Relu : ", 0
tampon: .fill 256
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour tout le monde
Relu : Bonjour tout le monde

2,4 Define Hotkey Officiel

Associe un texte à une touche de fonction F1 à F10 : l'appui sur la touche le tape comme au clavier.

Entrées
OctetsTypeRôle
P0uint8numéro de la touche, 1 (F1) à 10 (F10)
P2-P3addradresse du texte, précédé de sa longueur

Sorties : aucune.

F11 et F12 ne peuvent pas être définies. L'adresse du texte est en P2-P3 (P1 n'est pas utilisé). En NeoBASIC, fkey n, "texte" fait le même appel. En Mad Pascal 1.7.8, NeoDefineHotkey range l'adresse en P0-P1, ce qui écrase le numéro de touche : l'appel échoue (erreur 1) ; l'exemple fait l'appel directement.

Mots-clés NeoBASIC qui font cet appel : fkey

Texte de la documentation du firmware (anglais)

Define the function key F1..F10 specified in Parameter:0 as 1..10 to emit the length-prefixed string stored at the memory location specified in Parameters:2,3.

F11 and F12 cannot currently be defined.

C (llvm-mos)
/* Associer un texte à la touche F1, puis lister les touches (groupe 2, fonctions 4 et 8). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    neo_console_define_hotkey(1, "Bonjour");    /* F1 */
    neo_console_list_hotkeys();                 /* 2,8 : afficher les définitions */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Bonjour"
F8  : ""
Mad Pascal
// Associer un texte à la touche F1, puis lister les touches (groupe 2, fonctions 4 et 8).
// NeoDefineHotkey (Mad Pascal 1.7.8) range l'adresse en P0-P1 et écrase la touche : appel direct.
program hotkey;
uses crt, neo6502;
var texte: string[32];                          // chaîne Pascal : longueur puis texte
begin
  texte := 'Bonjour';
  NeoWaitMessage;
  NeoMessage.params[0] := 1;                    // P0 : F1
  wordParams[1] := word(@texte);                // P2-P3 : adresse du texte
  NeoSendMessage(2, 4);                         // Define Hotkey
  NeoWaitMessage;
  NeoShowHotkeys;                               // 2,8 : afficher les définitions
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Bonjour"
F8  : ""
NeoBASIC
10 ' Associer un texte a la touche F1, puis lister les touches (groupe 2, fonctions 4 et 8)
20 fkey 1, "Bonjour"
30 fkey
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Bonjour"
Assembleur 65C02 (64tass)
; Associer un texte à la touche F1, puis lister les touches (groupe 2, fonctions 4 et 8).
        .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:  jsr WaitMessage
        lda #1
        sta ControlPort+4          ; P0 : F1
        lda #<texte
        sta ControlPort+6          ; P2-P3 : adresse du texte
        lda #>texte
        sta ControlPort+7
        lda #2
        ldx #4                     ; fonction 4 : Define Hotkey
        jsr appel
        jsr WaitMessage
        lda #2
        ldx #8                     ; fonction 8 : List Hotkeys
        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
diviseur: .byte 0

texte:  .byte 7                    ; longueur
        .text "Bonjour"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Bonjour"
F8  : ""

2,5 Define Character Officiel

Redessine l'un des caractères 192 à 255 de la police, ligne par ligne (6 colonnes × 7 lignes).

Entrées
OctetsTypeRôle
P0uint8code du caractère (192 à 255)
P1-P77 × uint8les 7 lignes du dessin, de haut en bas ; bits 0 à 5 = colonnes

Sorties : aucune.

Les caractères redéfinis restent en place jusqu'à la réinitialisation. En NeoBASIC, defchr c, l1, …, l7 fait le même appel.

Mots-clés NeoBASIC qui font cet appel : defchr

Texte de la documentation du firmware (anglais)

Define a font character specified in Parameter:0 within the range of 192..255. Fill bits 0..5 (columns) of Parameters:1..7 (rows) with the character bitmap.

C (llvm-mos)
/* Dessiner un visage souriant dans le caractère 192 (groupe 2, fonction 5). */
#include <stdio.h>
#include <neo/api.h>

static const uint8_t visage[7] = { 0x1E, 0x21, 0x2D, 0x21, 0x2D, 0x33, 0x1E };   /* bits 0-5 */

int main(void) {
    neo_console_define_char(192, visage);
    printf("Caractere 192 redefini : %c\n", 192);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Caractere 192 redefini : .
Mad Pascal
// Dessiner un visage souriant dans le caractère 192 (groupe 2, fonction 5).
program defchar;
uses crt, neo6502;
const visage: array[0..6] of byte = ($1E, $21, $2D, $21, $2D, $33, $1E);   // bits 0-5
begin
  NeoSetChar(192, @visage);
  NeoWaitMessage;
  writeln('Caractere 192 redefini : ', chr(192));
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Caractere 192 redefini : .
NeoBASIC
10 ' Dessiner un visage souriant dans le caractere 192 (groupe 2, fonction 5)
20 defchr 192, $1e, $21, $2d, $21, $2d, $33, $1e
30 print "Caractere 192 redefini : ";chr$(192)
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Caractere 192 redefini : .
Assembleur 65C02 (64tass)
; Dessiner un visage souriant dans le caractère 192 (groupe 2, 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:  jsr WaitMessage
        lda #192
        sta ControlPort+4          ; P0 : le caractère
        ldx #6
_copie: lda visage,x               ; P1-P7 : les 7 lignes
        sta ControlPort+5,x
        dex
        bpl _copie
        lda #2
        ldx #5                     ; fonction 5 : Define Character
        jsr appel
        lda #<message
        ldx #>message
        jsr ecrire
        lda #192
        jsr WriteCharacter
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

visage:  .byte $1E, $21, $2D, $21, $2D, $33, $1E
message: .text "Caractere 192 redefini : ", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Caractere 192 redefini : .

2,6 Write Character Officiel

Écrit un caractère, ou exécute un code de contrôle, à la position du curseur.

Entrées
OctetsTypeRôle
P0char32-126 et $A0-$FF : caractère affiché ; $80-$8F : couleur du texte ; $90-$9F : couleur du fond ; codes de contrôle : 8 retour arrière, 9 tabulation, 10 ligne suivante, 12 effacer l'écran, 13 retour à la ligne, 20 curseur en haut à gauche, 1/4/19/23 curseur gauche/droite/bas/haut, 24 inverser le caractère sous le curseur, 26 supprimer

Sorties : aucune.

C'est la routine WriteCharacter du noyau ($FFF1) ; les codes viennent de CONWrite dans le firmware.

Texte de la documentation du firmware (anglais)

Write the character specified in Parameter:0 to the console at the cursor position. Refer to Section "Console Codes" for details.

C (llvm-mos)
/* Écrire un texte, en changeant la couleur (groupe 2, fonction 6). */
#include <neo/api.h>

int main(void) {
    const char *texte = "\x83" "Bonjour" "\x87" "\r";   /* $83 : couleur 3, $87 : couleur 7 */
    while (*texte)
        neo_console_write_char(*texte++);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Mad Pascal
// Écrire un texte, en changeant la couleur (groupe 2, fonction 6).
program ecrire6;
uses crt, neo6502;
var texte: string[16];
    i: byte;
begin
  texte := #$83'Bonjour'#$87#13;               // $83 : couleur 3, $87 : couleur 7, retour à la ligne
  for i := 1 to length(texte) do
  begin
    NeoWaitMessage;
    NeoMessage.params[0] := ord(texte[i]);
    NeoSendMessage(2, 6);                       // Write Character
  end;
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
NeoBASIC
10 ' Ecrire un texte, en changeant la couleur (groupe 2, fonction 6)
20 t$ = chr$($83) + "Bonjour" + chr$($87) + chr$(13) : ' $83 : couleur 3, $87 : couleur 7
30 for i = 1 to len(t$)
40 while peek($ff00) : wend
50 poke $ff04, asc(mid$(t$, i, 1)) : poke $ff01, 6 : poke $ff00, 2
60 next i
70 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Assembleur 65C02 (64tass)
; Écrire un texte, en changeant la couleur (groupe 2, fonction 6).
        .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:  ldx #0
_suiv:  lda texte,x
        beq _fin
        jsr WaitMessage
        sta ControlPort+4          ; P0 : caractère ou code
        phx
        lda #2
        ldx #6                     ; fonction 6 : Write Character
        jsr appel
        plx
        inx
        bne _suiv
_fin:   rts

; 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
diviseur: .byte 0

texte:  .byte $83                  ; couleur 3
        .text "Bonjour"
        .byte $87, 13, 0           ; couleur 7, retour à la ligne
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour

2,7 Set Cursor Pos Officiel

Place le curseur sur une case de l'écran (colonne, ligne).

Entrées
OctetsTypeRôle
P0uint8colonne (0 = gauche)
P1uint8ligne (0 = haut)

Sorties : aucune.

En NeoBASIC, cursor x, y fait le même appel. La taille de l'écran est donnée par 2,9.

Mots-clés NeoBASIC qui font cet appel : cursor

Texte de la documentation du firmware (anglais)

Move the cursor to the screen character cell Parameter:0 (X), Parameter:1 (Y).

C (llvm-mos)
/* Écrire en colonne 10 de la ligne suivante (groupe 2, fonction 7). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t x, y;
    neo_console_cursor_pos(&x, &y);             /* 2,13 : où est le curseur */
    neo_console_set_cursor_pos(10, y);          /* colonne 10, même ligne */
    printf("Ici\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
          Ici
Mad Pascal
// Écrire en colonne 10 de la ligne courante (groupe 2, fonction 7).
program curseur;
uses crt, neo6502;
var x, y: byte;
begin
  NeoGetCursorPos(x, y);                        // 2,13 : où est le curseur
  NeoWaitMessage;
  NeoMessage.params[0] := 10;                   // colonne
  NeoMessage.params[1] := y;                    // ligne
  NeoSendMessage(2, 7);                         // Set Cursor Pos
  NeoWaitMessage;
  writeln('Ici');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
          Ici
NeoBASIC
10 ' Ecrire en colonne 10 de la ligne courante (groupe 2, fonction 7)
20 while peek($ff00) : wend
30 poke $ff01, 13 : poke $ff00, 2
40 while peek($ff00) : wend : y = peek($ff05)
50 cursor 10, y
60 print "Ici"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
          Ici
Assembleur 65C02 (64tass)
; Écrire en colonne 10 de la ligne courante (groupe 2, fonction 7).
        .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:  jsr WaitMessage
        lda #2
        ldx #13                    ; Cursor Position
        jsr appel
        ldy ControlPort+5          ; ligne actuelle
        jsr WaitMessage
        lda #10
        sta ControlPort+4          ; P0 : colonne 10
        sty ControlPort+5          ; P1 : même ligne
        lda #2
        ldx #7                     ; fonction 7 : Set Cursor Pos
        jsr appel
        lda #<ici
        ldx #>ici
        jmp ecrire

; 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
diviseur: .byte 0

ici:    .text "Ici", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
          Ici

2,8 List Hotkeys Officiel

Affiche les textes associés aux touches de fonction (voir 2,4).

Entrées : aucune.

Sorties : aucune.

En NeoBASIC, fkey sans argument fait le même appel.

Mots-clés NeoBASIC qui font cet appel : fkey

Texte de la documentation du firmware (anglais)

Display the current function key definitions.

C (llvm-mos)
/* Lister les touches de fonction après avoir défini F1 (groupe 2, fonction 8). */
#include <neo/api.h>

int main(void) {
    neo_console_define_hotkey(1, "Liste");      /* 2,4 */
    neo_console_list_hotkeys();                 /* List Hotkeys */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Liste"
F8  : ""
Mad Pascal
// Lister les touches de fonction après avoir défini F1 (groupe 2, fonction 8).
program listkeys;
uses crt, neo6502;
var texte: string[16];
begin
  texte := 'Liste';
  NeoWaitMessage;
  NeoMessage.params[0] := 1;                    // 2,4 : F1 ...
  wordParams[1] := word(@texte);                // ... texte en P2-P3
  NeoSendMessage(2, 4);
  NeoWaitMessage;
  NeoShowHotkeys;                               // List Hotkeys
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Liste"
F8  : ""
NeoBASIC
10 ' Lister les touches de fonction apres avoir defini F1 (groupe 2, fonction 8)
20 fkey 1, "Liste"
30 while peek($ff00) : wend
40 poke $ff01, 8 : poke $ff00, 2
50 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Liste"
Assembleur 65C02 (64tass)
; Lister les touches de fonction après avoir défini F1 (groupe 2, fonction 8).
        .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:  jsr WaitMessage
        lda #1
        sta ControlPort+4          ; F1
        lda #<texte
        sta ControlPort+6
        lda #>texte
        sta ControlPort+7
        lda #2
        ldx #4                     ; 2,4 : Define Hotkey
        jsr appel
        jsr WaitMessage
        lda #2
        ldx #8                     ; fonction 8 : List Hotkeys
        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
diviseur: .byte 0

texte:  .byte 5
        .text "Liste"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
F1  : "Liste"
F8  : ""

2,9 Screen Size Officiel

Donne la taille de la console en caractères.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8hauteur (nombre de lignes)
P1uint8largeur (nombre de colonnes)

Attention à l'ordre : la hauteur vient d'abord. La taille dépend du mode vidéo (5,9).

Texte de la documentation du firmware (anglais)

Returns the console size in characters, in Parameter:0 (height) and Parameter:1 (width).

C (llvm-mos)
/* Taille de la console (groupe 2, fonction 9). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t largeur, hauteur;
    neo_console_screen_size(&largeur, &hauteur);
    printf("Console : %u colonnes, %u lignes\n", largeur, hauteur);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Console : 53 colonnes, 30 lignes
Mad Pascal
// Taille de la console (groupe 2, fonction 9).
program taille;
uses crt, neo6502;
var hauteur, largeur: byte;
begin
  NeoGetScreenSize(hauteur, largeur);
  writeln('Console : ', largeur, ' colonnes, ', hauteur, ' lignes');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Console : 30 colonnes, 53 lignes
NeoBASIC
10 ' Taille de la console (groupe 2, fonction 9)
20 ' lire les resultats dans des variables juste apres l'appel : print reutilise la boite aux lettres
30 while peek($ff00) : wend
40 poke $ff01, 9 : poke $ff00, 2
50 while peek($ff00) : wend : h = peek($ff04) : l = peek($ff05)
60 print "Console : ";l;" colonnes, ";h;" lignes"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Console : 30 colonnes, 53 lignes
Assembleur 65C02 (64tass)
; Taille de la console (groupe 2, fonction 9).
        .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:  jsr WaitMessage
        lda #2
        ldx #9                     ; fonction 9 : Screen Size
        jsr appel
        lda ControlPort+4          ; P0 : hauteur
        sta hauteur
        lda ControlPort+5          ; P1 : largeur
        sta largeur
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda largeur
        jsr decimal
        lda #<m2
        ldx #>m2
        jsr ecrire
        lda hauteur
        jsr decimal
        lda #<m3
        ldx #>m3
        jmp ecrire

; 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
diviseur: .byte 0

hauteur: .byte 0
largeur: .byte 0
m1:      .text "Console : ", 0
m2:      .text " colonnes, ", 0
m3:      .text " lignes", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Console : 30 colonnes, 53 lignes

2,10 Insert Line Officiel

Insère une ligne vide à la ligne donnée ; les lignes suivantes descendent, la dernière de l'écran est perdue.

Entrées
OctetsTypeRôle
P0uint8numéro de la ligne (0 = haut)

Sorties : aucune.

Fonction de service de la console (l'éditeur s'en sert) ; la documentation du firmware déconseille de l'utiliser directement.

Texte de la documentation du firmware (anglais)

This is a support function which inserts a blank line in the console and should not be used.

C (llvm-mos)
/* Insérer une ligne vide entre A et B (groupe 2, fonction 10). */
#include <stdio.h>
#include <neo6502.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(2, 12);                                 /* écran vide : les lignes sont en haut */
    printf("Ligne A\nLigne B\nLigne C\n");
    libre();
    api(2, 13);                                 /* Cursor Position */
    uint8_t y = ControlPort.params[1];          /* ligne sous « Ligne C » */
    libre();
    ControlPort.params[0] = y - 2;              /* la ligne de « Ligne B » */
    api(2, 10);                                 /* Insert Line */
    libre();
    ControlPort.params[0] = 0;
    ControlPort.params[1] = y + 1;              /* sous les lignes décalées */
    api(2, 7);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A

Ligne B
Ligne C
Mad Pascal
// Insérer une ligne vide entre A et B (groupe 2, fonction 10).
program insline;
uses crt, neo6502;
var x, y: byte;
begin
  NeoSendMessage(2, 12);                        // écran vide : les lignes sont en haut
  NeoWaitMessage;
  writeln('Ligne A'); writeln('Ligne B'); writeln('Ligne C');
  NeoGetCursorPos(x, y);                        // ligne sous « Ligne C »
  NeoWaitMessage;
  NeoMessage.params[0] := y - 2;                // la ligne de « Ligne B »
  NeoSendMessage(2, 10);                        // Insert Line
  NeoWaitMessage;
  NeoMessage.params[0] := 0;
  NeoMessage.params[1] := y + 1;                // sous les lignes décalées
  NeoSendMessage(2, 7);
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A

Ligne B
Ligne C
NeoBASIC
10 ' Inserer une ligne vide entre A et B (groupe 2, fonction 10)
15 while peek($ff00) : wend : poke $ff01, 12 : poke $ff00, 2 : ' ecran vide
20 print "Ligne A" : print "Ligne B" : print "Ligne C"
30 while peek($ff00) : wend
40 poke $ff01, 13 : poke $ff00, 2
50 while peek($ff00) : wend : y = peek($ff05)
60 poke $ff04, y - 2 : poke $ff01, 10 : poke $ff00, 2
70 while peek($ff00) : wend
80 cursor 0, y + 1
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A

Ligne B
Ligne C
Assembleur 65C02 (64tass)
; Insérer une ligne vide entre A et B (groupe 2, fonction 10).
        .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:  jsr WaitMessage
        lda #2
        ldx #12                    ; écran vide : les lignes sont en haut
        jsr appel
        lda #<lignes
        ldx #>lignes
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #13                    ; Cursor Position
        jsr appel
        lda ControlPort+5          ; ligne sous « Ligne C »
        sta posy
        jsr WaitMessage
        sec
        sbc #2
        sta ControlPort+4          ; P0 : la ligne de « Ligne B »
        lda #2
        ldx #10                    ; fonction 10 : Insert Line
        jsr appel
        jsr WaitMessage
        stz ControlPort+4
        lda posy
        inc a
        sta ControlPort+5          ; sous les lignes décalées
        lda #2
        ldx #7
        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
diviseur: .byte 0

posy:   .byte 0
lignes: .text "Ligne A", 13, "Ligne B", 13, "Ligne C", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A

Ligne B
Ligne C

2,11 Delete Line Officiel

Supprime la ligne donnée ; les lignes suivantes remontent, une ligne vide apparaît en bas de l'écran.

Entrées
OctetsTypeRôle
P0uint8numéro de la ligne (0 = haut)

Sorties : aucune.

Fonction de service de la console (l'éditeur s'en sert) ; la documentation du firmware déconseille de l'utiliser directement.

Texte de la documentation du firmware (anglais)

This is a support function which deletes a line in the console and should not be used.

C (llvm-mos)
/* Supprimer la ligne « Ligne B » (groupe 2, fonction 11). */
#include <stdio.h>
#include <neo6502.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(2, 12);                                 /* écran vide : les lignes sont en haut */
    printf("Ligne A\nLigne B\nLigne C\n");
    libre();
    api(2, 13);                                 /* Cursor Position */
    uint8_t y = ControlPort.params[1];
    libre();
    ControlPort.params[0] = y - 2;              /* la ligne de « Ligne B » */
    api(2, 11);                                 /* Delete Line */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A
Ligne C
Mad Pascal
// Supprimer la ligne « Ligne B » (groupe 2, fonction 11).
program delline;
uses crt, neo6502;
var x, y: byte;
begin
  NeoSendMessage(2, 12);                        // écran vide : les lignes sont en haut
  NeoWaitMessage;
  writeln('Ligne A'); writeln('Ligne B'); writeln('Ligne C');
  NeoGetCursorPos(x, y);
  NeoWaitMessage;
  NeoMessage.params[0] := y - 2;                // la ligne de « Ligne B »
  NeoSendMessage(2, 11);                        // Delete Line
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A
Ligne C
NeoBASIC
10 ' Supprimer la ligne "Ligne B" (groupe 2, fonction 11)
15 while peek($ff00) : wend : poke $ff01, 12 : poke $ff00, 2 : ' ecran vide
20 print "Ligne A" : print "Ligne B" : print "Ligne C"
30 while peek($ff00) : wend
40 poke $ff01, 13 : poke $ff00, 2
50 while peek($ff00) : wend : y = peek($ff05)
60 poke $ff04, y - 2 : poke $ff01, 11 : poke $ff00, 2
70 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A
Ligne C
Assembleur 65C02 (64tass)
; Supprimer la ligne « Ligne B » (groupe 2, fonction 11).
        .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:  jsr WaitMessage
        lda #2
        ldx #12                    ; écran vide : les lignes sont en haut
        jsr appel
        lda #<lignes
        ldx #>lignes
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #13                    ; Cursor Position
        jsr appel
        lda ControlPort+5
        jsr WaitMessage
        sec
        sbc #2
        sta ControlPort+4          ; P0 : la ligne de « Ligne B »
        lda #2
        ldx #11                    ; fonction 11 : Delete Line
        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
diviseur: .byte 0

lignes: .text "Ligne A", 13, "Ligne B", 13, "Ligne C", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ligne A
Ligne C

2,12 Clear Screen Officiel

Efface l'écran de la console et replace le curseur en haut à gauche.

Entrées : aucune.

Sorties : aucune.

Le code de contrôle 12 envoyé par 2,6 a le même effet. La visibilité du curseur (2,19) est rétablie.

Texte de la documentation du firmware (anglais)

Clears the screen.

C (llvm-mos)
/* Effacer l'écran (groupe 2, fonction 12). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    printf("Ce texte va disparaitre\n");
    neo_console_clear_screen();
    printf("Ecran efface\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ecran efface
Mad Pascal
// Effacer l'écran (groupe 2, fonction 12).
program cls;
uses crt, neo6502;
begin
  writeln('Ce texte va disparaitre');
  NeoSendMessage(2, 12);                        // Clear Screen
  NeoWaitMessage;
  writeln('Ecran efface');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ecran efface
NeoBASIC
10 ' Effacer l'ecran (groupe 2, fonction 12)
20 print "Ce texte va disparaitre"
30 while peek($ff00) : wend
40 poke $ff01, 12 : poke $ff00, 2
50 while peek($ff00) : wend
60 print "Ecran efface"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ecran efface
Assembleur 65C02 (64tass)
; Effacer l'écran (groupe 2, fonction 12).
        .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 #<avant
        ldx #>avant
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #12                    ; fonction 12 : Clear Screen
        jsr appel
        lda #<apres
        ldx #>apres
        jmp ecrire

; 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
diviseur: .byte 0

avant:  .text "Ce texte va disparaitre", 13, 0
apres:  .text "Ecran efface", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ecran efface

2,13 Cursor Position Officiel

Donne la position du curseur (colonne, ligne).

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8colonne
P1uint8ligne

Mots-clés NeoBASIC qui font cet appel : print

Texte de la documentation du firmware (anglais)

Returns the current screen character cell of the cursor in Parameter:0 (X), Parameter:1 (Y).

C (llvm-mos)
/* Position du curseur après un texte de 7 caractères (groupe 2, fonction 13). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t x, y;
    printf("Bonjour");                          /* 7 caractères, sans retour à la ligne */
    neo_console_cursor_pos(&x, &y);
    printf("\nCurseur : colonne %u, ligne %u\n", x, y);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Curseur : colonne 7, ligne 27
Mad Pascal
// Position du curseur après un texte de 7 caractères (groupe 2, fonction 13).
program position;
uses crt, neo6502;
var x, y: byte;
begin
  write('Bonjour');                             // 7 caractères, sans retour à la ligne
  NeoGetCursorPos(x, y);
  writeln;
  writeln('Curseur : colonne ', x, ', ligne ', y);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Curseur : colonne 7, ligne 27
NeoBASIC
10 ' Position du curseur apres un texte de 7 caracteres (groupe 2, fonction 13)
20 ' lire les resultats dans des variables juste apres l'appel : print reutilise la boite aux lettres
30 print "Bonjour";
40 while peek($ff00) : wend
50 poke $ff01, 13 : poke $ff00, 2
60 while peek($ff00) : wend : x = peek($ff04) : y = peek($ff05)
70 print
80 print "Curseur : colonne ";x;", ligne ";y
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Curseur : colonne 7, ligne 29
Assembleur 65C02 (64tass)
; Position du curseur après un texte de 7 caractères (groupe 2, fonction 13).
        .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 #<texte
        ldx #>texte
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #13                    ; fonction 13 : Cursor Position
        jsr appel
        lda ControlPort+4          ; recopier avant d'afficher
        sta posx
        lda ControlPort+5
        sta posy
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda posx
        jsr decimal
        lda #<m2
        ldx #>m2
        jsr ecrire
        lda posy
        jsr decimal
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

posx:   .byte 0
posy:   .byte 0
texte:  .text "Bonjour", 0
m1:     .text 13, "Curseur : colonne ", 0
m2:     .text ", ligne ", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Bonjour
Curseur : colonne 7, ligne 27

2,14 Clear Region Officiel

Efface un rectangle de l'écran, bornes comprises.

Entrées
OctetsTypeRôle
P0uint8colonne de départ
P1uint8ligne de départ
P2uint8colonne de fin (comprise)
P3uint8ligne de fin (comprise)

Sorties : aucune.

Les bornes sont ramenées dans l'écran ; le rectangle est rempli d'espaces aux couleurs en cours.

Texte de la documentation du firmware (anglais)

Erase all characters within the rectangular region specified in Parameters:0,1 (begin X,Y) and Parameters:2,3 (end X,Y).

C (llvm-mos)
/* Creuser les colonnes 2 à 5 de trois lignes (groupe 2, fonction 14). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t x, y;
    printf("XXXXXXXXXX\nXXXXXXXXXX\nXXXXXXXXXX\n");
    neo_console_cursor_pos(&x, &y);
    neo_console_clear_region(2, y - 3, 5, y - 1);   /* colonnes 2 à 5 comprises */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
XX    XXXX
XX    XXXX
XX    XXXX
Mad Pascal
// Creuser les colonnes 2 à 5 de trois lignes (groupe 2, fonction 14).
program region;
uses crt, neo6502;
var x, y: byte;
begin
  writeln('XXXXXXXXXX'); writeln('XXXXXXXXXX'); writeln('XXXXXXXXXX');
  NeoGetCursorPos(x, y);
  NeoClearRegion(2, y - 3, 5, y - 1);           // colonnes 2 à 5 comprises
  NeoWaitMessage;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
XX    XXXX
XX    XXXX
XX    XXXX
NeoBASIC
10 ' Creuser les colonnes 2 a 5 de trois lignes (groupe 2, fonction 14)
20 for i = 1 to 3 : print "XXXXXXXXXX" : next i
30 while peek($ff00) : wend
40 poke $ff01, 13 : poke $ff00, 2
50 while peek($ff00) : wend : y = peek($ff05)
60 poke $ff04, 2 : poke $ff05, y - 3 : poke $ff06, 5 : poke $ff07, y - 1 : poke $ff01, 14 : poke $ff00, 2
70 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
XX    XXXX
XX    XXXX
XX    XXXX
Assembleur 65C02 (64tass)
; Creuser les colonnes 2 à 5 de trois lignes (groupe 2, fonction 14).
        .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 #<lignes
        ldx #>lignes
        jsr ecrire
        jsr WaitMessage
        lda #2
        ldx #13                    ; Cursor Position
        jsr appel
        ldy ControlPort+5          ; ligne sous le bloc
        jsr WaitMessage
        lda #2
        sta ControlPort+4          ; P0 : colonne 2
        tya
        sec
        sbc #3
        sta ControlPort+5          ; P1 : première ligne du bloc
        lda #5
        sta ControlPort+6          ; P2 : colonne 5 (comprise)
        dey
        sty ControlPort+7          ; P3 : dernière ligne du bloc
        lda #2
        ldx #14                    ; fonction 14 : Clear Region
        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
diviseur: .byte 0

lignes: .text "XXXXXXXXXX", 13, "XXXXXXXXXX", 13, "XXXXXXXXXX", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
XX    XXXX
XX    XXXX
XX    XXXX

2,15 Set Text Color Officiel

Choisit la couleur du texte et celle du fond pour les caractères écrits ensuite.

Entrées
OctetsTypeRôle
P0uint8couleur du texte (0 à 15)
P1uint8couleur du fond (0 à 15)

Sorties : aucune.

Les codes $80-$8F et $90-$9F écrits par 2,6 font la même chose caractère par caractère. 2,18 relit les couleurs en cours, pour les rétablir.

Texte de la documentation du firmware (anglais)

Sets the foreground colour to Parameter:0 and the background colour to Parameter:1.

C (llvm-mos)
/* Écrire en couleur, puis rétablir les couleurs (groupe 2, fonctions 15 et 18). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t encre, papier;
    neo_console_get_text_color(&encre, &papier);  /* 2,18 : couleurs en cours */
    neo_console_set_text_color(3, 1);             /* texte 3 sur fond 1 */
    printf("Texte en couleur");
    neo_console_set_text_color(encre, papier);    /* rétablir */
    printf("\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Texte en couleur
Mad Pascal
// Écrire en couleur, puis rétablir les couleurs (groupe 2, fonctions 15 et 18).
program couleur;
uses crt, neo6502;
var encre, papier: byte;
begin
  NeoSendMessage(2, 18);                        // Read Ink/Paper Colours
  NeoWaitMessage;
  encre := NeoMessage.params[0];
  papier := NeoMessage.params[1];
  NeoSetTextColor(3, 1);                        // texte 3 sur fond 1
  NeoWaitMessage;
  write('Texte en couleur');
  NeoSetTextColor(encre, papier);               // rétablir
  NeoWaitMessage;
  writeln;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Texte en couleur
NeoBASIC
10 ' Ecrire en couleur, puis retablir les couleurs (groupe 2, fonctions 15 et 18)
20 while peek($ff00) : wend
30 poke $ff01, 18 : poke $ff00, 2
40 while peek($ff00) : wend : e = peek($ff04) : p = peek($ff05)
50 poke $ff04, 3 : poke $ff05, 1 : poke $ff01, 15 : poke $ff00, 2
60 while peek($ff00) : wend
70 print "Texte en couleur";
80 while peek($ff00) : wend
90 poke $ff04, e : poke $ff05, p : poke $ff01, 15 : poke $ff00, 2
100 while peek($ff00) : wend
110 print
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Texte en couleur
Assembleur 65C02 (64tass)
; Écrire en couleur, puis rétablir les couleurs (groupe 2, fonctions 15 et 18).
        .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:  jsr WaitMessage
        lda #2
        ldx #18                    ; 2,18 : couleurs en cours
        jsr appel
        lda ControlPort+4
        sta encre
        lda ControlPort+5
        sta papier
        jsr WaitMessage
        lda #3
        sta ControlPort+4          ; P0 : texte 3
        lda #1
        sta ControlPort+5          ; P1 : fond 1
        lda #2
        ldx #15                    ; fonction 15 : Set Text Color
        jsr appel
        lda #<texte
        ldx #>texte
        jsr ecrire
        jsr WaitMessage
        lda encre                  ; rétablir
        sta ControlPort+4
        lda papier
        sta ControlPort+5
        lda #2
        ldx #15
        jsr appel
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

encre:  .byte 0
papier: .byte 0
texte:  .text "Texte en couleur", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Texte en couleur

2,16 Cursor Inverse Officiel

Inverse les couleurs (texte et fond) de la case du curseur ; un second appel les rétablit.

Entrées : aucune.

Sorties : aucune.

Fonction de service (clignotement du curseur) ; la documentation du firmware déconseille de l'utiliser.

Texte de la documentation du firmware (anglais)

Toggles the cursor colour between normal and inverse (ie: swaps FG and BG colors). This should not be used.

C (llvm-mos)
/* Inverser la case du curseur, puis la rétablir (groupe 2, fonction 16). */
#include <stdio.h>
#include <neo6502.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(2, 16);                                 /* Cursor Inverse */
    libre();
    api(2, 16);                                 /* et retour */
    printf("Case du curseur inversee deux fois\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Case du curseur inversee deux fois
Mad Pascal
// Inverser la case du curseur, puis la rétablir (groupe 2, fonction 16).
program inverse;
uses crt, neo6502;
begin
  NeoCursorInverse;                             // Cursor Inverse
  NeoWaitMessage;
  NeoCursorInverse;                             // et retour
  NeoWaitMessage;
  writeln('Case du curseur inversee deux fois');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Case du curseur inversee deux fois
NeoBASIC
10 ' Inverser la case du curseur, puis la retablir (groupe 2, fonction 16)
20 for i = 1 to 2
30 while peek($ff00) : wend
40 poke $ff01, 16 : poke $ff00, 2
50 next i
60 while peek($ff00) : wend
70 print "Case du curseur inversee deux fois"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Case du curseur inversee deux fois
Assembleur 65C02 (64tass)
; Inverser la case du curseur, puis la rétablir (groupe 2, fonction 16).
        .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:  jsr WaitMessage
        lda #2
        ldx #16                    ; fonction 16 : Cursor Inverse
        jsr appel
        jsr WaitMessage
        lda #2
        ldx #16                    ; et retour
        jsr appel
        lda #<texte
        ldx #>texte
        jmp ecrire

; 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
diviseur: .byte 0

texte:  .text "Case du curseur inversee deux fois", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Case du curseur inversee deux fois

2,17 Tab() implementation Officiel

Écrit des espaces jusqu'à ce que le curseur atteigne la colonne donnée (sert au tab() de NeoBASIC).

Entrées
OctetsTypeRôle
P0uint8colonne à atteindre

Sorties : aucune.

Si le curseur est déjà au-delà, rien n'est écrit. En NeoBASIC, tab(n) dans un print fait le même appel.

Mots-clés NeoBASIC qui font cet appel : tab()

Texte de la documentation du firmware (anglais)

Internal helper.

C (llvm-mos)
/* Aligner B en colonne 10 (groupe 2, fonction 17). */
#include <stdio.h>
#include <neo6502.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) {
    printf("A");
    libre();
    ControlPort.params[0] = 10;                 /* colonne à atteindre */
    api(2, 17);                                 /* Tab */
    printf("B\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
A         B
Mad Pascal
// Aligner B en colonne 10 (groupe 2, fonction 17).
program tab;
uses crt, neo6502;
begin
  write('A');
  NeoWaitMessage;
  NeoMessage.params[0] := 10;                   // colonne à atteindre
  NeoSendMessage(2, 17);                        // Tab
  NeoWaitMessage;
  writeln('B');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
A         B
NeoBASIC
10 ' Aligner B en colonne 10 (groupe 2, fonction 17)
20 print "A";tab(10);"B"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
A         B
Assembleur 65C02 (64tass)
; Aligner B en colonne 10 (groupe 2, fonction 17).
        .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 #'A'
        jsr WriteCharacter
        jsr WaitMessage
        lda #10
        sta ControlPort+4          ; P0 : colonne à atteindre
        lda #2
        ldx #17                    ; fonction 17 : Tab
        jsr appel
        lda #'B'
        jsr WriteCharacter
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
A         B

2,18 Read Ink/Paper Colours Officiel

Donne les couleurs en cours du texte (encre) et du fond (papier).

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8couleur du texte
P1uint8couleur du fond
Texte de la documentation du firmware (anglais)

Read the ink/paper colours into Param[0] and Param[1]

C (llvm-mos)
/* Couleurs en cours (groupe 2, fonction 18). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    uint8_t encre, papier;
    neo_console_get_text_color(&encre, &papier);
    printf("Encre : %u, papier : %u\n", encre, papier);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Encre : 2, papier : 0
Mad Pascal
// Couleurs en cours (groupe 2, fonction 18).
program couleurs;
uses crt, neo6502;
var encre, papier: byte;
begin
  NeoSendMessage(2, 18);                        // Read Ink/Paper Colours
  NeoWaitMessage;
  encre := NeoMessage.params[0];
  papier := NeoMessage.params[1];
  writeln('Encre : ', encre, ', papier : ', papier);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Encre : 2, papier : 0
NeoBASIC
10 ' Couleurs en cours (groupe 2, fonction 18)
20 ' lire les resultats dans des variables juste apres l'appel : print reutilise la boite aux lettres
30 while peek($ff00) : wend
40 poke $ff01, 18 : poke $ff00, 2
50 while peek($ff00) : wend : e = peek($ff04) : p = peek($ff05)
60 print "Encre : ";e;", papier : ";p
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Encre : 2, papier : 0
Assembleur 65C02 (64tass)
; Couleurs en cours (groupe 2, fonction 18).
        .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:  jsr WaitMessage
        lda #2
        ldx #18                    ; fonction 18 : Read Ink/Paper Colours
        jsr appel
        lda ControlPort+4
        sta encre
        lda ControlPort+5
        sta papier
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda encre
        jsr decimal
        lda #<m2
        ldx #>m2
        jsr ecrire
        lda papier
        jsr decimal
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

encre:  .byte 0
papier: .byte 0
m1:     .text "Encre : ", 0
m2:     .text ", papier : ", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Encre : 2, papier : 0

2,19 Show/Hide Cursor Reversing Officiel

Montre ou cache le curseur clignotant.

Entrées
OctetsTypeRôle
P0uint8non nul : visible, 0 : caché

Sorties : aucune.

Effacer l'écran (2,12) rend le curseur visible.

Texte de la documentation du firmware (anglais)

Set the cursor visibility to Param[0]. This is reset by clearing the screen.

C (llvm-mos)
/* Cacher le curseur, puis le réafficher (groupe 2, fonction 19). */
#include <stdio.h>
#include <neo/api.h>

int main(void) {
    neo_console_set_cursor_visibility(0);       /* caché */
    neo_console_set_cursor_visibility(1);       /* visible */
    printf("Curseur cache puis reaffiche\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Curseur cache puis reaffiche
Mad Pascal
// Cacher le curseur, puis le réafficher (groupe 2, fonction 19).
program visibilite;
uses crt, neo6502;

procedure curseur(visible: byte);
begin
  NeoWaitMessage;
  NeoMessage.params[0] := visible;
  NeoSendMessage(2, 19);                        // Show/Hide Cursor
  NeoWaitMessage;
end;

begin
  curseur(0);
  curseur(1);
  writeln('Curseur cache puis reaffiche');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Curseur cache puis reaffiche
NeoBASIC
10 ' Cacher le curseur, puis le reafficher (groupe 2, fonction 19)
20 for v = 0 to 1
30 while peek($ff00) : wend
40 poke $ff04, v : poke $ff01, 19 : poke $ff00, 2
50 next v
60 while peek($ff00) : wend
70 print "Curseur cache puis reaffiche"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Curseur cache puis reaffiche
Assembleur 65C02 (64tass)
; Cacher le curseur, puis le réafficher (groupe 2, fonction 19).
        .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 #0                     ; caché
        jsr visible
        lda #1                     ; visible
        jsr visible
        lda #<texte
        ldx #>texte
        jmp ecrire

visible:
        pha
        jsr WaitMessage
        pla
        sta ControlPort+4          ; P0 : visibilité
        lda #2
        ldx #19                    ; fonction 19 : Show/Hide Cursor
        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
diviseur: .byte 0

texte:  .text "Curseur cache puis reaffiche", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Curseur cache puis reaffiche

2,20 Console Debug Echo Trinity

Recopie tout ce qui s'écrit sur la console vers le port de débogage (l'UART GP28/GP29 sur la carte) : un PC peut ainsi capter le texte de l'écran.

Entrées
OctetsTypeRôle
P0uint80 : arrêt ; 1 : caractères imprimables et Entrée (en CR LF) ; 2 : aussi les caractères $A0-$FF

Sorties : aucune.

Dans les émulateurs, l'écho part sur la sortie d'erreur.

Texte de la documentation du firmware (anglais)

Parameter:0 non zero : every printable character written to the console (and Enter, as CR LF) is also sent to the debug port (UART GP28/GP29 on the board, stderr in the emulators) ; 2 also forwards the characters $A0-$FF. 0 stops the echo. Lets a PC capture the screen text of a real board over the serial link (Trinity T-20, F-92 of the fork).

C (llvm-mos)
/* Recopier la console vers le port de débogage le temps d'une ligne (groupe 2, fonction 20). */
#include <stdio.h>
#include <neo6502.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 void echo(uint8_t mode) {
    libre();
    ControlPort.params[0] = mode;
    api(2, 20);                                 /* Console Debug Echo */
}

int main(void) {
    echo(1);
    printf("Ce texte part aussi sur le port de debogage\n");
    echo(0);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ce texte part aussi sur le port de debogage
Mad Pascal
// Recopier la console vers le port de débogage le temps d'une ligne (groupe 2, fonction 20).
program echo;
uses crt, neo6502;

procedure echo(mode: byte);
begin
  NeoWaitMessage;
  NeoMessage.params[0] := mode;
  NeoSendMessage(2, 20);                        // Console Debug Echo
  NeoWaitMessage;
end;

begin
  echo(1);
  writeln('Ce texte part aussi sur le port de debogage');
  echo(0);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ce texte part aussi sur le port de debogage
NeoBASIC
10 ' Recopier la console vers le port de debogage le temps d'une ligne (groupe 2, fonction 20)
20 while peek($ff00) : wend
30 poke $ff04, 1 : poke $ff01, 20 : poke $ff00, 2
40 while peek($ff00) : wend
50 print "Ce texte part aussi sur le port de debogage"
60 while peek($ff00) : wend
70 poke $ff04, 0 : poke $ff01, 20 : poke $ff00, 2
80 while peek($ff00) : wend
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ce texte part aussi sur le port de debogage
Assembleur 65C02 (64tass)
; Recopier la console vers le port de débogage le temps d'une ligne (groupe 2, fonction 20).
        .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 #1
        jsr echo
        lda #<texte
        ldx #>texte
        jsr ecrire
        lda #0
echo:   pha
        jsr WaitMessage
        pla
        sta ControlPort+4          ; P0 : mode d'écho
        lda #2
        ldx #20                    ; fonction 20 : Console Debug Echo
        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
diviseur: .byte 0

texte:  .text "Ce texte part aussi sur le port de debogage", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ce texte part aussi sur le port de debogage

2,21 Set Console Font Trinity

Remplace la police des caractères $20-$7F de la console par une police en RAM ; l'adresse 0 rétablit la police intégrée.

Entrées
OctetsTypeRôle
P0-P1addr96 caractères de 8 octets (un octet par ligne, bit 7 = pixel de gauche), du $20 au $7F ; 0 : police intégrée
P2-P3addr96 caractères de 14 octets pour les cases 9×14 du mode Hercules (1) ; 0 : garder la police 8×14 intégrée
Sorties
OctetsTypeRôle
erreuruint8non nul si la police dépasserait la fin de la mémoire

La police est lue sur place à chaque rafraîchissement, sans copie : la garder intacte tant qu'elle est choisie. Toute la console est redessinée. Un changement de mode (5,9) ou un redémarrage rétablit la police intégrée. Les caractères $A0-$BF (symboles Latin-1) et $C0-$FF (2,5) ne changent pas.

Texte de la documentation du firmware (anglais)

Selects the font used by the console for the characters $20-$7F (Trinity T-20, F-95 of the fork). On input:

Parameters:0,1 is the address, in 6502 RAM, of 96 glyphs of 8 bytes (one byte per row, bit 7 = leftmost pixel ; the console draws the 6 leftmost columns in 6x8 cells and all 8 in 8x8 cells), in ASCII order from $20 to $7F ; $0000 restores the built in font.

Parameters:2,3 is likewise the address of 96 glyphs of 14 bytes (8 columns) used by the 9x14 cells of the Hercules mode 1 ; $0000 keeps the built in 8x14 font. Each address is checked and applied on its own.

The glyphs are read in place at every repaint (no copy) : the program must keep them intact while the font is selected. The whole console is repainted. Characters $A0-$BF keep the built in Latin-1 symbols and $C0-$FF the user defined characters (Function 2,5 ; Latin-1 letters by default). The built in font is restored by a mode change (5,9) and at reset. Sets the error flag if the glyphs would run past the end of memory.

C (llvm-mos)
/* Remplacer la police par des cadres, puis rétablir l'originale (groupe 2, fonction 21). */
#include <stdio.h>
#include <neo6502.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 police[96 * 8];                  /* 96 caractères de 8 lignes */

static void choisir(uint16_t adresse) {
    libre();
    ControlPort.params[0] = adresse & 0xFF;
    ControlPort.params[1] = adresse >> 8;
    ControlPort.params[2] = 0;                  /* mode Hercules : police intégrée */
    ControlPort.params[3] = 0;
    api(2, 21);                                 /* Set Console Font */
}

int main(void) {
    static const uint8_t cadre[8] = { 0x00, 0xFC, 0x84, 0x84, 0x84, 0x84, 0xFC, 0x00 };
    for (unsigned i = 0; i < sizeof police; i++)
        police[i] = cadre[i % 8];
    choisir((uint16_t)police);
    printf("Police remplacee\n");
    choisir(0);                                 /* police intégrée */
    printf("Police d'origine\n");
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police remplacee
Police d'origine
Mad Pascal
// Remplacer la police par des cadres, puis rétablir l'originale (groupe 2, fonction 21).
program police;
uses crt, neo6502;
const cadre: array[0..7] of byte = ($00, $FC, $84, $84, $84, $84, $FC, $00);
var fonte: array[0..767] of byte;               // 96 caractères de 8 lignes
    i: word;

procedure choisir(adresse: word);
begin
  NeoWaitMessage;
  wordParams[0] := adresse;
  wordParams[1] := 0;                           // mode Hercules : police intégrée
  NeoSendMessage(2, 21);                        // Set Console Font
  NeoWaitMessage;
end;

begin
  for i := 0 to 767 do fonte[i] := cadre[i and 7];
  choisir(word(@fonte));
  writeln('Police remplacee');
  choisir(0);                                   // police intégrée
  writeln('Police d''origine');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police remplacee
Police d'origine
NeoBASIC
10 ' Remplacer la police par des cadres, puis retablir l'originale (groupe 2, fonction 21)
20 a = alloc(768)
30 for i = 0 to 95 : for r = 0 to 7 : read v : poke a + i * 8 + r, v : next r : restore : next i
40 data 0, $fc, $84, $84, $84, $84, $fc, 0
50 while peek($ff00) : wend
60 poke $ff04, a & 255 : poke $ff05, a >> 8 : poke $ff06, 0 : poke $ff07, 0 : poke $ff01, 21 : poke $ff00, 2
70 while peek($ff00) : wend
80 print "Police remplacee"
90 while peek($ff00) : wend
100 poke $ff04, 0 : poke $ff05, 0 : poke $ff06, 0 : poke $ff07, 0 : poke $ff01, 21 : poke $ff00, 2
110 while peek($ff00) : wend
120 print "Police d'origine"
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police remplacee
Police d'origine
Assembleur 65C02 (64tass)
; Remplacer la police par des cadres, puis rétablir l'originale (groupe 2, fonction 21).
        .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

POLICE = $4000                     ; 96 caractères de 8 lignes = 768 octets

start:  lda #<POLICE               ; remplir la police : le même cadre partout
        sta ptr
        lda #>POLICE
        sta ptr+1
        ldx #96
_car:   ldy #7
_lig:   lda cadre,y
        sta (ptr),y
        dey
        bpl _lig
        clc
        lda ptr
        adc #8
        sta ptr
        bcc _s
        inc ptr+1
_s:     dex
        bne _car
        lda #<POLICE
        ldx #>POLICE
        jsr choisir
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda #0                     ; police intégrée
        tax
        jsr choisir
        lda #<m2
        ldx #>m2
        jmp ecrire

; A/X = adresse de la police (0 : intégrée).
choisir:
        pha
        jsr WaitMessage
        pla
        sta ControlPort+4          ; P0-P1 : police 8×8
        stx ControlPort+5
        stz ControlPort+6          ; P2-P3 : 0, police Hercules intégrée
        stz ControlPort+7
        lda #2
        ldx #21                    ; fonction 21 : Set Console Font
        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
diviseur: .byte 0

cadre:  .byte $00, $FC, $84, $84, $84, $84, $FC, $00
m1:     .text "Police remplacee", 13, 0
m2:     .text "Police d'origine", 13, 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police remplacee
Police d'origine

2,22 Get Media Key Trinity

Donne la dernière touche multimédia du clavier USB (volume, lecture, piste suivante…) et les touches système, puis les efface.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0-P1uint16code « Consumer Control » (page HID $0C) : $00E9 volume +, $00EA volume −, $00E2 muet, $00CD lecture/pause, $00B5 suivant, $00B6 précédent, $0223 accueil… ; 0 : rien
P2uint8touches système : bit 0 veille, bit 1 marche, bit 2 réveil

Les deux valeurs sont remises à zéro par l'appel : un programme l'interroge régulièrement. Les claviers exposent ces touches sur une seconde interface HID, que le firmware reprend au gestionnaire de manettes.

Texte de la documentation du firmware (anglais)

Returns the last media key pressed on the USB keyboard in Parameters:0,1 (Consumer Control usage, HID usage page $0C : $00E9 volume up, $00EA volume down, $00E2 mute, $00CD play/pause, $00B5 next, $00B6 previous, $0223 home...) and the system keys in Parameter:2 (bit 0 sleep, bit 1 power, bit 2 wake). Both are cleared by this call, so a program polls it ; 0 means nothing pressed since the last call. Keyboards expose these keys on a second HID interface without boot protocol, which the firmware claims from the gamepad manager (Trinity T-39).

C (llvm-mos)
/* Dernière touche multimédia (groupe 2, fonction 22). */
#include <stdio.h>
#include <neo6502.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(2, 22);                                 /* Get Media Key */
    uint16_t touche = ControlPort.params[0] | (ControlPort.params[1] << 8);
    uint8_t systeme = ControlPort.params[2];
    printf("Touche multimedia : %u, systeme : %u\n", touche, systeme);   /* 0 : rien */
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Touche multimedia : 0, systeme : 0
Mad Pascal
// Dernière touche multimédia (groupe 2, fonction 22).
program media;
uses crt, neo6502;
var touche: word;
    systeme: byte;
begin
  NeoSendMessage(2, 22);                        // Get Media Key
  NeoWaitMessage;
  touche := wordParams[0];
  systeme := NeoMessage.params[2];
  writeln('Touche multimedia : ', touche, ', systeme : ', systeme);   // 0 : rien
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Touche multimedia : 0, systeme : 0
NeoBASIC
10 ' Derniere touche multimedia (groupe 2, fonction 22)
20 ' lire les resultats dans des variables juste apres l'appel, avant tout calcul : print et * reutilisent la boite aux lettres
30 while peek($ff00) : wend
40 poke $ff01, 22 : poke $ff00, 2
50 while peek($ff00) : wend : t0 = peek($ff04) : t1 = peek($ff05) : s = peek($ff06) : t = t0 + 256 * t1
60 print "Touche multimedia : ";t;", systeme : ";s
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Touche multimedia : 0, systeme : 0
Assembleur 65C02 (64tass)
; Dernière touche multimédia (groupe 2, fonction 22) : affiche l'octet de poids faible.
        .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:  jsr WaitMessage
        lda #2
        ldx #22                    ; fonction 22 : Get Media Key
        jsr appel
        lda ControlPort+4          ; P0 : code (poids faible)
        sta touche
        lda ControlPort+6          ; P2 : touches système
        sta systeme
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda touche
        jsr decimal
        lda #<m2
        ldx #>m2
        jsr ecrire
        lda systeme
        jsr decimal
        lda #13
        jmp WriteCharacter

; 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
diviseur: .byte 0

touche:  .byte 0
systeme: .byte 0
m1:      .text "Touche multimedia : ", 0
m2:      .text ", systeme : ", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Touche multimedia : 0, systeme : 0

2,23 Get Lock Keys Trinity

Donne l'état des touches de verrouillage du clavier USB : Verr. Num, Verr. Maj, Arrêt défil.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8bit 0 Verr. Num, bit 1 Verr. Maj, bit 2 Arrêt défil

Le firmware bascule ces états à chaque appui et allume les voyants du clavier. Verr. Maj inverse la casse des lettres seulement ; Verr. Num donne les chiffres au pavé numérique ; Arrêt défil n'est qu'un état, libre pour le programme. Verr. Num est éteint au démarrage.

Texte de la documentation du firmware (anglais)

Returns in Parameter:0 the state of the lock keys of the USB keyboard : bit 0 Num Lock, bit 1 Caps Lock, bit 2 Scroll Lock (Trinity T-40). The firmware toggles them on each press and lights the matching LEDs on the keyboard, which the upstream never did. They also drive how keys are read (Trinity T-41) : Caps Lock swaps the case of the letters only, Num Lock gives the numeric keypad its figures (off : the navigation keys printed on the keys). Scroll Lock is only a state and a LED, for the program to use as it likes. Num Lock starts off.

C (llvm-mos)
/* État des touches de verrouillage (groupe 2, fonction 23). */
#include <stdio.h>
#include <neo6502.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 const char *oui_non(uint8_t b) { return b ? "oui" : "non"; }

int main(void) {
    libre();
    api(2, 23);                                 /* Get Lock Keys */
    uint8_t v = ControlPort.params[0];
    printf("Verr. Num : %s, Verr. Maj : %s, Arret defil : %s\n",
           oui_non(v & 1), oui_non(v & 2), oui_non(v & 4));
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Verr. Num : non, Verr. Maj : non, Arret defil : non
Mad Pascal
// État des touches de verrouillage (groupe 2, fonction 23).
program verrous;
uses crt, neo6502;
var v: byte;

function oui_non(b: byte): string;
begin
  if b <> 0 then result := 'oui' else result := 'non';
end;

begin
  NeoSendMessage(2, 23);                        // Get Lock Keys
  NeoWaitMessage;
  v := NeoMessage.params[0];
  writeln('Verr. Num : ', oui_non(v and 1), ', Verr. Maj : ', oui_non(v and 2),
          ', Arret defil : ', oui_non(v and 4));
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Verr. Num : non, Verr. Maj : non, Arret defil : non
NeoBASIC
10 ' Etat des touches de verrouillage (groupe 2, fonction 23)
20 ' lire les resultats dans des variables juste apres l'appel : print reutilise la boite aux lettres
30 while peek($ff00) : wend
40 poke $ff01, 23 : poke $ff00, 2
50 while peek($ff00) : wend : v = peek($ff04)
60 n$ = "non" : m$ = "non" : d$ = "non"
70 if v & 1 then n$ = "oui"
80 if v & 2 then m$ = "oui"
90 if v & 4 then d$ = "oui"
100 print "Verr. Num : ";n$;", Verr. Maj : ";m$;", Arret defil : ";d$
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Verr. Num : non, Verr. Maj : non, Arret defil : non
Assembleur 65C02 (64tass)
; État des touches de verrouillage (groupe 2, fonction 23).
        .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:  jsr WaitMessage
        lda #2
        ldx #23                    ; fonction 23 : Get Lock Keys
        jsr appel
        lda ControlPort+4          ; bit 0 Num, bit 1 Maj, bit 2 Défil
        sta etat
        lda #<m1
        ldx #>m1
        jsr ecrire
        lda #1
        jsr oui_non
        lda #<m2
        ldx #>m2
        jsr ecrire
        lda #2
        jsr oui_non
        lda #<m3
        ldx #>m3
        jsr ecrire
        lda #4
        jsr oui_non
        lda #13
        jmp WriteCharacter

oui_non:
        and etat
        beq _non
        lda #<oui
        ldx #>oui
        jmp ecrire
_non:   lda #<non
        ldx #>non
        jmp ecrire

; 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
diviseur: .byte 0

etat:   .byte 0
m1:     .text "Verr. Num : ", 0
m2:     .text ", Verr. Maj : ", 0
m3:     .text ", Arret defil : ", 0
oui:    .text "oui", 0
non:    .text "non", 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Verr. Num : non, Verr. Maj : non, Arret defil : non

← L'API du Neo6502