Exécution d'un programme en le chargeant en mémoire

Exécution d'un programme en le chargeant en mémoire

Lorsque l’on souhaite exécuter un programme sur Amstrad CPC, la procédure consiste à utiliser la commande RUN du Basic, qui va se charger de lire des données sur la disquette (ou cassette), les transférer en RAM et de sauter à son point d’entrée. Je vous propose d’écrire un petit programme qui sera capable d’être exécuté avec une simple commande LOAD, c’est a dire que le simple fait de le transférer en RAM provoquera son exécution!

Le principe

AMSDOS refuse de charger un fichier dans une zone trop basse. Par contre, si un programme est logé haut dans la RAM, ça passe. Il faut savoir que la pile se trouve en &C000 initialement. A chaque fois que le CPC appelle une fonction il empile l’adresse de retour (ce qui revient à « descendre » dans la mémoire).

Autrement dit, si le basic en &1234 fait un CALL xxxx alors &1237 est placé dans la pile en &BFFF et &BFFE (SP=SP-2). Lorsque la fonction en xxxx sera terminée, elle fera un RET qui récupérera l’adresse &1237 et remettre la pile en &C000 (SP=SP+2).

Ceci étant posé, si l’on charge un fichier logé en &BEBE qui va jusqu’à &C000, et que dans la zone ou se trouve la pile couramment, sont logés des octets &BE, &BE, &BE,&BE….. Le premier RET que le système va faire à l’issue du chargement va amener directement le Z80A en &BEBE et donc démarrer le code chargé.

Le programme

 di
 ld bc,#7F10
 ld hl,#4B5C
 out (c),c
noend
 out (c),h
 nop
 out (c),l
 nop
 jr noend
 defs 140,#be ; #bfff-#bebe = 140

Si l’on sauvegarde ce code depuis le CPC, il faudra l’assembler à un autre endroit (le programme est relogeable tel quel), le sauvegarder, et modifier le header AMSdos pour que le programme soit logé a la bonne addresse.

Une autre possibilité consiste à utiliser RASM, qui peut directement générer ce DSK avec un header Amsdos correct pour notre fichier :

org #BEBE
start:
 di
 ld bc,#7F10
 ld hl,#4B5C
 out (c),c
noend:
 out (c),h
 nop
 out (c),l
 nop
 jr noend
 defs #bfff-$,#be
end:

save 'arg.bin', start, end-start, DSK,'arg.dsk'

La preuve par l’image:

La preuve par l’emulation (via TinyCPC) : Démarrer:

Par contre, ce qui n’a jamais été fait, c’est de pouvoir lancer un programme en faisant un CAT. Je pense que c’est impossible… mais qui sait…