18 — Propagace změny scroll offset (SOF)

Základní informace

Tento dokument popisuje jak rychle se změna scroll offset registru (SOF, porty CF01H/CF02H) projeví v DRAM adresach pouzitych pro video fetch. SOF určuje, který řádek VRAM se zobrazi na vrcholu obrazovky.

Klíčová otazka: Projevy se změna SOF až po dokonceni aktualniho řádku, nebo uz uprostřed?

Odpoved: Uprostřed řádku. SOF se přímo podílí na generování DRAM adresy a nova hodnota se pouzije uz pro následující sloupec.

SOF registr

Format

SOF = (CF02H[1:0] << 8) | CF01H[7:0]
Rozsah: 0-1023 (10 bitu)

Prevod na VRAM offset

Režim Vzorec 1 řádek
320x200 VRAM_offset = SOF * 8 SOF += 5
640x200 VRAM_offset = SOF * 16 SOF += 5

Vliv SOF na DRAM adresy

Měření: SOF=0 vs SOF=5

Porovnání DRAM adres na stejně pozici displeje (PAL, 320x200/4c):

Řádek SOF=0 RAS SOF=5 RAS Posun
0 0xB0-0xD7 0xF0-0x17* +0x40
1 0x01-0x27 0x40-0x67 +0x3F
2 0x50-0x77 0x90-0xB7 +0x40

* Rozsah 0xF0-0x17 pretece přes 0xFF → 0x00 → 0x01... Čtení s RAS=0x00 jsou nerozeznatelně od DRAM refresh a v testu filtrovane, proto počet čtení 78 místo 80.

SOF=5 způsobuje posun RAS o priblizne 0x40 (64), což odpovídá posunu o 1 řádek v DRAM adresnim prostoru. Mění se i ČAS adresy.

SOF-H efekt

Změna SOF z 0 na 256 (zápis CF02H = 0x01) se rovnez projevuje v DRAM adresach — RAS base se posune o velky skok.

Propagace SOF — mid-scanline

Měření

SOF zmeneno z 0 na 5 uprostřed viditelneho řádku (io_write na CLK0=600). Zaznamenana RAS sekvence pro všech 40 sloupců:

Col[ 0] CLK0= 330 RAS=0x60
Col[ 1] CLK0= 346 RAS=0x61
  ...                         <- plynule +1 za sloupec
Col[16] CLK0= 586 RAS=0x70
Col[17] CLK0= 602 RAS=0x71   <- posledni sloupec s SOF=0
Col[18] CLK0= 618 RAS=0x9A   *** SKOK o 41 (0x71 -> 0x9A) ***
Col[19] CLK0= 634 RAS=0x9B
  ...                         <- opet plynule +1
Col[39] CLK0= 954 RAS=0xAF

Analýza

SOF změna se projevila na Col[18], CLK0=618 — to je první sloupec, jehoz DRAM fetch zacal po dokonceni io_write.

Časování: - io_write zahajena: CLK0=600 - io_write trvá: ~18-20 CLK0 (3 CPU takty + hold) - Col[17] fetch: CLK0=602 (zacal před dokoncenim io_write → SOF=0) - Col[18] fetch: CLK0=618 (zacal po dokonceni io_write → SOF=5)

Skok v RAS: 0x71 → 0x9A = +41 = +0x29. Toto je konzistentni se SOF posunem o 5 jednotek (kazda = 8 bajtů) v DRAM adresnim prostoru (0x28 = 40 + korekce za aktualni pozici sloupce).

Následující řádky

Po změně SOF uprostřed řádku jsou následující řádky plynule:

Radek +1: RAS 0xD8-0xFF (plynule, 40 sloupcu)
Radek +2: RAS 0x28-0x4F (plynule, 40 sloupcu)
Radek +3: RAS 0x78-0x9F (plynule, 40 sloupcu)

Žádné diskontinuity — SOF je stabilne pouzivany od okamziku zápisu.

Vizuální dopad

Změna během blanking (bezpečná)

Pokud se SOF mění během HBLN blanking (CLK0 957-329), celý následující řádek používá novy SOF. Toto je bezpecny způsob změny scrollu — bez vizualnich artefaktu.

Bezpečné okno: ~508 CLK0 (~28.6 us, ~101 T-stavu CPU).

Změna během visible (torn line)

Pokud se SOF mění během viditelné oblasti, dojde k torn line: - Sloupce před změnou: stare VRAM adresy (SOF=0) - Sloupce po změně: nove VRAM adresy (SOF=5) - Vizuálně: řádek zobrazuje data ze dvou různých pozic VRAM

Col 0 ---- Col 17 | Col 18 ---- Col 39
  SOF=0 data      |   SOF=5 data
  (stary scroll)  |   (novy scroll)

Toto je analogie "torn frame" efektu znameho z modernich GPU, ale na úrovni jednoho řádku.

Registr CF01H vs CF02H

SOF se sklada ze dvou registru: - CF01H (SOF-L): dolnich 8 bitu - CF02H (SOF-H): horní 2 bity

Každý zápis se projeví okamžitě a nezavisle. Pokud software mění SOF po castech (CF01H, pak CF02H), mezi obema zápisy existuje kratke okno (~20 CLK0), kde SOF ma nekonzistentni hodnotu (novy SOF-L, stary SOF-H). Pro vetsinu operaci to není problem (změna o 1-2 řádky mění jen SOF-L), ale velke skoky (změna SOF-H) by mely byt provadeny během blanking.

Porovnání s paletou a borderem

Registr Port Delay Mid-line? Mechanismus
Paleta F0H 10-14 CLK0 Ano F601 latch -> NAND mux -> F666 FF
Border CF06H 6 CLK0 Ano Latch -> RBGI MUX -> F666 FF
SOF-L CF01H ~18 CLK0 Ano Latch -> DRAM addr generace
SOF-H CF02H ~18 CLK0 Ano Latch -> DRAM addr generace

Všechny I/O registry se propagovany okamžitě — GDG nepoužívá žádný "double-buffering" nebo "latch at line start" mechanismus.

Nedokumentované DMD režimy

SOF propagace je nezávislá na konkretnim DMD režimu — SOF se podílí na generování DRAM adresy (RAS) a všechny grafické režimy (DMD3=0) používají stejný mechanismus.

Nedokumentované režimy DMD=0x03 a DMD=0x07 mají stejnou SOF propagaci jako jejich oficialni protejsky (320x200 resp. 640x200). Mid-scanline torn line efekt nastává stejným způsobem.

Pro MZ-700 režimy (DMD=0x08-0x0F včetně 0x0C-0x0F) je SOF také platný — posuva základní adresu text/color RAM v DRAM.

Stav ověření

Simulace (HDL): Všechny hodnoty pochází z gate-level simulace (GDG_core.vhd + cocotb testbench test_iorq_propagation.py).

Ověřeno: - SOF=0 vs SOF=5: DRAM adresy se liší (RAS posun ~0x40, ČAS odlišně) - SOF-H: zápis CF02H se projevuje v adresach - Mid-line změna: diskontinuita v RAS sekvenci na Col[18] (CLK0=618) po io_write zahajene na CLK0=600 - Následující řádky po změně: plynule (žádné diskontinuity) - 3 po sobe jdouci řádky s SOF=0 a SOF=5 zaznamenany a porovnany

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