Group 34 — Window Manager Trinity
34,1 New Window · 34,2 Dispose Window · 34,3 Show Window · 34,4 Select Window · 34,5 Move Window · 34,6 Size Window · 34,7 Find Window · 34,8 Get Content Rect · 34,9 Set Window Title · 34,10 Front Window · 34,11 End Update · 34,12 Set Port
The window manager of the Trinity toolbox holds up to 8 windows, numbered 1 to 8. The firmware draws the frames; the program draws the contents with QuickDraw (group 32).
After each change (opening, closing, moving...), the firmware erases the visible contents, repaints the frames and posts one update event (group 33, type 9) per visible window. To answer it: 34,12 (Set Port), drawing with group 32, then 34,11 (End Update).
The examples reset the toolbox with 32,19 at the start and at the end: it keeps its state from one program to the next.
34,1 New Window Trinity
Creates a visible window, brings it to the front and returns its number.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | addr | address of the frame Rect (screen coordinates) |
P2-P3 | addr | address of the title, preceded by its length (read in place) |
P4 | uint8 | flags: bit 0 title bar, bit 1 close box, bit 2 grow box |
| Bytes | Type | Meaning |
|---|---|---|
P5 | uint8 | window number (1 to 8) |
erreur | uint8 | 1 bad parameters (inverted frame for instance), 2 no window left |
The firmware draws the frame: one-pixel border, 10-line title bar, boxes; the program draws the content. Frame 20, 20, 120, 100 with a title bar gives the content 21, 31, 119, 99. The title is read in place at each drawing: the string must stay intact while the window exists. After each change, the firmware posts one update event (type 9) per visible window, back to front, then activate events (type 10); on the bench, the ninth window is refused with error 2. NeoBASIC has no keyword for this call.
Firmware documentation text
Toolbox (Trinity, T-12, ADR-01 of the fork). Creates a visible window whose frame is the Rect at Parameters:0,1 (screen coordinates, see group 32) with the length-prefixed title at Parameters:2,3 (up to 255 characters, read in place : the program keeps the string intact while the window exists ; T-21) and the flags of Parameter:4 (bit 0 title bar, bit 1 close box, bit 2 grow box) ; returns its number (1-8) in Parameter:5, or an error (1 bad parameters, 2 no window left). The new window comes to the front. The firmware draws the frames (1 pixel border, 10 line title bar, close box, grow box) ; the content is drawn by the program : after every change of the window set the firmware erases the visible contents, repaints the frames and posts one update event (group 33, type 9) per visible window, back to front, and activate events (type 10). To handle an update : Set Port (34,12), draw with group 32, then End Update (34,11).
C (llvm-mos)
/* Ouvrir une fenêtre (groupe 34, fonction 1, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect cadre = {20, 20, 120, 100}, envers = {120, 20, 20, 100}, c;
static const char titre[] = "\005Essai";
int main(void) {
uint8_t w, e;
reinit();
w = nouvelle(&cadre, titre, 7); /* barre de titre, fermeture, agrandissement */
contenu(w, &c);
nouvelle(&envers, titre, 7); /* droite avant gauche : refusé */
e = ControlPort.error;
reinit();
printf("Fenetre : %u, contenu : %d, %d, %d, %d\n", w, c.g, c.h, c.d, c.b);
printf("Cadre a l'envers : erreur %u\n", e);
return 0;
}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 165C02 assembly (64tass)
; Ouvrir une fenêtre (groupe 34, fonction 1, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta w
jsr WaitMessage
lda w
sta ControlPort+4
lda #<c
sta ControlPort+5 ; P1-P2 : adresse du Rect
lda #>c
sta ControlPort+6
lda #34
ldx #8 ; 34,8 : Get Content Rect
jsr appel
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+2
sta e
lda #<b3
ldx #>b3
jsr envoi
lda #<t4
ldx #>t4
jsr ecrire
lda w
jsr decimal
lda #<t5
ldx #>t5
jsr ecrire
lda c
ldx c+1
jsr dec16
lda #<t6
ldx #>t6
jsr ecrire
lda c+2
ldx c+2+1
jsr dec16
lda #<t7
ldx #>t7
jsr ecrire
lda c+4
ldx c+4+1
jsr dec16
lda #<t8
ldx #>t8
jsr ecrire
lda c+6
ldx c+6+1
jsr dec16
lda #13
jsr WriteCharacter
lda #<t9
ldx #>t9
jsr ecrire
lda e
jsr decimal
lda #13
jsr WriteCharacter
rts
cadre: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
envers: .word 120, 20, 20, 100 ; gauche, haut, droite, bas (droite et bas exclus)
c: .fill 8
essai: .byte 5
.text "Essai" ; chaîne précédée de sa longueur, lue sur place
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : barre de titre, fermeture, agrandissement
.word cadre, essai
.byte 7
w: .byte 0
b2: .byte 34, 1, 5 ; droite avant gauche : refusé
.word envers, essai
.byte 7
e: .byte 0
b3: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t4: .text "Fenetre : ", 0
t5: .text ", contenu : ", 0
t6: .text ", ", 0
t7: .text ", ", 0
t8: .text ", ", 0
t9: .text "Cadre a l'envers : erreur ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Fenetre : 1, contenu : 21, 31, 119, 99
Cadre a l'envers : erreur 134,2 Dispose Window Trinity
Removes a window from the screen and frees its number.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
Outputs: none.
The example opens windows 1 and 2, closes 1: 2 is in front, and the next window takes number 1 again. NeoBASIC has no keyword for this call.
Firmware documentation text
Removes window Parameter:0 from the screen and frees its number.
C (llvm-mos)
/* Fermer une fenêtre (groupe 34, fonction 2, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";
int main(void) {
uint8_t a, b, d, c;
reinit();
a = nouvelle(&r1, titre, 1);
b = nouvelle(&r2, titre, 1);
fenetre(2, a); /* Dispose Window : son numéro est libéré */
d = devant();
c = nouvelle(&r1, titre, 1);
reinit();
printf("Fenetres %u et %u ; apres fermeture de %u : devant %u\n", a, b, a, d);
printf("Nouvelle fenetre : %u\n", c);
return 0;
}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 : 165C02 assembly (64tass)
; Fermer une fenêtre (groupe 34, fonction 2, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta b
lda a
ldx #2 ; Dispose Window : son numéro est libéré
jsr fen
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d
lda #<b3
ldx #>b3
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta n
lda #<b4
ldx #>b4
jsr envoi
lda #<t5
ldx #>t5
jsr ecrire
lda a
jsr decimal
lda #<t6
ldx #>t6
jsr ecrire
lda b
jsr decimal
lda #<t7
ldx #>t7
jsr ecrire
lda a
jsr decimal
lda #<t8
ldx #>t8
jsr ecrire
lda d
jsr decimal
lda #13
jsr WriteCharacter
lda #<t9
ldx #>t9
jsr ecrire
lda n
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
r2: .word 60, 50, 200, 150 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 34, 1, 5 ; 34,1 : New Window
.word r2, titre
.byte 1
b: .byte 0
d: .byte 0
b3: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
n: .byte 0
b4: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t5: .text "Fenetres ", 0
t6: .text " et ", 0
t7: .text " ; apres fermeture de ", 0
t8: .text " : devant ", 0
t9: .text "Nouvelle fenetre : ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Fenetres 1 et 2 ; apres fermeture de 1 : devant 2
Nouvelle fenetre : 134,3 Show Window Trinity
Hides or shows a window.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
P1 | uint8 | non zero to show, 0 to hide |
Outputs: none.
A hidden window is no longer in front and is no longer found by 34,7. On the bench, the window shown again takes back its place in front. Mind P1: it must be set at each call. NeoBASIC has no keyword for this call.
Firmware documentation text
Shows (Parameter:1 non zero) or hides window Parameter:0.
C (llvm-mos)
/* Cacher ou montrer une fenêtre (groupe 34, fonction 3, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) { /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
libre();
p16(0, x);
p16(2, y);
api(34, 7);
zone = ControlPort.params[5]; /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
return ControlPort.params[4];
}
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";
static void montrer(uint8_t w, uint8_t oui) { /* Show Window : P1 non nul montre, 0 cache */
libre();
ControlPort.params[0] = w;
ControlPort.params[1] = oui;
api(34, 3);
}
int main(void) {
uint8_t b, d1, t1, d2, t2;
reinit();
nouvelle(&r1, titre, 1);
b = nouvelle(&r2, titre, 1);
montrer(b, 0);
d1 = devant();
t1 = trouver(150, 120); /* point couvert par la seule fenêtre 2 */
montrer(b, 1);
d2 = devant();
t2 = trouver(150, 120);
reinit();
printf("Cachee : devant %u, en (150, 120) : %u\n", d1, t1);
printf("Montree : devant %u, en (150, 120) : %u\n", d2, t2);
return 0;
}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) : 265C02 assembly (64tass)
; Cacher ou montrer une fenêtre (groupe 34, fonction 3, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta b
jsr WaitMessage
lda #0
sta ControlPort+5 ; P1 : 0 cache
lda b
ldx #3 ; Show Window
jsr fen
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d1
lda #<b3
ldx #>b3
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta t1
lda ControlPort+9 ; P5 : zone
sta z
jsr WaitMessage
lda #1
sta ControlPort+5 ; P1 : non nul montre
lda b
ldx #3 ; Show Window
jsr fen
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d2
lda #<b4
ldx #>b4
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta t2
lda ControlPort+9 ; P5 : zone
sta z
lda #<b5
ldx #>b5
jsr envoi
lda #<t6
ldx #>t6
jsr ecrire
lda d1
jsr decimal
lda #<t7
ldx #>t7
jsr ecrire
lda t1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t8
ldx #>t8
jsr ecrire
lda d2
jsr decimal
lda #<t9
ldx #>t9
jsr ecrire
lda t2
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
r2: .word 60, 50, 200, 150 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
t1: .byte 0
t2: .byte 0
z: .byte 0
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
b2: .byte 34, 1, 5 ; 34,1 : New Window
.word r2, titre
.byte 1
b: .byte 0
d1: .byte 0
b3: .byte 34, 7, 4 ; 34,7 : Find Window
.word 150, 120
d2: .byte 0
b4: .byte 34, 7, 4 ; 34,7 : Find Window
.word 150, 120
b5: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t6: .text "Cachee : devant ", 0
t7: .text ", en (150, 120) : ", 0
t8: .text "Montree : devant ", 0
t9: .text ", en (150, 120) : ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Cachee : devant 1, en (150, 120) : 0
Montree : devant 2, en (150, 120) : 234,4 Select Window Trinity
Brings a window to the front (and shows it).
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
Outputs: none.
At point (80, 70), covered by both windows, 34,7 finds the front window: 2, then 1 once selected. NeoBASIC has no keyword for this call.
Firmware documentation text
Brings window Parameter:0 to the front (and shows it).
C (llvm-mos)
/* Mettre une fenêtre devant (groupe 34, fonction 4, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) { /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
libre();
p16(0, x);
p16(2, y);
api(34, 7);
zone = ControlPort.params[5]; /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
return ControlPort.params[4];
}
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";
int main(void) {
uint8_t a, d1, t1, d2, t2;
reinit();
a = nouvelle(&r1, titre, 1);
nouvelle(&r2, titre, 1);
d1 = devant();
t1 = trouver(80, 70); /* point couvert par les deux fenêtres */
fenetre(4, a); /* Select Window */
d2 = devant();
t2 = trouver(80, 70);
reinit();
printf("Avant : devant %u, en (80, 70) : %u\n", d1, t1);
printf("Apres : devant %u, en (80, 70) : %u\n", d2, t2);
return 0;
}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) : 165C02 assembly (64tass)
; Mettre une fenêtre devant (groupe 34, fonction 4, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
lda #<b2
ldx #>b2
jsr envoi
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d1
lda #<b3
ldx #>b3
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta t1
lda ControlPort+9 ; P5 : zone
sta z
lda a
ldx #4 ; Select Window
jsr fen
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d2
lda #<b4
ldx #>b4
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta t2
lda ControlPort+9 ; P5 : zone
sta z
lda #<b5
ldx #>b5
jsr envoi
lda #<t6
ldx #>t6
jsr ecrire
lda d1
jsr decimal
lda #<t7
ldx #>t7
jsr ecrire
lda t1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t8
ldx #>t8
jsr ecrire
lda d2
jsr decimal
lda #<t9
ldx #>t9
jsr ecrire
lda t2
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
r2: .word 60, 50, 200, 150 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
t1: .byte 0
t2: .byte 0
z: .byte 0
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 34, 1, 5 ; 34,1 : New Window
.word r2, titre
.byte 1
d1: .byte 0
b3: .byte 34, 7, 4 ; 34,7 : Find Window
.word 80, 70
d2: .byte 0
b4: .byte 34, 7, 4 ; 34,7 : Find Window
.word 80, 70
b5: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t6: .text "Avant : devant ", 0
t7: .text ", en (80, 70) : ", 0
t8: .text "Apres : devant ", 0
t9: .text ", en (80, 70) : ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Avant : devant 2, en (80, 70) : 2
Apres : devant 1, en (80, 70) : 134,5 Move Window Trinity
Moves the top left corner of a window frame.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
P1-P2 | int16 | corner X |
P3-P4 | int16 | corner Y |
Outputs: none.
The size does not change: the 100 × 80 frame put at (150, 60) gives the content 151, 71, 249, 139. Dragging the window is up to the program, from mouse events: 34,7 tells when the title bar is hit. NeoBASIC has no keyword for this call.
Firmware documentation text
Moves the top left corner of the frame of window Parameter:0 to Parameters:1,2 (X) and Parameters:3,4 (Y). Dragging is done by the program from mouse events : Find Window says when the title bar is hit.
C (llvm-mos)
/* Déplacer une fenêtre (groupe 34, fonction 5, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) { /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
libre();
p16(0, x);
p16(2, y);
api(34, 7);
zone = ControlPort.params[5]; /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
return ControlPort.params[4];
}
static Rect r1 = {20, 20, 120, 100}, c;
static const char titre[] = "\001A";
int main(void) {
uint8_t a, t;
reinit();
a = nouvelle(&r1, titre, 1);
libre();
ControlPort.params[0] = a;
p16(1, 150); /* Move Window : nouveau coin haut gauche du cadre */
p16(3, 60);
api(34, 5);
contenu(a, &c);
t = trouver(50, 60); /* l'ancienne place est libre */
reinit();
printf("Contenu : %d, %d, %d, %d ; ancienne place : %u\n", c.g, c.h, c.d, c.b, t);
return 0;
}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 : 065C02 assembly (64tass)
; Déplacer une fenêtre (groupe 34, fonction 5, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
jsr WaitMessage
lda #150 ; Move Window : nouveau coin haut gauche du cadre (X = 150...
sta ControlPort+5
stz ControlPort+6
lda #60 ; ... Y = 60)
sta ControlPort+7
stz ControlPort+8
lda a
ldx #5
jsr fen
jsr WaitMessage
lda a
sta ControlPort+4
lda #<c
sta ControlPort+5 ; P1-P2 : adresse du Rect
lda #>c
sta ControlPort+6
lda #34
ldx #8 ; 34,8 : Get Content Rect
jsr appel
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta t
lda ControlPort+9 ; P5 : zone
sta z
; l'ancienne place est libre
lda #<b3
ldx #>b3
jsr envoi
lda #<t4
ldx #>t4
jsr ecrire
lda c
ldx c+1
jsr dec16
lda #<t5
ldx #>t5
jsr ecrire
lda c+2
ldx c+2+1
jsr dec16
lda #<t6
ldx #>t6
jsr ecrire
lda c+4
ldx c+4+1
jsr dec16
lda #<t7
ldx #>t7
jsr ecrire
lda c+6
ldx c+6+1
jsr dec16
lda #<t8
ldx #>t8
jsr ecrire
lda t
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
c: .fill 8
t: .byte 0
z: .byte 0
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 34, 7, 4 ; 34,7 : Find Window
.word 50, 60
b3: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t4: .text "Contenu : ", 0
t5: .text ", ", 0
t6: .text ", ", 0
t7: .text ", ", 0
t8: .text " ; ancienne place : ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Contenu : 151, 71, 249, 139 ; ancienne place : 034,6 Size Window Trinity
Changes the width and height of a window frame.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
P1-P2 | uint16 | frame width in pixels |
P3-P4 | uint16 | frame height in pixels (3 at least) |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 for a size too small |
The top left corner does not move: 50 × 40 gives the content 21, 31, 69, 59. A height of 2 is refused. NeoBASIC has no keyword for this call.
Firmware documentation text
Sets the frame of window Parameter:0 to Parameters:1,2 pixels wide and Parameters:3,4 high (3 at least).
C (llvm-mos)
/* Changer la taille d'une fenêtre (groupe 34, fonction 6, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect r1 = {20, 20, 120, 100}, c;
static const char titre[] = "\001A";
static uint8_t taille(uint8_t w, uint16_t l, uint16_t h) { /* Size Window : largeur, hauteur du cadre */
libre();
ControlPort.params[0] = w;
p16(1, l);
p16(3, h);
api(34, 6);
return ControlPort.error;
}
int main(void) {
uint8_t a, e;
reinit();
a = nouvelle(&r1, titre, 1);
taille(a, 50, 40);
contenu(a, &c);
e = taille(a, 50, 2); /* moins de 3 : refusé */
reinit();
printf("Contenu : %d, %d, %d, %d\n", c.g, c.h, c.d, c.b);
printf("Hauteur 2 : erreur %u\n", e);
return 0;
}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 165C02 assembly (64tass)
; Changer la taille d'une fenêtre (groupe 34, fonction 6, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
jsr WaitMessage
lda #50 ; Size Window : largeur 50...
sta ControlPort+5
stz ControlPort+6
lda #40 ; ... hauteur 40
sta ControlPort+7
stz ControlPort+8
lda a
ldx #6
jsr fen
jsr WaitMessage
lda a
sta ControlPort+4
lda #<c
sta ControlPort+5 ; P1-P2 : adresse du Rect
lda #>c
sta ControlPort+6
lda #34
ldx #8 ; 34,8 : Get Content Rect
jsr appel
jsr WaitMessage
lda #50 ; Size Window : largeur 50...
sta ControlPort+5
stz ControlPort+6
lda #2 ; ... hauteur 2 : moins de 3, refusé
sta ControlPort+7
stz ControlPort+8
lda a
ldx #6
jsr fen
sta e
lda #<b2
ldx #>b2
jsr envoi
lda #<t3
ldx #>t3
jsr ecrire
lda c
ldx c+1
jsr dec16
lda #<t4
ldx #>t4
jsr ecrire
lda c+2
ldx c+2+1
jsr dec16
lda #<t5
ldx #>t5
jsr ecrire
lda c+4
ldx c+4+1
jsr dec16
lda #<t6
ldx #>t6
jsr ecrire
lda c+6
ldx c+6+1
jsr dec16
lda #13
jsr WriteCharacter
lda #<t7
ldx #>t7
jsr ecrire
lda e
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
c: .fill 8
e: .byte 0
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t3: .text "Contenu : ", 0
t4: .text ", ", 0
t5: .text ", ", 0
t6: .text ", ", 0
t7: .text "Hauteur 2 : erreur ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Contenu : 21, 31, 69, 59
Hauteur 2 : erreur 134,7 Find Window Trinity
Returns the frontmost visible window under a point, and the part hit.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | int16 | point X |
P2-P3 | int16 | point Y |
| Bytes | Type | Meaning |
|---|---|---|
P4 | uint8 | window (0 if none) |
P5 | uint8 | part: 1 content, 2 title bar or border, 3 close box, 4 grow box |
Measured on the bench for frame 20, 20, 120, 100: the close box covers x 23 to 29, y 22 to 28; the grow box, the bottom right corner of the content from (111, 91). NeoBASIC has no keyword for this call.
Firmware documentation text
Returns in Parameter:4 the frontmost visible window under the point Parameters:0,1 (X), Parameters:2,3 (Y) (0 if none) and in Parameter:5 the part hit : 1 content, 2 title bar or border (drag), 3 close box, 4 grow box.
C (llvm-mos)
/* Trouver la fenêtre sous un point (groupe 34, fonction 7, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t zone;
static uint8_t trouver(int16_t x, int16_t y) { /* 34,7 Find Window : fenêtre sous le point, zone dans « zone » */
libre();
p16(0, x);
p16(2, y);
api(34, 7);
zone = ControlPort.params[5]; /* 1 contenu, 2 barre ou bord, 3 fermeture, 4 agrandissement */
return ControlPort.params[4];
}
static Rect r1 = {20, 20, 120, 100};
static const char titre[] = "\001A";
static const int16_t px[5] = {50, 50, 25, 115, 5}, py[5] = {25, 60, 25, 95, 5};
static const char *nom[5] = {"Barre de titre", "Contenu", "Fermeture", "Agrandissement", "Dehors"};
int main(void) {
uint8_t i, w[5], z[5];
reinit();
nouvelle(&r1, titre, 7); /* barre de titre, fermeture, agrandissement */
for (i = 0; i < 5; i++) {
w[i] = trouver(px[i], py[i]);
z[i] = zone;
}
reinit();
for (i = 0; i < 5; i++)
printf("%s : %u, %u\n", nom[i], w[i], z[i]);
return 0;
}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, 065C02 assembly (64tass)
; Trouver la fenêtre sous un point (groupe 34, fonction 7, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta w0
lda ControlPort+9 ; P5 : zone
sta z0
lda #<b3
ldx #>b3
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta w1
lda ControlPort+9 ; P5 : zone
sta z1
lda #<b4
ldx #>b4
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta w2
lda ControlPort+9 ; P5 : zone
sta z2
lda #<b5
ldx #>b5
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta w3
lda ControlPort+9 ; P5 : zone
sta z3
lda #<b6
ldx #>b6
jsr envoi
lda ControlPort+8 ; P4 : fenêtre
sta w4
lda ControlPort+9 ; P5 : zone
sta z4
lda #<b7
ldx #>b7
jsr envoi
lda #<t8
ldx #>t8
jsr ecrire
lda w0
jsr decimal
lda #<t9
ldx #>t9
jsr ecrire
lda z0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t10
ldx #>t10
jsr ecrire
lda w1
jsr decimal
lda #<t11
ldx #>t11
jsr ecrire
lda z1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t12
ldx #>t12
jsr ecrire
lda w2
jsr decimal
lda #<t13
ldx #>t13
jsr ecrire
lda z2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t14
ldx #>t14
jsr ecrire
lda w3
jsr decimal
lda #<t15
ldx #>t15
jsr ecrire
lda z3
jsr decimal
lda #13
jsr WriteCharacter
lda #<t16
ldx #>t16
jsr ecrire
lda w4
jsr decimal
lda #<t17
ldx #>t17
jsr ecrire
lda z4
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : barre de titre, fermeture, agrandissement
.word r1, titre
.byte 7
w0: .byte 0
z0: .byte 0
b2: .byte 34, 7, 4 ; 34,7 : Find Window
.word 50, 25
w1: .byte 0
z1: .byte 0
b3: .byte 34, 7, 4 ; 34,7 : Find Window
.word 50, 60
w2: .byte 0
z2: .byte 0
b4: .byte 34, 7, 4 ; 34,7 : Find Window
.word 25, 25
w3: .byte 0
z3: .byte 0
b5: .byte 34, 7, 4 ; 34,7 : Find Window
.word 115, 95
w4: .byte 0
z4: .byte 0
b6: .byte 34, 7, 4 ; 34,7 : Find Window
.word 5, 5
b7: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t8: .text "Barre de titre : ", 0
t9: .text ", ", 0
t10: .text "Contenu : ", 0
t11: .text ", ", 0
t12: .text "Fermeture : ", 0
t13: .text ", ", 0
t14: .text "Agrandissement : ", 0
t15: .text ", ", 0
t16: .text "Dehors : ", 0
t17: .text ", ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Barre de titre : 1, 2
Contenu : 1, 1
Fermeture : 1, 3
Agrandissement : 1, 4
Dehors : 0, 034,8 Get Content Rect Trinity
Writes the content rectangle of a window (inside the frame, below the title bar).
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
P1-P2 | addr | address of the Rect to fill |
Outputs: none.
Screen coordinates. Without a title bar, the content starts just below the one-pixel border. NeoBASIC has no keyword for this call.
Firmware documentation text
Writes the content rectangle of window Parameter:0 (screen coordinates, inside the frame and below the title bar) into the Rect at Parameters:1,2.
C (llvm-mos)
/* Lire le rectangle de contenu (groupe 34, fonction 8, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect r1 = {20, 20, 120, 100}, c1, c2;
static const char titre[] = "\001A";
int main(void) {
reinit();
contenu(nouvelle(&r1, titre, 1), &c1); /* avec barre de titre */
contenu(nouvelle(&r1, titre, 0), &c2); /* même cadre, sans barre */
reinit();
printf("Avec barre de titre : %d, %d, %d, %d\n", c1.g, c1.h, c1.d, c1.b);
printf("Sans : %d, %d, %d, %d\n", c2.g, c2.h, c2.d, c2.b);
return 0;
}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, 9965C02 assembly (64tass)
; Lire le rectangle de contenu (groupe 34, fonction 8, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
jsr WaitMessage
lda a
sta ControlPort+4
lda #<c1
sta ControlPort+5 ; P1-P2 : adresse du Rect
lda #>c1
sta ControlPort+6
lda #34
ldx #8 ; 34,8 : Get Content Rect
jsr appel
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta b
jsr WaitMessage
lda b
sta ControlPort+4
lda #<c2
sta ControlPort+5 ; P1-P2 : adresse du Rect
lda #>c2
sta ControlPort+6
lda #34
ldx #8 ; 34,8 : Get Content Rect
jsr appel
lda #<b3
ldx #>b3
jsr envoi
lda #<t4
ldx #>t4
jsr ecrire
lda c1
ldx c1+1
jsr dec16
lda #<t5
ldx #>t5
jsr ecrire
lda c1+2
ldx c1+2+1
jsr dec16
lda #<t6
ldx #>t6
jsr ecrire
lda c1+4
ldx c1+4+1
jsr dec16
lda #<t7
ldx #>t7
jsr ecrire
lda c1+6
ldx c1+6+1
jsr dec16
lda #13
jsr WriteCharacter
lda #<t8
ldx #>t8
jsr ecrire
lda c2
ldx c2+1
jsr dec16
lda #<t9
ldx #>t9
jsr ecrire
lda c2+2
ldx c2+2+1
jsr dec16
lda #<t10
ldx #>t10
jsr ecrire
lda c2+4
ldx c2+4+1
jsr dec16
lda #<t11
ldx #>t11
jsr ecrire
lda c2+6
ldx c2+6+1
jsr dec16
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
c1: .fill 8
c2: .fill 8
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : avec barre de titre
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 34, 1, 5 ; même cadre, sans barre
.word r1, titre
.byte 0
b: .byte 0
b3: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t4: .text "Avec barre de titre : ", 0
t5: .text ", ", 0
t6: .text ", ", 0
t7: .text ", ", 0
t8: .text "Sans : ", 0
t9: .text ", ", 0
t10: .text ", ", 0
t11: .text ", ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Avec barre de titre : 21, 31, 119, 99
Sans : 21, 21, 119, 9934,9 Set Window Title Trinity
Changes the title of a window and repaints its frame.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
P1-P2 | addr | address of the title, preceded by its length (read in place) |
Outputs: none.
The title bar is white (colour 15), the text black. The example counts the black pixels of the bar, to the right of the close box: 16 for "A", 94 for "ABCDEF". It measures everything before printing, as the console writes to the same plane. NeoBASIC has no keyword for this call.
Firmware documentation text
Changes the title of window Parameter:0 to the length-prefixed string at Parameters:1,2 (read in place, see New Window) and repaints its frame.
C (llvm-mos)
/* Changer le titre d'une fenêtre (groupe 34, fonction 9, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t pixel(int16_t x, int16_t y) { /* 5,33 : couleur du fond en (x, y) */
libre();
p16(0, x);
p16(2, y);
api(5, 33);
return ControlPort.params[0];
}
static Rect r1 = {20, 20, 120, 100};
static const char court[] = "\001A", long_[] = "\006ABCDEF";
static uint16_t noirs(void) { /* pixels noirs du titre (après la case de fermeture) */
int16_t x, y;
uint16_t n = 0;
for (y = 22; y < 29; y++)
for (x = 31; x < 119; x++)
if (pixel(x, y) == 0)
n++;
return n;
}
int main(void) {
uint8_t a;
uint16_t n1, n2;
putchar(12); /* écran effacé : on relit des pixels */
reinit();
a = nouvelle(&r1, court, 3);
n1 = noirs();
libre();
ControlPort.params[0] = a;
p16(1, (uint16_t)long_); /* Set Window Title : chaîne lue sur place */
api(34, 9);
n2 = noirs();
reinit();
printf("Pixels du titre : A %u, ABCDEF %u\n", n1, n2);
return 0;
}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 9465C02 assembly (64tass)
; Changer le titre d'une fenêtre (groupe 34, fonction 9, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
jsr noirs
lda nb
sta n1
lda nb+1
sta n1+1
jsr WaitMessage
lda #<long
sta ControlPort+5 ; P1-P2 : nouveau titre, lu sur place
lda #>long
sta ControlPort+6
lda a
ldx #9 ; Set Window Title
jsr fen
jsr noirs
lda nb
sta n2
lda nb+1
sta n2+1
lda #<b2
ldx #>b2
jsr envoi
lda #<t3
ldx #>t3
jsr ecrire
lda n1
ldx n1+1
jsr dec16
lda #<t4
ldx #>t4
jsr ecrire
lda n2
ldx n2+1
jsr dec16
lda #13
jsr WriteCharacter
rts
; Pixels noirs du titre (après la case de fermeture) : x 31 à 118, y 22 à 28, dans nb.
noirs: stz nb
stz nb+1
lda #22
sta yy
_y: lda #31
sta xx
_x: lda xx
ldy yy
jsr pixel
cmp #0
bne _nx
inc nb
bne _nx
inc nb+1
_nx: inc xx
lda xx
cmp #119
bne _x
inc yy
lda yy
cmp #29
bne _y
rts
; Couleur du fond (5,33) en (A, Y), X et Y inférieurs à 256, rendue dans A.
pixel: pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
long: .byte 6
.text "ABCDEF"
nb: .word 0
xx: .byte 0
yy: .byte 0
n1: .fill 2
n2: .fill 2
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 3
a: .byte 0
b2: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t3: .text "Pixels du titre : A ", 0
t4: .text ", ABCDEF ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Pixels du titre : A 16, ABCDEF 9434,10 Front Window Trinity
Returns the frontmost visible window.
Inputs: none.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window (0 if none) |
Without windows, 0; the last one opened is in front; once it is closed, the one below comes back to the front. NeoBASIC has no keyword for this call.
Firmware documentation text
Returns the frontmost visible window in Parameter:0 (0 if none).
C (llvm-mos)
/* Savoir quelle fenêtre est devant (groupe 34, fonction 10, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150};
static const char titre[] = "\001A";
int main(void) {
uint8_t b, d0, d2, d1;
reinit();
d0 = devant(); /* Front Window : 0 sans fenêtre */
nouvelle(&r1, titre, 1);
b = nouvelle(&r2, titre, 1);
d2 = devant();
fenetre(2, b);
d1 = devant();
reinit();
printf("Aucune : %u, deux : %u, apres fermeture : %u\n", d0, d2, d1);
return 0;
}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 : 165C02 assembly (64tass)
; Savoir quelle fenêtre est devant (groupe 34, fonction 10, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d0
lda #<b1
ldx #>b1
jsr envoi
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta b
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d2
lda b
ldx #2 ; 34,2
jsr fen
lda #0
ldx #10 ; 34,10 : Front Window
jsr fen
lda ControlPort+4
sta d1
lda #<b3
ldx #>b3
jsr envoi
lda #<t4
ldx #>t4
jsr ecrire
lda d0
jsr decimal
lda #<t5
ldx #>t5
jsr ecrire
lda d2
jsr decimal
lda #<t6
ldx #>t6
jsr ecrire
lda d1
jsr decimal
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
r2: .word 60, 50, 200, 150 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
d0: .byte 0
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
b2: .byte 34, 1, 5 ; 34,1 : New Window
.word r2, titre
.byte 1
b: .byte 0
d2: .byte 0
d1: .byte 0
b3: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t4: .text "Aucune : ", 0
t5: .text ", deux : ", 0
t6: .text ", apres fermeture : ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Aucune : 0, deux : 2, apres fermeture : 134,11 End Update Trinity
To call after redrawing the content of a window: repaints the frames of the windows above it.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
Outputs: none.
The content is clipped to its own rectangle only: while painting it, the program overwrites the frames of the front windows that overlap it. The example handles the update events (type 9): 34,12, painting in colour 4, then 34,11. The border of window 2 lying on window 1 turns 4, then goes back to 15. NeoBASIC has no keyword for this call.
Firmware documentation text
To call after redrawing the content of window Parameter:0 : repaints the frames of the windows above it, which the content drawing may have overwritten (contents are clipped to the content rectangle only).
C (llvm-mos)
/* Terminer le dessin d'une fenêtre (groupe 34, fonction 11, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static uint8_t pixel(int16_t x, int16_t y) { /* 5,33 : couleur du fond en (x, y) */
libre();
p16(0, x);
p16(2, y);
api(5, 33);
return ControlPort.params[0];
}
typedef struct { uint8_t what, message, message2, modifiers; int16_t x, y; } EventRecord;
static EventRecord ev;
static Rect r1 = {20, 20, 120, 100}, r2 = {60, 50, 200, 150}, ecran = {0, 0, 320, 240};
static const char titre[] = "\001A";
int main(void) {
uint8_t a, avant = 0, apres = 0;
putchar(12);
reinit();
libre(); p16(0, 0); api(33, 1); /* 33,1 : file d'événements */
a = nouvelle(&r1, titre, 1);
nouvelle(&r2, titre, 1); /* la fenêtre 2 couvre un coin de la 1 */
for (;;) { /* événements de mise à jour (type 9), de l'arrière vers l'avant */
libre(); p16(0, (uint16_t)&ev); p16(2, 0x100); api(33, 2);
if (!ControlPort.params[4])
break;
fenetre(12, ev.message); /* 34,12 Set Port : découpe sur le contenu */
libre(); ControlPort.params[0] = 4; api(32, 4);
libre(); p16(0, (uint16_t)&ecran); api(32, 8); /* peint tout le contenu en couleur 4 */
if (ev.message == a)
avant = pixel(80, 50); /* bord haut de la fenêtre 2, dans le contenu de la 1 */
fenetre(11, ev.message); /* End Update : repeint les cadres des fenêtres au-dessus */
if (ev.message == a)
apres = pixel(80, 50);
}
reinit();
printf("Bord de la fenetre 2 : avant %u, apres %u\n", avant, apres);
return 0;
}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 1565C02 assembly (64tass)
; Terminer le dessin d'une fenêtre (groupe 34, fonction 11, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda #<b2
ldx #>b2
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
lda #<b3
ldx #>b3
jsr envoi
_ev: lda #<b4
ldx #>b4
jsr envoi
lda ControlPort+8
beq _fini
lda ev+1 ; message : la fenêtre à redessiner
ldx #12 ; 34,12 Set Port : découpe sur le contenu
jsr fen
lda #<b5
ldx #>b5
jsr envoi
lda #<b6
ldx #>b6
jsr envoi
lda ev+1
cmp a
bne _maj
lda #80 ; bord haut de la fenêtre 2, dans le contenu de la 1
ldy #50
jsr pixel
sta av
_maj: lda ev+1
ldx #11 ; End Update : repeint les cadres des fenêtres au-dessus
jsr fen
lda ev+1
cmp a
bne _ev
lda #80
ldy #50
jsr pixel
sta ap
bra _ev
_fini:
lda #<b7
ldx #>b7
jsr envoi
lda #<t8
ldx #>t8
jsr ecrire
lda av
jsr decimal
lda #<t9
ldx #>t9
jsr ecrire
lda ap
jsr decimal
lda #13
jsr WriteCharacter
rts
; Couleur du fond (5,33) en (A, Y), X et Y inférieurs à 256, rendue dans A.
pixel: pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
r2: .word 60, 50, 200, 150 ; gauche, haut, droite, bas (droite et bas exclus)
ecran: .word 0, 0, 320, 240 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
ev: .fill 8 ; EventRecord : type, message, message2, modificateurs, X, Y
av: .byte 0
ap: .byte 0
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 33, 1, 2 ; 33,1 : file d'événements
.word 0
b2: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b3: .byte 34, 1, 5 ; la fenêtre 2 couvre un coin de la 1
.word r2, titre
.byte 1
b4: .byte 33, 2, 4 ; 33,2 : mises à jour (type 9), de l'arrière vers l'avant
.word ev, $100
b5: .byte 32, 4, 1, 4 ; 32,4 : couleur 4
b6: .byte 32, 8, 2 ; 32,8 : peint tout le contenu
.word ecran
b7: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t8: .text "Bord de la fenetre 2 : avant ", 0
t9: .text ", apres ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Bord de la fenetre 2 : avant 4, apres 1534,12 Set Port Trinity
Sets the QuickDraw clip (group 32) to the content of a window.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | window number |
Outputs: none.
It is the first step to draw in a window: any drawing of group 32 then stays inside the content. 32,3 reads back the clip: that of the content. NeoBASIC has no keyword for this call.
Firmware documentation text
Sets the QuickDraw clip rectangle (group 32) to the content rectangle of window Parameter:0.
C (llvm-mos)
/* Dessiner dans une fenêtre (groupe 34, fonction 12, Trinity). */
#include <stdio.h>
#include <neo6502.h>
#include <neo/api.h>
/* Appel brut de la boîte aux lettres : fonction puis groupe (écrit en dernier, il lance l'appel). */
static void api(uint8_t groupe, uint8_t fonction) {
ControlPort.function = fonction;
ControlPort.command = groupe;
while (ControlPort.command) /* attendre la fin */
;
}
static void libre(void) { /* attendre que la boîte aux lettres soit libre */
while (ControlPort.command)
;
}
/* Rect de QuickDraw : gauche, haut, droite, bas (16 bits signés ; droite et bas exclus). */
typedef struct { int16_t g, h, d, b; } Rect;
static void p16(uint8_t i, uint16_t v) { /* paramètre 16 bits en Pi, Pi+1 */
ControlPort.params[i] = v & 0xFF;
ControlPort.params[i + 1] = v >> 8;
}
static uint8_t nouvelle(Rect *cadre, const char *titre, uint8_t options) { /* 34,1 New Window : rend le numéro */
libre();
p16(0, (uint16_t)cadre);
p16(2, (uint16_t)titre); /* chaîne précédée de sa longueur, lue sur place */
ControlPort.params[4] = options; /* bit 0 barre de titre, bit 1 fermeture, bit 2 agrandissement */
api(34, 1);
return ControlPort.params[5];
}
static uint8_t fenetre(uint8_t f, uint8_t w) { /* appel 34,f sur la fenêtre w ; rend l'indicateur d'erreur */
libre();
ControlPort.params[0] = w;
api(34, f);
return ControlPort.error;
}
static uint8_t devant(void) { /* 34,10 Front Window */
libre();
api(34, 10);
return ControlPort.params[0];
}
static void contenu(uint8_t w, Rect *r) { /* 34,8 Get Content Rect */
libre();
ControlPort.params[0] = w;
p16(1, (uint16_t)r);
api(34, 8);
}
static void reinit(void) { /* 32,19 Toolbox Reset : plus aucune fenêtre */
libre();
api(32, 19);
}
static Rect r1 = {20, 20, 120, 100}, k;
static const char titre[] = "\001A";
int main(void) {
reinit();
fenetre(12, nouvelle(&r1, titre, 1)); /* Set Port : la découpe de QuickDraw devient le contenu */
libre(); p16(0, (uint16_t)&k); api(32, 3); /* 32,3 Get Clip */
reinit();
printf("Decoupe : %d, %d, %d, %d\n", k.g, k.h, k.d, k.b);
return 0;
}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, 9965C02 assembly (64tass)
; Dessiner dans une fenêtre (groupe 34, fonction 12, Trinity).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #<b0
ldx #>b0
jsr envoi
lda #<b1
ldx #>b1
jsr envoi
lda ControlPort+9 ; P5 : numéro de la fenêtre
sta a
lda a
ldx #12 ; Set Port : la découpe de QuickDraw devient le contenu
jsr fen
lda #<b2
ldx #>b2
jsr envoi
lda #<b3
ldx #>b3
jsr envoi
lda #<t4
ldx #>t4
jsr ecrire
lda k
ldx k+1
jsr dec16
lda #<t5
ldx #>t5
jsr ecrire
lda k+2
ldx k+2+1
jsr dec16
lda #<t6
ldx #>t6
jsr ecrire
lda k+4
ldx k+4+1
jsr dec16
lda #<t7
ldx #>t7
jsr ecrire
lda k+6
ldx k+6+1
jsr dec16
lda #13
jsr WriteCharacter
rts
r1: .word 20, 20, 120, 100 ; gauche, haut, droite, bas (droite et bas exclus)
titre: .byte 1
.text "A" ; chaîne précédée de sa longueur, lue sur place
k: .fill 8
b0: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
b1: .byte 34, 1, 5 ; 34,1 : New Window
.word r1, titre
.byte 1
a: .byte 0
b2: .byte 32, 3, 2 ; 32,3 Get Clip
.word k
b3: .byte 32, 19, 0 ; 32,19 Toolbox Reset : plus aucune fenêtre
t4: .text "Decoupe : ", 0
t5: .text ", ", 0
t6: .text ", ", 0
t7: .text ", ", 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Affiche le mot de 16 bits A (poids faible), X (poids fort) en décimal, sans zéros de tête.
dec16: sta n16
stx n16+1
stz vu
ldy #0 ; puissance de 10 en cours : 10000, 1000, 100, 10
_p: ldx #0 ; chiffre
_s: lda n16
sec
sbc p10l,y
pha
lda n16+1
sbc p10h,y
bcc _neg ; plus petit : chiffre trouvé
sta n16+1
pla
sta n16
inx
bra _s
_neg: pla
txa
ora vu
beq _suiv ; pas de zéro de tête
txa
ora #'0'
phy
jsr WriteCharacter
ply
lda #1
sta vu
_suiv: iny
cpy #4
bne _p
lda n16 ; les unités, toujours
ora #'0'
jmp WriteCharacter
p10l: .byte <10000, <1000, <100, <10
p10h: .byte >10000, >1000, >100, >10
n16: .word 0
vu: .byte 0
; Appel 34,X sur la fenêtre A ; rend l'indicateur d'erreur dans A.
fen: pha
phx
jsr WaitMessage
plx
pla
sta ControlPort+4 ; P0 : numéro de la fenêtre
lda #34
jsr appel
lda ControlPort+2
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Decoupe : 21, 31, 119, 99