ARTICLES
66 / 74 |
Les Types de fichier
Nous allons partir a la découverte des différents types de fichier.
bit 0 | 1 si le fichier est protégé |
bits 1 et 2 |
00 = Basic 01 = Binaire 10 = Image écran (DUMP) 11 = ASCII |
bit 3 | Inutilisé |
bits 4 à 7 | Version toujours à 0, sauf dans le cas de fichiers ASCII pour lesquels le bit 4 est a 1. |
Les types de fichiers sont aux nombres de 8 :
&X00000000 = 0 (Basic)
&X00000001 = 1 (Basic protégé)
&X00000010 = 2 (Binaire)
&X00000011 = 3 (Binaire protégé)
&X00000100 = 4 (Ecran)
&X00000101 = 5 (Ecran protégé)
&X00010110 = 22 (ASCII)
&X00010111 = 23 (ASCII Protégé)
Fichier 0 (Basic), Fichier en user 0, nom = 0.BAS, début = &170 (368), longueur &F (15)
00 30 20 20 20 20 20 20 20 42 41 53 00 00 00 00
00 00 00 00 00 70 01 00 0F 00 00 00 00 00 00 00
Fichier 1 (Basic Protégé), Fichier en user 0, nom = 1.BAS, début = &170 (368), longueur &F (15)
00 31 20 20 20 20 20 20 20 42 41 53 00 00 00 00
00 00 01 00 00 70 01 00 0F 00 00 00 00 00 00 00
Fichier 2 (Binaire), Fichier en user 1, nom = BINBIN.BIN, debut = &1234, longueur = &5678, exécution = &9ABC
01 42 49 4E 42 49 4E 20 20 42 49 4E 00 00 00 00
00 00 02 00 00 34 12 00 78 56 BC 9A 00 00 00 00
Fichier 22 (Ascii) :
Entre la théorie et la pratique nous avons une petite différence sur CPC, en fait nous n'avons pas d'entête pour les fichiers ASCII, du coup comment savoir si nous avons affaire a un fichier ASCII protégé ou non ?
Ligne 1 :
Octet #00 : User (&00 a &FF)
Octets #01 a #0B : Nom du fichier (8 pour le nom, 3 pour l'extension)
Ligne 2 :
Octet #12 : Type de fichier
Octets #15 et #16 : adresse de début, lu selon le principe du poids fort et du poids faible, pour les fichiers 0 et 1 ça sera &70 &01 qui se lira &0170 (368 en décimal) soit l'adresse de début en mémoire pour un fichier Basic.
Octets #18 et #19 : longueur du fichier, ici aussi ça sera lu selon le principe du poids forts et du poids faible (la taille maximum pour un fichier est 65 Ko (&FFFF)
Octets #1A et #1B : adresse d'exécution du fichier binaire, toujours lu selon le principe du poids forts et du poids faible.
10 PRINT "TEST"
On sauvegarde notre petit listing par : SAVE"FICHIER.BAS"
Pour le recharger en mémoire nous faisons : LOAD"FICHIER.BAS"
Un petit LIST et nous récupérons notre ligne.
Classique, rien a signaler.
L'exemple sera stocké comme suit : 0D 00 0A 00 BF 20 22 54 45 53 54 22 00 00 00 ......"TEST"...
10 PRINT "TEST"
On sauvegarde notre petit listing par : SAVE"FICHIER.BAS",P (le paramètre P pour Protéger)
Pour le recharger en mémoire nous faisons : LOAD"FICHIER.BAS" et nous avons un petit souci, impossible de le lister.
L'exemple sera stocké comme suit : A6 2C E7 EA D3 17 1D B8 DE 8C 2E 2E 3B D4 6D .,..........;.m
Lorsqu'on charge un fichier, c'est le 1er bloc qui va être lu, le CPC du coup va pouvoir connaître le type de fichier, son adresse de chargement, sa longueur et surtout s'il est protégé, et s'il est protégé il va modifier la mémoire en écrivant la valeur &FF (255) à l'adresse mémoire &AE45 (pour CPC 464) ou &AE2C (pour les CPC 664 et 6128).
Le programme Deprotej part de ce constat et va modifier le chargement du fichier en remettant l'adresse &AE45 (pour CPC 464) ou &AE2C (pour les CPC 664 et 6128) a zéro après la lecture du 1er bloc du fichier.
Une petite astuce pour les CPC 464, il suffit de taper 3 pokes avant le chargement du fichier Basic protégé :
POKE &AC02, &90
POKE &AC03, &C0
POKE &AC01, &C3
LOAD"FICHIER.BAS"
LIST
L'ordre de saisie des pokes a son importance, en fait nous demandons un JP #C090, qui correspond dans la ROM supérieure à l'affichage du READY.
En basic, nous pouvons facilement sauvegarder un fichier Binaire (par exemple l'écran)
SAVE "PROGRAM.BIN",B,&C000,&4000,&DEAD
B correspond au BINAIRE
&C000 = l'adresse de début en mémoire
&4000 = la longueur a sauvegarder
&DEAD = l'adresse d'exécution du fichier Binaire (ici c'est complétement fantaisiste et ça devrait rappeler des souvenir à ertains).
Pour recharger l'écran, il faut faire LOAD"PROGRAM.BIN",&C000
Si le programme avait du être chargé en &4000, nous aurions du abaisser la mémoire (&4000 - 1 = &3FFF)
MEMORY &3FFF:LOAD"PROGRAM.BIN",&4000
Si le chargement se situe encore plus bas en mémoire, nous sommes obligés d'utiliser la commande OPENOUT :
OPENOUT "D":MEMORY &3E7:CLOSEOUT:LOAD"PROGRAM.BIN",&3E8
A ma connaissance, il n'est pas possible de sauvegarder un fichier binaire protégé directement en basic, il faut passer par une routine en assembleur.
Voici un cours programme en assembleur pour sauvegarder la page écran.
HEXA |
ASSEMBLEUR |
COMMENTAIRES |
06,0C | ld B,#0C | Longueur du nom du fichier |
21,1D,BE | ld HL,#BE1D | Adresse de stockage du nom du fichier |
11,40,00 | ld DE,#0040 | Adresse d'un tampon de 2K |
CD,8C,BC | call #BC8C | Ouverture d'un fichier en sortie |
21,00,C0 | ld HL,#C000 | Adresse de début a sauvegarder |
11,00,40 | ld DE,#4000 | Longueur des données |
01,AD,DE | ld BC,#DEAD | Adresse d'exécution du fichier sauvegardé |
3E,03 | ld a,3 | Type de fichier (3 = binaire protégé) |
CD,98,BC | call #BC98 | Ecriture directe du contenu des données dans un fichier |
CD,8F,BC | call #BC8F | Fermeture propre d'un fichier en sortie |
C9 | ret | Retour |
Pour ceux qui n'ont pas d'assembleur ou qui préfèrent utiliser le basic, voici comment faire :
10 DATA 06,0C
20 DATA 21,1D,BE
30 DATA 11,40,00
40 DATA CD,8C,BC
50 DATA 21,00,C0
60 DATA 11,00,40
70 DATA 01,00,C0
80 DATA 3E,03
90 DATA CD,98,BC
100 DATA CD,8F,BC
110 DATA C9
120 DATA 45,43,52,41,4E,20,20,20,2E,42,49,4E
130 FOR i=&BE00 TO &BE28:READ A$:POKE I,VAL("&"+a$):NEXT
140 MODE 1:CALL &BE00
150 PRINT CHR$(7):CALL &BB06
160 CLS:LOAD"ECRAN.BIN",&C000
La routine BASIC avec le code ASSEMBLEUR va sauvegarder la zone écran de 17 Ko dans le fichier "ECRAN.BIN" en mode Binaire protégé.
Ensuite, lorsque vous entendrez le BEEP, si vous appuyez sur une touche, vous verrez l'écran se charger. Nous voyons des traits a l'écran, c'est juste le décodage des blocs au fur et à mesure.
Sauvegarder un fichier binaire en mode protégé ne sert pas à grand chose, le fichier est certes protégé sur la disquette, mais cela n'empêche en rien son chargement (et son décodage automatique), contrairement au Basic.
...
...
American Standard Code for Information Interchange.
Plusieurs techniques sont possibles.
1) Fichier de programmation basic sauvegardé en ASCII.
SAVE"FICHIER.TXT",A
Je vois déjà pointer la question, mais a quoi ça sert ?
Imaginons que nous ayons un gros programme basic et que nous voulions le découper de telle façon que nous puissions charger/décharger différentes parties.
Voici un petit exemple tout bête concernant cette idée :
- Programme principal
10 MODE 1
20 a=1
30 REM MENU PRINCIPAL
40 IF A=1 THEN CHAIN MERGE "partie1.BAS",30000,DELETE 30000-
50 IF A=2 THEN CHAIN MERGE "partie2.BAS",30000,DELETE 30000-
60 IF A=3 THEN CHAIN MERGE "partie3.BAS",30000,DELETE 30000-
70 GOTO 30
- partie1.bas : numérotation commençant en 30000
30000 PRINT "A = ";A
30010 PRINT "PARTIE 1"
30020 CALL &BB06
30030 CLS
30040 a=2:GOTO 30
- partie2.bas : numérotation commençant en 30000
30000 PRINT "A = ";A
30010 PRINT "PARTIE 2"
30020 CALL &BB06
30030 CLS
30040 a=3:GOTO 30
- partie3.bas : numérotation commençant en 30000
30000 PRINT "A = ";A
30010 PRINT "PARTIE 3"
30020 CALL &BB06
30030 CLS
30040 a=1:GOTO 30
L'avantage d'utiliser CHAIN MERGE c'est que les variables ne seront pas détruites.
2) Fichier de texte brut
Je vais me référer a une ancienne routine que j'avais écrite pour le fanzine papier "Le Canard Déchainé" (Coucou Toug), Les Fichiers Ascii
LECTURE
1 'QUETZALCOATL & KUKULCAN
10 MODE 2:BORDER 0:INK 0,0:INK 1,26:PEN 1
15 PRINT "APPUYER SUR UNE TOUCHE POUR AFFICHER UNE LIGNE":PRINT
20 OPENOUT "D":MEMORY &3000:CLOSEOUT
30 INPUT "NOM DU FICHIER ASCII A CHARGER ";NOM$
40 IF NOM$="" THEN CAT:GOTO 30
50 CLS:OPENIN NOM$
60 WHILE NOT EOF:LINE INPUT #9,A$:PRINT A$
70 WHILE INKEY$<>"":WEND
80 CALL &BB06:WEND:CLOSEIN:CALL &BB03:CALL &BB06:GOTO 30
ECRITURE
1 'QUETZALCOATL & KUKULCAN
10 MODE 2:BORDER 26:INK 0,26:INK 1,0:PEN 1
15 PRINT "Saisir le mot 'END' pour sauvegarder le fichier":PRINT
20 OPENOUT "D":MEMORY &3000:CLOSEOUT
30 INPUT "NOM DU FICHIER ASCII A CREER";NOM$
40 IF NOM$="" THEN 40
50 OPENOUT NOM$
60 LINE INPUT "",A$
65 IF UPPER$(A$)="END" THEN CLOSEOUT:END
70 PRINT #9,A$
90 GOTO 60
3) Fichier de données
Voici un petit exemple :
ECRITURE du fichier "DATA" avec 2 champs de données
10 OPENOUT "DATA"
20 for I=1 to 10
30 PRINT #9,I
40 PRINT #9,(I*9)
50 NEXT
60 CLOSEOUT
LECTURE du fichier "DATA" avec 2 champs de données
10 OPENIN "DATA"
20 for I=1 to 10
30 INPUT #9,A
40 INPUT #9,B
50 PRINT A;" * 9 = ";B
60 NEXT
70 CLOSEIN
...
Article rédigé par : T&J/GPA, Kukulcan
Article créé le : | Jeudi 14 Février 2013 à 10 h 57 |
Dernière mise à jour le : | Mercredi 20 Février 2013 à 09 h 23 |