Tento dokument popisuje jak rychle se změna Display Mode Register (DMD, port CEH) projeví v generovanem video výstupu. DMD určuje grafický režim — rozlišení (320/640), počet barev (2/4/16), výběr roviny (Frame A/B) a přepnutí mezi MZ-800 grafikou a MZ-700 textovym rezimem.
Klíčová otazka: Projeví se změna DMD okamžitě (mid-scanline), nebo až po dokonceni aktualniho řádku?
Odpoved: Okamžitě, mid-scanline. Podobne jako paleta a SOF, GDG nepoužívá žádný double-buffering. DMD se propaguje přes F601 D-latch → F612 D flip-flop do celé pipeline.
Port CEH (zapis):
Bit: 7 6 5 4 3 2 1 0
X X X X DMD3 DMD2 DMD1 DMD0
DMD3 DMD2:
0 0 → 320x200 graficky rezim
0 1 → 640x200 graficky rezim
1 X → MZ-700 znakovy rezim (40x25)
DMD1 DMD0 (v grafickem rezimu):
0 0 → Frame A (roviny I, II)
0 1 → Frame B (roviny III, IV)
1 0 → Oba framy (16 barev / 4 barvy 640)
| DMD | Režim | Barvy | Roviny | Pixel clock |
|---|---|---|---|---|
| 00H | 320x200 | 4 | I, II (Frame A) | CLK0/2 |
| 01H | 320x200 | 4 | III, IV (Frame B) | CLK0/2 |
| 02H | 320x200 | 16 | I-IV (oba framy) | CLK0/2 |
| 04H | 640x200 | 2 | I (Frame A) | CLK0 |
| 08H | MZ-700 text | 8 | — | CLK0/2 |
I/O zapis na port CEH (DT[3:0])
|
F601 D-latche (transparentni pri write strobe)
|
bus_DMD[3:0]
|
F612 D flip-flopy (taktovane CLK0)
|
Kombinacni logika: pixel clock mux, CAS dekoder, pipeline rizeni
|
Video pipeline (DRAM fetch, shift registr, paletovy MUX)
|
F666 vystupni flip-flop → IGRB piny
VRAM = 0xFF. V 320x200 = palette 3 (bílá IGRB=1111). V 640x200 = palette 1 (jiná barva). Uprostřed viditelneho řádku prepnuto DMD z 0x00 na 0x04.
| Write CLK0 | Přechod CLK0 | Delay | Poznámka |
|---|---|---|---|
| 400 | 414 | 14 CLK0 | |
| 600 | 606 | 6 CLK0 | |
| 800 | 814 | 14 CLK0 |
Průměrná latence: ~6-14 CLK0 — stejná jako u palety (viz doc 17).
CLK0: ... 601 602 603 604 605 606 607 608 ...
IGRB: 1111 1111 1111 1111 1111 1111 0001 0001 0001 ...
^^^
320x200 pixely → 640x200 pixely
Na CLK0=606 se IGRB změní z bílé (1111, palette 3 v 320x200) na jinou barvu (pixel data interpretovana v 640x200 režimu).
| Write CLK0 | Přechod CLK0 | Delay | Poznámka |
|---|---|---|---|
| 600 | 624 | 24 CLK0 | Pomalejsi! |
Přepnutí z 640x200 na 320x200 trvá 24 CLK0 — vyrazne dele než opačný směr (6-14 CLK0). Důvod: pipeline musí přepnout pixel clock z CLK0 na CLK0/2 a pockat na resynchronizaci interní děličky a shift registru.
| Write CLK0 | Přechod CLK0 | Delay | Poznámka |
|---|---|---|---|
| 600 | 606 | 6 CLK0 | Kratky glitch 6 px |
Přepnutí do MZ-700 režimu je rychle (6 CLK0). Na IGRB výstupu se objevi kratky glitch (~6 pixelů s jinou barvou), pak se pipeline stabilizuje na MZ-700 výstup.
Tyto prechody nelze merit přes IGRB, protože s VRAM=0xFF produkuji oba režimy vizuálně stejný výstup (bílý). Měření provedeno přes DRAM fetch pattern (změna ČAS adres a poctu čtení na sloupec).
| Směr | DRAM přechod | Metoda | Poznámka |
|---|---|---|---|
| 640→MZ-700 | ~18 CLK0 | První MZ-700 CG čtení@CLK0=618 | Rychle |
| MZ-700→640 | ~34 CLK0 | První 640 čtení@CLK0=634 | Nejpomalejsi! |
| MZ-700→320 | ~18 CLK0 | První 320 čtení@CLK0=618 | Rychle |
MZ-700→640 je nejpomalejsi přechod (~34 CLK0). MZ-700 používá pixel clock CLK0/2 (jako 320x200), takže přepnutí na 640x200 (CLK0) vyžaduje stejnou resynchronizaci děličky jako 320→640, ale navíc musí přepnout z textového na grafický pipeline.
Každý režim používá jiné základní ČAS adresy pro video fetch:
| Režim | ČAS základ (bez bit 0) | Poznámka |
|---|---|---|
| 320x200/4c (Frame A) | 0x1A, 0x5A, 0xBE, 0xFE | Roviny I+II |
| 640x200/2c | 0x8E, 0xCE, 0xFE | Rovina I |
| 320x200/4c (Frame B) | 0x20, 0x60, 0x9E, 0xBE, 0xDE, 0xFE | Roviny III+IV |
| MZ-700 text | 0xA7, 0xB7, 0x9E, ... | Znak+barva+CG |
ČAS adresa jednoznacne identifikuje, v jakem režimu GDG aktualne provádí video fetch.
CLK0= 594 RAS=0xFF CAS=0xBF [320]
CLK0= 598 RAS=0xFF CAS=0xFF [refresh]
CLK0= 602 RAS=0x30 CAS=0x1A [320] <- posledni 320 fetch
CLK0= 606 RAS=0x30 CAS=0x5A [320]
CLK0= 610 RAS=0xFF CAS=0xBF [320]
CLK0= 614 RAS=0xFF CAS=0xFF [refresh]
CLK0= 618 RAS=0x31 CAS=0x1B [prechod]
CLK0= 622 RAS=0x31 CAS=0x5B [prechod]
CLK0= 626 RAS=0xFF CAS=0xFF [refresh]
CLK0= 634 RAS=0x32 CAS=0x1A [640]
CLK0= 638 RAS=0x32 CAS=0x5A [640]
DRAM fetch pattern se mění postupne — poslední 320x200 čtení na CLK0=610, první 640x200 čtení na CLK0=634. Přechod trvá ~24 CLK0 od zahajeni io_write.
V 320x200 režimu GDG vklada "mystery reads" (RAS=0x00, ČAS=0x40) mezi video sloupce. Po přepnutí na 640x200 mystery reads ihned zmizi — první sloupec v 640x200 režimu uz nemá mystery read.
Frame A (DMD=0x00) čte roviny I+II z VA bus. Frame B (DMD=0x01) čte roviny III+IV z VC bus. Přepnutí mění pouze DMD bit 0 — pixel clock a rozlišení zustavaji stejně.
VA paměť = 0xFF (Frame A = palette 3, bílá), VC paměť = 0x00 (Frame B = palette 0, zelená).
| Směr | Write CLK0 | Přechod CLK0 | Delay |
|---|---|---|---|
| A→B | 600 | 622 | 22 CLK0 |
Celý následující řádek jiz zobrazuje Frame B data (palette 0).
Frame A a Frame B používají odlišně ČAS adresy: - Frame A: ČAS základ 0x1A, 0x5A, 0xBE, 0xFE - Frame B: ČAS základ 0x20, 0x60, 0x9E, 0xBE, 0xDE, 0xFE
Frame B ma vice unikatnich ČAS hodnot — pravděpodobně kvuli čtení ze 4 rovin (III, IV) místo 2 (I, II) s odlisnym mapovanim.
Přepnutí DMD během HBLN blanking (CLK0 957-329) se plně projeví na následujícím řádku:
| Přechod | Zmenenych pixelů | Poznámka |
|---|---|---|
| 320x200 → 640x200 | 640/640 | Barva se změní (jiný pixel clock) |
| 640x200 → 320x200 | 640/640 | Barva se změní zpet |
| 320x200 → MZ-700 | 0/640 | Obe barvy stejně (VRAM=0xFF) |
| MZ-700 → 320x200 | 0/640 | Obe barvy stejně (VRAM=0xFF) |
| 320x200/4c → 16c | 0/640 | Palette 3 stejná v obou režimech |
| Frame A → Frame B | ověřeno v testu 3 | ČAS adresy se změní |
Pozn.: přepnutí 320→MZ-700 a zpet nezpusobi vizuální změnu pokud VRAM=0xFF (CG vzor=plný blok, stejný barevný výsledek). Skutečná změna je v DRAM fetch patternu (2 vs 4 čtení/sloupec).
Blanking přepnutí DMD: CLK0 957-329 = 508 CLK0 (~28.6 us, ~101 T-stavu CPU). Stejně okno jako pro palette, border a SOF.
Důležité zjištění: směr přepnutí ovlivňuje latenci.
| Směr | Delay | Důvod |
|---|---|---|
| 320→640 | 6-14 CLK0 | Pixel clock CLK0/2 → CLK0 (zrychleni) |
| 640→320 | 24 CLK0 | Pixel clock CLK0 → CLK0/2 (spomaleni, resync) |
| 320→MZ-700 | 6 CLK0 | Podobny pixel clock (CLK0/2) |
| Frame A→B | 22 CLK0 | Jen změna rovin, ale pipeline reset |
| 640/2c→0x07 | 7 CLK0 | Oba CLK0, jen změna interpretace rovin |
| 320/4c→0x0C | 6 CLK0 | = 320→MZ-700 (0x0C je MZ-700 text) |
Přepnutí z vyssiho rozlišení na nižší (640→320) je pomalejsi protože interní pixel clock dělička se musí resynchronizovat na CLK0/2. Přepnutí na vyšší rozlišení (320→640) je rychle protože CLK0 je základní hodiny.
| Registr | Port | Delay | Mid-line? | Směr závislost |
|---|---|---|---|---|
| Paleta | F0H | 10-14 CLK0 | Ano | — |
| Border | CF06H | 6 CLK0 | Ano | — |
| SOF-L | CF01H | ~18 CLK0 | Ano | — |
| SOF-H | CF02H | ~18 CLK0 | Ano | — |
| DMD (320→640) | CEH | 6-14 CLK0 | Ano | Rychle |
| DMD (640→320) | CEH | 24 CLK0 | Ano | Pomale |
| DMD (Frame A→B) | CEH | 22 CLK0 | Ano | Stredni |
Všechny I/O registry GDG se propagovany okamžitě. GDG nepoužívá žádný double-buffering, line-start latch ani frame-start latch pro žádný registr.
| Směr | Delay | Poznámka |
|---|---|---|
| 320/4c → 0x03 | — | Nerozeznatelně (oba IGRB=bílé s VRAM=0xFF) |
| 0x03 → 320/4c | — | Nerozeznatelně |
| 320/16c → 0x03 | — | Nerozeznatelně |
| 0x03 → 320/16c | — | Nerozeznatelně |
| 640/2c → 0x07 | 7 CLK0 | Rychle — oba režimy v 640 rozlišení |
| 0x07 → 640/2c | — | Nerozeznatelně (oba IGRB shodné) |
| 640/4c → 0x07 | — | Nerozeznatelně |
| 0x07 → 640/4c | — | Nerozeznatelně |
| MZ-700 → 0x0C | — | Identický režim |
| 0x0C → MZ-700 | — | Identický režim |
| 320/4c → 0x0C | 6 CLK0 | Stejná latence jako 320→MZ-700 |
| 0x0C → 320/4c | — | Nerozeznatelně |
Pozn.: Většina přechodu je nerozeznatelna protože VRAM=0xFF produkuje v obou režimech vizuálně shodný výstup (bílý). Přechod je detekovatelny pouze když se IGRB výstup liší — napriklad 640/2c→0x07 (palette 1 vs palette 0).
DMD=0x03 ↔ 320x200: Protože oba režimy používají CLK0/2 pixel clock, ocekavame stejný delay jako u 320↔320 přechodu (~6-14 CLK0). Nelze ověřit s uniformnim VRAM vzorem.
DMD=0x07 ↔ 640x200: Ověřený delay 7 CLK0 (640/2c→0x07), konzistentni s ostatnimi prepnutimi v ramci 640 rozlišení. Oba režimy sdili CLK0 pixel clock — žádná resynchronizace děličky není potřeba.
DMD=0x0C ↔ 320x200: Delay 6 CLK0 (320→0x0C), identický s 320→MZ-700 (0x08). Potvrzuje ze 0x0C = MZ-700 text.
GDG technický umožňuje přepnutí režimu uprostřed řádku. Vysledkem je část řádku v puvodnim režimu a zbytek v novem. Toto se liší od vetsiny modernich GPU, které bufferuji změny do V-blank.
Možné využití: - Racing-the-beam efekty: různě rozlišení na různých castech obrazovky (analogie Atari 2600 TIA) - Double buffering: přepnutí Frame A/B během blanking je bezpečné a projeví se na následujícím řádku
Simulace (HDL): Všechny hodnoty pochází z gate-level simulace
(GDG_core.vhd + cocotb testbenche test_dmd_propagation.py
a test_dmd_undocumented.py).
Ověřeno: - 320→640 mid-line: 3 pozice (CLK0 400/600/800), delay 6-14 CLK0 - 640→320 mid-line: delay 24 CLK0 (pomalejsi než opačný směr) - 320→MZ-700 mid-line: delay 6 CLK0 - 640→MZ-700 mid-line: DRAM přechod ~18 CLK0 (IGRB nerozeznatelně) - MZ-700→640 mid-line: DRAM přechod ~34 CLK0 (nejpomalejsi přechod) - MZ-700→320 mid-line: DRAM přechod ~18 CLK0 (IGRB nerozeznatelně) - Frame A→B mid-line: delay 22 CLK0 - DRAM fetch ČAS změna: 320 vs 640 vs MZ-700 (rozlisne ČAS adresy) - Mystery reads zmizi po přepnutí 320→640 - Blanking switch: plna propagace na následujícím řádku (všechny směry) - Frame A vs B: odlišně ČAS adresy (jiné roviny) - Nedokumentované režimy (test_midline_switch_undocumented): - 640/2c→0x07: delay 7 CLK0 - 320/4c→0x0C: delay 6 CLK0 (= 320→MZ-700) - 0x0C↔MZ-700: identický režim (žádný přechod) - 0x03/0x07 ↔ oficialni režimy: většina nerozeznatelna s VRAM=0xFF
Reálně HW: Ještě neověřeno.