16 — Propagace zápisu VRAM v MZ-800 grafických režimech

Základní informace

Tento dokument popisuje časování propagace změny obsahu VRAM do generovaneho obrazu v MZ-800 grafických režimech (DMD bit 3 = 0). Pro MZ-700 textový režim viz 09-mz700-fetch-pipeline.md.

Klíčová otazka: Jak daleko před paprskem musí byt CPU zápis do VRAM, aby se změna projevila na aktualnim řádku?

Video fetch pipeline

2 DRAM čtení na sloupec (ne 4!)

Každý ze 40 sloupců na řádku vyžaduje přesně 2 DRAM čtení v page-mode (společný RAS, 2 ČAS cykly):

Čtení CLK0 offset Účel
1 +0 Plane I data (VA bus)
2 +4 Plane II data (VA bus), případně VC bus

Každý sloupec trvá 16 CLK0. Dve čtení jsou rozlozena s mezerou 4 CLK0 v prvních 8 CLK0 sloupce. Zbylych 8 CLK0 slouzi pro interspersed DRAM operace (viz nize).

Pozn.: Dokument 11 uvadel 160 čtení/řádek (40×4). Správný počet je 80 video čtení (40×2). Dodatecna DRAM čtení během viditelné oblasti nejsou video data fetch — viz sekce Mystery reads.

Adresy

Režim RAS ČAS 1 (plane I) ČAS 2 (plane II)
320x200/4c 0xB0+N 0x88/0x89 0xC8/0xC9
640x200/2c 0xB0+N 0x92/0x93 0xD2/0xD3
320x200/16c 0xB0+N 0x9C/0x9D 0xDC/0xDD

Pozn.: RAS = 0xB0+N plati pro konkrétní řádek (raster line). Na jiných radcich ma RAS jinou základní hodnotu, ale vždy +1 za každý sloupec.

Kazde čtení produkuje 8 bitu na VA bus (roviny I+II) a současně 8 bitu na VC bus (roviny III+IV). Jedno čtení = 8 pixelů jedne roviny. Pro 4-barevný režim (2 roviny) staci 2 čtení na kompletní sloupec dat.

Mystery reads (RAS=0x00, ČAS=0x40)

V režimu 320x200 (DMD=0x00, 0x02) jsou mezi každý video sloupec vlozena další DRAM čtení na adrese DRAM 0x0040 (RAS=0x00, ČAS=0x40). Časování: CLK0 +12 od zacatku sloupce.

Fáze v ramci sloupce CLK0 offset Operace
Video read 1 +0 Plane I data
Video read 2 +4 Plane II data
(mezera) +8
Mystery read +12 DRAM 0x0040

V režimu 640x200 (DMD=0x04) tyto mystery reads nenastávají.

Prakticky dopad: mystery reads obsazuji DRAM sbernici, cimz prodluzuji dobu od CPU zápisu do DRAM aktualizace v režimu 320x200 oproti 640x200 (38 vs 22 CLK0 pro free write).

Časová osa jednoho řádku

CLK0:  0        329  340                       957   1135
       |         |    |                         |      |
       | refresh |    |    40 sloupcu x 16 CLK0 |      |
       | + mystery    |    = 640 CLK0           |      |
       |         |    |                         |      |
       |     prefetch | canvas start       prefetch    |
       |     col 0    |                    col 39 end  |

Přesně pozice (PAL, CKSW=0)

Udalost CLK0 Poznámka
Prefetch col 0 329 První DRAM čtení
HBLN visible 335 Status Register bit 7 = 1
Canvas start 340 První pixel na výstupu
Col N prefetch 329 + N×16 První DRAM čtení pro sloupec N
Col 39 prefetch 953 Poslední video sloupec
Col 39 konec 957 Poslední DRAM čtení
HBLN blank 975 Status Register bit 7 = 0

Pipeline latence

Měření

