| Приставки > Картриджи / диски |
| Дампинг, обсуждаем, делимся ромами своих дампов |
| << < (5/7) > >> |
| stargazer:
Все, я победил этот странный баг с искаженными цветами :cool: Обновил архив с исходниками и скомпилированными файлами ядра. Проблема никак не связана с моими правками и проявилась только из-за более новой версии компилятора. Вот функция, которая читает 16-битное слово из регистра VDP, в нашем случае из регистра данных с указателем в CRAM --- Код: ---/* vdp_ctrl.c */ static unsigned int vdp_68k_data_r_m5(void) { uint16 data = 0; /* Clear pending flag */ pending = 0; /* Check destination code (CD0-CD3) & CD4 */ switch (code & 0x1F) { case 0x00: { /* read two bytes from VRAM */ /* .... */ break; } case 0x04: { /* VSRAM index */ int index = addr & 0x7E; /* .... */ break; } case 0x08: { /* Read 9-bit word from CRAM */ data = *(uint16 *)&cram[addr & 0x7E]; /* Unpack 9-bit CRAM data (BBBGGGRRR) to 16-bit bus data (BBB0GGG0RRR0) */ data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1); /* Unused bits are set using data from next available FIFO entry */ data |= (fifo[fifo_idx] & ~0xEEE); /* .... */ break; } case 0x0c: /* undocumented 8-bit VRAM read */ { /* .... */ break; } default: { /* Invalid code value (normally locks VDP, hard reset required) */ break; } } /* Increment address register */ addr += reg[15]; /* Return data */ return data; } --- Конец кода --- А вот функция чтения 32-битного значения из памяти при эмуляции инструкций CPU 68000, например для инструкций типа "move.l (a0),d1". Переменная "temp->read16" для данного случая содержит указатель на функцию, приведенную выше. --- Код: ---/* m68kcpu.h */ INLINE uint m68ki_read_32(uint address) { cpu_memory_map *temp; uint val; m68ki_set_fc(FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */ m68ki_check_address_error(address, MODE_READ, FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */ temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; if (temp->read16) val = ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2))); else val = m68k_read_immediate_32(address); #ifdef HOOK_CPU if (UNLIKELY(cpu_hook)) cpu_hook(HOOK_M68K_R, 4, address, val); #endif return val; } --- Конец кода --- Найдете ошибку? :) Порядок вызовов read16 в строке "val = ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));" не определен. При этом результат зависит от этого порядка, так как внутри read16 -> vdp_68k_data_r_m5 происходит увеличение внутреннего адреса VDP. В данном случае, компилятор почему-то решил, что выгоднее сначала посчитать правую часть выражения, а затем - левую. В результате в 32-битном значении старшее и младшее слова оказались перепутанными. Этот баг относится к классу "Undefined Behavior" |
| warezhunter_:
Попалась мне в руки вот такая китайская многоигровка: https://aliexpress.ru/item/1005003016654103.html Она интересна тем, что содержит в себе хакнутые версии игр. Например на кнопку Select в некоторых играх восстанавливается здороаье, в Felix The Cat можно трансформироваться в различные формы на кнопку Select. Мне даже удалось сдампить меню этой многоигровки и запустить через Fceux. Надо как то игры все повытаскивать оттуда. |
| aquasnake:
--- Цитата: stargazer от 20 Июль 2025, 23:29:42 ---doragasu --- Конец цитаты --- S29GL064: Spansion Nor-flash 64Mbit YX5200: 悦欣 sigle chip mp3 decoder(www.yxin18.com) HCT377: Latch, Octal D-type flip-flop The dumpped 4MB ROM may not be the full data, the full ROM I guess should be the size of 8MB. Despite having almost half of the data redundancy, the data at certain addresses is different. In principle, a RAM chip is needed, but by doubling the redundant data and using a latch to control the switching of the highest address bit, cost reduction can be achieved. |
| Werton:
--- Цитата: stargazer от 23 Июль 2025, 23:37:39 ---Этот баг относится к классу "Undefined Behavior" --- Конец цитаты --- Нет, это Unspecified Behavior :) |
| warezhunter_:
Попалась на глаза мне вот эта одноигровка: https://aliexpress.ru/item/1005002165797973.html и значит решил я её сдампить. Смотрю на плату а на ней квадратная микросхема SMD133 и еще две микросхемы CS18LV20483 и S29GL064N. Начинаю гуглить SMD133 это маппер MMC3, S29GL064N - 64 mbit флэш-память, CS18LV20483 - 256k SRAM-память. При попытке сдампить под MMC3 ничего не работает, помучался немного и полез гуглить как эта микросхема SMD133 работает и наткнулся на маппер 268 на сайте nesdev.org, еще раз внимательно разглядываю картридж и вижу надпись на нём Mindkids, вижу в таблице, что это маппер 268.0 или 268.1, дамплю как --mapper 268.0. Открываю его в Fceux 2.6.6 и он работает! Надо было додуматься еще одноигровку на нём сделать. :wacko: |
| JRBVZ:
Видимо для китайца S29GL064 дешевле чем аналогичная память меньшего объема, а вся сборка дешевле, чем что-то подобное на dip микросхемах. Так что вопрос только в экономике. |
| warezhunter_:
А вот еще один экземпляр на маппере 268.1 покупался примерно года 3 назад, сделан на базе Pocket Games 150 in 1 |
| warezhunter_:
И еще один, вот этот: https://aliexpress.ru/item/1005004232303718.html Только разобрать у меня его не получилось, ломать его я не хочу, но он сдампился с маппером 268.0, после чего запустился на эмуляторе. |
| Rumata:
--- Цитата: JRBVZ от 05 Сентябрь 2025, 11:52:34 ---Видимо для китайца S29GL064 дешевле чем аналогичная память меньшего объема, --- Конец цитаты --- Это же всё б/у, по наклейке даже моно узнать откуда. Им, небось, ещё и заплатили за утилизацию отходов |
| warezhunter_:
Всё не дает мне покоя этот картридж на аналоге MMC3 (микросхема AX5202P). Причем первые две части Rockman видимо перехачены под маппер MMC3. Сдампил я его под маппер MMC3 при помощи команды --- Код: ---famicom-duper dump --reset --mapper mmc3 --prg-size 256k --chr-size 256k --file rockman6in1(1).nes --- Конец кода --- Команду --reset приписал для того, чтобы при запуске предварительно переключилось в меню с выбором игр, так как при включении консоли стартует игра Rockboard и при нажатии на Reset переключается в нужное меню. При запуске полученного дампа через Fceux из меню стартует только одна игра Rockman 5. При изучении сдампленного рома, я обнаружил, что меню встроено в игру Rockman 5, а обращения к дополнительным регистрам такие: --- Код: ---Режим адрес значение hex start 6000 00 Rockman1 6800 12 Rockman2 6800 16 Rockman3 6800 04 Rockman4 6800 19 Rockman5 6800 00 Rockman6 6800 1B --- Конец кода --- То есть при выборе игры через меню, по адресу 6800 записывается определенное значение (для Rockman 1 - 12, для Rockman 2 - 16 и т.д.). Можно сдампить все игры по отдельности, предварительно записав нужное значение по адресу 6800, но я ковяряюсь уже второй день и не пойму как это сделать. Функционал дополнительного регистра похоже, что такой: 0: 0 - MMC3-256, 1 - MMC3-512; 1, 2, 3: PRG addr, bit2 видимо также используется как старший адрес CHR; 4: 0 - CHR ROM, 1 - CHR RAM Обращение по 6800 вероятно лочит регистр от записи. Прошу помощи в написании скрипта для кластеровского дампера, чтобы сдампить данный картридж. В программировании C# я не силен, что то более простое написать могу. |
| mutabor:
--- Цитата: warezhunter_ от 10 Август 2025, 10:52:46 ---Мне даже удалось сдампить меню этой многоигровки и запустить через Fceux. Надо как то игры все повытаскивать оттуда. --- Конец цитаты --- Надо разбираться как управляется маппер, зашитый в ПЛИС. При загрузке CHR RAM используются такие регистры: 5003 0 5005 0 5002 B 5006 0 5001 10 5006 1 5001 11 ... 5006 F 5001 1F Вероятно 5001 (и 5002?) управляют PRG банком, надо писать в этот регистр и смотреть что дампится. --- Цитата: warezhunter_ от 05 Сентябрь 2025, 11:31:24 ---Попалась на глаза мне вот эта одноигровка: SMD133 это маппер MMC3, S29GL064N - 64 mbit флэш-память, CS18LV20483 - 256k SRAM-память. --- Конец цитаты --- Ага, такое относительно часто попадается, повезло что 256k CHR. |
| Vlad666:
Можно ли как-то вытащить Super Mario Bros и Lost Levels из Super Mario All-Stars на SNES? |
| warezhunter_:
--- Цитата: mutabor от 09 Сентябрь 2025, 21:01:15 ---Вероятно 5001 (и 5002?) управляют PRG банком, надо писать в этот регистр и смотреть что дампится. --- Конец цитаты --- А можно какой то пример, как сделать запись в регистр а потом снять дамп? Я всю документацию на дампер этот пересмотрел, не могу понять как это сделать. |
| Yoti:
--- Цитата: Vlad666 от 09 Сентябрь 2025, 21:26:52 ---Можно ли как-то вытащить Super Mario Bros и Lost Levels из Super Mario All-Stars на SNES? --- Конец цитаты --- В этой теме дампят картриджи. Лучше сходи на поклон к великой платной нейросети с этим вопросом. :biggrin: |
| mutabor:
--- Цитата: warezhunter_ от 10 Сентябрь 2025, 04:25:39 ---А можно какой то пример, как сделать запись в регистр а потом снять дамп? --- Конец цитаты --- У тебя же кластеровский дампер? Надо писать скрипт для этого маппера. dumper.WriteCpu(0x5000, 0x00); // записываем 0 по адресу 0x5000 |
| warezhunter_:
--- Цитата: mutabor от 10 Сентябрь 2025, 19:27:40 ---У тебя же кластеровский дампер? Надо писать скрипт для этого маппера. dumper.WriteCpu(0x5000, 0x00); // записываем 0 по адресу 0x5000 --- Конец цитаты --- Да, есть у меня кластеровский дампер, и я видел эту команду в реализации некоторых мапперов. Попробую просто вставить эту команду в отдельный скрипт, обзову его как MyScript.cs и потом попробую выполнить дамп такой примерной командой: --- Код: ---famicom-dumper dump --mapper MMC3 --file game.nes --cs-file MyScript.cs --- Конец кода --- И посмотрю что получится. Добавлено позже: Для начала я попытался сдампить все игры по одной в том картридже 6 in 1 Rockman с предварительной записью по адресу 6800, при записи любого значения по этому адресу дампится только Rockman 6, пока я не могу понять как сдампить остальные игры. Данный картридж ведет себя странно, только что дампился Rockman 5 с записью 6800, а теперь это не дает никакого эффекта, дампится меню и запускается одна игра Rockman 5. Обнаружил, что скорее всего у меня в память ничего не записывается, вот код скрипта: --- Код: ---class MyScript { void Run(IFamicomDumperConnection dumper) { dumper.WriteCpu(0x6800, 0x12); //записываем 12 по адресу 0x6800 } } --- Конец кода --- Как только я его выполняю командой: --- Код: ---famicom-dumper script --cs-file MyScript.cs --- Конец кода --- Получаю: --- Код: ---Running MyScript.Run()... --- Конец кода --- Только проблема в том, что никуда ничего не записывается, светодиод на дампере гаснет на несколько секунд картридж перезапускается, как будто нажали на Reset или выключили питание. |
| mutabor:
--- Цитата: warezhunter_ от 13 Сентябрь 2025, 11:24:28 ---Только проблема в том, что никуда ничего не записывается, светодиод на дампере гаснет на несколько секунд картридж перезапускается, как будто нажали на Reset или выключили питание. --- Конец цитаты --- Ну так нужно не только в регистр записать, но и собственно ром сдампить. Возьми для примера скрипт для дампа NROM и добавь перед собственно дампом запись в регистр. |
| warezhunter_:
--- Цитата: mutabor от 13 Сентябрь 2025, 20:15:38 ---Ну так нужно не только в регистр записать, но и собственно ром сдампить. Возьми для примера скрипт для дампа NROM и добавь перед собственно дампом запись в регистр. --- Конец цитаты --- А куда вставлять то? Я пробовал вставить --- Код: ---public void DumpPrg(IFamicomDumperConnection dumper, List<byte> data, int size) { Console.Write("Reading PRG... "); dumper.WriteCpu (0x6800, 0x12); data.AddRange(dumper.ReadCpu((ushort)(0x10000 - size), size)); Console.WriteLine("OK"); } public void DumpChr(IFamicomDumperConnection dumper, List<byte> data, int size) { Console.Write("Reading CHR... "); dumper.WriteCpu (0x6800, 0x12); data.AddRange(dumper.ReadPpu(0x0000, size)); Console.WriteLine("OK"); } --- Конец кода --- Снял дамп до добавления dumper.WriteCpu (0x6800, 0x12) и после, они абсолютно ничем не отличаются. Значит запись Cpu либо игнорируется, либо Cpu залочена. Если записать по адресу 00D4 значение 10, а в 0040 значение от 0 до 5, то стартует сразу выбранная мгра 0 - Rockman, 1 - Rockman 2, 2 - Rockman3, 3 - Rockman3, 4 - Rockman5, 5 - Rockman6, но я пробовал добавлять всё это через WriteCpu, чтобы из меню стартовала нужная игра перед дампом, но реакции на команду WriteCpu никакой. |
| mutabor:
--- Цитата: warezhunter_ от 14 Сентябрь 2025, 08:48:50 ---Я пробовал вставить --- Конец цитаты --- Да, так верно --- Цитата: warezhunter_ от 14 Сентябрь 2025, 08:48:50 ---Снял дамп до добавления dumper.WriteCpu (0x6800, 0x12) и после, они абсолютно ничем не отличаются. --- Конец цитаты --- А тут уже возможны варианты. Во первых можно добавить ресет перед прочими действиями: dumper.Reset(); Во вторых может на самом деле маппер управляется по другому, либо нужна какая-то инициализация. Хоть и редко, но бывает так, что маппер работает с дампером не так, как с реальной приставкой - например постоянно ресетается или неправильно работают операции (особенно это касается обращений к нижней половине адресного пространства). Тут уже разбираться гораздо сложнее. Для начала можно поэкспериментировать на чем-то известном и безпроблемном, например простом MMC3 или SMD133. Точно разобравшись как работает запись и дамп - переходить уже к другим. В случае с рокманом - там судя по фото доп регистры реализованы на рассыпухе - т.е. если ничего не получается - можно составить схему и разобраться с ее логикой. |
| warezhunter_:
--- Цитата: mutabor от 14 Сентябрь 2025, 09:11:32 ---Во первых можно добавить ресет перед прочими действиями: dumper.Reset(); --- Конец цитаты --- Этот картридж устроен так, что при включении приставки запускается игра Rockboard, затем при нажатии на Reset вылазит вот это меню, Rockboard мне не нужна, поэтому я сразу перед дампом даю команду Reset, и еще одно выполнение Reset из меню вызовет переключение обратно на Rockboard надо двойной Reset получается делать. Я думал стартовать выбранную игру через запись в адрес 0040 значений от 0 до 5, после каждой записи в 0040 выполнять 00D4:10 (нажатие кнопки Start), но ощущение такое, что WriteCpu не работает вообще, команда либо игнорируется, либо память залочена и ошибок никаких не выдает. После изучения записи с другими картриджами, было выяснено, что запись сильно ограничена, дампер записывает только в некоторые области памяти. |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |