PDA

Просмотр полной версии : Перестали работать тестовые программы btime, minfo, ulatest3.



апро
08.03.2017, 03:38
Перестали работать тестовые программы btime, minfo, ulatest3 на клоне Спектр Калужский вариант 48, хотя месяц назад работали. Другие программы и игры работают без изменений и глюков. В чём может быть дело? Эти три теста после старта ресетятся. Может не туда пишу куда надо, но вопрос касается софта в некоторой степени.

Прогнал другие тесты, вроде всё как было раньше.
TEST430 1
59994
https://yadi.sk/i/tw65kKE33FEyZ8
https://yadi.sk/i/tw65kKE33FEyZ8

TEST430 2
59985
https://yadi.sk/i/7CS-jHnZ3FEypb
https://yadi.sk/i/7CS-jHnZ3FEypb

TEST430 3
59986
https://yadi.sk/i/kbF0JoUQ3FEyuC
https://yadi.sk/i/kbF0JoUQ3FEyuC

A48MT
59987
https://yadi.sk/i/rezETPpl3FEz2E
https://yadi.sk/i/rezETPpl3FEz2E

IntTest
59989
https://yadi.sk/i/TNU-phhM3FEzE4
https://yadi.sk/i/TNU-phhM3FEzE4

PD
59991
https://yadi.sk/i/A1vAaXw23FEzSV
https://yadi.sk/i/A1vAaXw23FEzSV

PLATFORM
59992
https://yadi.sk/i/AQgRDJUF3FEzXc
https://yadi.sk/i/AQgRDJUF3FEzXc

TactsTest
59993
https://yadi.sk/i/aHe1nm2M3FF2cD
https://yadi.sk/i/aHe1nm2M3FF2cD

mctest2
59990
https://yadi.sk/i/B6amLep33FF2hz
https://yadi.sk/i/B6amLep33FF2hz


Попробовал методом тыка заставить работать btime.
Лист из дебагера
59988
https://yadi.sk/i/YyKaMJ-T3FF3CL
https://yadi.sk/i/YyKaMJ-T3FF3CL
Переправил все rst 0 на nop в коде программы. Она заработала. Потом по одному вернул rst o на место. Таким образом нашёл 2 rst 0 которые рестартят программу.Их выделил зелёным. Может кто из програмистов скажет что не так в программе (в смысле с компом) , почему программа переходит к этим зелёным командам?
Скажу честно я не силён в программировании, ну так по мелочи, и не понял предназначения выделеных красным учасков кода. Похоже на какие то ловушки для чего то. Для чего rst 0? И на первый взгляд программа до них не доходит. Но если поменять хоть один halt выделеный красным на nop, то программа не работает(ресетится). Значит программа доходит до halt, но почему не выполняется rst 0 следующий за ней? Прошерстил литературу по поводу Halt и rst 0 - ничего необычного что бы делали эти две команды в месте не нашёл. Далее тупик.

goodboy
08.03.2017, 11:14
возможно `поплыл` кондёр в RC цепочке которая отвечает за длительность сигнала int

rst#0 это вообще-то программный сброс компа.
после нажатия на кнопку reset код начинается выполняться с адреса #0000 (то есть из ПЗУ),
также и после rst#0

в твоём примере что-то выполняется в подпрограмме на im2

