Разработка и ромхакинг > Ромхакинг и программирование
Sega MD VDP: Что оно такое и с чем его едят
<< < (3/3)
vladikcomper:

--- Цитата: Segaman от 26 Июль 2011, 09:19:15 ---а на гофере дма шрифт жует :D

--- Конец цитаты ---
Ты про Соник 3 в 1? Где именно шрифты жуются?


--- Цитата: Ti_ от 26 Июль 2011, 15:22:13 ---А как мне кажется  должно работать и move.l d7,(a0) , то есть условие что содержимое должно находится в ram или в регистре. 
(баг то по логике происходит, потому что если что-то типа move.l #$12345678,(a0) , а команда эта и число 12345678, это находится в ром, и из ром же должна передача пойти,только с другого адреса)

--- Конец цитаты ---
Не уверен, что-то мне подсказывает, что если бы можно было адресовать из регистров, они бы обязательно про это упомянули. Но опять же, ничего конкретно сказать не могу, так как не представляю из-за чего такие ограничения берутся. Хотя можно будет попробовать, а так же ради интереса посмотреть, что будет, если нарушить все условия.
Segaman:

--- Цитата: vladikcomper от 27 Июль 2011, 23:00:32 ---Ты про Соник 3 в 1? Где именно шрифты жуются?

--- Конец цитаты ---
в твоей заставке с авторами сборника
Ti_:

--- Цитата: Segaman от 26 Июль 2011, 09:19:15 ---а на гофере дма шрифт жует :D

--- Конец цитаты ---
а дюна на гофере нормально работает?
там сделали проверку если на переходах с 4F000 на 51000 и т.п. данные  оказываются , то переносятся 2-умя кусками через dma.  <_<
Nemesis_c:
нормально, только со звуком проблемы.
Segaman:

--- Цитата: Nemesis_c от 09 Август 2011, 00:08:46 ---нормально, только со звуком проблемы.

--- Конец цитаты ---
я играл, все чудесно. звук в меру жеванный.
большой разницы от оригинала нет.
имхо, играется чюдесно ^_^
Segaman:
до меня доперло, чем основано неперекрашивание нескольких пикселей в начале при смене цвета во время отрисовки картинки.
мне кажется всему виной обработка процедур в момент возникновения прерывания.
дело в том что каждая команда занимает определенное колличество циклов. а так, как прерывание происходит во время исполнения какой либо команды, проц сначала доделывает операцию, а потом только сбрасывается на прерывание, что занимает некоторое время и является причиной недоперекрашивания.
все гениальное просто :D
и тут уж никуда не деться
vladikcomper:

--- Цитата: Segaman от 29 Ноябрь 2011, 18:21:02 ---до меня доперло, чем основано неперекрашивание нескольких пикселей в начале при смене цвета во время отрисовки картинки.
мне кажется всему виной обработка процедур в момент возникновения прерывания.
дело в том что каждая команда занимает определенное колличество циклов. а так, как прерывание происходит во время исполнения какой либо команды, проц сначала доделывает операцию, а потом только сбрасывается на прерывание, что занимает некоторое время и является причиной недоперекрашивания.
все гениальное просто :D
и тут уж никуда не деться

--- Конец цитаты ---

HBlank, согласно внутренним счетчикам VDP, занимает столько времени, сколько нужно на отрисовку 2 пикслелей на экране. Согласно документации, это эквивалентно 36 циклам M68K. (Я это называю по памяти, так что могу немного наврать в цифрах).

Насчет "процессор сначала заканчивает обработку инструкции, а потом переключается на прерывание" - я тоже так думаю, хотя это только моя догадка, так как я не сильно разбираюсь в механизме обработки прерывания. Если оно так, действительно пара циклов может теряться. Однако крайне мало инструкций процессора занимают больше 10 циклов, и думаю, большая редкость застать длинную инструкцию в самом начале ее выполнения.

В то же время, обработка самого прерывания тоже должна занять пару циклов процессора. Нужно сохранить в стеке значение PC (Program Counter - оффсет текущей инструкции), на котором произошло прерывание, а также значение SR (Status Register). Кстати, именно из-за того, что в стеке настраивается состояние SR, для возврата из прерывания нужна специальная инструкция RTE, а не обычный RTS.

Но вряд ли может случиться так, что все эти операции по времени займут больше, чем само прерывание. Вот тот эффект про который ты говоришь, ты заметил в Канслвании. Но видел ли ты его когда-нибудь в Сониках? Я не видел, если только мельком в Соник 3 (в AIZ 2).
Где-то на первой странице этого топика я высказывал мысль, что дело в медленном коде. Думаю, так и есть. Код прерывания не оптимален, понатыкан всякими бранчами, отнимающими время процессора, а может сам перенос цветов в CRAM сделан медленно (например, если перебрасывать по 2 байта, да еще и в цикле, потери времени будут огромны). Ну а если код еще написан на Си...
Вобщем, из-за всего этого палитра не успевает переброситься вовремя, и уже начинается отображение новой строки с еще старой палитрой.
Segaman:
в сонике 3 просто спрайты с волнами на воде.
изза них ничего и не видно.
поправь меня если не прав.

 воще чтоб моск не парить не легче ли замутить DME переброс палитры?
так и быстрее. вдруг успеет? ^_^
vladikcomper:

--- Цитата: Segaman от 30 Ноябрь 2011, 19:09:36 ---в сонике 3 просто спрайты с волнами на воде.
изза них ничего и не видно.
поправь меня если не прав.

--- Конец цитаты ---
Спрайты в виде волн в Гидросити. И причем здесь мерцание пикселей? Мерцают спрайты.
Зато посмотри как интересно проходит линия воды в Angel Island Zone:

Я про этот уровень как раз и говорил. Здесь палитра меняется выборчно и в течении нескольких строк. Создается такой приятный эффект объемности. И только здесь, в AIZ2, в некоторых местах можно увидеть мерцающие пиксели, но они проходят через всю линию.


--- Цитата --- воще чтоб моск не парить не легче ли замутить DME переброс палитры?
так и быстрее. вдруг успеет?
--- Конец цитаты ---
Тоже задумывался, почему в Сониках перенос палитры во время прерывания не через DMA (насчет других игр не знаю). Думаю, дожна быть причина, Юджи Нака же крайне умный и умелый программист. Хотя, надо будет как-нибудь на досуге попробовать, заодно и проверить, как оно ведет себя на реальном железе.
Ti_:

--- Цитата: vladikcomper от 30 Ноябрь 2011, 22:36:33 ---Тоже задумывался, почему в Сониках перенос палитры во время прерывания не через DMA (насчет других игр не знаю).

--- Конец цитаты ---
Если малое количество данных нужно отослать, без дма быстрее. На само его включение больше уйдет времени, это раз. Второе - во время отображения скорость одинаковая.
Segaman:
нуда. так можно отправить сначал одну палитру, потом другую.
а период между ними поставить воще не вопрос :)
кстати в комикс зон творят с этим чюдеса.
взять последнюю 5 и 6 страницы. вода там очень хитрая.
Segaman:
вопрос знающим людям.
ситуация такая. пишу свою игру на сега.
написал свой движ отображения спрайтов и столкнулся с такой проблемой.
не могу согласовать приоритеты между спрайтами. почему то 0й показывает последним.
и еще не много не впетрю, как приоритет контролируется между слоями,
если он в спрайте имеет всего один бит.
Ti_:

