Signál nWTGD (pin 93) je open-drain výstup GDG pro Z80 /WAIT pin. Když je aktivní (low), CPU vloží Tw stavy a čeká.
GDG.vhd: nWTGD <= s_WTGD when (s_WTGD = '0') else 'Z'
Polarita: 0 = WAIT aktivní (CPU čeká), 'Z' = neaktivní (CPU běží).
WAIT se generuje pouze pro přístupy na adresy 0xC000–0xDFFF (character RAM + color RAM). Přístupy na jiné adresy WAIT nevyvolávají.
GDG implementuje jednoduchý mechanismus kontence VRAM přístupu:
READ a WRITE se chovaji symetricky — není žádný rozdíl v tom, zda první přístup je čtení nebo zápis.
CLK0: 0 335 975 1136
| | | |
| blanking | visible (640 CLK0) | blanking |
| | | |
WAIT: | neaktivni | 1. pristup: free | neaktivni |
| | 2.+ pristup: WAIT-->| |
| | | |
FF: | v resetu | | FF reset |
Všechny čtyři kombinace R/W se chovaji identický:
| Test | 1. přístup | 2. přístup |
|---|---|---|
| READ, READ | wait=0 | wait=21 TW |
| WRITE, WRITE | wait=0 | wait=21 TW |
| READ, WRITE | wait=0 | wait=21 TW |
| WRITE, READ | wait=0 | wait=21 TW |
Počet Tw stavu u 2.+ přístupu závisí na pozici v řádku — CPU čeká od okamziku přístupu až do CLK0 ≈ 975 (HBLN blank boundary):
| Pozice přístupu (CLK0) | Priblizny počet Tw |
|---|---|
| 400 | ~115 |
| 500 | ~95 |
| 800 | ~35 |
| 900 | ~15 |
Systém bezel 50+ řádku bez VRAM přístupu. Na každém z 10 následujících řádku proveden jeden READ na CLK0~500:
Důvod je v časování flip-flopu.
WAIT FF (xF645_141_12) se taktuje pouze na CPU rising edge (T2r). Detekci FF se ale nastaví až po T2r (s propagacnim zpozdenim). Z80 vzorkuje /WAIT na T2f (sestupna hrana T2). V tu chvili WAIT FF ještě drzi starou hodnotu.
Podrobny průběh pro první READ na řádku:
Faze | nRD | nMREQ | RD_FF.O | NAND | nWTGD | Poznamka
----------|-----|-------|---------|------|-------|--------
init | 1 | 1 | 1 | 0 | 1 | FF v resetu
T1r | 1 | 1 | 1 | 0 | 1 | adresa na sbernici
T1f | 1 | 0 | 1 | 0 | 1 | nMREQ aktivni
T2r | - | - | - | - | - | WAIT FF zachyti D=0 (stary stav!)
T2r+1ns | 0 | 0 | 0 | 1 | 1 | nRD padl -> READ FF se nastavi
T2f | 0 | 0 | 0 | 1 | 1 | Z80 vzorkuje: nWTGD=1 -> BEZ WAIT
T3r | 0 | 0 | 0 | 1 | 1 | WAIT FF konecne zachyti NAND=1
T3f | 1 | 1 | 0 | 1 | 0 | nWTGD=0, ale cyklus uz skoncil
READ FF se nastaví 1ns po T2r — NAND okamžitě stoupne na 1. Ale WAIT FF uz byl taktovan na T2r a zachytil D=0. Na T3r WAIT FF konecne zachyti NAND=1 a nWTGD spadne na 0. Z80 ale /WAIT kontroluje při T2f, což je před T3r — takže tento přístup projde free.
Pro WRITE je princip stejný: WRITE FF (F635) se nastavuje na sestupne hrane nCLK, což odpovídá okamziku kdy nWR stoupne zpet na 1 (T3f) — tedy až po skonceni cyklů.
| Signál | Visible start | Blank start | Šířka |
|---|---|---|---|
| HBLN | CLK0=335 | CLK0=975 | 640 CLK0 |
| WAIT FF reset | — | CLK0 ≈ 975 | — |
Detekci FF se resetuji na HBLN visible->blank přechodu (přetečení COLUMN čítače). WAIT se uvolní ve stejnem okamziku jako konci HBLN visible.
WAIT není automaticky aktivní během celé visible oblasti — aktivuje se teprve VRAM přístupem. První přístup armuje latch, druhý a další jsou penalizovany až do konce visible.
READ detect FF (xF615_141_13, radek 5760):
D = '1'
CLK = i_nRD NOR net_F302_30_5_out (rising edge = nRD padne)
nRES = net_F312_114_13_out
O = net_F302_140_13_in1
POZOR: F615 ma invertovane vystupy! O = NOT(O_DUMMY)
WRITE detect FF (xF635_81_20, radek 4119):
D = '1'
nCLK = net_F302_30_5_out NOR i_nWR (falling edge = nWR stoupne)
nRES = net_F312_94_20_out
nO = net_F312_77_18_in1
NAND brana (radek 5769):
net_F302_140_13_out = READ_FF.O NAND WRITE_FF.nO
WAIT vystupni FF (xF645_141_12, radek 5938):
D = net_F302_140_13_out
CLK = i_CPU (pri TEST='0')
nRES = net_F312_50_11_out
nO = o_nWTGD
S ohledem na invertované výstupy F615:
| Stav | READ_FF O_DUMMY | READ_FF.O | WRITE_FF O_DUMMY | WRITE_FF.nO | NAND | Význam |
|---|---|---|---|---|---|---|
| Oba v resetu | 0 | 1 | 0 | 1 | 0 | WAIT neaktivní |
| Po READ | 1 | 0 | 0 | 1 | 1 | WAIT aktivní |
| Po WRITE | 0 | 1 | 1 | 0 | 1 | WAIT aktivní |
| Po obou | 1 | 0 | 1 | 0 | 1 | WAIT aktivní |
WAIT je neaktivní pouze když oba FF jsou v resetu. Jakmile je nastaven kterykoli z nich, NAND = 1 -> WAIT aktivní.
net_F302_30_5_out = net_F101_30_4_out NAND net_F100_1_5_in
net_F101_30_4_out = NOT(i_nRFSH NAND NOT(i_nMREQ))
= '1' kdyz nMREQ='0' a nRFSH='1' (normalni pamet. cyklus, ne RFSH)
net_F100_1_5_in = adresovy dekoder (NAND4, radek 6583)
= '1' kdyz adresa v VRAM rozsahu (zavisi na DMD(3))
Vysledek: net_F302_30_5_out = '0' kdyz je detekovany VRAM pristup
Oba FF sdileji spolecnou část resetovaciho signálu — bufferovany RST0 (net_F312_50_11_in2, řádek 6081). Krome toho ma každý vlastní podminkovou část:
READ FF reset:
nRES = RST0_buf AND (xF635_141_14.nO OR NOT(net_F100_122_14_in))
Resetuje se když xF635_141_14 zachyti urcitou hodnotu a zároveň net_F100_122_14_in (odvozeny od video timing signálu) je '1'.
WRITE FF reset:
nRES = xF635_81_18.nO AND RST0_buf
xF635_81_18 je taktovany signálem odvozenym od nVRWR (VRAM write strobe).
Mereno ze simulace: - Oba FF se resetuji na CLK0 ≈ 975 (HBLN visible->blank hranice) - Reset pulz je kratky (~10 CLK0) - Po resetu zustavaji FF v resetu až do dalšího VRAM přístupu
Blackbox pozorovani na HW ukazalo: 1. READ "vždy" dostava WAIT během canvas 2. WRITE: první prochazi free, další dostavaji WAIT
Simulace ukazuje symetricke chování (první free pro R i W).
Možná vysvětlení rozdílu:
Typické použití: Z80 instrukce často provádí READ+WRITE par (LDIR, LD (HL),r, INC (HL) atd.). První READ projde free, nasledny WRITE dostane WAIT. Zvenku to vypada jako "READ způsobí WAIT", ale ve skutečnosti až druhý přístup je penalizovany.
Rozlišení měření: S logickym analyzatorem je tezke odlisit "první free, druhý waited" od "vždy waited", pokud software provádí vice VRAM přístupu na řádku.
Race condition: READ FF se nastaví 1ns po T2r. Na realnem hardware s analogovymi zpozdenimi hradel by se mohl WAIT stihnout zachytit ještě v témže T2 cyklů — to by ale vyzadovalo rychlejsi cestu do WAIT FF než přes cistu CPU rising edge.
Simulace (HDL): První přístup na řádku projde bez WAIT, symetricky pro READ i WRITE. Toto chování je konzistentni s gate-level netlistem (WAIT FF taktovany CPU rising edge nemá čas zachytit změnu NAND v ramci tehoz T2 cyklů).
Reálně HW: Ještě neověřeno. Planovano proverit logickym analyzatorem na skutecnem MZ-800 — zejména zda první READ skutečně projde free, nebo zda analogove zpozdeni v realnem chipu způsobí zachyceni WAIT ještě v témže cyklů.
| Vlastnost | Hodnota |
|---|---|
| Pin | 93 (nWTGD), open-drain |
| Polarita | 0=WAIT aktivní, Z=neaktivní |
| Adresový rozsah (MZ-700) | 0xC000–0xDFFF |
| První přístup na řádku | bez WAIT (R i W symetricky) — viz Stav ověření |
| Další přístupy na řádku | WAIT až do HBLN blank (~CLK0 975) |
| FF reset | Na HBLN visible->blank přechodu |
| WAIT FF clock | i_CPU (rising edge) |
| Vliv DMD na adresový rozsah | Ještě netestovano pro MZ-800 režimy |