Structure d'un fichier .K7 VG5000

Révision du 27/04/2014



Attention !! Informations partielles, tout n'est pas clair dans cette structure (comme d'habitude, aucun document officiel, grrr... )

Les bases

Le VG5000 est capable de manipuler différents types de fichiers :

- Basic
- Binaire
- Screen (image)
- Tableau
- Chaîne
- Basicode

La sauvegarde d'un fichier utilise la commande CSAVE (SAVE pour le format Basicode).

Le chargement d'un fichier utilise la commande CLOAD (LOAD pour le format Basicode).

Les fichiers ont tous le même format sauf les fichiers BASICODE.

Le format BASICODE est censé assurer une portabilité d'un listing Basic avec d'autres machines. Il est en théorie possible de charger sur un autre type d'ordinateur un fichier créé avec le VG5000. Cela n'a que peu d'intérêt de nos jours, il faut bien l'avouer. Nous n'aborderons dans la suite de ce texte que les formats de fichiers propres au VG5000.

Un fichier K7 VG5000 se compose de trois zones :

- un "header" ou "en-tête" de 42 octets (&2A) commençant par 10 octet &D3 et se terminant par 10 octets &D6.

- la zone de données

- un "footer" ou "fin de fichier" de 10 octets à &00

En fonction du type d'un fichier, le header contient plus ou moins d'informations dans ses 42 octets.

Le footer est, lui, toujours le même.

Afin de valider que le contenu d'un fichier n'est pas endommagé, le header contient un "checksum", une valeur 16 bits qui est la somme des différents octets de la zone de données.


Les différents types de Headers

Fichier BINAIRE

IndexValeur hexadécimaleCommentaire
&0000&D310 octets identiques
&000AMType fichier Binaire 1 octet
&000BNom du fichier6 octets (fin = 0 si moins de 6 octets)
&0011&00Fin du nom du fichier ?
&0012&008 octets inutilisés
&001AImplantation du fichierDeux octets
&001CLongueur du fichierDeux octets
&001E&xxChecksum, deux octets
&0020&D610 octets identiques
&002Avariabledébut de la zone de données

L'octet &000A semble ne pas être très important. La plupart des jeux commerciaux du VG5000 sont en assembleur mais sont lancés par le BASIC avec une commande CALL. Je suppose que cette technique est censée palier le fait qu'il n'y a pas dans le header d'adresse d'exécution pour un fichier binaire. Du coup, même si l'octet &0A est différent de "M", le programme se charge correctement.

Calcul du checksum : simple addition des valeurs des octets de données, sans tenir compte du header ni du footer.

Exemple :

Header K7 MCODE/Machaon (Binaire)

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 4D 43 4F 44 45 00 ..........MCODE.
4F 00 00 00 00 00 00 00 00 00 00 70 20 0D 40 B6 0..........p .@.
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................


Fichier implanté en &7000, longueur &D20


Fichier BASIC

Les lignes grisées correspondent à du code Basic. Comme la fin d'un fichier Basic est particulière, j'ai voulu représenter ici à la fois le début et la fin d'un ficher.

IndexValeur hexadécimaleCommentaire
&0000&D310 octets identiques
&000A&20Type fichier Basic
&000BNom du fichier6 octets (fin = 0 si moins de 6 octets)
&0011&00Fin du nom du fichier ?
&00121ère ligne à exécuter5 octets maxi 1 octet = 1 chiffre (ex : 10 = &31 &30) si elle a été indiquée valeur entre 1 et 65529. lors de la sauvegarde Si tous les octets ne sont pas remplis, on met des &00
&0017&00Fin de la ligne à exécuter ?
&0018&00Pas utilisé
&0019&00Pas utilisé
&001A&FC &49Implantation en mémoire du fichier, deux octets (toujours &49FC)
&001CLongueur du fichierDeux octets
&001Echecksumchecksum sur les données A priori, on ne tient pas compte du header
&0020&D610 octets identiques
&002A-Implantation de la ligne Basic suivant la première ligne
&002C-code 1ère ligne Basic
---
(fin - &0D)&00 &00 &00Fin du code Basic (adresse fin de ligne en mémoire à &0000)
(fin - &0A)&00Footer - 10 octets à &00 pour indiquer la fin du fichier.


Supprimer la ligne de départ dans le header d'un fichier BASIC permet de le charger en mémoire sans qu'il ne s'exécute.

Calcul du checksum : comme pour un fichier binaire.

Exemple :

Header K7 test (Basic)

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 20 4A 41 43 4B 50 .......... TEST.
4F 00 00 00 00 00 00 00 00 00 FC 49 11 00 0D 05 0..........I....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

Fichier implanté en &49FC, longueur &11, pas d'adresse d'exécution

Header K7 test2 (Basic)

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 20 4A 41 43 4B 50 .......... TEST.
00 00 36 35 35 32 33 00 00 00 FC 49 10 00 EC 04 ..65523....I....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

Fichier implanté en &49FC, longueur &10, ligne de depart 65523


Fichier BASIC protégé

Ce header particulier empêche le chargement manuel du programme même lorsque les octets correspondant à la ligne Basic sont supprimés. Il a été trouvé dans le jeu "Tarot" de Nice Ideas. Par rapport à un header standard :

IndexValeur hexadécimaleCommentaire
&0017&21à quoi cela correspond-il ? Mystère. Des valeurs autres que &00 donnent le même résultat.

Si vous supprimez simplement le numéro de ligne (octets &0011 à &0016), le programme fait un reset lorsque vous faites une commande LIST. Si vous supprimez aussi l'octet &0017, le programme est listable.

On retrouve cette protection sur d'autres programmes commerciaux.

Exemple :

