Groupe 9 — Tortue graphique Officiel
9,1 Turtle Initialise · 9,2 Turtle Turn · 9,3 Turtle Move · 9,4 Turtle Hide · 9,5 Turtle Home · 9,6 Turtle Show
La tortue est un crayon que l'on dirige : elle part du centre de l'écran (160, 120 en mode 0), cap vers le haut, tourne en degrés (vers la droite, dans le sens des aiguilles d'une montre) et avance en pixels en traçant ou non. Elle s'affiche avec l'un des sprites, choisi par 9,1 : une flèche jaune (couleur 3) qui suit son cap.
Sa position est gardée en nombres réels et tronquée au pixel inférieur pour tracer : un côté censé tomber sur x = 200 ou y = 120 peut tomber sur 199 ou 119. Les exemples relisent les traits là où ils tombent vraiment. La position du sprite (6,5), elle, est arrondie.
La tortue est cachée après 9,1 et le reste tant que 9,6 n'est pas appelé, même quand elle tourne ou avance ; tant qu'elle n'a pas été montrée, 6,5 rend 65535 pour sa position. NeoBASIC la prend en charge tout seul : sa première commande de tortue appelle 9,1 sur le sprite 127, puis 9,6.
Les exemples effacent l'écran (ils relisent des pixels, 5,33 et 5,36) et effacent les sprites (6,1) avant de rendre la main.
9,1 Turtle Initialise Officiel
Prépare la tortue : lui confie un sprite, la place au centre, cap vers le haut, cachée.
| Octets | Type | Rôle |
|---|---|---|
P0 | uint8 | numéro du sprite que la tortue prend |
Sorties : aucune.
L'image de la tortue n'est pas modifiable. L'exemple vérifie qu'elle est cachée (rien sur la couche des sprites au centre), puis la montre (9,6) : couleur 3 au centre, et 6,5 lit la position du sprite 0. NeoBASIC fait cet appel tout seul, sur le sprite 127, à la première commande de tortue ; l'exemple NeoBASIC écrit donc la boîte aux lettres lui-même pour prendre le sprite 0.
Texte de la documentation du firmware (anglais)
Initialise the turtle graphics system. Parameter:0 is the sprite number to use for the turtle,as the turtle graphics system “adopts” one of the sprites. The icon is not currently re-definable, and initially the turtle is hidden.
C (llvm-mos)
/* Confier la tortue au sprite 0 (groupe 9, fonction 1). */
#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 uint8_t sprite_pixel(uint16_t x, uint16_t y) { /* 5,36 : couche des sprites */
libre();
ControlPort.params[0] = x & 0xFF;
ControlPort.params[1] = x >> 8;
ControlPort.params[2] = y & 0xFF;
ControlPort.params[3] = y >> 8;
api(5, 36);
return ControlPort.params[0];
}
int main(void) {
uint16_t x, y;
putchar(12); /* écran effacé : on relit des pixels */
neo_turtle_init(0); /* Turtle Initialise : sprite 0, tortue cachée */
uint8_t avant = sprite_pixel(160, 120);
neo_turtle_show(); /* 9,6 */
uint8_t apres = sprite_pixel(160, 120);
neo_sprite_position(0, &x, &y); /* 6,5 : le sprite 0 est la tortue */
neo_sprite_reset(); /* 6,1 : effacer les sprites avant de rendre la main */
printf("Apres 9,1 : %s\n", avant ? "visible" : "cachee");
printf("Apres 9,6 : couleur %u en %u, %u\n", apres, x, y);
return 0;
}Apres 9,1 : cachee
Apres 9,6 : couleur 3 en 160, 120Mad Pascal
// Confier la tortue au sprite 0 (groupe 9, fonction 1).
program tortue1;
uses crt, neo6502;
var avant, apres: byte;
x, y: word;
procedure TurtleShow; // 9,6 : Mad Pascal n'a pas cet appel
begin
NeoSendMessage(9, 6);
NeoWaitMessage;
end;
begin
write(chr(12)); // écran effacé : on relit des pixels
TurtleInit(0); // Turtle Initialise : sprite 0, tortue cachée
avant := NeoGetSpritePixel(160, 120);
TurtleShow; // 9,6
apres := NeoGetSpritePixel(160, 120);
NeoGetSpriteXY(0, x, y); // 6,5 : le sprite 0 est la tortue
NeoResetSprites; // 6,1 : effacer les sprites avant de rendre la main
if avant <> 0 then writeln('Apres 9,1 : visible') else writeln('Apres 9,1 : cachee');
writeln('Apres 9,6 : couleur ', apres, ' en ', x, ', ', y);
end.Apres 9,1 : cachee
Apres 9,6 : couleur 3 en 160, 120NeoBASIC
10 ' Confier la tortue au sprite 0 (groupe 9, fonction 1)
20 cls : ' ecran efface : on relit des pixels
30 while peek($ff00) : wend : poke $ff04, 0 : poke $ff01, 1 : poke $ff00, 9 : ' Turtle Initialise : sprite 0, cachee
40 while peek($ff00) : wend : avant = spoint(160,120)
50 poke $ff01, 6 : poke $ff00, 9 : ' 9,6 : montrer
60 while peek($ff00) : wend : apres = spoint(160,120) : x = spritex(0) : y = spritey(0)
70 sprite clear : ' 6,1 : effacer les sprites avant de rendre la main
80 v$ = "cachee" : if avant then v$ = "visible"
90 print "Apres 9,1 : ";v$
100 print "Apres 9,6 : couleur ";apres;" en ";x;", ";yApres 9,1 : cachee
Apres 9,6 : couleur 3 en 160, 120Assembleur 65C02 (64tass)
; Confier la tortue au sprite 0 (groupe 9, fonction 1).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #160
ldy #120
jsr spixel
sta avant
lda #<montre
ldx #>montre
jsr envoi
lda #160
ldy #120
jsr spixel
sta apres
jsr position
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda avant
bne _vavant
lda #<tc
ldx #>tc
jsr ecrire
bra _favant
_vavant: lda #<tv
ldx #>tv
jsr ecrire
_favant:
lda #<t1
ldx #>t1
jsr ecrire
lda apres
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
jmp montrerxy
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
t0: .text "Apres 9,1 : ", 0
tc: .text "cachee", 13, 0
tv: .text "visible", 13, 0
t1: .text "Apres 9,6 : couleur ", 0
t2: .text " en ", 0
avant: .byte 0
apres: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Apres 9,1 : cachee
Apres 9,6 : couleur 3 en 160, 1209,2 Turtle Turn Officiel
Fait tourner la tortue à droite d'un nombre de degrés ; un nombre négatif la fait tourner à gauche.
| Octets | Type | Rôle |
|---|---|---|
P0-P1 | int16 | degrés : positif à droite, négatif à gauche |
Sorties : aucune.
Seul le reste de la division par 360 compte : tourner de -450 revient à tourner de 90 à gauche. La documentation du firmware et llvm-mos disent que l'appel montre la tortue cachée ; le code, officiel comme Trinity, ne le fait pas : l'exemple la trouve toujours cachée. En NeoBASIC, right n et left n font cet appel (left envoie -n).
Mots-clés NeoBASIC qui font cet appel : right
Texte de la documentation du firmware (anglais)
Turn the turtle right by Parameter:0,1 degrees. Show if hidden. To turn left, turn by a negative amount.
C (llvm-mos)
/* Faire tourner la tortue à droite et à gauche (groupe 9, fonction 2). */
#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 uint8_t sprite_pixel(uint16_t x, uint16_t y) { /* 5,36 : couche des sprites */
libre();
ControlPort.params[0] = x & 0xFF;
ControlPort.params[1] = x >> 8;
ControlPort.params[2] = y & 0xFF;
ControlPort.params[3] = y >> 8;
api(5, 36);
return ControlPort.params[0];
}
int main(void) {
uint16_t x1, y1, x2, y2;
putchar(12);
neo_turtle_init(0); /* 9,1 : au centre, cap vers le haut, cachée */
neo_turtle_turn(90); /* Turtle Turn : 90 degrés à droite */
uint8_t vue = sprite_pixel(160, 120); /* toujours cachée */
neo_turtle_move(20, 0, 0); /* 9,3 : 20 pixels sans tracer */
neo_turtle_show(); /* 9,6 */
neo_sprite_position(0, &x1, &y1);
neo_turtle_turn(-450); /* négatif : à gauche ; 450 = 360 + 90 */
neo_turtle_move(20, 0, 0);
neo_sprite_position(0, &x2, &y2);
neo_sprite_reset();
printf("Apres 9,2 : %s\n", vue ? "visible" : "cachee");
printf("90 a droite puis 20 : %u, %u\n", x1, y1);
printf("450 a gauche puis 20 : %u, %u\n", x2, y2);
return 0;
}Apres 9,2 : cachee
90 a droite puis 20 : 180, 120
450 a gauche puis 20 : 180, 100Mad Pascal
// Faire tourner la tortue à droite et à gauche (groupe 9, fonction 2).
program tortue2;
uses crt, neo6502;
var vue: byte;
x1, y1, x2, y2: word;
procedure TurtleShow; // 9,6 : Mad Pascal n'a pas cet appel
begin
NeoSendMessage(9, 6);
NeoWaitMessage;
end;
begin
write(chr(12));
TurtleInit(0); // 9,1 : au centre, cap vers le haut, cachée
TurtleRight(90); // Turtle Turn : 90 degrés à droite
vue := NeoGetSpritePixel(160, 120); // toujours cachée
TurtleMove(20, 0, 0); // 9,3 : 20 pixels sans tracer
TurtleShow;
NeoGetSpriteXY(0, x1, y1);
TurtleRight(word(-450)); // négatif : à gauche ; 450 = 360 + 90
TurtleMove(20, 0, 0);
NeoGetSpriteXY(0, x2, y2);
NeoResetSprites;
if vue <> 0 then writeln('Apres 9,2 : visible') else writeln('Apres 9,2 : cachee');
writeln('90 a droite puis 20 : ', x1, ', ', y1);
writeln('450 a gauche puis 20 : ', x2, ', ', y2);
end.Apres 9,2 : cachee
90 a droite puis 20 : 180, 120
450 a gauche puis 20 : 180, 100NeoBASIC
10 ' Faire tourner la tortue a droite et a gauche (groupe 9, fonction 2)
20 cls
30 while peek($ff00) : wend : poke $ff04, 0 : poke $ff01, 1 : poke $ff00, 9 : ' 9,1 : au centre, cap vers le haut, cachee
40 a = 90 : gosub 1000 : ' Turtle Turn : 90 degres a droite
50 vue = spoint(160,120) : ' toujours cachee
60 gosub 1100 : ' 20 pixels sans tracer
70 while peek($ff00) : wend : poke $ff01, 6 : poke $ff00, 9 : ' 9,6 : montrer
80 while peek($ff00) : wend : x1 = spritex(0) : y1 = spritey(0)
90 a = -450 : gosub 1000 : ' negatif : a gauche ; 450 = 360 + 90
100 gosub 1100 : x2 = spritex(0) : y2 = spritey(0)
110 sprite clear
120 v$ = "cachee" : if vue then v$ = "visible"
130 print "Apres 9,2 : ";v$
140 print "90 a droite puis 20 : ";x1;", ";y1
150 print "450 a gauche puis 20 : ";x2;", ";y2
160 end
1000 ' 9,2 : tourner de a degres (doke refuse un negatif : a & $ffff, meme valeur sur 16 bits)
1010 while peek($ff00) : wend : doke $ff04, a & $ffff : poke $ff01, 2 : poke $ff00, 9
1020 while peek($ff00) : wend : return
1100 ' 9,3 : avancer de 20 pixels, crayon leve
1110 while peek($ff00) : wend : doke $ff04, 20 : poke $ff06, 0 : poke $ff07, 0 : poke $ff01, 3 : poke $ff00, 9
1120 while peek($ff00) : wend : returnApres 9,2 : cachee
90 a droite puis 20 : 180, 120
450 a gauche puis 20 : 180, 100Assembleur 65C02 (64tass)
; Faire tourner la tortue à droite et à gauche (groupe 9, fonction 2).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #<d90
ldx #>d90
jsr envoi
lda #160 ; toujours cachée
ldy #120
jsr spixel
sta vue
lda #<m20
ldx #>m20
jsr envoi
lda #<montre
ldx #>montre
jsr envoi
jsr position
lda px
sta x1
lda py
sta y1
lda #<g450
ldx #>g450
jsr envoi
lda #<m20
ldx #>m20
jsr envoi
jsr position
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda vue
bne _vvue
lda #<tc
ldx #>tc
jsr ecrire
bra _fvue
_vvue: lda #<tv
ldx #>tv
jsr ecrire
_fvue:
lda #<t1
ldx #>t1
jsr ecrire
lda x1
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda y1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t2
ldx #>t2
jsr ecrire
jmp montrerxy
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
d90: .byte 9, 2, 2 ; 9,2 : Turtle Turn...
.word 90 ; ... 90 degrés à droite
g450: .byte 9, 2, 2
.word 65536-450 ; -450 : négatif, à gauche ; 450 = 360 + 90
m20: .byte 9, 3, 4 ; 9,3 : 20 pixels, sans tracer
.word 20
.byte 0, 0
t0: .text "Apres 9,2 : ", 0
tc: .text "cachee", 13, 0
tv: .text "visible", 13, 0
t1: .text "90 a droite puis 20 : ", 0
t2: .text "450 a gauche puis 20 : ", 0
vue: .byte 0
x1: .byte 0
y1: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Apres 9,2 : cachee
90 a droite puis 20 : 180, 120
450 a gauche puis 20 : 180, 1009,3 Turtle Move Officiel
Fait avancer la tortue d'un nombre de pixels dans la direction de son cap, en traçant ou non.
| Octets | Type | Rôle |
|---|---|---|
P0-P1 | int16 | distance en pixels (négative : recule) |
P2 | uint8 | couleur du trait (4 bits bas : 0 à 15) |
P3 | uint8 | différent de 0 : trace |
Sorties : aucune.
La documentation du firmware parle de « degrés » : c'est une distance en pixels. Un trait qui sortirait de l'écran n'est pas tracé du tout. L'exemple trace un carré de 40 pixels (côtés en couleurs 2 à 5, relus au milieu de chaque côté, l'intérieur restant à 0), puis avance crayon levé : rien n'est tracé (la même avance crayon baissé donne 7). En NeoBASIC, forward n fait cet appel, avec la couleur de pendown c (6 par défaut) ou crayon levé après penup.
Mots-clés NeoBASIC qui font cet appel : forward
Texte de la documentation du firmware (anglais)
Move the turtle forward by Parameter:0,1 degrees, drawing in colour Parameter:2 if Parameter:3 is non-zero.
C (llvm-mos)
/* Tracer un carré avec la tortue (groupe 9, fonction 3). */
#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)
;
}
int main(void) {
putchar(12);
neo_turtle_init(0); /* 9,1 : au centre (160, 120), cap vers le haut */
for (uint8_t c = 2; c <= 5; c++) {
neo_turtle_move(40, c, 1); /* Turtle Move : 40 pixels, couleur c, trait */
neo_turtle_turn(90);
}
neo_turtle_turn(180); /* demi-tour : vers le bas */
neo_turtle_move(20, 7, 0); /* crayon levé : rien n'est tracé */
uint8_t h = neo_graphics_read_pixel(160, 100); /* 5,33 : milieu de chaque côté */
uint8_t d = neo_graphics_read_pixel(180, 80);
uint8_t b = neo_graphics_read_pixel(199, 100);
uint8_t g = neo_graphics_read_pixel(180, 119);
uint8_t i = neo_graphics_read_pixel(180, 100); /* intérieur */
uint8_t l = neo_graphics_read_pixel(160, 130); /* sous le dernier déplacement */
neo_sprite_reset();
printf("Cotes : %u %u %u %u, interieur : %u\n", h, d, b, g, i);
printf("Crayon leve : %u\n", l);
return 0;
}Cotes : 2 3 4 5, interieur : 0
Crayon leve : 0Mad Pascal
// Tracer un carré avec la tortue (groupe 9, fonction 3).
program tortue3;
uses crt, neo6502;
var c, h, d, b, g, i, l: byte;
begin
write(chr(12));
TurtleInit(0); // 9,1 : au centre (160, 120), cap vers le haut
for c := 2 to 5 do begin
TurtleMove(40, c, 1); // Turtle Move : 40 pixels, couleur c, trait
TurtleRight(90);
end;
TurtleRight(180); // demi-tour : vers le bas
TurtleMove(20, 7, 0); // crayon levé : rien n'est tracé
h := NeoGetPixel(160, 100); // 5,33 : milieu de chaque côté
d := NeoGetPixel(180, 80);
b := NeoGetPixel(199, 100);
g := NeoGetPixel(180, 119);
i := NeoGetPixel(180, 100); // intérieur
l := NeoGetPixel(160, 130); // sous le dernier déplacement
NeoResetSprites;
writeln('Cotes : ', h, ' ', d, ' ', b, ' ', g, ', interieur : ', i);
writeln('Crayon leve : ', l);
end.Cotes : 2 3 4 5, interieur : 0
Crayon leve : 0NeoBASIC
10 ' Tracer un carre avec la tortue (groupe 9, fonction 3)
20 cls : turtle fast : ' la premiere commande prend le sprite 127 et montre la tortue
30 for c = 2 to 5
40 pendown c : forward 40 : right 90 : ' Turtle Move : 40 pixels, couleur c, trait
50 next c
60 right 180 : penup : forward 20 : ' demi-tour, crayon leve : rien n'est trace
70 h = point(160,100) : d = point(180,80) : b = point(199,100) : g = point(180,119) : ' milieu de chaque cote
80 i = point(180,100) : l = point(160,130) : ' interieur, sous le dernier deplacement
90 sprite clear
100 print "Cotes : ";h;" ";d;" ";b;" ";g;", interieur : ";i
110 print "Crayon leve : ";lCotes : 2 3 4 5, interieur : 0
Crayon leve : 0Assembleur 65C02 (64tass)
; Tracer un carré avec la tortue (groupe 9, fonction 3).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #2
sta couleur
_cote: lda #<avance
ldx #>avance
jsr envoi
lda #<d90
ldx #>d90
jsr envoi
inc couleur
lda couleur
cmp #6
bne _cote
lda #<demi
ldx #>demi
jsr envoi
lda #<leve
ldx #>leve
jsr envoi
lda #160
ldy #100
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta h
lda #180
ldy #80
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta d
lda #199
ldy #100
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta b
lda #180
ldy #119
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta g
; intérieur, puis sous le dernier déplacement
lda #180
ldy #100
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta i
lda #160
ldy #130
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta l
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda h
jsr decimal
lda #' '
jsr WriteCharacter
lda d
jsr decimal
lda #' '
jsr WriteCharacter
lda b
jsr decimal
lda #' '
jsr WriteCharacter
lda g
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda i
jsr decimal
lda #13
jsr WriteCharacter
lda #<t2
ldx #>t2
jsr ecrire
lda l
jsr decimal
lda #13
jsr WriteCharacter
rts
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
avance: .byte 9, 3, 4 ; 9,3 : Turtle Move, 40 pixels...
.word 40
couleur: .byte 2 ; ... dans cette couleur...
.byte 1 ; ... en traçant
d90: .byte 9, 2, 2 ; 9,2 : 90 degrés à droite
.word 90
demi: .byte 9, 2, 2 ; demi-tour : vers le bas
.word 180
leve: .byte 9, 3, 4 ; crayon levé : rien n'est tracé
.word 20
.byte 7, 0
t0: .text "Cotes : ", 0
t1: .text ", interieur : ", 0
t2: .text "Crayon leve : ", 0
h: .byte 0
d: .byte 0
b: .byte 0
g: .byte 0
i: .byte 0
l: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Cotes : 2 3 4 5, interieur : 0
Crayon leve : 09,4 Turtle Hide Officiel
Cache la tortue ; elle garde sa position et son cap.
Entrées : aucune.
Sorties : aucune.
Cachée, la tortue continue de tourner, d'avancer et de tracer. 6,5 rend alors la dernière position affichée. En NeoBASIC, turtle hide fait cet appel.
Mots-clés NeoBASIC qui font cet appel : turtle
Texte de la documentation du firmware (anglais)
Hide the turtle.
C (llvm-mos)
/* Montrer puis cacher la tortue (groupe 9, fonction 4). */
#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 uint8_t sprite_pixel(uint16_t x, uint16_t y) { /* 5,36 : couche des sprites */
libre();
ControlPort.params[0] = x & 0xFF;
ControlPort.params[1] = x >> 8;
ControlPort.params[2] = y & 0xFF;
ControlPort.params[3] = y >> 8;
api(5, 36);
return ControlPort.params[0];
}
int main(void) {
putchar(12);
neo_turtle_init(0);
neo_turtle_show(); /* 9,6 */
uint8_t vue = sprite_pixel(160, 120); /* la tortue est jaune (3) */
neo_turtle_hide(); /* Turtle Hide */
uint8_t cachee = sprite_pixel(160, 120);
neo_sprite_reset();
printf("Montree : %u, cachee : %u\n", vue, cachee);
return 0;
}Montree : 3, cachee : 0Mad Pascal
// Montrer puis cacher la tortue (groupe 9, fonction 4).
program tortue4;
uses crt, neo6502;
var vue, cachee: byte;
procedure TurtleShow; // 9,6 : Mad Pascal n'a pas cet appel
begin
NeoSendMessage(9, 6);
NeoWaitMessage;
end;
begin
write(chr(12));
TurtleInit(0);
TurtleShow; // 9,6
vue := NeoGetSpritePixel(160, 120); // la tortue est jaune (3)
TurtleHide; // Turtle Hide
cachee := NeoGetSpritePixel(160, 120);
NeoResetSprites;
writeln('Montree : ', vue, ', cachee : ', cachee);
end.Montree : 3, cachee : 0NeoBASIC
10 ' Montrer puis cacher la tortue (groupe 9, fonction 4)
20 cls
30 turtle show : ' la premiere commande prend le sprite 127 et montre la tortue
40 vue = spoint(160,120) : ' la tortue est jaune (3)
50 turtle hide : ' Turtle Hide
60 cachee = spoint(160,120)
70 sprite clear
80 print "Montree : ";vue;", cachee : ";cacheeMontree : 3, cachee : 0Assembleur 65C02 (64tass)
; Montrer puis cacher la tortue (groupe 9, fonction 4).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #<montre
ldx #>montre
jsr envoi
lda #160 ; la tortue est jaune (3)
ldy #120
jsr spixel
sta vue
lda #<cache
ldx #>cache
jsr envoi
lda #160
ldy #120
jsr spixel
sta cachee
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda vue
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda cachee
jsr decimal
lda #13
jsr WriteCharacter
rts
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
cache: .byte 9, 4, 0 ; 9,4 : Turtle Hide
t0: .text "Montree : ", 0
t1: .text ", cachee : ", 0
vue: .byte 0
cachee: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Montree : 3, cachee : 09,5 Turtle Home Officiel
Ramène la tortue au centre de l'écran, cap vers le haut, sans tracer.
Entrées : aucune.
Sorties : aucune.
Le centre dépend du mode d'affichage (la moitié de sa largeur et de sa hauteur). L'exemple éloigne la tortue (135 degrés, 50 pixels : 195, 155), la ramène, puis avance de 20 : elle monte bien, et le trait est au-dessus du centre. En NeoBASIC, turtle home fait cet appel, puis 9,6.
Mots-clés NeoBASIC qui font cet appel : turtle
Texte de la documentation du firmware (anglais)
Move the turtle to the home position (in the center, pointing upward).
C (llvm-mos)
/* Ramener la tortue au centre, cap vers le haut (groupe 9, fonction 5). */
#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)
;
}
int main(void) {
uint16_t x1, y1, x2, y2;
putchar(12);
neo_turtle_init(0);
neo_turtle_show(); /* 9,6 : visible, sa position se lit par 6,5 */
neo_turtle_turn(135);
neo_turtle_move(50, 0, 0); /* vers le bas à droite */
neo_sprite_position(0, &x1, &y1);
neo_turtle_home(); /* Turtle Home */
neo_turtle_move(20, 6, 1); /* 20 pixels : le cap est de nouveau vers le haut */
neo_sprite_position(0, &x2, &y2);
uint8_t c = neo_graphics_read_pixel(160, 110);
neo_sprite_reset();
printf("Avant : %u, %u\n", x1, y1);
printf("Apres 9,5 et 20 pas : %u, %u, trait %u\n", x2, y2, c);
return 0;
}Avant : 195, 155
Apres 9,5 et 20 pas : 160, 100, trait 6Mad Pascal
// Ramener la tortue au centre, cap vers le haut (groupe 9, fonction 5).
program tortue5;
uses crt, neo6502;
var c: byte;
x1, y1, x2, y2: word;
procedure TurtleShow; // 9,6 : Mad Pascal n'a pas cet appel
begin
NeoSendMessage(9, 6);
NeoWaitMessage;
end;
begin
write(chr(12));
TurtleInit(0);
TurtleShow; // 9,6 : visible, sa position se lit par 6,5
TurtleRight(135);
TurtleMove(50, 0, 0); // vers le bas à droite
NeoGetSpriteXY(0, x1, y1);
TurtleHome; // Turtle Home
TurtleMove(20, 6, 1); // 20 pixels : le cap est de nouveau vers le haut
NeoGetSpriteXY(0, x2, y2);
c := NeoGetPixel(160, 110);
NeoResetSprites;
writeln('Avant : ', x1, ', ', y1);
writeln('Apres 9,5 et 20 pas : ', x2, ', ', y2, ', trait ', c);
end.Avant : 195, 155
Apres 9,5 et 20 pas : 160, 100, trait 6NeoBASIC
10 ' Ramener la tortue au centre, cap vers le haut (groupe 9, fonction 5)
20 cls : turtle fast : ' la premiere commande prend le sprite 127 et montre la tortue
30 right 135 : penup : forward 50 : ' vers le bas a droite
40 x1 = spritex(127) : y1 = spritey(127)
50 turtle home : ' Turtle Home (puis 9,6 : montrer)
60 pendown 6 : forward 20 : ' 20 pixels : le cap est de nouveau vers le haut
70 x2 = spritex(127) : y2 = spritey(127) : c = point(160,110)
80 sprite clear
90 print "Avant : ";x1;", ";y1
100 print "Apres 9,5 et 20 pas : ";x2;", ";y2;", trait ";cAvant : 195, 155
Apres 9,5 et 20 pas : 160, 100, trait 6Assembleur 65C02 (64tass)
; Ramener la tortue au centre, cap vers le haut (groupe 9, fonction 5).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #<montre
ldx #>montre
jsr envoi
; visible : sa position se lit par 6,5
lda #<t135
ldx #>t135
jsr envoi
lda #<m50
ldx #>m50
jsr envoi
jsr position
lda px
sta x1
lda py
sta y1
lda #<maison
ldx #>maison
jsr envoi
lda #<m20
ldx #>m20
jsr envoi
jsr position
lda #160
ldy #110
ldx #33 ; 5,33 : Read Pixel
jsr pixel
sta c
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda x1
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda y1
jsr decimal
lda #13
jsr WriteCharacter
lda #<t1
ldx #>t1
jsr ecrire
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
lda c
jsr decimal
lda #13
jsr WriteCharacter
rts
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
t135: .byte 9, 2, 2 ; 9,2 : 135 degrés à droite
.word 135
m50: .byte 9, 3, 4 ; 9,3 : 50 pixels vers le bas à droite, sans tracer
.word 50
.byte 0, 0
maison: .byte 9, 5, 0 ; 9,5 : Turtle Home
m20: .byte 9, 3, 4 ; 20 pixels en couleur 6 : le cap est de nouveau vers le haut
.word 20
.byte 6, 1
t0: .text "Avant : ", 0
t1: .text "Apres 9,5 et 20 pas : ", 0
t2: .text ", trait ", 0
x1: .byte 0
y1: .byte 0
c: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Avant : 195, 155
Apres 9,5 et 20 pas : 160, 100, trait 69,6 Turtle Show Officiel
Montre la tortue : son sprite apparaît à sa position, orienté selon son cap.
Entrées : aucune.
Sorties : aucune.
C'est le seul appel qui montre la tortue (voir 9,2). Mad Pascal n'a pas de procédure pour cet appel : l'exemple écrit la boîte aux lettres. En NeoBASIC, turtle show fait cet appel ; la première commande de tortue et turtle home le font aussi.
Mots-clés NeoBASIC qui font cet appel : turtle
Texte de la documentation du firmware (anglais)
Show the turtle.
C (llvm-mos)
/* Montrer la tortue (groupe 9, fonction 6). */
#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 uint8_t sprite_pixel(uint16_t x, uint16_t y) { /* 5,36 : couche des sprites */
libre();
ControlPort.params[0] = x & 0xFF;
ControlPort.params[1] = x >> 8;
ControlPort.params[2] = y & 0xFF;
ControlPort.params[3] = y >> 8;
api(5, 36);
return ControlPort.params[0];
}
int main(void) {
uint16_t x, y;
putchar(12);
neo_turtle_init(0); /* 9,1 : cachée */
uint8_t avant = sprite_pixel(160, 120);
neo_turtle_show(); /* Turtle Show */
uint8_t apres = sprite_pixel(160, 120);
neo_sprite_position(0, &x, &y);
neo_sprite_reset();
printf("Avant : %u, apres 9,6 : %u, en %u, %u\n", avant, apres, x, y);
return 0;
}Avant : 0, apres 9,6 : 3, en 160, 120Mad Pascal
// Montrer la tortue (groupe 9, fonction 6).
program tortue6;
uses crt, neo6502;
var avant, apres: byte;
x, y: word;
procedure TurtleShow; // 9,6 : Mad Pascal n'a pas cet appel
begin
NeoSendMessage(9, 6);
NeoWaitMessage;
end;
begin
write(chr(12));
TurtleInit(0); // 9,1 : cachée
avant := NeoGetSpritePixel(160, 120);
TurtleShow; // Turtle Show
apres := NeoGetSpritePixel(160, 120);
NeoGetSpriteXY(0, x, y);
NeoResetSprites;
writeln('Avant : ', avant, ', apres 9,6 : ', apres, ', en ', x, ', ', y);
end.Avant : 0, apres 9,6 : 3, en 160, 120NeoBASIC
10 ' Montrer la tortue (groupe 9, fonction 6)
20 cls
30 while peek($ff00) : wend : poke $ff04, 0 : poke $ff01, 1 : poke $ff00, 9 : ' 9,1 : sprite 0, cachee
40 while peek($ff00) : wend : avant = spoint(160,120)
50 poke $ff01, 6 : poke $ff00, 9 : ' Turtle Show
60 while peek($ff00) : wend : apres = spoint(160,120) : x = spritex(0) : y = spritey(0)
70 sprite clear
80 print "Avant : ";avant;", apres 9,6 : ";apres;", en ";x;", ";yAvant : 0, apres 9,6 : 3, en 160, 120Assembleur 65C02 (64tass)
; Montrer la tortue (groupe 9, fonction 6).
.cpu "65c02"
* = $0800
ControlPort = $FF00 ; +0 groupe, +1 fonction, +2 erreur, +4.. paramètres
WaitMessage = $FFF4 ; attend que la boîte aux lettres soit libre
WriteCharacter = $FFF1 ; affiche le caractère de A
start: lda #12 ; écran effacé : on relit des pixels
jsr WriteCharacter
lda #<init
ldx #>init
jsr envoi
lda #160
ldy #120
jsr spixel
sta avant
lda #<montre
ldx #>montre
jsr envoi
lda #160
ldy #120
jsr spixel
sta apres
jsr position
lda #<raz
ldx #>raz
jsr envoi
lda #<t0
ldx #>t0
jsr ecrire
lda avant
jsr decimal
lda #<t1
ldx #>t1
jsr ecrire
lda apres
jsr decimal
lda #<t2
ldx #>t2
jsr ecrire
jmp montrerxy
; Couleur de la couche des sprites (5,36) ou du fond (5,33, si X = 33) en (A, Y), rendue dans A.
spixel: ldx #36
pixel: phx
pha
jsr WaitMessage
pla
sta ControlPort+4 ; P0-P1 : X (moins de 256 ici)
stz ControlPort+5
sty ControlPort+6 ; P2-P3 : Y
stz ControlPort+7
plx
lda #5
jsr appel
lda ControlPort+4
rts
; Position du sprite 0 (6,5), octets bas dans px et py (moins de 256 ici).
position:
jsr WaitMessage
stz ControlPort+4 ; P0 : sprite 0, la tortue
lda #6
ldx #5 ; 6,5 : Sprite Position
jsr appel
lda ControlPort+5
sta px
lda ControlPort+7
sta py
rts
px: .byte 0
py: .byte 0
; Affiche « px, py » et un retour à la ligne.
montrerxy:
lda px
jsr decimal
lda #<virg
ldx #>virg
jsr ecrire
lda py
jsr decimal
lda #13
jmp WriteCharacter
virg: .text ", ", 0
init: .byte 9, 1, 1, 0 ; 9,1 : Turtle Initialise, sprite 0 (tortue cachée)
montre: .byte 9, 6, 0 ; 9,6 : Turtle Show
raz: .byte 6, 1, 0 ; 6,1 : effacer les sprites avant de rendre la main
t0: .text "Avant : ", 0
t1: .text ", apres 9,6 : ", 0
t2: .text ", en ", 0
avant: .byte 0
apres: .byte 0
; Appel décrit par un bloc dont l'adresse est dans A (poids faible) et X (poids fort) :
; groupe, fonction, nombre de paramètres, puis les paramètres (P0, P1...).
envoi: sta blk
stx blk+1
jsr WaitMessage
ldy #2
lda (blk),y ; nombre de paramètres
clc
adc #3
sta fin
ldy #3
_copie: cpy fin
beq _lance
lda (blk),y
sta ControlPort+1,y ; octet 3 du bloc -> P0 ($FF04)...
iny
bra _copie
_lance: ldy #1
lda (blk),y
tax
lda (blk)
jmp appel
; Affiche la chaîne terminée par 0 dont l'adresse est dans A (poids faible) et X (poids fort).
ecrire: sta ptr
stx ptr+1
ldy #0
_e: lda (ptr),y
beq _f
jsr WriteCharacter
iny
bne _e
_f: rts
; Affiche A (0-255) en décimal, sans zéros de tête.
decimal:
phx
phy
ldx #0
ldy #100
jsr _chiffre
ldy #10
jsr _chiffre
ora #'0'
jsr WriteCharacter
ply
plx
rts
_chiffre:
sty diviseur
ldy #0
_div: cmp diviseur
bcc _fini
sbc diviseur
iny
bne _div
_fini: pha
tya
bne _ecrit
cpx #0
beq _saute
_ecrit: ora #'0'
jsr WriteCharacter
ldx #1
_saute: pla
rts
; Appel : A = groupe, X = fonction (les paramètres sont déjà en place).
appel: stx ControlPort+1
sta ControlPort ; écrit en dernier : lance l'appel
jmp WaitMessage
ptr = $80
blk = $82
diviseur: .byte 0
fin: .byte 0Avant : 0, apres 9,6 : 3, en 160, 120