--- Цитата: Segaman от 15 Декабрь 2011, 10:40:21 ---почему то 0й показывает последним.

--- Конец цитаты ---
Так сделано значит, счет с 1 по 79 , а 80-ый (0-ой) последний.  Смотри debug-vdp sprites.
Приоритет если 1 значит точно всегда сверху спрайт.
Если 0 - то, видимо еще зависит от того какой приоритет в тайлах в фоне.
vladikcomper:

--- Цитата: Segaman от 15 Декабрь 2011, 10:40:21 ---вопрос знающим людям.
ситуация такая. пишу свою игру на сега.
написал свой движ отображения спрайтов и столкнулся с такой проблемой.
не могу согласовать приоритеты между спрайтами. почему то 0й показывает последним.
и еще не много не впетрю, как приоритет контролируется между слоями,
если он в спрайте имеет всего один бит.

--- Конец цитаты ---
С нулевым спрайтом все логично - вначале VPD отображает его, потом он перекрывается следующим по списку тайлом, и так далее, что в итоге оказывается последним.

Флаг приоритета используется, чтобы поместить спрайт поверх всех планов, удобно для того, чтобы сделать HUD, например.

Без флага приоритета спрайт отображается поверх планов А и Б, и его могут перекрыть только тайлы планов А и Б с высоким приритетом. Вот как контроллер приоритетов VDP распределяет слои (приритеты даю по возврастанию):

