Forum Graph100

Forum Graph100

Vous n'êtes pas identifié.

Annonce

Bonjour et bienvenue sur le nouveau Forum Graph100 !
L'intégralité des données a été transférée sur un forum PunBB et tout les comptes sont fonctionnels avec le même nom d'utilisateur et mot de passe.
Un wiki est aussi disponible avec le même compte ! N'oubliez pas de remettre votre avatar, bon surf !
Pour plus d'informations, consultez ce post.

#1 23 Feb 2004 17:36:50

mastermage
Magicien G100
Lieu: Charleville-Mézières,Compiègne
Date d'inscription: 31 Jan 2002
Messages: 1008

Doc sur le format RomDISK (merci mes doigts)

Voila g tapé tt ca ce soir, et en plus g perdu quelques neurones... lisez si vous en avez le courage, et dites moi ce qui va pas (ou bien)

Code:

Le format ROMDISK de la Casio Graph100/Algebra FX 2/FX 1 (+)
version 2 - mastermage <mastermage AT bluelab DOT net>

____________________ Intro :

Le format ROMDISK, utilisé par ROM-DOS pour le stockage des fichiers sur
graph100, n'est autre qu'une déclinaison du système de fichiers FAT de
Microsoft pour MS-DOS.
J'expliquerai ici les differentes parties de ce système de fichiers, mais
vous pouvez toujours aller voir la documentation officielle de Microsoft.

____________________ Generalites :

Les processeurs Intel utilisent un mode de stockage appelé Litte Endian
(par opposition au Big Endian). Pour des raisons historiques (MS-DOS
ayant ete cree sur des PC) le systeme de fichiers FAT est lui aussi en L.E.
Mais qu'est-ce que le Little Endian ? C'est tout simplement de mettre en mémoire
l'octet le moins significatif (le LSB pour Less Signifiant Byte, en anglais)
en premier, et l'octet le plus significatif en dernier (le MSB, le Most
Signifiant Byte).
exemple: la valeur 0x1D4EF28C sera en mémoire 8C F2 4E 1D.
Je ne sais pas pourquoi cette organisation plutôt que l'autre (le Big Endian
est tout simplement le contraire) mais il faut juste s'y habituer.
D'autre part ca signifie que sur une machine de type Intel vous n'aurez rien a
changer (vu que la plupart des gens ont un PC) mais dans le cas d'un Mac par 
exemple il faudra faire l'inversion des octets !

Les valeurs précédées d'un 0x sont en hexadecimal, les autres valeurs sont en 
décimal.

____________________ Structure d'un lecteur ROMDDISK :

Un système de fichiers de type FAT est composé de quatre zones (dans l'ordre) :
  0 - une zone reservée
  1 - la zone contenant la File Allocation Table, ou FAT (d'où le nom du système
    de fichiers)
  2 - la zone du répertoire racine (Root Directory)
  3 - la zone des dossiers et fichiers
  
____________________ Secteur de Boot /BPB :

La première partie importante d'un volume FAT, c'est sa zone reservée, contenant
le BPB (BIOS Parameter Block) qui est situé dans le tout premier secteur du
volume, le secteur communément appelé secteur de boot.
Le BPB est une structure contenant beaucoup d'information très utiles sur le
systeme de fichiers.

j'utiliserai les noms donnés par Microsoft, parce que d'une part ils sont bien
choisis et d'autre part pour s'y retrouver par rapport à d'autres documentations
sur le systeme de fichiers FAT.

Name   Offset (octets) Longueur (octets)                Description
BS_jmpBoot    0    3    Instruction de saut vers le code de Boot, peut
                                prendre deux formes differentes:
                                jmpBoot[0] = 0xEB, jmpBoot[1] = 0x??,
                                        jmpBoot[2] = 0x90
                                ou
                                jmpBoot[0] = 0xE9, jmpBoot[1] = 0x??,
                                        jmpBoot[2] = 0x??

                                0x?? veut dire qu'on peut placer n'importe
                                quelle valeur dans cet octet. En fait c'est
                                une instruction de saut inconditionnel, dans le
                                langage machine x86 (et donc du V30 qui équipe
                                les graph100s), vers une routine d'
                                initialisation du systeme d'exploitation.
                                C'est d'ailleurs le code de Boot qui occupe le
                                reste de la zone reservee apres le BPB.
                                La premiere version est plus frequemment
                                utilisée.

BS_OEMName    3    8    Sur graph100 c'est "DLRDISK" (suivi de la
                                valeur 0 pour occuper les 8 octets). La
                                documentation de Microsoft affirme que ce champ
                                n'est qu'une chaine sans importance indiquant
                                quel système a formatté le volume , mais aussi
                                que certains pilotes (drivers) y font
                                attention. Dans l'incertitude par rapport à la
                                graph100 mieux vaut utiliser "DLRDISK".