апро
08.03.2017, 23:45
С конденсатором уже поиграл, схему выработки int изменил, точку снятия тоесть по времени немного раньше и немного позже тоже изменил но без результатно.
В пзу зашита прошивка турбо 90. Поэтому команда rst#0 не приводит к стиранию бейсик программы и машинного кода в памяти. Только по этому я безконечно долго могу проводить эксперименты с ресетами пока не испортится содержимое памяти.
Трассировка программы показывает что перед переходом по im 2 создаётся таблица вектора перехода по адресу FDDO-FE00 чтобы исключить помехи на шине данных в момент выборки вектора прерывания. Адрес перехода таблицы при любых значениях вектора равен FEFE. Проверил, с таблицей всё в порядке. По адресу FEFE расположена программа возврата из прерывания. Последний адрес записаный в стёк перед IM 2 имеет значение C0A5. Программа возврата увеличивает регистр стёка после IM 2 на 2 и возвращает по адресу C0A5. А там расположена засада INC HL, JP COA5 которая должна зациклить комп. Это моя логика происходяшего процесса но она ошибочна, так как на самом деле этого не поисходит. В реальном времени происходит как то по другому. Трасировщик или дебагер не может нормально выполнить команду IM 2 в пошаговом режиме - происходит порча данных и на реале и на виртуалке. Так что и тут засада. Могу сказать только что, автор такого тут нарамудил, что мне разобрать не по силам. Даже имея исходники https://yadi.sk/d/7-oaIq9w3FJTq9я не понимаю как это работает.

Spectramine
09.03.2017, 00:25
Возможно, плавает длительность кадра - время в тактах между прерываниями. В оригинальном спеке она вроде как завязана на кадровую развертку, а как на этом клоне - не знаю. По задумке автора, до команд RST0 процессор доходить нигде не должен - до них должно произойти прерывание, которое обходит их инкрементом SP, т.е. возврат из прерывания происходит на заранее загнанный в стек адрес.

апро
09.03.2017, 00:46
Длительность кадра задана жёстко как в балтике и ленинграде счётчиками. И что до RST 0 доходить не должно я тоже понимаю , но доходит в двух случаях. А вот что это за случаи я понять не могу. Процессор поменял без результатно. Есть идея поменять пзу и озу. ради экперимента. Но это несколько напрягает.

Spectramine
09.03.2017, 01:20
Похоже, если раньше работало, а сейчас не работает, изменились условия торможения процессора - возможно, торможение стало меняться от кадра к кадру, соответственно, длительность кадра для процессора тоже меняется. Программы в начале работы вычисляют длительность кадра, в расчете, что она будет постоянной, а она меняется, слетают вычисленные программные задержки, и выполняется RST0. Вряд ли дело в проце, ПЗУ или ОЗУ, возможно, дело в той части схемы, которая тормозит процессор.

апро
09.03.2017, 01:38
То есть проверить формирование сигнала WAIT ? Попробую пробежать по всем сигналам , может выловлю что небудь.

апро
17.03.2017, 14:31
Проверил счётчики.
Формирование всех сигналов.
Длительность кадров.
Длительность синхоимпульсов. ССИ = 10 мкс, КСИ = 256 мкс Ну тут есть отличия от тв стандарта, но в каждом кадре всё одинаково.
Поиграл длительностью INT от24 до 40 и более.
Заменил пзу и озу.
Проверил WAIT, ничего подозрительного в формировании не заметил кроме того что он формируется из MREQ, M1, WRBUF , а в ленинграде участвует ешё RD.
В итоге всё без изменений. Я уже начинаю думать, а не приснилось ли мне случаем, что они работали.
Может ещё советы будут что проверить?
А вообще эти тесты на всех клонах должны идти или есть какие то ограничения?

Spectramine
17.03.2017, 15:04
Проверил на эмуле ZXMAK2 под моделью Ленинград-1 - сбрасываются.

апро
31.03.2017, 00:27
Вот в этой теме есть полезная информация http://zx-pk.ru/threads/21212-tajmingi-pentagon-128-)/page2.html. Проведя эксперименты с эмулятором ZXMAK2 пришёл к выводу, что все клоны имеющие соотношение takt/int = 65184/1 и количество линий в кадре 291 с этими програмками не работают и похоже мне всё же приснилось, что они работали. Может какое-то влияние оказывает торможение памяти.
Остаётся не понятным код программы - что происходит когда отрабатывают 69888 тактов? Почему не доходит до rst 0? Тут какая то хитрость. Если тактов меньше и int приходит раньше, то доходт до rst 0.

код

ALIGNINT:
ld de, _align
push de
ld de, _try
push de
im 2
halt
rst 0 ; the interrupt handler never returns (it pops the last value off the stack) Обработчик прерывания никогда не возвращается (он выталкивает последнее значение из стека)
_try ; 46T+
push de ; 57T+

