19 — Propagace změny Display Mode Register (DMD)

Základní informace

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.

DMD registr

Format

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)

Hlavní režimy

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

Signálový řetězec

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

Propagace DMD — mid-scanline IGRB

Měření: 320x200 → 640x200

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).

Detail přechodu (write@CLK0=600)

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).

Měření: 640x200 → 320x200 (opačný směr)

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.

Měření: 320x200 → MZ-700

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.

Měření: 640→MZ-700, MZ-700→640, MZ-700→320

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.

Propagace DMD — DRAM fetch pattern

ČAS adresy dle režimu

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.

Mid-line ČAS změna (320→640, CLK0=600)

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.

Mystery reads po přepnutí

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/B switch (double buffering)

Mechanismus

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ě.

Měření mid-scanline

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).

DRAM adresy

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.

Blanking switch (bezpecny přechod)

Měření

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).

Bezpečné okno

Blanking přepnutí DMD: CLK0 957-329 = 508 CLK0 (~28.6 us, ~101 T-stavu CPU). Stejně okno jako pro palette, border a SOF.

Asymetrie smeruprep přepnutí

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.

Porovnání všech I/O registru

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.

Nedokumentované režimy — mid-scanline přepnutí

Měření (VRAM=0xFF, write@CLK0=600)

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).

Interpretace

Praktické dopady

Mid-scanline mode switch

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

Doporučení pro software

  1. Bezpečné přepnutí: zmenyt DMD během V-blank (celý snímek konzistentni)
  2. Per-line switch: zmenit během H-blank (celý řádek konzistentni)
  3. Mid-line efekty: možné, ale IGRB přechod není atomicky (6-24 CLK0 prechodove okno)
  4. Frame A/B double buffering: přepnout během V-blank, kreslit do neaktivniho framu

Stav ověření

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.