Header K7 Jackpot/Divertissements (Basic)

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 20 4A 41 43 4B 50 .......... JACKP
4F 00 31 00 00 00 00 03 00 00 FC 49 FC 17 9C E3 0.1........I....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

Fichier implanté en &49FC, longueur &17FC, ligne de depart 1 Octet &17 pas à zero, fichier protégé.


D'autres formats de fichiers existent sur le VG5000, c'est d'ailleurs assez étonnant pour une "petite" machine. Malheureusement, ils sont assez difficiles à exploiter voire inutilisables...


Fichier IMAGE (commande CSAVES)

Même principe qu'un fichier binaire standard, si ce n'est que l'octet 11 est un S (Screen) au lieu de M (Memory ?).
Ce format de fichier ne contient que la zone ram vidéo dans la mémoire du VG5000. On ne retrouve pas les tables de caractères redéfinis.

exemple :

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 20 4A 41 43 4B 50 ..........SIMAGE
00 00 00 00 00 00 00 03 00 00 00 40 D0 07 1F BB 0.1........@....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

Fichier implanté en &4000, longueur &7D0


Fichier TABLEAU (commande CSAVE*)

L'octet 11 a la valeur &BB.

exemple :

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 BB 4A 41 43 4B 50 ...........HERVE
00 00 00 00 00 00 00 03 00 00 00 59 2F 00 E1 02 ...........@....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

L'adresse d'implantation du fichier correspond au fait à l'emplacement en mémoire du tableau lors de sa sauvegarde (ici &5900).

Les données peuvent être rechargées avec la commande CLOAD*. ex : on lit le contenu du fichier TEST dans un tableau numérique A.

CLOAD* "TEST" A

Le tableau doit avoir été déclaré à l'aide d'une commande DIM avant le chargement.

Malheureusement, CLOAD* ne permet pas de sauvegarder des tableaux de chaînes de caractères. Le VG5000 accepte pourtant de faire une sauvegarde avec comme paramètre un tableau de type chaîne. Quel est donc ce mystère...

1 CLEAR 100,&"6FFF"
10 DIM A$(9)
20 FOR I=0 TO 9
30 A$(I)="TOTO"
40 NEXT I
50 CSAVE*"TEST" A$

Si vous éditez le contenu du fichier, il contient pour chaque élément du tableau non pas la chaîne "TOTO" mais un pointeur sur cette chaîne en mémoire, sa longueur et un séparateur (&7E). Le VG5000 ne sauvegarde donc pas les données de l'utilisateur mais sa propre cuisine interne.


Fichier CHAINE (commande CSAVEX)

L'octet 11 a la valeur &58 (X).

exemple :

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 58 54 45 53 54 00 ...........TEST.
00 00 00 00 00 00 00 00 00 00 04 4A 10 00 43 04 ...........@....
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

L'adresse d'implantation du fichier correspond au fait à l'emplacement en mémoire de la chaîne tableau lors de sa sauvegarde (ici &4A04).

La commande de chargement est : CLOAD "TEST" A$

Grosse contrainte à l'usage de cette commande, la variable dans laquelle la chaîne doit être stockée doit avoir une longueur minimale égale à celle de la chaîne sauvegardée. Si elle est plus longue, les caractères "en trop" ne seront pas écrasés. Bref, là aussi, usage restreint.

Au final, on comprend pourquoi les rares bouquins présentant des listings VG5000 ont fait l'économie d'une gestion de fichiers, les commandes VG5000 ne permettent pas facilement de sauvegarder des données utilisateur...
"Carnet d'adresses" de Loriciels par exemple sauvegarde les données sous la forme d'un fichier binaire.


Mélanger BASIC et BINAIRE dans un fichier

Il est possible de créer un fichier contenant à la fois des données Basic et binaire. Cela sert en général à limiter le nombre de fichiers à charger, et présente aussi l'avantage de protéger un petit peu le programme.
La technique trouvée pour générer ce type de fichier nécessite l'usage de l'émulateur DcVg5k. On doit pouvoir aussi le faire avec un vrai VG5000, mais c'est plus compliqué car il faudra implanter en mémoire une routine de chargement du programme binaire.

Les programmes commerciaux Philips en abusent pourtant, il doit donc y avoir une technique d'enregistrement permettant de créer des fichiers valides à coup sûr (programme externe au VG5000 ?).

Exemple :

Header K7 U.S.Rallye (Basic mixé avec binaire)

D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 4D 56 47 35 30 30 ..........MVG500
30 00 31 30 00 00 00 00 00 00 FC 49 80 34 59 95 0.10.......I.4Y.
D6 D6 D6 D6 D6 D6 D6 D6 D6 D6 xx xx xx xx xx xx ................

Fichier Basic/binaire, exécution en &49FC, longueur &3480, ligne de départ en 10

Méthode DcVg5k:

- Faire un reset de la machine.
- Charger le programme Basic
- Injecter en mémoire le programme binaire (avec la touche de commande "F9").
- Sauvegarder le tout avec une commande CSAVEM"PROG",&"49FC",&"longueur totale du code"

Miracle, le fichier peut être rechargé et est listable !
Si vous faites une réinitialisation à chaud, le programme se corrompt.

Attention ! Cette technique est pour l'instant totalement instable, et les programmes ne fonctionneront pas forcément. Plantage assuré avec de gros programmes.

L'analyse du header montre que le programme est considéré comme du binaire.

Etrangement, suivre la même procédure en ayant protégé la mémoire réservée au binaire avec une commande direct CLEAR xxx,&"yyyy" génère un fichier corrompu (message ERREUR FICHIER lors d'une tentative de chargement). Seule différence par rapport à la "bonne" méthode, le checksum est différent.