Od prvniho DRAM čtení (CLK0 329+N×16) k prvnimu pixelů na výstupu = ~8 CLK0 (~0.45 us).

To odpovídá situaci: - CLK0 +0: čtení plane I (8 pixelů) - CLK0 +4: čtení plane II (8 pixelů) - CLK0 +8: první pixel na výstupu

Pipeline tedy zpracovava data za 4 CLK0 od posledniho čtení. To je vyrazne méně než v MZ-700 textovém režimu (19 CLK0), protože není třeba CG lookup.

Korekce oproti dokumentu 11

Dokument 11 uvaděl pipeline latenci 3 CLK0 pro MZ-800 režimy. Toto číslo odpovidalo rozdílu HBLN visible (CLK0 335) a canvas start (CLK0 340), ne skutečně latenci pipeline od DRAM čtení.

Správná hodnota: 8 CLK0 od prvniho DRAM čtení k prvnimu pixelů na výstupu (ověřeno přímo změnou VRAM v presnem CLK0 a sledovanim IGRB přechodu).

CPU write — DRAM latence

Asynchronní DRAM zápis

GDG používá late write (read-modify-write) pro CPU zápisy. DRAM bunka se aktualizuje až po skonceni CPU cyklů — GDG provede DRAM zápis v dalším volnem slotu.

Merene hodnoty

Situace CPU cyklus DRAM latence Celkem WAIT
Blanking, 320x200 19 CLK0 +10 CLK0 29 CLK0 0 TW
Blanking, 640x200 18 CLK0 +11 CLK0 29 CLK0 0 TW
Visible free, 320x200 18 CLK0 +20 CLK0 38 CLK0 0 TW
Visible free, 640x200 17 CLK0 +5 CLK0 22 CLK0 0 TW
Visible WAIT, 320x200 30 CLK0 +1 CLK0 31 CLK0 3 TW
Visible WAIT, 640x200 30 CLK0 +1 CLK0 31 CLK0 3 TW

Vysvětlení sloupců: - CPU cyklus: délka Z80 write cyklů (T1-T3 + WAIT) - DRAM latence: doba od konce CPU cyklů do aktualizace DRAM bunky - Celkem: doba od zahajeni CPU zápisu do DRAM aktualizace - WAIT: počet wait T-stavu (0 pro free write, 3+ pro penalizovany)

Proč se 320x200 a 640x200 liší

V režimu 320x200 jsou mystery reads vlozeny mezi video sloupce a obsazuji DRAM sbernici. GDG musí cekat na volný slot pro CPU zápis, což prodluzuje DRAM latenci: - 320x200: 20 CLK0 navíc (musí cekat na mezeru po mystery read) - 640x200: 5 CLK0 navíc (žádné mystery reads, vice volnych slotu)

Praktické dopady: racing the beam

Bezpečné okno pro zápis

Pro změnu sloupce N na aktualnim řádku musí byt DRAM aktualizace dokoncena před CLK0 329 + N×16 (zacatek video fetch).

Minimalni před-start CPU zápisu:

Režim Během blanking Během visible (free)
320x200 CLK0 300+N×16 CLK0 291+N×16
640x200 CLK0 300+N×16 CLK0 307+N×16

Příklad pro sloupec 20 (stred obrazovky): - Blanking: CPU musí zahajit zápis před CLK0 620 - Visible 320x200: před CLK0 611 - Visible 640x200: před CLK0 627

Blanking je bezpecny

Změny VRAM během HBLN blanking se VŽDY projeví na následujícím řádku. Ověřeno simulací v obou režimech (640/640 pixelů).

Bezpečné okno pro blanking zápisy: CLK0 957 až 329 = 508 CLK0 (~28.6 us, ~101 T-stavu CPU).

Jeden free zápis během visible

První CPU zápis do VRAM během visible oblasti neobdrzi WAIT. Druhý a další zápisy dostavaji WAIT (3-6 TW).