BPB_BytsPerSec    11    2    Nombre d'octets par secteur. Ce champ peut
                                prendre les valeurs suivantes: 512, 1024, 2048
                                ou 4096, mais pour un maximum de compatibilité
                                mieux vaut opter pour 512, ce qui est de toute
                                façon le meilleur choix sur graph100 vu la
                                taille des volumes.

BPB_SecPerClus    13    1    Nombre de secteurs par unité d'allocation (ou
                                cluster). Sur graph100 ce champ est à 1 car le
                                système de fichiers est sur ROM ou FLASH.

BPB_RsvdSecCnt  14    2    Nombre de secteur constituant la zone reservée
                                au debut du volume (c'est la zone où nous nous
                                situons actuellement). Ce champ ne doit pas être
                                nul, et devrait toujours être à 1 pour des
                                raisons de compatibilité a cause des drivers ne
                                faisant pas attention à cette valeur.
                                (je ne sais pas si la graph100 y fait attention,
                                mais normallement elle devrait pouvoir utiliser
                                des valeurs autres que 1)

BPB_NumFATs    16    1    Nombre de structures FAT sur le volume.
                                Normallement ce champ contient 2 pour avoir une
                                FAT redondante (en cas de défaillance du disque
                                dur par exemple) mais sur graph100 il n'y en a
                                pas besoin vu que le système de fichiers est sur
                                ROM ou FLASH.

BPB_RootEntCnt    17    2    Ce champ contient le nombre maximal d'entrées de
                                32 octets dans le répertoire racine (Root
                                directory) que nous aurons le loisir de voir
                                plus tard. Cette valeur, multipliée par 32, doit
                                donner un multiple de taille de secteur (voir 
                                plus haut BPB_BytsPerSec).

BPB_TotSec16    19    2    Ce champ correspond au nombre de secteur du
                                volume. ce champ ne doit pas etre egal à 0 sur 
                                graph100.

BPB_Media    21    1    La valeur standard de ce champ est 0xF8, ce qui 
                                veut dire que le Media (le support du volume)
                                est fixe (ne peut pas être enlevé du système),
                                et c'est le cas pour la graph100.
                                L'autre point important, c'est le fait que cette 
                                valeur doit être aussi mise dans le premier 
                                octet (Low Byte) de la FAT.

BPB_FATSz16    22    2    Ce champ correspond au nombre de secteur occupé
                                par une FAT. Il ne doit pas être égal à 0 sur 
                                graph100.

BPB_SecPerTrk    24    2    Secteurs par piste, normallement utilisé par
                                l'interruption 0x13 pour la géometrie des 
                                disques. C'est inutile pour la graph100, et 
                                cette valeur est à 0xF000.

BPB_NumHeads    26    2    Même remarque que pour le champ précédent.
                                La valeur sur graph100 est 1.

BPB_HiddSec    28    4    Nombre de secteurs cachés avant la FAT, aussi
                                utilisé par l'interruption 0x13. Inutile sur 
                                graph100, doit être mis à 0.

Je rappelle que ma description est spécifique à la graph100, certaines remarques 
ne sont pas valables pour d'autres materiels.

Une autre chose très importante pour le premier secteur du système de fichiers 
FAT: sector[510] = 0x55 et sector[511] = 0xAA. ET CELA QUELLE QUE SOIT LA TAILLE 
D'UN SECTEUR (qui de toute facon a une taille supérieure ou égale à 512) !

Enfin, sur graph100, les zones non utilisées sont remplies avec la valeur 0xFF.

____________________ La structure de la FAT (File Alocation Table) :

