Sega MegaDrive – «Взломщик кодов».

Взлом, анализ работы, модификация и оптимизации.

Скачать модифицированную версию «Взломщика кодов».

Чит-инструменты под названием «Game Genie», разработки и производства американской компании (для разных приставок, в т.ч. для МегаДрайва) получили немалую мировую известность и распространение. Эмуляцию их работы интегрируют во многие программные эмуляторы самих игровых консолей. «Взломщик кодов» - продукт наших соотечественников и распространялся он локально, причем свет увидел его только спустя более 10-ти лет с тех пор, как Мегадрайв был актуальной на рынке (для его официального производителя - Сеги) игровой платформой.

Общий обзор.

«Взломщик кодов» (далее просто - взломщик) – такой же «сквозной» картридж, как и Game Genie. Однако, в отличие от Game Genie  (далее - GG, суть работы которого заключается в маскировании данных по заданным адресам ПЗУ картриджа значениями, указанными пользователем), который работает исключительно с адресами и данными «проходящими» сквозь него в/из картридж(а), что логично вобщем-то – взломщик работает исключительно с данными в ОЗУ самой приставки (которое на борту системы, внутри корпуса), позволяя а-ля «фризить» (фактически также заменять) значения заданных ячеек памяти. Но как? Если взломщик в слоте, а память - на плате МегаДрайва …

Тут особенно разнообразия вариантов нет. И даже не держа чит-девайс в руках и не изучая его работу, просто при такой постановке задачи очевидно: достижимо такое разве что в случае если мы с завидной регулярностью будем обновлять содержимое нужных нам ячеек памяти. Причем обновлять чаще, чем туда будут записывать и потом считывать алгоритмы при работе основной программы (игры) на картридже. Очевидно также, что такой подход будет расходовать на себя дополнительное процессорное время и факт такого «читерства» может быть легко обнаружен. И хоть последний аспект не актуален – т.к игры в большинстве своем создавались намного раньше взломщика и даже гипотетически не могли «задумываться» о защите от такого способа читерства. Но вот расход дополнительных ресурсов системы может быть не столь прозрачен для пользователя (геймера) и проявлять себя нежелательными «артефактами». Тормозами? Возможно, но маловероятно – а вот как показывает практика, в звуковом сопровождении (не всегда, но в ряде случаев) действительно появляются посторонние шумы (фоновый треск), об этом ниже.

Что внутри.

На плате взломщика функционально присутствуют ПЗУ, ОЗУ и маппер. И если с форм-фактором микросхем памяти как обычно тенденция к миниатюризации и удешевлению с течением времени, то маппер практически во всей массе серийных экземпляров выполнен на микросхеме ПЛМ. Однако существовала версия, где реализация маппера была на дискретной логике, благодаря чему, ее владелец воспользовался возможностью и срисовал принципиальную схему, копию которой я публикую ниже:

В ходе анализа и понимания работы схемы была выявлена и исправлена ошибка (выше представлен исправленный, верный вариант).

Вне зависимости от версии реализации, аппаратная архитектура девайса одинакова. Объем памяти программ (ПЗУ) здесь 256кбайт, плюс ОЗУ для хранения данных, и оно лишь 8-ми разрядное (т.е. код процессора 68k в нем не разместишь), размером 32кбайта.

На тыльной стороне расположен тумблер.

Версии взломщика.

Программное обеспечение («прошивка» взломщика) датирована 2000 годом. Судя по фотографиям, найденным в сети, первая версия была собрана «на рассыпухе», имела множество дискретной логики ттл-серии, массив ПЗУ был представлен аж двумя 8-битными микросхемами (скорее всего в целях удешевления конструкции, как ни странно), ну и ОЗУ (в большом DIP-корпусе). Выглядело это как то так.

Следующие редакции имеют уже реализацию маппера на ПЛМ (CPLD Altera EPM7032, серии MAX7000), 16-битную ПЗУ (в некоторых ранних редакциях даже сразу флэш-ПЗУ, повезло кому-то), и ОЗУ зачастую уже не в DIP, а в SOP-корпусе. Такие ревизии, как правило, имеют отсылку уже к 2006 году, как и в моем случае. Однако год указан лишь на полиграфической сопроводиловке и наклейке (очень низкого качества) – на плате лишь маркировка DY2572C. На фотке мой экземпляр (до модификаций).

Конфигурация CPLD как минимум обратно-совместима с дискретной схемой, так как версия ПО (да, таже что и в моем экземпляре) едина для всех аппаратных редакций (легко ищется в сети).

Принцип функционирования («пользовательский» – расширенный конспект инструкции).

При включении питания, вне зависимости от наличия картриджа в слоте сверху, для консоли в полном объеме доступна как ПЗУ взломщика, так и его ОЗУ. Т.е. формально его можно использовать как обычный картридж и записать игру соответствующего размера (256кбайт не много конечно, но есть игрушки, которым этого достаточно; ОЗУ в этом случае простаивает и не мешает). При штатном же использовании в ПЗУ взломщика записана «программа инициализации», а также база «кодов». Интерфейс позволяет выбрать из алфавитного списка название игры и один или по очереди несколько читов к ней. Соответствие выбранных читов и реально вставленного картриджа чисто под ответственность пользователя – никаких проверок нет. Не исключен и вариант, когда с одной и той же игрой, но разной региональности, код будет работать только с одной из них. А еще у одной и тоже игры (хоть и не часто) бывали разные версии (от официального разработчика) – вобщем даже правильный, казалось бы, выбор игры из базы - вовсе не гарантирует ожидаемого эффекта от кода. Есть возможность вводить коды и вручную. Далее, при выборе запуска игры (с кодами или без) маппер взломщика осуществляет переключение и передачу управления программе на картридже в его слоте.

Тумблер (переключатель на тыльной стороне взломщика) позволяет в любой момент активировать/деактивировать его вмешательство в процесс выполнения целевой программы (игры на картридже). Один, а не два (как можно подумать, тупо взглянув): оба переключателя просто запараллелены (не нашлось видно подходящего одинарного). Таким образом, для замыкания сигнальной линии достаточно включить один любой, два тоже допустимо, хотя и избыточно. При этом понятно, что для размыкания нужно отключать обязательно оба! (логическое «ИЛИ» вобщем). ЧуднО, но не смешно читать разные комментарии на ютубах и фантазии лохов на тему комбинаций из этих двух переключателей … (но техническое невежество, к сожалению, в сети со временем только прогрессирует).

Но вот тут вариантов несколько больше, чем может показаться навскидку:

 
Переключатель активен
Переключатель НЕ активен
Запуск с кодами
Штатный вариант работы взломщика. Влияние (в т.ч. возможно негативное) на работу целевой программы неизбежно – чем больше кодов внесено, тем более заметным может быть это влияние.
Воздействие на ход выполнения целевой программы отсутствует полностью. Фактически «сквозное» подключение игрового картриджа*
Запуск без кодов
Несмотря на то, что никакого полезного вмешательства в работу целевой программы взломщик в этом случае не вносит, но переключение картриджей все равно будет осуществляться! Что неизбежно влечет затраты времени и может быть не столь малозаметным, как того ожидаешь (даже ознакомившись с тем минимумом дополнительного кода, который выполняется в этом случае).

* Не забываем, что не все сигнальные линии разведены на взломщике из слота в слот. Ввиду этого часть игр и картриджей могут функционировать как не в полном объеме (недоступна память для сохранений напр.), так и не функционировать вовсе (EverDrive). Источники аналогового звука, расположенные на картридже, также не попадут в приставку через плату взломщика.

Некоторые игры, даже с введенными кодами, нужно стартовать (а иначе никак) при отключенном взломщике! – а включать его тумблером лишь после начала игры, загрузки поля и т.п.

Недостатки «Взломщика кодов».

