115 lines
6.0 KiB
Markdown
115 lines
6.0 KiB
Markdown
# Assembleur
|
|
pour assembler un fichier:
|
|
- depuis ce dossier
|
|
`cargo run --release -p asm fichierentre [fichiersortie]`
|
|
- depuis le sous dossier asm
|
|
`cargo run --release fichierentre [fichiersortie]`
|
|
|
|
syntaxe supplémentaire supportée:
|
|
- `let rx label`
|
|
assigne l'adresse de label a rx
|
|
- `D valeur`
|
|
rentre la donné brute égale à la valeur (immédiate ou addresse de label)
|
|
(pour mettre des données dans le fichier et pas du code executable)
|
|
- `eint` Active les interruptions
|
|
- `dint` Desactive les interruptions
|
|
- `swi` Active l'interruption swi
|
|
- `reti` Retourne depuis le handler d'interruption
|
|
- `umull` multiplication non signée usuelle
|
|
- `umulh` multiplication non signée, moitié haute du résultat 64 bits
|
|
- `smull` et `sumlh` versions signée de la multiplication
|
|
- `div` division non signée
|
|
- `mod` modulo non signé
|
|
|
|
# Simulateur
|
|
## pour lancer la simulation:
|
|
- depuis ce dossier
|
|
`cargo run --release -p simu fichierentre`
|
|
- depuis le sous dossier simu
|
|
`cargo run --release fichierentre`
|
|
|
|
## Features
|
|
rajouter --features=[liste séparé par des virgules]
|
|
- div_mul: Support des instruction de multiplication / division
|
|
- rgba: Écran au format RGBA plutot que 0BGR (alpha ignoré mais stocké)
|
|
- rich_keyboard: rajoute trois champs de mmio pour le clavier. Voir MMIO
|
|
- debug: repl similaire a la version python du simulateur
|
|
- futex: accélère le programme. ne marche pas sur les macs. actif par default, utiliser --no-default-features pour le desactiver
|
|
|
|
### instruction spéciale:
|
|
halt (jump 0) met le programme en pause, mais on peut se reveiller par des interuptions
|
|
|
|
call 0 termine l'exécution du simulateur proprement
|
|
|
|
## mmio:
|
|
- 0x01000000 à 0x0112c000 : Écran en lecture/écriture. un pixel par 32bits, de gauche a droite puis de bas en haut.
|
|
Format de pixel en 0BGR, 4 bits par couleur.
|
|
Passage au format RGBA (alpha ignoré, mais stocké) avec la feature rgba
|
|
- 0x01200000 : Clavier (scancode) (lecture seule)
|
|
- 0x01200004 : Horloge (millisecondes écoulé depuis le début de la simulation, wrappe tout les 49 jours) (lecture seule)
|
|
- 0x01200008 : Boutons de la souris (OR des boutons préssés) Gauche = 1, Droit=2, Clic Molette = 3, Autres non testé (lecture seule)
|
|
- 0x0120000c : Position horizontale de la souris (en pixels, -1 si hors de l'écran) (lecture seule)
|
|
- 0x01200010 : Position verticale de la souris (en pixels, -1 si hors de l'écran) (lecture seule)
|
|
- 0x01201000 : Activation des Interupts de MMIO. Remis a zero par `dint`. Attention, Écrire ici sans activer les interruptions va bloquer les intéruptions et l'affichage (écriture seule)
|
|
|
|
|
|
Si la feature rich_keyboard est active, tout en lecture seule:
|
|
- 0x01200000 - 12 : Clavier : Representation ascii multichar de la touche pressé, modifié par Alt, Ctrl ... (eg ascii(a), ascii(A), ascii(^a)) l'unicode peut faire des val > 255
|
|
- 0x01200000 - 8 : Clavier Representation ascii multichar non modifié (eg ascii(a), ascii(\r)) l'unicode peut faire des val > 255
|
|
- 0x01200000 - 4: Clavier (press | repeat << 1) press: 1 si appuis, 0 si relache. repeat: 1 si l'appuis vient d'une répétition due a l'OS
|
|
- 0x01200000 : Clavier (scancode, comme précédement) (lecture seule)
|
|
|
|
## Interuptions:
|
|
Si les interruptions sont activées (avec eint), qu'il y a une raison de faire une interruption,
|
|
et qu'on n'est pas déjà dans une routine d'interruption de priorité >=,
|
|
alors le cpu effectue les actions suivantes:
|
|
|
|
Finis l'instruction en cours si c'est une interruption externe
|
|
si interruption a des arguments, les mets dans les registres par ordre croissant,
|
|
Mets PC a (priorité de l'intéruption)*4 (instruction n°priorité)
|
|
|
|
Cela veut dire que votre début de programme, si vous voulez utiliser les interruption, doit être une table de jump vers les handler correspondant
|
|
|
|
Pour sortir d'une interuption, utilisez `reti`
|
|
*Il FAUT sortir avec un reti*
|
|
|
|
*Les interuptions utilisent la stack, donc lorsque les interuptions sont activés, il est interdit de stocker des information au dessus du pointeur de stack.
|
|
de même, `reti` ne peut pas être appellé par une sous fonction appellée depuis l'interrupt handler*
|
|
|
|
Les intéruptions et leurs arguments, par priorité croissante:
|
|
### 0: Point d'entrée
|
|
C'est ici que le programme commence. Seul cas d'utilisation
|
|
(ce n'est pas vraiment une interruption, juste la première entrée dans la jump table)
|
|
### 1: MMIO
|
|
Doivent être activé par le MMIO a l'adresse 0x01201000, en y écrivant le OR des (1<<identifiant)
|
|
On toujours pour argument (r0) leur identifiant
|
|
Les mmio corespondant sont modifié avant d'entrer dans l'intéruption, et TOUT LES MMIO d'une interuption active sont bloqués tant qu'on n'est pas sorti
|
|
- 1 : Clavier
|
|
- 2 : Boutons de la souris
|
|
- 3 : Mouvements de la souris
|
|
- 4 : Écran (rien n'est modifié, attend la sortie de l'intéruption pour afficher une frame)
|
|
### 2: SWI
|
|
Pas d'argument
|
|
|
|
### 3: Division par zero
|
|
2 arguments: numéro de registre de sortie et valeur du dividende.
|
|
lors de l'appel a reti, attend que r0 n'ai pas été modifié et un retour dans r1.
|
|
la registre de destination prend la valeur retourné dans r1
|
|
### 4: Load/Store illégal
|
|
Un load store a été fait a une adresse non multiple de 4
|
|
3 aruments:
|
|
si c'est un load: 0, addresse, numéro de registre de retour
|
|
si c'est un store: 1, addresse, valeure a stocker
|
|
ne modifiez pas r0, et dans le cas des load, r2. (ou restaurez avant le reti)
|
|
Si c'est un load, le registre destination prendra la valeur de retour, attendue dans r1
|
|
### 5: Unsupported Opcode
|
|
Une division multiplication alors qu'elle ne sont pas activées
|
|
4 arguments:
|
|
indice de registre de retour, argument 1, argument 2, fonction
|
|
Même mode de retour que la division par zero
|
|
### 6: Instruction Illégale
|
|
Une instruction non légale, ou un load / store a une adresse non mappé.
|
|
1 argument: l'opcode de l'instruction associé
|
|
Il est fortement recommendé d'utiliser cette intéruption pour afficher du debug, puis de quitter le programme, mais il est possible
|
|
de continuer a l'instruction suivante à l'aide d'un `reti`
|