Aller au contenu
Phosphoricwiki
Sommaire

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

Une trame PAL de l'ULA, en cyclesUne ligne dure 64 cycles du compteur horizontal de l'ULA. Les colonnes 0 à 39 sont lues aux comptes 0 à 39, une cellule de 6 pixels par cycle, soit 240 pixels ; le blanking occupe les comptes 40 à 63 et la synchronisation les comptes 49 à 52. 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.Compteur horizontal : 64 comptes par ligne, 1 compte = 1 cycle = 1 µslignes 0-199texte ou HIRES · 40 cellules × 6 pixelslignes 200-223 : 3 rangées de texteblankingsynchroblankinglignes 224-311 : hors image0404952630200224311lignes de la trame (PAL)Colonnes 0-39lues aux comptes 0-39Comptes 40-63blanking ; synchro en 49-52224 lignes visiblessur 312 lignes par trame312 × 64 = 19 968 cycles par trame · 50 trames par seconde
Une trame PAL : 312 lignes de 64 cycles. Les colonnes 0 à 39 sont lues aux comptes 0 à 39.

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.

Bandes noires et cyan dont les frontières penchent au milieu des lignes
Le programme du test réécrit l’écran pendant que le faisceau le balaie : les frontières penchent au milieu des lignes.
Bandes noires et cyan dont les frontières forment des marches
Le même programme avec --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-split lance 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-clock contient le cas déterministe et exact : une écriture au cycle c est vue par la cellule c et les suivantes.

Les modes

ModeDéfinitionMémoire
Texte40 × 28 caractères de 6 × 8 pixelsécran en $BB80, caractères en $B400 et $B800
HIRES240 × 200 pixels, 6 pixels par octetécran en $A000 (40 octets par ligne), puis 3 rangées de texte
Double hauteur, clignotement, jeu secondaireattributs 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

SortieOption
Fenêtre agrandie ×1 à ×4 (240 × 224 à 960 × 896), sans lissage--scale N, touche F3
Plein écranF11
Capture PNGF12 ; --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.

Sources dans le dépôt : docs/ACCURACY.md, docs/architecture/master-clock.md, README.md, tests/integration/test_raster_split.sh.