Как сейчас модно говорить «из коробки», взломщик с одной стороны работоспособен, с другой не очень. И нюансов разных много: как очевидных, так и не совсем, а порой, возможно, и специфичных (обусловленных другими аппаратными компонентами, совместно с которыми используется взломщик):

  • Меня, например, сразу стал напрягать весьма продолжительный по времени запуск ПО взломщика, а вторая интро-заставка а-ля «позор стоматолога» вызывала отвращение … Почему нельзя сразу максимально быстро попасть в главное меню взломщика? Долбление по клавишам джойстика чуть ускоряет процесс, но не революционно. Даже если хочешь просто запустить игру «насквозь» (без кодов) лишний десяток секунд, а то и более гарантирован;
  • Дурацкое управление «псевдо-мышью» очень тормознутое и неудобное, а по-другому никак! Почему бы не сделать было обычную клавишную навигацию? Дань моде начала 2000-х? Ладно, но почему хотябы по-умолчанию курсор не на запуске игры, а тупо в середине экрана?
  • Но полный абзац я испытал когда, включив колонки, услышал звуковое сопровождение всего этого горе-GUI'я! С какого бодуна и кто записывал этот аццкий трешак?! Тошнотворно до безобразия!!! Варианта в стоке два: играть без звука, или тестировать ресурс кнопки отключающей звук. Выпилить бы вообще нах все эти сортирные саунд-потуги – реально портят впечатление о продукте!
  • Дальше вроде по мелочам. Зачем было выключатель на тыльной стороне располагать так низко? – ведь его даже согласно ксерокопии приложенной к взломщику инструкции (типа «оригинальная комплектация») предполагается дергать даже во время игрового процесса! К нему спичкой то подлезть непросто! – не то чтобы пальцем. Благо зачастую его переключать не приходится вовсе (всегда включен, раз уж мы юзаем сие техно-чудо);
  • Звук решил не включать со взломщиком (см. выше), а тут выключить забыл – отплевался в очередной раз, да не об этом. На звуковое сопровождение при активном взломщике накладывается весьма явный фоновый треск – не критично, но явно дискомфортно. Виноват именно взломщик! – тут же отщелкиваешь его и шума нет, включаешь и снова … В разных играх интенсивность шума разная, где-то его нет практически вовсе. Реально процессорного времени не хватает? Или программисты рукожёпые и нищебродские 20 лет назад были? (писали на асме под досом в 866 кодировке). Тут уже в очередной раз появляется мысля о создании своего, альтернативного ПО для взломщика. А возможна ли вообще оптимизация в рамках имеющегося аппаратного решения (без капитальной его переработки, т.к. это уже будет другое устройство)?

Изложенный выше перечень обусловлен аппаратной и программной частью самого взломщика, но даже если его отключить (тумблером сзади) – полностью сквозного подключения картриджа он не обеспечивает, причем порой без явных причин (поленились дрожки на плате нарисовать). В результате получается что:

  • Если картридж имеет собственную периферию для генерации аналогового звукового сопровождения, то в приставку этот сигнал не попадет (нет соединения линий из слота в слот для B1 и B3);
  • Также не будет функционировать память сохранений игры на картридже, а маппер SSF, равно как и EverDrive - не будут работать вовсе (нет соединения линии из слота в слот для B31);
  • Отсутствие соединения ряда других линий менее критично, т.к. некоторые из них используются, пожалуй, лишь в 32X (а при очень большом желании взломщик можно воткнуть после 32X, а не перед), другие же несоединенные линии - еще реже.

Легкая модернизация.

Изложенное в этом подразделе, собственно, было теоретически проработано еще до покупки на Авито экземпляра взломщика (со второй попытки, первый уехал обратно к хозяину так бракованный был, с треснутым слотом). Требовалось обеспечить очередную «флэшеризацию» - заменить ПЗУ картриджа на записываемую (т.е. «электрически-стираемую») микросхему памяти, причем с расчетом на «внутрисхемную» ее прошивку через штатный краевой слотовый разъем. Благо последнее – процесс уже обкатанный мной досконально: есть замечательный интерфейс Flashkit и опенсорсный управляющий софт к нему, который я по необходимости дорабатываю (рекомендую к использованию). ПЗУ штатно хоть и бескорпусное фактически, но на адаптере под форм-фактор SOP-44, что уже хорошо. Ладно, будем колдовать ;-) Покупаю взломщик!