La seconde partie importante su système de fichiers FAT, c'est la FAT elle-même.
Cette structure définit une simple liste chainée (eh oui il faut revoir vos 
algorithmes et structures de données) pour mémoriser les differents emplacements 
des morceaux d'un même fichier (la défragmentation sert à optimiser la FAT et l'
emplacement des fichiers, pour qu'un même fichier ne soit plus eparpillé sur
tout un disque dur).
Les fichiers et les dossiers sont traités exactement de la même facon: un
dossier n'est ni plus ni moins qu'un fichier contenantun liste d'autres
fichiers, chaque entrée etant sur 32 octets. La FAT gère des clusters, et le
premier cluster de données est le cluster 2 (on verra pourquoi ensuite)
Sur graph100 1 cluster contient 1 secteur donc il n'y a pas de difference de
taille, mais le secteur 0 est le secteur de boot, alors que le cluster 2 est le
premier secteur de données. Il ne faut pas confondre ces deux termes.

On calclude le premier secteur de données comme ceci sur graph100
(une seule FAT) :

FirstDataSector = BPB_ResvdSecCnt + BPB_FATSz16 + RootDirSectors;
avec RootDirSectors le nombre de secteurs occupé par le répertoire racine, qu'on
peut calculer de la manière suivante :
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1))
                 / BPB_BytsPerSec;

Le type de FAT : Sur graph100 la FAT c'est de la FAT12. Le type de FAT est
déterminé en fonction du nombre de clusters qu'elle doit gérer. Ainsi, pour un
nombre de clusters < 4085 (strictement), le type de FAT est FAT12.
Vu la taille des volumes sur graph100, le systeme de fichiers est
OBLIGATOIREMENT FAT12 ! si vous voulez plus de précisions sur ce genre de chose,
réferrez vous a la documentation officielle.

La FAT12 est plus compliquée a gérer que la FAT16 ou même la FAT32, car alors
que pour ces deux derniers chaque entrée de la FAT est sur 2 ou 4 octets, pour
la FAT12 chaque entrée est codée sur 1.5 octets.

Pour trouver le bon emplacement, il faut faire :
FATOffset = N + (N / 2);
Avec N le numéro du cluster recherché.

Et en termes de secteur :
NumeroSecteur = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
OffsetSecteur = FATOffset % BPB_BytsPerSec;

Il faut maintenant recuperer le numéro de cluster sur 12 bits en mémoire, et ce
n'est pas évident, sachant que les valeurs 12 bits sont codées en L.E., tou en
étant les unes à la suite des autres :
ainsi les valeur 0x012 et 0x345, respectivement 12 0 et 5 43 (on met le 5 a part 
car seulement 4 bits pourront être placés dans le premier octet) en L.E. seront
à la suite sous cette forme en mémoire : 12 50 34

On peut proceder de la sorte :

si N est impair: Valeur = Valeur << 4;
si N est pair: Valeur = Valeur & 0x0FFF;
avec N l'index de la valeur qui a servi a calculer FATOffset.

El suffit ensuite de ranger cette valeur 16 bits dans la FAT, à l'endroit
calculé avec FATOffset (attention a effacer les bits correspondants, si N est
impair: c'est & 0x000F et si N est pair: c'est & 0xF000, il suffit
ensuite de faire un OU sur la FAT avec la valeur. )

Et inversement pour récuperer la valeur:, on va chercher dans la FAT la valeur
16 bits, puis:
si N est impair: Valeur = Valeur >> 4;
si N est pair: Valeur = Valeur & 0x0FFF;
avec N l'index de la valeur qui a servi a calculer FATOffset.

