


|
Coeurs FORTH 16 et 32 bits
Version 2.0 du 2 Avril 2006
Les particularités
du coeur 16 bits sont de couleur rouge
Les particularités
du coeur 32 bits sont de couleur verte
Ecrit par jpb.forth
Table des registres
Format des registres
Table des instructions
Format des instructions
Instructions supplémentaires au F21
Initialisation
Interruptions
Code des instructions FORTH de base (coeur 16 bits)
Périphériques internes
Introduction
Le processeur FORTH présenté ici est basé
sur le jeu d'instructions du F21 réalisé par la
société Ultra Technology (5 bits) avec un bus de données
16 bits et un bus d'adresse 21 bits extensible à 32 (le
bit A0 est toujours nul). Les piles de données
et de retour sont intégrées au format 16 32 bits.
Les accès à la mémoire peuvent s'effectuer
en mode 16 bits sur les adresses paires uniquement (bit A0 ignoré)
ou en mode octet (8 bits) sachant que les bits 0 à 7 du
bus des données(respectivement 8 à 15) sont sélectionnés
lorsque le bit A0 est à 1 (respectivement à 0).
Le mode d'accès est défini par l'état d'un
bit de contrôle spécifique (bit B) et est initialisé
à 16 bits. Lors d'accès à
la mémoire externe, seuls les 16 bits de poids faibles
de la pile de données sont tranférés. Les
16 bits de poids forts sont forcés à 0 en lecture,
une instruction spécifique permet d'étendre le signe
sur 32 bits.
Une zone de 65536 registres d'extensions maximum donne un
accès indirect aux registres internes du processeur e
aux périphériques intégrés afin d'optimiser
les échanges avec ceux-ci.
Tous les registres sont définis
sur 16 bits sauf précision:
Registres des données
|
Registres d'extension
|
Registres des adresses
|
|
|
|
|
|
|
T (16
32 bits)
|
S (16
32 bits)
|
Pile des données
(254 éléments)
...
|
|
|
R (16 32
bits)
|
Pile de retour
(255 éléments)
...
|
|
|
Pointeurs des piles
Adresse de T PNTT
|
Adresse de R PNTR
|
Contrôle/Etat CE
CCCCCCCCCCCCCCCC
|
C
|
I
|
M
|
B
|
S
|
...
|
EMU |
MT |
Interruption
Sauvegarde A
SA (16 32
bits)
|
Sauvegarde Page A SPA
|
Sauvegarde Page R SPR
|
Sauvegarde Contrôle/Etat SCE
|
Interfaces intégrés
TIMER
|
UART_BAUD
|
UART_CTRL
|
UART_DATA
|
Futurs interfaces
...
|
Image pile des données
(16 32
bits)
Image pile de retour
(16 32
bits)
|
|
Numéros des registres d'extension:
Numéro |
Registre |
0 |
PA espace libre |
1 |
PR espace libre |
2 |
PNTT
(512 à 767) |
3 |
PNTR
(768 à 1023) |
4 |
CE |
5 |
SA
(16 32
bits) |
6 |
SPA espace libre |
7 |
SPR espace libre |
8 |
SCE |
9
à 255 |
espace
libre |
256 |
TIMER
|
257 |
UART_BAUD
|
258 |
UART_CTRL
|
259 |
UART_DATA
|
260
à 511 |
espace
libre |
512
à 767 |
Pile des données (16 32 bits)
|
768
à 1023 |
Pile de retour (16 32 bits)
|
1024
à 65535 |
espace libre
|
Le processeur est optimisé pour un bus de données
de 16 bits et un bus d'adresse de 21 extensible à 32 bits.
Le bit de poids faible du bus d'adresse (bit 0) permet au logiciel
de différencier les octets pairs (bit 0 = 0) des octets
impairs (bit 1 = 1) ce qui implique que cette information soi
toujours présente dans les registres d'adresse. Ce bi
est ignoré par les instruction lors d'accès à
la mémoire qui demeure toujours sur 16 bits (le signal
A0 ne sort pas du processeur). Les post incrémentations
sont réalisées sur le bit 1 ce qui correspond à
une addition de 2 au registre. Les instructions C@ et C! son
émulées à partir des instructions du processeur
(voir le code des instructions FORTH de
base).
Le compteur de programme ou PC ne tient pas compte du bi
0. Les instructions sont toujours alignées sur les octets
pairs qui constituent les bits 8 à 15 de ces dernières.
Le PC est incrémenté de 2 unités à
chaque nouvelle ligne de code (1 unité pour le bit 1).
Les instructions de sauts relatifs ont un déplacement toujours
multiple de 2.
Les registres d'extensions, tous de largeur 16 bits sauf A et les piles de données et de retour
qui sont sur 32 bits, sont placés dans un espace
mémoire spécifique du processeur pouvant s'étendre
jusqu'à 65536 registres. Dans ce cas, le bit 0 est pris
en compte car il n'y a pas d'accès possible à ces
registres sous forme d'octet. Les bits 16
à 31 sont la copies du bit 15 (signe) dans le cas des registres
16 bits. Si leur contenu n'est que de 8 bits (octet de
l'UART par exemple), ils sont placés sur les 8 bits de
poids faibles du mot (bit 0 à 7) et les 8
24 bits de poids forts auront la
valeur du bit 7 pour facilité le test du bit de signe.
Voici la représentation des formats des différents
registres vis-à-vis des bus de données et d'adresses:
Bus de données
D15
|
D14
|
D13
|
D12
|
D11
|
D10
|
D9
|
D8
|
D7
|
D6
|
D5
|
D4
|
D3
|
D2
|
D1
|
D0
|
Registres de données (T, S et pile des données)
D31
|
D30
|
D29
|
D28
|
D27
|
D26
|
D25
|
D24
|
D23
|
D22
|
D21
|
D20
|
D19
|
D18
|
D17
|
D16
|
D15
|
D14
|
D13
|
D12
|
D11
|
D10
|
D9
|
D8
|
D7
|
D6
|
D5
|
D4
|
D3
|
D2
|
D1
|
D0
|
Registre Contrôle/Etat
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
C
|
I
|
M
|
B
|
S
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
EMU
|
MT
|
C correspond à la retenue (Carry)
I correspond à l'état de l'interruption (1 pour
interruption en cours)
M correspond au masque d'interruption (1 pour interruption masquée)
B correspond au mode d'accès (1 pour octet et 0 pour mo
de 16 bits)
S correspond à la disposition mémoire vive/mémoire
morte (1 pour mémoire vive en 0x00000000)
MT indique si le code 19 est mulu lorsqu'il vaut 1 ou addc lorsqu'il
vaut 0
EMU indique que le coeur est en émulation sous UNIX lorsqu'il
vaut 1
Registres d'adresses (A, R et pile de retour)
A31
|
A30
|
A29
|
A28
|
A27
|
A26
|
A25
|
A24
|
A23
|
A22
|
A21
|
A20
|
A19
|
A18
|
A17
|
A16
|
A15
|
A14
|
A13
|
A12
|
A11
|
A10
|
A9
|
A8
|
A7
|
A6
|
A5
|
A4
|
A3
|
A2
|
A1
|
A0
|
Les bits A0 à A15 de
la pile de retour sont aussi A16 à A31 pour les poids forts
du PC en appel et retour de sous programme
(utilisation de la pile sur 2 niveaux par les instructions call,
calla et ret)
L'état du bit A0 est ignoré lorsque le processeur
est en mode d'accès sur 16 bits (B = 0)
Registres de pages (PA e
PR)
A31
|
A30
|
A29
|
A28
|
A27
|
A26
|
A25
|
A24
|
A23
|
A22
|
A21
|
A20
|
A19
|
A18
|
A17
|
A16
|
A21 à A31 sont présents
dans l'extension 32 bits
Compteur de programme PC
A31
|
A30
|
A29
|
A28
|
A27
|
A26
|
A25
|
A24
|
A23
|
A22
|
A21
|
A20
|
A19
|
A18
|
A17
|
A16
|
A15
|
A14
|
A13
|
A12
|
A11
|
A10
|
A9
|
A8
|
A7
|
A6
|
A5
|
A4
|
A3
|
A2
|
A1
|
A0
|
A0 est toujours à 0
A21 à A31 sont présents dans l'extension 32 bits
Code |
Nom |
Description |
FORTH |
Retenue(C) |
00000 |
jmp |
Branchement relatif inconditionnel |
ELSE |
inchangée |
00001 |
jz |
Branchement relatif si T est égal
à 0 |
DUP IF |
inchangée |
00010 |
call |
Empilement de PC dans R (2
niveaux) et branchement relatif |
: |
inchangée |
00011 |
jnc |
Branchement relatif si retenue est égale
à 0 |
CARRY? IF |
inchangée |
00100 |
fcw |
Lecture du registre d'extension pointé
par R (16 bits de poids faibles)
dans T, le pointeur est ensuite dépilé |
indéfini |
inchangée |
00101 |
stcw |
Ecriture de T dans le registre d'extension
pointé par R (16 bits de poids faibles),
le pointeur est ensuite dépilé |
indéfini |
inchangée |
00110 |
ret |
Dépilement de PC depuis R (2
niveaux) |
; |
inchangée |
00111 |
iret |
Dépilement de PC depuis R (2
niveaux) et récupération des registres sauvegardés
par l'interruption |
indéfini |
récupérée |
01000 |
ftchrp |
SI B = 1
ALORS lecture de l'octet pointé par [Page
R, R] [R] et incrémentation
par 1 de [Page R, R] [R]
SINON lecture du mot de 16 bits pointé par [Page
R, R] [R] e
incrémentation par 2 de [Page
R, R] [R]
Les 16 bits de poids forts de T sont forcés à 0 |
BIT@
IF
R@ C@
R> 1+ >R
ELSE
R@ @
R> 2+ >R
THEN |
inchangée |
01001 |
ftchap |
SI B = 1
ALORS lecture de l'octet pointé par [Page
A, A] [A] et incrémentation
par 1 de [Page A, A] [A]
SINON lecture du mot de 16 bits pointé par [Page
A, A] [A] et incrémentation
par 2 de [Page A, A] [A]
Les 16 bits de poids forts de T sont forcés à 0 |
BIT@
IF
A @ C@
1 A +!
ELSE
A @ @
2 A +!
THEN |
inchangée |
01010 |
lit |
Lecture du mot pointé par PC et incrémentation
par 2 de PC. Seuls les 16 bits de poids
faibles de T sont chargés, les 16 bits de poids forts
sont forcés à 0 |
LITERAL |
mise à zéro |
01011 |
ftcha |
SI B = 1
ALORS lecture de l'octet pointé par [Page
A, A] [A]
SINON lecture du mot de 16 bits pointé par [Page
A, A] [A]
Les 16 bits de poids forts de T sont forcés à 0 |
BIT@
IF
A @ C@
ELSE
A @ @
THEN |
inchangée |
01100 |
strp |
SI B = 1
ALORS écriture de l'octet à l'adresse pointée
par [Page R, R] [R]
et incrémentation par 1 de [Page
R, R] [R]
SINON écriture du mot de 16 bits à l'adresse pointée
par [Page R, R] [R]
et incrémentation par 2 de [Page
R, R] [R]
Les 16 bits de poids forts de T sont forcés à 0 |
BIT@
IF
R@ C!
R> 1+ >R
ELSE
R@ !
R> 2+ >R
THEN |
inchangée |
01101 |
stap |
SI B = 1
ALORS écriture de l'octet à l'adresse pointée
par [Page A, A] [A]
et incrémentation par 1 de [Page
A, A] [A]
SINON écriture du mot de 16 bits à l'adresse pointée
par [Page A, A] [A]
et incrémentation par 2 de [Page
A, A] [A]
Les 16 bits de poids forts de T sont forcés à 0 |
BIT@
IF
A @ C!
1 A +!
ELSE
A @ !
2 A +!
THEN |
inchangée |
01110 |
swi
swab |
Interruption logicielle
Permutation des 16 bits de poids
forts avec les 16 bits de poids fables de T |
indéfini
SWAB |
inchangée |
01111 |
sta |
SI B = 1
ALORS écriture de l'octet à l'adresse pointée
par [Page A, A]
SINON écriture du mot de 16 bits à l'adresse pointée
par [Page A, A] |
BIT@
IF
A @ C!
ELSE
A @ !
THEN |
inchangée |
10000 |
com |
complément à 1 de T |
-1 XOR |
inchangée |
10001 |
rolc |
Rotation à gauche de T avec C |
CARRY?
IF
2* 1 OR
ELSE
2*
THEN |
bit 15 31 de T |
10010 |
rorc |
Rotation à droite de T avec C |
CARRY?
IF
2/ 32768 2147483648
OR
ELSE
2/ 32767 2147483647
AND
THEN |
bit 0 de T |
10011
MT=0 |
addc |
Addition de S à T si le bit 0 de T
est à 1 |
DUP 1 AND
IF
OVER +
THEN |
calculée |
10011
MT=1 |
mulu |
Multiplication non signée de T par
R (16x16 32x32
bits) dans R;T (32 64
bits avec poids forts dans R) |
R> U* >R |
inchangée |
10100 |
xorr |
Ou exclusif de S et de T dans T |
XOR |
inchangée |
10101 |
andd |
Et logique de S et de T dans T |
AND |
inchangée |
10110 |
...
sxt |
Réserve pour
application future
Extension du bit de signe (15) sur
les bits 16 à 31 |
...
DUP 32768 AND
IF
-32768 OR
ELSE
32767 AND
THEN |
...
inchangée |
10111 |
addd |
Addition de S et de T dans T |
+ |
calculée |
11000 |
pop |
Dépilement de R dans T |
R> |
inchangée |
11001 |
popa |
Empilement de A dans T |
A @ |
inchangée |
11010 |
dup |
Empilement de T dans T |
DUP |
inchangée |
11011 |
over |
Empilement de S dans T |
OVER |
inchangée |
11100 |
push |
Empilement de T dans R |
>R |
inchangée |
11101 |
pusha |
Dépilement de T dans A |
A ! |
inchangée |
11110 |
nop |
Délai d'un cycle machine |
NOP |
inchangée |
11111 |
drop |
Dépilement de T |
DROP |
inchangée |
-
|
calla |
Empilement de PC dans R (2
niveaux) et saut à une adresse 32 bits en absolu |
: |
inchangée |
BIT@ représente une pseudo instruction FORTH
qui effectue la lecture de l'état du bit B dans le registre
CE
A représente une pseudo variable FORTH destinée
à contenir une adresse
Les instructions sont définies dans une ligne de
code constituée de 16 bits. Il y a 3 types de lignes de
code:
Ligne avec 1 à 3 instructions:
Instruction 1 (5 bits) |
Instruction 2 (5 bits) |
Instruction 3 (5 bits)
|
0
|
Dans le cas des instructions ret, iret et swi, si elles
se trouvent en instruction 1 (respectivement instruction 2) les
instructions 2 et 3 (respectivement 3) seront ignorées.
L'argument de l'instruction lit est placé dans le
mot suivant.
Ligne avec 1 instruction de branchement relatif (jmp,
jz, call et jnc):
Instruction (5 bits)
|
Déplacement signé (10 bits)
|
0
|
Le bit de poids forts du déplacement ou bit de signe
(10) est étendu au bits 15 à 11 et à la page
avant d'être ajoutés au registre PC (uniquement lorsque
la condition est réalisée pour les instructions
jz et jnc). Le déplacement est multiple de 2 et s'étend
de -2048 à +2046 en octets (-1024 à +1024 en mots
de 16 bits). Un déplacement de 0 correspond à la
ligne suivante de l'instruction de saut.
Ligne avec 1 instruction pour appel de sous-programme
en adressage absolu:
Poids faibles des adresses (A15 à A1)
|
1
|
Poids forts des adresses ou Page (A31 à
A16)
|
Seuls les 5 bits de poids faibles (4 à 0)
du second mot sont utilisés en mode d'adressage 21 bits.
Instructions supplémentaires au F21
iret
Cette instruction correspond au retour du programme d'interruption.
Le PC est dépilé depuis la pile de retour (comme
dans le cas de l'instruction "ret") et les registres
Page A, A, Page
R et CE sont remplacés par leurs équivalents
sauvegardés.
fcw
Cette instruction permet d'empiler le contenu d'un registre
d'extension dont le numéro (ou adresse) est contenu dans
R (16 bits de poids faibles). Ce
numéro est ensuite retiré de la pile de retour.
stcw
Cette instruction permet d'initialiser le contenu d'un registre
d'extension avec T et dont le numéro (ou adresse) est contenu
dans R (16 bits de poids faibles).
Ce numéro est ensuite retiré de la pile de retour.
calla
Cette instruction permet de faire un appel de sous-programme
en adressage absolu. PC est sauvegardés dans la pile de
retour sur 2 niveaux et remplacé
par les 2 valeurs contenues dans le code.
ftchrp, ftchap, ftcha, strp, stap et sta
Ces instructions possèdent un mode de fonctionnemen
supplémentaire. Lorsque le bit B (pour "Byte")
est à 0, les données sont transférées
entre le bus externe et le registre T sur 16 bits (poids
faibles) indépendamment de l'état du bi
0 des registres d'adresses. Lorsque le bit B est à 1, les
données sont transférées sur 8 bits (octets)
et selon la méthode suivante:
En lecture, si le bit 0 du registre d'adresse est à
0, les bits 15 à 8 du bus des données sont transférés
dans les bits 7 à 0 de T. Si le bit 0 du registre d'adresse
est à 1, les bits 7 à 0 du bus des données
sont transférés dans les bits 7 à 0 de T.
Les bits 15 à 8 du de T prennent la valeur du bit 7 afin
de propager le bit de signe de l'octet lu (-256 à +255). Les bits 31 à 16 de T prennent la valeur
du bit 15 pour les registres 16 bits.
En écriture, si le bit 0 du registre d'adresse es
à 0, les bits 7 à 0 de T sont transférés
dans les bits 15 à 8 du bus des données. Si le bi
0 du registre d'adresse est à 1, les bits 7 à 0
de T sont transférés dans les bits 7 à 0
du bus des données.
swi
Cette instruction permet de déclencher
une interruption logicielle. Le PC est empilé dans la pile
de retour (comme pour un "call") et les registres Page
A, A, Page R et CE sont copiés dans leurs équivalents
sauvegardés, le masque M est activé (mis à
1) et le bit B est mis à 0 (accès en mode 16 bits).
swab
Cette instruction permet de permuter
les 16 bits de poids forts de T avec les 16 bits de poids faibles.
rolc et rorc
Ces deux instructions remplacent "shl" et "shr".
Elles permettent d'étendre plus efficacement les opérations
de décalage sur des nombres supérieurs à
16 32 bits
(32, 48, ...). "shl" pourra
être émulée par la séquence "dup
addd" équivalent à l'instruction FORTH "2*"
et "shr" par "dup rolc drop rorc" équivalen
à "2/".
mulu
Cette instruction remplace addc lorsque MT=1. MT est le
bit 0 du registre d'extension CE et à lecture seule, c'es
une indication dépendante de l'implémentation du
coeur. L'instruction mulu fait une multiplication non signée
de T par R et place les 16 32 bits de poids forts du résulta
dans R et les 16 32
bits de poids faible dans T.
sxt
Cette instruction étend le
bit de signe (bit 15) de T sur ses 16 bits de poids forts.
Lorsque le signal RESET est appliqué au processeur,
il se trouve en mode initialisation qui agit sur les différents
registres de la manière suivante:
- PNTT pointe la base de la pile des données (512),
- PNTR pointe la base de la pile de retour (768),
- PA est mis à zéro,
- PR est mis à zéro,
- A est mis à zéro,
- C est mis à zéro,
- M est mis à 1 pour masquer les interruption,
- B est mis à zéro pour l'accès en mode 16
bits,
- PC est mis à zéro,
- S est mis à zéro pour placer la mémoire
morte en 0x00000000 (mémoire vive en 0xFFF00000),
- MT dépend de l'architecture du coeur, 1 pour l'instruction
mulu et 0 pour l'instruction addc (code 19),
- EMU est mis à 1 si le coeur est émulé sous
UNIX.
A la fin de l'activation du signal RESET, le processeur
démarre à l'adresse 0x00000000. Le programmeur dispose
alors de 8 lignes de code (vecteur d'interruption placé
à l'adresse 0x00000010) permettant une petite initialisation
logicielle suivie du saut à l'adresse du programme principal.
Un signal de programmation marérielle externe (XMODEM)
permet d'activer (lorsque XMODEM = 0) l'accès à
la mémoire morte de 0x00000000 à 0x000001FF (512
octets ou 256 mots de 16 bits) afin que le processeur démarre
sur une séquence de téléchargement du logiciel
à partir de l'UART sous protocole XMODEM. Cette séquence
effectue un saut à l'adresse 0xFFF00000 à la fin
du transfert (le logiciel a donc été téléchargé
à cette même adresse). Le processeur détecte
une lecture à l'adresse 0xFFFXXXXX et inhibe alors l'accès
à la mémoire morte pour laisser apparaître
la mémoire FLASH.
L'émetteur est le système hôte (PC,
MAC ou autre) et le récepteur est le processeur. La vitesse
de l'UART est initialisée à 9600 Bauds.
Voici la liste des vecteurs d'interruption:
Vecteur
(adresse) |
Interruption |
0x00000000 |
RESET (initialisation) |
0x00000010 |
Fonctions périphériques |
0x00000020 |
Instruction
"swi"
Réserve |
0x00000030 |
Code opératoire
incorrect |
0x00000040 |
Débordemen
de la pile des données |
0x00000050 |
Débordemen
de la pile de retour |
La principale interruption du processeur est celle qui es
déclenchée par le signal RESET. Celui-ci provoque
l'initialisation décrite dans le paragraphe
correspondant.
Le processeur possède une entrée d'interruption
pour les fonctions périphériques internes et externes.
L'entrée en interruption est réalisée
à la fin de l'exécution de la ligne de code en cours.
Le processeur empile le PC dans la pile de retour et effectue
la sauvegarde des registres A, PA, PR e
CE en 1 seul cycle puis positionne le masque M d'interruption
à 1 (les registres de sauvegarde sont respectivement SA, SPA, SPR et SCE). Le bit B est initialisé
à 0 lors de l'entrée en interruption pour permettre
le fonctionnement en accès 16 bits aux données correspondan
au mode par défaut du processeur. Le registre PC est chargé
avec l'adresse 0x00000010 qui pointe le programme d'interruption.
Si le programmeur décide d'autoriser d'autres interruptions
à ce niveau, il doit sauvegarder les registres précédemmen
cités avant de démasquer les interruptions. Une
fois le programme terminé, il devra remasquer les interruptions
et récupérer les registres précédants
avant de lancer l'instruction iret.
Ceci permet de réduire au minimum le temps de réponse
du processeur à une interruption.
L'instruction "swi" déclenche
une interruption logicielle dont le vecteur est l'adresse 0x00000020.
Cette interruption est exécutée quelque soit l'éta
du masque M.
Une interruption est automatiquement déclenchée
sur détection d'un code opératoire erroné.
Le vecteur de cette interruption est 0x00000030.
Les piles des données et de retour ont une taille
limités à 256 mots de 16
32 bits chacune. Leur initialisation
positionne leur pointeur à 0x0200 (données) et 0x0300
(retour). Chaque insertion provoque une décrémentation
du pointeur. Chaque extraction provoque une incrémentation
du compteur. Une interruption est générée
lorsque les 8 bits de poids faibles des compteurs passent de 0xFF
à 0x00 en cas d'insertion ou de 0x00 à 0x01 en cas
d'extraction. Les vecteurs sont 0x00000040 pour la pile des données
et 0x00000050 pour la pile de retour.
Code des instructions FORTH de base (coeur 16 bits)
Voici l'implémentation des
instructions FORTH de base avec le code machine du coeur en 16
bits:
( Evaluation des acces aux registres d'extension.
Version 1.00 du 11 Novembre 2001.
Ecrit par jpb.forth .
)
TELECHARGEMENT
RAZ_ASSEMBLEUR
ASSEMBLEUR
; Evaluation des acces aux registres d'extension.
; Version 1.00 du 11 Novembre 2001
; Ecrit par jpb.forth
;
; Declaration des registres d'extension
; =====================================
;
; Registres de pages
;
PA EQU 0 ; page pour registre A
PR EQU 1 ; page pour registre R
;
; Pointeurs des piles
;
PNTT EQU 2 ; pointeur pile des donnees
PNTR EQU 3 ; pointeur pile de retour
;
; Controle/Etat
;
CE EQU 4 ; controle/etat
;
; Masques des differents bits du registre CE
;
MSQC EQU %1000000000000000 ; retenue
MSQI EQU %0100000000000000 ; etat inter.
MSQM EQU %0010000000000000 ; masque inter.
MSQB EQU %0001000000000000 ; mode octet
MSQS EQU %0000100000000000 ; select. memoire
;
; Sauvegardes interruption
;
SA EQU 5 ; sauvegarde registre A
SPA EQU 6 ; sauvegarde page A
SPR EQU 7 ; sauvegarde page R
SCE EQU 8 ; sauvegarde controle/etat
;
; Interfaces integres
;
TIMER EQU 256 ; timer
UBAUD EQU 257 ; vitesse UART
UCTRL EQU 258 ; controle UART
UDATA EQU 259 ; donnees UART
;
; Images des piles
;
DSTACK EQU 512 ; pile des donnees
RSTACK EQU 768 ; pile de retour
;
ORG 0
;
RESET JMP TEST ; Initialisation
;
ORG 16
;
IRQ IRET ; Interruption materielle
;
ORG 32
;
SWI IRET ; Interruption logicielle
;
ORG 48
;
INSTERR IRET ; Instruction illegale
;
ORG 64
;
DSERR IRET ; Debordement pile des donnees
;
ORG 80
;
RSERR IRET ; Debordement pile de retour
;
ORG 128
;
; Instructions de base
; ====================
;
DUP DUP ; n --> n,n
RET
;
DROP DROP ; n --> -
RET
;
SWAP PUSH ; n1,n2 --> n2,n1
PUSHA ; equivalent a "2 ROLL"
POP
POPA
RET
;
OVER OVER ; n1,n2 --> n1,n2,n1
RET
;
ROT PUSH ; n1,n2,n3 --> n2,n3,n1
PUSH ; equivalent a "3 ROLL"
PUSHA
POP
POP
POPA
RET
;
PDIDUP JZ PDIDUP1 ; ?DUP n --> n,n ou 0
DUP
PDIDUP1 RET
;
SR PUSHA ; >R n --> -
POP
POP
POPA
PUSH
PUSH
PUSH
RET
;
RS POP ; R> - --> n
POP
POP
PUSHA
PUSH
PUSH
POPA
RET
;
RF POP ; R@ - --> n
POP
POP
DUP
PUSHA
PUSH
PUSH
PUSH
POPA
RET
;
PICK LIT #PNTT ; n1 --> n2
PUSH
FCW
ADDD
PUSH
FCW
RET
;
POKE LIT #PNTT ; n1,n2 --> -
PUSH
FCW
ADDD
PUSH
STCW
RET
;
ROLL DUP ; n --> -
PUSH
LIT #PNTT
PUSH
FCW
ADDD
PUSHA
POP
ROLLA LIT #-1
ADDD
JZ ROLLB
POPA
PUSH
FCW
POPA
DUP
PUSH
LIT #-1
ADDD
DUP
PUSHA
PUSH
FCW
STCW
POPA
PUSH
STCW
JMP ROLLA
ROLLB DROP
RET
;
DEPTH LIT #PNTT ; n
PUSH
FCW
COM
LIT #1
ADDD
LIT #DSTACK+256
ADDD
RET
;
; Multiplication non signee 8x8 --> 16 bits
;
M16 PUSH ; n1,n2 --> n1*n2
DUP
ADDD
DUP
ADDD
DUP
ADDD
DUP
ADDD
DUP
ADDD
DUP
ADDD
DUP
ADDD
DUP
ADDD
POP
LIT #255
ANDD
ADDC
RORC
ADDC
RORC
ADDC
RORC
ADDC
RORC
ADDC
RORC
ADDC
RORC
ADDC
RORC
ADDC
RORC
PUSH
DROP
POP
RET
;
; Multiplication non signee 16x16 --> 32 bits
;
M32 PUSH ; n1,n2 --> (n1*n2)l,(n1*n2)h
DUP
DUP
XORR
POP
LIT #-1
PUSHA ; A = -1
LIT #16 ; n1,0,n2,cnt=16
M321 PUSH
PUSH
OVER
RORC
DROP
JNC M322
POP
DUP
PUSH
ADDD
M322 RORC
PUSH
RORC
POP
POP
POP
POPA
ADDD
JZ M323
JMP M321
M323 DROP ; (n1*n2)l,(n1*n2)h,n2,0
DROP
RET
;
; Division non signee 32/16 --> 16 et 16 bits
; quotient et reste
;
D32 COM ; nl,nh,d --> r,q
LIT #1 ; r = mod(nh_nl,d)
DUP ; q = div(nh_nl,d)
PUSHA ; A = 1
ADDD
LIT #16 ; nl,nh,-d,cnt=16
D321 PUSH
PUSH
PUSH
DUP
ADDD
POP
ROLC
DUP
POP
DUP
PUSH
ADDD ; nl,nh,nh-d
JNC D324
PUSH ; si nh >= d
DROP
POPA
ADDD
POP
POP
JMP D325
D324 DROP ; si nh < d
POP
D325 POP
LIT #-1 ; nl',nh',-d,cnt,-1
ADDD
JZ D326
JMP D321
D326 DROP ; q,r,-d,0
DROP
CALL SWAP ; r,q pour compatibilite FORTH
RET
;
ORG 512
;
; Vecteurs pour simulation
; le commentaire donne l'etat attendu de la pile des donnees
;
TEST LIT #1 ; 1
CALL DUP ; 1,1
CALL DROP ; 1
CALL DUP ; 1,1
CALL OVER ; 1,1,1
ADDD ; 1,2
CALL DUP ; 1,2,2
LIT #3 ; 1,2,2,3
CALL PICK ; 1,2,2,1
ADDD ; 1,2,3
CALL SWAP ; 1,3,2
CALL ROT ; 3,2,1
CALL SR ; 3,2
CALL SWAP ; 2,3
CALL RF ; 2,3,1
CALL OVER ; 2,3,1,3
CALL ROLL ; 3,1,2
CALL ROT ; 1,2,3
CALL DUP ; 1,2,3,3
CALL RS ; 1,2,3,3,1
ADDD ; 1,2,3,4
LIT #0 ; 1,2,3,4,0
CALL PDIDUP ; 1,2,3,4,0
ADDD ; 1,2,3,4
CALL PDIDUP ; 1,2,3,4,4
LIT #5 ; 1,2,3,4,4,5
CALL PICK ; 1,2,3,4,4,1
ADDD ; 1,2,3,4,5
CALL OVER ; 1,2,3,4,5,4
CALL POKE ; 1,5,3,4
CALL DUP ; 1,5,3,4,4
CALL PICK ; 1,5,3,4,1
CALL DUP ; 1,5,3,4,1,1
ADDD ; 1,5,3,4,2
CALL OVER ; 1,5,3,4,2,4
CALL POKE ; 1,2,3,4
CALL DEPTH ; 1,2,3,4,4
CALL M16 ; 1,2,3,16
CALL M32 ; 1,2,48,0
LIT #2 ; 1,2,48,0,2
CALL D32 ; 1,2,0,24
CALL DUP ; 1,2,0,24,24
CALL M16 ; 1,2,0,576
CALL SWAP ; 1,2,576,0
LIT #37 ; 1,2,576,0,37
CALL D32 ; 1,2,21,15
CALL M16 ; 1,2,315
CALL DUP ; 1,2,315,315
CALL M32 ; 1,2,33689,1
LIT #5 ; 1,2,33689,1,5
CALL D32 ; 1,2,0,19245
CALL M16 ; 1,2,0
ADDD ; 1,2
CALLA M32 ; 2,0
ADDD ; 2
CALLA DROP ; -
;
END
SIMULATION
( FIN
)
Périphériques internes
TIMER
Le rôle du TIMER est de générer une
interruption régulière pour le noyau temps réel.
Il est composé d'un seul registre de 16 bits placé
dans la zone des registres d'extension du processeur (0x0100).
Lorsque sa valeur est nulle (valeur correspondant à l'initialisation),
la fonction du TIMER est inhibée. Une écriture de
1 dans le registre permet de générer une interruption
toutes les 1 ms en incrémentant la valeur lue.
L'interruption est effacée par la lecture de ce même
registre qui donne le nombre de tours effectués par le
compteur avant que l'interruption soit servie. Cette valeur, codée
sur 4 bits (D3..D0), est automatiquement remise à 0 après
lecture. Les 12 28
bits de poids forts sont toujours lus à 0.
UART
L'UART permet le transfert de données entre le processeur
et un ordinateur hôte. Cette interface est composée
de 3 registres d'extension:
UART_BAUD (0x0101) permettant de choisir la fréquence
de transmission multipliée par 16 à partir de la
fréquence du processeur divisée par 13,5 (1,852
MHz). Lorsque sa valeur est de 12 (valeur correspondant à
l'initialisation), la vitesse de transmission est de 9600 bauds
avec une erreur de 0,47%. La valeur est codée sur 4 bits
(D3..D0) permettant de choisir parmi 16 valeurs de 7200 à
115200 bauds :
Vitesse (bits/s) = Fréquence Processeur (Hz)
/ [13,5*16*(UART_BAUD+1)]
UART_CTRL (0x0102) qui en lecture donne accès aux
différents bits d'état de l'UART et, en écriture,
sert de masque d'interruption sachant que chacun des bits d'éta
peut en générer une (le masque est positioné
à l'initialisation):
D15
rxrdy
|
D14
txrdy
|
D13
parityerr
|
D12
framingerr
|
D11
overrun
|
D10
réserve
|
D9
réserve
|
D8
réserve
|
D7
réserve
|
D6 réserve
|
D5
réserve
|
D4
réserve
|
D3
réserve
|
D2
réserve
|
D1
réserve
|
D0
réserve
|
UART_DATA (0x0103) qui en lecture donne accès à
l'octet reçu (rxrdy est remis à zéro) e
en écriture permet d'envoyer un octet (txrdy est remis
à zéro). L'octet est placé sur les bits D0
à D7. Les bits D8 à D15
D31 sont la copie du bit D7 en lecture.
Le format de transmission est fixé à 8 bits
de données, parité impaire et 1 bit de stop.
|
 |
 |