Je m'explique.
Une file de registre du Z80 contient BC/BC', DE/DE', HL/HL', AF/AF', IX, IY, WZ, SP et PC. Il y aura donc 8 files avec un ordre de priorité fixe pour chacune, que l'on va désigner comme des tâches. Le Z80 bootera avec la tâche la plus prioritaire. Si on n'active pas le mode multitâche coopératif, le fonctionnement général du Z80 sera normal comme si il n'y avait aucune tâche. Les registres IR, IM, IFF1 et IFF2 sont communs aux tâches.
Partant du principe que le mode d'interruption IM 0 est un vestige du 8080 qui n'est quasiment jamais utilisé par les systèmes Z80 (IM 1, voire IM 2), il pourrait servir à activer le mode multitâche coopératif (IM 1 et IM 2 désactiveraient ce mode). Il faut également des instructions qui permettent d'installer une tâche, d'activer une tâche ou de céder l'exécution à une autre tâche.
Attention, je précise qu'il n'y a bien qu'un seul processeur Z80 et un seul cœur d'exécution.
LDPC n,HL : modifie le registre PC de la tâche n. On présume que le PC pointe sur un prologue qui se charge d'installer la pile pour cette tâche et de faire l'initialisation nécessaire pour la routine qui suit dans le code.
Code : Tout sélectionner
LD HL, MyTaskSetup; PC to setup task #3
LDPC 3,HL ; setup task #3
... ; do whatever
Loop:
... ; do whatever
RAISE 3 ; active task #3 (this task is supposedly to be more prioritized than the current one)
... ; do whatever
JR/JP Loop
...
MyTaskSetup: ; call through the first RAISE 3
LD SP, MyTaskStack ; setup a stack for task #3
... ; do your necessary initialization
MyTaskRoutine: ; call through the rest of RAISE 3
... ; do your routine service
YIELD
JR/JP MyTaskRoutine
YIELD : marque la tâche courante comme étant inactive puis ordonne au Z80 de continuer l'exécution sur la tâche active la plus prioritaire. C'est comme l'équivalent d'un RET mais qui ne prend que 4 cycles, voire moins.
Reste les interruptions.
/RESET : à ce signal, on active la tâche 0 (la plus prioritaire). Elle sera toujours exécutée par RAISE 0. Faut-il que RST 00h en fasse de même ? je me le demande.
/NMI : à ce signal, on active la tâche 1. Elle sera toujours exécutée immédiatement sauf si la tâche 0 est active (elle reprend après un YIELD de la tâche 0). La routine n'a pas besoin de faire de la sauvegarde/restauration des registres en pile puisqu'elle dispose de ses propres registres, d'où un gain d'exécution de l'interruption non négligeable.
/INT : à ce signal, on active la tâche 2. Elle sera toujours exécutée immédiatement sauf si la tâche 0 ou 1 est active (elle reprend après un YIELD des deux tâches 0 et 1). La routine n'a pas besoin de faire de la sauvegarde/restauration des registres en pile puisqu'elle dispose de ses propres registres, d'où un gain d'exécution de l'interruption non négligeable.
RST 00h et 38h : Devrait-on les exécuter respectivement comme un RAISE 0 et RAISE 2 ? ces instructions ont des adresses fixes alors que les tâches 0, 1 et 2 ne sont pas tributaires de ces adresses donc ces instructions peuvent fonctionner indépendamment des tâches sur l'usage que voudra en faire le code système (très souvent le cas sur les machines).
Le registre R étant utilisé pour le rafraichissement et I pouvant être détourné à un usage spécifique (on pense au ZX81 par exemple), il vaut mieux les garder en commun pour toutes les tâches. Le registre IM devant contenir 0, il est logique qu'il soit aussi commun. Et enfin IFF1 et IFF2 ne devrait pas servir à grand chose en mode multi-tâche coopératif.
C'est tout... pour le moment.