CODING ★ Dr.Watson - Autoformation à l'assembleur par Micro Application ★

Dr.Watson - Autoformation à l'assembleur par Micro Application - Chapitre 09

CHAPITRE 9

OPERATIONS SPECIALES ET INTERRUPTIONS

Ce chapitre traite quelques propriétés parmi les moins utiles du Z80 en langage assembleur, tout au moins d'un point de vue purement logiciel. Beaucoup de ces opérations et propriétés spéciales décrites dans ce chapitre ne sont pratiquement pas utilisées du tout par la plupart des programmeurs.

Cependant, il est intéressant de les connaître. Les interruptions, expliquées ci-dessous, sont très utiles, mais en faire une explication détaillée ne sera pas notre but car elles sont plutôt un sujet pour un livre axé sur l'électronique.

Les interruptions

Quand on exécute un travail qui doit être fait, personne n'aime les interruptions tant que le travail n'est pas fini. Le Z80 est aussi comme ça, Quand il exécute un bout de programme, il a tous ses registres sous contrôle et tous ses flags mis correctement. Une Interruption, cependant, est un sous-programme qui demande a être exécuté quand il est prêt, pas quand le Z80 est prêt. En clair, une interruption vient de l'extérieur du champ de contrôle direct du Z80 –soit d'un appareil externe, soit du clavier. Dès lors, les flags doivent "être stockés par le Z80 - le plus souvent sur la pile, Alors le Z80 prendra en charge l'Interruption - c'est-à-dire faire tout ce que doit faire l'interruption, et il doit ensuite restaurer tous les registres et flags et continuer avec le programme originel. Manier des interruptions doit être possible dans tous les programmes qui attendent des interruptions, particulièrement si le programme effectue certains travaux qui ne doivent pas être interrompus. Si, par exemple un autre appareil envole une suite de données en mémoire/ alors une procédure "hand-shaking" (poignée de mains) est enclenchée entre les deux appareils. Tout simplement c'est un échange de messages du genre: "Je suis prêt à envoyer les données/ êtes-vous prêts à les recevoir?" "Oui" "Voilà les données ... fin des données." "Merci!"

Si un tel échange est Interrompu, les données risquent bien d'être mutilées, et donc d'être inutilisables, Pendant de telles périodes où aucune interruption n'est possible, le programme peut bloquer la plupart des interruptions - pas toutes - pour permettre à une procédure particulière d'être achevée. Les interruptions qui peuvent être bloquées sont appelées interruptions masquables, et les interruptions qui ne peuvent être bloquées sont appelées interruptions non-masquables, ou NMI.

L'instruction qui bloque toutes les interruptions masquables est DI:

DI DIsable maskable interrupts (Empêche les interruptions masquables)

Une fois achevée la partie de programme, de préférence courte, qui ne peut être interrompue, on peut à nouveau rendre possible les interruptions en utilisant EI

EI Enable maskable Interrupts (Permet les interruptions masquables)

Quand le Z80 prend en charge une interruption, il le fait au moyen d'un sous-programme en code machine. Comme les autres sous-programmes, ils doivent se terminer par une instruction de retour. Pour les interruptions non-masquables l'instruction est:

RETN RETurn from Non-maskable interrupt (Retour d'interruption non-

masquable)

Pour les interruptions masquable c'est:

