Programmation de WHDLoad

### Flot d'exécution

Le tableau suivant montre le flot d'exécutions d'un programme installé par WHDLoad. J'espère que cela aidera à comprendre comment WHDLoad fonctionne et comment WHDLoad, le slave et le programme installé coopèrent.

L'UTILISATEUR

- démarre la démo ou le jeu en cliquetant sur l'icône ou en démarrant WHDLoad par la ligne de commande.

Le système d'exploitation

- charge l'exécutable WHDLOAD et le démarre

WHDLoad

- vérifie l'environnement logiciel et matériel
- charge et vérifie le slave
- alloue la mémoire nécessaire pour le programme installé
- Si Preload/S est activé, les images disques et les fichiers sont chargés en mémoire (tant qu'il reste de la mémoire)
- désactive le système d'exploitation (désactive le multitâche et les interruptions, restreint l'environnement graphique à l'OCS, initialise tout le matériel avec des valeurs définies)
- saute dans le code du slave.

Slave

- charge le programme principal du programme installé en appelant une fonction WHDLoad (par exemple resload_DiskLoad ou resload_LoadFile)
- modifie le programme principal (pour que ce programme charge ses données à travers le slave, pour corriger des problèmes de compatibilité, pour aménager une sortie du programme)
- appelle le programme principal

Programme installé

- fait les choses qu'il a à faire
- au chargement des données à partir du disque, il appelle le slave (car celui-ci a modifié le programme pour cela précédemment), et le slave appelle WHDLoad, et WHDLoad active partiellement l'OS pour charger les données (uniquement si les données ne sont pas Preload'ed), puis retourne, retourne et le programme installé continue.

L'UTILISATEUR

- sort du programme en appuyant sur la Touche pour quitter

Le Slave

- retourne à WHDLoad et appelant resload_Abort

WHDLoad

- réactive l'OS (restaure les registres du hardware, l'affichage, et la mémoire)
- libère toutes les resources allouées
- retourne au système d'exploitation

### Comment installer un programme simple à 1 disque avec un chargement de pistes

C'est un guide pas à pas très petit et court qui explique comment créer un install en utilisant WHDLoad. Le guide reflète un cas simple et idéal. Dans le monde réel, un tel cas n'arrive probablement jamais. Pour les cas particuliers et les problèmes, lire les chapitres suivants.

1. Travail préliminaire
   - Créer un tiroir qui contient tous les fichiers.
   - Créer une image disque en utilisant DIC dans ce répertoire.
   - Créer un fichier #?.info avec "WHDLoad" comme <Outil par défaut> et un tooltype "SLAVE=#?" contenant le nom du slave (ou copier simplement une icône d'un exemple d'install, désactiver tous les tooltypes sauf "SLAVE=").
2. Le Slave
   Pour écrire le slave nous avons besoin des informations suivantes:
   1. Où est situé le programme exécutable principal sur le disque?
   2. Où est situé le programme de chargement dans le programme principal?
   Pour obtenir cette information, nous analysons d'abord le secteur de boot. La plupart du temps le programme principal est chargé à partir d'un exec.DoIO(). Parfois un programme de chargement spécial se trouve dans le secteur de boot. A présent nous écrivons un slave qui simule le bootblock et qui charge le programme principal à partir de l'image disque. Maintenant nous extrayons le programme principal de l'image ou d'un dump mémoire. Après cela, nous devons trouver le programme de chargement dans le programme principal. Une façon rapide est de rechercher le pattern $AAAAAAAAA ou $55555555 (utilisé par le décodage MFM) avec un éditeur hexadécimal. Couper la zone trouver à (+/- $1000 octets), le désassembler, et rechercher le début de la routine. Comprendre la liste des paramètres. Maintenant, nous créons le code du slave qui redirige la routine de chargement vers le slave. Ce dernier ajuste alors les paramètres et appelle la fonction resload_DiskLoad.
3. Dans le cas idéal, l'install est alors terminé.
   Une dernière chose à faire est de créer une icône sympa. Récupérer 2 images en utilisant snoop dans WHDLoad et SP ou un moniteur système ou U.A.E. et créer l'icône. La palette à 16 couleurs RomIcon est recommandée.

