CODINGANTOINE ★ ASSEMBLEUR Z80 - Les codes spéciaux ★

Z80: Les Codes Speciaux (1/2)Coding Antoine
Eh oui ! Après vous avoir fait ch.. en vous bassinant sur les codes non-valides du Z80 et en vous refilant une routine dont vous ne saviez que faire et qui de plus etait buggeé, je vais enfin TOUT vous dire sur ces fameux codes. Tout d'abord il faut que je réponde à une question que vous vous posez surement: Ma qu'est-ce que ça sont que ces codes spéciaux (combien de fois vais-je répéter ce mot ?!) ? Et bien ce sont des codes qui ne sont pas mentionnés dans les livres classiques tels "l'initiation à l'assembleur" ou "le langage machine de l'Amstrad", et qui normalement sont inconnus de la plupart des programmeurs. Notez qu'à la fin du bouquin "la Bible du CPC 6128", les auteurs parlent d'"instructions spéciales du type &CB (IX+d)" ; en vérité ce que leur désassembleur ne digère pas, ce sont des codes tout à fait normaux comme SRL (IY+4) - par exemple - rien à voir donc avec ce dont je vais vous parler.

Pour étudier ces codes, il faut un programme de test qui est normalement sur une des deux faces du disk... Quand vous l'exécutez il vous demande tout d'abord les valeurs à mettre dans les registres avant l'instruction à étudier, puis il vous demande le code hexa à étudier (16 octets maxi); cela peut etre un appel à une routine, si c'est une routine système il faudra prendre les valeurs système des registres alternatifs, sinon cette option n'est pas indispensable... Voilà pour le prog. de test.

Mais j'en vois qui perdent leur patience et c'est tout à fait normal...donc les codes spéciaux se divisent en fait en 2 catégories:
— les nouveaux codes qui correspondent en fait à des instructions existant déjà (plus de 230).
— les nouveaux codes qui ont une fonction qui ne correspond à aucune instruction déjà existante (plus de 340).

C'est bien sur la deuxième catégorie qui est la plus intéressante, mais nous allons aussi voir la première. Mais plutot que de traiter ces deux parties indépendamment l'une de l'autre, je préfère séparer les différents thèmes: codes en &CB, codes en &ED, index 8 bits, et enfin index en &CB avec post-transfert... allez c'est parti !!!

CODES EN &CB: Si vous avez une table des codes Z80, vous aurez remarqué qu'il y a une ligne vacante "en-dessous" de SLA, c'est-à-dire de CB 30 à CB 37. En effet ces codes correspondent en fait à une instruction nommée SLI. Elle fait la meme chose que SLA à une différence près: au lieu de décaler un 0 dans le bit de poids faible, elle y décale un 1...
Vous voyez que ce n'est pas si compliqué... Allez, je vous refile quand meme une petite table au cas où :

CB 30 CB 31 CB 32 CB 33 CB 34 CB 35 CB 36 CB 37
SLI B SLI C SLI D SLI E SLI H SLI L SLI (HL) SLI A
DD CB 36 dis FD CB 36 dis et n'oubliez pas que 'dis'
SLI (IX+dis) SLI (IY+dis) est un nombre signé...

CODES EN &ED: Rien de compliqué à comprendre ici non plus... Par contre c'est beaucoup plus bordélique (et je reste poli...) ! C'est pourquoi je vais dès maintenant vous refiler une table et les explications viendront après :

01 2 3 4 5 67
4IN B,
(C)
OUT
(C),B
SBC
HL,BC
LD
(ADR),BC
NEGRETNIM 0LD I,A
5IN D,
(C)
OUT
(C),D
SBC
HL,DE
LD
(ADR),DE
*NEG*RETNIM 1LD A,I
6IN H,
(C)
OUT
(C),H
SBC
HL,HL
LD
(ADR),HL
*NEG*RETN*RESETRRD
7*NOP *NOPSBC
HL,SP
LD
(ADR),SP*
NEG*RETN*NOP *NOP
89ABCDEF
4IN C,
(C)
OUT
(C),C
ADC
HL,BC
LD
BC,(ADR)
*NEGRETI*RESETLD R,A
5IN E,
(C)
OUT
(C),E
ADC
HL,DE
LD
DE,(ADR)
*NEG*RETIIM 2LD A,R
6IN L,
(C)
OUT
(C),L
ADC
HL,HL
LD
HL,(ADR)
*NEG*RESET*RESETRLD
7IN A,
(C)
OUT
(C),A
ADC
HL,SP
LD
SP,(ADR)
*NEG*RESET*RESET*NOP

