Tachibana
Language: English

Group 34 — Window Manager Trinity

34,1 New Window · 34,2 Dispose Window · 34,3 Show Window · 34,4 Select Window · 34,5 Move Window · 34,6 Size Window · 34,7 Find Window · 34,8 Get Content Rect · 34,9 Set Window Title · 34,10 Front Window · 34,11 End Update · 34,12 Set Port

The window manager of the Trinity toolbox holds up to 8 windows, numbered 1 to 8. The firmware draws the frames; the program draws the contents with QuickDraw (group 32).

After each change (opening, closing, moving...), the firmware erases the visible contents, repaints the frames and posts one update event (group 33, type 9) per visible window. To answer it: 34,12 (Set Port), drawing with group 32, then 34,11 (End Update).

The examples reset the toolbox with 32,19 at the start and at the end: it keeps its state from one program to the next.

34,1 New Window Trinity

Creates a visible window, brings it to the front and returns its number.

Inputs
BytesTypeMeaning
P0-P1addraddress of the frame Rect (screen coordinates)
P2-P3addraddress of the title, preceded by its length (read in place)
P4uint8flags: bit 0 title bar, bit 1 close box, bit 2 grow box
Outputs
BytesTypeMeaning
P5uint8window number (1 to 8)
erreuruint81 bad parameters (inverted frame for instance), 2 no window left

The firmware draws the frame: one-pixel border, 10-line title bar, boxes; the program draws the content. Frame 20, 20, 120, 100 with a title bar gives the content 21, 31, 119, 99. The title is read in place at each drawing: the string must stay intact while the window exists. After each change, the firmware posts one update event (type 9) per visible window, back to front, then activate events (type 10); on the bench, the ninth window is refused with error 2. NeoBASIC has no keyword for this call.

Firmware documentation text

Toolbox (Trinity, T-12, ADR-01 of the fork). Creates a visible window whose frame is the Rect at Parameters:0,1 (screen coordinates, see group 32) with the length-prefixed title at Parameters:2,3 (up to 255 characters, read in place : the program keeps the string intact while the window exists ; T-21) and the flags of Parameter:4 (bit 0 title bar, bit 1 close box, bit 2 grow box) ; returns its number (1-8) in Parameter:5, or an error (1 bad parameters, 2 no window left). The new window comes to the front. The firmware draws the frames (1 pixel border, 10 line title bar, close box, grow box) ; the content is drawn by the program : after every change of the window set the firmware erases the visible contents, repaints the frames and posts one update event (group 33, type 9) per visible window, back to front, and activate events (type 10). To handle an update : Set Port (34,12), draw with group 32, then End Update (34,11).

C (llvm-mos)
/* Ouvrir une fenêtre (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect cadre = {20, 20, 120, 100}, envers = {120, 20, 20, 100}, c;
static const char titre[] = "\005Essai";

int main(void) {
    uint8_t w, e;
    reinit();
    w = nouvelle(&cadre, titre, 7);             /* barre de titre, fermeture, agrandissement */
    contenu(w, &c);
    nouvelle(&envers, titre, 7);                /* droite avant gauche : refusé */
    e = ControlPort.error;
    reinit();
    printf("Fenetre : %u, contenu : %d, %d, %d, %d\n", w, c.g, c.h, c.d, c.b);
    printf("Cadre a l'envers : erreur %u\n", e);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1
Mad Pascal
// Ouvrir une fenêtre (groupe 34, fonction 1, Trinity).
program wm1;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

const essai: array[0..5] of byte = (5, ord('E'), ord('s'), ord('s'), ord('a'), ord('i'));
var cadre, envers, c: Rect;
    w, e: byte;
begin
  poser(cadre, 20, 20, 120, 100);
  poser(envers, 120, 20, 20, 100);
  reinit;
  w := nouvelle(@cadre, @essai, 7);             // barre de titre, fermeture, agrandissement
  contenu(w, @c);
  nouvelle(@envers, @essai, 7);                 // droite avant gauche : refusé
  e := NeoMessage.error;
  reinit;
  writeln('Fenetre : ', w, ', contenu : ', c.g, ', ', c.h, ', ', c.d, ', ', c.b);
  writeln('Cadre a l''envers : erreur ', e);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1