1) Фоновый цвет
2) План Б с низким приоритетом
3) План А с низким приоритетом
4) Спрайты с низким приоритетом
5) План Б с высоким приоритетом
6) План А с высоким приоритетом
7) Спрайты с высоким приоритетом

Низкий приоритет - это когда у спрайта или тайла на плане бит приоритета равен 0, высокий - 1.
Segaman:
спасибо большое, проблема разрешилась ^_^
Segaman:
опять проблема. с горизонтальным прерыванием.
хочу затемнить нижнюю часть экрана, а вместо этого максимум получается мерцание по 2 половинкам экрана.
т.е. сначала сверху светло, снизу темно, а на след кадре уже вверху темно, внизу светло
из 2 часов попыток ничего путного невышло.
узнал только что если записать 8A20 то горизонтальное прерывание будет происходить всегда через каждые 32 строки ($20)
пробовал и это использовать, всеравно ничего не выщло :'(
может я чтото упустил?
vladikcomper:
Горизонтальные прерывания - вещь очень прихотливая, тут если не уследить за какой-то малейшей деталью или не учесть мелочь - все пойдет комом.


--- Цитата ---узнал только что если записать 8A20 то горизонтальное прерывание будет происходить всегда через каждые 32 строки ($20)
--- Конец цитаты ---
Все верно, регистр VDP $0A задает интервал в строках, через который нужно совершать горизонтальное прерывание.

В VDP есть внутренний счечик горизонтальных линий, который уменьшается на единицу с каждой отрисованной линией, и когда он достигает нуля, случается горизонтальное прерывание (если включено), а в счетчик загружается значение регистра $0A. Помимо этого, счетчик автоматически обновляется на линии 0 (начало кадра) и на линиях 225-261 (период VBlank'а). Последнее означает, что во время VBlank'а горизонтальные прерывания случатся не должны.

Важно отметить, что счетчик *не* обновляется как только в регистр $0A записывается новое значение. Он обновляется только при вышеописанных условиях. И это логично, иначе счетчик линий потерял бы привязку к началу рисования кадра.

Поскольку кадр состоит из 224 линий, если задать счетчику значение меньшее, чем 112, горизонтальное прерывание случится больше одного раза. Segaman, если у тебя оно случается по нескольку раз за кадр, это может объяснить мерцание, а может, это какой-нибудь баг в коде.

Если ты хочешь сделать прерывание только в одном месте, нужно позаботиться о том, чтобы после первого вызова, код прерывания в пределах одного кадра больше не выполнялся. Для этого можно сделать флаг в памяти и включать его в процедуре прерывания. И выходить из кода прерывания, если флаг включен. Потом, можно сбрасывать флаг в процедуре вертикального прерывания, чтобы к новому кадру он снова был чист. Также в коде горизонтального прерывания можно задавать регистру VDP $0A значение $DF, так, прерывание гарантированно случится не более двух раз (при следующем прерывании в счечик будет загружено значение $DF - 223 линии).
Segaman:

--- Цитата: vladikcomper от 14 Февраль 2012, 20:00:17 ---Горизонтальные прерывания - вещь очень прихотливая, тут если не уследить за какой-то малейшей деталью или не учесть мелочь - все пойдет комом.

--- Конец цитаты ---
это я уже уяснил. спасибо за хелп.
чтоб я без вас делал ^_^
Навигация
Главная страница сообщений
Предыдущая страница

Перейти к полной версии