Vous aurez remarqué qu'en abscisse est porté le quartet faible et en ordonnée le quartet fort de l'instruction...ainsi l'instruction ADC HL,SP a pour code ED 7A... Les instructions précédées d'un astérisque sont les nouveaux codes. Ils correspondent tous à des instructions déjà existantes, sauf une que l'on va donc approfondir: l'instruction RESET.
Comme son nom l'indique elle effectue un reset du Z80. Mais me direz-vous cela correspond alors à RST 0 ? Non car cette dernière effectue simplement un saut à l'adresse &0000 comme un CALL 0. Tandis que RESET fait une sorte de reset hard de notre bon vieux Z80, c'est-à-dire que le PC passe à 0, que les interruptions sont inhibées, que le mode d'interruption IM 0 est activé et que l'exécution du programme reprend en &0000... Par contre le contenu des autres registres est conservé...

Pour mettre tout ceci en évidence voici une petite routine :

ORG &A500
DEBUT LD A,&C3
LD (0),A
LD HL,INIT
LD (1),HL
DB &ED,&66 ;=RESET
INIT IM 1
JP &A0A3

Assemblez cette mini-routine et lancez le prog. de test. Sélectionnez les valeurs que vous voulez pour les registres puis entrez comme code C3 00 A5 (=JP &A500). Vous voyez que tout fonctionne normalement. Maintenant remplacez tour à tour dans la routine IM 1 par un NOP, et DB &ED,&66 par un RST 0... Vous notez les résultats suivants:

; RESET (=DB &ED,&66) RST 0
IM 1 ;marche ; marche
NOP ;plante !! ; marche...

Ce tableau parle de lui-meme !! A noter quand meme qu'ED 66 et ED 4E sont des valeurs garanties pour l'instruction RESET, les autres moins... C'est-à-dire que je n'ai pas fini mes études sur ces codes en &ED et donc la table des codes que je vous ai fournie n'est pas sure à 100 %.

INDEX 8 BITS: C'est la partie la plus connue de ces codes spéciaux... Il s'agit de codes permettant aux registres IX et IY, de pouvoir etre manipulés par 8 bits...c'est-à-dire d'adresser indépendamment l'octet faible et l'octet fort...Pour cela, je ne vais pas vous mettre de tables mais plutot essayer d'éclaircir la logique de décodage des codes par le Z80. En effet, lorsque le Z80 rencontre une instruction portant au départ sur HL, et que celle-ci est précédée de DD ou FD, il remplace HL par IX ou IY; idem pour (HL) qui devient respectivement (IX+d) ou (IY+d), tout ceci à l'exception des codes en &ED et de EX DE,HL, mais vous devriez normalement déjà le savoir...

Maintenant, si l'instruction en question ne porte ni sur HL, ni sur (HL), le Z80 fait de meme avec H et L...ce qui permet de manipuler les 2 octets des regs. d'index indépendamment l'un de l'autre. En effet si l'instruction porte sur H ou L, c'est-à-dire en fait sur l'octet high ou low du reg. double HL, il le remplace par l'octet correspondant du reg. d'index sélectionné. Par exemple:

le code 4C correspond à LD C,H ... donc le code FD 4C fait de meme, mais en remplaçant H par l'octet High de IY.

Les conventions d'écriture sont :

IYH=octet High du reg. IY
IYL = " Low " " "
IXH = octet High du reg. IX
IXL = " Low " " "

Les instructions obtenues modifient les flags de la meme façon que leurs homologues...Attention cependant car l'adressage index 8 bits n'existe qu'avec les instructions qui ont un code d'instruction sur un octet; en clair celles qui ne commencent ni par &ED, ni par &CB. Cela donne donc la liste de mnémoniques suivante:

LD reg,valeur ; INC reg. ; DEC reg. ; LD reg.objet,reg.source
ADD A,reg. ; ADC A,reg. ; SUB reg. ; SBC A,reg.
AND reg. ; XOR reg. ; OR reg. ; CP reg.

Attention également car il n'y aura jamais de trucs du type LD (IX+d),IXH ou encore moins LD (HL),IYL. En effet ces instructions portent tout d'abord sur le reg. double (HL) et le Z80 se contente d'appliquer la règle normale des index 16 bits.

Maintenant que nous avons vu les instructions qui acceptent l'adressage index 8 bits, que deviennent les autres codes précédés d'un code d'index DD ou FD ?? Et bien ils se divisent en 3 groupes:

  • soit c'est une instruction qui a un code d'opération sur un octet et qui ne porte ni sur HL, ni sur H, ni sur L. Dans ce cas elle a la meme fonction que si on ne l'avait pas précédée d'un code d'index.
  • soit c'est une instruction commençant par &ED et c'est la meme chose que ci-dessus. C'est pourquoi il n'y a pas de SBC IX,DE ou encore de OUT (C),IYH.
  • soit c'est une instruction commençant par &CB et qui ne porte pas sur (HL), et c'est justement ce que nous allons voir maintenant...

INDEX EN &CB AVEC POST-TRANSFERT INDEXE: et c'est là que ça commence à devenir compliqué... Rien que le nom déjà a un je-ne-sais-quoi d'effrayant !! Allez je le répète pour vous achever complètement: codes spéciaux d'index en &CB avec post-transfert indexé... Remarquez que ce nom horrible, c'est moi qui l'ai inventé, alors...

Et puis tiens pour commencer on va le décortiquer un peu ce nom, pour savoir à quoi on a affaire...voyons voyons... Déjà on voit les mots 'index en &CB' et 'transfert indexé'. Ce sont donc des instructions de la forme: FD/DD CB dis cod . Où 'dis' est la distance de l'adressage indexé (8 bits signés...) et 'cod' le code d'opération. Oui bon d'accord mais pour l'instant ça nous avance pas à grand-chose.

Pour comprendre parfaitement ce dont il s'agit, il faut encore une fois expliquer le décodage par le Z80... Quand le Z80 rencontre un code en &CB précédé d'un code d'index: codXY_CB_dis_code , il effectue l'instruction correspondante en adressage indexé, c'est-à-dire sur (XY+dis). Mais ensuite, comme l'indique l'expression "post-transfert indexé", il charge le résultat de l'opération dans le registre normalement concerné s'il n'y avait pas eu de code d'index...

Par exemple le code FD CB 08 13 correspond à RL (IY+8) suivi de LD E,(IY+8). En effet CB 13 est le code de RL E et FD 08 fait pointer sur l'adresse (IY+8). Cette instruction sera notée par convention RL (IY+8)/E. Cette notation fait à mon avis bien apparaitre l'adressage indexé et la notion de post-transfert, c'est pourquoi je l'ai choisie.

A noter que l'instruction SLI vue plus haut permet aussi l'adressage indexé avec post-transfert. Par contre, l'instruction BIT n'effectue JAMAIS de post-transfert, les codes spéciaux correspondront en fait à un adressage indexé normal, du type BIT (IX+d) ou BIT (IY+d).

Et vi c'est enfin fini !! Hein ? Quoi ??!? Vous voulez savoir de quelle couleur sont les rasters de la Zebig Megademo ?? Incroyable...Y'en a qui suivent l'article depuis le début et qui n'ont pas encore compris de quoi ça parlait...vraiment lamentable !! Bon pour quand meme finir sur quelque chose de sérieux, je dirai que le débat sur les instructions spéciales n'est pas clos, et qu'il tout à fait possible de le reprendre une prochaine fois, notamment si vous n'avez pas tout compris, et si vous me le dites, paske je peux pas savoir si vous me le signalez pas, je m'appelle pas 36 15 Madame Irma...

Sinon, vous devriez normalement avoir droit, le mois prochain, à un petit cours assembleur sur les instructions dont on parle moins: DAA, RLD et RRD, etc... D'ailleurs vous pouvez parfaitement allonger cette liste, vous n'avez qu'à m'écrire... Ah bien sur, ce ne sera pas aussi long que ce mois-ci, mais là c'était parce que j'avais pris du retard... Allez mijotez-bien sur toutes ces nouvelles instructions et n'oubliez pas de vous aider du prog. de test que je vous ai mis sur le disk...ça vous aidera à comprendre comment elles fonctionnent...

Lire le correctif de MM&PF numéro°7

Antoine / POW pour MM&PF

★ ANNÉE: ???
★ AUTEUR: ANTOINE

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Z80: La Multiplication
» Coding » Cours et Initiation par Antoine / POW
» Coding » Z80: Les Codes Speciaux (2/2)
» Coding » Z80: La division
» Coding » Clefs2 50 - Amsdos - Ouverture Fantome d'un Fichier
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.73-desktop/c
Page créée en 492 millisecondes et consultée 3994 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.