NeoBASIC
10 ' Ouvrir une fenetre (groupe 34, fonction 1, Trinity)
20 c1 = alloc(8) : q = c1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 c2 = alloc(8) : q = c2 : g = 120 : h = 20 : d = 20 : b = 100 : gosub 8000 : ' droite avant gauche
40 t = alloc(6) : t$ = "Essai" : poke t, len(t$) : for i = 1 to len(t$) : poke t + i, asc(mid$(t$, i, 1)) : next i
50 k = alloc(8) : gosub 8500
60 q = c1 : o = 7 : gosub 8100 : w1 = w : ' barre de titre, fermeture, agrandissement
70 n = w1 : gosub 8400
80 q = c2 : gosub 8100 : e2 = e : ' refuse
90 gosub 8500
100 print "Fenetre : ";w1;", contenu : ";cg;", ";ch;", ";cd;", ";cb
110 print "Cadre a l'envers : erreur ";e2
120 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1
65C02 assembly (64tass)
; Ouvrir une fenêtre (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta w
        jsr WaitMessage
        lda w
        sta ControlPort+4
        lda #<c
        sta ControlPort+5          ; P1-P2 : adresse du Rect
        lda #>c
        sta ControlPort+6
        lda #34
        ldx #8                     ; 34,8 : Get Content Rect
        jsr appel
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+2
        sta e
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda w
        jsr decimal
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda c
        ldx c+1
        jsr dec16
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda c+2
        ldx c+2+1
        jsr dec16
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda c+4
        ldx c+4+1
        jsr dec16
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda c+6
        ldx c+6+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda e
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

cadre:  .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
envers: .word 120, 20, 20, 100        ; gauche, haut, droite, bas (droite et bas exclus)
c:      .fill 8
essai:  .byte 5
        .text "Essai"              ; chaîne précédée de sa longueur, lue sur place
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : barre de titre, fermeture, agrandissement
        .word cadre, essai
        .byte 7
w:      .byte 0
b2:     .byte 34, 1, 5             ; droite avant gauche : refusé
        .word envers, essai
        .byte 7
e:      .byte 0
b3:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t4:     .text "Fenetre : ", 0
t5:     .text ", contenu : ", 0
t6:     .text ", ", 0
t7:     .text ", ", 0
t8:     .text ", ", 0
t9:     .text "Cadre a l'envers : 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1

34,2 Dispose Window Trinity

Removes a window from the screen and frees its number.

Inputs
BytesTypeMeaning
P0uint8window number

Outputs: none.

The example opens windows 1 and 2, closes 1: 2 is in front, and the next window takes number 1 again. NeoBASIC has no keyword for this call.

Firmware documentation text

Removes window Parameter:0 from the screen and frees its number.

C (llvm-mos)
/* Fermer une fenêtre (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";

int main(void) {
    uint8_t a, b, d, c;
    reinit();
    a = nouvelle(&r1, titre, 1);
    b = nouvelle(&r2, titre, 1);
    fenetre(2, a);                              /* Dispose Window : son numéro est libéré */
    d = devant();
    c = nouvelle(&r1, titre, 1);
    reinit();
    printf("Fenetres %u et %u ; apres fermeture de %u : devant %u\n", a, b, a, d);
    printf("Nouvelle fenetre : %u\n", c);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1
Mad Pascal
// Fermer une fenêtre (groupe 34, fonction 2, Trinity).
program wm2;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var r1, r2: Rect;
    a, b, d, c: byte;
begin
  poser(r1, 20, 20, 120, 100);
  poser(r2, 60, 50, 200, 150);
  reinit;
  a := nouvelle(@r1, @titre, 1);
  b := nouvelle(@r2, @titre, 1);
  fenetre(2, a);                                // Dispose Window : son numéro est libéré
  d := devant;
  c := nouvelle(@r1, @titre, 1);
  reinit;
  writeln('Fenetres ', a, ' et ', b, ' ; apres fermeture de ', a, ' : devant ', d);
  writeln('Nouvelle fenetre : ', c);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1
NeoBASIC
10 ' Fermer une fenetre (groupe 34, fonction 2, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 r2 = alloc(8) : q = r2 : g = 60 : h = 50 : d = 200 : b = 150 : gosub 8000
40 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1
50 gosub 8500
60 q = r1 : gosub 8100 : a = w
70 q = r2 : gosub 8100 : bw = w
80 n = a : f = 2 : gosub 8200 : ' Dispose Window : son numero est libere
90 gosub 8600
100 q = r1 : gosub 8100 : c = w
110 gosub 8500
120 print "Fenetres ";a;" et ";bw;" ; apres fermeture de ";a;" : devant ";dv
130 print "Nouvelle fenetre : ";c
140 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1
65C02 assembly (64tass)
; Fermer une fenêtre (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta b
        lda a
        ldx #2                  ; Dispose Window : son numéro est libéré
        jsr fen
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d
        lda #<b3
        ldx #>b3
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta n
        lda #<b4
        ldx #>b4
        jsr envoi
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda a
        jsr decimal
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda b
        jsr decimal
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda a
        jsr decimal
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda d
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda n
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
r2:     .word 60, 50, 200, 150        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r2, titre
        .byte 1
b:      .byte 0
d:      .byte 0
b3:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
n:      .byte 0
b4:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t5:     .text "Fenetres ", 0
t6:     .text " et ", 0
t7:     .text " ; apres fermeture de ", 0
t8:     .text " : devant ", 0
t9:     .text "Nouvelle fenetre : ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1

34,3 Show Window Trinity

Hides or shows a window.

Inputs
BytesTypeMeaning
P0uint8window number
P1uint8non zero to show, 0 to hide

Outputs: none.

A hidden window is no longer in front and is no longer found by 34,7. On the bench, the window shown again takes back its place in front. Mind P1: it must be set at each call. NeoBASIC has no keyword for this call.

Firmware documentation text

Shows (Parameter:1 non zero) or hides window Parameter:0.

C (llvm-mos)
/* Cacher ou montrer une fenêtre (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) {  /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
    libre();
    p16(0, x);
    p16(2, y);
    api(34, 7);
    zone = ControlPort.params[5];               /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
    return ControlPort.params[4];
}

static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";

static void montrer(uint8_t w, uint8_t oui) {   /* Show Window : P1 non nul montre, 0 cache */
    libre();
    ControlPort.params[0] = w;
    ControlPort.params[1] = oui;
    api(34, 3);
}

int main(void) {
    uint8_t b, d1, t1, d2, t2;
    reinit();
    nouvelle(&r1, titre, 1);
    b = nouvelle(&r2, titre, 1);
    montrer(b, 0);
    d1 = devant();
    t1 = trouver(150, 120);                     /* point couvert par la seule fenêtre 2 */
    montrer(b, 1);
    d2 = devant();
    t2 = trouver(150, 120);
    reinit();
    printf("Cachee : devant %u, en (150, 120) : %u\n", d1, t1);
    printf("Montree : devant %u, en (150, 120) : %u\n", d2, t2);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2
Mad Pascal
// Cacher ou montrer une fenêtre (groupe 34, fonction 3, Trinity).
program wm3;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var zone: byte;

function trouver(x, y: smallint): byte;         // 34,7 Find Window : fenêtre sous le point, zone dans « zone »
begin
  NeoWaitMessage;
  wordParams[0] := word(x);
  wordParams[1] := word(y);
  NeoSendMessage(34, 7);
  NeoWaitMessage;
  zone := NeoMessage.params[5];                 // 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement
  result := NeoMessage.params[4];
end;

procedure montrer(w, oui: byte);                // Show Window : P1 non nul montre, 0 cache
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := oui;
  NeoSendMessage(34, 3);
  NeoWaitMessage;
end;

var r1, r2: Rect;
    b, d1, t1, d2, t2: byte;
begin
  poser(r1, 20, 20, 120, 100);
  poser(r2, 60, 50, 200, 150);
  reinit;
  nouvelle(@r1, @titre, 1);
  b := nouvelle(@r2, @titre, 1);
  montrer(b, 0);
  d1 := devant;
  t1 := trouver(150, 120);                      // point couvert par la seule fenêtre 2
  montrer(b, 1);
  d2 := devant;
  t2 := trouver(150, 120);
  reinit;
  writeln('Cachee : devant ', d1, ', en (150, 120) : ', t1);
  writeln('Montree : devant ', d2, ', en (150, 120) : ', t2);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2
NeoBASIC
10 ' Cacher ou montrer une fenetre (groupe 34, fonction 3, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 r2 = alloc(8) : q = r2 : g = 60 : h = 50 : d = 200 : b = 150 : gosub 8000
40 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1
50 gosub 8500
60 q = r1 : gosub 8100
70 q = r2 : gosub 8100 : bw = w
80 v = 0 : gosub 2000 : gosub 8600 : d1 = dv
90 x = 150 : y = 120 : gosub 8300 : t1 = fw : ' point couvert par la seule fenetre 2
100 v = 1 : gosub 2000 : gosub 8600 : d2 = dv
110 gosub 8300 : t2 = fw
120 gosub 8500
130 print "Cachee : devant ";d1;", en (150, 120) : ";t1
140 print "Montree : devant ";d2;", en (150, 120) : ";t2
150 end
2000 ' Show Window : v non nul montre, 0 cache
2010 while peek($ff00) : wend : poke $ff05, v : n = bw : f = 3 : goto 8210
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2
65C02 assembly (64tass)
; Cacher ou montrer une fenêtre (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta b
        jsr WaitMessage
        lda #0
        sta ControlPort+5          ; P1 : 0 cache
        lda b
        ldx #3                     ; Show Window
        jsr fen
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d1
        lda #<b3
        ldx #>b3
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta t1
        lda ControlPort+9          ; P5 : zone
        sta z
        jsr WaitMessage
        lda #1
        sta ControlPort+5          ; P1 : non nul montre
        lda b
        ldx #3                     ; Show Window
        jsr fen
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d2
        lda #<b4
        ldx #>b4
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta t2
        lda ControlPort+9          ; P5 : zone
        sta z
        lda #<b5
        ldx #>b5
        jsr envoi
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda d1
        jsr decimal
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda t1
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda d2
        jsr decimal
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda t2
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
r2:     .word 60, 50, 200, 150        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
t1:     .byte 0
t2:     .byte 0
z:      .byte 0
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
b2:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r2, titre
        .byte 1
b:      .byte 0
d1:     .byte 0
b3:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 150, 120
d2:     .byte 0
b4:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 150, 120
b5:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t6:     .text "Cachee : devant ", 0
t7:     .text ", en (150, 120) : ", 0
t8:     .text "Montree : devant ", 0
t9:     .text ", en (150, 120) : ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2

34,4 Select Window Trinity

Brings a window to the front (and shows it).

Inputs
BytesTypeMeaning
P0uint8window number

Outputs: none.

At point (80, 70), covered by both windows, 34,7 finds the front window: 2, then 1 once selected. NeoBASIC has no keyword for this call.

Firmware documentation text

Brings window Parameter:0 to the front (and shows it).

C (llvm-mos)
/* Mettre une fenêtre devant (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) {  /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
    libre();
    p16(0, x);
    p16(2, y);
    api(34, 7);
    zone = ControlPort.params[5];               /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
    return ControlPort.params[4];
}

static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";

int main(void) {
    uint8_t a, d1, t1, d2, t2;
    reinit();
    a = nouvelle(&r1, titre, 1);
    nouvelle(&r2, titre, 1);
    d1 = devant();
    t1 = trouver(80, 70);                       /* point couvert par les deux fenêtres */
    fenetre(4, a);                              /* Select Window */
    d2 = devant();
    t2 = trouver(80, 70);
    reinit();
    printf("Avant : devant %u, en (80, 70) : %u\n", d1, t1);
    printf("Apres : devant %u, en (80, 70) : %u\n", d2, t2);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1
Mad Pascal
// Mettre une fenêtre devant (groupe 34, fonction 4, Trinity).
program wm4;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var zone: byte;

function trouver(x, y: smallint): byte;         // 34,7 Find Window : fenêtre sous le point, zone dans « zone »
begin
  NeoWaitMessage;
  wordParams[0] := word(x);
  wordParams[1] := word(y);
  NeoSendMessage(34, 7);
  NeoWaitMessage;
  zone := NeoMessage.params[5];                 // 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement
  result := NeoMessage.params[4];
end;

var r1, r2: Rect;
    a, d1, t1, d2, t2: byte;
begin
  poser(r1, 20, 20, 120, 100);
  poser(r2, 60, 50, 200, 150);
  reinit;
  a := nouvelle(@r1, @titre, 1);
  nouvelle(@r2, @titre, 1);
  d1 := devant;
  t1 := trouver(80, 70);                        // point couvert par les deux fenêtres
  fenetre(4, a);                                // Select Window
  d2 := devant;
  t2 := trouver(80, 70);
  reinit;
  writeln('Avant : devant ', d1, ', en (80, 70) : ', t1);
  writeln('Apres : devant ', d2, ', en (80, 70) : ', t2);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1
NeoBASIC
10 ' Mettre une fenetre devant (groupe 34, fonction 4, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 r2 = alloc(8) : q = r2 : g = 60 : h = 50 : d = 200 : b = 150 : gosub 8000
40 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1
50 gosub 8500
60 q = r1 : gosub 8100 : a = w
70 q = r2 : gosub 8100
80 gosub 8600 : d1 = dv
90 x = 80 : y = 70 : gosub 8300 : t1 = fw : ' point couvert par les deux fenetres
100 n = a : f = 4 : gosub 8200 : ' Select Window
110 gosub 8600 : d2 = dv
120 gosub 8300 : t2 = fw
130 gosub 8500
140 print "Avant : devant ";d1;", en (80, 70) : ";t1
150 print "Apres : devant ";d2;", en (80, 70) : ";t2
160 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1
65C02 assembly (64tass)
; Mettre une fenêtre devant (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        lda #<b2
        ldx #>b2
        jsr envoi
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d1
        lda #<b3
        ldx #>b3
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta t1
        lda ControlPort+9          ; P5 : zone
        sta z
        lda a
        ldx #4                  ; Select Window
        jsr fen
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d2
        lda #<b4
        ldx #>b4
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta t2
        lda ControlPort+9          ; P5 : zone
        sta z
        lda #<b5
        ldx #>b5
        jsr envoi
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda d1
        jsr decimal
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda t1
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda d2
        jsr decimal
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda t2
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
r2:     .word 60, 50, 200, 150        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
t1:     .byte 0
t2:     .byte 0
z:      .byte 0
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r2, titre
        .byte 1
d1:     .byte 0
b3:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 80, 70
d2:     .byte 0
b4:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 80, 70
b5:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t6:     .text "Avant : devant ", 0
t7:     .text ", en (80, 70) : ", 0
t8:     .text "Apres : devant ", 0
t9:     .text ", en (80, 70) : ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1

34,5 Move Window Trinity

Moves the top left corner of a window frame.

Inputs
BytesTypeMeaning
P0uint8window number
P1-P2int16corner X
P3-P4int16corner Y

Outputs: none.

The size does not change: the 100 × 80 frame put at (150, 60) gives the content 151, 71, 249, 139. Dragging the window is up to the program, from mouse events: 34,7 tells when the title bar is hit. NeoBASIC has no keyword for this call.

Firmware documentation text

Moves the top left corner of the frame of window Parameter:0 to Parameters:1,2 (X) and Parameters:3,4 (Y). Dragging is done by the program from mouse events : Find Window says when the title bar is hit.

C (llvm-mos)
/* Déplacer une fenêtre (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) {  /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
    libre();
    p16(0, x);
    p16(2, y);
    api(34, 7);
    zone = ControlPort.params[5];               /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
    return ControlPort.params[4];
}

static Rect r1 = {20, 20, 120, 100}, c;
static const char titre[] = "\001A";

int main(void) {
    uint8_t a, t;
    reinit();
    a = nouvelle(&r1, titre, 1);
    libre();
    ControlPort.params[0] = a;
    p16(1, 150);                                /* Move Window : nouveau coin haut gauche du cadre */
    p16(3, 60);
    api(34, 5);
    contenu(a, &c);
    t = trouver(50, 60);                        /* l'ancienne place est libre */
    reinit();
    printf("Contenu : %d, %d, %d, %d ; ancienne place : %u\n", c.g, c.h, c.d, c.b, t);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 151, 71, 249, 139 ; ancienne place : 0
Mad Pascal
// Déplacer une fenêtre (groupe 34, fonction 5, Trinity).
program wm5;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var zone: byte;

function trouver(x, y: smallint): byte;         // 34,7 Find Window : fenêtre sous le point, zone dans « zone »
begin
  NeoWaitMessage;
  wordParams[0] := word(x);
  wordParams[1] := word(y);
  NeoSendMessage(34, 7);
  NeoWaitMessage;
  zone := NeoMessage.params[5];                 // 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement
  result := NeoMessage.params[4];
end;

var r1, c: Rect;
    a, t: byte;
begin
  poser(r1, 20, 20, 120, 100);
  reinit;
  a := nouvelle(@r1, @titre, 1);
  NeoWaitMessage;
  NeoMessage.params[0] := a;
  NeoMessage.params[1] := 150;                  // Move Window : nouveau coin haut gauche du cadre (X = 150...
  NeoMessage.params[2] := 0;
  NeoMessage.params[3] := 60;                   // ... Y = 60)
  NeoMessage.params[4] := 0;
  NeoSendMessage(34, 5);
  NeoWaitMessage;
  contenu(a, @c);
  t := trouver(50, 60);                         // l'ancienne place est libre
  reinit;
  writeln('Contenu : ', c.g, ', ', c.h, ', ', c.d, ', ', c.b, ' ; ancienne place : ', t);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 151, 71, 249, 139 ; ancienne place : 0
NeoBASIC
10 ' Deplacer une fenetre (groupe 34, fonction 5, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1 : k = alloc(8)
40 gosub 8500
50 q = r1 : gosub 8100 : a = w
60 while peek($ff00) : wend : doke $ff05, 150 : doke $ff07, 60 : ' Move Window : nouveau coin haut gauche du cadre
70 n = a : f = 5 : gosub 8210
80 gosub 8400
90 x = 50 : y = 60 : gosub 8300 : ' l'ancienne place est libre
100 gosub 8500
110 print "Contenu : ";cg;", ";ch;", ";cd;", ";cb;" ; ancienne place : ";fw
120 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 151, 71, 249, 139 ; ancienne place : 0
65C02 assembly (64tass)
; Déplacer une fenêtre (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        jsr WaitMessage
        lda #150                   ; Move Window : nouveau coin haut gauche du cadre (X = 150...
        sta ControlPort+5
        stz ControlPort+6
        lda #60                    ; ... Y = 60)
        sta ControlPort+7
        stz ControlPort+8
        lda a
        ldx #5
        jsr fen
        jsr WaitMessage
        lda a
        sta ControlPort+4
        lda #<c
        sta ControlPort+5          ; P1-P2 : adresse du Rect
        lda #>c
        sta ControlPort+6
        lda #34
        ldx #8                     ; 34,8 : Get Content Rect
        jsr appel
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta t
        lda ControlPort+9          ; P5 : zone
        sta z
                                   ; l'ancienne place est libre
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda c
        ldx c+1
        jsr dec16
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda c+2
        ldx c+2+1
        jsr dec16
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda c+4
        ldx c+4+1
        jsr dec16
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda c+6
        ldx c+6+1
        jsr dec16
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda t
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
c:      .fill 8
t:      .byte 0
z:      .byte 0
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 50, 60
b3:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t4:     .text "Contenu : ", 0
t5:     .text ", ", 0
t6:     .text ", ", 0
t7:     .text ", ", 0
t8:     .text " ; ancienne place : ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 151, 71, 249, 139 ; ancienne place : 0

34,6 Size Window Trinity

Changes the width and height of a window frame.

Inputs
BytesTypeMeaning
P0uint8window number
P1-P2uint16frame width in pixels
P3-P4uint16frame height in pixels (3 at least)
Outputs
BytesTypeMeaning
erreuruint81 for a size too small

The top left corner does not move: 50 × 40 gives the content 21, 31, 69, 59. A height of 2 is refused. NeoBASIC has no keyword for this call.

Firmware documentation text

Sets the frame of window Parameter:0 to Parameters:1,2 pixels wide and Parameters:3,4 high (3 at least).

C (llvm-mos)
/* Changer la taille d'une fenêtre (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect r1 = {20, 20, 120, 100}, c;
static const char titre[] = "\001A";

static uint8_t taille(uint8_t w, uint16_t l, uint16_t h) {   /* Size Window : largeur, hauteur du cadre */
    libre();
    ControlPort.params[0] = w;
    p16(1, l);
    p16(3, h);
    api(34, 6);
    return ControlPort.error;
}

int main(void) {
    uint8_t a, e;
    reinit();
    a = nouvelle(&r1, titre, 1);
    taille(a, 50, 40);
    contenu(a, &c);
    e = taille(a, 50, 2);                       /* moins de 3 : refusé */
    reinit();
    printf("Contenu : %d, %d, %d, %d\n", c.g, c.h, c.d, c.b);
    printf("Hauteur 2 : erreur %u\n", e);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1
Mad Pascal
// Changer la taille d'une fenêtre (groupe 34, fonction 6, Trinity).
program wm6;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

function taille(w: byte; l, h: word): byte;    // Size Window : largeur, hauteur du cadre
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(l);
  NeoMessage.params[2] := hi(l);
  NeoMessage.params[3] := lo(h);
  NeoMessage.params[4] := hi(h);
  NeoSendMessage(34, 6);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

var r1, c: Rect;
    a, e: byte;
begin
  poser(r1, 20, 20, 120, 100);
  reinit;
  a := nouvelle(@r1, @titre, 1);
  taille(a, 50, 40);
  contenu(a, @c);
  e := taille(a, 50, 2);                        // moins de 3 : refusé
  reinit;
  writeln('Contenu : ', c.g, ', ', c.h, ', ', c.d, ', ', c.b);
  writeln('Hauteur 2 : erreur ', e);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1
NeoBASIC
10 ' Changer la taille d'une fenetre (groupe 34, fonction 6, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1 : k = alloc(8)
40 gosub 8500
50 q = r1 : gosub 8100 : a = w
60 l = 50 : hh = 40 : gosub 2000
70 n = a : gosub 8400
80 hh = 2 : gosub 2000 : e2 = e : ' moins de 3 : refuse
90 gosub 8500
100 print "Contenu : ";cg;", ";ch;", ";cd;", ";cb
110 print "Hauteur 2 : erreur ";e2
120 end
2000 ' Size Window : largeur l, hauteur hh du cadre
2010 while peek($ff00) : wend : doke $ff05, l : doke $ff07, hh : n = a : f = 6 : goto 8210
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1
65C02 assembly (64tass)
; Changer la taille d'une fenêtre (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        jsr WaitMessage
        lda #50                    ; Size Window : largeur 50...
        sta ControlPort+5
        stz ControlPort+6
        lda #40                    ; ... hauteur 40
        sta ControlPort+7
        stz ControlPort+8
        lda a
        ldx #6
        jsr fen
        jsr WaitMessage
        lda a
        sta ControlPort+4
        lda #<c
        sta ControlPort+5          ; P1-P2 : adresse du Rect
        lda #>c
        sta ControlPort+6
        lda #34
        ldx #8                     ; 34,8 : Get Content Rect
        jsr appel
        jsr WaitMessage
        lda #50                    ; Size Window : largeur 50...
        sta ControlPort+5
        stz ControlPort+6
        lda #2                    ; ... hauteur 2 : moins de 3, refusé
        sta ControlPort+7
        stz ControlPort+8
        lda a
        ldx #6
        jsr fen
        sta e
        lda #<b2
        ldx #>b2
        jsr envoi
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda c
        ldx c+1
        jsr dec16
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda c+2
        ldx c+2+1
        jsr dec16
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda c+4
        ldx c+4+1
        jsr dec16
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda c+6
        ldx c+6+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda e
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
c:      .fill 8
e:      .byte 0
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t3:     .text "Contenu : ", 0
t4:     .text ", ", 0
t5:     .text ", ", 0
t6:     .text ", ", 0
t7:     .text "Hauteur 2 : 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1

34,7 Find Window Trinity

Returns the frontmost visible window under a point, and the part hit.

Inputs
BytesTypeMeaning
P0-P1int16point X
P2-P3int16point Y
Outputs
BytesTypeMeaning
P4uint8window (0 if none)
P5uint8part: 1 content, 2 title bar or border, 3 close box, 4 grow box

Measured on the bench for frame 20, 20, 120, 100: the close box covers x 23 to 29, y 22 to 28; the grow box, the bottom right corner of the content from (111, 91). NeoBASIC has no keyword for this call.

Firmware documentation text

Returns in Parameter:4 the frontmost visible window under the point Parameters:0,1 (X), Parameters:2,3 (Y) (0 if none) and in Parameter:5 the part hit : 1 content, 2 title bar or border (drag), 3 close box, 4 grow box.

C (llvm-mos)
/* Trouver la fenêtre sous un point (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) {  /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
    libre();
    p16(0, x);
    p16(2, y);
    api(34, 7);
    zone = ControlPort.params[5];               /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
    return ControlPort.params[4];
}

static Rect r1 = {20, 20, 120, 100};
static const char titre[] = "\001A";
static const int16_t px[5] = {50, 50, 25, 115, 5}, py[5] = {25, 60, 25, 95, 5};
static const char *nom[5] = {"Barre de titre", "Contenu", "Fermeture", "Agrandissement", "Dehors"};

int main(void) {
    uint8_t i, w[5], z[5];
    reinit();
    nouvelle(&r1, titre, 7);                    /* barre de titre, fermeture, agrandissement */
    for (i = 0; i < 5; i++) {
        w[i] = trouver(px[i], py[i]);
        z[i] = zone;
    }
    reinit();
    for (i = 0; i < 5; i++)
        printf("%s : %u, %u\n", nom[i], w[i], z[i]);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0
Mad Pascal
// Trouver la fenêtre sous un point (groupe 34, fonction 7, Trinity).
program wm7;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var zone: byte;

function trouver(x, y: smallint): byte;         // 34,7 Find Window : fenêtre sous le point, zone dans « zone »
begin
  NeoWaitMessage;
  wordParams[0] := word(x);
  wordParams[1] := word(y);
  NeoSendMessage(34, 7);
  NeoWaitMessage;
  zone := NeoMessage.params[5];                 // 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement
  result := NeoMessage.params[4];
end;

const px: array[0..4] of smallint = (50, 50, 25, 115, 5);
      py: array[0..4] of smallint = (25, 60, 25, 95, 5);
var r1: Rect;
    w, z: array[0..4] of byte;
    i: byte;
begin
  poser(r1, 20, 20, 120, 100);
  reinit;
  nouvelle(@r1, @titre, 7);                     // barre de titre, fermeture, agrandissement
  for i := 0 to 4 do begin
    w[i] := trouver(px[i], py[i]);
    z[i] := zone;
  end;
  reinit;
  writeln('Barre de titre : ', w[0], ', ', z[0]);
  writeln('Contenu : ', w[1], ', ', z[1]);
  writeln('Fermeture : ', w[2], ', ', z[2]);
  writeln('Agrandissement : ', w[3], ', ', z[3]);
  writeln('Dehors : ', w[4], ', ', z[4]);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0
NeoBASIC
10 ' Trouver la fenetre sous un point (groupe 34, fonction 7, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 7 : ' barre de titre, fermeture, agrandissement
40 gosub 8500
50 q = r1 : gosub 8100
60 dim w(4), z(4)
70 for i = 0 to 4 : read x, y : gosub 8300 : w(i) = fw : z(i) = zn : next i
80 data 50, 25, 50, 60, 25, 25, 115, 95, 5, 5
90 gosub 8500
100 for i = 0 to 4 : read n$ : print n$;" : ";w(i);", ";z(i) : next i
110 data "Barre de titre", "Contenu", "Fermeture", "Agrandissement", "Dehors"
120 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0
65C02 assembly (64tass)
; Trouver la fenêtre sous un point (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta w0
        lda ControlPort+9          ; P5 : zone
        sta z0
        lda #<b3
        ldx #>b3
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta w1
        lda ControlPort+9          ; P5 : zone
        sta z1
        lda #<b4
        ldx #>b4
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta w2
        lda ControlPort+9          ; P5 : zone
        sta z2
        lda #<b5
        ldx #>b5
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta w3
        lda ControlPort+9          ; P5 : zone
        sta z3
        lda #<b6
        ldx #>b6
        jsr envoi
        lda ControlPort+8          ; P4 : fenêtre
        sta w4
        lda ControlPort+9          ; P5 : zone
        sta z4
        lda #<b7
        ldx #>b7
        jsr envoi
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda w0
        jsr decimal
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda z0
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t10
        ldx #>t10
        jsr ecrire
        lda w1
        jsr decimal
        lda #<t11
        ldx #>t11
        jsr ecrire
        lda z1
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t12
        ldx #>t12
        jsr ecrire
        lda w2
        jsr decimal
        lda #<t13
        ldx #>t13
        jsr ecrire
        lda z2
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t14
        ldx #>t14
        jsr ecrire
        lda w3
        jsr decimal
        lda #<t15
        ldx #>t15
        jsr ecrire
        lda z3
        jsr decimal
        lda #13
        jsr WriteCharacter
        lda #<t16
        ldx #>t16
        jsr ecrire
        lda w4
        jsr decimal
        lda #<t17
        ldx #>t17
        jsr ecrire
        lda z4
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : barre de titre, fermeture, agrandissement
        .word r1, titre
        .byte 7
w0:     .byte 0
z0:     .byte 0
b2:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 50, 25
w1:     .byte 0
z1:     .byte 0
b3:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 50, 60
w2:     .byte 0
z2:     .byte 0
b4:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 25, 25
w3:     .byte 0
z3:     .byte 0
b5:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 115, 95
w4:     .byte 0
z4:     .byte 0
b6:     .byte 34, 7, 4             ; 34,7 : Find Window
        .word 5, 5
b7:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t8:     .text "Barre de titre : ", 0
t9:     .text ", ", 0
t10:    .text "Contenu : ", 0
t11:    .text ", ", 0
t12:    .text "Fermeture : ", 0
t13:    .text ", ", 0
t14:    .text "Agrandissement : ", 0
t15:    .text ", ", 0
t16:    .text "Dehors : ", 0
t17:    .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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0

34,8 Get Content Rect Trinity

Writes the content rectangle of a window (inside the frame, below the title bar).

Inputs
BytesTypeMeaning
P0uint8window number
P1-P2addraddress of the Rect to fill

Outputs: none.

Screen coordinates. Without a title bar, the content starts just below the one-pixel border. NeoBASIC has no keyword for this call.

Firmware documentation text

Writes the content rectangle of window Parameter:0 (screen coordinates, inside the frame and below the title bar) into the Rect at Parameters:1,2.

C (llvm-mos)
/* Lire le rectangle de contenu (groupe 34, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect r1 = {20, 20, 120, 100}, c1, c2;
static const char titre[] = "\001A";

int main(void) {
    reinit();
    contenu(nouvelle(&r1, titre, 1), &c1);      /* avec barre de titre */
    contenu(nouvelle(&r1, titre, 0), &c2);      /* même cadre, sans barre */
    reinit();
    printf("Avec barre de titre : %d, %d, %d, %d\n", c1.g, c1.h, c1.d, c1.b);
    printf("Sans : %d, %d, %d, %d\n", c2.g, c2.h, c2.d, c2.b);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99
Mad Pascal
// Lire le rectangle de contenu (groupe 34, fonction 8, Trinity).
program wm8;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var r1, c1, c2: Rect;
begin
  poser(r1, 20, 20, 120, 100);
  reinit;
  contenu(nouvelle(@r1, @titre, 1), @c1);       // avec barre de titre
  contenu(nouvelle(@r1, @titre, 0), @c2);       // même cadre, sans barre
  reinit;
  writeln('Avec barre de titre : ', c1.g, ', ', c1.h, ', ', c1.d, ', ', c1.b);
  writeln('Sans : ', c2.g, ', ', c2.h, ', ', c2.d, ', ', c2.b);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99
NeoBASIC
10 ' Lire le rectangle de contenu (groupe 34, fonction 8, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : k = alloc(8)
40 gosub 8500
50 o = 1 : gosub 8100 : n = w : gosub 8400 : ' avec barre de titre
60 a1 = cg : a2 = ch : a3 = cd : a4 = cb
70 o = 0 : gosub 8100 : n = w : gosub 8400 : ' meme cadre, sans barre
80 gosub 8500
90 print "Avec barre de titre : ";a1;", ";a2;", ";a3;", ";a4
100 print "Sans : ";cg;", ";ch;", ";cd;", ";cb
110 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99
65C02 assembly (64tass)
; Lire le rectangle de contenu (groupe 34, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        jsr WaitMessage
        lda a
        sta ControlPort+4
        lda #<c1
        sta ControlPort+5          ; P1-P2 : adresse du Rect
        lda #>c1
        sta ControlPort+6
        lda #34
        ldx #8                     ; 34,8 : Get Content Rect
        jsr appel
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta b
        jsr WaitMessage
        lda b
        sta ControlPort+4
        lda #<c2
        sta ControlPort+5          ; P1-P2 : adresse du Rect
        lda #>c2
        sta ControlPort+6
        lda #34
        ldx #8                     ; 34,8 : Get Content Rect
        jsr appel
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda c1
        ldx c1+1
        jsr dec16
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda c1+2
        ldx c1+2+1
        jsr dec16
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda c1+4
        ldx c1+4+1
        jsr dec16
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda c1+6
        ldx c1+6+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda c2
        ldx c2+1
        jsr dec16
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda c2+2
        ldx c2+2+1
        jsr dec16
        lda #<t10
        ldx #>t10
        jsr ecrire
        lda c2+4
        ldx c2+4+1
        jsr dec16
        lda #<t11
        ldx #>t11
        jsr ecrire
        lda c2+6
        ldx c2+6+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
c1:     .fill 8
c2:     .fill 8
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : avec barre de titre
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 34, 1, 5             ; même cadre, sans barre
        .word r1, titre
        .byte 0
b:      .byte 0
b3:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t4:     .text "Avec barre de titre : ", 0
t5:     .text ", ", 0
t6:     .text ", ", 0
t7:     .text ", ", 0
t8:     .text "Sans : ", 0
t9:     .text ", ", 0
t10:    .text ", ", 0
t11:    .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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99

34,9 Set Window Title Trinity

Changes the title of a window and repaints its frame.

Inputs
BytesTypeMeaning
P0uint8window number
P1-P2addraddress of the title, preceded by its length (read in place)

Outputs: none.

The title bar is white (colour 15), the text black. The example counts the black pixels of the bar, to the right of the close box: 16 for "A", 94 for "ABCDEF". It measures everything before printing, as the console writes to the same plane. NeoBASIC has no keyword for this call.

Firmware documentation text

Changes the title of window Parameter:0 to the length-prefixed string at Parameters:1,2 (read in place, see New Window) and repaints its frame.

C (llvm-mos)
/* Changer le titre d'une fenêtre (groupe 34, fonction 9, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

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 Rect r1 = {20, 20, 120, 100};
static const char court[] = "\001A", long_[] = "\006ABCDEF";

static uint16_t noirs(void) {                   /* pixels noirs du titre (après la case de fermeture) */
    int16_t x, y;
    uint16_t n = 0;
    for (y = 22; y < 29; y++)
        for (x = 31; x < 119; x++)
            if (pixel(x, y) == 0)
                n++;
    return n;
}

int main(void) {
    uint8_t a;
    uint16_t n1, n2;
    putchar(12);                                /* écran effacé : on relit des pixels */
    reinit();
    a = nouvelle(&r1, court, 3);
    n1 = noirs();
    libre();
    ControlPort.params[0] = a;
    p16(1, (uint16_t)long_);                    /* Set Window Title : chaîne lue sur place */
    api(34, 9);
    n2 = noirs();
    reinit();
    printf("Pixels du titre : A %u, ABCDEF %u\n", n1, n2);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Pixels du titre : A 16, ABCDEF 94
Mad Pascal
// Changer le titre d'une fenêtre (groupe 34, fonction 9, Trinity).
program wm9;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

const long: array[0..6] of byte = (6, ord('A'), ord('B'), ord('C'), ord('D'), ord('E'), ord('F'));

function noirs: word;                           // pixels noirs du titre (après la case de fermeture)
var x, y: word;
begin
  result := 0;
  for y := 22 to 28 do
    for x := 31 to 118 do
      if NeoGetPixel(x, y) = 0 then inc(result);
end;

var r1: Rect;
    a: byte;
    n1, n2: word;
begin
  write(chr(12));                               // écran effacé : on relit des pixels
  poser(r1, 20, 20, 120, 100);
  reinit;
  a := nouvelle(@r1, @titre, 3);
  n1 := noirs;
  NeoWaitMessage;
  NeoMessage.params[0] := a;
  NeoMessage.params[1] := lo(word(@long));      // Set Window Title : chaîne lue sur place
  NeoMessage.params[2] := hi(word(@long));
  NeoSendMessage(34, 9);
  NeoWaitMessage;
  n2 := noirs;
  reinit;
  writeln('Pixels du titre : A ', n1, ', ABCDEF ', n2);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Pixels du titre : A 16, ABCDEF 94
NeoBASIC
10 ' Changer le titre d'une fenetre (groupe 34, fonction 9, Trinity)
20 cls : ' ecran efface : on relit des pixels
30 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
40 t = alloc(2) : poke t, 1 : poke t + 1, asc("A")
50 lg = alloc(7) : poke lg, 6 : for i = 1 to 6 : poke lg + i, 64 + i : next i : ' ABCDEF
60 gosub 8500
70 o = 3 : gosub 8100 : a = w
80 gosub 2000 : n1 = nb
90 while peek($ff00) : wend : poke $ff04, a : doke $ff05, lg : ' Set Window Title : chaine lue sur place
100 n = a : f = 9 : gosub 8220
110 gosub 2000 : n2 = nb
120 gosub 8500
130 print "Pixels du titre : A ";n1;", ABCDEF ";n2
140 end
2000 ' pixels noirs du titre (apres la case de fermeture)
2010 nb = 0 : for y = 22 to 28 : for x = 31 to 118 : if point(x, y) = 0 then nb = nb + 1
2020 next x : next y : return
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Pixels du titre : A 16, ABCDEF 94
65C02 assembly (64tass)
; Changer le titre d'une fenêtre (groupe 34, fonction 9, 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 #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        jsr noirs
        lda nb
        sta n1
        lda nb+1
        sta n1+1
        jsr WaitMessage
        lda #<long
        sta ControlPort+5          ; P1-P2 : nouveau titre, lu sur place
        lda #>long
        sta ControlPort+6
        lda a
        ldx #9                     ; Set Window Title
        jsr fen
        jsr noirs
        lda nb
        sta n2
        lda nb+1
        sta n2+1
        lda #<b2
        ldx #>b2
        jsr envoi
        lda #<t3
        ldx #>t3
        jsr ecrire
        lda n1
        ldx n1+1
        jsr dec16
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda n2
        ldx n2+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        rts

; Pixels noirs du titre (après la case de fermeture) : x 31 à 118, y 22 à 28, dans nb.
noirs:  stz nb
        stz nb+1
        lda #22
        sta yy
_y:     lda #31
        sta xx
_x:     lda xx
        ldy yy
        jsr pixel
        cmp #0
        bne _nx
        inc nb
        bne _nx
        inc nb+1
_nx:    inc xx
        lda xx
        cmp #119
        bne _x
        inc yy
        lda yy
        cmp #29
        bne _y
        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

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
long:   .byte 6
        .text "ABCDEF"
nb:     .word 0
xx:     .byte 0
yy:     .byte 0
n1:     .fill 2
n2:     .fill 2
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 3
a:      .byte 0
b2:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t3:     .text "Pixels du titre : A ", 0
t4:     .text ", ABCDEF ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Pixels du titre : A 16, ABCDEF 94

34,10 Front Window Trinity

Returns the frontmost visible window.

Inputs: none.

Outputs
BytesTypeMeaning
P0uint8window (0 if none)

Without windows, 0; the last one opened is in front; once it is closed, the one below comes back to the front. NeoBASIC has no keyword for this call.

Firmware documentation text

Returns the frontmost visible window in Parameter:0 (0 if none).

C (llvm-mos)
/* Savoir quelle fenêtre est devant (groupe 34, fonction 10, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";

int main(void) {
    uint8_t b, d0, d2, d1;
    reinit();
    d0 = devant();                              /* Front Window : 0 sans fenêtre */
    nouvelle(&r1, titre, 1);
    b = nouvelle(&r2, titre, 1);
    d2 = devant();
    fenetre(2, b);
    d1 = devant();
    reinit();
    printf("Aucune : %u, deux : %u, apres fermeture : %u\n", d0, d2, d1);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Aucune : 0, deux : 2, apres fermeture : 1
Mad Pascal
// Savoir quelle fenêtre est devant (groupe 34, fonction 10, Trinity).
program wm10;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var r1, r2: Rect;
    b, d0, d2, d1: byte;
begin
  poser(r1, 20, 20, 120, 100);
  poser(r2, 60, 50, 200, 150);
  reinit;
  d0 := devant;                                 // Front Window : 0 sans fenêtre
  nouvelle(@r1, @titre, 1);
  b := nouvelle(@r2, @titre, 1);
  d2 := devant;
  fenetre(2, b);
  d1 := devant;
  reinit;
  writeln('Aucune : ', d0, ', deux : ', d2, ', apres fermeture : ', d1);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Aucune : 0, deux : 2, apres fermeture : 1
NeoBASIC
10 ' Savoir quelle fenetre est devant (groupe 34, fonction 10, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 r2 = alloc(8) : q = r2 : g = 60 : h = 50 : d = 200 : b = 150 : gosub 8000
40 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1
50 gosub 8500
60 gosub 8600 : d0 = dv : ' Front Window : 0 sans fenetre
70 q = r1 : gosub 8100
80 q = r2 : gosub 8100 : bw = w
90 gosub 8600 : d2 = dv
100 n = bw : f = 2 : gosub 8200
110 gosub 8600 : d1 = dv
120 gosub 8500
130 print "Aucune : ";d0;", deux : ";d2;", apres fermeture : ";d1
140 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Aucune : 0, deux : 2, apres fermeture : 1
65C02 assembly (64tass)
; Savoir quelle fenêtre est devant (groupe 34, fonction 10, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d0
        lda #<b1
        ldx #>b1
        jsr envoi
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta b
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d2
        lda b
        ldx #2                  ; 34,2
        jsr fen
        lda #0
        ldx #10                    ; 34,10 : Front Window
        jsr fen
        lda ControlPort+4
        sta d1
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda d0
        jsr decimal
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda d2
        jsr decimal
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda d1
        jsr decimal
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
r2:     .word 60, 50, 200, 150        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
d0:     .byte 0
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
b2:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r2, titre
        .byte 1
b:      .byte 0
d2:     .byte 0
d1:     .byte 0
b3:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t4:     .text "Aucune : ", 0
t5:     .text ", deux : ", 0
t6:     .text ", apres fermeture : ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Aucune : 0, deux : 2, apres fermeture : 1

34,11 End Update Trinity

To call after redrawing the content of a window: repaints the frames of the windows above it.

Inputs
BytesTypeMeaning
P0uint8window number

Outputs: none.

The content is clipped to its own rectangle only: while painting it, the program overwrites the frames of the front windows that overlap it. The example handles the update events (type 9): 34,12, painting in colour 4, then 34,11. The border of window 2 lying on window 1 turns 4, then goes back to 15. NeoBASIC has no keyword for this call.

Firmware documentation text

To call after redrawing the content of window Parameter:0 : repaints the frames of the windows above it, which the content drawing may have overwritten (contents are clipped to the content rectangle only).

C (llvm-mos)
/* Terminer le dessin d'une fenêtre (groupe 34, fonction 11, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

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];
}

typedef struct { uint8_t what, message, message2, modifiers; int16_t x, y; } EventRecord;
static EventRecord ev;
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150}, ecran = {0, 0, 320, 240};
static const char titre[] = "\001A";

int main(void) {
    uint8_t a, avant = 0, apres = 0;
    putchar(12);
    reinit();
    libre(); p16(0, 0); api(33, 1);             /* 33,1 : file d'événements */
    a = nouvelle(&r1, titre, 1);
    nouvelle(&r2, titre, 1);                    /* la fenêtre 2 couvre un coin de la 1 */
    for (;;) {                                  /* événements de mise à jour (type 9), de l'arrière vers l'avant */
        libre(); p16(0, (uint16_t)&ev); p16(2, 0x100); api(33, 2);
        if (!ControlPort.params[4])
            break;
        fenetre(12, ev.message);                /* 34,12 Set Port : découpe sur le contenu */
        libre(); ControlPort.params[0] = 4; api(32, 4);
        libre(); p16(0, (uint16_t)&ecran); api(32, 8);   /* peint tout le contenu en couleur 4 */
        if (ev.message == a)
            avant = pixel(80, 50);              /* bord haut de la fenêtre 2, dans le contenu de la 1 */
        fenetre(11, ev.message);                /* End Update : repeint les cadres des fenêtres au-dessus */
        if (ev.message == a)
            apres = pixel(80, 50);
    }
    reinit();
    printf("Bord de la fenetre 2 : avant %u, apres %u\n", avant, apres);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Bord de la fenetre 2 : avant 4, apres 15
Mad Pascal
// Terminer le dessin d'une fenêtre (groupe 34, fonction 11, Trinity).
program wm11;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

type EventRecord = record what, message, message2, modifiers: byte; x, y: smallint; end;
var ev: EventRecord;
    r1, r2, ecran: Rect;
    a, avant, apres: byte;
begin
  write(chr(12));
  poser(r1, 20, 20, 120, 100);
  poser(r2, 60, 50, 200, 150);
  poser(ecran, 0, 0, 320, 240);
  avant := 0;
  apres := 0;
  reinit;
  NeoWaitMessage;
  wordParams[0] := 0;
  NeoSendMessage(33, 1);                        // 33,1 : file d'événements
  NeoWaitMessage;
  a := nouvelle(@r1, @titre, 1);
  nouvelle(@r2, @titre, 1);                     // la fenêtre 2 couvre un coin de la 1
  repeat                                        // événements de mise à jour (type 9), de l'arrière vers l'avant
    NeoWaitMessage;
    wordParams[0] := word(@ev);
    wordParams[1] := $100;
    NeoSendMessage(33, 2);
    NeoWaitMessage;
    if NeoMessage.params[4] = 0 then break;
    fenetre(12, ev.message);                    // 34,12 Set Port : découpe sur le contenu
    NeoWaitMessage;
    NeoMessage.params[0] := 4;
    NeoSendMessage(32, 4);
    NeoWaitMessage;
    wordParams[0] := word(@ecran);
    NeoSendMessage(32, 8);                      // peint tout le contenu en couleur 4
    NeoWaitMessage;
    if ev.message = a then avant := NeoGetPixel(80, 50);   // bord haut de la fenêtre 2, dans le contenu de la 1
    fenetre(11, ev.message);                    // End Update : repeint les cadres des fenêtres au-dessus
    if ev.message = a then apres := NeoGetPixel(80, 50);
  until false;
  reinit;
  writeln('Bord de la fenetre 2 : avant ', avant, ', apres ', apres);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Bord de la fenetre 2 : avant 4, apres 15
NeoBASIC
10 ' Terminer le dessin d'une fenetre (groupe 34, fonction 11, Trinity)
20 cls
30 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
40 r2 = alloc(8) : q = r2 : g = 60 : h = 50 : d = 200 : b = 150 : gosub 8000
50 ec = alloc(8) : q = ec : g = 0 : h = 0 : d = 320 : b = 240 : gosub 8000
60 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1 : ev = alloc(8)
70 gosub 8500
80 while peek($ff00) : wend : doke $ff04, 0 : poke $ff01, 1 : poke $ff00, 33 : ' 33,1 : file d'evenements
90 q = r1 : gosub 8100 : a = w
100 q = r2 : gosub 8100 : ' la fenetre 2 couvre un coin de la 1
110 ' evenements de mise a jour (type 9), de l'arriere vers l'avant
120 while peek($ff00) : wend : doke $ff04, ev : doke $ff06, $100 : poke $ff01, 2 : poke $ff00, 33
130 while peek($ff00) : wend : if peek($ff08) = 0 then 220
140 n = peek(ev + 1) : f = 12 : gosub 8200 : ' 34,12 Set Port : decoupe sur le contenu
150 while peek($ff00) : wend : poke $ff04, 4 : poke $ff01, 4 : poke $ff00, 32
160 while peek($ff00) : wend : doke $ff04, ec : poke $ff01, 8 : poke $ff00, 32 : ' peint tout le contenu en couleur 4
170 while peek($ff00) : wend
180 if n = a then av = point(80, 50) : ' bord haut de la fenetre 2, dans le contenu de la 1
190 f = 11 : gosub 8200 : ' End Update : repeint les cadres des fenetres au-dessus
200 if n = a then ap = point(80, 50)
210 goto 120
220 gosub 8500
230 print "Bord de la fenetre 2 : avant ";av;", apres ";ap
240 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Bord de la fenetre 2 : avant 4, apres 15
65C02 assembly (64tass)
; Terminer le dessin d'une fenêtre (groupe 34, fonction 11, 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 #<b1
        ldx #>b1
        jsr envoi
        lda #<b2
        ldx #>b2
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        lda #<b3
        ldx #>b3
        jsr envoi
_ev:    lda #<b4
        ldx #>b4
        jsr envoi
        lda ControlPort+8
        beq _fini
        lda ev+1                   ; message : la fenêtre à redessiner
        ldx #12                    ; 34,12 Set Port : découpe sur le contenu
        jsr fen
        lda #<b5
        ldx #>b5
        jsr envoi
        lda #<b6
        ldx #>b6
        jsr envoi
        lda ev+1
        cmp a
        bne _maj
        lda #80                    ; bord haut de la fenêtre 2, dans le contenu de la 1
        ldy #50
        jsr pixel
        sta av
_maj:   lda ev+1
        ldx #11                    ; End Update : repeint les cadres des fenêtres au-dessus
        jsr fen
        lda ev+1
        cmp a
        bne _ev
        lda #80
        ldy #50
        jsr pixel
        sta ap
        bra _ev
_fini:
        lda #<b7
        ldx #>b7
        jsr envoi
        lda #<t8
        ldx #>t8
        jsr ecrire
        lda av
        jsr decimal
        lda #<t9
        ldx #>t9
        jsr ecrire
        lda ap
        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

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
r2:     .word 60, 50, 200, 150        ; gauche, haut, droite, bas (droite et bas exclus)
ecran:  .word 0, 0, 320, 240        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
ev:     .fill 8                    ; EventRecord : type, message, message2, modificateurs, X, Y
av:     .byte 0
ap:     .byte 0
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 33, 1, 2             ; 33,1 : file d'événements
        .word 0
b2:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b3:     .byte 34, 1, 5             ; la fenêtre 2 couvre un coin de la 1
        .word r2, titre
        .byte 1
b4:     .byte 33, 2, 4             ; 33,2 : mises à jour (type 9), de l'arrière vers l'avant
        .word ev, $100
b5:     .byte 32, 4, 1, 4          ; 32,4 : couleur 4
b6:     .byte 32, 8, 2             ; 32,8 : peint tout le contenu
        .word ecran
b7:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t8:     .text "Bord de la fenetre 2 : avant ", 0
t9:     .text ", apres ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Bord de la fenetre 2 : avant 4, apres 15

34,12 Set Port Trinity

Sets the QuickDraw clip (group 32) to the content of a window.

Inputs
BytesTypeMeaning
P0uint8window number

Outputs: none.

It is the first step to draw in a window: any drawing of group 32 then stays inside the content. 32,3 reads back the clip: that of the content. NeoBASIC has no keyword for this call.

Firmware documentation text

Sets the QuickDraw clip rectangle (group 32) to the content rectangle of window Parameter:0.

C (llvm-mos)
/* Dessiner dans une fenêtre (groupe 34, fonction 12, 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)
        ;
}

/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;

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 nouvelle(Rect *cadre, const char *titre, uint8_t options) {   /* 34,1 New Window : rend le numéro */
    libre();
    p16(0, (uint16_t)cadre);
    p16(2, (uint16_t)titre);                    /* chaîne précédée de sa longueur, lue sur place */
    ControlPort.params[4] = options;            /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
    api(34, 1);
    return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) {  /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
    libre();
    ControlPort.params[0] = w;
    api(34, f);
    return ControlPort.error;
}
static uint8_t devant(void) {                   /* 34,10 Front Window */
    libre();
    api(34, 10);
    return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) {       /* 34,8 Get Content Rect */
    libre();
    ControlPort.params[0] = w;
    p16(1, (uint16_t)r);
    api(34, 8);
}
static void reinit(void) {                      /* 32,19 Toolbox Reset : plus aucune fenêtre */
    libre();
    api(32, 19);
}

static Rect r1 = {20, 20, 120, 100}, k;
static const char titre[] = "\001A";

int main(void) {
    reinit();
    fenetre(12, nouvelle(&r1, titre, 1));       /* Set Port : la découpe de QuickDraw devient le contenu */
    libre(); p16(0, (uint16_t)&k); api(32, 3);  /* 32,3 Get Clip */
    reinit();
    printf("Decoupe : %d, %d, %d, %d\n", k.g, k.h, k.d, k.b);
    return 0;
}
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Decoupe : 21, 31, 119, 99
Mad Pascal
// Dessiner dans une fenêtre (groupe 34, fonction 12, Trinity).
program wm12;
uses crt, neo6502;
type Rect = record g, h, d, b: smallint; end; // gauche, haut, droite, bas (16 bits signés ; droite et bas exclus)

const titre: array[0..1] of byte = (1, ord('A'));   // chaîne précédée de sa longueur, lue sur place

procedure poser(var r: Rect; g, h, d, b: smallint);
begin
  r.g := g; r.h := h; r.d := d; r.b := b;
end;

function nouvelle(cadre, t: pointer; options: byte): byte;   // 34,1 New Window : rend le numéro
begin
  NeoWaitMessage;
  wordParams[0] := word(cadre);
  wordParams[1] := word(t);
  NeoMessage.params[4] := options;              // bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement
  NeoSendMessage(34, 1);
  NeoWaitMessage;
  result := NeoMessage.params[5];
end;

function fenetre(f, w: byte): byte;             // appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoSendMessage(34, f);
  NeoWaitMessage;
  result := NeoMessage.error;
end;

function devant: byte;                          // 34,10 Front Window
begin
  fenetre(10, 0);
  result := NeoMessage.params[0];
end;

procedure contenu(w: byte; r: pointer);         // 34,8 Get Content Rect
begin
  NeoWaitMessage;
  NeoMessage.params[0] := w;
  NeoMessage.params[1] := lo(word(r));
  NeoMessage.params[2] := hi(word(r));
  NeoSendMessage(34, 8);
  NeoWaitMessage;
end;

procedure reinit;                               // 32,19 Toolbox Reset : plus aucune fenêtre
begin
  NeoWaitMessage;
  NeoSendMessage(32, 19);
  NeoWaitMessage;
end;

var r1, k: Rect;
begin
  poser(r1, 20, 20, 120, 100);
  reinit;
  fenetre(12, nouvelle(@r1, @titre, 1));        // Set Port : la découpe de QuickDraw devient le contenu
  NeoWaitMessage;
  wordParams[0] := word(@k);
  NeoSendMessage(32, 3);                        // 32,3 Get Clip
  NeoWaitMessage;
  reinit;
  writeln('Decoupe : ', k.g, ', ', k.h, ', ', k.d, ', ', k.b);
end.
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Decoupe : 21, 31, 119, 99
NeoBASIC
10 ' Dessiner dans une fenetre (groupe 34, fonction 12, Trinity)
20 r1 = alloc(8) : q = r1 : g = 20 : h = 20 : d = 120 : b = 100 : gosub 8000
30 t = alloc(2) : poke t, 1 : poke t + 1, asc("A") : o = 1 : k = alloc(8)
40 gosub 8500
50 gosub 8100 : n = w : f = 12 : gosub 8200 : ' Set Port : la decoupe de QuickDraw devient le contenu
60 while peek($ff00) : wend : doke $ff04, k : poke $ff01, 3 : poke $ff00, 32 : ' 32,3 Get Clip
70 while peek($ff00) : wend
80 gosub 8500
90 print "Decoupe : ";deek(k);", ";deek(k + 2);", ";deek(k + 4);", ";deek(k + 6)
100 end
8000 ' Rect en q : gauche g, haut h, droite d, bas b (16 bits signes ; droite et bas exclus)
8010 doke q, g : doke q + 2, h : doke q + 4, d : doke q + 6, b
8020 return
8100 ' 34,1 New Window : cadre q, titre t (precede de sa longueur, lu sur place), options o ; numero dans w
8110 while peek($ff00) : wend : doke $ff04, q : doke $ff06, t : poke $ff08, o
8120 poke $ff01, 1 : poke $ff00, 34
8130 while peek($ff00) : wend : w = peek($ff09) : e = peek($ff02)
8140 return
8200 ' appel 34,f sur la fenetre n ; erreur dans e
8210 while peek($ff00) : wend : poke $ff04, n
8220 poke $ff01, f : poke $ff00, 34
8230 while peek($ff00) : wend : e = peek($ff02)
8240 return
8300 ' 34,7 Find Window en (x, y) : fenetre dans fw, zone dans zn
8310 while peek($ff00) : wend : doke $ff04, x : doke $ff06, y : f = 7 : gosub 8220
8320 fw = peek($ff08) : zn = peek($ff09)
8330 return
8400 ' 34,8 Get Content Rect de la fenetre n dans le Rect k ; valeurs dans cg, ch, cd, cb
8410 while peek($ff00) : wend : poke $ff04, n : doke $ff05, k : f = 8 : gosub 8220
8420 cg = deek(k) : ch = deek(k + 2) : cd = deek(k + 4) : cb = deek(k + 6)
8430 return
8500 ' 32,19 Toolbox Reset : plus aucune fenetre ; 34,10 Front Window dans dv
8510 while peek($ff00) : wend : poke $ff01, 19 : poke $ff00, 32
8520 while peek($ff00) : wend : return
8600 f = 10 : gosub 8220 : dv = peek($ff04) : return
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Decoupe : 21, 31, 119, 99
65C02 assembly (64tass)
; Dessiner dans une fenêtre (groupe 34, fonction 12, 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 #<b0
        ldx #>b0
        jsr envoi
        lda #<b1
        ldx #>b1
        jsr envoi
        lda ControlPort+9          ; P5 : numéro de la fenêtre
        sta a
        lda a
        ldx #12                 ; Set Port : la découpe de QuickDraw devient le contenu
        jsr fen
        lda #<b2
        ldx #>b2
        jsr envoi
        lda #<b3
        ldx #>b3
        jsr envoi
        lda #<t4
        ldx #>t4
        jsr ecrire
        lda k
        ldx k+1
        jsr dec16
        lda #<t5
        ldx #>t5
        jsr ecrire
        lda k+2
        ldx k+2+1
        jsr dec16
        lda #<t6
        ldx #>t6
        jsr ecrire
        lda k+4
        ldx k+4+1
        jsr dec16
        lda #<t7
        ldx #>t7
        jsr ecrire
        lda k+6
        ldx k+6+1
        jsr dec16
        lda #13
        jsr WriteCharacter
        rts

r1:     .word 20, 20, 120, 100        ; gauche, haut, droite, bas (droite et bas exclus)
titre:  .byte 1
        .text "A"                  ; chaîne précédée de sa longueur, lue sur place
k:      .fill 8
b0:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
b1:     .byte 34, 1, 5             ; 34,1 : New Window
        .word r1, titre
        .byte 1
a:      .byte 0
b2:     .byte 32, 3, 2             ; 32,3 Get Clip
        .word k
b3:     .byte 32, 19, 0            ; 32,19 Toolbox Reset : plus aucune fenêtre
t4:     .text "Decoupe : ", 0
t5:     .text ", ", 0
t6:     .text ", ", 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

; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen:    pha
        phx
        jsr WaitMessage
        plx
        pla
        sta ControlPort+4          ; P0 : numéro de la fenêtre
        lda #34
        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
Output observed in the Phosphoneo emulator, Trinity firmware 0.16.69:
Decoupe : 21, 31, 119, 99

← The Neo6502 API