Maintenant voila l'organisation de la FAT par rapport aux fichiers :

  - le premier octet est la valeur du champ BPB_Media, c'est a dire 0xF8.
  - les deux octets suivants sont mis à 0xFF

  - ensuite on suit les règles évoquées plus haut : à un numéro de cluster
    est associé le numéro du cluster suivant du fichier sauf si c'est le dernier
    cluster du fichier auquel cas on mettre comme valeur 0xFFF. (un cluster
    defectueux aura la valeur 0xFF7, mais sur graph100 ca n'a aucun intérêt).

Attention ! Les index de cluster commencent à 2 (surement pour pouvoir calculer
plus facilement les adresses en FAT12)

Ce qui donne en pratique: ValeurCluster(NumeroCluster) = NumeroClusterSuivant ou
                          FinFichier ou SecteurDefectueux.

Voila le principe de la FAT !

                              ____IMPORTANT !____
==> un des meilleurs moyens de comprendre est de regarder une image ROMDISK <==
==> avec un editeur hexadecimal.                                            <==
==> D'autre part les lecteurs généres par les outils de création de lecteur <==
==> ont leurs fichiers sur des clusters contigus.                           <==
                              ___________________

____________________ La structure des Repertoires - le root

Un dossier dans le systeme de fichiers FAT n'est rien d'autre qu'un "fichier"
composé d'une liste d'entrées de 32 octets. Un seul Dossier doit être TOUJOURS
présent, c'est le répertoire racine (Root Directory). dans le cas de la
graph100, le root est situé dans un emplacement spécial, après la FAT, et n'est
pas compris dans les cluster de données, ceux-ci démarrant APRES le root. La
taille du root est déterminée par le champ BPB_RootEntCnt dans le secteur de
boot.

Son secteur est :
FirstRootDirSecNum = BPB_ResvdSecCnt +  BPB_FATSz16;

Voici la structure d'une entrée de 32 octets dans une liste de fichiers :

Name      Offset (octets) Taille (octets)    Description

DIR_Name    0    11    Nom du fichier

DIR_Attr    11    1    Attributs du fichier :
                                ATTR_READ_ONLY  0x01
                                ATTR_HIDDEN     0x02
                                ATTR_SYSTEM     0x04
                                ATTR_VOLUME_ID  0x08
                                ATTR_DIRECTORY  0x10
                                ATTR_ARCHIVE    0x20

                                Les deux derniers bits (les plus signifiants)
                                doivent être mis à 0 lors de la création
                                du fichier (ils sont censés être resevrés par le
                                systeme d'esploitation mais sur graph100 ils
                                sont inutiles car inmodifiables)

DIR_NTRes    12    1    La documentation de microsoft annonce :
                                "reservé pour WindowsNT". On ne s'en occupe pas
                                et on met ce champ à 0.

DIR_CrtTimeTenth 13    1    Champ pour les dixièmes de secondes qui sert
                                pour les... centièmes de seconde.
                                La précision du champ DIR_CrtTime est de deux
                                secondes, donc DIR_CrtTimeTenth sera entre 0 et
                                199 dixiemes de seconde inclus pour combler
                                cette lacune.

DIR_CrtTime    14    2    L'heure à laquelle le fichier a été créé.
                                Le format de l’heure, codée sur 16 bits est
                                Bits 0-4: Secondes/2, 0-29 inclus,
                                                           (0-58 secondes)
                                Bits 5-10: Minutes, 0-59 inclus.
                                Bits 11-15: Heures, 0-23 inclus.


DIR_CrtDate    16    2    La date à laquelle le fichier a été créé.
                                le format de la date, codé sur 16 bits est
                                Bits 0-4: Jour du mois, 1-31 inclus
                                Bits 5-8: Mois de l'année, 1 = Janvier,
                                                           1-12 inclus.
                                Bits 9-15: Années depuis 1980, 0-127 inclus
                                                               (1980-2107).


DIR_LstAccDate    18    2    Date du dernier accès au fichier (il n'y a pas
                                la gestion de l'heure du dernier acces au
                                fichier) autant en lecture qu'en ecriture. Si c'
                                est en ecriture cette date doit être la même que
                                DIR_WrtDate.

DIR_FstClusHI    20    2    Mot le plus signifiant du numero du premier
                                cluster du fichier. Toujours à 0 sur un système
                                de fichiers FAT12 et donc sur graph100.

DIR_WrtTime    22    2    Heure de la dernière écriture sur le fichier. La
                                création du fichier est considérée comme une
                                écriture.

DIR_WrtDate    24    2    Date de la dernière écriture sur le fichier. La
                                création du fichier est considérée comme une
                                écriture.

DIR_FstClusLO    26    2    Mot le moins signifiant du numero du premier
                                cluster du fichier, c'est lui seul qui determine
                                le premier cluster du fichier en FAT12 (et donc
                                sur graph100)

DIR_FileSize    28    4    Taille du fichier sur 32 bits.

Quelques précision :

  - Les attributs de fichier :

    ATTR_READ_ONLY     L'ecriture sur ce fichier devrait échouer.

    ATTR_HIDDEN     Le fait de lister un repertoire de doit pas afficher les
                        fichiers/dossiers cachés.

    ATTR_SYSTEM     Le fichier appartient au système d'exploitation.

    ATTR_VOLUME_ID     Il ne doit y avoir qu'un seul "fichier" sur le volume
                        ayant cet attribut, et ce fichier doit être dans le root
                        Le nom de ce fichier est le nom du volume. DIR_FstClusHI
                        et DIR_FstClusLO doivent toujours être a 0 pour le nom
                        du volume, car aucun cluster n'est associé à cette
                        entrée.
                        Sur Graph100, le nom de volume est "ROM-DISK"

    ATTR_DIRECTORY    Ce ficher est un Dossier, il contient d'autres fichiers.

    ATTR_ARCHIVE      Cet attribut est mis sur un fichier lorsqu'il a été
                        modifié, et ce pour que les utilitaires d'archivage
                        compression puissent déterminer quels fichiers ont été
                        modifiées depuis le dernier archivage.
  - Les dates :

    Seuls DIR_WrtTime et DIR_WrtDate sont obligatoires, les autres champs
    sont optionnels et peuvent être mis à 0.

  - Les noms de fichier :

    Considérons DIR_Name comme une tableau de caractères :
    * si DIR_Name[0] == 0xE5, alors l'entrée dans le répertoire est libre.

    * si DIR_Name[0] == 0x00, alors l'entrée dans le répertoire est libre (comme
                              pour 0xE5),et il n'y a plus d'entrées allouées
                              après celle-ci (tous les octets de toutes les
                              entrées apres celle-ci sont mis à 0).

    La valeur 0 indique au système de fichiers que le reste des entrées n'a pas
    besoin d'être analysé car elles sont toutes libres.

    DIR_Name est constitué de deux parties: le nom(8 caractères) et l'extension
    (3 caractères). Les caractères non utilisés sont remplis par le caractère
    espace (0x20).

    DIR_Name[0] ne doit pas être égal à 0x20 :
    Il y a un caractère '.' implicite character entre le nom et l'extension dans
    DIR_Name.
    Les caractères minuscules ne sont pas autorisés.

    Les valeurs suivantes ne sont pas autorisés :
    * Valeurs inférieures à 0x20.
    * 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
      0x5B, 0x5C, 0x5D, et 0x7C.

