Group 39 — AGI Pictures Trinity
39,1 Draw Picture · 39,2 Show Picture · 39,3 Picture Duration · 39,4 Read Picture Point · 39,5 Draw Cel · 39,6 Restore Rect · 39,7 Add Cel To Plane · 39,8 Fill Plane Priority
Group 39 decodes and displays the pictures of Sierra AGI games (version 2), the interface asked for by the Neo6502AGI port. An AGI picture (PICTURE resource) is a series of drawing commands: visual colour (F0), priority (F2), lines (F6), fill (F8), end (FF). 39,1 decodes it into a 160 × 168 point plane kept at the start of graphics memory: one byte per point, priority in the high nibble, visual colour (0 to 15) in the low one. A cleared plane is colour 15, priority 4.
39,2 copies the colours of the plane to the screen (320 points wide, each point doubled; 8 or 4 bit per pixel modes). 39,4 reads a point of the plane. 39,5 and 39,6 draw and erase the cels of animated objects on the screen without writing the plane, which serves for the priority test: an object is hidden behind scenery of higher priority. 39,7 and 39,8 write into the plane (the add.to.pic command).
The examples use a 21 byte picture: a red rectangle (colour 12, priority 9) filled with yellow (14), from (20, 30) to (100, 80). They read plane points back with 39,4 or screen points with 5,33. Pictures, tiles and sprites use the same graphics memory: a program using this group must not use them. NeoBASIC has no keyword for this group: the example writes the mailbox ($FF00).
39,1 Draw Picture Trinity
Decodes an AGI picture (a Sierra PICTURE resource) into the 160 × 168 point plane.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | addr | address of the picture in 6502 RAM |
P2-P3 | uint16 | length of the picture in bytes |
P4 | uint8 | bit 0: clear the plane first (priority 4, colour 15) |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 address outside 6502 RAM or length 0, 2 fill stack overflow |
The plane is kept in graphics memory, one byte per point: priority in the high nibble, visual colour in the low one. A cleared plane is colour 15, priority 4. The picture of the examples (21 bytes) draws a red rectangle (colour 12, priority 9) and fills it with yellow (14): the plane is read back with 39,4. Without clearing (bit 0 at 0) a second picture is drawn over the first; with clearing it starts from an empty plane. Graphics memory is shared with sprites, tiles and images: a program using this group must not use them. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Trinity (T-107). Decodes the Sierra AGI v2 PICTURE resource at address Parameters:0,1 of 6502 RAM, length Parameters:2,3, into the 160x168 AGI plane kept at offset 0 of graphics memory (page $90, 26 880 bytes, one byte per pixel : priority in the high nibble, visual colour in the low nibble). If bit 0 of Parameter:4 is set the plane is first cleared (priority 4, visual 15). Generic : works for any AGI game. The 6502 is held for the whole decoding (a few ms to about 40 ms). Errors : 1 address range outside 6502 RAM or length 0, 2 fill stack overflow. The fill stack uses graphics memory just after the plane (offsets 26 880 to 30 975, 4 096 bytes). Graphics memory is shared with sprites, tiles and images : a program using this group must not use them.
C (llvm-mos)
/* Décoder une image AGI (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
/* seconde image : un seul point de couleur 3 en (90,90) */
static const uint8_t img2[] = {0xF0, 0x03, 0xF6, 0x5A, 0x5A, 0xFF};
int main(void) {
uint8_t e0, c1, p1, c2, p2, c3, p3, c4, p4, c5, p5, c6, p6, c7, p7, e1;
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
e0 = ControlPort.error;
libre();
ControlPort.params[0] = 20;
ControlPort.params[1] = 30;
api(39, 4);
c1 = ControlPort.params[2];
p1 = ControlPort.params[3];
libre();
ControlPort.params[0] = 50;
ControlPort.params[1] = 50;
api(39, 4);
c2 = ControlPort.params[2];
p2 = ControlPort.params[3];
libre();
ControlPort.params[0] = 5;
ControlPort.params[1] = 5;
api(39, 4);
c3 = ControlPort.params[2];
p3 = ControlPort.params[3];
libre();
p16(0, (uint16_t)img2);
p16(2, sizeof img2);
ControlPort.params[4] = 0;
api(39, 1);
libre();
ControlPort.params[0] = 20;
ControlPort.params[1] = 30;
api(39, 4);
c4 = ControlPort.params[2];
p4 = ControlPort.params[3];
libre();
ControlPort.params[0] = 90;
ControlPort.params[1] = 90;
api(39, 4);
c5 = ControlPort.params[2];
p5 = ControlPort.params[3];
libre();
p16(0, (uint16_t)img2);
p16(2, sizeof img2);
ControlPort.params[4] = 1;
api(39, 1);
libre();
ControlPort.params[0] = 20;
ControlPort.params[1] = 30;
api(39, 4);
c6 = ControlPort.params[2];
p6 = ControlPort.params[3];
libre();
ControlPort.params[0] = 90;
ControlPort.params[1] = 90;
api(39, 4);
c7 = ControlPort.params[2];
p7 = ControlPort.params[3];
libre();
p16(0, (uint16_t)img);
p16(2, 0);
ControlPort.params[4] = 1;
api(39, 1);
e1 = ControlPort.error;
printf("Image : erreur %u\n", e0);
printf("Trait : couleur %u, priorite %u\n", c1, p1);
printf("Interieur : couleur %u, priorite %u\n", c2, p2);
printf("Fond : couleur %u, priorite %u\n", c3, p3);
printf("Sans effacement : trait %u, point %u\n", c4, c5);
printf("Avec effacement : trait %u, point %u\n", c6, c7);
printf("Longueur 0 : erreur %u\n", e1);
return 0;
}Image : erreur 0
Trait : couleur 12, priorite 9
Interieur : couleur 14, priorite 9
Fond : couleur 15, priorite 4
Sans effacement : trait 12, point 3
Avec effacement : trait 15, point 3
Longueur 0 : erreur 1Mad Pascal
// Décoder une image AGI (groupe 39, fonction 1, Trinity).
program agi1;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
// seconde image : un seul point de couleur 3 en (90,90)
const img2: array[0..5] of byte = ($F0, $03, $F6, $5A, $5A, $FF);
var e0, c1, p1, c2, p2, c3, p3, c4, p4, c5, p5, c6, p6, c7, p7, e1: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
e0 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 20;
NeoMessage.params[1] := 30;
appel(39, 4);
c1 := NeoMessage.params[2];
p1 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 50;
NeoMessage.params[1] := 50;
appel(39, 4);
c2 := NeoMessage.params[2];
p2 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 5;
NeoMessage.params[1] := 5;
appel(39, 4);
c3 := NeoMessage.params[2];
p3 := NeoMessage.params[3];
NeoWaitMessage;
p16(0, word(@img2));
p16(2, 6);
NeoMessage.params[4] := 0;
appel(39, 1);
NeoWaitMessage;
NeoMessage.params[0] := 20;
NeoMessage.params[1] := 30;
appel(39, 4);
c4 := NeoMessage.params[2];
p4 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 90;
NeoMessage.params[1] := 90;
appel(39, 4);
c5 := NeoMessage.params[2];
p5 := NeoMessage.params[3];
NeoWaitMessage;
p16(0, word(@img2));
p16(2, 6);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
NeoMessage.params[0] := 20;
NeoMessage.params[1] := 30;
appel(39, 4);
c6 := NeoMessage.params[2];
p6 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 90;
NeoMessage.params[1] := 90;
appel(39, 4);
c7 := NeoMessage.params[2];
p7 := NeoMessage.params[3];
NeoWaitMessage;
p16(0, word(@img));
p16(2, 0);
NeoMessage.params[4] := 1;
appel(39, 1);
e1 := NeoMessage.error;
writeln('Image : erreur ', e0);
writeln('Trait : couleur ', c1, ', priorite ', p1);
writeln('Interieur : couleur ', c2, ', priorite ', p2);
writeln('Fond : couleur ', c3, ', priorite ', p3);
writeln('Sans effacement : trait ', c4, ', point ', c5);
writeln('Avec effacement : trait ', c6, ', point ', c7);
writeln('Longueur 0 : erreur ', e1);
end.Image : erreur 0
Trait : couleur 12, priorite 9
Interieur : couleur 14, priorite 9
Fond : couleur 15, priorite 4
Sans effacement : trait 12, point 3
Avec effacement : trait 15, point 3
Longueur 0 : erreur 1NeoBASIC
10 ' Décoder une image AGI (groupe 39, fonction 1, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 ' seconde image : un seul point de couleur 3 en (90,90)
90 dj = alloc(6)
100 poke dj + 0, 240 : poke dj + 1, 3 : poke dj + 2, 246 : poke dj + 3, 90 : poke dj + 4, 90 : poke dj + 5, 255
110 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
120 e0 = e
130 while peek($ff00) : wend : poke $ff04 + 0, 20 : poke $ff04 + 1, 30 : f = 4 : gosub 8100
140 c1 = peek($ff04 + 2)
150 p1 = peek($ff04 + 3)
160 while peek($ff00) : wend : poke $ff04 + 0, 50 : poke $ff04 + 1, 50 : f = 4 : gosub 8100
170 c2 = peek($ff04 + 2)
180 p2 = peek($ff04 + 3)
190 while peek($ff00) : wend : poke $ff04 + 0, 5 : poke $ff04 + 1, 5 : f = 4 : gosub 8100
200 c3 = peek($ff04 + 2)
210 p3 = peek($ff04 + 3)
220 while peek($ff00) : wend : doke $ff04 + 0, dj : doke $ff04 + 2, 6 : poke $ff04 + 4, 0 : f = 1 : gosub 8100
230 while peek($ff00) : wend : poke $ff04 + 0, 20 : poke $ff04 + 1, 30 : f = 4 : gosub 8100
240 c4 = peek($ff04 + 2)
250 p4 = peek($ff04 + 3)
260 while peek($ff00) : wend : poke $ff04 + 0, 90 : poke $ff04 + 1, 90 : f = 4 : gosub 8100
270 c5 = peek($ff04 + 2)
280 p5 = peek($ff04 + 3)
290 while peek($ff00) : wend : doke $ff04 + 0, dj : doke $ff04 + 2, 6 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
300 while peek($ff00) : wend : poke $ff04 + 0, 20 : poke $ff04 + 1, 30 : f = 4 : gosub 8100
310 c6 = peek($ff04 + 2)
320 p6 = peek($ff04 + 3)
330 while peek($ff00) : wend : poke $ff04 + 0, 90 : poke $ff04 + 1, 90 : f = 4 : gosub 8100
340 c7 = peek($ff04 + 2)
350 p7 = peek($ff04 + 3)
360 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 0 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
370 e1 = e
380 print "Image : erreur ";e0
390 print "Trait : couleur ";c1;", priorite ";p1
400 print "Interieur : couleur ";c2;", priorite ";p2
410 print "Fond : couleur ";c3;", priorite ";p3
420 print "Sans effacement : trait ";c4;", point ";c5
430 print "Avec effacement : trait ";c6;", point ";c7
440 print "Longueur 0 : erreur ";e1
450 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnImage : erreur 0
Trait : couleur 12, priorite 9
Interieur : couleur 14, priorite 9
Fond : couleur 15, priorite 4
Sans effacement : trait 12, point 3
Avec effacement : trait 15, point 3
Longueur 0 : erreur 165C02 assembly (64tass)
; Décoder une image AGI (groupe 39, 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:
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #20
sta ControlPort+4
lda #30
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c1
lda ControlPort+7
sta p1
jsr WaitMessage
lda #50
sta ControlPort+4
lda #50
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c2
lda ControlPort+7
sta p2
jsr WaitMessage
lda #5
sta ControlPort+4
lda #5
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c3
lda ControlPort+7
sta p3
jsr WaitMessage
lda #<img2
sta ControlPort+4
lda #>img2
sta ControlPort+5
lda #<(fimg2-img2)
sta ControlPort+6
lda #>(fimg2-img2)
sta ControlPort+7
stz ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #20
sta ControlPort+4
lda #30
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c4
lda ControlPort+7
sta p4
jsr WaitMessage
lda #90
sta ControlPort+4
lda #90
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c5
lda ControlPort+7
sta p5
jsr WaitMessage
lda #<img2
sta ControlPort+4
lda #>img2
sta ControlPort+5
lda #<(fimg2-img2)
sta ControlPort+6
lda #>(fimg2-img2)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #20
sta ControlPort+4
lda #30
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c6
lda ControlPort+7
sta p6
jsr WaitMessage
lda #90
sta ControlPort+4
lda #90
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c7
lda ControlPort+7
sta p7
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<0
sta ControlPort+6
lda #>0
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
lda ControlPort+2
sta e1
lda #<t0
ldx #>t0
jsr ecrire
lda e0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda c1
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t3
ldx #>t3
jsr ecrire
lda c2
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda c3
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p3
jsr decimal
lda #13
jsr WriteCharacter
lda #<t5
ldx #>t5
jsr ecrire
lda c4
jsr decimal
lda #<t6
ldx #>t6
jsr ecrire
lda c5
jsr decimal
lda #13
jsr WriteCharacter
lda #<t7
ldx #>t7
jsr ecrire
lda c6
jsr decimal
lda #<t6
ldx #>t6
jsr ecrire
lda c7
jsr decimal
lda #13
jsr WriteCharacter
lda #<t8
ldx #>t8
jsr ecrire
lda e1
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
; seconde image : un seul point de couleur 3 en (90,90)
img2:
.byte $F0, $03, $F6, $5A, $5A, $FF
fimg2:
e0: .byte 0
c1: .byte 0
p1: .byte 0
c2: .byte 0
p2: .byte 0
c3: .byte 0
p3: .byte 0
c4: .byte 0
p4: .byte 0
c5: .byte 0
p5: .byte 0
c6: .byte 0
p6: .byte 0
c7: .byte 0
p7: .byte 0
e1: .byte 0
t0: .text "Image : erreur ", 0
t1: .text "Trait : couleur ", 0
t2: .text ", priorite ", 0
t3: .text "Interieur : couleur ", 0
t4: .text "Fond : couleur ", 0
t5: .text "Sans effacement : trait ", 0
t6: .text ", point ", 0
t7: .text "Avec effacement : trait ", 0
t8: .text "Longueur 0 : erreur ", 0Image : erreur 0
Trait : couleur 12, priorite 9
Interieur : couleur 14, priorite 9
Fond : couleur 15, priorite 4
Sans effacement : trait 12, point 3
Avec effacement : trait 15, point 3
Longueur 0 : erreur 139,2 Show Picture Trinity
Copies the colours of the AGI picture to the screen, each point doubled in width (320 × 168).
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | uint16 | screen line for the top of the picture |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 if the mode is not 320 points wide with 8 or 4 bits, or if the picture does not fit |
Only the colours (0 to 15) are copied; the palette is not changed. The example shows the picture at line 72 of mode 0 (72 + 168 = 240) and reads the screen back with 5,33: picture point (20, 30) takes screen pixels 40 and 41 of line 102, point (19, 30) pixels 38 and 39. At line 100 the picture runs off the screen: error 1. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Copies the visual colours (0-15) of the AGI plane to the screen draw page, from line Parameters:0,1, each pixel doubled in width (320 x 168). Modes 320 pixels wide with 8 or 4 bits per pixel. The palette is not changed. Error 1 if the mode is not supported or the picture does not fit.
C (llvm-mos)
/* Montrer l'image AGI à l'écran (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
int main(void) {
uint8_t e0, a1, a2, a3, a4, e1;
putchar(12); /* efface l'écran avant toute mesure */
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
p16(0, 72);
api(39, 2);
e0 = ControlPort.error;
libre(); p16(0, 40); p16(2, 102); api(5, 33); a1 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 41); p16(2, 102); api(5, 33); a2 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 38); p16(2, 102); api(5, 33); a3 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 100); p16(2, 122); api(5, 33); a4 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre();
p16(0, 100);
api(39, 2);
e1 = ControlPort.error;
printf("Montrer : erreur %u\n", e0);
printf("Trait : %u %u, a gauche : %u\n", a1, a2, a3);
printf("Interieur : %u\n", a4);
printf("Ligne 100 : erreur %u\n", e1);
return 0;
}Montrer : erreur 0
Trait : 12 12, a gauche : 15
Interieur : 14
Ligne 100 : erreur 1Mad Pascal
// Montrer l'image AGI à l'écran (groupe 39, fonction 2, Trinity).
program agi2;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
var e0, a1, a2, a3, a4, e1: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
write(chr(12)); // efface l'écran avant toute mesure
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
p16(0, 72);
appel(39, 2);
e0 := NeoMessage.error;
NeoWaitMessage; p16(0, 40); p16(2, 102); appel(5, 33); a1 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 41); p16(2, 102); appel(5, 33); a2 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 38); p16(2, 102); appel(5, 33); a3 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 100); p16(2, 122); appel(5, 33); a4 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage;
p16(0, 100);
appel(39, 2);
e1 := NeoMessage.error;
writeln('Montrer : erreur ', e0);
writeln('Trait : ', a1, ' ', a2, ', a gauche : ', a3);
writeln('Interieur : ', a4);
writeln('Ligne 100 : erreur ', e1);
end.Montrer : erreur 0
Trait : 12 12, a gauche : 15
Interieur : 14
Ligne 100 : erreur 1NeoBASIC
10 ' Montrer l'image AGI à l'écran (groupe 39, fonction 2, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 cls
90 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
100 while peek($ff00) : wend : doke $ff04 + 0, 72 : f = 2 : gosub 8100
110 e0 = e
120 while peek($ff00) : wend : doke $ff04, 40 : doke $ff06, 102 : f = 33 : g = 5 : gosub 8110 : a1 = peek($ff04)
130 while peek($ff00) : wend : doke $ff04, 41 : doke $ff06, 102 : f = 33 : g = 5 : gosub 8110 : a2 = peek($ff04)
140 while peek($ff00) : wend : doke $ff04, 38 : doke $ff06, 102 : f = 33 : g = 5 : gosub 8110 : a3 = peek($ff04)
150 while peek($ff00) : wend : doke $ff04, 100 : doke $ff06, 122 : f = 33 : g = 5 : gosub 8110 : a4 = peek($ff04)
160 while peek($ff00) : wend : doke $ff04 + 0, 100 : f = 2 : gosub 8100
170 e1 = e
180 print "Montrer : erreur ";e0
190 print "Trait : ";a1;" ";a2;", a gauche : ";a3
200 print "Interieur : ";a4
210 print "Ligne 100 : erreur ";e1
220 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnMontrer : erreur 0
Trait : 12 12, a gauche : 15
Interieur : 14
Ligne 100 : erreur 165C02 assembly (64tass)
; Montrer l'image AGI à l'écran (groupe 39, 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 #12 ; efface l'écran avant toute mesure
jsr WriteCharacter
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #<72
sta ControlPort+4
lda #>72
sta ControlPort+5
lda #39
ldx #2
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #<40
sta ControlPort+4
lda #>40
sta ControlPort+5
lda #<102
sta ControlPort+6
lda #>102
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a1
jsr WaitMessage
lda #<41
sta ControlPort+4
lda #>41
sta ControlPort+5
lda #<102
sta ControlPort+6
lda #>102
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a2
jsr WaitMessage
lda #<38
sta ControlPort+4
lda #>38
sta ControlPort+5
lda #<102
sta ControlPort+6
lda #>102
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a3
jsr WaitMessage
lda #<100
sta ControlPort+4
lda #>100
sta ControlPort+5
lda #<122
sta ControlPort+6
lda #>122
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a4
jsr WaitMessage
lda #<100
sta ControlPort+4
lda #>100
sta ControlPort+5
lda #39
ldx #2
jsr appel
lda ControlPort+2
sta e1
lda #<t0
ldx #>t0
jsr ecrire
lda e0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda a1
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda a2
jsr decimal
lda #<t3
ldx #>t3
jsr ecrire
lda a3
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda a4
jsr decimal
lda #13
jsr WriteCharacter
lda #<t5
ldx #>t5
jsr ecrire
lda e1
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
e0: .byte 0
a1: .byte 0
a2: .byte 0
a3: .byte 0
a4: .byte 0
e1: .byte 0
t0: .text "Montrer : erreur ", 0
t1: .text "Trait : ", 0
t2: .text " ", 0
t3: .text ", a gauche : ", 0
t4: .text "Interieur : ", 0
t5: .text "Ligne 100 : erreur ", 0Montrer : erreur 0
Trait : 12 12, a gauche : 15
Interieur : 14
Ligne 100 : erreur 139,3 Picture Duration Trinity
Gives the duration of the last picture decoding, in microseconds.
Inputs: none.
| Bytes | Type | Meaning |
|---|---|---|
P0-P3 | uint32 | duration of 39,1 in microseconds (0 on the emulators) |
The duration is measured on the board only: the emulators answer 0, which is what the example prints (the four bytes P0 to P3). On the board expect a few milliseconds up to about forty, depending on the picture. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Returns in Parameters:0-3 the duration of the last Draw Picture in microseconds (board only, 0 on the emulators).
C (llvm-mos)
/* Durée du décodage d'une image AGI (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
int main(void) {
uint8_t d0, d1, d2, d3;
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
api(39, 3);
d0 = ControlPort.params[0];
d1 = ControlPort.params[1];
d2 = ControlPort.params[2];
d3 = ControlPort.params[3];
printf("Duree : %u %u %u %u\n", d0, d1, d2, d3);
return 0;
}Duree : 0 0 0 0Mad Pascal
// Durée du décodage d'une image AGI (groupe 39, fonction 3, Trinity).
program agi3;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
var d0, d1, d2, d3: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
appel(39, 3);
d0 := NeoMessage.params[0];
d1 := NeoMessage.params[1];
d2 := NeoMessage.params[2];
d3 := NeoMessage.params[3];
writeln('Duree : ', d0, ' ', d1, ' ', d2, ' ', d3);
end.Duree : 0 0 0 0NeoBASIC
10 ' Durée du décodage d'une image AGI (groupe 39, fonction 3, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
90 while peek($ff00) : wend : f = 3 : gosub 8100
100 d0 = peek($ff04 + 0)
110 d1 = peek($ff04 + 1)
120 d2 = peek($ff04 + 2)
130 d3 = peek($ff04 + 3)
140 print "Duree : ";d0;" ";d1;" ";d2;" ";d3
150 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnDuree : 0 0 0 065C02 assembly (64tass)
; Durée du décodage d'une image AGI (groupe 39, 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:
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #39
ldx #3
jsr appel
lda ControlPort+4
sta d0
lda ControlPort+5
sta d1
lda ControlPort+6
sta d2
lda ControlPort+7
sta d3
lda #<t0
ldx #>t0
jsr ecrire
lda d0
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda d1
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda d2
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda d3
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
d0: .byte 0
d1: .byte 0
d2: .byte 0
d3: .byte 0
t0: .text "Duree : ", 0
t1: .text " ", 0Duree : 0 0 0 039,4 Read Picture Point Trinity
Reads the colour and the priority of a point of the AGI plane.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | X (0 to 159) |
P1 | uint8 | Y (0 to 167) |
| Bytes | Type | Meaning |
|---|---|---|
P2 | uint8 | visual colour (0 to 15) |
P3 | uint8 | priority (0 to 15) |
erreur | uint8 | 1 if the point is outside the plane |
The coordinates are those of the plane (160 × 168), not of the screen. Outside the plane the error is 1 and P2, P3 are left unchanged. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Returns the visual colour (Parameter:2) and the priority (Parameter:3) of the point Parameter:0, Parameter:1 (X 0-159, Y 0-167) of the AGI plane. Error 1 if out of range.
C (llvm-mos)
/* Lire un point du plan AGI (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
int main(void) {
uint8_t c1, p1, c2, p2, c3, p3, c4, p4, e1, c5, p5, e2;
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
ControlPort.params[0] = 20;
ControlPort.params[1] = 30;
api(39, 4);
c1 = ControlPort.params[2];
p1 = ControlPort.params[3];
libre();
ControlPort.params[0] = 50;
ControlPort.params[1] = 50;
api(39, 4);
c2 = ControlPort.params[2];
p2 = ControlPort.params[3];
libre();
ControlPort.params[0] = 5;
ControlPort.params[1] = 5;
api(39, 4);
c3 = ControlPort.params[2];
p3 = ControlPort.params[3];
libre();
ControlPort.params[0] = 160;
ControlPort.params[1] = 0;
api(39, 4);
c4 = ControlPort.params[2];
p4 = ControlPort.params[3];
e1 = ControlPort.error;
libre();
ControlPort.params[0] = 0;
ControlPort.params[1] = 168;
api(39, 4);
c5 = ControlPort.params[2];
p5 = ControlPort.params[3];
e2 = ControlPort.error;
printf("Trait (20, 30) : couleur %u, priorite %u\n", c1, p1);
printf("Dedans (50, 50) : couleur %u, priorite %u\n", c2, p2);
printf("Fond (5, 5) : couleur %u, priorite %u\n", c3, p3);
printf("X = 160 : erreur %u ; Y = 168 : erreur %u\n", e1, e2);
return 0;
}Trait (20, 30) : couleur 12, priorite 9
Dedans (50, 50) : couleur 14, priorite 9
Fond (5, 5) : couleur 15, priorite 4
X = 160 : erreur 1 ; Y = 168 : erreur 1Mad Pascal
// Lire un point du plan AGI (groupe 39, fonction 4, Trinity).
program agi4;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
var c1, p1, c2, p2, c3, p3, c4, p4, e1, c5, p5, e2: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
NeoMessage.params[0] := 20;
NeoMessage.params[1] := 30;
appel(39, 4);
c1 := NeoMessage.params[2];
p1 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 50;
NeoMessage.params[1] := 50;
appel(39, 4);
c2 := NeoMessage.params[2];
p2 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 5;
NeoMessage.params[1] := 5;
appel(39, 4);
c3 := NeoMessage.params[2];
p3 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 160;
NeoMessage.params[1] := 0;
appel(39, 4);
c4 := NeoMessage.params[2];
p4 := NeoMessage.params[3];
e1 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 0;
NeoMessage.params[1] := 168;
appel(39, 4);
c5 := NeoMessage.params[2];
p5 := NeoMessage.params[3];
e2 := NeoMessage.error;
writeln('Trait (20, 30) : couleur ', c1, ', priorite ', p1);
writeln('Dedans (50, 50) : couleur ', c2, ', priorite ', p2);
writeln('Fond (5, 5) : couleur ', c3, ', priorite ', p3);
writeln('X = 160 : erreur ', e1, ' ; Y = 168 : erreur ', e2);
end.Trait (20, 30) : couleur 12, priorite 9
Dedans (50, 50) : couleur 14, priorite 9
Fond (5, 5) : couleur 15, priorite 4
X = 160 : erreur 1 ; Y = 168 : erreur 1NeoBASIC
10 ' Lire un point du plan AGI (groupe 39, fonction 4, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
90 while peek($ff00) : wend : poke $ff04 + 0, 20 : poke $ff04 + 1, 30 : f = 4 : gosub 8100
100 c1 = peek($ff04 + 2)
110 p1 = peek($ff04 + 3)
120 while peek($ff00) : wend : poke $ff04 + 0, 50 : poke $ff04 + 1, 50 : f = 4 : gosub 8100
130 c2 = peek($ff04 + 2)
140 p2 = peek($ff04 + 3)
150 while peek($ff00) : wend : poke $ff04 + 0, 5 : poke $ff04 + 1, 5 : f = 4 : gosub 8100
160 c3 = peek($ff04 + 2)
170 p3 = peek($ff04 + 3)
180 while peek($ff00) : wend : poke $ff04 + 0, 160 : poke $ff04 + 1, 0 : f = 4 : gosub 8100
190 c4 = peek($ff04 + 2)
200 p4 = peek($ff04 + 3)
210 e1 = e
220 while peek($ff00) : wend : poke $ff04 + 0, 0 : poke $ff04 + 1, 168 : f = 4 : gosub 8100
230 c5 = peek($ff04 + 2)
240 p5 = peek($ff04 + 3)
250 e2 = e
260 print "Trait (20, 30) : couleur ";c1;", priorite ";p1
270 print "Dedans (50, 50) : couleur ";c2;", priorite ";p2
280 print "Fond (5, 5) : couleur ";c3;", priorite ";p3
290 print "X = 160 : erreur ";e1;" ; Y = 168 : erreur ";e2
300 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnTrait (20, 30) : couleur 12, priorite 9
Dedans (50, 50) : couleur 14, priorite 9
Fond (5, 5) : couleur 15, priorite 4
X = 160 : erreur 1 ; Y = 168 : erreur 165C02 assembly (64tass)
; Lire un point du plan AGI (groupe 39, 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:
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #20
sta ControlPort+4
lda #30
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c1
lda ControlPort+7
sta p1
jsr WaitMessage
lda #50
sta ControlPort+4
lda #50
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c2
lda ControlPort+7
sta p2
jsr WaitMessage
lda #5
sta ControlPort+4
lda #5
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c3
lda ControlPort+7
sta p3
jsr WaitMessage
lda #160
sta ControlPort+4
stz ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c4
lda ControlPort+7
sta p4
lda ControlPort+2
sta e1
jsr WaitMessage
stz ControlPort+4
lda #168
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c5
lda ControlPort+7
sta p5
lda ControlPort+2
sta e2
lda #<t0
ldx #>t0
jsr ecrire
lda c1
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda p1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t2
ldx #>t2
jsr ecrire
lda c2
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda p2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t3
ldx #>t3
jsr ecrire
lda c3
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda p3
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda e1
jsr decimal
lda #<t5
ldx #>t5
jsr ecrire
lda e2
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
c1: .byte 0
p1: .byte 0
c2: .byte 0
p2: .byte 0
c3: .byte 0
p3: .byte 0
c4: .byte 0
p4: .byte 0
e1: .byte 0
c5: .byte 0
p5: .byte 0
e2: .byte 0
t0: .text "Trait (20, 30) : couleur ", 0
t1: .text ", priorite ", 0
t2: .text "Dedans (50, 50) : couleur ", 0
t3: .text "Fond (5, 5) : couleur ", 0
t4: .text "X = 160 : erreur ", 0
t5: .text " ; Y = 168 : erreur ", 0Trait (20, 30) : couleur 12, priorite 9
Dedans (50, 50) : couleur 14, priorite 9
Fond (5, 5) : couleur 15, priorite 4
X = 160 : erreur 1 ; Y = 168 : erreur 139,5 Draw Cel Trinity
Draws an AGI view cel to the screen, without touching the plane.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | addr | address of the cel header in 6502 RAM |
P2 | uint8 | X of the left side |
P3 | uint8 | Y of the bottom line |
P4 | uint8 | object priority |
P5 | uint8 | bit 0: mirror horizontally |
P6-P7 | uint16 | screen line of the top of the plane |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 empty cel, position outside the plane, header outside RAM or unsupported mode; 2 cel data cut by the end of RAM |
The cel starts with its width, its height and a byte in PC format (bit 7 mirror, bits 6 to 4 loop, low nibble transparent colour); then the lines, a series of bytes "colour in the high nibble, length in the low nibble", 0 at the end of a line. A point is drawn if it is not transparent and if the object priority is greater than or equal to the plane priority there. The plane is never written. The example draws the 4 × 2 point cel with priority 12 on the inside of the rectangle (priority 9): it shows, the transparent point lets the yellow through. With priority 5 it is hidden, and the plane stays 14 / 9. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Trinity (T-109). Draws the AGI view cel whose header (width, height, then a byte in PC format : bit 7 mirror, bits 6-4 normal loop, low nibble transparent colour ; only the transparent colour is read, then the RLE lines : colour in the high nibble, length in the low nibble, 0 at the end of each line) is at address Parameters:0,1 of 6502 RAM, its left side at X Parameter:2, its bottom line at Y Parameter:3 (AGI pixels), with the object priority Parameter:4 ; bit 0 of Parameter:5 mirrors it horizontally. The plane top is at screen line Parameters:6,7. A pixel is drawn when it is not transparent and the object priority is greater than or equal to the plane priority at that point ; on a control line (priority 0 to 3) the first point below which is not one is used, 15 if the bottom is reached (assumptions, see Neo6502AGI docs/specs/view-v2.md). The cel is clipped to the plane ; a line longer than the width is cut. Draw Cel never writes the plane. The caller handles the order of the objects : after Restore Rect has erased an object, the objects it overlapped must be drawn again. Errors : 1 empty cel, position outside the plane, header outside 6502 RAM or unsupported mode ; 2 cel data cut by the end of 6502 RAM.
C (llvm-mos)
/* Dessiner un cel sur l'image (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
/* cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne) */
static const uint8_t cel[] = {0x04, 0x02, 0x00, 0x01, 0x32, 0x11, 0x00, 0x24, 0x00};
int main(void) {
uint8_t e0, a1, a2, a3, a4, e1, a5, c1, p1;
putchar(12); /* efface l'écran avant toute mesure */
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
p16(0, 72);
api(39, 2);
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 60;
ControlPort.params[4] = 12;
ControlPort.params[5] = 0;
p16(6, 72);
api(39, 5);
e0 = ControlPort.error;
libre(); p16(0, 120); p16(2, 131); api(5, 33); a1 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 122); p16(2, 131); api(5, 33); a2 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 126); p16(2, 131); api(5, 33); a3 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 120); p16(2, 132); api(5, 33); a4 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 76;
ControlPort.params[4] = 5;
ControlPort.params[5] = 0;
p16(6, 72);
api(39, 5);
e1 = ControlPort.error;
libre(); p16(0, 120); p16(2, 148); api(5, 33); a5 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 60;
api(39, 4);
c1 = ControlPort.params[2];
p1 = ControlPort.params[3];
printf("Priorite 12 : erreur %u\n", e0);
printf("Haut : %u %u %u, bas : %u\n", a1, a2, a3, a4);
printf("Priorite 5 : erreur %u, ecran %u\n", e1, a5);
printf("Plan : couleur %u, priorite %u\n", c1, p1);
return 0;
}Priorite 12 : erreur 0
Haut : 14 3 1, bas : 2
Priorite 5 : erreur 0, ecran 14
Plan : couleur 14, priorite 9Mad Pascal
// Dessiner un cel sur l'image (groupe 39, fonction 5, Trinity).
program agi5;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
// cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
const cel: array[0..8] of byte = ($04, $02, $00, $01, $32, $11, $00, $24, $00);
var e0, a1, a2, a3, a4, e1, a5, c1, p1: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
write(chr(12)); // efface l'écran avant toute mesure
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
p16(0, 72);
appel(39, 2);
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 60;
NeoMessage.params[4] := 12;
NeoMessage.params[5] := 0;
p16(6, 72);
appel(39, 5);
e0 := NeoMessage.error;
NeoWaitMessage; p16(0, 120); p16(2, 131); appel(5, 33); a1 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 122); p16(2, 131); appel(5, 33); a2 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 126); p16(2, 131); appel(5, 33); a3 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 120); p16(2, 132); appel(5, 33); a4 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 76;
NeoMessage.params[4] := 5;
NeoMessage.params[5] := 0;
p16(6, 72);
appel(39, 5);
e1 := NeoMessage.error;
NeoWaitMessage; p16(0, 120); p16(2, 148); appel(5, 33); a5 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 60;
appel(39, 4);
c1 := NeoMessage.params[2];
p1 := NeoMessage.params[3];
writeln('Priorite 12 : erreur ', e0);
writeln('Haut : ', a1, ' ', a2, ' ', a3, ', bas : ', a4);
writeln('Priorite 5 : erreur ', e1, ', ecran ', a5);
writeln('Plan : couleur ', c1, ', priorite ', p1);
end.Priorite 12 : erreur 0
Haut : 14 3 1, bas : 2
Priorite 5 : erreur 0, ecran 14
Plan : couleur 14, priorite 9NeoBASIC
10 ' Dessiner un cel sur l'image (groupe 39, fonction 5, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 ' cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
90 dc = alloc(9)
100 poke dc + 0, 4 : poke dc + 1, 2 : poke dc + 2, 0 : poke dc + 3, 1 : poke dc + 4, 50 : poke dc + 5, 17
110 poke dc + 6, 0 : poke dc + 7, 36 : poke dc + 8, 0
120 cls
130 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
140 while peek($ff00) : wend : doke $ff04 + 0, 72 : f = 2 : gosub 8100
150 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 60 : poke $ff04 + 4, 12 : poke $ff04 + 5, 0 : doke $ff04 + 6, 72 : f = 5 : gosub 8100
160 e0 = e
170 while peek($ff00) : wend : doke $ff04, 120 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a1 = peek($ff04)
180 while peek($ff00) : wend : doke $ff04, 122 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a2 = peek($ff04)
190 while peek($ff00) : wend : doke $ff04, 126 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a3 = peek($ff04)
200 while peek($ff00) : wend : doke $ff04, 120 : doke $ff06, 132 : f = 33 : g = 5 : gosub 8110 : a4 = peek($ff04)
210 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 76 : poke $ff04 + 4, 5 : poke $ff04 + 5, 0 : doke $ff04 + 6, 72 : f = 5 : gosub 8100
220 e1 = e
230 while peek($ff00) : wend : doke $ff04, 120 : doke $ff06, 148 : f = 33 : g = 5 : gosub 8110 : a5 = peek($ff04)
240 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 60 : f = 4 : gosub 8100
250 c1 = peek($ff04 + 2)
260 p1 = peek($ff04 + 3)
270 print "Priorite 12 : erreur ";e0
280 print "Haut : ";a1;" ";a2;" ";a3;", bas : ";a4
290 print "Priorite 5 : erreur ";e1;", ecran ";a5
300 print "Plan : couleur ";c1;", priorite ";p1
310 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnPriorite 12 : erreur 0
Haut : 14 3 1, bas : 2
Priorite 5 : erreur 0, ecran 14
Plan : couleur 14, priorite 965C02 assembly (64tass)
; Dessiner un cel sur l'image (groupe 39, 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 #12 ; efface l'écran avant toute mesure
jsr WriteCharacter
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #<72
sta ControlPort+4
lda #>72
sta ControlPort+5
lda #39
ldx #2
jsr appel
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #60
sta ControlPort+7
lda #12
sta ControlPort+8
stz ControlPort+9
lda #<72
sta ControlPort+10
lda #>72
sta ControlPort+11
lda #39
ldx #5
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #<120
sta ControlPort+4
lda #>120
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a1
jsr WaitMessage
lda #<122
sta ControlPort+4
lda #>122
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a2
jsr WaitMessage
lda #<126
sta ControlPort+4
lda #>126
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a3
jsr WaitMessage
lda #<120
sta ControlPort+4
lda #>120
sta ControlPort+5
lda #<132
sta ControlPort+6
lda #>132
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a4
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #76
sta ControlPort+7
lda #5
sta ControlPort+8
stz ControlPort+9
lda #<72
sta ControlPort+10
lda #>72
sta ControlPort+11
lda #39
ldx #5
jsr appel
lda ControlPort+2
sta e1
jsr WaitMessage
lda #<120
sta ControlPort+4
lda #>120
sta ControlPort+5
lda #<148
sta ControlPort+6
lda #>148
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a5
jsr WaitMessage
lda #60
sta ControlPort+4
lda #60
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c1
lda ControlPort+7
sta p1
lda #<t0
ldx #>t0
jsr ecrire
lda e0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda a1
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda a2
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda a3
jsr decimal
lda #<t3
ldx #>t3
jsr ecrire
lda a4
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda e1
jsr decimal
lda #<t5
ldx #>t5
jsr ecrire
lda a5
jsr decimal
lda #13
jsr WriteCharacter
lda #<t6
ldx #>t6
jsr ecrire
lda c1
jsr decimal
lda #<t7
ldx #>t7
jsr ecrire
lda p1
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
; cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
cel:
.byte $04, $02, $00, $01, $32, $11, $00, $24
.byte $00
fcel:
e0: .byte 0
a1: .byte 0
a2: .byte 0
a3: .byte 0
a4: .byte 0
e1: .byte 0
a5: .byte 0
c1: .byte 0
p1: .byte 0
t0: .text "Priorite 12 : erreur ", 0
t1: .text "Haut : ", 0
t2: .text " ", 0
t3: .text ", bas : ", 0
t4: .text "Priorite 5 : erreur ", 0
t5: .text ", ecran ", 0
t6: .text "Plan : couleur ", 0
t7: .text ", priorite ", 0Priorite 12 : erreur 0
Haut : 14 3 1, bas : 2
Priorite 5 : erreur 0, ecran 14
Plan : couleur 14, priorite 939,6 Restore Rect Trinity
Copies a rectangle of the AGI plane to the screen: erases the objects drawn there.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | X |
P1 | uint8 | Y |
P2 | uint8 | width |
P3 | uint8 | height |
P4-P5 | uint16 | screen line of the top of the plane |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 if the width or the height is 0, or if the mode is not supported |
The rectangle is clipped to the plane. The objects it overlapped must then be drawn again by the caller. The example draws a cel, restores 2 × 1 points: the restored point gets the plane colour back (14), the rest of the cel is untouched. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Trinity (T-109). Copies the visual colours of the AGI plane to the screen on the rectangle X Parameter:0, Y Parameter:1, width Parameter:2, height Parameter:3 (AGI pixels, clipped to the plane), the plane top being at screen line Parameters:4,5 : this erases the objects drawn there. Error 1 if the width or the height is 0 or the mode is not supported.
C (llvm-mos)
/* Restaurer un rectangle de l'image (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
/* cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne) */
static const uint8_t cel[] = {0x04, 0x02, 0x00, 0x01, 0x32, 0x11, 0x00, 0x24, 0x00};
int main(void) {
uint8_t a1, a2, e0, a3, a4, e1;
putchar(12); /* efface l'écran avant toute mesure */
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
p16(0, 72);
api(39, 2);
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 60;
ControlPort.params[4] = 12;
ControlPort.params[5] = 0;
p16(6, 72);
api(39, 5);
libre(); p16(0, 122); p16(2, 131); api(5, 33); a1 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 126); p16(2, 131); api(5, 33); a2 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 59;
ControlPort.params[2] = 2;
ControlPort.params[3] = 1;
p16(4, 72);
api(39, 6);
e0 = ControlPort.error;
libre(); p16(0, 122); p16(2, 131); api(5, 33); a3 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre(); p16(0, 126); p16(2, 131); api(5, 33); a4 = ControlPort.params[0]; /* 5,33 : Read Pixel */
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 59;
ControlPort.params[2] = 0;
ControlPort.params[3] = 1;
p16(4, 72);
api(39, 6);
e1 = ControlPort.error;
printf("Avant : %u et %u\n", a1, a2);
printf("Restaurer : erreur %u, apres : %u et %u\n", e0, a3, a4);
printf("Largeur 0 : erreur %u\n", e1);
return 0;
}Avant : 3 et 1
Restaurer : erreur 0, apres : 14 et 1
Largeur 0 : erreur 1Mad Pascal
// Restaurer un rectangle de l'image (groupe 39, fonction 6, Trinity).
program agi6;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
// cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
const cel: array[0..8] of byte = ($04, $02, $00, $01, $32, $11, $00, $24, $00);
var a1, a2, e0, a3, a4, e1: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
write(chr(12)); // efface l'écran avant toute mesure
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
p16(0, 72);
appel(39, 2);
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 60;
NeoMessage.params[4] := 12;
NeoMessage.params[5] := 0;
p16(6, 72);
appel(39, 5);
NeoWaitMessage; p16(0, 122); p16(2, 131); appel(5, 33); a1 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 126); p16(2, 131); appel(5, 33); a2 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 59;
NeoMessage.params[2] := 2;
NeoMessage.params[3] := 1;
p16(4, 72);
appel(39, 6);
e0 := NeoMessage.error;
NeoWaitMessage; p16(0, 122); p16(2, 131); appel(5, 33); a3 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage; p16(0, 126); p16(2, 131); appel(5, 33); a4 := NeoMessage.params[0]; // 5,33 : Read Pixel
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 59;
NeoMessage.params[2] := 0;
NeoMessage.params[3] := 1;
p16(4, 72);
appel(39, 6);
e1 := NeoMessage.error;
writeln('Avant : ', a1, ' et ', a2);
writeln('Restaurer : erreur ', e0, ', apres : ', a3, ' et ', a4);
writeln('Largeur 0 : erreur ', e1);
end.Avant : 3 et 1
Restaurer : erreur 0, apres : 14 et 1
Largeur 0 : erreur 1NeoBASIC
10 ' Restaurer un rectangle de l'image (groupe 39, fonction 6, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 ' cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
90 dc = alloc(9)
100 poke dc + 0, 4 : poke dc + 1, 2 : poke dc + 2, 0 : poke dc + 3, 1 : poke dc + 4, 50 : poke dc + 5, 17
110 poke dc + 6, 0 : poke dc + 7, 36 : poke dc + 8, 0
120 cls
130 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
140 while peek($ff00) : wend : doke $ff04 + 0, 72 : f = 2 : gosub 8100
150 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 60 : poke $ff04 + 4, 12 : poke $ff04 + 5, 0 : doke $ff04 + 6, 72 : f = 5 : gosub 8100
160 while peek($ff00) : wend : doke $ff04, 122 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a1 = peek($ff04)
170 while peek($ff00) : wend : doke $ff04, 126 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a2 = peek($ff04)
180 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 59 : poke $ff04 + 2, 2 : poke $ff04 + 3, 1 : doke $ff04 + 4, 72 : f = 6 : gosub 8100
190 e0 = e
200 while peek($ff00) : wend : doke $ff04, 122 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a3 = peek($ff04)
210 while peek($ff00) : wend : doke $ff04, 126 : doke $ff06, 131 : f = 33 : g = 5 : gosub 8110 : a4 = peek($ff04)
220 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 59 : poke $ff04 + 2, 0 : poke $ff04 + 3, 1 : doke $ff04 + 4, 72 : f = 6 : gosub 8100
230 e1 = e
240 print "Avant : ";a1;" et ";a2
250 print "Restaurer : erreur ";e0;", apres : ";a3;" et ";a4
260 print "Largeur 0 : erreur ";e1
270 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnAvant : 3 et 1
Restaurer : erreur 0, apres : 14 et 1
Largeur 0 : erreur 165C02 assembly (64tass)
; Restaurer un rectangle de l'image (groupe 39, 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 #12 ; efface l'écran avant toute mesure
jsr WriteCharacter
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #<72
sta ControlPort+4
lda #>72
sta ControlPort+5
lda #39
ldx #2
jsr appel
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #60
sta ControlPort+7
lda #12
sta ControlPort+8
stz ControlPort+9
lda #<72
sta ControlPort+10
lda #>72
sta ControlPort+11
lda #39
ldx #5
jsr appel
jsr WaitMessage
lda #<122
sta ControlPort+4
lda #>122
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a1
jsr WaitMessage
lda #<126
sta ControlPort+4
lda #>126
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a2
jsr WaitMessage
lda #60
sta ControlPort+4
lda #59
sta ControlPort+5
lda #2
sta ControlPort+6
lda #1
sta ControlPort+7
lda #<72
sta ControlPort+8
lda #>72
sta ControlPort+9
lda #39
ldx #6
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #<122
sta ControlPort+4
lda #>122
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a3
jsr WaitMessage
lda #<126
sta ControlPort+4
lda #>126
sta ControlPort+5
lda #<131
sta ControlPort+6
lda #>131
sta ControlPort+7
lda #5
ldx #33 ; 5,33 : Read Pixel
jsr appel
lda ControlPort+4
sta a4
jsr WaitMessage
lda #60
sta ControlPort+4
lda #59
sta ControlPort+5
stz ControlPort+6
lda #1
sta ControlPort+7
lda #<72
sta ControlPort+8
lda #>72
sta ControlPort+9
lda #39
ldx #6
jsr appel
lda ControlPort+2
sta e1
lda #<t0
ldx #>t0
jsr ecrire
lda a1
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda a2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t2
ldx #>t2
jsr ecrire
lda e0
jsr decimal
lda #<t3
ldx #>t3
jsr ecrire
lda a3
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda a4
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda e1
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
; cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
cel:
.byte $04, $02, $00, $01, $32, $11, $00, $24
.byte $00
fcel:
a1: .byte 0
a2: .byte 0
e0: .byte 0
a3: .byte 0
a4: .byte 0
e1: .byte 0
t0: .text "Avant : ", 0
t1: .text " et ", 0
t2: .text "Restaurer : erreur ", 0
t3: .text ", apres : ", 0
t4: .text "Largeur 0 : erreur ", 0Avant : 3 et 1
Restaurer : erreur 0, apres : 14 et 1
Largeur 0 : erreur 139,7 Add Cel To Plane Trinity
Writes a cel into the AGI plane (the add.to.pic command) instead of the screen.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | addr | address of the cel header in 6502 RAM |
P2 | uint8 | X of the left side |
P3 | uint8 | Y of the bottom line |
P4 | uint8 | priority (4 to 15) |
P5 | uint8 | bit 0: mirror horizontally |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 priority outside 4-15, empty cel, position outside the plane or header outside RAM; 2 cel data cut |
Same parameters as 39,5, without a screen line: each non-transparent point that passes the priority test receives the cel colour and the given priority (control lines 0 to 3 already in the plane are kept). Priority 0 ("from Y") is for the caller to compute, hence the refusal of 0 to 3. 39,6 then shows the result. The example reads the plane after the addition, tries priority 3 (error 1), then priority 5 on a plane of priority 9: nothing is written. NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Trinity (T-122), for the AGI command add.to.pic. Same parameters as Draw Cel (cel header at Parameters:0,1 of 6502 RAM, left X Parameter:2, bottom Y Parameter:3, priority Parameter:4, bit 0 of Parameter:5 = mirror) without screen line : the cel is written into the AGI plane, not to the screen. Each point which is not transparent and passes the priority test of Draw Cel (priority greater than or equal to the plane priority, control lines included) receives the cel colour and the given priority. The priority must be 4 to 15 (0, "from Y", is computed by the caller). Same clipping as Draw Cel ; Restore Rect then shows the result. Errors : 1 priority outside 4-15 and the errors 1 and 2 of Draw Cel (the screen mode is not used).
C (llvm-mos)
/* Ajouter un cel au plan AGI (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
/* cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne) */
static const uint8_t cel[] = {0x04, 0x02, 0x00, 0x01, 0x32, 0x11, 0x00, 0x24, 0x00};
int main(void) {
uint8_t e0, c1, p1, c2, p2, c3, p3, e1, e2, c4, p4;
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 60;
ControlPort.params[4] = 12;
ControlPort.params[5] = 0;
api(39, 7);
e0 = ControlPort.error;
libre();
ControlPort.params[0] = 61;
ControlPort.params[1] = 59;
api(39, 4);
c1 = ControlPort.params[2];
p1 = ControlPort.params[3];
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 59;
api(39, 4);
c2 = ControlPort.params[2];
p2 = ControlPort.params[3];
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 60;
api(39, 4);
c3 = ControlPort.params[2];
p3 = ControlPort.params[3];
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 60;
ControlPort.params[4] = 3;
ControlPort.params[5] = 0;
api(39, 7);
e1 = ControlPort.error;
libre();
p16(0, (uint16_t)cel);
ControlPort.params[2] = 60;
ControlPort.params[3] = 76;
ControlPort.params[4] = 5;
ControlPort.params[5] = 0;
api(39, 7);
e2 = ControlPort.error;
libre();
ControlPort.params[0] = 60;
ControlPort.params[1] = 76;
api(39, 4);
c4 = ControlPort.params[2];
p4 = ControlPort.params[3];
printf("Ajout : erreur %u\n", e0);
printf("Cel (61, 59) : couleur %u, priorite %u\n", c1, p1);
printf("Vide (60, 59) : couleur %u, priorite %u\n", c2, p2);
printf("Bas (60, 60) : couleur %u, priorite %u\n", c3, p3);
printf("Priorite 3 : erreur %u\n", e1);
printf("Priorite 5 : erreur %u\n", e2);
printf("Point (60, 76) : couleur %u, priorite %u\n", c4, p4);
return 0;
}Ajout : erreur 0
Cel (61, 59) : couleur 3, priorite 12
Vide (60, 59) : couleur 14, priorite 9
Bas (60, 60) : couleur 2, priorite 12
Priorite 3 : erreur 1
Priorite 5 : erreur 0
Point (60, 76) : couleur 14, priorite 9Mad Pascal
// Ajouter un cel au plan AGI (groupe 39, fonction 7, Trinity).
program agi7;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
// cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
const cel: array[0..8] of byte = ($04, $02, $00, $01, $32, $11, $00, $24, $00);
var e0, c1, p1, c2, p2, c3, p3, e1, e2, c4, p4: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 60;
NeoMessage.params[4] := 12;
NeoMessage.params[5] := 0;
appel(39, 7);
e0 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 61;
NeoMessage.params[1] := 59;
appel(39, 4);
c1 := NeoMessage.params[2];
p1 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 59;
appel(39, 4);
c2 := NeoMessage.params[2];
p2 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 60;
appel(39, 4);
c3 := NeoMessage.params[2];
p3 := NeoMessage.params[3];
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 60;
NeoMessage.params[4] := 3;
NeoMessage.params[5] := 0;
appel(39, 7);
e1 := NeoMessage.error;
NeoWaitMessage;
p16(0, word(@cel));
NeoMessage.params[2] := 60;
NeoMessage.params[3] := 76;
NeoMessage.params[4] := 5;
NeoMessage.params[5] := 0;
appel(39, 7);
e2 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 60;
NeoMessage.params[1] := 76;
appel(39, 4);
c4 := NeoMessage.params[2];
p4 := NeoMessage.params[3];
writeln('Ajout : erreur ', e0);
writeln('Cel (61, 59) : couleur ', c1, ', priorite ', p1);
writeln('Vide (60, 59) : couleur ', c2, ', priorite ', p2);
writeln('Bas (60, 60) : couleur ', c3, ', priorite ', p3);
writeln('Priorite 3 : erreur ', e1);
writeln('Priorite 5 : erreur ', e2);
writeln('Point (60, 76) : couleur ', c4, ', priorite ', p4);
end.Ajout : erreur 0
Cel (61, 59) : couleur 3, priorite 12
Vide (60, 59) : couleur 14, priorite 9
Bas (60, 60) : couleur 2, priorite 12
Priorite 3 : erreur 1
Priorite 5 : erreur 0
Point (60, 76) : couleur 14, priorite 9NeoBASIC
10 ' Ajouter un cel au plan AGI (groupe 39, fonction 7, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 ' cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
90 dc = alloc(9)
100 poke dc + 0, 4 : poke dc + 1, 2 : poke dc + 2, 0 : poke dc + 3, 1 : poke dc + 4, 50 : poke dc + 5, 17
110 poke dc + 6, 0 : poke dc + 7, 36 : poke dc + 8, 0
120 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
130 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 60 : poke $ff04 + 4, 12 : poke $ff04 + 5, 0 : f = 7 : gosub 8100
140 e0 = e
150 while peek($ff00) : wend : poke $ff04 + 0, 61 : poke $ff04 + 1, 59 : f = 4 : gosub 8100
160 c1 = peek($ff04 + 2)
170 p1 = peek($ff04 + 3)
180 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 59 : f = 4 : gosub 8100
190 c2 = peek($ff04 + 2)
200 p2 = peek($ff04 + 3)
210 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 60 : f = 4 : gosub 8100
220 c3 = peek($ff04 + 2)
230 p3 = peek($ff04 + 3)
240 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 60 : poke $ff04 + 4, 3 : poke $ff04 + 5, 0 : f = 7 : gosub 8100
250 e1 = e
260 while peek($ff00) : wend : doke $ff04 + 0, dc : poke $ff04 + 2, 60 : poke $ff04 + 3, 76 : poke $ff04 + 4, 5 : poke $ff04 + 5, 0 : f = 7 : gosub 8100
270 e2 = e
280 while peek($ff00) : wend : poke $ff04 + 0, 60 : poke $ff04 + 1, 76 : f = 4 : gosub 8100
290 c4 = peek($ff04 + 2)
300 p4 = peek($ff04 + 3)
310 print "Ajout : erreur ";e0
320 print "Cel (61, 59) : couleur ";c1;", priorite ";p1
330 print "Vide (60, 59) : couleur ";c2;", priorite ";p2
340 print "Bas (60, 60) : couleur ";c3;", priorite ";p3
350 print "Priorite 3 : erreur ";e1
360 print "Priorite 5 : erreur ";e2
370 print "Point (60, 76) : couleur ";c4;", priorite ";p4
380 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnAjout : erreur 0
Cel (61, 59) : couleur 3, priorite 12
Vide (60, 59) : couleur 14, priorite 9
Bas (60, 60) : couleur 2, priorite 12
Priorite 3 : erreur 1
Priorite 5 : erreur 0
Point (60, 76) : couleur 14, priorite 965C02 assembly (64tass)
; Ajouter un cel au plan AGI (groupe 39, 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:
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #60
sta ControlPort+7
lda #12
sta ControlPort+8
stz ControlPort+9
lda #39
ldx #7
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #61
sta ControlPort+4
lda #59
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c1
lda ControlPort+7
sta p1
jsr WaitMessage
lda #60
sta ControlPort+4
lda #59
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c2
lda ControlPort+7
sta p2
jsr WaitMessage
lda #60
sta ControlPort+4
lda #60
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c3
lda ControlPort+7
sta p3
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #60
sta ControlPort+7
lda #3
sta ControlPort+8
stz ControlPort+9
lda #39
ldx #7
jsr appel
lda ControlPort+2
sta e1
jsr WaitMessage
lda #<cel
sta ControlPort+4
lda #>cel
sta ControlPort+5
lda #60
sta ControlPort+6
lda #76
sta ControlPort+7
lda #5
sta ControlPort+8
stz ControlPort+9
lda #39
ldx #7
jsr appel
lda ControlPort+2
sta e2
jsr WaitMessage
lda #60
sta ControlPort+4
lda #76
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c4
lda ControlPort+7
sta p4
lda #<t0
ldx #>t0
jsr ecrire
lda e0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda c1
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t3
ldx #>t3
jsr ecrire
lda c2
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda c3
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p3
jsr decimal
lda #13
jsr WriteCharacter
lda #<t5
ldx #>t5
jsr ecrire
lda e1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t6
ldx #>t6
jsr ecrire
lda e2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t7
ldx #>t7
jsr ecrire
lda c4
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p4
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
; cel 4 x 2, transparent = 0 : ligne du haut 0,3,3,1 ; ligne du bas 2,2,2,2 (RLE : couleur dans le quartet haut, longueur dans le bas, 0 en fin de ligne)
cel:
.byte $04, $02, $00, $01, $32, $11, $00, $24
.byte $00
fcel:
e0: .byte 0
c1: .byte 0
p1: .byte 0
c2: .byte 0
p2: .byte 0
c3: .byte 0
p3: .byte 0
e1: .byte 0
e2: .byte 0
c4: .byte 0
p4: .byte 0
t0: .text "Ajout : erreur ", 0
t1: .text "Cel (61, 59) : couleur ", 0
t2: .text ", priorite ", 0
t3: .text "Vide (60, 59) : couleur ", 0
t4: .text "Bas (60, 60) : couleur ", 0
t5: .text "Priorite 3 : erreur ", 0
t6: .text "Priorite 5 : erreur ", 0
t7: .text "Point (60, 76) : couleur ", 0Ajout : erreur 0
Cel (61, 59) : couleur 3, priorite 12
Vide (60, 59) : couleur 14, priorite 9
Bas (60, 60) : couleur 2, priorite 12
Priorite 3 : erreur 1
Priorite 5 : erreur 0
Point (60, 76) : couleur 14, priorite 939,8 Fill Plane Priority Trinity
Sets the priority of the points of a rectangle of the AGI plane, without changing the colours.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | X |
P1 | uint8 | Y |
P2 | uint8 | width |
P3 | uint8 | height |
P4 | uint8 | priority (0 to 15) |
| Bytes | Type | Meaning |
|---|---|---|
erreur | uint8 | 1 if the width or the height is 0, or the priority above 15 |
The rectangle is clipped to the plane. Used for the margin of add.to.pic (priority 0 to 3). NeoBASIC has no keyword for this call: the example writes the mailbox directly.
Firmware documentation text
Trinity (T-122). Sets to Parameter:4 (0 to 15) the priority of the points of the AGI plane in the rectangle X Parameter:0, Y Parameter:1, width Parameter:2, height Parameter:3 (AGI pixels, clipped to the plane) ; the visual colours are not changed. Used for the margin of add.to.pic (priority 0 to 3). Error 1 if the width or the height is 0 or the priority is above 15.
C (llvm-mos)
/* Fixer la priorité d'un rectangle du plan (groupe 39, 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)
;
}
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;
}
/* image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50) */
static const uint8_t img[] = {0xF0, 0x0C, 0xF2, 0x09, 0xF6, 0x14, 0x1E, 0x64, 0x1E, 0x64, 0x50, 0x14, 0x50, 0x14, 0x1E, 0xF0, 0x0E, 0xF8, 0x32, 0x32, 0xFF};
int main(void) {
uint8_t e0, c1, p1, c2, p2, e1, e2;
libre();
p16(0, (uint16_t)img);
p16(2, sizeof img);
ControlPort.params[4] = 1;
api(39, 1);
libre();
ControlPort.params[0] = 30;
ControlPort.params[1] = 40;
ControlPort.params[2] = 10;
ControlPort.params[3] = 10;
ControlPort.params[4] = 2;
api(39, 8);
e0 = ControlPort.error;
libre();
ControlPort.params[0] = 35;
ControlPort.params[1] = 45;
api(39, 4);
c1 = ControlPort.params[2];
p1 = ControlPort.params[3];
libre();
ControlPort.params[0] = 45;
ControlPort.params[1] = 45;
api(39, 4);
c2 = ControlPort.params[2];
p2 = ControlPort.params[3];
libre();
ControlPort.params[0] = 30;
ControlPort.params[1] = 40;
ControlPort.params[2] = 10;
ControlPort.params[3] = 10;
ControlPort.params[4] = 16;
api(39, 8);
e1 = ControlPort.error;
libre();
ControlPort.params[0] = 30;
ControlPort.params[1] = 40;
ControlPort.params[2] = 0;
ControlPort.params[3] = 10;
ControlPort.params[4] = 2;
api(39, 8);
e2 = ControlPort.error;
printf("Rectangle : erreur %u\n", e0);
printf("Dedans (35, 45) : couleur %u, priorite %u\n", c1, p1);
printf("Dehors (45, 45) : couleur %u, priorite %u\n", c2, p2);
printf("Priorite 16 : erreur %u\n", e1);
printf("Largeur 0 : erreur %u\n", e2);
return 0;
}Rectangle : erreur 0
Dedans (35, 45) : couleur 14, priorite 2
Dehors (45, 45) : couleur 14, priorite 9
Priorite 16 : erreur 1
Largeur 0 : erreur 1Mad Pascal
// Fixer la priorité d'un rectangle du plan (groupe 39, fonction 8, Trinity).
program agi8;
uses crt, neo6502;
// image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
const img: array[0..20] of byte = ($F0, $0C, $F2, $09, $F6, $14, $1E, $64, $1E, $64, $50, $14, $50, $14, $1E, $F0, $0E, $F8, $32, $32, $FF);
var e0, c1, p1, c2, p2, e1, e2: byte;
procedure p16(i: byte; v: word); // paramètre 16 bits en Pi, Pi+1
begin
NeoMessage.params[i] := lo(v);
NeoMessage.params[i + 1] := hi(v);
end;
procedure appel(g, f: byte); // lance l'appel et attend la fin
begin
NeoSendMessage(g, f);
NeoWaitMessage;
end;
begin
NeoWaitMessage;
p16(0, word(@img));
p16(2, 21);
NeoMessage.params[4] := 1;
appel(39, 1);
NeoWaitMessage;
NeoMessage.params[0] := 30;
NeoMessage.params[1] := 40;
NeoMessage.params[2] := 10;
NeoMessage.params[3] := 10;
NeoMessage.params[4] := 2;
appel(39, 8);
e0 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 35;
NeoMessage.params[1] := 45;
appel(39, 4);
c1 := NeoMessage.params[2];
p1 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 45;
NeoMessage.params[1] := 45;
appel(39, 4);
c2 := NeoMessage.params[2];
p2 := NeoMessage.params[3];
NeoWaitMessage;
NeoMessage.params[0] := 30;
NeoMessage.params[1] := 40;
NeoMessage.params[2] := 10;
NeoMessage.params[3] := 10;
NeoMessage.params[4] := 16;
appel(39, 8);
e1 := NeoMessage.error;
NeoWaitMessage;
NeoMessage.params[0] := 30;
NeoMessage.params[1] := 40;
NeoMessage.params[2] := 0;
NeoMessage.params[3] := 10;
NeoMessage.params[4] := 2;
appel(39, 8);
e2 := NeoMessage.error;
writeln('Rectangle : erreur ', e0);
writeln('Dedans (35, 45) : couleur ', c1, ', priorite ', p1);
writeln('Dehors (45, 45) : couleur ', c2, ', priorite ', p2);
writeln('Priorite 16 : erreur ', e1);
writeln('Largeur 0 : erreur ', e2);
end.Rectangle : erreur 0
Dedans (35, 45) : couleur 14, priorite 2
Dehors (45, 45) : couleur 14, priorite 9
Priorite 16 : erreur 1
Largeur 0 : erreur 1NeoBASIC
10 ' Fixer la priorité d'un rectangle du plan (groupe 39, fonction 8, Trinity)
20 ' image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
30 di = alloc(21)
40 poke di + 0, 240 : poke di + 1, 12 : poke di + 2, 242 : poke di + 3, 9 : poke di + 4, 246 : poke di + 5, 20
50 poke di + 6, 30 : poke di + 7, 100 : poke di + 8, 30 : poke di + 9, 100 : poke di + 10, 80 : poke di + 11, 20
60 poke di + 12, 80 : poke di + 13, 20 : poke di + 14, 30 : poke di + 15, 240 : poke di + 16, 14 : poke di + 17, 248
70 poke di + 18, 50 : poke di + 19, 50 : poke di + 20, 255
80 while peek($ff00) : wend : doke $ff04 + 0, di : doke $ff04 + 2, 21 : poke $ff04 + 4, 1 : f = 1 : gosub 8100
90 while peek($ff00) : wend : poke $ff04 + 0, 30 : poke $ff04 + 1, 40 : poke $ff04 + 2, 10 : poke $ff04 + 3, 10 : poke $ff04 + 4, 2 : f = 8 : gosub 8100
100 e0 = e
110 while peek($ff00) : wend : poke $ff04 + 0, 35 : poke $ff04 + 1, 45 : f = 4 : gosub 8100
120 c1 = peek($ff04 + 2)
130 p1 = peek($ff04 + 3)
140 while peek($ff00) : wend : poke $ff04 + 0, 45 : poke $ff04 + 1, 45 : f = 4 : gosub 8100
150 c2 = peek($ff04 + 2)
160 p2 = peek($ff04 + 3)
170 while peek($ff00) : wend : poke $ff04 + 0, 30 : poke $ff04 + 1, 40 : poke $ff04 + 2, 10 : poke $ff04 + 3, 10 : poke $ff04 + 4, 16 : f = 8 : gosub 8100
180 e1 = e
190 while peek($ff00) : wend : poke $ff04 + 0, 30 : poke $ff04 + 1, 40 : poke $ff04 + 2, 0 : poke $ff04 + 3, 10 : poke $ff04 + 4, 2 : f = 8 : gosub 8100
200 e2 = e
210 print "Rectangle : erreur ";e0
220 print "Dedans (35, 45) : couleur ";c1;", priorite ";p1
230 print "Dehors (45, 45) : couleur ";c2;", priorite ";p2
240 print "Priorite 16 : erreur ";e1
250 print "Largeur 0 : erreur ";e2
260 end
8100 ' appel 39,f, parametres deja poses ; erreur dans e
8105 g = 39
8110 poke $ff01, f : poke $ff00, g
8120 while peek($ff00) : wend : e = peek($ff02) : returnRectangle : erreur 0
Dedans (35, 45) : couleur 14, priorite 2
Dehors (45, 45) : couleur 14, priorite 9
Priorite 16 : erreur 1
Largeur 0 : erreur 165C02 assembly (64tass)
; Fixer la priorité d'un rectangle du plan (groupe 39, 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:
jsr WaitMessage
lda #<img
sta ControlPort+4
lda #>img
sta ControlPort+5
lda #<(fimg-img)
sta ControlPort+6
lda #>(fimg-img)
sta ControlPort+7
lda #1
sta ControlPort+8
lda #39
ldx #1
jsr appel
jsr WaitMessage
lda #30
sta ControlPort+4
lda #40
sta ControlPort+5
lda #10
sta ControlPort+6
lda #10
sta ControlPort+7
lda #2
sta ControlPort+8
lda #39
ldx #8
jsr appel
lda ControlPort+2
sta e0
jsr WaitMessage
lda #35
sta ControlPort+4
lda #45
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c1
lda ControlPort+7
sta p1
jsr WaitMessage
lda #45
sta ControlPort+4
lda #45
sta ControlPort+5
lda #39
ldx #4
jsr appel
lda ControlPort+6
sta c2
lda ControlPort+7
sta p2
jsr WaitMessage
lda #30
sta ControlPort+4
lda #40
sta ControlPort+5
lda #10
sta ControlPort+6
lda #10
sta ControlPort+7
lda #16
sta ControlPort+8
lda #39
ldx #8
jsr appel
lda ControlPort+2
sta e1
jsr WaitMessage
lda #30
sta ControlPort+4
lda #40
sta ControlPort+5
stz ControlPort+6
lda #10
sta ControlPort+7
lda #2
sta ControlPort+8
lda #39
ldx #8
jsr appel
lda ControlPort+2
sta e2
lda #<t0
ldx #>t0
jsr ecrire
lda e0
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda c1
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t3
ldx #>t3
jsr ecrire
lda c2
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda p2
jsr decimal
lda #13
jsr WriteCharacter
lda #<t4
ldx #>t4
jsr ecrire
lda e1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t5
ldx #>t5
jsr ecrire
lda e2
jsr decimal
lda #13
jsr WriteCharacter
rts
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
diviseur: .byte 0
; image AGI : ligne rouge (12) priorité 9 autour de (20,30)-(100,80), puis remplissage jaune (14) en (50,50)
img:
.byte $F0, $0C, $F2, $09, $F6, $14, $1E, $64
.byte $1E, $64, $50, $14, $50, $14, $1E, $F0
.byte $0E, $F8, $32, $32, $FF
fimg:
e0: .byte 0
c1: .byte 0
p1: .byte 0
c2: .byte 0
p2: .byte 0
e1: .byte 0
e2: .byte 0
t0: .text "Rectangle : erreur ", 0
t1: .text "Dedans (35, 45) : couleur ", 0
t2: .text ", priorite ", 0
t3: .text "Dehors (45, 45) : couleur ", 0
t4: .text "Priorite 16 : erreur ", 0
t5: .text "Largeur 0 : erreur ", 0Rectangle : erreur 0
Dedans (35, 45) : couleur 14, priorite 2
Dehors (45, 45) : couleur 14, priorite 9
Priorite 16 : erreur 1
Largeur 0 : erreur 1