Page en construction.
Il ne s’agit pas d’une traduction complète de la datasteat mais d’un résumé.
J’en traduit un peu de temps en temps un peu d’aide ne serait pas de refus.
Il se peut qu’il y ait des erreurs car les documentations ne sont pas très claires mais je m’efforce d’éclaircir certaines zones d’ombres.
Ne vous y fiez pas trop pour l’instant, si vous voyez des erreurs n’hésitez pas a la corriger.
Instruction Group | Mnemonic |
---|---|
Data transfer instruction | LDEA, MOV, TRANS, TRANSB, XCH |
Repeat prefix | REP, REPE, REPNE, REPNZ, REPZ |
Primitive block transfer instruction | CMPBK, CMPBKB, CMPBKW, CMPM, CMPMB, CMPMW, LDM, LDMB, LDMW, MOVBK, MOVBKB, MOVBKW, STM, STMB, STMW |
Input/output instruction | IN, OUT |
Primitive input/output instruction | INM, OUTM |
Addition/subtraction instruction | ADD, ADDC, SUB, SUBC |
Increment/decrement instruction | DEC, INC |
Multiplication instruction | MUL, MULU |
Division instruction | DIV, DIVU |
BCD adjustment instruction | ADJ4A, ADJ4S, ADJBA, ADJBS |
Data conversion instruction | CVTBD, CVTBW, CVTDB, CVTWL |
Comparison instruction | CMP |
Complement operation instruction | NEG, NOT |
Logical operation instruction | AND, OR, TEST, XOR |
Bit manipulation instruction | CLR1 CY,CLR1 DIR, SET1 CY, SET1 DIR, NOT1 CY |
Shift instruction | SHL, SHR, SHRA |
Rotate instruction | ROL, ROLC, ROR, RORC |
Subroutine control instruction | CALL, RET |
Stack manipulation instruction | DISPOSE, POP, PREPARE, PUSH |
Branch instruction | BR |
Conditional branch instruction | BC, BCWZ, BE, BGE, BGT, BH, BL, BLE, BLT, BN, BNC, BNE, BNH, BNL, BNV,BNZ, BP, BPE, BPO, BZ, BV, DBNZ, DBNZE, DBNZNE |
Interrupt instruction | BRK, BRKV, CHKIND, RETI |
CPU control instruction | BUSLOCK, DI, EI, FPO1Note, HALT, NOP, POLL |
Segment override prefix | DS0:, DS1:, PS:, SS: |
Plus de détails sur les instructions asm du V30:
classe : 286
Instructions supplémentaire : ADD4S, BRKEM, CALLN, CLR1, CMP4S, EXT, FPO2, INS, NOT1, REPC, REPNC, RETEM, ROL4, ROR4, SET1, SUB4S, TEST1
Structure : RISC (programme et données accessible avec le même bus d’adresse)
Fréquence max de travail: 8 MHz
Bus d’adresse : 20 bits
Bus de données : 16 bits
Largeur de Pile : 16 bits
Connections a un co-processeur : possible
Symbole électrique :
Description des broches :
Type | nom | rôle |
---|---|---|
Sorties | A19 – A0 | bus d’adresse |
Entrée | DI15 – DI0 | bus de données en entrée |
Sortie | DO15 – DO0 | bus de donnée en sortie |
Sortie | UBEB | disponibilité d’une donnée |
Sortie | BS3 – BS0 | bus de statu |
Entrée | READYB | signal de génération de cycle d’attente |
Sortie | BUSLOCKB | signal look |
Entrée | POLLB | signal périodique de system externe |
Entrée | RESET | RAZ du uC |
Entrée | HLDRQ | accusé réception des données en sortie |
Sortie | HLDAK | accusé réception des données en entrée |
Entrée | NMI | interruption non masquable |
Entrée | INT | interruption masquable |
Entrée | CLK | horloge system |
Entrée | BUNRI | broche de test |
Entrée | TEST | broche de test |
Entrée | TBI22 – TBI0 | bus de test |
Entrée | DBINT | réservé pour le NEC |
Sortie | DBMODE | idem |
Sortie | DBA20 | idem |
Sortie | DBRD | idem |
Sortie | DBWR | idem |
Entrée | DBNMIM | idem |
Sortie | DBHLTST | idem |
Sortie | TEOI | idem |
Sortie | TILENT – TILEN0 | idem |
Sortie | TBRA | idem |
Sortie | TINTA | idem |
Ces registres sont des registres de 16 bits. Chacun de ces registres sont divisé en deux parties de 8 bits :
Ainsi on peut accéder à ces registres en 16bit si on s’adressa a eux avec AW, BW, CW ou DW ou en 8 bits si on utilise AH, BH, CH, DH, AL, BL, CL, DL.
Par exemple si on met $FF dans AH et $08 dans AL, alors le registre AW contiendra la valeur $FF08. Cette caractéristique est exploitée par un grand nombre d’instructions comme la multiplication ou la division.
La mémoire adressé par les 286 est divisée en segments de 64 Ko et le uC peux gérer 4 segments simultanément. (cf chap 4.3 “Adresse physique et adresse logique”)
L’adresse du début de chaque segments sont indiquée dans les registres suivants :
Ca explique le fait que l’exécutable (.exe) qui est chargé en RAM lors de son lancement ne peux pas dépasser 64 Ko. C’est différent pour les .rxe
Ces registres sont utilisés comme pointeurs pour spécifier une adresse dans la mémoire et peut être référencé dans une instruction. Ils peuvent aussi être utilisé comme index.
SP est utilisé comme pointeur de pile.
BP est utilisé comme pointeur de base
Ce registre contient l’adresse de l’instruction qui va être exécuté.
Ce registre est incrémenté a que chaque fois que le microprogramme vas chercher une instruction ou un code dans la file d’instruction.
Lors d’une instruction conditionnelle ou un saut le PC est initialisé avec l’adresse de l’instruction de destination.
Ce registre comporte un ensemble de bits qui donnent une information très complète sur la dernière opération effectuée.
Lors des sauts conditionnelle le uC regarde a quel niveau est ce bite (appelé flag) pour effectuer le saut ou non.
Par exemple pour exécuter le code suivant :
A = A - B SI (A == 0) ALORS SAUT @label (instruction asm : JZ @label) Suite du prog ….
Le uC regarde le flag correspondant au résultat nulle Si ce flag est a 1 ça veux dire que la dernière opération effectué a donné un résultat nulle et que donc A est nulle alors le branchement est effectué. Si non il n’est pas effectué.
Il est rare que le programmeur utilise directement ces flags car ils sont principalement utilisés par le uC.
Le PSW comporte 6 flags d’état et 4 flags de contrôle.
Flags d’état :
Avec tous ces flags le uC peux gérer toutes les conditions.
Toutes les instructions n’initialisent pas de flags d’état, pour savoir si un/des flags d’état sont modifié par une instruction il faut se reporter a sa description (ç’est souvent une source d’erreurs du programmeur notamment avec les instructions non signées).
Généralement on utilise ces flags en lecture.
Flags de contrôle :
Généralement on utilise ces flags en écriture.
organisation de ces flags dans la registre d’état PSW :
bit15 | bit14 | bit13 | bit12 | bit11 | bit10 | bit9 | bit8 | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MD | 1 | 1 | 1 | V | DIR | IE | BRK | S | Z | 0 | AC | 0 | P | 1 | CY |
Lors d’une interruption ou d’un saut a un sous programme le PSW est automatiquement sauvegardé dans la pile et il est restauré lorsque une instruction de retour (RET ou RETI) est rencontré.
Ce registre peut aussi être sauvegardé/restauré manuellement avec las instructions PUSH PSW et POP PSW
Ce sont 2 registres de 16 bits qui sont utilisé pour lire ou écrire des données en mémoire avec le mode d’adressage indexé.
Ces registres peuvent être référencé dans une instruction qui accepte l’adressage indexé.
En outre, suivant certaines instructions ils peuvent avoir d’autres fonctions spécifiques.
NECV30Mx peut adresser un espace mémoire de 1Mo car il a 20 bits d’adresse. Voici comment est organisé cette mémoire :
Zone mémoire | description | remarque |
---|---|---|
$FFFFF - $FFFFC | espace réservé | ne pas l’utiliser |
$FFFFB – $FFFF0 | région dédiée | automatiquement utilisé lors de RAZ, START … |
$FFFEF - $00400 | espace pour l’utilisation général | utilisé pour le programme,l’OS,bios... |
$003FF - $00000 | table de vecteurs d’interruption | Voir chapitre sur les interruptions |
C’est théoriquement possible d’accéder à un espace I/O de 64 Ko dans une région indépendante de la mémoire. Cet espace est accessible avec les 16 bits de poids faible du bus d’adresse.
Zone mémoire | description |
---|---|
$FFFF - $FF00 | non utilisable par l’utilisateur |
$FEFF - $0000 | possibilité de mettre un périphérique dans cette zone |
Cet espace in/out sunt accesible avec les instruction IN et OUT
Les 1Mo de mémoire, généreusement proposé par le bus d’adresse de 20 bits, ne sont pas directement atteignable par le uC.
En effet, le uC fabrique une adresse sur 20 bits mais les registres internes ne font que 16 bits.
Il est donc possible de gères un espace mémoire de seulement 64 Ko.
L’idée est d’utiliser une adresse de base de segment sur 16 bits et un offset sur 16 bits.
En les additionnant de façon judicieuse il est ainsi possible d’accéder a un block de 64 Ko qui peux se situer n’importe ou dans les 1Mo de l’espace mémoire.
Voici comment sont additionné l’adresse de segment et l’offset :
[Adresse du segment (16 bits)] [0 0 0 0] + [Valeur de l’offset (16 bits)] ---------------------------------------- [ Adresse logique codée sur 20 bits ]
Bien sure, cette addition est faite automatiquement par le uC, vous n’avez pas à vous en préoccuper. Il faut simplement savoir comment ça se passe pour bien l’utiliser.
La valeur présente sur le bus d’adresse est l’adresse physique, L’adresse logique est le couple segment-offset.
Rappelons qu’il y a 4 types de segments (Programme, pile, donée0, donée1). Le début de chaque segment est spécifié dans ces registres PS, SS, DS0 et DS1. L’OS de la G100 initialise lui même ce système de segmentation grâce à ces registres lors de la lecture d’un fichier.
Il ne vaut mieux pas y toucher sauf si vous savez ce que vous faites. (Par contre vous pouvez toucher aux offsets)
Segment de programme (pointé par le registre PS):
Il contiens le code binaire, constantes, tables de constantes…
Segment de pile (pointé par le registre SS) :
il est utilisé pour sauvegarder les registres courant lors d’un saut a un sous programme ainsi que l’adresse de retours pour les restituer lors d’un RET ou un RETI. Il est aussi utilisé par un grand nombre de compilateurs pour passer des paramètres de fonctions ou pour stocker les variables locales.
Segment de donnée0 (pointé par le registre DS0) :
Il permet de stocker des données. Lors de l’exécution d’une instruction de groupe A il est utilisé comme un espace de source de donnée, dans ce cas le contenu du registre IX deviens l’offset de ce segment.
Segment de donnée 1 (pointé par DS1) :
Lors d’une instruction du groupe B il est utilisé comme espace de destination de donnée, dans ce cas le registre IY deviens l’offset de ce segment. Lors de l’exécution d’une instruction du groupe A il peux servir pour stocker les données
Le tableau suivant représente les couples segments offset :
offset | registre de segment | commentaire |
---|---|---|
PFP | PS | utilisé par le microprogramme pour chercher les instructions dans la file |
SP | SS | utilisé pour aller chercher une donnée dans la pile |
IX | DS0 | utilisé pour chercher une donnée 0 |
IY | DS1 | utilisé pour chercher une donnée 1 |
L’adresse effective est calculée par l’Unité d’EXécution (EXU).
Dans le cas le plus général elle est déterminée par le polynôme suivant :
Base + (Index * Scale) + Déplacement
Avec :
Base = registre de 16 bits Index = registre de 16 bits Scale = 1, 2, 3 ou 4 Déplacement = valeur de 8 ou 16 bits
La présence de tous les éléments n’est pas obligatoire, par conséquent l’EXU peux calculer une adresse effective suivant plusieurs méthodes d’adressage.
Cette méthode d’adressage est utilisée pour manipuler plusieurs tables de char, int, long.
MOV AW , WORD PTR [BW + 2*IX +4] MOV AL , BYTE PTR [BW]
Si ce n’est déjà fait, il est temps de prendre connaissance des instructions asm de base comme les sauts conditionnels et les transfert de données (cf le tableau et le fichier a télécharger du 1er chap).
Adressage direct :
Cet adressage est utilisé pour les branchements lointains. Les 4 octets fournis par l’instruction permettent au uC d’initialiser les registres de segment et d’offset PS et PC qui pointent sur la prochaine instruction qui doit être effectué.
CALL far_proc BR far_label
Adressage relatif :
Cet adressage est utilise pour les sauts un peu moins grand. Ici les 2 octets fourni par l’instruction permet de calculer le déplacement par apport à l’adresse de base du segment de code.
CALL near_proc BR near_label BR short_label
Adressage indirect :
Dans ce cas l’adresse d’arrivée est indiquée par un registre de 16 bits. La valeur de ce registre est directement chargée dans le PC.
CALL AW BR IX
Adressage mémoire :
Le saut est calculé grâce à une adresse effective, il est possible d’adresser en dehors du segment de donnée actuel.
CALL WORD_VAR [BW] CALL WORD_VAR [BW+IX] BR WORD_VAR [BR+2] BR WORD_VAR [BP+IY]
Dans le .pdf concernant les instructions asm les modes d’adressages possibles pour une instruction sont indiqués par les codes suivants :
code d’adressage | registres utilisable ou valeur utilisable |
---|---|
reg, reg’ | AW, BW, CW, DW, SP, BP, IX, IY, AL, AH, BL, BH, CL, CH, DL, DH |
reg8, reg8’ | AL, AH, BL, BH, CL, CH, DL, DH |
reg16, reg16’ | AW, BW, CW, DW, SP, BP, IX, IY |
sreg | PS, SS, DS0, DS1 |
acc | AW, AL |
imm8 | de $0 à $FF |
imm16 | de $0 à $FFFF |
imm | de $0 à $FFFF |
pop_value | de $0 à $FFFF |
Dans le .pdf concernant les instructions asm la taille de la donnée a transférer est indiqué par les codes suivant :
code de taille de donnée | taille de donnée |
---|---|
dmem | 8/16-bit data |
mem | 8/16-bit data |
mem8 | 8-bit data |
mem16 | 16-bit data |
La forme général d’un transfert de donnée se pressante de fa forme suivante :
InstructionASM Destination , Source
Il faut faire attention a ce que l’instruction de transfert de donnée manipule une donnée de la bonne taille et avec les bons registres, pour ça referez vous au fichier .pdf et aux tableaux ci dessus. La taille de la donnée est déterminée par le registre de transfert.
Adressage immediat :
imm16 : MOV AW, 216 ;216 -> AW imm8 : SHL AL, 5 ;5 -> AL IN acc, imm8 ;imm8 -> acc OUT imm8, acc pop_value : RET 16
Adressage direct :
MOV byte_var, 216 ;Valeur pointé par [216] -> byte_var
Adressage indirect :
reg16 : MOV AW, IX ;Valeur du registre IX -> AW IN acc, DW INM dst_block, DW OUT DW, acc ;Valeur de l'accumulateur -> DW OUTM DW, src_block reg8 : ADD AL, CH ;Valeur du registre CH -> AL
Adressage memoire :
MOV word_var [BW+2], AW ;Valeur de AW -> memoire pointé par [BW+2] SUB AW, [BP+6] MOV word_var [IY+2], 0 SUB AW, [IX+6] ;Valeur pointé par [IX+6] -> AW MOV word_var [BW+6] [IY+2],0 SUB AW, [BP+6+IX]
Le uC utilise un bus de données de 16bit il peux donc transférer des données de deux octets dans l’espace mémoire.
Les mémoires sont divisés en deux blocks de 512 Ko mis en parallèle afin de constituer une source de stockage d’une largeur de donnée de 16bits.
Lorsque le bit de poids faible (A0) est à 0 l’accès a la m mémoire se fait eu un cycle de bus, si non il faut deux cycles de bus.
Dans le premier cycle de bus, UBEB = 0 et A0 = 1 donc seul l’octet de poids fort est accessible en écriture ou en lecture.
Lorsque l’octet de poids fort à été traité le second cycle de bus consiste a faire les opérations suivantes pour traiter l’octet de poids faible : UBEB = 1, A0 = 0.
Le system de segmentation n’est pas utilisé lors du transfert d’une donnée en mémoire avec une instruction IN ou OUT.
Dans ce cas seul les 16 bits de poids faible du bus d’adresse (A0-A15) sont pris en compte, les bits A16-A19 sont quand a eux à 0.
Les données transférées peuvent être de 8bits ou de 16bits par conséquent il est possible de connecter au uC des périphériques gérant des données de 8 ou 16 bits.
L’accès a la zone d’entrée/sortie est plus rapide que lorsque l’on fait appel au system de segmentation, en effet il faut seulement 1 ou 2 cycles de bus suivant qu’on gère 8 ou 16 bits.
Les signaux du bus d’adresse (A19-A0), du bus de contrôle (BS3-BS0) et UBEB sont synchronisé au front montant de l’horloge.
La donnée (DI15-DI0) et le signale READYB sont échantillonné au prochain front montant de l’horloge.
Si a ce moment READYB = 0 alors un cycle d’attente sur l’horloge (TW) est rajouté et la donnée est re-échantillonné au front suivant, pendant ce temps le bus d’adresse est maintenu. Il est ainsi possible de connecté des mémoires plus lentes que le uC, mais attention il est possible de bénéficier que de 3 TW.
Les signaux du bus d’adresse (A19-A0), du bus de contrôle (BS3-BS0) , UBEB et le bus de donnée (D015-DO0) sont synchronisé au front montant de l’horloge.
Au front montant suivant de l’horloge le signal READYB est échantillonné. Si READYB = 1, alors un cycle TW est rajouté car la donnée est invalide parce que la mémoire est trop lente.
Il y a deux possibilités pour accéder a un sous programme :
Une interruption est générée lorsque :
Lorsque un de ces événements se produit le microprogramme saute a la routine y correspondant (gestion du clavier, réception d’une donnée série…) automatiquement. Une fois cette routinne d’IT terminée le microprogramme reviens exécuter le code qu’il executait avant le saut.
Une IT se comporte comme l’appelle d’un sous programma avec CALL. C’est donc totalement transparent pour le programmeur et les évenements interruptifs peuvent étre traité de façon automatique.
Pour utiliser ce principe il faut toute fois configurer les IT et coder les routines d’IT (qui ne seront jamais appelé par un CALL).
A une IT correspond un vecteur d’IT. Ce vecteur est placé à une adresse déterminé par le constructeur du uC. Le contenu de ce vecteur est quand a lui initialisé par l’utilisateur avec l’adresse sur 4 octets du sous programme “visé” par l’interruption.
Le NEC a donc une table de vecteurs d’IT qui correspond a l’ensemble de toutes les sources d’IT possible avec ce uC :
Les vecteurs 6 a 31 sont réservé par le NEC, donc non utilisable par l’utilisateur
Les 4 octets présent dans le vecteur permettent d’initialiser le compteur programme (CP) st el segment de code (PS) pour permettre au microprogramme de sauter a la bonne adresse.
Lors d’une IT le uC effectue les mêmes opérations que pour une instruction CALL :
Voici en détail les opérations :
TA <- vector lower word data (offset value) TC <- vector higher word data (program segment value) SP <- SP–2, (SP+1, SP) PSW IE <- 0, BRK 0, MD 1 SP <- SP–2, (SP+1, SP) PS PS <- TC SP <- SP–2, (SP+1, SP) PC PC <- TA
Chaque IT ont un niveau de priorité. Si plusieurs IT interviennent en même temps l’IT traité en 1er est celle qui a le niveau le plus élevé.
D’une règle générale l’ordre des IT sont :