Приставки > Картриджи / диски
Вертикальные точки Dendy многоигровка
<< < (3/3)
NStormX:
megavolt85, шутки шутками, но как можно заметить - в дампе работает только бомбермэн, а на картридже на реальном железе работают две игры. Плюс к слову проблемы с графикой на реальном железе на порядок меньше чем в дампе. Никто и не пытается сдампить то, что не работает на реальном железе. Идея лишь сдампить то, что работает, а для этого нужно сэмулировать маппер.
supremacy:
NStormX, начнём с того, что не все многоигровки можно сдампить дампером Кластера. На некоторых будет срабатывать сброс, и ты не сможешь выбрать другие банки.
А технология дампа не особо сложная - нужно сначала сдампить nrom, загрузить в эмулятор, поставить брэйкпоинты на запись в 6000-ffff и запустить игру из меню. Программа остановится на переключении банка, по коду смотришь по какому адресу и какими битами переключаются банки и дописываешь в свой скрипт соответствующие команды.
NStormX:
supremacy, благодарю за помощь! Так как ранее этим не занимался просьба по возможности ответить на нубские вопросы.
Отладил я это меню. Переключение производится следующим образом (для удобства сделал таблицу):
Адрес записи    Записываемое значение    Адрес перехода    Игра
$AF08    $A0    $8003    HUMAN
$AF0C    $A0    $8000    ISLAND
$AF01    $F0    $C000    BOMBERMAN (main bank)
$AF04    $A0    $8010    GRADIUS
Насколько я понимаю у нас переключение банки производится записью в (0xAF00+(bank*4)) байта 0xA0. Но остаются вопросы: откуда начинается PRG и откуда CHR в данном конкретном картридже и какова их длина.

Допустим получился такой скрипт (ниже). Но во первых непонятно как проверять (кроме как писать свой обработчик в эмулятор хотя уверен он уже есть), так как я не знаю что за маппер и в wiki.nesdev.com мапперов с записью в эти адреса не нашел (возможно плохо искал). В общем вопросов пока больше чем ответов. Заранее благодарю за терпение :)


--- Код: ---MapperName = "New1"
MapperNumber = 255
DefaultPrgSize = 4 * 32 * 1024 // 4x от nrom, сколько в реале - хз
DefaultChrSize = 4 * 8 * 1024 // 4x от nrom, сколько в реале - хз

function DumpPrg(size)
  print("Reading main PRG bank...")
  ReadAddPrg(0x8000, size / 4) // а с 8000 ли начинается? и какова длина блока PRG
local banks = 4
for b = 1, banks-1, 1 do
print("Reading PRG bank #" .. tostring(b+1) .. "...")
WriteCpu(0xAF00+4*b, {0xA0})
ReadAddPrg(0x8000, size / 4)
end
end

function DumpChr(size)
  print("Reading main CHR...")
  ReadAddChr(0x0000, size / 4) // а с 0 ли начинается? и какова длина блока CHR
local banks = 4
for b = 1, banks-1, 1 do
print("Reading CHR #" .. tostring(b+1) .. "...")
WriteCpu(0xAF00+4*b, {0xA0})
ReadAddChr(0x0000, size / 4)
end
end

function EnablePrgRam(size)
print("Warning: SRAM is not supported by this mapper")
end
--- Конец кода ---
supremacy:
Смотришь на каком маппере оригинальные игры, в данном случае CNROM. Меню, как правило, переключает старшие адреса, а саму игру дампишь уже используя команды её оригинального маппера (если китайцы её не перехачили).

PRG всегда бери 32KB, CHR тоже бери по 32КБ, итоговый размер 128+128

Но в конце концов ты захочешь запустить свой дамп в эмуляторе и тут тебе придётся либо найти уже реализованный такой же маппер, либо доработать эмулятор.
А если ты найдёшь уже готовый дамп то, наверное, нет смысла дампить твой картридж 8)

P.S. Записываемое значение в твоей табличке не правильное, ты записал что по этому адресу находится, а не то что в регистре A сейчас, у маппера есть защита от конфликтов на шине, поэтому значения не совпадают.
KykyPyky:
Отладка меню довольно трудоемкая операция. Китайцы воровали и хачили меню друг у друга, писали меню сразу под несколько мапперов.
Вроде понятно как работает, написал lua скрипт, а оно не дампится :neznayu:
Подобным мозгоебством можно заниматься только из-за большой любви к конкретному рому. :lol:

Лучше начинать исследование с осмотра карика и микросхем его составляющих.
Нам повезло, маппер не на капле, а на стандартной логике.
Две микрухи ls161 и ls32. Сохранять данные, а значит переключать банки может только одна из них - ls161.
Качаем даташит на нее или ищем распиновку в интернете:


