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…