Устройство реально новое (разъем слота тугой, ламели снизу без царапин), культура пайки низкая, но на припой не жмотились. Отмываем плату от древней канифоли, пропаиваем аккуратно микросхему ОЗУ. Ну и непринужденно отпаиваем стоковую ПЗУшку (при помощи сплава розе и обычного паяльника) – ниже фотка дорожек под ней.

Перечень модификаций:

  • Разрезаем (очень аккуратно) перемычку между 43 и 44 ногами (снимаем #WE с VCC, чтоб микросхема могла принимать данные, а не только отдавать) – после этого можно запаивать флэшку.
  • Какую флэш-ПЗУ выбрать? В идеале PA28F200. Также (несмотря на легкое отличие в распиновке) подойдет AM29F200. Но у меня была в хозяйстве лишь еще одна (с донора предыдущего проекта) PA28F400 – используем ее наполовину, даже предварительная оценка давала фактическую уверенность в ожидаемом результате. Всё равно софт для программатора мне дописывать – поэтому без разницы что ставить ;-))
  • Соединяем высвобожденную ногу 43 флэшки с контактом слота B28 (или предпоследней ногой микросхемы ОЗУ) – кусочком провода, а как иначе? Можно сделать вполне изящно (см. фотку ниже). Прямо как «доктор прописал» - и почему было бы сразу не сделать такую дорожку на печатной плате? Однократке бы точно не помешало!
  • Каплей припоя замыкаем тест-поинт «B» (шунтируем верхний резистор в резистивном делителе питания данной микросхемы). Без этого VCC (питание) будет ниже 5В, чего явно не достаточно для стабильного стирания и записи древней пятивольтовой памяти (она и от 12В не отказалась бы, так что пять это точно самый минимум). Нижний (килоомный) резистор в делителе можно вообще отпаять за ненадобностью теперь, но можно и оставить – его шунтирующий по питанию эффект: всего лишь 5мА потерь (не стоит имхо взмаха паяльника).
  • Каплей припоя замыкаем тест-поинт «А». Тут очередной трэш! Смотрел на такой изврат с широко закрытыми глазами … Какой лопух придумал питать статическое кмоп-ОЗУ «паразитным» способом (через сигнальные линии) – «земля в воздухе», каково? И самое главное, зачем? Даташит на эту микросхему такого не предусматривает, ровно как и здравый инженерный ум. Сборщик также осуществлял пайку с выключенным мозгом – поэтому каплю припоя придется оставить нам, благо есть место куда (проводок не нужен).

Вобщем получилась такая красота.

А на следующей фотке - завершенное конструктивное решение для тестирования нового софта взломщика.

Картридж можно (и нужно, ибо удобно!) «шить насквозь» не вынимая из взломщика – см. также описание к обновленной версии ПО FlashKit-MD-Plus. Единым модулем, за уши слота взломщика по середине, очень практично и быстро конструкция переставляется из программатора в приставку, и обратно :-)

Детальный анализ работы взломщика.