На входы 3,4,5,6 подается сигнал, запоминается и с выводов 14,13,12,11 снимается.
Вооружимся распиновкой карика https://wiki.nesdev.com/w/index.php/Cartridge_connector, острым зрением и/или тестером,
отследим подается сигнал и куда уходит.
Сигнал подается с выводов 10,11,12,13 карика, это адресные линии процессора.
Уходит на адреса капель prg и chr. Какие именно адреса мы не знаем.

--- Код: ---CPU A0 -> P0 161 -> CHR
CPU A1 -> P1 161 -> CHR
CPU A2 -> P2 161 -> CHR + PRG
CPU A3 -> P3 161 -> PRG

--- Конец кода ---
Получается что бы сдампить chr нам нужно в карик записать 2^3=8 значений по адресам с разными битами A0-A2.
Остальные биты значение не имеют. Как и записываемые данные. Переключение происходит только на основании адреса.
Данные которые надо записать мы прочитаем из этой же ячейки адреса, что бы избежать конфликта шин.
Получается на lua вот так:

--- Код: ---WriteCpu(0x8000 + bank, ReadPrg(0x8000 + bank, 1))
--- Конец кода ---

Для дампа prg нужно записать 2^2=4 значений по адресам с разными битами A2-A3.
В lua нет битовых операций сдвига, но можно биты сдвинуть влево умножением на число 2 нужное количество раз.

--- Код: ---WriteCpu(0x8000 + bank*2*2, ReadPrg(0x8000 + bank*2*2, 1))
--- Конец кода ---

Теперь разберемся с номером маппера.
Что бы преобразовать любой адрес в номер банка chr, нужно обнулить все биты кроме последних трех.
Для этого подходит логическое И над адресом и числом 7 или 0x07 или 0b00000111

--- Код: ---A & 0x07
--- Конец кода ---
Для prg нужно обнулить биты кроме 2 и 3, а потом сдвинуть вправо на 3 бита.

--- Код: ---(A & 0x0f) >> 2
или
(A >> 2) & 0x03
--- Конец кода ---

Скачиваем исходники fceux.
Все простенькие мапперы которые переключаются адресом собраны в файле fceux-2.2.2/src/boards/addrlatch.cpp.
Открываем его и ищем что-то подобное на математику выше.
Ура! Кажется такой маппер уже реализован :wow:

--- Код: ---static void M217Sync(void) {
setprg32(0x8000, (latche >> 2) & 3);
setchr8(latche & 7);
}
--- Конец кода ---
Т.к. игры у нас на 32к prg то выбираем маппер 217, а не 214.

Еще можно поискать маппер на вики несдева, начинать копать вот отсюда http://wiki.nesdev.com/w/index.php/Mapper
Но некоторые мапперы там не описаны, например наш http://wiki.nesdev.com/w/index.php/INES_Mapper_217

Итоговый lua файл:

--- Код: -----
-- Mapper # 217
-- addr latch: 74-161, 74-32


MapperName = "Mapper #217"
MapperNumber = 217
DefaultPrgSize = 4*0x8000
DefaultChrSize = 8*0x2000

function DumpPrg(size)
        for b = 0, banks-1 do
            WriteCpu(0x8000 + bank*2*2, ReadPrg(0x8000 + bank*2*2, 1))
            print("Reading PRG bank #" .. tostring(b) .. "...")
            ReadAddPrg(0x8000, 0x8000)
        end
end

function DumpChr(size)
        for b = 0, banks-1 do
            WriteCpu(0x8000 + bank, ReadPrg(0x8000 + bank, 1))
            print("Reading CHR bank #" .. tostring(b) .. "...")
            ReadAddChr(0x0000, 0x2000)
        end
end

function EnablePrgRam(size)
end
--- Конец кода ---
Файл нуждается в проверке, я его даже не запускал.
NStormX:
KykyPyky, искренне благодарю за ликбез! С этим как и с другими картриджами разбираюсь чисто just for fun. Никакой практической цели кроме как изучить работу железа и ПО приставок - нет. Сами игры не нужны от слова совсем - тут чисто интересна задача.
Скрипт поправил, правда CHR в отличии от приставки криво дампится (Dino Richi с побитым CHR, на приставке все корректно). Bomberman зависает на первом уровне, причем если не писать в Cpu скриптом на этапе дампинга CHR - не зависает, но соответственно кривая графика.

Исправленный скрипт прилагаю.

supremacy, также благодарю за советы.
Навигация
Главная страница сообщений
Предыдущая страница

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