а чем он поможет если загрузчик нестандартый (esxdos такое явно непрожуёт)
Вид для печати
а чем он поможет если загрузчик нестандартый (esxdos такое явно непрожуёт)
ZX-Blockeditor справился с конвертацией, но goodboy прав - загрузчик там нестандартный и через esxdos не загружается.
В ZXMAK2 обычно TAP грузится моментально, а в этой демке по-старинке со скоростью обычного магнитофона загружается.
- - - Добавлено - - -
Перевел через ZXMAK2 в SNA формат. Не уверен, что 100% правильный тест получается таким образом, но глюк есть.
Почему-то буквы идут только по бардюру, а по самому экрану нет. Ну и сами буквы перекособочены. Тут можно грешить, что что-то неправильно загрузилось из-за SNA формата, а может быть и что-то неправильно работает в самом эмуляторе.
- - - Добавлено - - -
дык, а какой толк тогда от адаптированной версии. Мы же вроде тайминги ZX128 проверяем.
goodboy,
и какая маска для этого порта нужна чтобы правильно работало?
у меня вот так: !A[15] && !A[1] && A[0]
в sil4 используется порт #7ffc
как я понял на-фирме a15&&a1
#c==%1100 (в твой расклад попадает)
возможно команда outi барахлит
Вот теперь буквы нормально идут :)
жаль что оригинал только в TZX. Нельзя проверить ZX128 вариант.
а что было не-так ?
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. На мой взгляд, это костыль.
Нарыл ещё один тест, который тестирует задержки ZX128. Вроде в теме его ещё не выкладывали (был похожий под 48к). Есть нюанс - он заточен под модель 128к с late timings, поэтому на эмуляции с early timings дает несколько ошибок. (Не уверен, что формат .z80 сохраняет информацию о модификации таймингов (issue 2 = late timings?), поэтому при использовании снапа .z80 надо иметь это ввиду. Кстати, большинство эмулей игнорируют эту информацию и при чтении szx снапов).
Хм.. вообще ничего не понимаю. Сейчас отключил contendent задержку в ZX128 вообще - и SIL4 стал отображать правильно буквы во весь экран! Есть небольшой глючок - квадратик красный дергается, но это пока не важно.
Получается, что задержек не должно быть вообще. А как так может быть? Чуваки рассчитали тайминги обращения так что попадают именно в тот момент (два такта из 8), когда нет задержек? Такое вообще возможно?
Меня трудно удивить какими-то новыми тестами, кроме вновь написанных..
http://zx-pk.ru/showthread.php?t=261...l=1#post856405
Там написано, что в SpecEmu всего одна ошибка в нем..
Удалось сделать так, чтобы SIL4 заработал, но квадратик телепается.
Правда, такты contendent памяти пришлось сдвинуть и данные portFF еще сильнее сдвинуть относительно реального чтения данных видеопамяти. Как-то это неправильно.
Не могу понять почему и в Speccy2010 и в ZXMAK2 проверяют состояние шины адреса когда nMREQ = 1. Ну это же бред! Шина в таком состоянии не активна же. Что-то я не пойму этого момента. Либо какой-то костыль, либо еще какое-то извращение.
Есть ли где описание этого момента? На http://www.zxdesign.info про это нет ни слова, что еще раз убеждает что это какая-то неправильная проверка. Должно быть либо nIORQ==0 либо nMREQ==0. Во всех остальных случаях шина адреса не имеет значения.
в режиме Пентагона тоже телепается. но там 1t , а в 128 4t - не должен. Такты не выровнены в циклах, но для ZX128 это не существенно должно быть
- - - Добавлено - - -
Скрытый текст
http://s3.micp.ru/jgyJ1.jpg[свернуть]
Вот так все печально в режиме zx128. Это все же проблемы с тормознутой памятию или с положением Int-a ? INT-ом точно не выравнивается(((
zebest,
Если убрать часть кода contendent тормоза в ZXMAK2, то и в нем квадратик начинает телепаться. Так что проблема именно в правильном торможении.
а это где так? в Speccy2010?
- - - Добавлено - - -
Я думаю, этот загадочный цикл чтения без активности nMREQ, это, наверное nIORQ? Ведь, согласно схеме, на ULA приходит не чистый nIORQ, а смешаный с A0. Соответственно если идет обращение к нечетному порту, то на ULA не приходит ни nMREQ (поскольку это не чтение памяти) ни nIORQ (поскольку замаскирован A0=1).
Видишь суслика? И я не вижу. А он есть!
В общем, после многочисленных тестов пришел к выводу - Т80 не точная модель что касается тактов. Если я выдаю INT в начале 248 строки, то в ULATEST3 я должен получить красивую картинку по contendent памяти и тоже красивое распределение данных порта FF. Но этого нет. Поэтому начинается подгонка тактов, смещение INT и прочая лабуда. Где-то это работает. Где-то вылезают глюки.
В A-Z80 картина на порядок лучше и в принципе похоже на настоящий процессор. Но, блин, она не доделанная. Неправильно раотают INIR и OTIR инструкции - это то, что я сам нашел. А сколько еще может быть ошибок - не знаю. Автор не горит желанием это исправлять.
Сделал один вариант для Т80, при котором Shock, Ulatest3, SIL4 работают правильно, но растактовка и тайминги в коде - просто ужас.
Сейчас делаю второй вариант в надежде сделать это не так ужасно.
Потом решу что пойдет в релиз.
Кстати, если надо, могу какие-нибудь тесты прогнать на оригинальных 48, 128 и +3, правда только с магнитофона. И вероятно не слишком быстро.
zebest,
Я имел ввиду не общее количество тактов каждой комманды - тут вопросов нет, выглядит как точная копия.
А вот что творится с сигналами внутри этих тактов - большой вопрос. Для пятногона это неважно, а вот для ZX это очень важно, поскольку contendent модель очень чувствительная к положению сигналов и то, на каком именно такте производятся определенные действия.
У Т80 несколько top моделей, которые ведут себя по-разному. Возможно, получится подвинуть сигналы в этих обертках, потому как я вижу что T80a имеет несколько иное распределение сигналов чем T80s, которая в свою очередь отличается от T80se.
- - - Добавлено - - -
zebest,
Ну вот сейчас смотрю на графике Z80a: nIORQ активируется на первом такте, а нужно на втором. При этом первый такт в IO цикле очень странный. Он длится 2 такта вместо одного. Ну ок, можно было подумать, что это так объединили T2 и TW такты. Ну дык, это тогда Т2 должен иметь два такта, а не Т1.
А ты говоришь, точный...
- - - Добавлено - - -
Сделал фикс для кривого nIORQ у T80 и глюки исчезли! Использую contendent модель из книжки Криса Смита (она же в zx_ula проекте используется). Так что теория вполне себе работает. А вот в том же Speccy2010 модель тормоза довольно кривая, видимо подгонялась под неточность процессора, поэтому там и странные номера тактов используются, и обратная петля ввиде WaitCancel.
в Shock в ZX128 слева вверху есть маленькая помарка ввиде смещенного куска, но я уверен что это и в оригинальном ZX128 имется. Просто в моем эмуляторе очень широкий бордюр. Во всех эмуляторах что я видел - бордюр довольно узкий - поэтому там не видно это место.
угу. А глюки те же.
Сначала хотел влезть в код Т80, чтобы подвинуть nIORQ, но потом решил подвинуть в видео контроллере. А то вдруг что-то задену.
В общем, всё работает сейчас как надо. Растактовка тоже красиво теперь выглядит, как и должно в железном ZX. С единственной заковыркой - начало INT. Пришлось двинуть на 2 такта в ZX48, на 6 в ZX128 и на 4 в P128.
Надо будет еще раз прогнать все тесты перед релизом.
- - - Добавлено - - -
zebest,
Не мог бы ты посмотреть в Speccy2010 что пишет TEST 4.30?
Интересует сообщение об AY. У меня он ругается на неправильное подключение.
который из ROM\ПЗУ работает?? Ничего не ругается на звук, все нормально пишет. фото сделай, где именно ругается
А проверь эту поделку на реальном ZX128. Ибо в эмулях - полная фигня.
4 эмууля со мной согласны, зато отсальные 22 - ни разу не согласны ((
тест вакуумный, сферический
Так может как раз эти 4 эмуля и самые неправильные?((((
в моем эмуляторе вот так:
Вложение 55989
А вот собственно сообщения об ошибке AY:
Вложение 55990Вложение 55991
ну и хорошо. осталось узнать, как оно все же на оригинале смотрицца, ибо большинство(!) эмулей криво показывают.
Попиксельно на бордюре не сделать, минимум по 2 пикселя(такт) можно, но в пентагоне, в 128 модели минимуум 4 такта, из за особенностей архитектуры) так что тут нормально
Не понимаю почему этот тест ругается на AY.
Есть ли какие более вразумительные тесты музыкального чипа? чтобы писал что именно не так если не нравится.
- - - Добавлено - - -
P.S.: починил-таки :) Не думал, что так по-извращенски он подключается в спектруме.
вообщето все ровно наоборот :)
Под 128 дем с хитрыми выкрутасами на contended memory тьма тьмущая, под 48 late можно найти, а вот под 48 early почти ничего нет
- - - Добавлено - - -
Потому что в оригинальном спектруме неполная дешифрация используется, поэтому задержки бывают даже когда на самом деле нет обращения к памяти или портам. В таких случаях задержка зависит от того что сейчас на шине адреса у процессора, а там обычно внутреннее состояние, как правило IR или HL
- - - Добавлено - - -
в пентагоне более сложные тайминги, чем в оригинальном спектруме. Поэтому и нет эмуляторов которые точно тайминги пентагона эмулируют. Про демы я не слышал, но есть тесты которыми легко поймать неточную эмуляцию видеогенератора пентагона. Ктото пытался добавить поддержку в свой эмулятор, но насколько точно это вышло не знаю. В ZXMAK2, ошибка сведена к 1 такту.
ZXMAK,
Порекомендуйте хитрые демки для ZX128 для проверки contendent памяти.
Я ZX128 уже сделал, те мои измышления были давно :)
Демок под пентагон хоть отбавляй. Практически все русские демки под него. Из тех, что требуют точные тайминги - Eye Ache, например.
Дайте ссылки или выложите их тут - хочу потестировать.
Мне почему-то показалось, что под пентагон как раз-таки легко настроить тайминги. По крайней мере, я это сделал за день. И то, основная часть времени ушла на то, чтобы понять, что проблема была в модели процессора а не в видео контроллере.
- - - Добавлено - - -
по-моему, вы всё усложняете. Пентагон сделан весь на простой логике, и повторить его тайминги зная схему - раз плюнуть. На FPGA вообще можно нарисовать схему как есть, если что. Это на ZX стояла ULA которую раскусили только когда спилили и под микроскопом разглядели. А логику 155 серии не надо вскрывать ;)
один из хороших тестов для contended memory - это игра sidewise, она и в 48 и в 128 работает. Если есть ошибки в эмуляции задержек, спрайт игрока будет иногда мерцать. На правильных таймингах он мерцать не должен вообще. Это конечно не гарантирует что тайминги правильные, т.к. отсутствия мерцания можно из без задержек добиться, но если задержки эмулируются, то эту игру можно использовать для теста ошибок в эмуляции таймингов. Но, как я уже сказал - отсутствие мерцания не говорит о правильных таймингах. Тут правило наоборот - если мерцает, значит есть ошибки в таймингах
- - - Добавлено - - -
eye ache точных таймингов вообще не требует, там хоть плюс минус лапоть все будет смотреться более менее нормально. Она даже на эмуляторе Шалаева шла, где таймингов вообще нет... :)
нет, посмотри кусок схемы с триггером для прерываний. Там не просто логика чтобы на фиксированном такте прерывание генерировать, все сложней - меняется порядок выборки ink/paper - все это влияет на тайминги. Если ошибка +-1 такт не имеет значения, то это можно не учитывать (так и происходит во всех эмуляторах), но эту ошибку можно поймать тестом. btime тест насколько помню, в эмуляторах на границе такта пикселы либо есть, либо нету. На реальном пентагоне они мерцают.
Это происходит потому что на некоторых тактах происходит конфликт доступа к памяти между процессором и видеогенератором и видеогенератор откладывает чтение на следующий такт, при этом меняется порядок выборки ink/paper.
По сути в пентагоне нужно аналогичную логику, как для contended memory эмулировать, чтобы добавлять задержку и менять порядок выборки байтов. Только тут задержка не процессора, а для видеоконтроллера происходит и немного более хитрым образом. Но если вся логика и возможные варианты для contended memory изучены, исследованы и подробно описаны, то для пентагона такой информации нигде нет и никто это не исследовал
Ошибка в 1 такт для демок не критична, врядли где-то артефакты появятся. В unreal ошибка эмуляции вообще 10-20 тактов и никто этого не замечает... :)
ZX128 в ZXMAK2 достаточно точно эмулируется, 48К late тоже, для 48К early есть ньюансы с длительностью инта нигде информации по этому нет, все демы и тесты работают корректно. Но в каком-то тесте с прерываниями можно поймать разницу - на всех эмуляторах значения разные, какое на реальном 48К early неизвестно.
Один из ключевых тестов для проверки contended memory - ulatest3, есть несколько модификаций.
При любых тестах contended memory важно помнить, что нужно использовать только оригинальную прошивку ROM, если хоть один байт ROM отличается, то результаты могут быть некорректными.