Groupe 34 — Gestionnaire de fenêtres 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
Le gestionnaire de fenêtres de la boîte à outils de Trinity tient jusqu'à 8 fenêtres, numérotées de 1 à 8. Le firmware dessine les cadres ; le programme dessine les contenus avec QuickDraw (groupe 32).
Après chaque changement (ouverture, fermeture, déplacement...), le firmware efface les contenus visibles, redessine les cadres et poste un événement de mise à jour (groupe 33, type 9) par fenêtre visible. Pour y répondre : 34,12 (Set Port), dessin avec le groupe 32, puis 34,11 (End Update).
Les exemples remettent la boîte à outils à zéro avec 32,19 au début et à la fin : elle garde son état d'un programme à l'autre.
34,1 New Window Trinity
Crée une fenêtre visible, la met devant et rend son numéro.
| Octets | Type | Rôle |
|---|---|---|
P0-P1 | addr | adresse du Rect du cadre (coordonnées de l'écran) |
P2-P3 | addr | adresse du titre, précédé de sa longueur (lu sur place) |
P4 | uint8 | options : bit 0 barre de titre, bit 1 case de fermeture, bit 2 case d'agrandissement |
| Octets | Type | Rôle |
|---|---|---|
P5 | uint8 | numéro de la fenêtre (1 à 8) |
erreur | uint8 | 1 paramètres invalides (cadre à l'envers par exemple), 2 plus de fenêtre libre |
Le firmware dessine le cadre : bord d'un pixel, barre de titre de 10 lignes, cases ; le programme dessine le contenu. Le cadre 20, 20, 120, 100 avec barre de titre donne le contenu 21, 31, 119, 99. Le titre est lu sur place à chaque dessin : la chaîne doit rester intacte tant que la fenêtre existe. Après chaque changement, le firmware poste un événement de mise à jour (type 9) par fenêtre visible, de l'arrière vers l'avant, puis des événements d'activation (type 10) ; au banc, la neuvième fenêtre est refusée avec l'erreur 2. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
Toolbox (Trinity, T-12, ADR-01 of the fork). 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;
}Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1Mad 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.Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1NeoBASIC
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) : returnFenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 1Assembleur 65C02 (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 0Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 134,2 Dispose Window Trinity
Retire une fenêtre de l'écran et libère son numéro.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
Sorties : aucune.
L'exemple ouvre les fenêtres 1 et 2, ferme la 1 : la 2 est devant, et la fenêtre suivante reprend le numéro 1. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1Mad 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.Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1NeoBASIC
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) : returnFenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 1Assembleur 65C02 (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 0Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 134,3 Show Window Trinity
Cache ou montre une fenêtre.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
P1 | uint8 | non nul pour montrer, 0 pour cacher |
Sorties : aucune.
Une fenêtre cachée n'est plus devant et n'est plus trouvée par 34,7. Au banc, la fenêtre montrée de nouveau reprend sa place devant. Attention à P1 : il doit être posé à chaque appel. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2Mad 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.Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2NeoBASIC
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) : returnCachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 2Assembleur 65C02 (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 0Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 234,4 Select Window Trinity
Met une fenêtre devant (et la montre).
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
Sorties : aucune.
Au point (80, 70), couvert par les deux fenêtres, 34,7 trouve la fenêtre de devant : la 2, puis la 1 une fois choisie. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1Mad 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.Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1NeoBASIC
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) : returnAvant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 1Assembleur 65C02 (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 0Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 134,5 Move Window Trinity
Déplace le coin haut gauche du cadre d'une fenêtre.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
P1-P2 | int16 | X du coin |
P3-P4 | int16 | Y du coin |
Sorties : aucune.
La taille ne change pas : le cadre de 100 × 80 posé en (150, 60) donne le contenu 151, 71, 249, 139. Le glisser de la fenêtre est à la charge du programme, à partir des événements de la souris : 34,7 dit quand la barre de titre est touchée. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Contenu : 151, 71, 249, 139 ; ancienne place : 0Mad 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.Contenu : 151, 71, 249, 139 ; ancienne place : 0NeoBASIC
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) : returnContenu : 151, 71, 249, 139 ; ancienne place : 0Assembleur 65C02 (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 0Contenu : 151, 71, 249, 139 ; ancienne place : 034,6 Size Window Trinity
Change la largeur et la hauteur du cadre d'une fenêtre.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
P1-P2 | uint16 | largeur du cadre en pixels |
P3-P4 | uint16 | hauteur du cadre en pixels (3 au moins) |
| Octets | Type | Rôle |
|---|---|---|
erreur | uint8 | 1 pour une taille trop petite |
Le coin haut gauche ne bouge pas : 50 × 40 donne le contenu 21, 31, 69, 59. Une hauteur de 2 est refusée. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1Mad 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.Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 1NeoBASIC
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) : returnContenu : 21, 31, 69, 59
Hauteur 2 : erreur 1Assembleur 65C02 (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 0Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 134,7 Find Window Trinity
Rend la fenêtre visible la plus en avant sous un point, et la partie touchée.
| Octets | Type | Rôle |
|---|---|---|
P0-P1 | int16 | X du point |
P2-P3 | int16 | Y du point |
| Octets | Type | Rôle |
|---|---|---|
P4 | uint8 | fenêtre (0 si aucune) |
P5 | uint8 | partie : 1 contenu, 2 barre de titre ou bord, 3 case de fermeture, 4 case d'agrandissement |
Relevé au banc pour le cadre 20, 20, 120, 100 : la case de fermeture occupe x 23 à 29, y 22 à 28 ; la case d'agrandissement, le coin bas droit du contenu à partir de (111, 91). NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0Mad 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.Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0NeoBASIC
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) : returnBarre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 0Assembleur 65C02 (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 0Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 034,8 Get Content Rect Trinity
Écrit le rectangle de contenu d'une fenêtre (dans le cadre, sous la barre de titre).
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
P1-P2 | addr | adresse du Rect à remplir |
Sorties : aucune.
Coordonnées de l'écran. Sans barre de titre, le contenu commence juste sous le bord d'un pixel. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99Mad 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.Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99NeoBASIC
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) : returnAvec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 99Assembleur 65C02 (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 0Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 9934,9 Set Window Title Trinity
Change le titre d'une fenêtre et redessine son cadre.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
P1-P2 | addr | adresse du titre, précédé de sa longueur (lu sur place) |
Sorties : aucune.
La barre de titre est blanche (couleur 15), le texte noir. L'exemple compte les pixels noirs de la barre, à droite de la case de fermeture : 16 pour « A », 94 pour « ABCDEF ». Il mesure tout avant d'afficher, car la console écrit dans le même plan. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Pixels du titre : A 16, ABCDEF 94Mad 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.Pixels du titre : A 16, ABCDEF 94NeoBASIC
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) : returnPixels du titre : A 16, ABCDEF 94Assembleur 65C02 (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 0Pixels du titre : A 16, ABCDEF 9434,10 Front Window Trinity
Rend la fenêtre visible la plus en avant.
Entrées : aucune.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | fenêtre (0 si aucune) |
Sans fenêtre, 0 ; la dernière ouverte est devant ; après sa fermeture, celle de dessous repasse devant. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Aucune : 0, deux : 2, apres fermeture : 1Mad 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.Aucune : 0, deux : 2, apres fermeture : 1NeoBASIC
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) : returnAucune : 0, deux : 2, apres fermeture : 1Assembleur 65C02 (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 0Aucune : 0, deux : 2, apres fermeture : 134,11 End Update Trinity
À appeler après avoir redessiné le contenu d'une fenêtre : redessine les cadres des fenêtres posées dessus.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
Sorties : aucune.
Le contenu n'est découpé que sur son propre rectangle : en le peignant, le programme écrase les cadres des fenêtres de devant qui le chevauchent. L'exemple traite les événements de mise à jour (type 9) : 34,12, peinture en couleur 4, puis 34,11. Le bord de la fenêtre 2 posé sur la fenêtre 1 passe à 4, puis redevient 15. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Bord de la fenetre 2 : avant 4, apres 15Mad 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.Bord de la fenetre 2 : avant 4, apres 15NeoBASIC
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) : returnBord de la fenetre 2 : avant 4, apres 15Assembleur 65C02 (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 0Bord de la fenetre 2 : avant 4, apres 1534,12 Set Port Trinity
Pose la découpe de QuickDraw (groupe 32) sur le contenu d'une fenêtre.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro de la fenêtre |
Sorties : aucune.
C'est le premier pas pour dessiner dans une fenêtre : tout dessin du groupe 32 reste ensuite dans le contenu. 32,3 relit la découpe : celle du contenu. NeoBASIC n'a pas de mot-clé pour cet appel.
Texte de la documentation du firmware (anglais)
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;
}Decoupe : 21, 31, 119, 99Mad 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.Decoupe : 21, 31, 119, 99NeoBASIC
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) : returnDecoupe : 21, 31, 119, 99Assembleur 65C02 (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 0Decoupe : 21, 31, 119, 99