Group 9 — Turtle Graphics Official
9,1 Turtle Initialise · 9,2 Turtle Turn · 9,3 Turtle Move · 9,4 Turtle Hide · 9,5 Turtle Home · 9,6 Turtle Show
The turtle is a pen you steer: it starts at the centre of the screen (160, 120 in mode 0), heading up, turns in degrees (to the right, clockwise) and moves in pixels, drawing or not. It is shown with one of the sprites, chosen by 9,1: a yellow arrow (colour 3) that follows its heading.
Its position is kept as real numbers and truncated to the pixel below when drawing: a side meant to land on x = 200 or y = 120 may land on 199 or 119. The examples read the lines back where they really land. The sprite position (6,5), for its part, is rounded.
The turtle is hidden after 9,1 and stays so until 9,6 is called, even while it turns or moves; until it has been shown, 6,5 returns 65535 for its position. NeoBASIC handles it on its own: its first turtle command calls 9,1 on sprite 127, then 9,6.
The examples clear the screen (they read pixels back, 5,33 and 5,36) and clear the sprites (6,1) before returning.
9,1 Turtle Initialise Official
Sets up the turtle: gives it a sprite, puts it at the centre, heading up, hidden.
| Bytes | Type | Meaning |
|---|---|---|
P0 | uint8 | number of the sprite the turtle takes |
Outputs: none.
The turtle image cannot be changed. The example checks that it is hidden (nothing on the sprite layer at the centre), then shows it (9,6): colour 3 at the centre, and 6,5 reads the position of sprite 0. NeoBASIC makes this call on its own, on sprite 127, at the first turtle command; the NeoBASIC example therefore writes the mailbox itself to take sprite 0.
Firmware documentation text
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, 12065C02 assembly (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 Official
Turns the turtle right by a number of degrees; a negative number turns it left.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | int16 | degrees: positive right, negative left |
Outputs: none.
Only the remainder of the division by 360 counts: turning by -450 is turning 90 to the left. The firmware documentation and llvm-mos say the call shows the hidden turtle; the code, official as well as Trinity, does not: the example still finds it hidden. In NeoBASIC, right n and left n make this call (left sends -n).
NeoBASIC keywords that make this call: right
Firmware documentation text
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, 10065C02 assembly (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 Official
Moves the turtle forward by a number of pixels along its heading, drawing or not.
| Bytes | Type | Meaning |
|---|---|---|
P0-P1 | int16 | distance in pixels (negative: moves back) |
P2 | uint8 | line colour (low 4 bits: 0 to 15) |
P3 | uint8 | not zero: draws |
Outputs: none.
The firmware documentation says "degrees": it is a distance in pixels. A line that would leave the screen is not drawn at all. The example draws a 40 pixel square (sides in colours 2 to 5, read back in the middle of each side, the inside staying at 0), then moves with the pen up: nothing is drawn (the same move with the pen down gives 7). In NeoBASIC, forward n makes this call, with the colour of pendown c (6 by default) or pen up after penup.
NeoBASIC keywords that make this call: forward
Firmware documentation text
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 : 065C02 assembly (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 Official
Hides the turtle; it keeps its position and heading.
Inputs: none.
Outputs: none.
While hidden, the turtle still turns, moves and draws. 6,5 then returns the last position shown. In NeoBASIC, turtle hide makes this call.
NeoBASIC keywords that make this call: turtle
Firmware documentation text
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 : 065C02 assembly (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 Official
Brings the turtle back to the centre of the screen, heading up, without drawing.
Inputs: none.
Outputs: none.
The centre depends on the display mode (half its width and height). The example takes the turtle away (135 degrees, 50 pixels: 195, 155), brings it back, then moves 20: it goes up, and the line is above the centre. In NeoBASIC, turtle home makes this call, then 9,6.
NeoBASIC keywords that make this call: turtle
Firmware documentation text
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 665C02 assembly (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 Official
Shows the turtle: its sprite appears at its position, turned to its heading.
Inputs: none.
Outputs: none.
This is the only call that shows the turtle (see 9,2). Mad Pascal has no procedure for this call: the example writes the mailbox. In NeoBASIC, turtle show makes this call; the first turtle command and turtle home make it too.
NeoBASIC keywords that make this call: turtle
Firmware documentation text
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, 12065C02 assembly (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