____________________ Spécificités des dossiers :

Lors de la création d'un dossier, il faut mettre ATTR_DIRECTORY dans ses
attributs, puis mettre son champ DIR_FileSize à 0 (DIR_FileSize est inutilisé et
toujours mis à 0 avec ATTR_DIRECTORY), on determinera alors la taille d'un
dossier en calculant le nombre de clusters qu'il occupe grâce à la FAT.
Un cluster est alloué au dossier et on modifie le champ DIR_FstClusLO pour qu'il
pointe sur le cluster alloué, puis on place une marque de fin de cluster sur le
cluster du dossier dans la FAT. Ensuite on initialise tous les octets du cluster
à 0.

On doit ensuite créer deux entrées :
le première doit avoir pour nom "." et la deuxième "..", c'est la seule
exception à la rêgle des noms de fichiers.

Le champ DIR_FileSize de ces deux entrées est mis à 0, et tous les champs de
date et d'heure de ces entrées sont mises aux mêmes valeurs que pour le dossier
que l'on vient juste de créer, puis on fait pointer DIR_FstClusLO de "." sur le
cluster du nouveau dossier, et DIR_FstClusLO de ".." sur le cluster du dossier
parent (0 si le dossier parent est le root)


____________________ Spécificités des fichiers :

Si un secteur n’est pas completement utilise par un fichier, il faut le combler
avec la valeur 0xFF.

____________________ Historique /Remerciements / etc ... :

Version 2 - plus de précisions :)
Version 1 - Incomplet, plein d'erreurs...

