Tachibana
Langue : français

Groupe 38 — Gestionnaire de ressources Trinity

38,1 Open Resource File · 38,2 Close Resource File · 38,3 Count Resources · 38,4 Find Resource · 38,5 Get Resource Info · 38,6 Get Resource Size · 38,7 Load Resource · 38,8 Use Font

Le gestionnaire de ressources de la boîte à outils de Trinity lit des fichiers de ressources au format NR1 : un en-tête (« NR », version 1, nombre de ressources), une table de 16 octets par ressource (type de 4 caractères, identifiant sur 16 bits, décalage et taille sur 32 bits), puis les données. Ils se fabriquent avec tools/toolbox/mkres.py, dans le dépôt de Trinity.

Les exemples utilisent demo.res, posé à la racine du stockage et fabriqué ainsi : mkres.py demo.res TEXT:1:bonjour.txt FONT:1:cadre.nf1 TEXT:2:neo.txt, où bonjour.txt contient « Bonjour », neo.txt « Neo6502 ! » et cadre.nf1 la police d'un caractère de l'exemple 32,15 (17 octets). Les exemples l'ouvrent sur le canal de fichier 1.

38,1 Open Resource File Trinity

Ouvre un fichier de ressources NR1 sur un canal de fichier.

Entrées
OctetsTypeRôle
P0uint8canal de fichier
P1-P2addradresse du nom, précédé de sa longueur
Sorties
OctetsTypeRôle
erreuruint81 canal invalide ou pas un fichier de ressources, 2 erreur de stockage

Un seul fichier de ressources est ouvert à la fois : en ouvrir un autre ferme le premier. Rien n'est gardé côté RP2040 : la table est relue sur le stockage à chaque appel. Au banc, un fichier absent rend l'erreur 2. NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Toolbox (Trinity, T-12, ADR-01 of the fork). Opens on file channel Parameter:0 the resource file whose length-prefixed name is at Parameters:1,2 (format NR1, built by tools/mkres.py of the fork archive : a table of resources, each with a 4 character type, a 16 bit id, an offset and a size, then the data). One resource file is open at a time (opening another closes it) ; nothing is cached in the RP2040, the table is read from storage on each call. Errors : 1 bad channel or not a resource file, 2 storage error. Resources are numbered 1..count in table order.

C (llvm-mos)
/* Ouvrir un fichier de ressources (groupe 38, fonction 1, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

static const char absent[] = "\010rien.res";

int main(void) {
    uint8_t e1, e2, n;
    e1 = ouvrir(absent);                        /* fichier absent : erreur de stockage */
    e2 = ouvrir(demo);
    libre(); res(3); n = ControlPort.params[0]; /* 38,3 : nombre de ressources */
    fermer();
    printf("Fichier absent : erreur %u\ndemo.res : erreur %u, %u ressources\n", e1, e2, n);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fichier absent : erreur 2
demo.res : erreur 0, 3 ressources
Mad Pascal
// Ouvrir un fichier de ressources (groupe 38, fonction 1, Trinity).
program rs1;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

const absent: array[0..8] of byte = (8, ord('r'), ord('i'), ord('e'), ord('n'), ord('.'), ord('r'), ord('e'), ord('s'));
var e1, e2, n: byte;
begin
  e1 := ouvrir(@absent);                        // fichier absent : erreur de stockage
  e2 := ouvrir(@demo);
  res(3); n := NeoMessage.params[0];            // 38,3 : nombre de ressources
  fermer;
  writeln('Fichier absent : erreur ', e1);
  writeln('demo.res : erreur ', e2, ', ', n, ' ressources');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fichier absent : erreur 2
demo.res : erreur 0, 3 ressources
NeoBASIC
10 ' Ouvrir un fichier de ressources (groupe 38, fonction 1, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "rien.res" : gosub 8900 : gosub 8000 : e1 = e : ' fichier absent : erreur de stockage
30 s$ = "demo.res" : gosub 8900 : gosub 8000 : e2 = e
40 while peek($ff00) : wend : f = 3 : gosub 8110 : n = peek($ff04) : ' 38,3 : nombre de ressources
50 gosub 8200
60 print "Fichier absent : erreur ";e1
70 print "demo.res : erreur ";e2;", ";n;" ressources"
80 end
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fichier absent : erreur 2
demo.res : erreur 0, 3 ressources
Assembleur 65C02 (64tass)
; Ouvrir un fichier de ressources (groupe 38, fonction 1, Trinity).
        .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 #<absent
        ldx #>absent
        jsr ouvrir                 ; fichier absent : erreur de stockage
        sta e1
        lda #<demo
        ldx #>demo
        jsr ouvrir
        sta e2
        jsr WaitMessage
        ldx #3                  ; 38,3 : nombre de ressources
        jsr res
        lda ControlPort+4
        sta n
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda e1
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda e2
        jsr decimal
        lda #<t2
        ldx #>t2
        jsr ecrire
        lda n
        jsr decimal
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
absent: .byte 8
        .text "rien.res"
e1:     .byte 0
e2:     .byte 0
n:      .byte 0
t0:     .text "Fichier absent : erreur ", 0
t1:     .text "demo.res : erreur ", 0
t2:     .text ", ", 0
t3:     .text " ressources", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fichier absent : erreur 2
demo.res : erreur 0, 3 ressources

38,2 Close Resource File Trinity

Ferme le fichier de ressources et son canal.

Entrées : aucune.

Sorties
OctetsTypeRôle
erreuruint81 si aucun fichier n'est ouvert

Après la fermeture, les autres fonctions du groupe rendent l'erreur 1. NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Closes the resource file and its channel (error 1 if none is open).

C (llvm-mos)
/* Fermer le fichier de ressources (groupe 38, fonction 2, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

int main(void) {
    uint8_t e1, e2, e3;
    ouvrir(demo);
    libre(); e1 = res(2);                       /* Close Resource File : ferme aussi le canal */
    libre(); e2 = res(2);                       /* plus rien d'ouvert */
    libre(); e3 = res(3);
    printf("Fermeture : erreur %u ; encore : erreur %u\nCompter ensuite : erreur %u\n", e1, e2, e3);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fermeture : erreur 0 ; encore : erreur 1
Compter ensuite : erreur 1
Mad Pascal
// Fermer le fichier de ressources (groupe 38, fonction 2, Trinity).
program rs2;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

var e1, e2, e3: byte;
begin
  ouvrir(@demo);
  e1 := res(2);                                 // Close Resource File : ferme aussi le canal
  e2 := res(2);                                 // plus rien d'ouvert
  e3 := res(3);
  writeln('Fermeture : erreur ', e1, ' ; encore : erreur ', e2);
  writeln('Compter ensuite : erreur ', e3);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fermeture : erreur 0 ; encore : erreur 1
