From b3e2b04df0614cf8c378369b8333e1cc249e301d Mon Sep 17 00:00:00 2001
From: Florent Gluck <florent.gluck@hesge.ch>
Date: Mon, 14 Oct 2024 23:12:44 +0200
Subject: [PATCH] Updated lab-virtual_game_machine.md: added sprite engine
 description

---
 .../lab-virtual_game_machine.md               | 96 +++++++++++++++++--
 1 file changed, 90 insertions(+), 6 deletions(-)

diff --git a/labs/lab-virtual_game_machine/lab-virtual_game_machine.md b/labs/lab-virtual_game_machine/lab-virtual_game_machine.md
index f0bcdbf..a388fc4 100644
--- a/labs/lab-virtual_game_machine/lab-virtual_game_machine.md
+++ b/labs/lab-virtual_game_machine/lab-virtual_game_machine.md
@@ -184,7 +184,95 @@ Le périphérique se programme en PMIO.
 
 Le code pour programmer l'écriture d'un secteur vous est donné dans le fichier `ide_phys.c` du code du guest.
 
-### (5) Clavier
+### (5) Moteur de sprites
+
+Ce périphérique est exposé physiquement et virtuellement. Le moteur de sprites (*sprite engine*) est capable de gérer un total de 8 sprites. Un sprite est simplement une petite image 2D affichée à une position spécifique de l'écran. Chaque sprite est référencé par un numéro entier (slot) entre 0 et 7. Le moteur de sprites offre, pour chaque sprite, trois fonctionnalités possibles\ :
+
+- Définir le contenu du sprite (largeur, hauteur, contenu en pixels)
+- Définir la visibilité du sprite
+- Positionner le sprite
+
+Un sprite est un ensemble de pixels. Le premier pixel est le pixel du coin supérieur gauche du sprite. Chaque pixel est encodé sur 32 bits selon le format RGBA8888.
+
+**Comportement du VMM**
+
+Le VMM doit afficher tout sprite marqué comme visible à la position spécifiée. La position est exprimée en pixels où la position (0,0) représente le coin supérieur gauche de l'écran. Le sprite est positionné selon son coin supérieur gauche.
+L'affichage doit être rafraîchi à une fréquence de 60 Hz. La petite librairie graphique **`gfxlib`** mentionnée plus bas comporte un exemple d'affichage de sprites sur lequel vous pouvez vous inspirer.
+
+**Guest: accès paravirtualisé**
+
+- Numéro d'hypercall: 5
+- Rôle: défini le contenu du sprite
+- Paramètres de l'hypercall:
+  \footnotesize
+  ```{.c}
+  uint8_t slot;      // sprite identifier
+  uint64_t data;     // sprite data address
+  uint32_t width;    // sprite width in pixels
+  uint32_t height;   // sprite height in pixels
+  ```
+  \normalsize
+
+- Numéro d'hypercall: 6
+- Rôle: défini la visibilité du sprite
+- Paramètres de l'hypercall:
+  \footnotesize
+  ```{.c}
+  uint8_t slot;      // sprite identifier
+  uint8_t toggle;    // visibility (1 = visible, 0 = not visible)
+  ```
+  \normalsize
+
+- Numéro d'hypercall: 7
+- Rôle: positionne le sprite
+- Paramètres de l'hypercall:
+  \footnotesize
+  ```{.c}
+  uint8_t slot;      // sprite identifier
+  int32_t x;         // x position
+  int32_t y;         // y position
+  ```
+  \normalsize
+
+**Guest: accès physique**
+
+Le périphérique se programme en MMIO.
+
+- Adresse registre de statut (read-only): 0x3E800000
+- Adresse registre de commande (write-only): 0x3E800010
+- Adresse registre de donnée de base (write-only): 0x3E800020
+
+**Définir le contenu du sprite:**
+
+1. Ecrire la valeur 9, sur 32 bits, dans le registre de commande
+1. Spécifier le slot (identifiant) du sprite:
+   1. écrire la valeur 27, sur 32 bits, dans le registre de commande
+   1. écrire le numéro du slot, sur 32 bits, dans le registre de donnée
+1. Ecrire la largeur du sprite, sur 32 bits, dans le registre de donnée
+1. Ecrire la hauteur du sprite, sur 32 bits, dans le registre de donnée
+1. Ecrire le contenu en pixels du sprite dans le registre de donnée
+   - le nombre de pixels = largeur * hauteur
+   - un pixel du sprite est défini en écrivant 4 fois, sur 8 bits, dans le registre de donnée selon l'ordre: composante rouge, verte, bleue, alpha
+   - le premier pixel représente le coin supérieur gauche du sprite
+
+**Définir la visibilité du sprite:**
+
+1. Ecrire la valeur 14, sur 32 bits, dans le registre de commande
+1. Spécifier le slot (identifiant) du sprite:
+   1. écrire la valeur 27, sur 32 bits, dans le registre de commande
+   1. écrire le numéro du slot, sur 32 bits, dans le registre de donnée
+1. Ecrire la valeur 1 (visible) ou 0 (invisible), sur 8 bits, dans le registre de donnée
+
+**Positionner le sprite:**
+
+1. Ecrire la valeur 35, sur 32 bits, dans le registre de commande
+1. Spécifier le slot (identifiant) du sprite:
+   1. écrire la valeur 27, sur 32 bits, dans le registre de commande
+   1. écrire le numéro du slot, sur 32 bits, dans le registre de donnée
+1. Ecrire la position x du sprite, sur 32 bits, dans le registre de donnée
+1. Ecrire la position y du sprite, sur 32 bits, dans le registre de donnée
+
+### (6) Clavier
 
 Ce périphérique est exposé physiquement et virtuellement. Côté guest OS, lorsque l'interruption matérielle 1 est reçue, cela signifie qu'une touche clavier à été pressée et la valeur de celle-ci peut alors être récupérée par le guest.
 
@@ -194,7 +282,7 @@ Ce périphérique est exposé physiquement et virtuellement. Côté guest OS, lo
 
 **Guest: accès paravirtualisé**
 
-- Numéro d'hypercall: 5
+- Numéro d'hypercall: 8
 - Paramètres de l'hypercall:
   \footnotesize
   ```{.c}
@@ -212,10 +300,6 @@ Comment obtenir le code de la touche pressée\ ?
 
 1. Lire 32 bits (le code de la touche) depuis le registre de donnée
 
-### (6) Moteur de sprites
-
-**TODO**: cette section sera ajoutée bientôt
-
 ## Cahier des charges
 
 ### Processus de build
-- 
GitLab