L'image et l'ULA
L’ULA de Phosphoric ne dessine plus une ligne d’un coup : elle lit une cellule par cycle, à l’instant où le faisceau la croise. C’est ce qui rend possibles les effets de milieu de ligne des démos.
Dans cette page
Le balayage, en cycles
Le compteur horizontal de l’ULA compte de 0 à 63 à chaque ligne, un compte par cycle :
- les colonnes 0 à 39 de l’écran sont lues aux comptes 0 à 39, une cellule de 6 pixels par cycle, soit 240 pixels ;
- le blanking occupe les comptes 40 à 63, et l’impulsion de synchronisation les comptes 49 à 52.
« Colonne 0 au cycle 0 de la ligne » n’est donc pas une convention de l’émulateur : c’est le compteur
de la puce, tel qu’un guide non officiel de l’ULA l’a relevé à l’oscilloscope. L’option
--ula-fetch-offset reste pour expérimenter, mais sa valeur juste est 0.
Une trame compte 312 lignes, dont 224 visibles : 200 lignes de texte ou de HIRES, puis 3 rangées de texte. 312 × 64 = 19 968 cycles par trame, 50 trames par seconde.
Une cellule par cycle
Depuis la version 2.0, l’ULA de Phosphoric lit chaque cellule au cycle où le faisceau la lit. L’encre, le fond et les attributs de texte sont un état de la ligne, qui persiste d’une cellule à la suivante, comme sur la puce.
Conséquence : une écriture du processeur au milieu d’une ligne n’atteint que les cellules pas encore balayées. Un programme qui change la couleur ou le mode en cours de ligne obtient ce que le matériel donnerait, et non une ligne uniforme. C’est le split raster.


--ula-line, le rendu d’avant la 2.0 : chaque ligne lue d’un coup, des
frontières en marches.La preuve
make test-raster-splitlance un vrai programme 6502 de 32 octets qui réécrit la mémoire écran en alternant deux couleurs de fond. Il compare le rendu par cycle au rendu ligne par ligne, et exige des lignes qui diffèrent sur une partie seulement de leur largeur : une coupure au milieu d’une ligne, que le rendu ligne par ligne ne peut pas produire.make test-clockcontient le cas déterministe et exact : une écriture au cycle c est vue par la cellule c et les suivantes.
Les modes
| Mode | Définition | Mémoire |
|---|---|---|
| Texte | 40 × 28 caractères de 6 × 8 pixels | écran en $BB80, caractères en $B400 et $B800 |
| HIRES | 240 × 200 pixels, 6 pixels par octet | écran en $A000 (40 octets par ligne), puis 3 rangées de texte |
| Double hauteur, clignotement, jeu secondaire | attributs de texte 8 à 15 | — |
Dans un octet HIRES, les six bits de poids faible sont les pixels ; si les bits 5 et 6 sont à zéro,
l’octet est un attribut. Un attribut de mode (24 à 31) peut changer de mode en cours de trame :
la source de la lecture bascule alors entre $A000 et $BB80, ligne à ligne. Le bit 7 d’un octet
inverse sa cellule : il complémente l’encre et le fond (XOR 7), il ne les échange pas.
Ce qui n’est pas dessiné
- La bordure et le blanking : l’image fait toujours 240 × 224 pixels.
- La phase absolue entre le balayage et le processeur : les compteurs de l’ULA tournent librement et le reset du 6502 est asynchrone, donc aucun logiciel ne peut l’observer sur un Oric non modifié. Seul un fil ajouté de l’ULA vers le VIA, le « VSYNC hack », la rendrait visible ; il n’est pas émulé.
- Les modes étendus de l’ULA-NG en plein écran sont rendus par ligne, et non par cellule.
Afficher et exporter
| Sortie | Option |
|---|---|
| Fenêtre agrandie ×1 à ×4 (240 × 224 à 960 × 896), sans lissage | --scale N, touche F3 |
| Plein écran | F11 |
| Capture PNG | F12 ; --screenshot FICHIER à la fin, --screenshot-at CYCLES:FICHIER |
| Capture quand une case mémoire prend une valeur | --screenshot-when ADR:VAL:FICHIER |
| Texte de l’écran en ASCII, ou image en texte ANSI | --screenshot-text, --screenshot-ansi |
| Vidéo Motion-JPEG en AVI | --video FICHIER, --video-fps, --video-quality |
| Diffusion vers un Chromecast (flux MJPEG 720 × 672 et son WAV) | --cast-server, --cast-to (construction CAST=1) |
Les captures déclenchées par cycle sont répétables : --screenshot-at peut être donné plusieurs fois
dans la même exécution. C’est ainsi qu’on prend une série d’images d’une démo.