Картинка грузится, звук есть, но игрушки пока не стартуют.
http://dl.dropbox.com/u/12408899/CVB...-232143%29.zip
Вид для печати
Картинка грузится, звук есть, но игрушки пока не стартуют.
http://dl.dropbox.com/u/12408899/CVB...-232143%29.zip
Интересно возможно ли реализация данного устройства на одной меге?
По ногам вроде хватает, хватит ли по производительности?
Василий Николаевич, когда уже цвет-то будет? Не надоело в сером купаться?
Сие для меня в оталённой перспективе. Но если кто меня ткнёт носом где можно почитать про VGA так, чтобы можно было понять и реализовать - буду несказанно рад.
Для начала прикинь потянет ли АВРка видеовыхлоп в два раза бымтрей. По сути и упрощенно - нужно выводить каждую строку изображения не один, а два раза подряд, вместе со строчным синхроимпульсом. Причем в два раза быстрей. Т.н. "скандаблер". Вот и весь ВГА.
Можно почитать это:
Всем привет. Только что запускал R-TYPE. Но корабля не было и через 10 секунд свалился в сбой. Ни у кого не завалялось тестовых программок для проверки эмуляции? Типа для проверки корректности выполнения команд Z80?
всем спасибо.
Смотрите в приложении набор утилиток для тестирования. Начать стоит, наверное, с z80tests.
Благодарю, Higgins. Запустил Z80tests и в итоге кругом failed: (да как он вообще у меня работает?)
Ну, что, хорошее начало. :)
Судя по картинке, тест даже не может корректно сообщить об ошибке, то есть проблемы с какими-то основными вещами.
Можно попробовать еще раз глазами внимательно проверить реализации самых первых инструкций в тесте и, если будут найдены ошибки, исправить их и попробовать тест еще раз. Если тест сообщит, что тест для этих инструкции пройден успешно, значит сам код тестирования исполняется верно, и можно продолжать искать ошибки для других инструкций. Иначе, нельзя быть уверенным в том, что код тестирования исполняется верно, и тогда сообщения Failed/Passed не имеют никакого значения. В этом случае следует начать с проверки основных инструкций (арифметика, сравнения и переходы) и флагов (C, Z).
Ну вот, например, SCF: MRIN failed: что это за MRIN? SCF я делаю элементарно:
EX37: CBR F,1<<NN - сбрасываю N
SBR F,1<<CC - устанавливаю с
NOP - коррекция времени выполнения команды
JMP LOOP - возврат в следующий цикл M1
и ещё не ясно что такое expected GRND
А Basic глючит следующим образом: PRINT 10 - в ответ - 1. PRINT 12.21 - в ответ 1.21. Целую часть пишет всегда либо 1 (если >=1) либо 0 (<1). Синус, косинус считает при этом верно. При загрузки программ с кассеты загрузчик стартует только со второй попытки загрузки, а в первый раз выдаёт OK и сваливается в main-loop.
А Basic глючит следующим образом: PRINT 10 - в ответ - 1. PRINT 12.21 - в ответ 1.21. Целую часть пишет всегда либо 1 (если >=1) либо 0 (<1). Синус, косинус считает при этом верно. При загрузки программ с кассеты загрузчик стартует только со второй попытки загрузки, а в первый раз выдаёт OK и сваливается в main-loop.
А вот и R-TYPE.
А вот и Robocop:
MRIN означает, что утилита не может правильно вывести значение контрольной суммы, т.е. ошибки эмулятора приводят к тому, что вместо шестнадцатиричных цифр печатаются неподходящие буквы и токены.
Тест печатает цифры контрольной суммы с помощью RST #10. Для ориентации в коде: само значение контрольной суммы хранится по адресу #9527. По адресам #8926 - #8931 лежит тело цикла тестирования. Процедура по адресу #80F5 печатает значение в HL (собственно, контрольную сумму). Процедура #80FE печатает значение в A. Процедура #810B печатает значение в четырех младших битах A, то есть одну шестнадцатиричную цифру.
Все эти процедуры печати очень простые и не работать там, в общем-то, нечему, за одним исключением: процедура #810B использует DAA. Это для вас должно быть звоночком. Во-первых, потому что проблемы с этой инструкцией -- обычное дело для эмуляторов. Во-вторых, потому что проблемы с печатью чисел в BASIC тоже указывают на возможные проблемы именно с этой инструкцией.
Значит, вопрос такой: как вы считаете результат для DAA?
Посчитать DAA можно так:
Команда короткая -- 4 такта, поэтому в вашем случае, чтобы выдержать скорость эмуляции, наверное, понадобится вводить таблички.Цитата:
#define PF_LOG(n) ((!PF_LOG4((n)) == !PF_LOG4((n) >> 4)) << PF_BIT)
case 0x27: /* DAA: f(4) */
d = 0x0000;
if((Z80_AF & Z80_CF) || Z80_AF >= 0x9a00) d |= 0x6000, Z80_AF |= Z80_CF;
if((Z80_AF & Z80_HF) || ((Z80_AF & 0x0f00) >= 0x0a00)) d |= 0x0600;
if(!(Z80_AF & Z80_NF)) Z80_AF = ((Z80_AF + d) & 0xff00) |
(((Z80_AF & 0x0f00) >= 0x0a00) << HF_BIT) | (Z80_AF & Z80_CF);
else Z80_AF = ((Z80_AF - d) & 0xff00) |
(((Z80_AF & Z80_HF) && (Z80_AF & 0x0f00) <= 0x0500) << HF_BIT) | Z80_NF | (Z80_AF & Z80_CF);
r = (Z80_AF >> 8);
Z80_AF |= PF_LOG(r) | (!r << ZF_BIT) | (r & (Z80_SF | Z80_XF | Z80_YF));
Нашелся еще один тест на инструкции. Смотрите в приложении.
Она у меня как раз и сделана таблицей - вытаскиваю AF из EEPROM - там как раз 4 К и хватает впритык. Но просто саму таблицу пока не сгенерировал. И проблема как раз в том, что не сваливаюсь я к исполнению этой команды. Спасибо за подсказку !!!
ZEXFIX не грузится. Загрузчик проглатывает, он стартует, а при дальнейшей загрузке уходит в сброс. Может код можно ещё как-то подгрузить?
Пробовал так: CLEAR 32768: LOAD "" CODE: RANDOMIZE USR 32768
Итог приложен. Сваливается в сброс, режим G и ворчит при нажатии на клавишу.
Higgins особую благодарность. Ткнул носом прямо в проблему. Буду генерировать DAA.
Попытался реализовать DAA. Уже лучше:
Отлично. Видно, что DAA свое дело делает.
SCF тестируется в паре с CCF, поэтому пока оба не будут работать первый тест не пройдем. Я посмотрел ваш старый код для CCF -- выглядит правильно, но нет копирования битов 3 и 5 из A в F. Для теста это существенно. Но: я попробовал тест на SCF без копирования битов 3 и 5 в CCF и у меня не получилось то же значение, что на вашей картинке. Стало быть, еще могут быть проблемы в других инструкциях, задействованных в подсчете контрольной суммы.
Исправил DAA. Стало ещё лучше. Уже PRINT выдаёт адекватные значения.
Прилагаю тесты.
Шлю данные через PC-2:
Начиная с 0X8085 но не до конца:
Значения регистров в первой строке похожи на правду. Но:
1) Нужны еще значения регистров IX и IY и
2) Не понятно, почему после инструкции по адресу #8085, которая должна быть "LD HL, (nn)", исполняется инструкция по адресу #0038. До первого CALL/RST там еще далеко.
Забыл отключить маскируемое прерывание.
Там вначале есть RST10: он пишет SCF : . Вот что сейчас (пока не до конца. Процесс долгий.)
Инструкция "OR L" по адресу #808E не взводит флаг PF при A=#80 и L=#C2.
Посчитать значение флага можно так (n -- результат операции):
Цитата:
#define PF_LOG(n) ((!PF_LOG4((n)) == !PF_LOG4((n) >> 4)) << PF_BIT)
#define PF_LOG4(n) ((1u << ((n) & 0xf)) & 0x9669u)
#define PF_BIT 2
Угу. Только мне от этой двоичной арифметики что-то нехорошо становится. Можно это как-то проще интерпретировать? Я так понимаю: если в результате операции произошло изменение (то что стало минус то что было), превышающее значение 0f, значит флаг V возводится?
А в AVR бит V вообще как-то странно используется ... Операция OR, например, его просто сбрасывает.
Есть вторая часть трейсинга:
PF для битовых операций (включая OR) считается не так, как для арифметических, не по переменам знаков.
Интерпретировать эту арифметику очень просто: 0x9669 это просто битовый массив размером 16, т.е. числам 0...15 поставлено в соответствие значение 0 или 1. Макрос PF_LOG4(n) реализует это соответствие: для числа (n) в диапазоне 0..15 он возвращает поставленное ему в соответствие значение -- 0 или 1. Макрос PF_LOG(n) сравнивает значения, которые дает PF_LOG4() для четырех старших и четырех младших разрядов своего аргумента (n). Если эти значения совпадают, значит PF должен быть взведен, иначе PF должен быть сброшен.
Да, тяжело мне иметь дело с профкссиональным эмуляторщиком ...
Для начала не могли бы вы мне, любителю - самоучке объяснить в этой ситуации сам смысл флага P в этой инструкции? Это влаг чётности, переполнения дополнения до 2 или что-то другое?
Предыдущие объяснения я понимаю так:
Флаг Р определяется только по значению результата после выполнения инструкции. Берутся две тетрады результата - старшая и младшая. Каждой ставится в соответствие по одному биту - 1 или 0 в соответствии со значением каждой тетрады (0-15). Если эти два бита равны - флаг возводится, не равны - сбрасывается. Если это так - мне останется только уяснить сам принцип этого соответствия - PF_LOG4(n) - имеется ли здесь в виду (прошу прощения за такую глупость) функция логарифма по основанию 4 ?
Для битовых операций это флаг четности. Его можно реализовать одной большой табличкой, а можно двумя маленькими, подсчитывая четность не для восьми разрядов, а для двух половинок из четырех разрядов.
Да, значение флага зависит только от результата операции.
Верно.
"PF" значит флаг PF. "LOG" означает реализацию флага для логических операций (еще есть PF_ARI() -- для арифметических операций). "4" значит, что четность вычсляется для четырехразрядного операнда.
А-а-а-а-а-а ...
Так чётность у меня уже есть таблицей .....
Просто читаю мануал на Z80, а там про OR написано: P/V is set if overflow; reset otherwise. Ну я его и оставляю таким, как у AVR. Что-ж это значит, ерроры в мануале? Да уж ....
А у AND r, CP r, ADC A,r, ADD A,r, SUB r и SBC r там тоже overflow стоит ...
И ещё: и ещё, и ещё .... Всю ночь кулером гудел. Жена уже ругается: