Давным-давно, в далекой-предалекой галактике… В общем была такая приставка “Денди”. И было на нее море пиратских картриджей разной степени паршивости. Но один не давал мне покоя.
Через некоторое время после покупки желанной “Денди”, я, как и все, столкнулся с проблемой, что комплектный картридж с “танчиками” уже не вставляет, как раньше. Назрела необходимость покупки нового, чтобы было хотя бы на что меняться с другими товарищами. Продавались картриджи с помпой по всей Москве, так что был выбран самый простой и удобный вариант – Универмаг Московский возле Ярославского вокзала. На третьем этаже был целый отдел с игрушками, причем не только от фирмы Steepler.
К выбору картриджа я подошел со всей тщательностью. Выбирал самый тяжелый и самый желтый картридж из всех. Чем тяжелее картридж, тем больше в него влезало игр, причем наклейка на этот показатель никак не влияла. Забегая вперед, скажу, что на моем в последствии наклейки не оказалось вовсе. Наконец, выбор был сделан: многоигровка 7-в-1 с “Черным плащом”, “змейками” и “Magic Jewel”.
Началась новая эра (лично для меня), после простеньких “уточек” и “марио” я получил сразу великолепнейшие и красивейшие игры с музыкой (сколько времени я убил на запись и прослушивание заставочной темы из Робокопа, это не передать словами).
Была лишь одна вещь, которая омрачала мою радость. Игра “Snake Rattle’n Roll” на этом картридже всегда намертво зависала в седьмом уровне на “фонтанчиках”. Как только брался приз-часы, появлялся одинокий фонтанчик, а дальше следовала неминуемая смерть. Обидно было еще и потому, что даже с секретными переходами между уровнями, известными мне на тот момент, добраться до того места было ой как сложно. Впоследствии был, конечно же, найден переход из первого уровня сразу в восьмой, что несколько спасло дело, но это было уже достаточно поздно и всерьез игру пройти так и не удалось. Спустя время, картридж и вовсе затерялся в чьих-то закромах и так ко мне и не вернулся. Но история на этом не заканчивается, а начинается новая.
Некоторое время назад я получил по почте пачку картриджей (кстати, огромная просьба тем, кто мне что-то отправлял вне зависимости, хотел бы он вернуть картриджи обратно или нет, свяжитесь со мной по почте, и засвидетельствуйте принадлежность тех или иных посылок именно вам; память у меня плохая, а посылки скопились за довольно большое время, сам я уже могу и не вспомнить, кого за что благодарить). Среди тех картриджей оказался один, полу-живой, с явными следами вандало-ремонта, и показывал он только одну игру “Черный плащ” с глюками в графике. На плате значилось 12-в-1. После выпайки и считывания ПЗУ, оказалось, что это ни что иное, как тот самый родной картридж со “змейками”. Вот он, герой рассказа, в коробке с оригинальной наклейкой:

7 в 1 "со змейками"
Замулить маппер не составило большого труда, благо все игры имеются в отдельном виде, все (кроме простых) работают на оригинальной версии MMC1 от Nintendo и соответственно могут быть выделены нужные для переключения банки ПЗУ и для пиратского маппера. К слову сказать, несмотря на простоту, пиратский вариант сам по себе позволяет практически идеально имитировать работу большинства картриджей на базе MMC1, с тем лишь исключением, что каждую игру необходимо индивидуально модифицировать. В частности, “Робокоп” требовал от пиратов огромных усилий по модификации кода, потому как функции смены банков разбросаны в нем по всему ПЗУ, с чем доблестные тайваньцы успешно справились.
Пришла очередь узнать наконец, что же было причиной такого жестокого зависания “змеек”.

То самое место
Вот оно, проблемное место. Одно движение вниз, чтобы забрать приз-часы и прощай долгие часы трудов по прохождению до этого места. Экспериментально было найдено место, где игра срывается в бездну, а также исходный байт данных, который к этому ведет. Осталось только найти место, где он получает свое деструктивное значение. И такое место было найдено:
| Оригинальный код | Пиратский модифицированный код |
$FFC9:8D FF BF STA $BFFF = #$A1 $FFCC:4A LSR A = #$06 $FFCD:8D FF BF STA $BFFF = #$A1 $FFD0:4A LSR A = #$03 $FFD1:8D FF BF STA $BFFF = #$A1 $FFD4:4A LSR A = #$01 $FFD5:8D FF BF STA $BFFF = #$A1 $FFD8:4A LSR A = #$00 $FFD9:8D FF BF STA $BFFF = #$A1 $FFDC:60 RTS A = #$00 $8C72:A8 TAY A = #$00 $8C73:A9 0F LDA #$0F $8C75:8D 06 20 STA $2006 = #$5E $8C78:A9 78 LDA #$78 $8C7A:8D 06 20 STA $2006 = #$5E $8C7D:A9 77 LDA #$77 $8C7F:85 AC STA $00AC = #$93 $8C81:84 AB STY $00AB = #$00 $8C83:AD 07 20 LDA $2007 = #$AE $8C86:AD 07 20 LDA $2007 = #$37 $8C89:99 53 06 STA $0653,Y @ $0653 = #$0A |
$FFC9:0A ASL A = #$06 $FFCA:0A ASL A = #$0C $FFCB:0A ASL A = #$18 $FFCC:8D FF BF STA $BFFF = #$A1 $FFCF:EA NOP $FFD0:EA NOP $FFD1:2C FF BF BIT $BFFF = #$A1 $FFD4:EA NOP $FFD5:2C FF BF BIT $BFFF = #$A1 $FFD8:4A LSR A = #$30 $FFD9:2C FF BF BIT $BFFF = #$A1 $FFDC:60 RTS $8C72:A8 TAY A = #$18 $8C73:A9 0F LDA #$0F $8C75:8D 06 20 STA $2006 = #$5E $8C78:A9 78 LDA #$78 $8C7A:8D 06 20 STA $2006 = #$5E $8C7D:A9 77 LDA #$77 $8C7F:85 AC STA $00AC = #$93 $8C81:84 AB STY $00AB = #$07 $8C83:AD 07 20 LDA $2007 = #$12 $8C86:AD 07 20 LDA $2007 = #$37 $8C89:99 53 06 STA $0653,Y @ $066B = #$68 |
Первая часть кода – это функция смены банков графики. Часть своих данных игра хранит там и периодически ей надо их оттуда считывать. В частности, в видео-ПЗУ хранятся некоторые данные уровня, например как раз данные активных объектов. Когда мы берем приз-часы, игровое поле модифицируется так, чтобы появились анимированные фонтанчики. Втора часть кода как раз и переносит нужные данные в ОЗУ приставки. Обе функции вызываются одна за другой, первая с параметром номера банка в регистре А, вторая с параметром индекса массива данных, с которого необходимо начать копирование данных.
Не так явно бросается в глаза тот факт, что оригинальная функция смены банков всегда очищает регистр А, так как сдвигает его на 5 бит вправо, а число, в него записываемое, не превышает 31. Таким образом, в оригинальной игре, после вызова функции смены банка, функция копирования всегда должна инициализироваться нулевым значением в регистре А. У пиратов же, функция состоит из старой части, в которой опкоды MOV заменены на BIT, чтобы не влиять на пиратский маппер, а нужное значение для его собственного регистра получается сдвигом индекса банка графики на 3 влево. Таким образом, на выходе из этой функции регистр А не очищается, а его значение передается как индекс начала области данных для копирования. В определенный момент нужные данные пишутся не туда и приводят к фатальному сбою.
Исправить данный баг можно было бы всего лишь добавлением гарантированной очистки регистра А перед выходом из подпрограммы смены банка. Вот так, пиратская недоработка могла стоить кучи нервных клеток для молодого организма и кучи впустую потраченного времени на ее поиск у взрослого.
Вот и сказочки конец, а кто дочитал до этого места, получит приз.
Why only in Russian?? I need to translate this:] Please add some comments in English.
комментарий от dr88 — 08/17/2009 @ 14:10
Я до читал до конца, где мой приз??? )))
комментарий от Fallved — 08/17/2009 @ 16:25
dr88, lol, I can’t write so much in english, sorry
комментарий от cah4e3 — 08/17/2009 @ 17:34
Fallved, а приз – дамп этого картриджа лол, на CaH4e3’s Stuff Home.
комментарий от cah4e3 — 08/17/2009 @ 17:36
I always look for your updates:) Could be nice to translate them sometimes:P
комментарий от dr88 — 08/17/2009 @ 18:03
I always translate my updates
this one first I didn’t translate lol
комментарий от cah4e3 — 08/17/2009 @ 18:27
Alright, if anyone wants, I can translate it for you, English-speakers. Just mail me on cr45h_it_away@mail.ru, my mailbox is always open for guests (but not for spam intruders, of course, tee-hee-hee…)
комментарий от Crash Nicker — 08/17/2009 @ 18:43
No worries Cah4e3, just want to get rid of mall the mistakes you usually make d;)
комментарий от Crash Nicker — 08/17/2009 @ 18:45
И правда помню этот катридж был и у меня. Действительно, ситуация со змейкой на уровне с фонтанчиками долго вводила меня в ступор! Потом как-то и забылось…
Буквально на днях решил пройти уже с помощью эмулятора этот Snake. Прошёл без проблем и фонтанчики. А вот в самом последнем уровне пришлось долго повозиться в самом конце, чтобы запрыгнуть в финишную “лунку”. На приставке я бы это точно вряд ли прошёл – терпения бы столько не хватило
комментарий от RoxMarty — 08/18/2009 @ 04:12
Интересно!
Хотя на денди мне эти “змейки” не разу не встречались…
комментарий от Tigran — 08/19/2009 @ 00:07
Спасибо Cah4e3, что ты есть. Интересно пишешь. Я отлично помню этих “змеек”, игра мне не понравилась – очень сложная, и дальше 4-го уровня я не проходил.
З.Ы. “сколько времени я убил на запись и прослушивание заставочной темы из Терминатора”. Может все-таки из “Робокопа 3″? Я сам не мог наслушаться.:)
комментарий от Grun D — 08/19/2009 @ 01:17
Hello. Will you make more Contra dumps? Like Forest Contra, New Contra and the multicart?
комментарий от uacelite — 08/19/2009 @ 10:14
У меня был точно такой карик=))
только в змейках дальше 4 кроаня не доходил…
комментарий от MopoZ — 08/21/2009 @ 10:27
Да, было время, то же бился с этими фонтанчиками, в конце концов забил и улетал на ракете в 8. Доходил до луны но ногу убить так и не смог, не бессмертна ли она в этой пиратке? На эмуле прошел без проблем.
комментарий от Lex_05 — 08/27/2009 @ 19:47
>>Началась новая эра (лично для меня), после простеньких «уточек» и «марио» я получил сразу великолепнейшие и красивейшие игры с музыкой (сколько времени я убил на запись и прослушивание заставочной темы из Робокопа, это не передать словами).<<
Точь-в-точь про меня.
)) Я точно также после картриджа 9999in1, прилагавегося к приставке, вскоре потерял интерес к простым играм и приобрел заветную 7-игровку – абсолютно точно такую же как на фото. И о сколько времени я убил на "змеек". Страшно подумать сколько жизней изменил баг с очисткой регистра А… Спасибо, Cah4e3, что поведал наконец о причине этого чёртового глюка!
комментарий от kinaman — 09/07/2009 @ 21:16
Мдя из за одного регисра A я тоже в свое время не смог пройти этот уровень.
Была вот ещё одна игра Frankenstein – The Monster Returns с примерно темже глюком, зависала во втором уровне при прыжке на “кочку” на болоте. Причём перепробовал много картриджей глюк был на всех. Интесрено с чем там связано на эмуляторах идёт без проблем.
комментарий от VBKesha — 10/23/2009 @ 19:08
ну если найдется картридж, то легко. такой фигни было еще несколько, типа глюков на лифте в shatterhand, правда сам я его не помню ниразу.
комментарий от cah4e3 — 10/23/2009 @ 21:40
cah4e3, спасибо
комментарий от v4era — 11/25/2009 @ 02:51
Hello. Will you make more Contra pirate dumps?
комментарий от uacelite — 12/16/2009 @ 01:44
Спасибо за инфу
Тоже в детстве оч мучался, только переход с 1 на 8 или 5 на 8й решал… На самом деле, баг еще проявляется даже если не брать часы, а просто прыгнуть в пропасть право-вверх от часов. Видимо, там тоже банки переключаются
комментарий от daNIL — 01/25/2010 @ 02:41
It´s possible to emulate a rom call Where´s Bin Laden? That Cartrige is a clone of Where´s Wally is so rare i saw a image no the internet and i don´t now where is the image now
.
комментарий от AnimalBear — 01/26/2010 @ 19:35
It’s only possible if you find cartridge for me, even images didn’t help.
комментарий от cah4e3 — 01/27/2010 @ 15:52
да,какой облом был когда игра зависла,я думал картридж заезжанный а оно вон оказывается как …
лишь только спустя долгие годы прошел её на эмуляторе.
комментарий от Руслан — 03/14/2010 @ 05:27
Contra pirate dumps?
комментарий от contrafan — 04/25/2010 @ 00:20
Да-да, точь в точь как и я. Только у меня вместо танчиков наряду с уточками был “лоде руннер”
)).
Со змейками парился аналогично. Более того, однажды совершил невозможное – дошёл до этого места один двумя змейками!!! (просто никто из друзей не мог дойти до туда) Хотел сделать такой трюк. Одну змейку подталкиваю пальцем ноги на часы, а вторую тут же пихаю в водопад. Фонтанчик брызнул один раз, змейка естественно с него свалилась и поплыла вниз. Потом стандартный “матрас” на экране.
А ещё мне удалось на втором уровне заставить ногу упасть в море – наизабавнейший баг!
комментарий от Raptor — 04/29/2010 @ 18:24