С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
zebest,
да, я так уже и сделал.
в ZX128 буквы все в разложенном виде. Опять где-то проблема с contendent mem или io.
Я для проверки загрузил через магнитофонный вход - та же проблема с буквами. Ну значит по крайней мере SNA правильно работает.
Надо теперь думать что не так.
goodboy,
Просто из декодера порта 7FFD убрал проверку на A0. В оригинале, как во всех доках написано, А0 должен быть равен 1. Поэтому 7FFC не попадал. Ну раз в фирменном так сделано, значит пусть будет без A0.
- - - Добавлено - - -
Я теперь понимаю почему в Speccy2010 INT начинается в конце предыдущей строки, а не в начале.
У T80 тайминги сдвинуты.
Особо продвинутые чуваки, типа "PRESENTED BY PASHA NIKITIN" ничтоже сумняшеся щёлкали странички через "OUT #0D, A" и даже, о ужас, через "OUT #00, A". Нуачо, работает.
Заходим в BASIC, вводим OUT 0, 255 — красота.
В правильно заданном вопросе содержится половина ответа
Руки бы по отрывать дезигнерам спектрума.
- - - Добавлено - - -
Особо умиляет, что в пентагоне на обычной логике тех же времен сделали обращение к памяти без торможения, а на оригинале почему-то не смогли.
- - - Добавлено - - -
Кстати, на Т80 сигнал nRFSH не надо учитывать. Сам-то сигнал есть, а адреса на шине нет (ну или неправильный, я не проверял).
Т80 создавался по принципу "что мы знаем о Z80?". И постепенно допиливался и подгонялся. Наверное, можно считать что его допилили до почти совершенного состояния.
A-Z80 создавался по реальному железу, но реверсили без достаточно тщательности. Это же ведь тоже не автоматические действия. Там достаточно ручной работы. Поэтому есть ошибки. А автор уже отошел от этого проекта и не особо горит желанием фиксить. Я ему писал об ошибках, но он как-то вяло реагирует да и повторяет постоянно что уже многое забыл. А больше никто этим проектом не занимается.
В общем, вначале многообещающий проект превратился в недоделанный.
Это как с MOS6581/8580 - вроде и есть модель, и даже в большинстве случаев работает. Но не всегда. Тоже подгоняют по принципу "наверное, должно быть так". А настоящей модели нет. Точнее есть, но тоже нифига не доделанная.
- - - Добавлено - - -
кстати, по поводу contendent:
Оставлю этот кусок кода из ZXMAK2 тут для истории:
Меня привлекла внимание функция contendPortLate. Круто там навернули аж тройную проверку.Код:namespace ZXMAK2.Hardware.Spectrum { public class UlaSpectrum128_Early : UlaDeviceBase { public UlaSpectrum128_Early() { Name = "ZX Spectrum 128 [early model]"; } #region IBusDevice public override void BusInit(IBusManager bmgr) { base.BusInit(bmgr); bmgr.Events.SubscribeRdMem(0xC000, 0x4000, ReadMem4000); bmgr.Events.SubscribeRdMemM1(0xC000, 0x4000, ReadMem4000); bmgr.Events.SubscribeRdMem(0xC000, 0xC000, ReadMemC000); bmgr.Events.SubscribeRdMemM1(0xC000, 0xC000, ReadMemC000); bmgr.Events.SubscribeRdNoMreq(0xC000, 0x4000, ContendNoMreq); bmgr.Events.SubscribeWrNoMreq(0xC000, 0x4000, ContendNoMreq); bmgr.Events.SubscribeRdNoMreq(0xC000, 0xC000, ContendNoMreq); bmgr.Events.SubscribeWrNoMreq(0xC000, 0xC000, ContendNoMreq); bmgr.Events.SubscribeRdIo(0x0000, 0x0000, ReadPortAll); bmgr.Events.SubscribeWrIo(0x0000, 0x0000, WritePortAll); } #endregion public override bool IsEarlyTimings { get { return true; } } protected override SpectrumRendererParams CreateSpectrumRendererParams() { // ZX Spectrum 128 // Total Size: 456 x 311 // Visible Size: 352 x 303 (48+256+48 x 55+192+56) var timing = SpectrumRenderer.CreateParams(); timing.c_frameTactCount = 70908; timing.c_ulaLineTime = 228; timing.c_ulaFirstPaperLine = 63; timing.c_ulaFirstPaperTact = 64; // 64 [40sync+24border+128scr+32border] timing.c_ulaBorder4T = true; timing.c_ulaBorder4Tstage = 2; timing.c_ulaBorderTop = 32; //55 timing.c_ulaBorderBottom = 32; //56 timing.c_ulaBorderLeftT = 16; //16T timing.c_ulaBorderRightT = 16; //32T timing.c_ulaIntBegin = 64 + 2; timing.c_ulaIntLength = 36; // according to fuse timing.c_ulaWidth = (timing.c_ulaBorderLeftT + 128 + timing.c_ulaBorderRightT) * 2; timing.c_ulaHeight = (timing.c_ulaBorderTop + 192 + timing.c_ulaBorderBottom); return timing; } #region Bus Handlers protected override void WriteMem4000(ushort addr, byte value) { contendMemory(); base.WriteMem4000(addr, value); } protected override void WriteMemC000(ushort addr, byte value) { if ((m_pageC000 & 1) != 0) contendMemory(); base.WriteMemC000(addr, value); } protected void ReadMem4000(ushort addr, ref byte value) { contendMemory(); } protected void ReadMemC000(ushort addr, ref byte value) { if ((m_pageC000 & 1) != 0) contendMemory(); } #region The same as 48 protected void ContendNoMreq(ushort addr) { if (IsContended(addr)) contendMemory(); } protected override void WritePortFE(ushort addr, byte value, ref bool handled) { } private void WritePortAll(ushort addr, byte value, ref bool handled) { contendPortEarly(addr); contendPortLate(addr); if ((addr & 0x0001) == 0) { int frameTact = (int)((CPU.Tact - 2) % FrameTactCount); UpdateState(frameTact); PortFE = value; } } private void ReadPortAll(ushort addr, ref byte value, ref bool handled) { contendPortEarly(addr); contendPortLate(addr); int frameTact = (int)((CPU.Tact - 1) % FrameTactCount); base.ReadPortFF(frameTact, ref value); } #endregion #endregion private bool IsContended(int addr) { int test = addr & 0xC000; return (test == 0x4000 || (test == 0xC000 && (m_pageC000 & 1) != 0)); } private bool IsPortUla(int addr) { return (addr & 1) == 0; } #region The same as 48 private void contendMemory() { int frameTact = (int)(CPU.Tact % FrameTactCount); CPU.Tact += m_contention[frameTact]; } private void contendPortEarly(int addr) { if (IsContended(addr)) { int frameTact = (int)(CPU.Tact % FrameTactCount); CPU.Tact += m_contention[frameTact]; } } private void contendPortLate(int addr) { int shift = 1; int frameTact = (int)((CPU.Tact + shift) % FrameTactCount); if (IsPortUla(addr)) { CPU.Tact += m_contention[frameTact]; } else if (IsContended(addr)) { CPU.Tact += m_contention[frameTact]; frameTact += m_contention[frameTact]; frameTact++; frameTact %= FrameTactCount; CPU.Tact += m_contention[frameTact]; frameTact += m_contention[frameTact]; frameTact++; frameTact %= FrameTactCount; CPU.Tact += m_contention[frameTact]; frameTact += m_contention[frameTact]; frameTact++; frameTact %= FrameTactCount; } } protected override void OnTimingChanged() { base.OnTimingChanged(); m_contention = UlaSpectrum48.CreateContentionTable( SpectrumRenderer.Params, new int[] { 6, 5, 4, 3, 2, 1, 0, 0, }); } private int[] m_contention; #endregion //protected override void EndFrame() //{ // base.EndFrame(); // if (IsKeyPressed(System.Windows.Forms.Keys.F1)) // { // c_ulaBorder4T = true; // c_ulaBorder4Tstage = 0; // OnTimingChanged(); // } // if (IsKeyPressed(System.Windows.Forms.Keys.F2)) // { // c_ulaBorder4T = true; // c_ulaBorder4Tstage = 1; // OnTimingChanged(); // } // if (IsKeyPressed(System.Windows.Forms.Keys.F3)) // { // c_ulaBorder4T = true; // c_ulaBorder4Tstage = 2; // OnTimingChanged(); // } // if (IsKeyPressed(System.Windows.Forms.Keys.F4)) // { // c_ulaBorder4T = true; // c_ulaBorder4Tstage = 3; // OnTimingChanged(); // } // if (IsKeyPressed(System.Windows.Forms.Keys.F5)) // { // c_ulaBorder4T = false; // OnTimingChanged(); // } //} //private static bool IsKeyPressed(System.Windows.Forms.Keys key) //{ // return (GetKeyState((int)key) & 0xFF00) != 0; //} //[System.Runtime.InteropServices.DllImport("user32")] //private static extern short GetKeyState(int vKey); } public class UlaSpectrum128 : UlaSpectrum128_Early { public UlaSpectrum128() { Name = "ZX Spectrum 128 [late model]"; } public override bool IsEarlyTimings { get { return false; } } protected override SpectrumRendererParams CreateSpectrumRendererParams() { var timing = base.CreateSpectrumRendererParams(); timing.c_ulaFirstPaperTact += 1; timing.c_ulaBorder4Tstage = (timing.c_ulaBorder4Tstage + 1) & 3; return timing; } } }
У меня ощущение, что опять весь алгоритм придется переписывать
Кстати, Shock на ZXMAK2 в режиме ZX128 не работает. Сбрасывается при загрузке цветных полос.
weiv,
понятно. но в ZXMAK2 я не нашел отключение быстрой загрузки с ленты.
Странно, что в режиме ZX48 работает.
- - - Добавлено - - -
В общем, загрузил я Shock в ZXMAK2 ZX128. Надо было просто войти в Basic 48 - и оттуда загрузить. В общем, с таймингами ZX128 в ZXMAK2 отлично выглядит, без глюка в правом нижнем углу.
Только не получается что-то портировать алгоритм на verilog.
В начале сообщения как раз и предлагается грузить демку после USR 0 в режиме 128к. (Проблемы с SHOCK при быстрой загрузке с ленты только у Спектакулятора, в режиме 48к и с отключенным старт/стопом ленты - слетевшие из-за быстрой загрузки тайминги не выравниваются даже после остановки ленты. Но это мелочи).
zebest,
А как этот Song In Lines выглядет на Speccy2010 в режиме ZX128?
О! пофиксил проблему в Shock в правом нижнем углу в режиме ZX128! Остался лишь маленький еле заметный глюк в правом верхнем углу.
zebest,
не, тут дело не в медленной странице. Ты постоянно забываешь, что проблема у меня была из-за цикла рефреша, которую я уже давно пофиксил.
Тут в чем-то другом.
Судя по всему, contendent алгоритм для ZX48 и ZX128 идинаковый. Вон даже в ZXMAK2 он идентичен за исключением проверки на верхние 16кб. И в ZXMAK2 SIL4 выглядет отлично.
Отсюда вывод, что алгоритм contendent в Speccy2010 не совсем правильный не только для ZX128 но и ZX48.
Я пофиксил угол в Shock, но в ZX48 вылезли глюки. Я пока сделал проверку и включаю разные алгоритмы, но это костыль. Так быть не должно.
Надо разобраться в алгоритме ZXMAK2, но я пока не уловил смыл полностью.
- - - Добавлено - - -
zebest, мне не нравится в алгоритме Speccy2010 обратная петля ввиде ulaWaitCancel. На мой взгляд, это костыль.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)