Функционал взломщика, используемый в его софтовой части, определен и ограничен возможностями его маппера. Смотрим на схему дискретного варианта и осмысляем происходящие там «движения» единичек и нулей (вспоминается ВУЗ'овская «дискретная математика»). Кроме комбинационной составляющей в схеме присутствуют всего лишь два триггера, а стало быть, вся она может пребывать не более чем в одном из четырех своих состояний. Правый (по схеме) функционирует в режиме RS-триггера, его состояние определяет выбор (разрешение функционирования) либо памяти взломщика (сброшенное состояние), либо памяти картриджа в слоте (установленное состояние). Левый (по схеме) функционирует в режиме T-триггера цель которого переключать правый триггер значением своего состояния. Как устанавливаются и от чего переключаются эти два триггера?

T-триггер (левый)

  • Обнуляется по входу R при включении питания (пока не зарядился C2) – далее, до коммутации питания, активности и сброса этого триггера в данной точке быть не может;
  • Может быть установлен по входу S при низком уровне на линии M3. Но для приставки это тоже вход! А генерировать низкий уровень в этой точке может исключительно данный маппер, об этом ниже;
  • Циклически меняет свое состояние при восходящем фронте сигнала на входе C. На данный вход сигнал поступает c дешифратора почти полного адреса (неопределенность старшего бита доопределяется сигналом CE) и соответствует единственному адресу – 0x000078 (активный уровень со схемы дешифратора инверсный, а триггер срабатывает лишь на переходе из 0 в 1, т.е. когда заданный адрес «уходит»);

Заведомо противоположным состоянием своих выходов (прямого и инверсного) он участвует в манипуляции сигналами R и S правого триггера.

RS-триггер (правый)

  • Аналогично предыдущему обнуляется при включении питания (D-триггер тут не используется даже при старте, RS-компонента превалирует над D, подтяжка входов D и C к 1 исключительно во избежание ловли помех). Далее получается, что после подачи питания и заряда C2 вызвать сброс этого триггера может лишь левый триггер своим сброшенным состоянием (причем однозначно!) и то лишь при замкнутом тумблере SA1 (что соответствует «активному» режиму взломщика);
  • Установить этот триггер может либо пребывающий в установленном состоянии левый триггер при начале активного (нулевого) уровня с дешифратора по 0x000078. Либо активный уровень (опять-таки нулевой) со второго дешифратора. Второй дешифратор срабатывает на диапазон адресов 0x3F0000 – 0x03FFFFF (и формально на 0xBF0000 – 0xBFFFFF, но без активации DTACK тут система зависнет, т.е. это не вариант) в случае если имеет место быть сброшенное состояние данного триггера (т.е. выбрана память взломщика, а не картриджа его слоте). Последнее было бы избыточным, если активное (нулевое) состояние данного дешифратора не было заведено на M3, что вызывает также сброс МегаДрайва (его переключение в режим МастерСистем). При этом устанавливается левый триггер по своему входу S. Лишь после деактивации дешифратора МегаДрайв возвращается в нативный режим.

Как-то так.

Стоковый софт взломщика видать (судя по анализу кода) написан именно под эту схему и несколько нетипичен в своей реализации: при работе инициализационной части (т.е. всего пользовательского интерфейса взломщика) прерывание VInt отключено и не разу не возникает, а вместе с этим и нет обращения к 0x000078 – результат: рваная и медленная отрисовка всех элементов графического интерфейса, такова дань такой архитектуре маппера, разобранной выше. Теперь соберем изложенное воедино в виде высокоуровневого алгоритма работы маппера взломщика по рассмотренной схеме (т.е. чем должен был руководствоваться программист, создавая ПО для  взломщика, которое мы имеем в наличии):

  1. При включении подключается память взломщика и начинается выполнение программы в его ПЗУ;
  2. VInt на этапе работы программы инициализации взломщика (выбора/ввода кодов) мы вызывать и обрабатывать не имеем права! Так как каждый второй его вызов (обращение к таблице векторов процессора 68k по адресу 0x000078) переключит маппер и подставит в адресное пространство память картриджа в слоте взломщика (это приведет к непредсказуемому результату, но явно нарушит работу ПО взломщика). Копировать код ПО взломщика в ОЗУ МегаДрайва (стоковый код этого не делает) тоже не вариант – т.к. таблица векторов на внешнем картридже также произвольна и неизвестно куда нас может кинуть очередной VInt. Вобщем просто не трогаем VInt внутри ПО взломщика (для его дискретной реализации);
  3. Когда ПО взломщика под управлением пользователя произвело необходимую инициализацию, сохраняющуюся в микросхеме ОЗУ взломщика – можно передавать управление картриджу (начинать игру);
  4. Не мудрствуя, но несколько нетривиально-оригинальным образом передается управление на старт программы в картридже - обращением по любому адресу из диапазона 0x3F0000 – 0x3FFFFF вызывается переход приставки в режим МастерСистем и возврат из него (ресет черз ж* короче);
  5. Первый вызов VInt (из игры) переключит маппер (в случае активности тумблера), и вот тут-то ПО взломщика (стоковая версия) в первый раз и обработает его! Суть обработчика заключается исключительно в чтении адресов и значений из ОЗУ взломщика, заполненного во время его инициализации в п.п.1-3 и внесении правок в основное ОЗУ приставки в соответствии с этими данными;
  6. Заканчивается обработчик VInt (в коде ПО взломщика) фактически вторичным чтением и переходом по таблице векторов к его же началу и неизбежным повтором процедуры патчинга ОЗУ приставки – но срабатывает маппер, и второго прохода сразу вслед за первым быть не должно (в идеале). Начиная с адреса 0x000079 читается уже содержимое картриджа и далее выполняется код обработчика VInt из него. (Примечание: код операции «move» 0x4EF9 занимает часть соседнего вектора, на нее выполняется безусловный переход в конце обработчика VInt, но это типа не должно смущать и мешать, т.к. этот «другой» вектор не используется, то и не будет попытки интерпретировать код операции как адрес);
  7. Переходим к п.5 и т.д. Т.е. фактически мы получаем «добавку» в виде кода заполнения заданных адресов ОЗУ приставки определенными значениями в начале каждого VInt в основной программе (игре). Добавить можно разве лишь то, что на сигналы сброса (кнопку ресет приставки) взломщик реагировать не может технически.

Вот. Но маппер на ПЛМ (EPM7032), судя по тестам, хоть и обратно совместим, но работает еще и иначе! У него есть дополнительные «фишки», а именно:

  • После включения питания, до обращения по адресу из диапазона 0x3F0000 – 0x3FFFFF допускается использование VInt, т.е. обращение к 0x000078 не обрабатывается (в т.ч. независимо от положения тумблера), что допускает использование взломщика как картриджа для обычной программы (странный вариант применения, конечно, но факт), а также дает возможность создать адекватный софт с нормальным динамичным интерфейсом (несовместимый с дискретной версией взломщика);
  • Передав управление (запустив игру, обращением по адресу из диапазона 0x3F0000 – 0x3FFFFF) вернуться обратно в режим «инициализации» - т.е. подключить память взломщика и не обрабатывать переключение маппера по VInt. Для этого после первого чтения 0x000078 (когда мы провалились в обработчик типа штатно патчим ОЗУ приставки) мы обращаемся по томуже диапазону (0x3F0000 – 0x3FFFFF), чего штатный обработчик не делает. После этого обращение по 0x000078 уже не переключает маппер до следующего обращения к 0x3F0000 – 0x3FFFFF (тумблер, разумеется, включен в это время)... Было бы здорово, если оно было бы так – но нет (вообще странно, но словно на программаторе и в приставке маппер работает по-разному). Без этой фишки прочитать идентификатор игры на вставленном картридже до выбора кодов врядли получится реализовать. А не переписать ли маппер? В наличии нашлась даже вдвое большая ПЛМ (EPM7064) …

Каким бы хотелось видеть софт взломщика?

Недостатков у взломщика в настоящей реализации немало. Однако многие из них обусловлены исключительно программной составляющей (и совместимостью с архаичной дискретной версией), но несмотря на достаточную примитивность его маппера – видится наличие возможности создания более оптимального и функционального софта.

В планах создать с нуля ПО для взломщика с использованием SGDK и сделать его код общедоступным. А реализовать в нем в первую очередь следующее:

  • Удобный и быстрый интерфейс взаимодействия с использованием крестовины, кнопок, в т.ч. «горячих клавиш» (без «мышевого» курсора как оно в стоке);
  • Оптимизировать «добавочный код» к VInt для максимального быстродействия и минимального влияния на выполнение программы картриджа в слоте, избавиться от фонового треска;
  • По возможности предусмотреть детектирование вставленной в слот игры (читать ее идентификатор из заголовка) чтоб не рыться ручками по базе (возможно исключительно только для версии на CPLD-маппере);
  • Реализовать механизм отслеживания значений в ОЗУ приставки для создания новых «чит-кодов» (есть надежда, что железо позволит);
  • Реализовать механизм сохранения кодов (внутрисистемное обновление базы) путем само-программирования части микросхемы флэш-ПЗУ (должно получиться);

А еще планируется переписать логику маппера в CPLD, сохранив обратную совместимость! И тут хоть объекты управления так просто не поменяешь (управляем лишь подключением памяти взломщика или картриджа), то исходными данными (полный адрес, без старшего разряда – т.е. фактически первые 8МБайт) можно манипулировать всецело ;-) И весьма удобным видится вариант при старте и ините взломщика во вторые 4Мб адресовать память картриджа (и задачу чтения идентификатора решаем и картридж прошивать «внутри-приставочно» даже можно). Можно и обработку еще какого-нибудь прерывания припилить. Разумеется, предусмотреть функцию блокировку обработки VInt после передачи управления в программу на картридже (пригодится для отслеживания новых кодов).

