| Разработка и ромхакинг > Ромхакинг и программирование |
| [NES] регистры PPU |
| (1/2) > >> |
| neoborg:
всем привет. у меня проблема вывода графики на экран с помощю регистров. я записываю нужные мне 2 байта в 2006, затем номер тайла в 2007. по идее байт в 2006 должен автоматически увеличиваться после записи в 2007. а у меня в 2006 через 8-9 раз после записи в 2007 сбрасывается и начинается заново. то есть допустим записал в 2006 20, затем 00. пишу 60 в 2007 9 раз подряд. по идее в 2006 адрес уже 2008. а оно скидывает мне на 2000, и все по новой. снова до 2008, и снова на 2000, сколько раз подряд я бы не писал. следовательно не могу нормально нарисовать свое изображение, потому что все пишется по 2000-2008. причем код игры в это время ничего не пишет в изображение PPU, только цвет меняет раз в несколько кадров. я посмотрел как сам код игры уже рисует, вижу что он сначала делает BIT по 2002. ок, я тоже сделал, начало уже доходить в 2006 где-то до 201A, затем снова сбрасывается. свой код я не цеплял к коду игры, писал отдельный. я проверял, если я запусткаю свой код во время того, как игра выводит графику, то таких проблем нет, все пишется по порядку и сколько угодно долго. значит что-то нужно включить или изменить до начала вывода графики, но я в графике и регистрах плохо шарю. что нужно сделать? по-другому сформулирую вопрос, с чего начинается вывод графики на экран? если можно, то поподробнее |
| Xerox:
neoborg, задействуй Y или X в своих процедурах, только смотри, чтобы он в этот момент не использовался кодом. Если что, сохрани прошлое значение Y куда нибудь, затем после процедуры восстанови его. Примерная программка: 07:C064:A9 3F LDA #$3F - пишешь нужные значения в 2006, только помни что если хочешь записать в 2000, сначала пиши 00, затем 20 07:C066:8D 06 20 STA $2006 = #$00 07:C069:8E 06 20 STX $2006 = #$00 07:C06C:A0 20 LDY #$20 - здесь указываешь количество байтов, которые хочешь записать 07:C06E:BD 00 03 LDA $0300,X @ $0300 = #$0F - пишешь свои значения графики, если хочешь использовать кучу, то лучше задействовать Х, чтобы они подхватывались автоматически >07:C071:8D 07 20 STA $2007 = #$00 - пишешь их в 2007 07:C074:E8 INX - х повышается для следующего твоего значения 07:C075:88 DEY - уменьшается на 1 количество байтов, нужных для записи в 2007 07:C076:D0 F6 BNE $C06E - процедура выполняется до тех пор, пока не запишутся все твои байты |
| neoborg:
--- Цитата: Xerox от 04 Сентябрь 2015, 09:30:15 ---neoborg, задействуй Y или X в своих процедурах --- Конец цитаты --- уже 04:A006:60 RTS ----------------------------------------- >04:A007:8A TXA 04:A008:48 PHA 04:A009:98 TYA 04:A00A:48 PHA 04:A00B:A5 BF LDA $00BF = #$00 04:A00D:C9 B4 CMP #$B4 04:A00F:F0 40 BEQ $A051 04:A011:2C 02 20 BIT $2002 = #$08 04:A014:A0 00 LDY #$00 04:A016:A2 10 LDX #$10 04:A018:A5 BC LDA $00BC = #$00 04:A01A:D0 04 BNE $A020 04:A01C:A9 20 LDA #$20 04:A01E:85 BC STA $00BC = #$00 04:A020:8D 06 20 STA $2006 = #$40 04:A023:A5 BD LDA $00BD = #$00 04:A025:8D 06 20 STA $2006 = #$40 04:A028:A5 BF LDA $00BF = #$00 04:A02A:D0 04 BNE $A030 04:A02C:A9 B0 LDA #$B0 04:A02E:85 BF STA $00BF = #$00 04:A030:B1 BE LDA ($BE),Y @ $003C = #$00 04:A032:8D 07 20 STA $2007 = #$00 04:A035:C8 INY 04:A036:CA DEX 04:A037:D0 F7 BNE $A030 04:A039:A5 BD LDA $00BD = #$00 04:A03B:69 10 ADC #$10 04:A03D:85 BD STA $00BD = #$00 04:A03F:A5 BD LDA $00BD = #$00 04:A041:D0 02 BNE $A045 04:A043:E6 BC INC $00BC = #$00 04:A045:A5 BE LDA $00BE = #$00 04:A047:69 10 ADC #$10 04:A049:85 BE STA $00BE = #$00 04:A04B:A5 BE LDA $00BE = #$00 04:A04D:D0 02 BNE $A051 04:A04F:E6 BF INC $00BF = #$00 04:A051:68 PLA 04:A052:A8 TAY 04:A053:68 PLA 04:A054:AA TAX 04:A055:60 RTS ----------------------------------------- Добавлено позже: --- Цитата: Xerox от 04 Сентябрь 2015, 09:30:15 --- 07:C064:A9 3F LDA #$3F - пишешь нужные значения в 2006, только помни что если хочешь записать в 2000, сначала пиши 00, затем 20 --- Конец цитаты --- вообще-то в регистр 2006 сначала пишется старший байт, затем младший. так что для 2000 сначала писать 20, затем 00. |
| Xerox:
--- Цитата: neoborg от 04 Сентябрь 2015, 09:32:48 ---уже вообще-то в регистр 2006 сначала пишется старший байт, затем младший. так что для 2000 сначала писать 20, затем 00. --- Конец цитаты --- Да, извиняюсь, сплю наверное еще :))) Я так понял по коду, что ты пишешь 16 байтов, а потом вообще выходишь из процедуры. А тебе нужно записать больше, да? Почему не хочешь записать все нужные байты, а потом выйти? После А037 он заканчивает записывать 16 байтов, которые в Х, а затем идет вниз по коду и дальше у тебя нет возврата наверх, он идет на RTS. А вообще неплохо бы посмотреть код в деле :) |
| neoborg:
--- Цитата: Xerox от 04 Сентябрь 2015, 10:00:43 ---Да, извиняюсь, сплю наверное еще :))) Я так понял по коду, что ты пишешь 10 байтов, а потом вообще выходишь из процедуры. А тебе нужно записать больше, да? Почему не хочешь записать все нужные байты, а потом выйти? --- Конец цитаты --- ну да, рано еще, понимаю) я пишу всего 16 байтов (10 в hex, точнее 0F, но код завершается, когда доходит до 00) за раз, потому что сразу много не получается, я писал что 2006 обнуляется. я написал такой код, чтобы он работал каждый кадр в течение 64 кадров и потиху вывел мне все нужное по адресам 2000-23ff ppu, но он даже так не пашет. на следующий кадр все равно начинает обнуляться. наверняка есть что-то, что заставит его писать нормально. я добавил в первый пост, что если я запущу свой код во время вывода графики по изначальному коду игры, оно сработает и будет писать по порядку |
| Xerox:
neoborg, Ну просто есть подозрение, что у тебя адрес BD после RTS опять где то обнуляется по коду. А нельзя ром посмотреть в деле? так вслепую сложно сказать |
| neoborg:
--- Цитата: Xerox от 04 Сентябрь 2015, 10:06:51 ---neoborg, Ну просто есть подозрение, что у тебя адрес BD после RTS опять где то обнуляется по коду. А нельзя ром посмотреть в деле? так вслепую сложно сказать --- Конец цитаты --- это наврядли, но не в этом смысл. я в fceux прогоняю код вручную, он не работает как надо, обнуляется 2006. значит он и на деле бы также работал Добавлено позже: --- Цитата: Xerox от 04 Сентябрь 2015, 10:06:51 ---neoborg, А нельзя ром посмотреть в деле? так вслепую сложно сказать --- Конец цитаты --- ну попробуй например вписать вот это A9208D0620A9008D0620A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720A9808D0720 куда-нибудь и запустить. сначала когда графика нарисуется, а затем во время вывода графики. проверяй ppu по адресу 2000, пишет он все по порядку или нет ром можешь отсюда взять http://vk.cc/4a2UGb, я запускаю его либо пока рисуется графика сначала, либо когда показывает выбор режима игры Добавлено позже: в общем, я заметил, что код работает\не работает в зависимости от банка памяти, который сейчас активен. я хотел прицепить код к чтению кнопки паузы на джойстике, но видимо нужно выбрать другой банк и найти к чему прицепиться теперь. Добавлено позже: ----------- ок, я по-другому сформулирую вопрос. с чего начинается вывод графики на экран? ----------- |
| Xerox:
neoborg, хмм... ну мне помогло отключение на время ppu LDA 00 STA 2001 затем пишешь все байты, которые хочешь вместить и включаешь его обратно. lda 1e sta 2001 Пишет все байты до конца даже в середине игры. Не знаю правда, как это отразится на твоей игре, но проверь :) Наверное выключать ппу стоит только если ты одноразово хочешь что то обновить, большой кусок байтов. Если нужно постоянно что то обновлять, каждый кадр, то наверное мой метод не поможет. А, кстати еще по коду, попробуй добавить после BIT $2002 BPL vblancwait (10 FB), чтобы он проматывал текущий vblanc до конца и начинал новый с нуля, возможно поможет. |
| neoborg:
--- Цитата: Xerox от 04 Сентябрь 2015, 13:29:53 ---neoborg, хмм... ну мне помогло отключение на время ppu LDA 00 STA 2001 затем пишешь все байты, которые хочешь вместить и включаешь его обратно. lda 1e sta 2001 Пишет все байты до конца даже в середине игры. Не знаю правда, как это отразится на твоей игре, но проверь :) Наверное выключать ппу стоит только если ты одноразово хочешь что то обновить, большой кусок байтов. Если нужно постоянно что то обновлять, каждый кадр, то наверное мой метод не поможет. А, кстати еще по коду, попробуй добавить после BIT $2002 BPL vblancwait (10 FB) --- Конец цитаты --- спасибо. я уже повытирал все записи в регистры от 2000-2005 до тех пор, пока не перестала выводиться графика. оказалось, что при записи A8 в 2000 позволяет писать по порядку в 2007, а при 28 запрещает. разница между 28 и A8 в том, что при A8 байт D7 - 1, а при 28 - 0 (цитата: формирование запроса немаскируемого прерывания NMI при кадровом синхроимпульсе: 0 - запрещено; 1 - разрешено). короче моего времени хватило только на то, чтобы до этого дойти, завтра буду пробовать дальше. но вроде получилось промотать код и записать в 2007 по порядку. я не знаю че такое vblancwait (10 FB) |
| Xerox:
neoborg, Ну я так понял, что писать в 2007 можно только когда идет vblank и длится он примерно 2200 циклов. BPI 2002 инициирует его, а опкод BPL ждет, когда начнется следующий vblanc. В хексе это будет 10 FB. Ну раз у тебя и так работает, тогда наверное можно и не писать. Сорри, что ничем не помог - сам еще только разбираюсь с этим :) |
| neoborg:
--- Цитата: Xerox от 04 Сентябрь 2015, 22:01:54 ---neoborg, --- Конец цитаты --- все равно спасибо за попытки) отстальные поленились ответить. я вот сам только начал графику осваивать. вроде ромхачу непрохо, и в спрайтах шарю чутка, но всегда же чего-то не знаешь/ все равно чета не получается. |
| CaH4e3:
отвечу на главный вопрос: графика начинается обычно с прочтения документации... для денди таковой написано огромное количество, в том числе на русском языке, подробно описывающих, как надо и как не надо программировать денди.. а вообще, надо до кучи еще разобраться, что игра сама делает и как работает, прежде чем что-то в нее вставлять... если она ничего не выводит, это ничего не значит. каждый кадр она может обнулять регистры 2006 перед скроллом и тп если хочешь вывести графику в игре, найди, как эту графику выводит она и сделай также или теми же функциями. |
| neoborg:
--- Цитата: CaH4e3 от 05 Сентябрь 2015, 11:45:22 ---отвечу на главный вопрос: графика начинается обычно с прочтения документации... для денди таковой написано огромное количество, в том числе на русском языке, подробно описывающих, как надо и как не надо программировать денди.. а вообще, надо до кучи еще разобраться, что игра сама делает и как работает, прежде чем что-то в нее вставлять... если она ничего не выводит, это ничего не значит. каждый кадр она может обнулять регистры 2006 перед скроллом и тп если хочешь вывести графику в игре, найди, как эту графику выводит она и сделай также или теми же функциями. --- Конец цитаты --- ого, сам санчез написал) я не нашел таких доков, реально искал. вот единственный нормальный типа мануал по денди , 2я часть http://gfaq.ru/publ/sistemy/konsoli_stacionarnye/igrovaja_pristavka_dendy_chast_2/35-1-0-1923 , который я нашел и я смотрел как игра это делает, мне это не помогло. я ж в первый раз это делаю, может просто не вижу в упор того чего надо. мне нужен подробный ответ. например "рисование графики начинается с записи хх в регистр 2000, затем еще какие-нибудь 2003 и тд, затем BIT 2002, и затем уже 2006-2007". ну или хотя бы ссылки на эти доки |
| blackbird_ru:
neoborg, вот те доки. http://nintendoage.com/pub/faq/NA/index.html?load=nerdy_nights_out.html - туторы с самого начала http://nesdev.com/NESDoc.pdf - неплохое собрание основной информации в одном месте http://e-tradition.net/bytes/6502/6502_instruction_set.html - удобный сет по асму. только шрифт чуть больше сделать нужно. http://wiki.nesdev.com/w/index.php/Nesdev_Wiki - всё обо всём. Найдёшь что нужно, если знаешь что искать, а если не найдёшь, есть форум и куча примеров на нём. |
| neoborg:
--- Цитата: blackbird_ru от 05 Сентябрь 2015, 16:14:26 ---neoborg, вот те доки. --- Конец цитаты --- спасибо, но не помогло. ничего нового не узнал, что не понимал осталось непонятным, везде пишут что типа пиши 2 раза в 2006, затем в 2007, адрес 2006 будет постоянно увеличиваться и будет тебе щастье. только не пашет нирена. я даже пытался насильно вписывать в 2006 каждый шаг, тоже не получилось 04:A206:60 RTS ----------------------------------------- 04:A207:8A TXA 04:A208:48 PHA 04:A209:98 TYA 04:A20A:48 PHA 04:A20B:A2 00 LDX #$00 04:A20D:A9 20 LDA #$20 04:A20F:8D 06 20 STA $2006 = #$21 04:A212:8E 06 20 STX $2006 = #$21 04:A215:BD 00 B0 LDA $B000,X @ $B000 = #$00 04:A218:8D 07 20 STA $2007 = #$00 04:A21B:E8 INX 04:A21C:D0 EF BNE $A20D 04:A21E:68 PLA 04:A21F:A8 TAY 04:A220:68 PLA 04:A221:AA TAX 04:A222:60 RTS ----------------------------------------- зато я вот что вычитал: Генерация кадра начинается с левого верхнего угла и идет по строкам вниз. По окончании вывода каждой строки в видеосигнал добавляется строчный синхроимпульс. Так последовательно отображаются все 240 строк, составляющие полный экран. В завершение видеопроцессор посылает одновременно кадровый синхроимпульс и сигнал немаскируемого прерывания NMI. Это занимает время, необходимое для вывода четырех телевизионных строк. Затем видеопамять становится доступной в течение периода формирования кадрового синхроимпульса. Данный период равен времени, затрачиваемому на вывод 20 телевизионных строк, после чего доступ к видеопамяти запрещается и начинается развертка нового кадра. Такой процесс повторяется 50 раз в секунду для системы PAL и 60 раз в секунду для NTSC. и как мне понять что вот сейчас пора писать в видеопамять пока доступ открыт? мне вообще может кто-нибудь просто сказать что и когда надо до этого прописывать, а не посылать читать доки, в которых нету даже примеров? так, ну вроде получилось с помощью принудительной записи в регистры как я выложил выше, даже сделал прикольный эффект, только почему на nestopia криво отображается? на mednafen и fceux нормально |
| blackbird_ru:
--- Цитата: neoborg ---и как мне понять что вот сейчас пора писать в видеопамять пока доступ открыт? --- Конец цитаты --- так прерывание срабатывает же. в роме указан адрес где оно начинается. Добавлено позже: И если ничего не понял, значит плохо читал. Так всё расписано, всё. |
| Xerox:
--- Цитата: neoborg от 05 Сентябрь 2015, 20:14:00 ---так, ну вроде получилось с помощью принудительной записи в регистры как я выложил выше, даже сделал прикольный эффект, только почему на nestopia криво отображается? на mednafen и fceux нормально --- Конец цитаты --- На нестопии вообще больше половины хаков криво отображаются :) |
| evgeny:
--- Цитата: Xerox ---На нестопии вообще больше половины хаков криво отображаются --- Конец цитаты --- Потому что нестопия точнее железо эмулирует и все недочеты хаков вылезают наружу. |
| Xerox:
evgeny, так смысл тогда на нестопии играть, если на том же фсеуксе все нормально идет? Обычному игроку пофиг, что там точнее эмулирует, главное, чтобы игрушка шла как надо :) |
| evgeny:
Xerox, Ну так и авторы эмуляторов разные цели. У кого-то чтобы все наиболее точно соответствовало железу, а у кого-то обеспечить как можно большую совместимость со всеми играми, даже если они плохо работают на железе. Хотя fceux позиционировался как точный, как ни странно. Но я лично неоднократно убеждался, что нестопия ближе к железу. |
| Навигация |
| Главная страница сообщений |
| Следующая страница |