ld bc,32677 ; 67T+
call DELAY ; 32744T+
ld bc,(FRAMET) ; 32764T+

call DELAY ; 69884T+
nop ; 69888T+ - the idea seems to be that if we run for exactly FRAME tacts, we are perfectly aligned Идея состоит в том, что если Мы бежим точно за тактами FRAME, Мы идеально выровнены
pop de
rst 0 ; really crazy way to handle timing errors (e.g. it crashes on Scorpion due to unaccounted M1 delays) Действительно сумасшедший способ обработки временных ошибок (Например, он терпит крушение на Scorpion из-за неучтенных задержек M1)

_align ; 55T
inc de
halt
rst 0

Spectramine
31.03.2017, 01:00
Когда отрабатывают 69888 тактов, происходит обработка прерывания. А обработчик прерывания меняет адрес возврата, и этим обходит rst 0.

апро
01.04.2017, 01:20
Может я что то недопонимаю, но насколько я понял из книг по ассемблеру, прерывание начинает обрабатывться после команды IM 2, а закончится обработка должна командой RET. После команды IM 2 обработчик начинает считать такты в своих мудрёных счётчиках, и если результат счёта соответствует расчётному то программа работает , а если нет то доходит до команды RST 0. Но я не врублюсь , что заставляет программу доходить до какого то места и неожиданно начинать с другого.
Вот к примеру код трасировал в спектакуляторе. До команд с точками остановки программа не доходит никогда. А до команд которые стоят перед ними доходит. Как так? Что заставляет процессор бросить выполнять пограмму на пол пути? Красными стрелками я отметил где программа ещё вы полняется, а до отмеченых точек остановки не доходит. Я понимаю если бы там были команды переходов, но там INC E несколько штук. А в следующм месте POP DE.
60418
https://yadi.sk/i/caL98-_o3GY93N

А в моём реальном клоне программа отрабатывает до RST 0 в обоих местах, и не бросает выполняться на пол пути. В чём фокус?

Я могу предположить, что в отмеченных местах на картинке приходит следующий сигнал INT и каким то чудом прерывает выполнение программы в нескольких тактах от команды RST 0. Но я нигде не читал про такую фишку. Везде описаны прерывания только по команде IM.
И тут назревает следующий вопрос. Если поцессор бросает выпонять программу в этих местах, то откуда начинает дальше? Могу предположить с адреса на вершине стёка.

null_device
01.04.2017, 04:12
каким то чудом прерывает выполнение программы в нескольких тактах от команды RST 0. Но я нигде не читал про такую фишку. Везде описаны прерывания только по команде IM.

Немаскируемые прерывания NMI - нет?!

Alex Rider
01.04.2017, 05:17
Может я что то недопонимаю, но насколько я понял из книг по ассемблеру, прерывание начинает обрабатывться после команды IM 2

Что заставляет процессор бросить выполнять пограмму на пол пути?
Процедура обработки прерывания начинает работать в момент прихода импульса на вход /INT процессора. В Spectrum'е импульсы на этот вход поступают примерно 50 раз в секунду, а точнее с частотой обновления экрана. У разных клонов чуть разная частота обновления и геометрия экрана и скорость работы процессора.

Если процессор бросает выпонять программу в этих местах, то откуда начинает дальше? Могу предположить с адреса на вершине стёка.
Это правильное предположение. В момент прихода импульса прерывания как будто бы выполняется команда call, при этом на стек попадает адрес возврата. Обработчик прерывания завергается командой RET, адрес возвра снимается о стека и выполнение продолжается со следующей команды - как бы происходит аппаратный вызов подпрограммы. обработчику прерывания ничего не мешает подменить адрес возврата на стеке и "продолжить" выполнять программу с любого места.


