Pour comprendre le format des programmes DAI, il faut d'abord comprendre comment sont calculés les checksums. Commençons donc par les checksums...
Nous verrons ensuite le format d'un programme DAI Comment le DAI calcule-t-il un checksum ?Principe d'un code de contrôle d'erreurComme son nom l'indique, un checksum est une somme de contrôle, c'est en quelque sorte la preuve par neuf de l'informaticien. Lorsqu'on lit une suite d'octets à partir d'un média, on risque d'avoir des erreurs de transmission entre l'émetteur et le récepteur, mais comment savoir qu'une erreur s'est produite ? C'est là qu'intervient le contrôle de checksum ! Le principe est le suivant : L'émetteur et le récepteur doivent d'abord connaître les règles appliquées, on parle alors d'adopter un protocole de communication. Le protocole pourrait être le suivant par exemple : L'émetteur n'envoie que des paquets de 10 octets, suivis de deux octets représentant la somme de tous les octets. Prenons un exemple où l'émetteur veut envoyer 00 01 02 03 04 05 06 07 08 09 la somme fait 45, il doit donc envoyer deux octets supplémentaires représentant la somme 45, soit 00 2DSi la transmission se passe bien, le récepteur doit recevoir les 10 octets plus les 2 octets de contrôle. Il doit ensuite refaire le même calcul que l'émetteur, c'est à dire additionner les 10 octets de donnée et comparer le résultat avec les deux octets de contrôle reçus. Si la somme fait bien 45, alors il peut supposer que la transmission est correcte. Si la somme ne correspond pas aux 2 octets de contrôle, alors c'est qu'il y a soit une erreur sur le bloc de données, soit sur le code de contrôle lui-même, soit sur les deux si la liaison est très mauvaise. Dans ce cas le récepteur demandera la réémission à l'émetteur ou bien mettra fin à la transmission. Bien sûr les algorithmes sont plus subtiles que l'exemple ci-dessus... Voici l'exemple du DAI : Le checksum implémenté dans le firmware du DAILes données sur cassettes sont organisées en blocs et chaque bloc de données est contrôlé par un checksum. Pour identifier les checksums des données, il faut donc connaître la façon dont ils sont calculés. L'algorithme est le suivant. Au préalable il faut savoir que le DAI ne génère que des checksums ayant une taille d'un octet. 1° CKS = 56H ; Initialisiser le checksum avec la valeur 56H 2° Octet = Lire le premier octet du bloc 3° CKS = CKS XOR Octet ; On fait un XOR entre le ckecksum et la valeur de l'octet; 4° CKS = RLC (CKS) ; Permutation circulaire à gauche de tous les bits de CKS :
Ceci donne la nouvelle valeur du checksum 5° Tant que le bloc n'est pas fini, on lit l'octet suivant du bloc et on répète les étapes 3 et 4
Exemple, soit la suite d'octet suivante : 43 4F 50 59 20 4B 37 20 52 53 32 33 32 20 4F 42 4A Il s'agit de la représentation hexadécimale du nom de programme "COPY K7 RS232 OBJ". En exécutant l'algorithme ci-dessus, voici ce que l'on obtient : |
0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | <=== Valeur initiale checksum (#56) |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |
0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | |
1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | |
1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | |
0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | |
0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | |
1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | |
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | |
1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | |
0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | |
0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | |
1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | |
1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | |
0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | |
0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | |
0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | |
0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | |
1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | |
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | |
1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | |
1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | |
0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | |
0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | |
1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | |
1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | |
1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | |
1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | |
0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |
La valeur finale obtenue est 13H ce qui correspond au checksum.
La première ligne bleue correspond au XOR entre la valeur 56H et la valeur du premier octet 43H ce qui donne 15H.
La première ligne marron correspond à la rotation gauche des bits de 15H, ce qui donne 2AH.
La deuxième ligne bleue correspond au XOR entre la valeur du checksum obtenue à l'étape précédente (2AH) et la valeur du deuxième octet de données 4FH, ce qui donne 65H.
La deuxième ligne marron correspond à la rotation gauche des bits de CAH, ce qui donne 35H
Et ainsi de suite jusqu'à la fin.
J'ai conçu ce petit fichier Excel pour faciliter l'identification des checksum dans un fichier de DAI, il m'a rendu de grands services, vous pouvez le télécharger ici : Cheksum.zip
Format d'un programme DAI
Examinons un programme que vous connaissez peut-être déjà si vous avez lu la page liaison DAI PC Voici ce que vous découvririez si vous parcouriez un à un les octets du fichier constituant le programme "COPYK7RS232.BIN G7000".
Code binaire | Signification | Valeur décimale | Commentaires | Nom donné à la zone | |
---|---|---|---|---|---|
31 | Code d'un fichier binaire | 1 | TypeFichier | ||
00 15 | Longueur du nom de programme | 21 | LgNom | ||
73 | Checksum des 2 octets précédents | CksLgNom | |||
43 4F 50 59 4B 37 52 53 32 33 32 2E 42 49 4E 20 47 37 30 30 30 | COPYK7RS232.BIN G7000 | Les 21 octets du nom | Nom | ||
E9 | Checksum des 21 octets du nom | CksNom | |||
00 02 | Longueur de l'adresse d'implantation du programme en mémoire | LgAdrProg | |||
5D | Checksum de l'adresse d'implantation du programme en mémoire | CksLgAdrProg | |||
00 70 | Adresse d'implantation du programme en mémoire, l'octet le moins significatif (LSB) étant stocké en premier, il faut lire 7000H | 28672 | C'est à cette adresse que sera logé le programme binaire exécutable | AdrProg | |
B9 | Checksum de l'adresse d'implantation du programme en mémoire | CksAdrProg | |||
00 5A | Longueur du programme exécutable | 90 | LgProg | ||
ED | Checksum de la longueur du programme exécutable | CksLgProg | |||
21 B9 D7 | LXI | H,:D7B9 |
Les 90 octets du programme exécutable. Ils seront donc chargés à partir de l'adresse 7000H Pour ceux qui ont lu la page liaison DAI PC vous aurez reconnu le programme permettant de lire une cassette et d'envoyer les octets un à un sur la sortie série RS232.
|
Prog | |
11 A4 D7 | LXI | D,:D7A4 | 01 C5 02 | LXI | B,:02C5 |
CD 4F DE | CALL | :DE4F | |||
21 3B 70 | LXI | H,MESS1$ | |||
CD D4 DA | CALL | :DAD4 | |||
CD BB D6 | CALL | :D6BB | |||
DA 09 E0 | JC | :0E009 | |||
CA 12 70 | JZ | GETC | |||
FE 31 | CPI | :31 | |||
C2 0C 70 | JNZ | DEBUT | |||
F3 | DI | ||||
CD 2E D4 | CALL | :D42E | |||
CD F4 D3 | CALL | :D3F4 | |||
F3 | DI | ||||
2A 72 00 | LHLD | :72 | |||
77 | MOV | M,A | |||
32 06 FF | STA | :FF06 | |||
CD D4 D4 | CALL | :D4D4 | |||
D2 27 70 | JNC | SUIT1 | |||
CD 45 D4 | CALL | :D445 | |||
C3 0C 70 | JMP | DEBUT | |||
0C 0D 0D | DATA | :C,:D,:D | |||
28 31 29 3D 4C 4F 41 44 | ASC | '(1)=LOAD' | |||
0D | DATA | :D | |||
28 42 52 45 41 4B 29 3D 55 54 | ASC |
'(BREAK)=UT' |
|||
0D 0D | DATA | :D,:D | |||
43 48 4F 49 58 3F | ASC |
'CHOIX?' |
|||
00 | DATA | 0 | |||
2C | Checksum des 90 octets du bloc programme précédent | CksProg |