Pro jediný zápis ("painting ahead of beam"): 1. CPU zahaji zápis během visible oblasti 2. Zápis trvá 38 CLK0 (320x200) nebo 22 CLK0 (640x200) celkem 3. Pokud cilovy sloupec ještě nebyl precten, změna se projeví

Ale: po tomto jednom zápisu následuje "horka fáze" (32 CLK0 v 320x200, 17 CLK0 v 640x200). Další zápis dostane WAIT.

LDIR do VRAM

LDIR provádí střídavě READ + WRITE. READ v MZ-800 režimu nepenalizuje (viz dokument 15). Mezi WRITE a následujícím READ další iterace uplyne ~70 CLK0, což je za hranici horke fáze. LDIR do VRAM tedy běží bez WAITu — ale každý zápis produkuje DRAM aktualizaci se zpozdenim.

Porovnání režimu

Vlastnost 320x200/4c 640x200/2c 320x200/16c 0x03 (nedok.) 0x07 (nedok.)
Video čtení/řádek 80 (40×2) 80 (40×2) 80 (40×2) 284 182 (81×2)
Mystery čtení/řádek 39 0 39 0 0
Prefetch CLK0 329 329 329 329 329
Pipeline latence ~8 CLK0 ~8 CLK0 ~8 CLK0 ~8 CLK0 ~8 CLK0
Visible free latence 38 CLK0 22 CLK0 38 CLK0 ~22 CLK0* 22 CLK0
Bezpečné blanking okno 508 CLK0 508 CLK0 508 CLK0 508 CLK0 508 CLK0

(*) DMD=0x03 nemá mystery reads (na rozdíl od 0x00/0x02), proto ma kratsí visible free latenci priblizne odpovídající 640x200.

16-barevný režim (DMD=0x02) ma stejně časování jako 4-barevný (DMD=0x00), včetně mystery reads. Jediný rozdíl: ČAS adresy (0x9C/0xDC místo 0x88/0xC8).

Nedokumentované režimy — poznámky

DMD=0x03 (320x200, bits[1:0]=11): Hybridni režim s 284 video ctenimi (jako Frame B), ČAS zaklady 0x0A, 0x4A, 0xBE, 0xFE. Používá VC bus (roviny III+IV), VA bus je ignorovan. Na rozdíl od 0x00/0x02 nemá mystery reads, což znamená vice volnych slotu pro CPU DRAM zápisy během viditelné oblasti.

DMD=0x07 (640x200, bits[1:0]=11): Identický DRAM fetch pattern jako 0x06 (182 čtení, ČAS 0x0A/0x4A/0xFE). Používá VC bus (plane III) pro oba bity paletoveho indexu, plane I (VA) je ignorovan. Z hlediska propagace VRAM zápisu se chova identický jako ostatní 640x200 režimy.

Stav ověření

Simulace (HDL): Všechny hodnoty pochází z gate-level simulace (GDG_core.vhd + cocotb testbenche test_mz800_propagation.py a test_dmd_undocumented.py).

Ověřeno: - Fetch timing: 2 video čtení/sloupec, 16 CLK0/sloupec, start CLK0 329 - Pipeline latence: ~8 CLK0 (přímo měření VRAM flip + IGRB) - DRAM adresy: 3 režimy (4c, 2c, 16c), ČAS rozlišení dle režimu - Mystery reads: 39/řádek v 320x200 (DMD=0x00, 0x02), 0 v 640x200 - Blanking propagace: 640/640 pixelů (320x200), 638/640 (640x200) - CPU write timing: blanking 29 CLK0, visible 22-38 CLK0, WAIT 31 CLK0 - Nedokumentované režimy (test_all_dmd_overview, test_vram_plane_usage): - DMD=0x03: 284 vid čtení, 0 mystery, ČAS 0x0A/0x4A/0xBE/0xFE, VC only - DMD=0x07: 182 vid čtení, 0 mystery, ČAS 0x0A/0x4A/0xFE (= 0x06)

Reálně HW: Ještě neověřeno.