Приставки > Картриджи / диски

Дампинг, обсуждаем, делимся ромами своих дампов

<< < (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 не работает вообще, команда либо игнорируется, либо память залочена и ошибок никаких не выдает. После изучения записи с другими картриджами, было выяснено, что запись сильно ограничена, дампер записывает только в некоторые области памяти.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

[*] Предыдущая страница

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