Merci à mes doigts, ma tête, le café, Superna qui a retrouvé la premiere version de ma doc, 2072 (Touche parce que je le vaux bien),
microsoft (c'est tres rare, mais bon la doc sur le FAT ca vient de chez eux),
et tous les autres...

Hors ligne

 

#2 24 Feb 2004 05:37:36

Superna
Ex-Trouvetou G100
Lieu: Sous Linux ^^
Date d'inscription: 01 Feb 2002
Messages: 2275
Site web

Re: Doc sur le format RomDISK (merci mes doigts)

____________________ Spécificités des dossiers :

Si un secteur n’est pas completement utilise par un fichier, il faut le combler
avec la valeur 0xFF.

tu t planté de titre a la fin !

et de rien d'avoir retrouvé ton ancienne doc.......

Hors ligne

 

#3 24 Feb 2004 05:59:37

mastermage
Magicien G100
Lieu: Charleville-Mézières,Compiègne
Date d'inscription: 31 Jan 2002
Messages: 1008

Re: Doc sur le format RomDISK (merci mes doigts)

Voila c rectifié smile

lol c vrai superna... MERCI  :mrgreen:

Hors ligne

 

#4 24 Feb 2004 08:46:43

dada66
Membre Communauté Graph100
Lieu: Perpignan
Date d'inscription: 09 Oct 2002
Messages: 1033

Re: Doc sur le format RomDISK (merci mes doigts)

Dommage Mastermage que tu donnes ceci un peu tard, parce que moi g cherché tout seul avec un éditeur héxadécimal pour savoir comme ca marche smile


Flash100, F100Console, GComm, ... : http://flash100.free.fr/xoops

Hors ligne

 

#5 24 Feb 2004 10:02:16

Azor
Le Coté Obscur De La G100
Lieu: glop glop!
Date d'inscription: 04 May 2002
Messages: 5479
Site web

Re: Doc sur le format RomDISK (merci mes doigts)

bon et interressant document, mais faudrait peut ètre des images pour illustrer un peu... mais a part ça c' est niquel!


Anciennement X-thunder28
Cats shall rule teh world!

Hors ligne

 

#6 24 Feb 2004 11:02:03

mastermage
Magicien G100
Lieu: Charleville-Mézières,Compiègne
Date d'inscription: 31 Jan 2002
Messages: 1008

Re: Doc sur le format RomDISK (merci mes doigts)

je vais le faire en html smile

dada: au moins maintenant tu as la doc complete !

Hors ligne

 

#7 02 Mar 2004 14:25:35

RonanKer
Membre Communauté Graph100
Lieu: France (44-49)
Date d'inscription: 26 Feb 2002
Messages: 379
Site web

Re: Doc sur le format RomDISK (merci mes doigts)

ds secteur de boot /BPB:
"beacoup"->"beaucoup"

à BPB_bytspersec
  "facon"->"façon"

à BPB_rsvdseccnt
  "actuellment"-> "actuellement"

dans DIR_CrtTimeTenth13
  tu te delire un peu trop... mais bon ça passe si on réécrit le texte ainsi :
DIR_CrtTimeTenth13   1   Champ pour les dixièmes de secondes qui sert
                                pour les... centièmes de seconde.
                                La précision du champ DIR_CrtTime est de deux
                                secondes, donc DIR_CrtTimeTenth sera entre 0 et
                                199 centièmes de seconde inclus pour combler
                                cette lacune.


à attr-archive
  "archvage"->"archivage"

après -les noms de fichier...
  "une tableau"->"un tableau"

puis les valeurs autorisées...
  "and"->"et"

et enfin à la fin de spécif des dossiers ton texte est en anglais...

voilà tout ce que j'ai remarqué...

sinon très bien j'ai apris des trucs interessents !


**********************
[URL=http://ronan.kerdudou.free.fr]site perso http://ronan.kerdudou.free.fr[/URL]
http://www.all.lyrics.for.free.fr
[URL=http://www.motostar44.fr]motos nantes : http://www.motostar44.fr[/URL]

Hors ligne

 

#8 02 Mar 2004 14:58:39

mastermage
Magicien G100
Lieu: Charleville-Mézières,Compiègne
Date d'inscription: 31 Jan 2002
Messages: 1008

Re: Doc sur le format RomDISK (merci mes doigts)

enfin un qui a lu jusqu'au bout smile merci beacoup ronanker, c'est corrigé

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr