Pentagon 2.666LE (часть 2)
12xi
Чистил лишние клоки.
Ещё расставлял _n для сигналов с инверсной логикой.
Читал документацию на Quartus.
Настроил в TimeQuest Timing Analyzer требование Fmax = 65 MHz, оптимизировал (вывел do из процессора), была сборка на 65 МГц, но глючная, лучшая рабочая - на 63, и та нестабильная.
Начал делать точки останова и пошаговое исполнение. Они будут замораживать процессор на T2 (адрес выставлен в начале T1, за время T1 его можно проверить, а на следующем такте не дать клок). Останавливает, а при попытке продолжения сбивается.
13xi
Читал документацию на Verilog:
- не вижу, как указать общий файл настроек для if/ifdef (
`include "defs.v"не работает в ModelSim) - влияют ли настройки module path declarations на синтез в Quartus?
- поддерживается ли
$timeskew,$fullskewв Quartus?
Читал документацию на память. /WE надо держать 7 нс. Данные при записи можно держать от 5 нс до конца /WE, дальше не надо (допустимая задержка 0). Память переводит данные в Z-состояние по /OE=1 или /WE=0 за 5 нс (так что конфликт есть, если явно не указать задержку данных, а её в проекте нет). При чтении от адреса до валидных данных 10 нс.
Убирал ещё клоки (осталось 7 из 46).
Ограничил использование i2c_start_condition_n (слишком короткий импульс). Работает нестабильно.
14xi
Выдал данные на ОЗУ только во втором полутакте. 65 МГц, нестабильно.
Вывел из самого процессора virt_cpu_memwr_n, завязал запись на него. Работает нестабильно.
Ограничил зависимости от i2c_command_strobe и i2c_data_strobe.
Ускорил заливку прошивки (I2C ногодрыганием).
Добавил показ номера загружаемой страницы ПЗУ на бордере.
15xi
Делаю синхронность i2c уже от dvixel_clock. Иногда пропадают начальные биты (вместо них 0).
В одной сборке изредка пропускаются биты (даже при автоматическом обмене) - хотя асинхронность осталась только при передаче от FPGA.
Мешает ответ ack от FPGA. Без него грузится стабильно даже без дополнительных задержек в ARM (но дальше виснет, т.к. автоматические обмены без него не работают), но с ним вообще никак.
Собрал условно стабильную версию (запускается не всегда) с единственным клоком dvixel_clock, условно стабильна одна сборка из 4.
18xi
Добавил Alt=Caps Shift+Symbol Shift, как на Sprinter, ZX Evo и в UnrealSpeccy.
Сделал при битой CMOS памяти запись настроек памяти и скорости по умолчанию.
Сделал выдачу данных на память по shifted_dvixel_clock (сдвинуто на 3.65 нс). В cmos setup стрелки срабатывают как старые нажатия, иногда загружается с глючным видеоконтроллером.
Сделал в видеоконтроллере чтение по shifted_dvixel_clock. Не помогло.
Сделал запись по (ramwrdataenable = '1' and ramwrdataenable_shifted = '1') и вернул как было. Стало лучше.
Возможно, dvixel_clock и shifted_dvixel_clock инициализируются разными числами при заливке из Keil и по включению.
Переделал на одну фазу, вернул запись по ramwrdataenable_shifted. Видеоконтроллер работает. Но мышка работает только при заливке из Keil. NedoOS не грузится (висит на a979 во время mount M - он вообще не должен туда попадать). В другой раз завис на 61ba. в другой раз не загрузилось ПЗУ даже из Keil.
Вернул включение процессора только после старта мышки - не помогло.
Сделал в точках останова run и one step. Работает, но в момент ловли точки останова некоторые точки (6,c,e) разблокируются (было только один раз, в другой сборке не было).
Нельзя было сделать one step, не ставя точку останова - исправил. Сборка на 68 МГц, стабильная.
Почему-то надо несколько раз нажимать run, чтобы продолжить.
Иногда останавливается не с той адресной шиной (52, 6c0e), хотя адрес PC правильный (6c0d). 6c0d=halt, по идее больше ничего не должно светиться. Остановка всегда должна быть на M1 T2.
Исправил virt_cpu_am1. починилось.
19xi
Исправил чтение памяти, но иногда не читает (например, на командах ld (),hl (после inc hl), push bc (после inc (iy+)), dec l (после успешного jr z), in a,(c) (после успешного jr c)).
Исправил promisenomreq. Постоянное нечтение исправилось, но иногда всё равно не прочитывает какой-нибудь адрес.
Сдвигал shifted_clock на разные наносекунды, не помогло
Иногда кривые обмены по I2C. Иногда ARM виснет с get_data_flag!=0. Если убрать проверку на get_data_flag: почему-то send_data_flag получилось равным 2, что привело к зависанию.
Убрал чтение ОЗУ, чтобы сравнить. Частично работает, не работает Borsch на 57.
Глюки I2C только в середине работы, где частота низкая - от неправильного времени выставления ack? Попробовал сделать по состоянию scl=0 на 8-м бите - обмены не работают. Сделал выставление ack по задним фронтам scl. ПЗУ не зашивается, но обмен работает. Сделал универсально - переключение режима по команде. 57 один раз зависло в фаталле.
Вернул синхронную работу с ОЗУ без смещения - стабильно несколько сборок.
Читает данные процессора, а не по заданному адресу. Исправил. Перестало работать 57.
20xi
Чтение после last_tstate = '1' вообще не работает, (promisenomreq = '1' and last_tstate = '0') не работает на 57.
dinst используется только в tstate[2], но другие случаи использования di - в любом такте (хотя по идее это di_reg, который защёлкивается в tstate[2]). Сделал тоже в 2 - вообще не работает. Сделал чтение только в M1 - не помогло (и зависает обмен).
Чтение только в первом такте M1 (запрос в последнем такте команды) - не помогло.
Чтение только в последнем такте M1 (запрос в 3-м такте) - не происходит (m1_n стоит только 2 такта). Исправил. Теперь не читает во время останова (т.к. стоим на tstate[2] - адрес был известен на tstate[1]). Исправил - теперь запрос можно и во 2-м такте M1. Вообще не работает и не всегда помогает во время останова. Останавливать позже нельзя - потом нельзя будет поменять команду или переставить PC. Сделал только 3-й такт M1 или breakpoint_event. Работает, но почему-то иногда не прочитывает отдельные байты даже во время breakpoint_event!
Добавляю дизасм из UnrealSpeccy. stdio.h нельзя добавить - нет места. Заменил sprintf на костыли.
Убрал string.h, заменил на несколько маленьких функций - не
хватает именно ОЗУ (504 KB flash, 32 KB RAM). Сделал много const — собралось.
Проблемы были с несовместимостью знаков char, шириной short (из-за этого адреса печатались не полностью).
Отвалилась запись на диск. Починил — ВГ93 приоритетнее дебагера.
Borsch и noise при шагании вылетают (а Gluk нет — потому что он не на 57 МГц? да, при 28 МГц они трассируются нормально).
Пробую без чтения памяти при шагании — всё равно вылетает (не выдан запрос на чтение памяти для процессора?).
По идее надо при старте из брякпоинта сделать запрос памяти для процессора в T2, причём в такте запроса от процессора (пока процессор не активен), на следующем такте (тоже T2, но уже такт ответа) он может читать свои данные. То есть процессор должен проснуться, когда идёт такт ответа, иначе он прочитает данные видеоконтроллера. Значит, надо снять breakpoint_event, когда идёт такт запроса от процессора (по идее с текущим процессором запрос выдастся сам, но при изменениях возможны глюки). Значит, kill_breakpoint_event должен быть готов, когда идёт такт ответа (cpuram_flag = '1'). Попробовал вместо этого сделать 28 МГц во время breakpoint_event (он не снимается при шагании, но активен во время шагания. надо проверить ещё момент снятия. Сейчас в этот момент запрос дебагера не выдаётся, потому что прошло время от одной команды из ARM до другой). Работает.
21xi
Как частота I2C влияет на первичную инициализацию мыши? до неё transmit_cmos_data, где есть ожидание получения.
Перенёс transmit_cmos_data после инициализации мыши — не помогло (висит на 1-м байте, пересброс мыши работает).
Перенёс i2c_setup после инициализации мыши — помогло (хотя во время инициализации мыши обмен по i2c и так не идёт!).
Добавил показ предыдущего PC.
Добавил смену PC — сразу стало опять не всегда читать на всех частотах (сборка на 64). И отваливается обмен по i2c.
Сделал blk0_d(7 downto 0) <= ramwrdata(7 downto 0) when (ramwrdataenable = '1') else (others => 'Z'); и т.п. — стало лучше, но не совсем. 57 нестабильно.
Сделал blk0_d(7 downto 0) <= ramwrdata(7 downto 0) when (ramwrdataenable = '1' and ram_reading = '0') else (others => 'Z'); и т.п. — так читает всегда, кроме момента записи PC.
PC не обновляется сразу. сделал ручную запись PC приоритетнее всех других записей PC — не помогло. Добавил запись в PC отладчика (обычно туда пишется по началу M1) во время смены PC — получилась нестабильная сборка (i2c, чтение). другой seed — тоже.
Сделал на полтакта: blk0_d(7 downto 0) <= ramwrdata(7 downto 0) when (ramwrdataenable = '1' and ramwrdataenable_shifted = '1') else (others => 'Z'); — так всегда читает.
NGS работает, но The Link не работает на 28 (показывает картинку, потом чёрный экран). на 3.5 и 7 (реально само переключает) работает, но виснет на брусках с глюками. После этого ещё плохо сбрасывается или вообще не сбрасывается (из-за несброса NGS, он остаётся в состоянии подмены ПЗУ). В версии с github тоже.
Возможно, не успевает DMA в NGSе. В этом эффекте используется развёрнутый цикл pop hl:ld (hl),d (GSBAR24.H позиция курсора #2BDD), развёрнутый цикл pop af;pop hl:ld (hl),a (позиция курсора #2EF8) и развёрнутый цикл pop de;pop hl:ld (hl),d:dec h:ld (hl),e (позиция курсора #2FCC).
22xi
С воткнутым NGS не работает на 57 МГц ни в одной версии, начиная с p2666_megaturbo.zip
Сделал iorq_after_bus_n <= virt_cpu_iorq_n. 57 МГц не вылечилось.
Убрал чтение внешней памяти (из ZX-BUS). Попробовал не выдавать mreq на внешнюю шину. Не помогло. Пробовал не выдавать rd, wr, iorq — не помогло. Если не выдавать csr (/CS ROM) — процессор читает нопы. [выборка ПЗУ /csr_out=romaccess_n (из FPGA) -(резистор)-> /bus_rdrom (подменяется платами) -(резистор)-> /rdrom_in (в FPGA)] Удивительно, что эта цепочка вообще работает на 57 МГц без воткнутых плат. Сделал (virt_cpu_memrd_n='0' and romaccess_n='0' and fpga_rdrom_input='1' and cpu_speed(1)='0'), остальные защиты убрал — помогло. То есть дело не в иголке по rdrom, а в том, что собственный rdrom просто не успевает вернуться через всю плату за такт.
На 57 МГц с NGS не работают NedoOS (виснет после монтирования SD-Card — может быть, обращается к NGS?) и Fatall (сразу вываливается с глюками на экране). [выбор страницы ПЗУ rs_out (из FPGA) -(резистор)-> bus_rs (подменяется платами) -(резистор)-> rs_in (в FPGA)] сделал romselect <= fpga_rs_in when portxx77(3)='0' else port7ffd(4) — не помогло (если вынуть NGS — работает).
Сделал торможение до 28 и даже 7 МГц в iocycle — не помогло (в Fatall тоже), так виснет и внутри NedoOS. Убрал выдачу rd,wr,mreq,iorq на 57 МГц. Даже без этих сигналов с NGS не работает.
Сделал невыдачу rd,wr,mreq,iorq,rfsh,halt,busack,m1 при 57 МГц. Fatall заработал. NedoOS зависло на loading term.com, в другой раз ещё раньше, в третий снова на loading term.com, в четвёртый дошло до очистки экрана. Сделал невыдачу dos при 57 МГц, но восстановил rfsh, halt, busack. Дошло до показа курсора.
gstest на 28 работает.
Не были подключены внешние int и wait — исправил (хотя wait в TV80 выглядит подозрительно).
Нельзя останавливаться после префикса команды! иначе он сработает на новой команде! Исправил.
Процессор сразу переходит к следующему адресу или вообще случайному — считывает команду, которая была до останова. Надо дать время прочитать команду перед шаганием? (захватывается в IR в T2 из D). breakpoint_event вычисляется в T1. в T2 его используют для cen, в это время происходит переход на T3. То есть процессор заморожен на T3. Разморозка происходит при cpuram=1 (чтение ОЗУ для Z80). Сделал T1 по inbreak (хотя это костыль, и он будет опасен при будущем переносе вычислений в T1), подкорректировал шину адреса. стало лучше.
Добавил запись в память дебагером. Работает, но в некоторых сборках иногда пишет случайные числа, похожие на коды команд (которых нет на экране!)
25xi
KOE говорит, что у него не показывает с моей версией видеоконтроллера, хотя там из параметров развёртки изменено только положение ССИ и горизонтального гашения на 16 пикс (проверил, вставил старую логику — собралось 100% так же).
Проверил сигналы запроса памяти - все источники по переднему
фронту, кроме memrd_n_negedge, memwr_n_negedge.
memrd должен быть уже готов в Т1, чтобы было чтение в Т2!
Проверил, что чтение из di только в T2 (по posedge).
26xi
Наконец сделал memrd,memwr по posedge, но memrd пришлось
добавить лишний такт. Всё равно работает на 57 нестабильно.
Сделал iorq,rd,wr по posedge (2 такта), но rd,wr пока только для
iorq (для mreq используются только memrd,memwr) - не помогло (и
NedoOS не работает на 57).
Не хватало данных первые полтакта - исправил. Не помогло.
Может быть, надо защёлкивать данные ОЗУ безусловно в
определённый момент перед логикой внутреннего защёлкивания в
процессоре? Но надо дать 10 нс на чтение, полтакта мало
(проверено)!
Пробовал сдвигать фазу чтения. Через PLL не получилось. Пробовал
через negedge pixel_clock (за 4.4 нс до конца такта) - читает
нестабильно.
Пробовал при этом полный такт записи - всё равно читает
нестабильно (особенно D0). И некоторые сборки не работают.
В авторской версии момент чтения был вообще через 4.4 нс после
конца такта (т.е. после окончания OE). Но так не получится
защёлкнуть данные в Т2, а там по дороге ещё мукс ШД.
Поставил ограничение времени "Input delay from pin to internal
cells" 4 от blk0_d[], blk1_d[] до IR и DI_Reg - Fitter
проигнорировал. поставил IR[0] и т.д. Fitter проигнорировал.
Поставил blk0_d[0] и т.д. Fitter проигнорировал. В документации
есть намёки, что это в пикосекундах, поставил 4000. Теперь
пишет, что надо от 0 до 6, проигнорировал почти все (но не
все!). Или это число промежуточных ячеек? Поставил 0, но какой в
этом смысл? Не помогло.
Надо вставлять в сам процессор задержанный на 90 градусов клок
специально для записи в IR и DI_Reg?
27xi
Задержал на 90 градусов запись из ОЗУ в DI_Reg (это касается и
данных от портов!). NedoOS не работает на 57 с NGS (без него
работает).
Задержал на 90 градусов запись из ОЗУ в IR (текущая инструкция).
Всё сломалось - постоянно выполняет какие-то 3-байтные команды.
Попробовал так же упростить логику IR без задержанного клока.
Всё так же сломано, и память в дебагере стала читаться
нестабильно. Добавил задержку на 90 градусов для дебагера.
Читает стабильно, но процессор глючит (иногда только успевает
вывести цветовую таблицу).
Исправил выбор читаемой микросхемы ram_blk на wasram_blk (т.к.
уже начало T3) - всё равно глючит.
Сделал безусловную буферизацию данных ОЗУ по posedge
dvixel_clock, потом использование в других местах (4.4 нс до
использования) - всё равно глючит.
Убрал все ограничения на ram, были варнинги - не помогло,
видеоконтроллер стал читать нестабильно
Вернул часть ограничений (Fast Output Register, Fast Output
Enable Register, Speed Optimization Technique) - дебагер и
видеоконтроллер исправились, процессор нет.
Поставил 28 МГц изначально, убрал Fast Output Enable Register
(его Fitter игнорирует) и вернул DQS Frequency (зачем, если это
не DDR?). На 28 тоже не работает. Убрал override_ram - на 28
валится в бейсик (стабильный), иногда без сброса бейсика
(продолжает редактировать ту же строку после двукратного F12),
хотя кнопки на сбросе работают, только все соответствующие опции
глючат.
Сделал мукс ШД по virt_cpu_memrdresult_n (такт сразу после
истинного T2). memrd и memwr сделал по posedge и ровно на один
такт перед истинным T2 (т.е. с cen). Всё чтение завязано на
истинный T2 (время работы ОЗУ на процессор). Читает FF.
Переписал promisemreq (rd: перед истинным T2, wr: перед истинным
T3) - не помогло.
Убирал IOWait (растягивает T1 в iocycle) - не помогло.
В ModelSim всё работает, хотя в сигналах иголки!
Попробовал постоянные 57 МГц (так нет иголок) - помогло.
Попробовал постоянные 28 МГц - читает FF. В ModelSim тоже не
работает. Нашёл повторный IR_change, убрал. В ModelSim
заработало, в ПЛИС заработало.
Убрал тест, пересобрал с реальным ОЗУ - в начале ПЗУ что-то
исполняет, но в память почти не пишет, в дебагер редко прилетают
числa.
Вернул чтение в дебагере (override_ram) и переключение 57/28 МГц
по ресету. Что-то пишет в экран, но мало.
28xi
Заменил promisetrueT2/3 (с учётом сложного promisecen) на более
простой promiseT2/3 (теперь один такт запроса не гарантируется,
могут быть запросы в мёртвых тактах) - работает NedoOS, но br не
грузится на 57 (без NGS грузится). Иногда виснет при старте
NedoOS после "ZXNetUsb not found".
Заменил в муксе данных do процессора write_buf_negedge на
write_buf_posedge. NedoOS не грузится на 57 (виснет перед
монтированием SD-карты или после loading term.com или после
очистки экрана) (без NGS всё нормально).
Включил отладочные iorq,rd,wr по posedge (T2+T3) - вообще не
работает (сбой на 0001 ex af,af' (08 d9 c3...) - попадает на
ffdc). Как будто данные не успевают к дешифрации команды -
Quartus не проверяет, когда они от разных, но связанных клоков?
Стало понятно, почему работали некоторые старые сборки, а
некоторые не работали - в некоторых случаях мукс ШД успевал за
6.3 нс внутри такта ОЗУ (само ОЗУ = 8-10 нс), но там ещё была
логика защёлки в процессоре. Общая сумма не должна превышать
17.54 нс. А в авторских версиях мегамукс ШД+защёлка в процессоре
успевали за 13.1+17.54 нс (т.к. 28.5 МГц).
Вернул простые memwr, promisemreq, memrd по negedge - работает.
Упростил memrd_n_negedge - только в T1 (раньше требовалось ещё
T2, т.к. входной мукс ШД процессора был по memrd) - работает
Упростил мукс ШД через ideportfound - работает
Упростил portfound (addr_bff7, убрал ebl в ненужных местах).
Упростил мукс ШД через wasrdromaccess_n и убирание iord во
внутренних портах (приоритет теперь у внутренних портов) -
работает, но сломались младшие биты палитры (r,g всегда в 0 -
яркие).
Переставил условия - теперь данные из ZX-BUS приходят всегда по
умолчанию (приоритет у внутренних портов, память не
перехватывается) - мукс ШД уже влезает в 6 нс. поменял на 5 нс.
Не работает jp. Показывает самое долгое m1 и write_buf_posedge,
потому что они по posedge (остаётся всего 5 нс на логику с ними
в муксе ШД).
Вернул write_buf_negedege. Не работает jp. Не успевают.
сформироваться сами rd, wr и т.п. по negedge — им нужно 7 нс, а есть только (17.54/2)-5.11 = 3.66 нс.
Переставил условия (не читалось ОЗУ). Сделал wasram_blk по negedge. Влезло в 5 нс (тормознее всего portfound), но ещё есть 64 ошибки в дешифраторе. Работает с глючными младшими битами палитры и не играет AY.
Сделал 4 нс и portfound по negedge shifted_dvixel_clock (4.4 нс после negedge dvixel_clock, остаётся 4.4 нс до нового такта dvixel_clock) — не успевает. AY играет, но фальшивит.
Сделал portfound по задержанным (posedge dvixel_clock) rd, wr, dos, убрал ebl — то же самое, сломалась запись в дебагере.
Сделал portfound и защёлку в видеоконтроллере по negedge dvixel_clock — то же самое, запись в дебагере работает.
Сделал сборку port_rd_data частично через and, а не мукс — теперь тормозят другие сигналы, term.com not found. Запись в дебагере сломана.
Упростил сигнал направления данных на ZX-BUS до virt_cpu_wr_n. В муксе ШД не успевают iorq_rd_set (используется в rd?) и memrdresult_n. term.com not found.
Сделал memrdresult_n по negedge dvixel_clock. Упростил до минимума iorq, mreq, rd, wr — все по negedge. Мукс ШД почти успевает. SD-карта не работает, дисковод тоже, снег на "go sleep". Чтение, запись в дебагере работают.
Видно обратную связь:
do -> IR (do -> virt_cpu_d (в write_buf_negedge) -> fpga_d (в virt_cpu_wr_n=1) -> virt_cpu_d (в virt_cpu_rd_n=0) -> dinst (безусловно) -> IR (условная защёлка по lateclk))
Поэтому переделал мукс ШД по virt_cpu_wr_n. Не помогло.
Сделал чтение buf_fpga_d вместо fpga_d — стало лучше, мукс ШД влезает в 3.835 нс.
Сделал do тоже в wr (а не в write_buf_negedge) — когда-то так и было. На shifted_dvixel_clock оставил 3.65 нс — когда-то так и было. Не успевает, сломалась запись в дебагере.
Переделал write (можно и iorq, no_read так же) на регистр через promisewrite. Был мукс в дешифраторе. Чтобы его начать с T1 (используем уже в negedge dvixel_clock в T1), установил его в истинном last_tstate. Gluk работает, но gluk boot не запускает, TR-DOS глючит. Кнопки по сбросу работают только D и тест клавиатуры (почему-то по любой одной клавише из оставшихся). Вход в тест клавиатуры всегда — где-то запорот CY (601f: jp c,61d2=TSTKEY).
Нашёл один глюк с promisewrite в push. Сделал iorq_r через promiseiorq. Починился глюк с тестом клавы и запуском в Gluk boot, но 3D движок не работает (не работает даже print "a", print 2, list 11 (сам по себе показывает), randomize usr 15616, хотя в TR-DOS можно смотреть LIST), а Fatall показывает курсор не там.
В tv80_core заменил iorq_i на iorq_r для скорости. Дешифратор успевает, а для мукса ШД не хватает 0.896 нс (на один из битов обратной связи, которая не нужна). Те же глюки. Работает doctor (на D:), CMOS Setup, C, D, help, tstkey.
Вернул сложные rd, wr, iorq, mreq — палитра не починилась, но SD-карту видит (но не грузит NedoOS и не показывает панельки Fatall). Дешифратор успевает, а для мукса ШД не хватает 0.886 нс.
Убрал обратную связь — D работает как di в процессоре (так было в TV80). Теперь всё успевает.
Вернул в мукс ШД virt_cpu_iord_n = '0' (зависит от ZX-BUS!) на внутренние порты. Не хватает 1.127 нс на мукс ШД. Палитра исправилась. NedoOS не исправился, Fatall тоже, диск A работает.
Сделал вместо virt_cpu_iord_n = '0' просто virt_cpu_iorq_n = '0' для внутренних портов. Вернул медленный write. Палитра опять испортилась. NedoOS доходит до term.com not found.
Добавил and virt_cpu_rd_n = '0' для внутренних портов. Усилил дешифрацию портов бетадиска — перекрывали SD-card. Палитра OK, NedoOS OK. При воткнутом NGS: NedoOS не грузится на 57 и на 28, виснет до или после "Drive M mounted".
29xi
promisewrite неправильно работало во время тактов чтения индексного смещения. Исправил — Fatall и все опции сброса работают, бейсик и NedoOS нет (не включается текстовый режим, видно сообщения на графическом). AY и палитра использовали ШД, засорённую ZX-BUS, исправил на do.
Добавил вывод регистров, а также состояний процессора:
{1'b0,tstate[6:0], IntCycle,NMICycle,Prefix[1:0], IntE_FF2,IntE_FF1,IStatus[1:0]}.
Не сработало 128e: ld (iy+31),2. Разобрался, в каком порядке идут машинные циклы: 0,0,5,6,2 (1 пропускается — только в этой команде!). Исправил. Бейсик исправился. С NGS не грузится NedoOS и не работает Fatall. Без NGS нормально. Убрал защиту палитры по eff7[2], глюк палитры в KOT исчез.
Убираю сдвинутый клок из процессора и из защёлки данных процессора. Всё работает (AY играет нормально), но запись в дебагере глючит.
Ускорил сигнал dos_n, который по negedge (в портах достаточно задержанного wasdos_n) — с воткнутым NGS не грузит NedoOS даже на 28, Fatall работает. Сломана запись на A (иногда даже каталог глючный).
Переписал breakpoint_event по negedge. Сломалось чтение в дебагере — исправил. Сделал запись в дебагере в любом свободном такте во время breakpoint_event. F7 с лёту останавливается на T1 или T2. breakpoints останавливается всегда на T2. Запись на точке останова опять не работает (T2), при шагании работает (T1).
Забыл and tstate(1) — добавил. После останова в случайном месте шагает по машинным циклам команды. F9 тоже. При этом инкрементирует R. С NGS виснет при загрузке NedoOS: на 57 МГц всё время читает порт 0057, на 28 МГц всё время читает порт bb.
Добавил not(virt_cpu_m1_n) — почему-то firstm1_n формируется не только в M1. Убрал чтение ZX-BUS. Исправилось. На 57 МГц NedoOS не грузится с NGS (всё время читает порт 0057), на 28 грузится. Без NGS нормально.
Заменил направление ZX-BUS на write (чтобы данные были доступны не только в стробе, вдруг не успевают захватить), вернул чтение ШД ZX-BUS. Не помогло, на всех частотах крутится на bb даже без NGS.
Сделал полную дешифрацию портов бетадиска (пересекалось с 3b NGS?). Не помогло.
Вернул условия для внешних портов. Поставил параметры развёртки из новой версии авторских. Не помогло.
Инвертировал write, вставил новый видеоконтроллер — 57 NedoOS не грузится с NGS (висит на портах сдкарты), без него работает. 28 грузится и так, и так, тест NGS проходит.
Теперь работа с ОЗУ полностью синхронная (с этого момента все сборки стабильные), но ZX-BUS работает только на 28 МГц и ниже!
2xii
Убрал чтение ZX-BUS из ШД - на 57 NedoOS не грузится с NGS (висит на портах сдкарты).
Убрал iorq_after_bus - NedoOS грузится на 57.
Вернул шину данных при отсутствии iorq_after_bus - всё грузится, gstest проходит на 28, но висит на uploading test tune. Вернул сложную логику с приоритетом ZX-BUS над чтением ОЗУ и rdromaccess вместо wasrdromaccess. Не помогло. Сделал приоритет ZX-BUS над всем, как было (только iorq, rd буферизированы) - не помогло.
Глюксервис неправильно показывает стек (ожидал e=0 от удалённого цикла) - исправил.
Добавил Mode=FastZ80 (сокращённые растактовки процессора) в зависимости от megaturbo. Не работает (после ldir неправильный bc). Убрал в Mode=1 ограничение тактов в машинных циклах - запустился глюксервис со всеми утилитами, но Fatall и NedoOS вместо запуска пищат (через бейсик) и виснут на любой скорости.
Вернул сложную логику с приоритетом ZX-BUS над чтением ОЗУ и rdromaccess вместо wasrdromaccess - не помогло. Сделал приоритет ZX-BUS над всем, как было (только iorq, rd буферизированы) - не помогло. Вернул Mode как константу в alu и mcode - 50 МГц, не помогло. Явно важен порядок параметров в #, а внутри модулей прописаны только значения по умолчанию. Убрал везде из параметров, передаю как переменную - работает, в megaturbo 3168 dhrystones/s.
Добавил no_read в promisemreq - в megaturbo 3225 dhrystones/s (было 3097, на 28 МГц - 1694).
3xii
Set PC работает глючно, потому что надо переходить на T1 (чтобы выставлять адрес чтения). Пытался исправить, заодно заменил T1 в записи на tlatewrite - сборка на 57, зависло на ldir. Заменил T1 в чтении тоже и установил A вместе с PC - работает.
Ускорил no_read через рег.
В z80.com не работает клавиатура внутри (на 28 тоже. bit 0,c:jr z...), хотя работает во время сброса (комбинации опрашиваются через in a, порты через keymatrix, а там in r,(c), но в других прогах работает), сброс 6+8+0 иногда работает, но работает выход (1+3+5), отладчик (4+5) и снапшот (1+2+5). Это он просто виснет и работает на некоторых процах благодаря глюку ld a,i, исправил (заменил на halt).
Неправильно работают кнопки на cyrus 2 (только space правильно), там код из rst 0x38 бейсика, только вместо портов читает из keymatrix. Это не очищены системные переменные (работает после smb). Исправил (забил системные переменные 0xff).
4xii
Ускорил декодирование CB и ld (hl),n в core через регистры - gstest работает медленно, показывает память reported by boot: 255 pages, reported by 0x20: 0 bytes, виснет на uploading test tune (читает из bb). Второй раз быстро, reported by 0x20: 16711679 bytes, виснет на uploading test tune (читает из bb).
Ускорил inc/dec rp до 4 тактов в megaturbo - сборка на 57, в megaturbo 3263 dhrystones/s.
Ускорил все M1 до 4 тактов в megaturbo - на 57 не работает даже бейсик, на 28 глючит Borsch. Ускорил только в push и djnz - сборка на 60, то же. Ускорил только в push - сборка на 59, то же. Ускорил только в djnz - сборка на 59, работает. Ускорил int, ret cc, rst - сборка на 57, бейсик не работает. Убрал ускорение rst - сборка на 63, Borsch не работает и не грузится, br работает. Убрал ускорение int - сборка на 59, работает. У этих команд общее - что они пишут в стек (push, int, rst).
Ускорил outi(r) - сборка на 59, в megaturbo 3267 dhrystones/s, работает. Остались только push, rst, int, nmi.
IncDec16Moment_r <= ((tstate[1] && !mcycle[0]) ||
(tstate[3/*2*/] && mcycle[0])) && IncDec_16[2];
//for tstate[4/*3*/] ([2] in next mcycles)
переделал на tstate[2] && mcycle[0], как было до оптимизации процессора, чтобы 16-битные инкременты считались в T3, а не в T4 - не работает (крутится на ldir). IncDec_16 ещё не готово в T2! учёл его отдельно - не работает. Попробовал для скорости включить уже 4 такта на M1 всегда - сборка на 53, inc hl работает как inc bc (не успевает декодер?).
5xii
Вернул инкременты в Т4 M1, сделал отдельный DecrementedSP_r, который в T_Res по aDECSP копируется в A. aDECSP и безусловный DecrementedSP_r формируются в T3 (а вообще всегда). Не работает.
Сделал расчёт DecrementedSP_r в T3 - не работает (в 000a push bc старший байт (первый записываемый) не записался в память).
Вернул длительности этих команд. Не работает. Вернул aSP - работает. Сделал опять 4 такта в mode=1, aDECSP использует SP-1 и только в mode=1 - работает (3276 или 3280 dhrystones/s).
Вернул 3 такта в прочих машинных циклах в mode=1. megaturbo не работает (работает Gluk, D, тест клавы, но S не стирает курсор, nv не двигает курсор, dhrystone не работает) - ldir срабатывает как ldi.
Исправил так:
if (/*I_BC_BT_r*/I_BC || I_BT)
F[Flag_P] <= #1 IncDecP;
Теперь 3453 dhrystones/s - эквивалентная частота 58 МГц!
6xii
Добавил сигнал promisecpuram_flag (такт запроса, следующий — cpuram_flag), чтобы можно было делать сложный арбитр.
С NGS Fatall не работает на 28 (читает порт bb), хотя работает на 57. Вернул сложную ШД с внешним приоритетом, но без проверки iorq, rd на внутренних портах — не помогло, и gstest всё так же виснет на uploading test tune. Вернул простую ШД — не помогло.
9xii
Сделал для ZX-BUS данные с конца прошлого такта. Fatall на 28 не вылечился (читает порт bb), хотя на 57 работает.
Защёлкнул данные ZX-BUS с конца именно такта T2 (а то прошлый такт тоже был T3) — не помогло, gstest стал правильно показывать объём памяти.
Вернул работу ZX-BUS в 57 МГц — NedoOS стала грузиться на 57 с ZX-BUS, так что исправление было не напрасным. Fatall висит и на 28, и на 57.
Добавил защёлкивание rdrom по тому же принципу (по уму надо в середине T3, но сейчас нереально) — всё сломалось на 57 с NGS, а gstest не стал лучше. Сделал вместо защёлкивания (romaccess_n = '1' or fpga_rdrom_input='0') — Fatall висит и на 57.
Сделал (wasromaccess_n = '1' or fpga_rdrom_input='0') — то же.
может не работать, если rdrom только в стробе mreq, rd (заканчивается в середине Т3, а не в конце)
Судя по исходнику, работа gstest не должна зависеть от rdrom.
Чем же отличается uploading test tune от остальных операций?
только sendDat():
output(datareg, data);
dataread2 = 128;
while (dataread2 != 0)
{
dataread2 = (input(cmdreg) & 128);
}
В старых прошивках при хорошем исполнении из bb читались нули (или 01101110 после работы новой прошивки) (сейчас читается 00111110, а в процессе заливки держится 10111110). Раньше всё защёлкивалось на 4.4 нс позже конца T2. Иначе NGS не успевает отвечать? Но поставил всегда 3.5 МГц — ничего не изменилось.
Слишком долгий iorq? Нет, всё как было.
Что-то не так с записью в порт? do меняется в конце T1 (по идее надо в начале или в середине), для mreq тогда ещё не выдано wr, а для iorq выдано. Действительно надо wr на полную длительность iorq, для этого iorq придётся начать с конца T1. Так оно и есть по исходнику (в ModelSim процессор перестал работать).
Сделал dbus_oe по write (реально там используется fpga_dir: 1 из fpga, 0 в fpga). Не помогло.
Оказалось, был переименован сигнал fpga_dir! вернул — теперь всё время попадает в тест клавиатуры (хотя клавиши не нажаты, и сам тест работает адекватно).
Убрал подмену ПЗУ. Fatall не починился. На 57 стоит на 0001 xor a (после di), не шагает, только инкрементирует R. прерывания выключены (IM 1), при этом Halt_FF=1 (выставляется при Halt (IR[5:0] == 6'b110110 halt) в last_tstate. но мы не после halt! как такое может быть? ошибка в promisenoread?
Попробовал сложную ШД, только с буферизацией источников по posedge. Fatall вылетает на любой скорости в тех же местах (то есть дело не в rdrom, там стоит защита на 57) + такой же глюк с зацикливанием. gstest работает на любой скорости.
В ldi был недопустимый promisenoread — убрал, как убрано в cpi, ini, outi (надо сделать в зависимости от зацикленности или вообще как-то выкидывать последний машинный цикл). Всё равно вылетает и так же зацикливается.
Убрал no_read (promisenoread остались только в add hl,rp, jr, jr cc, adc/sbc hl,rp) — не помогло.
Убрал promiseIORQ — не помогло.
Откуда Halt_FF? может быть только на команде halt. Обнуляется по reset или IntCycle или NMICycle.
10xii
Добавил показ сигнала dos.
Убрал из внешней ШД всё, кроме IDE — так Fatall работает.
Вернул данные порта — глючит так же.
Подставил вместо них 00 — глючит так же. без SD-карты тоже.
При шагании выполняет не то, что написано! Fatall включил eff7 bit 3 (pg0 в 0000). Убрал эту фичу — Fatall починился.
Вернул полную внешнюю ШД, promisenoread, promiseiorq — работает (даже определение памяти в gstest на 57).
halt всегда стоит на следующей команде. Обнулил Halt_FF в inbreak, чтобы не попадать в обработчик прерывания каждый раз. Не сработало.
Когда делаем шаг, inbreak снимается до следующей команды, поэтому IR от halt всё равно обрабатывается. Дал вместо него breakpoint_event — не помогло. Обнулил ещё IntCycle — помогло.
Пробовал убрать лишний машинный цикл из ldir — не смог.
11xii
Добавил вывод дизасма по oldpc.
Попробовал rdrom на 57 МГц так: (virt_cpu_memrdresult_n='0' and wasromaccess_n='0' and fpga_rdrom_input='1') — работает на всех частотах. gstest работает, кроме размера памяти на 57 МГц.
Fatall при старте на 57 МГц (в режиме Fast или Max) крутится на чтении bb (в режиме Slow норм), на 28 норм, после переключения на ходу на 57 норм.
Вернул приоритет внешних портов через fpga_io0..2 — то же самое, но память в gstest на 57 показывается правильно.
Попробовал promisecpuram_flag = promisemreq;// ~virt_cpu_wait_counter[0]; — так не заливается прошивка ПЗУ
Усилил дешифрацию eff7 до exf7 (иначе пересекалось с 77), вернул bit 3 eff7 — работает.
ZX-BUS заработал на 57 МГц (p2666_arbiter15.zip)!
12xii
Делаю 57 МГц без тормозов.
Упростил условия для доступа в память дебагера и ВГ93. Fatall на 57 не запускается — крутится на чтении bb, NedoOS не грузится на 57 — крутится на чтении bb.
Поменял приоритеты для выставления адресов и данных (для других сигналов так): ARM > Z80 > ВГ93 > debug (видео надо будет между Z80 и ВГ93). То же. ВГ93 пишет бред (через байт идут паразитные записи, т.е. правильные байты растянуты: b?o?o?t и т.д. т.е. импульс записи длится 2 такта, write_trz снимается по (vg_tormoz = '1' and vg93_override_ram = '0'), а по нему устанавливается и снимается vg_require_tormoz).
Добавил для ВГ93 условие записи (и чтения) только в чётных тактах (раньше так и было). Помогло.
Перенёс арбитр в top. Добавил видеоконтроллер на общих правах (пока не даёт работать ВГ93 и дебагеру).
Сделал в видеоконтроллере захват только валидных данных (если запрос не был прерван более приоритетными): адрес формируется через такт, потом такт арбитра, потом такт чтения, потом полтакта на защёлкивание и полтакта на изменение пикселя — итого 4 такта 57 МГц (4 пикс текста, 2 пикс 6912), именно такая должна быть периодичность опроса. В основном показывает правильно, но: 6912 — небольшой снег (чёрный и белый), EGA — норм, текст — буквы и атрибуты взамен друг друга (и на 57 исчезает 2-й символ), небольшой белый снег на 57 МГц.
13xii
Переписал видеоконтроллер, чтобы все ATM режимы работали от одного счётчика, с одним буфером данных и одной рамкой, кратной 8.
Не работает. Строил растактовки на бумаге — не получается как нарисовано.
16xii
Сделал начало чтения на 4 такта (2 малых пикселя) раньше — текстмод нормально (только нет одного пикселя слева), EGA слева экрана вместо пикселей с x=0,1 отображаются 128,129, пиксель 128 видно справа экрана. hires: неправильные атрибуты в левой колонке, нет одного пикселя слева (он справа). 6912: нет одного пикселя слева (он справа). На 57 в текстмоде небольшой снег атрибутами (задержка атрибута на 2 знакоместа), на EGA и 6912 тоже есть небольшой снег. Снег объясним только при двух пропусках подряд.
20xii
Сделал показ и разбирал циклограмму арбитра с экрана.
23xii
Повторные запросы от процессора в соседних тактах видны на 28 постоянно, на 57 как минимум во время обработки прерывания, на 3.5 не видны.
24xii
В ModelSim не получаются повторные запросы на 28 МГц. promisemreq и memrd, memwr работают по negedge, но это не должно портить.
25xii
Проверил на ModelSim на 28 с командой halt (0x76) — все запросы на 1 такт!
Сделал mreq, memrd, memwr по posedge — на 3.5 (чисто), 7 (чисто), 57 (с паразитными запросами) работает, на 28 (чисто) виснет (при переключении на 57 продолжает работать).
Проверил на ModelSim на 57 — все запросы на 1 такт! (и пропали иголки)
Вынул NGS — всё так же, но 28 с паразитными запросами и снегом.
26xii
Попробовал команды halt (0x76), rst 0x38 (0xff) в железе — паразитных запросов нет (28, 57). В ModelSim команда не отрабатывает.
Сделал для чтения условие (~write && ~no_read) — всё равно паразитные запросы на 28, 57. Даже на цепочке out:jr.
Попробовал постоянную команду jr (0x18) — паразитные запросы на 57 (иногда на 28). В ModelSim команда не отрабатывает. Не были выставлены setpc_n, inbreak — добавил, не помогло. Добавил Mode=1 — не помогло. Сделал выдачу D постоянно — не помогло.
Так в ModelSim не работает (получается Z-состояние):
always @* virt_cpu_d[7:0] <= 8'h18;
assign virt_cpu_data[7:0] = virt_cpu_d[7:0];
Работает только прямая подстановка 8'h18 в процессоре. Но и так паразитных запросов нет.
Видимо, паразитные запросы вылечились, а на экране иллюзия из-за половинок тактов (период 24 полутакта, видно половинки). Проверил целыми тактами — да. Теперь нет снега.
Сдвинул рамку 6912 на 2 малых пикс. влево, рамку EGA на 1 малый пикс. влево — ОК (для текстмода тоже), обнуление адреса сдвинул на 1 малый пикс. влево — не помогло.
Обнуление адреса сдвинул ещё на 1 малый пикс. влево, убрал фазы запросов с экрана. OK, но нестабильная сборка на 57.
Упростил арбитр — OK. На 57 МГц — gstest работает (NGS в слоте 3), ZXNetUSB нет (в слоте 1). 28 — наоборот (с NGS бывает, надо перевключать). С ZXNetUSB без NGS красная лампочка после mount (даже на 57) и виснет на dhcp resolving (без кабеля только на 28, с кабелем на 28 и 57)! Переставил ZXNetUSB в слот 3 — не помогло.
На авторской прошивке в слоте 3 — то же самое, но в слоте 1 (без NGS) — работает, пинг проходит.
zxwiztst.$C проходит тест памяти (по портам). SL811H — no device detected. send broadcast виснет на "open socket in UDP mode" (там через память), аналогично receive packet.
Чтобы сделать стабильную работу дебагера, добавил сигналы busy (в момент запроса) по цепочке приоритетов из сигналов запросов предыдущих абонентов — не помогло.
На обоих частотах ВГ93 пишет лишний каждый второй байт, читает хорошо. Сделал автоснятие запроса ВГ93 — исправилось, но дебагер нестабильный.
Исправил опечатку debuf_mreq_busy — дебагер исправился.
Первое знакоместо в 16C продублировано. Исправил.
Теперь 57 МГц без тормозов и снега — эквивалентная частота 63 МГц (http://alonecoder.nedopc.com/p2666_arbiter41-.zip)!
27xii
В zxwiztst.$C memmap работает при запуске с дискеты на 3.5 (находит memmap, но иногда не находит порты) и полностью, если в прошивке жёстко задать частоту 3.5 МГц или 7 МГц (14 не работает). Но wizcfg всё равно вылетает.
Пробовал добавить задержку 15 тактов после rdrom при csr — одна сборка глючная, другая в тесте виснет на детекте ZXNetUSB (на команде ld (0000),a, T1). Добавил !rdromwaiting — не видит memmap на max, fast, slow.
Попробовал начать rd в середине первого T1 — не помогло.
28xii
Попробовал ловить rdrom и начинать тормоз в конце T1 (чтобы задержать T2) — не помогло.
Прошагал wizcfg. Вылет в wiznet_read. Запарывает pgsys (0a). Сделал точки останова по записи в память (нижние 4 работают и по выполнению, и по записи, верхние только по выполнению). Выяснил, что память портит команда ini (08:50fc — в версии evo это 51aa, в эмуляторе туда не попадает, потому что в wizcfg детект эмулятора) в w53_rd_udp_loop в драйвере w5300, задан очень большой счётчик ix, он прочитан из портов 30ab, 31ab (w53_rd_ipraw) (50cd — в evo 517b). Конкретно из портов прочитано b7,8e (hl=b78e), de=0800, вычитается hl-de, потом прибавляется обратно.
Временно сделал 3.5 МГц в !megaturbo. Не помогло. И из-за растягивания rdrom тест не определяет ни memmap, ни порты.
Убрал растягивание rdrom. Не помогло, тест даже иногда не видит порты.
Мог быть паразитный rd в no_read — убрал. Растянул iorq и wr для iorq в соответствии с растянутым rd. Так не работает SD-карта.
Вернул rd, wr, iorq в нерастянутое состояние. Не помогло с NedoOS. Зато тест проходит с портами и memmap.
В итоге ZXNetUSB работает неполноценно (правильно работал только в старых прошивках) (http://alonecoder.nedopc.com/p2666_megaslow2.zip). Кто сможет починить — пишите!
Поделитесь вашим мнением о статье