### Problèmes possibles et cas spéciaux

#### Chargeur de pistes non standard

Certains programmes utilisent leur propre format de piste. Cela signifie que DIC est incapable de créer les images disque. Pour créer les fichiers ou les images à partir de tels disques, l'utilisation de RawDIC est recommandée. Consultez la documentation de RawDIC pour plus d'informations.

#### Plusieurs disques

Si le programme utilise plus d'un disque, le slave doit rediriger les accès disque vers l'image appropriée. Parfois cela n'est pas facile. Certains programmes utilisent plus d'un lecteur, donc vous pouvez utiliser le numéro du lecteur pour sélectionner le disque. La plupart des programmes utilisent un identificateur sur chaque disque pour les distinguer. Dans ce cas, utilisez une variable qui contient le numéro du disque, et à chaque accès à l'identificateur du disque (trouver un tel accès en analysant les paramètres du chargeur), augmenter la variable (si le dernier disque est atteint, la remettre à 0). Avec un peu de chance, le chargeur relit l'identificateur encore et encore jusqu'à ce que le bon disque soit inséré. Parfois une requête du programme demandant d'insérer le bon disque apparaît. Désactivez-là.

#### Sauvegarde des meilleurs scores

Pas grand chose à dire ici. Utiliser resload_SaveFile pour écrire la zone de mémoire appropriée sur le disque. Vous pouvez aussi crypter le fichier pour éviter que des gros nazes le modifient trop facilement. Il est déconseillé d'écrire directement sur les images disque en utilisant resload_SaveFileOffset), en effet, si quelque chose se passe mal (par exemple plantage), il est possible que les images soient corrompues.

#### Sauvegarde des parties

Même chose que pour les hiscores.

#### Accès au système d'exploitation

Quand le slave et le programme installé sont exécutés, aucune fonction du système n'est disponible! Cependant, il faut désactiver toutes les tentatives d'accès par le programme installé. S'il n'y en a pas beaucoup, et s'ils n'ont pas beaucoup d'intérêt dans l'environnement WHDLoad (comme exec.Disable() ou exec.SuperState()), les convertir en NOP ($4e71). Si l'accès est une fonction importante (comme exec.DoIO()), redirigez les vers le slave et émulez les. S'il y en a beaucoup, créez une simple bibliothèque exec dans une zone inutilisée (initialisez le mot long à l'adresse $4). Vous pouvez jeter un oeil à la source du slave d'Oscar, qui émule exec.AllocMem(). Pour détecter les accès au système d'exploitation, execbase est mis initialement à $f0000001 afin que toutes les routines qui essayent d'utiliser execbase créeront une exception "Address Error".
Si un usage intensif des fonctions de l'OS il y a, utilisez un des paquetages kickemu qui se trouvent dans l'archive whdload développement. Il existe un paquetage pour le Kick 1.3 ('src/sources/whdload/kick13.s') et un pour le Kick 3.1 ('src/sources/whdload/kick31.s'). Ces paquetages nécessitent une image kickstart et créént un environnement système complet à l'intérieur de l'espace WHDLoad. Consulter également le fichier readme fourni pour de plus amples informations.

### Problèmes de compatibilité courants

#### Espace d'adressage limité sur 68000/68010/68ec020

Sur ces processeurs, l'espace d'adressage est limité à 16 méga-octets ($000000...$ffffff) parce que le CPU possède uniquement 24 lignes d'adresse. Aussi, les accès à des adresses supérieures sont en fait effectuées sur les 16MB de base, et les 8 bits de poids fort sont ignorés comme s'ils étaient à zéro. Certains programmes utilisent ces octets pour stocker des données, ou oublient simplement de les mettre à zéro. Sur un processeur à espace d'adressage 32 bits (4 giga-octets) comme les 68020/68ec030/68030/68040/68060, ces programmes ne fonctionneront pas, car l'adresse complète 32 bit sera utilisée.
Pour résoudre ce problème, vous devez patcher ces accès et les rediriger vers l'adresse appropriée.
Parfois la raison de ces accès à de telle adresse est un pointer non-initialisé. Dans ce cas, il serait utile d'effacer le contenu de la mémoire de $400 à ws_BaseMemSize.

#### Structures de pile différentes selon le processeur

Les structures de pile créées par le processeurs lors d'interruptions ou d'exceptions sont différentes entre les membres de la famille des 680x0. Sur le 68000, la structure de la pile comporte 6 octets, sauf en cas d'erreurs d'adressage et d'erreurs de bus. La structure de pile contient le SR dans (a7) et le PC dans (2,a7). Sur tous les autres processeurs (68010+), la taille minimale de structure de pile est 8 octets et contient le numéro du vecteur d'interruption/exception dans (6,a7). Cette structure de pile est créée pour "Trap #xx" et les interruptions sur 68010-68060. Les structures de pile sur d'autres exceptions sont différentes sur chaque processeur. L'instruction RTE fonctionne différemment entre le 68000 et les 68010+. Sur un 68000, il restaure simplement le SR et le PC et continue l'exécution du programme à l'addresse où il avait été interrompu. Sur les processeurs 68010+, il libère en plus le reste de la structure de pile selon le format de celle-ci.
Certains programmes empilent une adresse (PC) et un SR et exécutent un RTE. Cela fonctionne uniquement sur 68000. Sur un 68010+ le résultat est indéfini.
Si un programme fait cette opération, vous devez réparer ça. Parfois, il suffit de remplacer le RTE par un RTR.

#### MOVEM.x RL,-(An) sur 68000/010 et 68020/030/040

Il existe une différence si le registre utilisé dans le mode prédécrémentation est aussi dans la liste des registres. Pour le 68020, 68030 et le 68040, la valeur écrite en mémoire est la valeur initiale du registre décrémentée de la taille de l'opération. Le 68000 et le 68010 écrivent la valeur initiale du registre (non décrémentée).
Une telle construction étant peu utile, aucun logiciel n'est connu pour avoir des problèmes à cause de cela.

### Conseils généraux pour écrire des installs

- Ne pas modifier les registres CPU des processeurs plus récents comme le VBR ou le CACR. Le VBR est toujours à 0 du point de vue du programmeur du slave, même s'il est déplacé en raison de l'émulation des auto vecteurs (et des traps si le flag WHDL_EmulTrap est mis). Les bits dans le CACR sont différents pour chaque processeur. Il y a une seule façon correcte de modifier les caches, c'est en utilisant resload_SetCACR/SetCPU et les bitdefs de 'exec/execbase.i' et 'whdload.i'. Il faut également désactiver ou sauter tout ce qui concerne ces registres dans le programme installé.
- Ne jamais modifier les images disque. Cela présente l'avantage de permettre de créer des disquettes avec les images et de démarrer le jeu à partir des disquettes (à condition que le programme fonctionne sans corrections, ce qui est loin d'être le cas le plus probable).
- Ne jamais inclure de données/fichiers originaux du programme directement dans le slave (problème de copyright).
- Activer les caches uniquement si vous êtes sûr que le programme tourne sur tous les processeurs.
- Utiliser le moins de mémoire de base possible (ws_BaseMemSize). Certains utilisateurs ont des tags résidents à la fin de la mémoire Chip, aussi il est intéressant d'utiliser uniquement $1f0000 au lieu de $200000 et WHDLoad peut utiliser de la mémoire allouée en absolu.

### Trucs et astuces

#### Quel est la meilleure solution: fichiers images disque ou fichiers ?

Parfois vous devez choisir entre fichiers images disque ou vrais fichiers. Les deux ont leurs avantages. L'utilisation des images disque est souvent la façon la plus facile et rapide de créér le slave. Mais les vrais fichiers sont plus facilement cachés (s'il y a peu de mémoire ou que celle-ci est fragmentée). L'espace requis sur le disque dur est également moindre avec des vrais fichiers qu'avec des images disque. Utilisez les images disque que s'il y a beaucoup de fichiers (plus de 30).