Нюансы реализации.

В процессе создания собственного ПО, разумеется подглядываешь и анализируешь как некоторые моменты реализованы в штатном. Чтоб с одной стороны велосипед не изобретать, а если изобретать, то не повторять ошибок. Обращу внимание на следующие моменты:

  • Несмотря на то, что взломщик создан для внесения правок значений в ОЗУ приставки, и соответственно адресная часть в его кодах 16-ти разрядная (64кбайта) – в своем набортном ОЗУ, как и в «базе» внутри своего ПЗУ он хранит 24-х битные адреса. Старший байт при этом всегда 0xFF. Во время инициализации взломщика перед запуском игры в процессе создания массива пар «адрес:значение» в его ОЗУ в независимости от способа (из базы или вручную) под адрес выделяется три байта и один байт под значение. Наличие 0x00 в качестве старшего байта очередного адреса означает конец таблицы патчинга в ОЗУ взломщика (в интерфейсе это явно не видно и напрямую не задается). Вся ОЗУ взломщика не инициализируется;
  • Несмотря на то что ОЗУ взломщика 8-битная, она используется как массив с последовательной сквозной адресацией – просто инкремент адреса производить нужно дважды (или дельту смещения умножать на 2).
  • Один код адресует с точностью до байта и фризит ячейку размером в байт. Для заморозки слова нужно вводить два кода! Например, нам нужно реализовать такой патч: FF9C10:007F – для этого мы должны ввести два кода: 9C10:00 и 9C11:7F (но в случае подобного кода, с нулевым первым байтом - на практике достаточно ввести бывает лишь последний).

