Comme nous l'avons découvert dans la partie précédente , les codes machine du jeu ne peuvent pas être téléchargés directement de la disquette vers l'adresse de destination. Nous les téléchargerons vers un autre emplacement et après le téléchargement, nous les déplacerons si nécessaire. De plus, nous voulons créer un chargeur de démarrage à un bloc lorsque le chargeur de démarrage et les données chargées sont dans le même fichier de base. Un tel chargeur ne peut être écrit que dans des codes machine. Dans le même temps, comme nous avons un fichier monobloc, le chargeur dans les codes machine devra être placé dans les commentaires au chargeur en BASIC.

Au total, il s'avère la multi-étape suivante:
- De BASIC, nous transférons le contrôle au programme dans des codes machine.
- Le programme dans les codes machine transfère le chargeur de démarrage de la zone BASIC vers une autre zone qui n'est pas affectée par les codes machine du jeu et lui transfère le contrôle.
- Téléchargez et décompressez l'image de démarrage.
- Nous chargeons les codes de la machine de jeu dans une zone qui ne chevauche pas la zone des variables système.
- Nous transférons les codes machine à l'adresse de destination.
- Nous transférons le contrôle au programme.
Le développement devra commencer au milieu (paragraphe 3). Le fait est que pour écrire un programme de déplacement, vous devez connaître la taille du programme à déplacer et pour intégrer des codes machine dans une base, vous devez connaître la taille du programme de déplacement.
Chargeur de démarrage monobloc (partie dans les codes machine)
Dans TR-DOS, le chargement de données à partir d'un fichier monobloc ressemble plus au téléchargement d'un fichier sans en-tête à partir d'une bande, lorsque des données d'une taille prédéterminée sont simplement lues à partir de la position actuelle et chargées dans une zone spécifique de la mémoire. Pour cela, dans TR-DOS, la routine à #3D13
. Tout d'abord, téléchargez et décompressez l'image:
LD DE, ($5CF4) ; LD BC, $0805 ; B - (9)*, ; — #05 ( ) LD HL, $8000 ; 32768** CALL $3D13 ; TR-DOS CALL $8000 ;
& ast; - voir la compression de l'image de démarrage dans la partie précédente;
& ast; & ast; - Le déballeur est déplaçable, vous pouvez donc télécharger n'importe où.
De même, téléchargez les codes des machines de jeux:
LD DE, ($5CF4) ; LD BC, $2505 ; B - , ; — #05 ( ) LD HL, $6000 ; 24576 CALL $3D13 ; TR-DOS
À ce stade, nous n'avons plus besoin de TR-DOS; nous pouvons transférer des codes machine à l'adresse de destination à l'aide de l' LDIR
processeur LDIR
:
LD HL, $6000 ; (, ) LD DE, $5B00 ; LD BC, $2500 ; ( data.bin) LDIR
Eh bien, à la fin, nous transférons le contrôle au programme de la même manière que dans le chargeur de démarrage d'origine - en déplaçant le pointeur de la pile:
LD SP, $5D7C RET
Maintenant que le code du chargeur est prêt, vous devez le compiler pour connaître sa taille, dont nous aurons besoin plus loin.
$ pasmo tmp.asm tmp.bin $ wc -c tmp.bin 44 tmp.bin
Procédure de transfert du chargeur de démarrage
Le chargeur de démarrage prend 44 octets. Vous devez maintenant écrire la procédure pour déplacer le chargeur de démarrage des commentaires en BASIC (point 2 de la liste au début de l'article). Le problème est que l'adresse où se trouve la zone BASIC peut varier en fonction des périphériques connectés à l'ordinateur.Par conséquent, pour déterminer où vous souhaitez transférer des données, vous devez vous concentrer sur la variable système PROG
(comme dans le chargeur de démarrage d'origine) ou au compteur logiciel (registre processeur PC
).
Il n'est pas si facile d'accéder au compteur de logiciels - aucune instruction de processeur comme LD HL, PC
n'existe. J'ai espionné la solution dans Laser Compress et elle ressemble à ceci (utilisation pas vraiment ciblée de la procédure UNSTACK_Z
):
LD DE, $00 ; , , ; . ; 1 INC E ; 1 E, , ; . 1 CALL $1FC6 ; ( , LD HL, PC) ADD HL, DE ; LD DE, $F800 ; LD BC, $002C ; , (44 ) LDIR JP $F800 ; ; ;
Au moment d'appeler la procédure ROM #1FC6
, l'adresse de la prochaine instruction ( ADD HL, DE
) sera sur la pile. C'est lui qui sera enregistré suite à l'appel de la procédure en HL
. En conséquence, pour déterminer le nombre qui doit être écrit dans la toute première ligne, vous devez à nouveau compiler un morceau de ADD HL, DE
et voir combien cela prendra:
$ pasmo tmp.asm tmp.bin $ wc -c tmp.bin 12 tmp.bin
Il s'est avéré 12 octets. En conséquence, dans la première ligne, nous écrivons 11 ( #0B
).
Ensuite, nous composons la procédure de déplacement avec le chargeur (voir le fichier fini ), qu'il déplacera et compilera à nouveau. Il devrait se révéler 56 octets.
Il convient de noter ici qu'après avoir écrit cette pièce, j'ai compris qu'au lieu de calculer la longueur du programme à déplacer, vous pouvez utiliser des étiquettes et laisser l'assembleur le comprendre. Mais pour la justice historique, laissons cela tel quel.
Chargeur de démarrage monobloc (partie de base)
Maintenant que nous connaissons la taille du chargeur de démarrage dans les codes machine, nous pouvons écrire le chargeur de démarrage en BASIC et collecter le tout dans un fichier monobloc.
Les codes machine sont intégrés dans un fichier de base dans un commentaire ou à la fin d'un fichier. La seconde complique généralement l'étude du fichier et est plus adaptée à la protection, nous allons donc utiliser la première option. L'option de commentaire est la suivante:
1 REM @#$%... 10 RANDOMIZE USR (PEEK 23635+256*PEEK 23636+5)
23635
( #5C53
) est l'adresse de la variable système PROG
que nous avons mentionnée précédemment. 5
est le décalage du premier caractère du commentaire par rapport à PROG
(2 octets sont le numéro de ligne, 2 octets sont la longueur de la ligne et 1 octet est l'opérateur REM
). Si vous souhaitez ajouter d'autres commentaires avant les codes machine, par exemple votre nom, votre numéro de téléphone ou votre adresse postale, la valeur 5
devra être ajustée.
Si nous n'utilisions aucun utilitaire supplémentaire pour créer le chargeur de démarrage, nous aurions besoin d'entrer des caractères arbitraires après REM
d'une quantité non inférieure à la longueur du programme dans les codes machine que nous voulons mettre à la place du commentaire (dans notre cas, 56 octets). Après cela, on pourrait charger le programme via LOAD "" CODE PEEK 23635+256*PEEK 23636+5
et enregistrer le fichier.
Cependant, bas2tap
peut rendre le processus beaucoup plus facile. il peut compiler un fichier de base et y incorporer des données binaires si chaque octet est représenté comme un nombre hexadécimal entre accolades. Pour ce faire, exécutez le chargeur de démarrage compilé via hexdump
:
$ hexdump -ve '1/1 "{%02x}"' loader.bin {11}{0b}{00}{1c}{cd}{c6}{1f}{19}{11}...
hexdump
mettons la sortie hexdump
à la place du commentaire dans la première ligne après REM
et compilons le chargeur de démarrage sur la -sboot
( -sboot
est le nom du fichier sur la bande, -a10
est le numéro de ligne du -a10
):
$ bas2tap -sboot -a10 boot.bas boot.tap
Convertissez le chargeur de démarrage du format tap
en hobeta
via le format intermédiaire 0
:
$ tapto0 -f boot.tap $ 0tohob boot.000
Création d'un fichier monobloc
À ce stade, nous avons déjà tous les fichiers nécessaires pour créer une image de disquette. Vous pouvez créer une image et y copier tous les fichiers nécessaires:
createtrd Pac-Man.trd hobeta2trd boot.\$$B Pac-Man.trd hobeta2trd screen.\$$C Pac-Man.trd hobeta2trd data.\$$C Pac-Man.trd
L'image de disquette résultante devrait déjà fonctionner. Vous pouvez l'exécuter dans l'émulateur et vérifier, mais ce n'est pas tout. Étant donné que le chargeur de démarrage ne télécharge pas les fichiers suivants non pas par nom, mais en fonction de la position de la tête du lecteur, le chargement ne fonctionnera que si les fichiers se trouvent sur le disque l'un après l'autre. Cela doit être corrigé.
Le principe est le suivant: TR-DOS stocke les informations de taille de fichier redondantes:
- Taille en secteurs - utilisée pour placer des fichiers sur une disquette et les copier.
- Taille en octets - utilisée pour charger le contenu.
Habituellement, ces tailles se correspondent (256 octets par secteur), mais ce n'est pas nécessaire. Nous en profiterons. Si vous modifiez la taille du fichier de démarrage dans les secteurs à une valeur égale à la taille totale de tous les fichiers que nous voulons télécharger, mais ne changez pas la taille en octets, TR-DOS copiera toutes les données dans un seul grand fichier, mais seule la base sera chargée au démarrage partie.
Sur un vrai spectre ou dans un émulateur, la piste zéro peut être éditée avec des programmes comme Disk Doctor, par exemple, Hex Disk Editor :

Mais cela peut être simplifié: une image trd n'est rien de plus qu'une copie d'octets de toutes les données sur une disquette, elle peut donc être éditée dans n'importe quel éditeur hexadécimal:
$ hexdump -C Pac-Man.trd | head -4 00000000 62 6f 6f 74 20 20 20 20 42 d0 00 d0 00 01 00 01 |boot B.......| 00000010 73 63 72 65 65 6e 20 20 43 40 9c 14 07 08 01 01 |screen C@......| 00000020 64 61 74 61 20 20 20 20 43 00 5b 00 25 25 09 01 |data C.[.%%..| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Comme vous pouvez le voir, au tout début de la disquette (sur la piste zéro), il y a une table d'allocation de fichiers dans laquelle les informations sur chaque fichier prennent 16 octets. La taille en secteurs est stockée en octets avec le décalage #0D
(troisième colonne à droite). La taille de nos fichiers est #01
, #08
et #25
secteurs, ce qui au total est #2E
. Nous écrivons cette valeur dans l'octet correspondant et supprimons les en-têtes restants, car ils ne sont plus nécessaires:
$ hexdump -C Pac-Man.trd | head -4 00000000 62 6f 6f 74 20 20 20 20 42 d0 00 d0 00 2E 00 01 |boot B.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Nous avons maintenant une image de disquette à part entière. Il doit se charger correctement et être entièrement copié d'un disque à l'autre. Il ne reste plus qu'à réduire la taille de l'image. Puisqu'une image trd est une copie d'octets, elle prend toujours 640 Ko. Dans la pratique, dans la plupart des cas, il est plus pratique d'utiliser le format scl, qui ressemble plus à hobeta stocke directement les données de fichier:
$ trd2scl Pac-Man.trd Pac-Man.scl
Maintenant c'est sûr. Le processus d'adaptation du début à la fin se trouve dans le référentiel du projet sur le github.
Outils:
- Pasmo est un assembleur croisé pour la Z80.
bas2tap
est un compilateur croisé du dialecte Spectrum BASIC.trd2scl
- convertisseur trd-image en scl.
Liens connexes:
- «Adaptation des programmes au système TR-DOS» par Nikolai Rodionov.
- «Fonctions TR-DOS» du magazine Info Guide n ° 1.
- «La structure de la disquette TR-DOS» du livre «TR-DOS pour professionnels et amateurs» .
- Une référence aux variables système et aux procédures Spectrum ROM .