А в моём реальном клоне программа отрабатывает до RST 0 в обоих местах, и не бросает выполняться на пол пути. В чём фокус?
На 100% не подскажу, потому что, повторюсь, я не дебажил этот код. Если обработчик подменяет адрес возврата, то достиженеи команды RST 0 зависит от того, успело ли прийти прерывание до этой самой RST 0. Если успело, то обработчик подменяет адрес, и выполнение обходит RST 0. Если не успело - RST 0 выполняется и сбрасывает машину.

От чего зависит успело или не успело? Скорее всего от модели эмулируемой машины. У ориигнального ZX Spectrum и, например, у ZS Scorpion за время между импульсами прерывания "тикает" 69888 тактов, у Pentagon128 - 71680 тактов. Соответственно, между прерываниями успевает выполниться и разное количество команд, Пентагон может "успеть" выполнить RST 0 до прихода прерывания, подменяющего адрес исполнения, а оригинал - нет.

Spectramine
01.04.2017, 12:15
Может я что то недопонимаю, но насколько я понял из книг по ассемблеру, прерывание начинает обрабатывться после команды IM 2,

Команда IM 2 не начинает обработку прерывания, она задает режим обработки прерывания.


а закончится обработка должна командой RET. Обработка прерывания также может завершиться командой RETI или RETN. А может вообще не заканчиваться, можно на прерываниях построить и главный программный цикл, но так делают редко.


После команды IM 2 обработчик начинает считать такты в своих мудрёных счётчиках, и если результат счёта соответствует расчётному то программа работает , а если нет то доходит до команды RST 0. Нет никаких счетчиков в обработчике прерываний, здесь, по крайней мере. Счетчики есть в основной программе. Вот например цепочка INC E в листинге - кусок такого счетчика.


Но я не врублюсь , что заставляет программу доходить до какого то места и неожиданно начинать с другого. Прерывание и заставляет. По сигналу INT делается подтверждение прерывания, и переход на обработчик прерывания (команды перехода НЕТ, это делается аппаратно, но есть адрес перехода, для режима IM 2 на спеке он хранится в памяти по адресу: (старший байт=регистру I, младший=$FF). А обработчик прерывания уже меняет адрес возврата, обходя этим команду RST 0.


А в моём реальном клоне программа отрабатывает до RST 0 в обоих местах, и не бросает выполняться на пол пути. В чём фокус?

Фокус в нестабильном времени кадра между прерываниями. Из-за вайтовых задержек программа не может точно вычислить время кадра в тактах, и прерывание должно произойти позже расчетного момента перед командой RST 0. То есть RST 0 отрабатывает, и идет сброс.


Я могу предположить, что в отмеченных местах на картинке приходит следующий сигнал INT и каким то чудом прерывает выполнение программы в нескольких тактах от команды RST 0. Но я нигде не читал про такую фишку. Везде описаны прерывания только по команде IM.

Вы неправильно представляете работу системы прерываний. По команде IM задается _режим_обработки_прерывани , а не происходит само прерывание. Сам прерывание происходит по приходу сигнала INT. Этот сигнал приходит со строгой периодичностью, с длиной периода, равной времени кадра между прерываниями (69888 тактов на фирменных 48 к, но с другой длиной на других машинах. Проблема в том, что точно вычислить эту длину на некоторых машинах программно можно, а на некоторых - нельзя (или можно, но используя другие приемы, не такие, как в данной программе)).


И тут назревает следующий вопрос. Если поцессор бросает выпонять программу в этих местах, то откуда начинает дальше? Могу предположить с адреса на вершине стёка.

Во время прихода сигнала прерывания на стек кладется адрес возврата - место, на котором программа была прервана. Команда RET в обработчике прерывания делает переход на это место, считывая его адрес со стека. НО - можно программно в обработчике прерывания изменить этот адрес перехода. В данной программе он просто пропускается на стеке ($FEFE INC SP:INC SP), а переход происходит на следующий адрес, хранящийся на стеке (EI: RET). EI (разрешение прерываний) нужно, т.к. при переходе в обработчик прерывания запрещаются аппаратно.

апро
02.04.2017, 01:49
Я не правильно представлял процес работы прерывания. Спасибо за разъяснения, я всё понял.