Оптимизация штатного ПО взломщика.

В процессе пока разбираешься что к чему, порой просто для быстроты и удобства обкатываешь некоторые вещи в виде инъекций в стоковую версию. Таким образом, фактически почти сама-собой собралась модифицированная версия стоковой софтины взломщика (конечно, не все тестовые семплы вошли в нее, а только актуальные и совместимые между собой).

  • Первое и самое главное. Код обработчика VInt вынесен в хвост образа (по адресу 0x03D600), скорректирована таблица векторов – теперь мы в разумных рамках куда как менее ограничены его размером, места для тестирования более чем достаточно. Это позволило реализовать приостановку работы процессора Z80 вначале обработчика (перед сохранением контекста в стек и копированием данных) с возобновлением его работы в конце (путем захвата/освобождения шины). Таким образом существенно минимизировался шум, привносимый взломщиком в звуковое сопровождение игр. Однако в ряде примеров он полностью не исчезает, и это не связано с увеличением времени выполнения VInt суммарно (так как количество кодов на это не влияет, равно как и их наличие как таковое – можно сразу переключать маппер обратно, но ритмичное потрескивание все равно может остаться в отдельно взятой игре). Короче, в некоторых играх просто так написан звуковой драйвер (он не рассчитан на такой трюк, какой делает взломщик) и лучше чем в этом моде просто-напросто от шумов не избавишься. Но шумов реально стало меньше.
  • Вычищена вся дурацко-нелепая озвучка, т.е. действительно вся!
  • Удален (т.е. поскипан) длительный показ противного интро «позор стоматолога», что к томуже существенно уменьшило время запуска. Интро с огнем решил оставить (хотя вариант его исключения тоже успешно протестирован).

Результатом доволен более чем. Стало хоть как-то юзабельно в отличие от того, что было «из коробки».

Скачать модифицированную версию «Взломщика кодов».

PS. В качестве отправной точки для изучения архитектуры «Взломщика кодов» немало помогла информация от товарищей murgatroid_79 и Segaman с форума emu-land.net – за что им большой респект ;-)

MiGeRA (июль-август 2022)

Заглавная » MegaDrive » Sega MegaDrive – «Взломщик кодов»