Veuillez consulter cette page à partir de l'interface principale.
Tutoriel: framebuffer
yasep/tuto/tuto_fb.fr.html version 2012-11-18 par Laura Bécognée et Yann Guidon
Version préliminaire
 

Initiation à la programmation graphique avec le YASEP

Introduction

Ce petit tutoriel propose de montrer comment construire un programme pour le YASEP, pas à pas, avec un exemple simple : remplir le framebuffer avec une couleur pseudo aléatoire.

Prérequis et suppositions :

⚠ Le code ne fonctionnera pas si la fenêtre du framebuffer n'est pas ouverte ⚠

N'oubliez pas de l'ouvrir en cliquant ici puis de la lier à la même carte mémoire.

Coder une boucle

Pour remplir l'écran, il faudra balayer tous ses pixels, ce qui nécessite une boucle.

1) Affectation des registres :

;  R3 : compteur
;  A1 : loop
2) Préparation des itérations pour la boucle :
  mov 65536 R3

Le cpu est en 32 bits (et le framebuffer en 24 bits par pixel + 8 bits inutilisés). Chaque mot de YASEP accède donc à 1 pixel

Avec un fb de 256*256, ça fait 65 536 pixels il faut donc 65 536 itérations pour balayer tout le framebuffer.

3) Préparation du rebouclage :

  add 4 PC A1
On calcule 4+PC et on met le résultat dans A1, ça crée un repère (sur l'instruction suivante) qui permet de revenir dessus pour reboucler.

4) On décrémente le compteur

  add -1 R3

5) On remet A1 dans PC si R3 n'est pas égal à 0

  mov A1 PC NZ R3

6) On bloque le processeur pour arrêter le programme :

  HALT

 

Voici le programme complet :

; fbLFSR_1 : boucle 65536 fois
.name fbLFSR_1
.profile YASEP32

; Affectation des registres :
;   R3 : compteur
;   A1 : loop

mov 65536 R3

add 4 PC A1

;;;;; début de la boucle ;;;;;
  ; décrémente le compteur
  add -1 R3

  ; on remet A1 dans PC si R3 n'est pas égal à 0
  mov A1 PC NZ R3
;;;;;; fin de la boucle ;;;;;;

HALT

 

Changer la couleur du framebuffer

Maintenant, nous pouvons accéder au framebuffer, ce qui nécessite de gérer l'adresse des pixels ainsi que leur valeur (qui est fixe pour l'instant).

1) Affectation des registres :

;  R1 : couleur (Registre simple de stockage)
;  R3 : compteur
;  A1 : loop
;  A2 : écran (registre d'Adresse)
;       associé à D2 (registre de Donnée)

2) On pointe sur le début du framebuffer :

  mov 20000h A2
Cette adresse peut changer arbitrairement, vérifier que cela correspond bien au champ "Adresse début" en haut à droite de la fenêtre du framebuffer.

3) On décide de la couleur :

  mov 00A0FFh R1 ; #00A0FF : bleu ciel

On place #00A0FF dans R1. C'est une valeur inférieure à 500 000 donc une seule instruction nécessaire avec YASEP32.

4) On écrit la couleur dans le framebuffer :

  mov R1 D2
  add 4 A2 ; et on passe au pixel suivant

 

Voici le programme complet :

; fbLFSR_2 : remplit l'écran avec une couleur
.name fbLFSR_2
.profile YASEP32

; Affectation des registres :
;   R1 : couleur (Registre simple de stockage)
;   R3 : compteur
;   A1 : loop
;   A2 : écran (registre d'Adresse)
       ; associé à D2 (registre de Donnée)

mov 65536 R3

; adresse du framebuffer:
mov 20000h A2

mov 00A0FFh R1 ; #00A0FF : bleu ciel

add 4 PC A1

;;;;; début de la boucle ;;;;;
  ; écrit la couleur dans le framebuffer
  mov R1 D2
  add 4 A2

  ; décrémente le compteur
  add -1 R3

  ; on remet A1 dans PC si R3 n'est pas égal à 0
  mov A1 PC NZ R3
;;;;;; fin de la boucle ;;;;;;

HALT

 

Changer la couleur avec un LFSR

Nous allons maintenant remplir l'écran avec des pixels pseudo-aléatoires. Pour cela, on utilise un "Registre à décalage à rétroaction linéaire". La théorie mathématique est mieux expliquée sur la page Wikipedia anglaise et un article très détaillé est disponible chez UnixGarden. Le principe est réduit à un décalage et un XOR.

Toutes les subtilités mathématiques sont concentrées dans la valeur choisie pour le XOR, qu'on appelle "polynôme". Il existe des tables de valeurs valides, et comme on utilise 32 bits, on choisit une des valeurs les plus utilisées, celle du CRC32 standard: 0x04C11DB7

La seule contrainte est qu'il faut s'assurer que R1 n'est pas initialisé avec la valeur 0. La couleur "bleu ciel" convient donc et R1 reste initialisé avec cette valeur.

1) Affectation des registres :

   R1 : LFSR (couleur)
   R2 : polynome
   R3 : compteur
   A1 : loop
   A2 : écran (registre d'Adresse)
        associé à D2 (registre de Donnée)

2) On initialise le polynôme du LFSR :

  movh 04C1h R2 ; MSB
  or   1DB7h R2 ; LSB
C'est une valeur qui ne tient pas dans 20 bits, il faut donc la "couper en deux" et la charger dans R1 avec une séquence de 2 instructions.

3) On génère un bit pseudo-aléatoire :

  ADD R1 R1 ; décale le registre
  ; et met le bit de poids fort dans la retenue

4) Si la retenue est à 1 alors on XOR avec le polynome :

  xor R2 R1 CARRY

 

Voici le programme complet :

; fbLFSR : remplit l'écran avec
; une couleur pseudo-aléatoire
.name fbLFSR
.profile YASEP32

; Affectation des registres :
;   R1 : LFSR (couleur)
;   R2 : polynome
;   R3 : compteur
;   A1 : loop
;   A2 : écran (registre d'Adresse)
       ; associé à D2 (registre de Donnée)

mov 65536 R3

; adresse du framebuffer:
mov 20000h A2

mov 00A0FFh R1 ; #00A0FF : bleu ciel

; initialise le polynôme du LFSR:
movh 04C1h R2 ; MSB
or   1DB7h R2 ; LSB

add 4 PC A1

;;;;; début de la boucle ;;;;;
  ; génère un bit pseudo-aléatoire :
  ADD R1 R1 ; décale le registre et
            ; met le bit de poids fort
            ; dans la retenue

  ; si la retenue est à 1, alors on xor
  xor R2 R1 CARRY

  ; écrit la couleur dans le framebuffer
  mov R1 D2
  add 4 A2

  ; décrémente le compteur
  add -1 R3

  ; on remet A1 dans PC si R3 n'est pas égal à 0
  mov A1 PC NZ R3
;;;;;; fin de la boucle ;;;;;;

HALT