RETI RETurn from Interrupt (Retour d'interruption)

Si vous réfléchissez à ce qui précède, vous avez peut-être compris que les interruptions peuvent être interrompues. Cependant, il y a des priorités: par exemple, une interruption masquable ne pourra normalement pas interrompre une interruption non-masquable - la plupart du temps elle devra attendre.

L'interruption la plus prioritaire de toutes est une "demande du bus" ou BUSRQ. Avec les autres interruptions masquables et non-masquables, le Z80 finira au moins d'exécuter l'instruction en cours avant de s'occuper de l'interruption. Avec un BUSRQ, au contraire, le Z80 réagit au battement suivant de son horloge interne - c'est-à-dire au cycle suivant - qu'il ait accompli l'instruction suivante ou non.

La réaction du Z80 à une interruption masquable dépend du mode actuel d'interruption. Dans tous les cas, il empêche en premier lieu des interruptions (masquables) supplémentaires, et sauvegarde le PC sur la pile. Il est toujours nécessaire de permettre à nouveau les interruptions (Ei) avant de sortir de vos programmes de service des interruptions.

MODES D'INTERRUPTION POUR INTERRUPTIONS MASQUABLES

Le mode implicite est le mode 0. Il peut être fixé a l'intérieur d'un programme en utilisant l'instruction:

IM 0 Met mode d'interruption 0

Avant de recevoir et d'accepter une interruption en mode 0, le Z80 attendra que le périphérique externe lui donne une instruction au cycle d'horloge suivant au moyen de sa ligne d'entrée générale, le "bus de données".

Cette instruction est généralement un appel (CALL) d'un programme gérant des interruptions que le programmeur a placé quelque part en mémoire. C'est aussi souvent une instruction de redémarrage (ReSTart):

RST n Relancer à adresse n

L'adresse n est une adresse d'un seul octet et se trouve obligatoirement parmi les adresses suivantes: &0, 88, &10, 818, 820, 828, &30, et 838, Comme RST est une instruction d'un seul octet, elle est souvent utilisée quand on a besoin d'une réponse rapide à l'interruption. Le problème avec RST est qu'il y a seulement de la place dans ces cases mémoires pour un saut à une autre adresse - particulièrement s'il va plusieurs programmes gérant des interruptions, chacun utilisé par des appareils différents utilisant des adresses RST différentes.

CALL et RST entraînent tous deux la sauvegarde du PC sur la pile. Le Z80 empêche des interruptions supplémentaires et commence la routine de service des interruptions. Si le programmeur a besoin de préserver les registres et les flags, le programme gérant les interruptions doit commencer à peu près comme ça:

PROGRAMME 9.1

PUSH AF

PUSH BC

PUSH DE

PUSH HL

PUSH IX

PUSH IY

Et devrait finir à peu près comme ceci:

PROGRAMME 9.2

POP IY

POP IX

POP HL

POP DE

POP BC

POP AF

EI

RETI

Remarquez le "AF". C'est l'accumulateur et les flags. Le prochain mode d'interruption est le mode 1.

IM 1 Met mode d'interruption 1

Ce mode est identique au mode d'interruption 0 à la différence que le Z80 exécute automatiquement un RST &38 avant d'accepter une interruption masquable. De plus, le Z80 ignorera le contenu de son bus de données dans le cycle d'horloge suivant l'interruption. Le dernier mode est le mode 2:

IM 2 Met le mode d'interruption 2

Dans ce mode, après avoir fini l'instruction en cours, sauvegardé le PC et empêché des interruptions masquables supplémentaires, le Z80 sautera à n'importe quelle case mémoire d'adresse paire - c'est-à-dire dont le bit le moins significatif est 0. Les huit bits les plus significatifs devront "être mis à l'avance sur un registre spécial appelé registre de vecteur d'interruption, ou registre "I". Les huit bits les moins significatifs de l'adresse sont envoyés par le périphérique interrupteur. Cela permet au Z80 de sauter à n'importe laquelle des 128 adresses figurant dans une table en mémoire commençant à l'adresse octet fort figurant dans le registre I.

LES REGISTRES DE REMPLACEMENT

Vous êtes maintenant parfaitement au courant du fait que le Z80 a beaucoup de registres différents, en particulier. A, B, C, D, E, H, L, et les flags. Eh bien, le Z80 a un deuxième Jeu de ces registres particuliers, connu sous le nom de registres de remplacement, A', B', C', D', E', H', L' et les flags de remplacement F'.

Même s'ils peuvent être utilisés par le programmeur, il est déconseillé de les utiliser sur l'Amstrad.

L'utilisation de programmes intégrés les altérerait, comme le ferait n'importe quelle interruption. Les instructions pour les utiliser sont les suivantes:

EXX Intervertit les couples de registres

Cette instruction intervertit les contenus de BC, DE, et HL avec leurs remplaçants. Notez que toute instruction suivante utilisant par exemple DE utilisera maintenant le nouveau contenu de DE, qui était

auparavant dans DE'.

Si on utilise les registres de remplacement B' ou C', ils doivent être restaurés avant d'être basculés à nouveau sur le jeu de registres originel et de permettre les interruptions. Un programme pour utiliser les registres de remplacement ressemblera donc à ceci:

DI ; Empêche les interruptions

EXX ;Intervertit les couples de registres

PUSH BC Sauvegarde nouveau BC

POP BC Restaure BC

EXX Revient sur registres initiaux

EI ; Empêche les interruptions

Les programmes de ce genre doivent être courts, car diverses interruptions automatiques du système d'exploitation telles que les horloges, les examens du clavier etc. ont besoin des registres de remplacement, et qu'un programme trop long peut poser des problèmes. C'est vrai quelque soit le moment où on empêche les interruptions. (Pour plus de détails voir Soft 158).

Une autre instruction permet d'utiliser A' et F':

EX AF,AF' Intervertit les contenus de AF et AF'

F' doit être restauré avant une nouvelle interversion. Encore une fois, les interruptions doivent être empêchées tandis qu'on utilise ces registres.

Notez qu'on utilise la même instruction pour réintervertir les registres - c'est-à-dire EX AF,AF' et non EX AF',AF.

D'AUTRES INSTRUCTIONS D'ECHANGE

Il y a deux autres formes de EX qui valent la peine d'être mentionnées:

EX DE,HL Intervertit les contenus de DE et de HL

et

EX (SP),HL Intervertit le haut de la pile et le contenu de HL

EX (SP),IX Intervertit le haut de la Pile et le contenu de IX

EX (SP),IY Intervertit le haut de la pile et le contenu de IY

Le premier octet sur la pile va dans L et vice-versa, et l'octet suivant sur la pile va dans H (et vice versa). Procéder de la même façon avec IX et IY.

ARRET

HALT Arrête l'exécution du programme

Cette instruction arrête le Z80 jusqu'à ce qu'une Interruption soit reçue. La seule chose qu'elle fasse est de 'rafraîchir' la mémoire. Comme vous le savez, si vous coupez l'ordinateur, il oublie tous les programmes ou les données figurant dans sa mémoire. Ceci parce que la mémoire est une mémoire RAM dynamique ou Random Access Memory. Si la mémoire n'est pas mise à jour ou rafraîchie en permanence - c'est-à-dire si le voltage interne n'est pas corrigé en permanence, alors ces voltages disparaissent et les données stockées avec eux. Le Z80 utilise un registre de rafraîchissement qui lui dit quelle mémoire il doit rafraîchir et à quel moment.

LES ENTREES ET LES SORTIES DU Z80

Le Z80 a toute une famille d'instructions conçues pour permettre des entrées et des sorties a partir et vers des appareils externes. Encore une fois, ces instructions sont orientées électronique, et seront seulement expliquées brièvement ici.

IN A,(n) Entre le contenu du port n dans l'accumulateur

Un port est un connecteur avec un appareil externe. Tel numéro renvoie à tel port déterminé par l'électronique - c'est-à-dire par le câblage et par les circuits de l'ordinateur.

Le port, pour ce qui concerne l'ordinateur, est un magasin de données de huit bits.

IN A,(n) n'affecte aucun des flags.

Il existe une forme de l'instruction IN qui permet au contenu d'un port dont le numéro figure dans le registre C d'être placé dans n'importe lequel des registres A,B,C,D,E,H, ou L:

IN r,(C) Entre le contenu du port adressé par C dans registre r

Cette instruction annule le flag addition/soustraction. Le flag carry n'est pas affecté, mais les autres flags sont altérés suivant la valeur entrée.

Si elles sont nécessaires, le Z80 a d'autres formes de l'instruction IN qui mettent en parallèle LDI, LDIR etc.

La première est:

INI Entre le contenu du port adressé par C, décrémente B, incrémente HL

Avec cette instruction, B peut être utilisé comme compteur de boucle si c'est nécessaire. Notez, cependant, que B seulement est utilisé par INI, plutôt que BC comme dans LDI par exemple. C doit contenir le numéro de port, et HL la case mémoire dans laquelle la donnée sera placée. INI altère le signe, les flags demi-carry et parité/dépassement, et met le flag addition/soustraction. Le flag carry n'est pas affecté. Le flag zéro est mis quand B=1.

INIR Entre le contenu du port adressé par C, décrémente B, incrémente HL,

recommence jusqu'à ce que B=0

Cette fonction est équivalente à INI sauf qu'elle recommence automatiquement jusqu'à ce que B soit décrémenté jusqu'à zéro. Les flags sont affectés de la même manière qu'avec INI sauf que le flag zéro est toujours mis.

IND Entre le contenu du port adressé par C, décrémente B, décrémente HL

INDR Entre contenu du port adressé par C, décrémente B, décrémente HL, recommence jusqu'à ce que B=0

Ces instructions sont respectivement identiques à INI et INIR, sauf que HL est décrémenté au lieu d'être incrémente.

OUT (n),A Sort le contenu de l'accumulateur sur le port n

OUT (C),r Sort le contenu du registre r sur le port adressé par C

La dernière de ces deux instructions est différente de IN r,(C) par le fait qu'elle n'affecte aucun flag.

OUTI Sort sur le port adressé par C le contenu de la mémoire adressée par HL, décrémente B, incrémente HL

OTIR Sort sur le port adressé par C le contenu de la mémoire adressée par HL, décrémente B, incrémente HL, recommence jusqu'à ce que B=0

OUTD Sort sur le port adressé par C le contenu de la mémoire adressé par HL, décrémente B, décrémente HL

OTDR Sort sur le port adressé par C le contenu de la mémoire adressée par HL décrémente B, décrémente HL, recommence jusqu'à ce que B=0

Ces instructions affectent les flags de la même façon que les instructions IN correspondantes.

Une Instruction peu utile n'a pas encore été mentionnée:

NOP

NOP No Opération (Pas d'opération)

Elle dit au Z80 de ne rien faire pendant un cycle d'horloge. Cela peut "être très utile pour une bonne mise au point de la durée des boucles de temporisation. De même, si vous utilisez des adresses absolues plutôt que

des étiquettes symboliques, elle peut être utilisée pour compléter votre programme afin d'autoriser des erreurs d'adressage.

RESUME

Ce chapitre a couvert les instructions suivantes:

DI EX AF,AF'

EI EX DE,HL

RETN EX (SP),HL

RETI EX (SP),IX

IM0 EX (SP),IY

IM1 HALT

im3 IN A,(n)

RST n IN r,(C)

EXX INI

OUI (n),A INIR

DUT (C),r IND

OUTI INDR

OTIR NOP

OUTD

OTDR

★ ANNÉES: 1985
★ AUTEUR: T. Hebertson
★ CONVERTION: CRACKERS VELUS

Page précédente : Dr.Watson - Autoformation à l'assembleur par Micro Application - Chapitre 08
 
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 213 millisecondes et consultée 1218 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.