Compter ensuite : erreur 1
NeoBASIC
10 ' Fermer le fichier de ressources (groupe 38, fonction 2, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "demo.res" : gosub 8900 : gosub 8000
30 gosub 8200 : e1 = e : ' Close Resource File : ferme aussi le canal
40 gosub 8200 : e2 = e : ' plus rien d'ouvert
50 while peek($ff00) : wend : f = 3 : gosub 8110 : e3 = e
60 print "Fermeture : erreur ";e1;" ; encore : erreur ";e2
70 print "Compter ensuite : erreur ";e3
80 end
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fermeture : erreur 0 ; encore : erreur 1
Compter ensuite : erreur 1
Assembleur 65C02 (64tass)
; Fermer le fichier de ressources (groupe 38, fonction 2, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        jsr WaitMessage
        ldx #2                  ; Close Resource File : ferme aussi le canal
        jsr res
        sta e1
        jsr WaitMessage
        ldx #2                  ; plus rien d'ouvert
        jsr res
        sta e2
        jsr WaitMessage
        ldx #3                  ; 38,3
        jsr res
        sta e3
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda e1
        jsr decimal
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda e2
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t2
        ldx #>t2
        jsr ecrire
        lda e3
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
e1:     .byte 0
e2:     .byte 0
e3:     .byte 0
t0:     .text "Fermeture : erreur ", 0
t1:     .text " ; encore : erreur ", 0
t2:     .text "Compter ensuite : erreur ", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Fermeture : erreur 0 ; encore : erreur 1
Compter ensuite : erreur 1

38,3 Count Resources Trinity

Rend le nombre de ressources du fichier ouvert.

Entrées : aucune.

Sorties
OctetsTypeRôle
P0uint8nombre de ressources

Les ressources sont numérotées de 1 à ce nombre, dans l'ordre de la table. NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Returns the number of resources of the open file in Parameter:0.

C (llvm-mos)
/* Compter les ressources (groupe 38, fonction 3, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

int main(void) {
    uint8_t n;
    ouvrir(demo);
    libre(); res(3);                            /* Count Resources : numérotées de 1 à n */
    n = ControlPort.params[0];
    fermer();
    printf("Ressources : %u\n", n);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ressources : 3
Mad Pascal
// Compter les ressources (groupe 38, fonction 3, Trinity).
program rs3;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

var n: byte;
begin
  ouvrir(@demo);
  res(3);                                       // Count Resources : numérotées de 1 à n
  n := NeoMessage.params[0];
  fermer;
  writeln('Ressources : ', n);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ressources : 3
NeoBASIC
10 ' Compter les ressources (groupe 38, fonction 3, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "demo.res" : gosub 8900 : gosub 8000
30 while peek($ff00) : wend : f = 3 : gosub 8110 : n = peek($ff04) : ' Count Resources : numerotees de 1 a n
40 gosub 8200
50 print "Ressources : ";n
60 end
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ressources : 3
Assembleur 65C02 (64tass)
; Compter les ressources (groupe 38, fonction 3, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        jsr WaitMessage
        ldx #3                  ; Count Resources : numérotées de 1 à n
        jsr res
        lda ControlPort+4
        sta n
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda n
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
n:      .byte 0
t0:     .text "Ressources : ", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Ressources : 3

38,4 Find Resource Trinity

Cherche une ressource par son type et son identifiant.

Entrées
OctetsTypeRôle
P0-P3uint8type : 4 caractères ASCII, complétés par des espaces
P4-P5uint16identifiant
Sorties
OctetsTypeRôle
P6uint8numéro de la ressource (0 si absente)
erreuruint83 si la ressource est absente

NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Looks for the resource of type Parameters:0-3 (4 ASCII characters, padded with spaces) and id Parameters:4,5 ; returns its number in Parameter:6 (0 and error 3 if not found).

C (llvm-mos)
/* Chercher une ressource par type et numéro (groupe 38, fonction 4, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

static uint8_t chercher(const char *type, uint16_t id) {   /* Find Resource : type de 4 caractères, id */
    uint8_t i;
    libre();
    for (i = 0; i < 4; i++)
        ControlPort.params[i] = type[i];
    p16(4, id);
    res(4);
    return ControlPort.params[6];               /* numéro de la ressource, 0 si absente */
}

int main(void) {
    uint8_t f, t, n, e;
    ouvrir(demo);
    f = chercher("FONT", 1);
    t = chercher("TEXT", 2);
    n = chercher("TEXT", 9);
    e = ControlPort.error;
    fermer();
    printf("FONT 1 : %u, TEXT 2 : %u, TEXT 9 : %u (erreur %u)\n", f, t, n, e);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
FONT 1 : 2, TEXT 2 : 3, TEXT 9 : 0 (erreur 3)
Mad Pascal
// Chercher une ressource par type et numéro (groupe 38, fonction 4, Trinity).
program rs4;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

function chercher(a, b, c, d: char; id: word): byte;   // Find Resource : type de 4 caractères, id
begin
  NeoWaitMessage;
  NeoMessage.params[0] := ord(a); NeoMessage.params[1] := ord(b);
  NeoMessage.params[2] := ord(c); NeoMessage.params[3] := ord(d);
  NeoMessage.params[4] := lo(id); NeoMessage.params[5] := hi(id);
  res(4);
  result := NeoMessage.params[6];               // numéro de la ressource, 0 si absente
end;

var f, t, n, e: byte;
begin
  ouvrir(@demo);
  f := chercher('F', 'O', 'N', 'T', 1);
  t := chercher('T', 'E', 'X', 'T', 2);
  n := chercher('T', 'E', 'X', 'T', 9);
  e := NeoMessage.error;
  fermer;
  writeln('FONT 1 : ', f, ', TEXT 2 : ', t, ', TEXT 9 : ', n, ' (erreur ', e, ')');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
FONT 1 : 2, TEXT 2 : 3, TEXT 9 : 0 (erreur 3)
NeoBASIC
10 ' Chercher une ressource par type et numero (groupe 38, fonction 4, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "demo.res" : gosub 8900 : gosub 8000
30 t$ = "FONT" : id = 1 : gosub 2000 : fo = r
40 t$ = "TEXT" : id = 2 : gosub 2000 : tx = r
50 id = 9 : gosub 2000 : n = r : e9 = e
60 gosub 8200
70 print "FONT 1 : ";fo;", TEXT 2 : ";tx;", TEXT 9 : ";n;" (erreur ";e9;")"
80 end
2000 ' Find Resource : type t$ (4 caracteres), id ; numero dans r, 0 si absente
2010 while peek($ff00) : wend : for i = 1 to 4 : poke $ff03 + i, asc(mid$(t$, i, 1)) : next i : doke $ff08, id
2020 f = 4 : gosub 8110 : r = peek($ff0a) : return
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
FONT 1 : 2, TEXT 2 : 3, TEXT 9 : 0 (erreur 3)
Assembleur 65C02 (64tass)
; Chercher une ressource par type et numéro (groupe 38, fonction 4, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        lda #<b0
        ldx #>b0
        jsr envoi
        lda ControlPort+10         ; P6 : numéro, 0 si absente
        sta fo
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+10         ; P6 : numéro, 0 si absente
        sta tx
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+10         ; P6 : numéro, 0 si absente
        sta n
        lda ControlPort+2
        sta e
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda fo
        jsr decimal
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda tx
        jsr decimal
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda n
        jsr decimal
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda e
        jsr decimal
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
b0:     .byte 38, 4, 6             ; Find Resource : FONT 1
        .text "FONT"
        .word 1
fo:     .byte 0
b1:     .byte 38, 4, 6             ; Find Resource : TEXT 2
        .text "TEXT"
        .word 2
tx:     .byte 0
b2:     .byte 38, 4, 6             ; Find Resource : TEXT 9
        .text "TEXT"
        .word 9
n:      .byte 0
e:      .byte 0
t3:     .text "FONT 1 : ", 0
t4:     .text ", TEXT 2 : ", 0
t5:     .text ", TEXT 9 : ", 0
t6:     .text " (erreur ", 0
t7:     .text ")", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
FONT 1 : 2, TEXT 2 : 3, TEXT 9 : 0 (erreur 3)

38,5 Get Resource Info Trinity

Rend le type et l'identifiant d'une ressource.

Entrées
OctetsTypeRôle
P0uint8numéro de la ressource (1 à n, dans l'ordre de la table)
Sorties
OctetsTypeRôle
P1-P4uint8type (4 caractères)
P5-P6uint16identifiant
erreuruint83 si le numéro est hors de la table

Avec 38,3, permet de parcourir toute la table. NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Returns the type of resource Parameter:0 in Parameters:1-4 and its id in Parameters:5,6 (error 3 if the number is out of range).

C (llvm-mos)
/* Lire le type et l'identifiant d'une ressource (groupe 38, fonction 5, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

int main(void) {
    uint8_t i, j, e, t[3][4];
    uint16_t id[3];
    ouvrir(demo);
    for (i = 0; i < 3; i++) {
        libre();
        ControlPort.params[0] = i + 1;
        res(5);                                 /* Get Resource Info */
        for (j = 0; j < 4; j++)
            t[i][j] = ControlPort.params[1 + j];    /* type en P1-P4 */
        id[i] = ControlPort.params[5] | ControlPort.params[6] << 8;   /* id en P5-P6 */
    }
    libre(); ControlPort.params[0] = 4; e = res(5); /* hors de la table */
    fermer();
    for (i = 0; i < 3; i++)
        printf("%u : %c%c%c%c %u\n", i + 1, t[i][0], t[i][1], t[i][2], t[i][3], id[i]);
    printf("4 : erreur %u\n", e);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
1 : TEXT 1
2 : FONT 1
3 : TEXT 2
4 : erreur 3
Mad Pascal
// Lire le type et l'identifiant d'une ressource (groupe 38, fonction 5, Trinity).
program rs5;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

var i, j, e: byte;
    t: array[0..11] of byte;
    id: array[0..2] of word;
begin
  ouvrir(@demo);
  for i := 0 to 2 do begin
    NeoWaitMessage;
    NeoMessage.params[0] := i + 1;
    res(5);                                     // Get Resource Info
    for j := 0 to 3 do t[i * 4 + j] := NeoMessage.params[1 + j];   // type en P1-P4
    id[i] := NeoMessage.params[5] + NeoMessage.params[6] shl 8;    // id en P5-P6
  end;
  NeoMessage.params[0] := 4; e := res(5);       // hors de la table
  fermer;
  for i := 0 to 2 do
    writeln(i + 1, ' : ', chr(t[i * 4]), chr(t[i * 4 + 1]), chr(t[i * 4 + 2]), chr(t[i * 4 + 3]), ' ', id[i]);
  writeln('4 : erreur ', e);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
1 : TEXT 1
2 : FONT 1
3 : TEXT 2
4 : erreur 3
NeoBASIC
10 ' Lire le type et l'identifiant d'une ressource (groupe 38, fonction 5, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "demo.res" : gosub 8900 : gosub 8000
30 dim t$(2), id(2)
40 for k = 0 to 2
50 while peek($ff00) : wend : poke $ff04, k + 1 : f = 5 : gosub 8110 : ' Get Resource Info
60 t$(k) = "" : for i = 0 to 3 : t$(k) = t$(k) + chr$(peek($ff05 + i)) : next i : ' type en P1-P4
70 id(k) = deek($ff09) : next k : ' id en P5-P6
80 while peek($ff00) : wend : poke $ff04, 4 : f = 5 : gosub 8110 : e4 = e : ' hors de la table
90 gosub 8200
100 for k = 0 to 2 : print k + 1;" : ";t$(k);" ";id(k) : next k
110 print "4 : erreur ";e4
120 end
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
1 : TEXT 1
2 : FONT 1
3 : TEXT 2
4 : erreur 3
Assembleur 65C02 (64tass)
; Lire le type et l'identifiant d'une ressource (groupe 38, fonction 5, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        ldx #0                     ; ressource 1, 2, 3
        ldy #0                     ; place dans info
_r:     phx
        phy
        jsr WaitMessage
        plx
        pla
        pha
        phx
        inc a
        sta ControlPort+4
        ldx #5                     ; Get Resource Info : type en P1-P4, id en P5-P6
        jsr res
        ply
        ldx #0
_c:     lda ControlPort+5,x
        sta info,y
        iny
        inx
        cpx #6
        bne _c
        plx
        inx
        cpx #3
        bne _r
        jsr WaitMessage
        lda #4                     ; hors de la table
        sta ControlPort+4
        ldx #5                  ; 38,5
        jsr res
        sta e
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t0
        ldx #>t0
        jsr ecrire
        ldx #0
_t0:    lda info,x
        jsr WriteCharacter
        inx
        cpx #4
        bne _t0
        lda #' '
        jsr WriteCharacter
        lda info+4
        ldx info+4+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t1
        ldx #>t1
        jsr ecrire
        ldx #6
_t1:    lda info,x
        jsr WriteCharacter
        inx
        cpx #10
        bne _t1
        lda #' '
        jsr WriteCharacter
        lda info+10
        ldx info+10+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t2
        ldx #>t2
        jsr ecrire
        ldx #12
_t2:    lda info,x
        jsr WriteCharacter
        inx
        cpx #16
        bne _t2
        lda #' '
        jsr WriteCharacter
        lda info+16
        ldx info+16+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda e
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
info:   .fill 18                   ; 3 × (type sur 4 octets, id sur 2)
e:      .byte 0
t0:     .text "1 : ", 0
t1:     .text "2 : ", 0
t2:     .text "3 : ", 0
t3:     .text "4 : erreur ", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
1 : TEXT 1
2 : FONT 1
3 : TEXT 2
4 : erreur 3

38,6 Get Resource Size Trinity

Rend la taille d'une ressource en octets.

Entrées
OctetsTypeRôle
P0uint8numéro de la ressource (1 à n, dans l'ordre de la table)
Sorties
OctetsTypeRôle
P1-P4uint32taille en octets

NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Returns the size in bytes of resource Parameter:0 in Parameters:1-4 (32 bits).

C (llvm-mos)
/* Lire la taille d'une ressource (groupe 38, fonction 6, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

int main(void) {
    uint8_t i;
    uint16_t t[3];
    ouvrir(demo);
    for (i = 0; i < 3; i++) {
        libre();
        ControlPort.params[0] = i + 1;
        res(6);                                 /* Get Resource Size : 32 bits en P1-P4 */
        t[i] = ControlPort.params[1] | ControlPort.params[2] << 8;
    }
    fermer();
    printf("Tailles : %u, %u, %u octets\n", t[0], t[1], t[2]);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Tailles : 7, 17, 9 octets
Mad Pascal
// Lire la taille d'une ressource (groupe 38, fonction 6, Trinity).
program rs6;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

var i: byte;
    t: array[0..2] of word;
begin
  ouvrir(@demo);
  for i := 0 to 2 do begin
    NeoWaitMessage;
    NeoMessage.params[0] := i + 1;
    res(6);                                     // Get Resource Size : 32 bits en P1-P4
    t[i] := NeoMessage.params[1] + NeoMessage.params[2] shl 8;
  end;
  fermer;
  writeln('Tailles : ', t[0], ', ', t[1], ', ', t[2], ' octets');
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Tailles : 7, 17, 9 octets
NeoBASIC
10 ' Lire la taille d'une ressource (groupe 38, fonction 6, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 s$ = "demo.res" : gosub 8900 : gosub 8000
30 dim t(2)
40 for k = 0 to 2
50 while peek($ff00) : wend : poke $ff04, k + 1 : f = 6 : gosub 8110 : ' Get Resource Size : 32 bits en P1-P4
60 t(k) = deek($ff05) : next k
70 gosub 8200
80 print "Tailles : ";t(0);", ";t(1);", ";t(2);" octets"
90 end
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Tailles : 7, 17, 9 octets
Assembleur 65C02 (64tass)
; Lire la taille d'une ressource (groupe 38, fonction 6, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        ldx #0
_r:     phx
        jsr WaitMessage
        pla
        pha
        lsr a
        inc a
        sta ControlPort+4          ; ressource 1, 2, 3
        ldx #6                     ; Get Resource Size : 32 bits en P1-P4
        jsr res
        plx
        lda ControlPort+5
        sta t,x
        lda ControlPort+6
        sta t+1,x
        inx
        inx
        cpx #6
        bne _r
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t0
        ldx #>t0
        jsr ecrire
        lda t
        ldx t+1
        jsr dec16
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda t+2
        ldx t+2+1
        jsr dec16
        lda #<t2
        ldx #>t2
        jsr ecrire
        lda t+4
        ldx t+4+1
        jsr dec16
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
t:      .fill 6                    ; 3 tailles sur 16 bits
t0:     .text "Tailles : ", 0
t1:     .text ", ", 0
t2:     .text ", ", 0
t3:     .text " octets", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Tailles : 7, 17, 9 octets

38,7 Load Resource Trinity

Copie une ressource dans une page de mémoire (pages de 12,2).

Entrées
OctetsTypeRôle
P0uint8numéro de la ressource (1 à n, dans l'ordre de la table)
P1uint8page : $00 RAM du 6502, $80 et $81 mémoire vidéo, $90 mémoire graphique
P2-P3addradresse dans la page
P4-P5uint16nombre d'octets au plus
Sorties
OctetsTypeRôle
P6-P7uint16nombre d'octets lus (toute la ressource si elle tient)
erreuruint81 si la zone sort de la page

Avec un maximum de 4 octets, seul le début de la ressource est lu : « Bonj ». NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Reads resource Parameter:0 into memory page Parameter:1 ($00 6502 RAM, $80/$81 video RAM, $90 graphics RAM ; pages of Function 12,2) at address Parameters:2,3, at most Parameters:4,5 bytes ; Parameters:6,7 receive the number of bytes read (the whole resource when it fits). Error 1 if the range leaves the page.

C (llvm-mos)
/* Charger une ressource en mémoire (groupe 38, fonction 7, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

static char tampon[16];

static uint16_t charger(uint8_t r, uint16_t max) {   /* Load Resource : page $00 (RAM du 6502), adresse, max */
    libre();
    ControlPort.params[0] = r;
    ControlPort.params[1] = 0;
    p16(2, (uint16_t)tampon);
    p16(4, max);
    res(7);
    return ControlPort.params[6] | ControlPort.params[7] << 8;   /* octets lus */
}

int main(void) {
    uint16_t n1, n2;
    uint8_t i;
    ouvrir(demo);
    n1 = charger(3, sizeof tampon);             /* TEXT 2 en entier */
    printf("TEXT 2 : %u octets, ", n1);
    for (i = 0; i < n1; i++)
        putchar(tampon[i]);
    n2 = charger(1, 4);                         /* TEXT 1, 4 octets au plus */
    fermer();
    printf("\nTEXT 1, 4 au plus : %u octets, ", n2);
    for (i = 0; i < n2; i++)
        putchar(tampon[i]);
    putchar('\n');
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
TEXT 2 : 9 octets, Neo6502 !
TEXT 1, 4 au plus : 4 octets, Bonj
Mad Pascal
// Charger une ressource en mémoire (groupe 38, fonction 7, Trinity).
program rs7;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

var tampon: array[0..15] of byte;

function charger(r: byte; max: word): word;     // Load Resource : page $00 (RAM du 6502), adresse, max
begin
  NeoWaitMessage;
  NeoMessage.params[0] := r;
  NeoMessage.params[1] := 0;
  NeoMessage.params[2] := lo(word(@tampon));
  NeoMessage.params[3] := hi(word(@tampon));
  NeoMessage.params[4] := lo(max);
  NeoMessage.params[5] := hi(max);
  res(7);
  result := NeoMessage.params[6] + NeoMessage.params[7] shl 8;   // octets lus
end;

var n1, n2, i: word;
begin
  ouvrir(@demo);
  n1 := charger(3, 16);                         // TEXT 2 en entier
  write('TEXT 2 : ', n1, ' octets, ');
  for i := 0 to n1 - 1 do write(chr(tampon[i]));
  writeln;
  n2 := charger(1, 4);                          // TEXT 1, 4 octets au plus
  fermer;
  write('TEXT 1, 4 au plus : ', n2, ' octets, ');
  for i := 0 to n2 - 1 do write(chr(tampon[i]));
  writeln;
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
TEXT 2 : 9 octets, Neo6502 !
TEXT 1, 4 au plus : 4 octets, Bonj
NeoBASIC
10 ' Charger une ressource en memoire (groupe 38, fonction 7, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 tp = alloc(16)
30 s$ = "demo.res" : gosub 8900 : gosub 8000
40 r = 3 : mx = 16 : gosub 2000 : n1 = lu : ' TEXT 2 en entier
50 print "TEXT 2 : ";n1;" octets, "; : gosub 3000
60 r = 1 : mx = 4 : gosub 2000 : n2 = lu : ' TEXT 1, 4 octets au plus
70 gosub 8200
80 print "TEXT 1, 4 au plus : ";n2;" octets, "; : gosub 3000
90 end
2000 ' Load Resource : ressource r, page $00 (RAM du 6502), adresse tp, mx octets au plus ; octets lus dans lu
2010 while peek($ff00) : wend : poke $ff04, r : poke $ff05, 0 : doke $ff06, tp : doke $ff08, mx
2020 f = 7 : gosub 8110 : lu = deek($ff0a) : return
3000 for i = 0 to lu - 1 : print chr$(peek(tp + i)); : next i : print : return
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
TEXT 2 : 9 octets, Neo6502 !
TEXT 1, 4 au plus : 4 octets, Bonj
Assembleur 65C02 (64tass)
; Charger une ressource en mémoire (groupe 38, fonction 7, Trinity).
        .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 #<demo
        ldx #>demo
        jsr ouvrir
        lda #<b0
        ldx #>b0
        jsr envoi
        lda ControlPort+10         ; P6-P7 : octets lus
        sta n1
        lda ControlPort+11
        sta n1+1
        lda #<t1
        ldx #>t1
        jsr ecrire
        lda n1
        ldx n1+1
        jsr dec16
        lda #<t2
        ldx #>t2
        jsr ecrire
        ldx #0
_m1:    cpx n1
        beq _f1
        lda tampon,x
        jsr WriteCharacter
        inx
        bra _m1
_f1:    lda #13
        jsr WriteCharacter
        lda #<b3
        ldx #>b3
        jsr envoi
        lda ControlPort+10         ; P6-P7 : octets lus
        sta n2
        lda ControlPort+11
        sta n2+1
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda n2
        ldx n2+1
        jsr dec16
        lda #<t5
        ldx #>t5
        jsr ecrire
        ldx #0
_m2:    cpx n2
        beq _f2
        lda tampon,x
        jsr WriteCharacter
        inx
        bra _m2
_f2:    lda #13
        jsr WriteCharacter
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
tampon: .fill 16
b0:     .byte 38, 7, 6, 3, 0       ; Load Resource : TEXT 2 en entier, page $00 (RAM du 6502)
        .word tampon, 16
n1:     .fill 2
t1:     .text "TEXT 2 : ", 0
t2:     .text " octets, ", 0
b3:     .byte 38, 7, 6, 1, 0       ; TEXT 1, 4 octets au plus
        .word tampon, 4
n2:     .fill 2
t4:     .text "TEXT 1, 4 au plus : ", 0
t5:     .text " octets, ", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
TEXT 2 : 9 octets, Neo6502 !
TEXT 1, 4 au plus : 4 octets, Bonj

38,8 Use Font Trinity

Charge une ressource (comme 38,7) puis en fait la police de QuickDraw (32,15).

Entrées
OctetsTypeRôle
P0uint8numéro de la ressource (1 à n, dans l'ordre de la table)
P1uint8page : $00 RAM du 6502, $80 et $81 mémoire vidéo, $90 mémoire graphique
P2-P3addradresse dans la page
P4-P5uint16nombre d'octets au plus
Sorties
OctetsTypeRôle
erreuruint81 si la ressource n'est pas une police NF1 valide

La police est lue sur place à chaque dessin (voir 32,15) : la zone où elle est chargée doit rester intacte. L'exemple charge la police d'un caractère de demo.res et écrit « A » avec 32,16 : un cadre 8 × 8, coin allumé, milieu éteint. NeoBASIC n'a pas de mot-clé pour cet appel.

Texte de la documentation du firmware (anglais)

Load Resource (same parameters) followed by Function 32,15 Set Font on the loaded NF1 font : the resource becomes the QuickDraw font (error 1 if it is not a valid font).

C (llvm-mos)
/* Charger une police depuis les ressources (groupe 38, fonction 8, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>

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

/* demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
   caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ». */
static const char demo[] = "\010demo.res";       /* nom précédé de sa longueur */

static void p16(uint8_t i, uint16_t v) {        /* paramètre 16 bits en Pi, Pi+1 */
    ControlPort.params[i] = v & 0xFF;
    ControlPort.params[i + 1] = v >> 8;
}
static uint8_t res(uint8_t f) {                 /* appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur */
    api(38, f);
    return ControlPort.error;
}
static uint8_t ouvrir(const char *nom) {        /* 38,1 Open Resource File, sur le canal de fichier 1 */
    libre();
    ControlPort.params[0] = 1;
    p16(1, (uint16_t)nom);
    return res(1);
}
static void fermer(void) {                      /* 38,2 Close Resource File */
    libre();
    res(2);
}

static uint8_t police[32];                       /* la police est lue sur place : elle doit rester en mémoire */
static const char texte[] = "\001A";

static uint8_t pixel(int16_t x, int16_t y) {    /* 5,33 : couleur du fond en (x, y) */
    libre(); p16(0, x); p16(2, y); api(5, 33);
    return ControlPort.params[0];
}
static uint8_t utiliser(uint8_t r) {            /* Use Font : Load Resource puis 32,15 Set Font */
    libre();
    ControlPort.params[0] = r;
    ControlPort.params[1] = 0;
    p16(2, (uint16_t)police);
    p16(4, sizeof police);
    return res(8);
}

int main(void) {
    uint8_t e1, e2, coin, milieu;
    putchar(12);                                /* écran effacé : on relit des pixels */
    libre(); api(32, 1);                        /* 32,1 Init Graf */
    ouvrir(demo);
    e1 = utiliser(2);                           /* FONT 1 */
    libre(); ControlPort.params[0] = 6; api(32, 4);
    libre(); p16(0, 100); p16(2, 100); api(32, 5);
    libre(); p16(0, (uint16_t)texte); api(32, 16);   /* 32,16 : « A », un cadre 8 × 8 */
    coin = pixel(100, 100);
    milieu = pixel(104, 104);
    e2 = utiliser(1);                           /* TEXT 1 : pas une police */
    fermer();
    libre(); api(32, 1);                        /* police intégrée */
    printf("Police : erreur %u, coin %u, milieu %u\nTEXT 1 : erreur %u\n", e1, coin, milieu, e2);
    return 0;
}
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police : erreur 0, coin 6, milieu 0
TEXT 1 : erreur 1
Mad Pascal
// Charger une police depuis les ressources (groupe 38, fonction 8, Trinity).
program rs8;
uses crt, neo6502;
// demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
// caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
const demo: array[0..8] of byte = (8, ord('d'), ord('e'), ord('m'), ord('o'), ord('.'), ord('r'), ord('e'), ord('s'));

function res(f: byte): byte;                    // appel 38,f (paramètres déjà posés) ; rend l'indicateur d'erreur
begin
  NeoSendMessage(38, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function ouvrir(nom: pointer): byte;            // 38,1 Open Resource File, sur le canal de fichier 1
begin
  NeoWaitMessage;
  NeoMessage.params[0] := 1;
  NeoMessage.params[1] := lo(word(nom));
  NeoMessage.params[2] := hi(word(nom));
  result := res(1);
end;

procedure fermer;                               // 38,2 Close Resource File
begin
  NeoWaitMessage;
  res(2);
end;

const texte: array[0..1] of byte = (1, ord('A'));
var police: array[0..31] of byte;               // la police est lue sur place : elle doit rester en mémoire
    e1, e2, coin, milieu: byte;

function utiliser(r: byte): byte;               // Use Font : Load Resource puis 32,15 Set Font
begin
  NeoWaitMessage;
  NeoMessage.params[0] := r;
  NeoMessage.params[1] := 0;
  NeoMessage.params[2] := lo(word(@police));
  NeoMessage.params[3] := hi(word(@police));
  NeoMessage.params[4] := 32;
  NeoMessage.params[5] := 0;
  result := res(8);
end;

begin
  write(chr(12));                               // écran effacé : on relit des pixels
  NeoWaitMessage; NeoSendMessage(32, 1); NeoWaitMessage;   // 32,1 Init Graf
  ouvrir(@demo);
  e1 := utiliser(2);                            // FONT 1
  NeoMessage.params[0] := 6; NeoSendMessage(32, 4); NeoWaitMessage;
  wordParams[0] := 100; wordParams[1] := 100; NeoSendMessage(32, 5); NeoWaitMessage;
  wordParams[0] := word(@texte); NeoSendMessage(32, 16); NeoWaitMessage;   // 32,16 : « A », un cadre 8 × 8
  coin := NeoGetPixel(100, 100);
  milieu := NeoGetPixel(104, 104);
  e2 := utiliser(1);                            // TEXT 1 : pas une police
  fermer;
  NeoSendMessage(32, 1); NeoWaitMessage;        // police intégrée
  writeln('Police : erreur ', e1, ', coin ', coin, ', milieu ', milieu);
  writeln('TEXT 1 : erreur ', e2);
end.
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police : erreur 0, coin 6, milieu 0
TEXT 1 : erreur 1
NeoBASIC
10 ' Charger une police depuis les ressources (groupe 38, fonction 8, Trinity)
15 ' demo.res (fabrique avec tools/toolbox/mkres.py de Trinity) : TEXT 1, FONT 1, TEXT 2
20 cls : ' ecran efface : on relit des pixels
30 po = alloc(32) : ' la police est lue sur place : elle doit rester en memoire
40 tx = alloc(2) : poke tx, 1 : poke tx + 1, asc("A")
50 while peek($ff00) : wend : poke $ff01, 1 : poke $ff00, 32 : ' 32,1 Init Graf
60 s$ = "demo.res" : gosub 8900 : gosub 8000
70 r = 2 : gosub 2000 : e1 = e : ' FONT 1
80 while peek($ff00) : wend : poke $ff04, 6 : poke $ff01, 4 : poke $ff00, 32
90 while peek($ff00) : wend : doke $ff04, 100 : doke $ff06, 100 : poke $ff01, 5 : poke $ff00, 32
100 while peek($ff00) : wend : doke $ff04, tx : poke $ff01, 16 : poke $ff00, 32 : ' 32,16 : « A », un cadre 8 x 8
110 while peek($ff00) : wend : co = point(100, 100) : mi = point(104, 104)
120 r = 1 : gosub 2000 : e2 = e : ' TEXT 1 : pas une police
130 gosub 8200
140 while peek($ff00) : wend : poke $ff01, 1 : poke $ff00, 32 : ' police integree
150 while peek($ff00) : wend
160 print "Police : erreur ";e1;", coin ";co;", milieu ";mi
170 print "TEXT 1 : erreur ";e2
180 end
2000 ' Use Font : Load Resource de r dans po (32 octets au plus) puis 32,15 Set Font
2010 while peek($ff00) : wend : poke $ff04, r : poke $ff05, 0 : doke $ff06, po : doke $ff08, 32 : f = 8 : goto 8110
8000 ' 38,1 Open Resource File sur le canal 1 : nom precede de sa longueur en nm ; erreur dans e
8010 while peek($ff00) : wend : poke $ff04, 1 : doke $ff05, nm : f = 1
8100 ' appel 38,f, parametres deja poses ; erreur dans e
8110 poke $ff01, f : poke $ff00, 38
8120 while peek($ff00) : wend : e = peek($ff02) : return
8200 ' 38,2 Close Resource File
8210 while peek($ff00) : wend : f = 2 : goto 8110
8900 ' chaine s$ precedee de sa longueur, dans un bloc neuf nm
8910 nm = alloc(len(s$) + 1) : poke nm, len(s$) : for i = 1 to len(s$) : poke nm + i, asc(mid$(s$, i, 1)) : next i : return
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police : erreur 0, coin 6, milieu 0
TEXT 1 : erreur 1
Assembleur 65C02 (64tass)
; Charger une police depuis les ressources (groupe 38, fonction 8, Trinity).
        .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 #12                    ; écran effacé : on relit des pixels
        jsr WriteCharacter
        lda #<b0
        ldx #>b0
        jsr envoi
        lda #<demo
        ldx #>demo
        jsr ouvrir
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+2
        sta e1
        lda #<b2
        ldx #>b2
        jsr envoi
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<b4
        ldx #>b4
        jsr envoi
        lda #100
        ldy #100
        jsr pixel
        sta co
        lda #104
        ldy #104
        jsr pixel
        sta mi
        lda #<b5
        ldx #>b5
        jsr envoi
        lda ControlPort+2
        sta e2
        jsr WaitMessage
        ldx #2                  ; 38,2 Close Resource File
        jsr res
        lda #<b6
        ldx #>b6
        jsr envoi
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda e1
        jsr decimal
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda co
        jsr decimal
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda mi
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t10
        ldx #>t10
        jsr ecrire
        lda e2
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

; Couleur du fond (5,33) en (A, Y), X et Y inférieurs à 256, rendue dans A.
pixel:  pha
        jsr WaitMessage
        pla
        sta ControlPort+4          ; P0-P1 : X
        stz ControlPort+5
        sty ControlPort+6          ; P2-P3 : Y
        stz ControlPort+7
        lda #5
        ldx #33                    ; 5,33 : Read Pixel
        jsr appel
        lda ControlPort+4
        rts

; demo.res (fabriqué avec tools/toolbox/mkres.py de Trinity) : TEXT 1 « Bonjour », FONT 1 (police NF1 d'un
; caractère, un cadre 8 × 8), TEXT 2 « Neo6502 ! ».
demo:   .byte 8
        .text "demo.res"           ; nom précédé de sa longueur
police: .fill 32                   ; la police est lue sur place : elle doit rester en mémoire
texte:  .byte 1
        .text "A"
b0:     .byte 32, 1, 0             ; 32,1 Init Graf
b1:     .byte 38, 8, 6, 2, 0       ; Use Font : FONT 1, puis 32,15 Set Font
        .word police, 32
e1:     .byte 0
b2:     .byte 32, 4, 1, 6          ; 32,4 : couleur 6
b3:     .byte 32, 5, 4             ; 32,5
        .word 100, 100
b4:     .byte 32, 16, 2            ; 32,16 : « A », un cadre 8 × 8
        .word texte
co:     .byte 0
mi:     .byte 0
b5:     .byte 38, 8, 6, 1, 0       ; TEXT 1 : pas une police
        .word police, 32
e2:     .byte 0
b6:     .byte 32, 1, 0             ; police intégrée
t7:     .text "Police : erreur ", 0
t8:     .text ", coin ", 0
t9:     .text ", milieu ", 0
t10:    .text "TEXT 1 : erreur ", 0

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

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

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

; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16:  sta n16
        stx n16+1
        stz vu
        ldy #0                     ; puissance de 10 en cours : 10000, 1000, 100, 10
_p:     ldx #0                     ; chiffre
_s:     lda n16
        sec
        sbc p10l,y
        pha
        lda n16+1
        sbc p10h,y
        bcc _neg                   ; plus petit : chiffre trouvé
        sta n16+1
        pla
        sta n16
        inx
        bra _s
_neg:   pla
        txa
        ora vu
        beq _suiv                  ; pas de zéro de tête
        txa
        ora #'0'
        phy
        jsr WriteCharacter
        ply
        lda #1
        sta vu
_suiv:  iny
        cpy #4
        bne _p
        lda n16                    ; les unités, toujours
        ora #'0'
        jmp WriteCharacter
p10l:   .byte <10000, <1000, <100, <10
p10h:   .byte >10000, >1000, >100, >10
n16:    .word 0
vu:     .byte 0

; 38,1 Open Resource File, sur le canal de fichier 1 : nom en A (poids faible) et X (poids fort) ; erreur dans A.
ouvrir: pha
        phx
        jsr WaitMessage
        lda #1
        sta ControlPort+4
        plx
        stx ControlPort+6
        pla
        sta ControlPort+5
        ldx #1
; Appel 38,X (paramètres déjà posés) ; rend l'indicateur d'erreur dans A.
res:    lda #38
        jsr appel
        lda ControlPort+2
        rts

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

ptr      = $80
blk      = $82
diviseur: .byte 0
fin:     .byte 0
Sortie observée dans l'émulateur Phosphoneo, firmware Trinity 0.16.69 :
Police : erreur 0, coin 6, milieu 0
TEXT 1 : erreur 1

← L'API du Neo6502