Всем привет, меня зовут Александр. Увлекаюсь программированием и разработкой электроники в свободное время. Мне бы хотелось поведать Вам, товарищи, историю одного программатора.
Был обычный январский вечер и ничего не предвещало беды, однако сын моего друга не смог смириться с праздным проведением семейного досуга и сломал только что купленное ему творение китайского клонопрома. Ну как сломал, уронил, если можно так сказать, с 8-го этажа. Собрав остатки чуда азиатского дядюшки, друг с надеждой в глазах, вручил мне останки потерпевшего.
Как Вы уже, наверное, догадались, речь пойдет о портативной консоли SUP, которая представляет собой клон обычной Famicom в портативном виде, причем выполненная в форм-факторе GameBoy. Забегая вперед, скажу, что починить бедолагу не представлялось возможным, но у нее остался один целый элемент - микросхема флэш памяти. Тут мне, как пацану любившему в лихие 90-е погонять в Dendy, свело олдскулы и поплутав на одном небезызвестном сайте объявлений, была приобретена подобная консоль для изучения. Обзоров в интернете на нее полно, потому кратко расскажу, что приставка собой представляет. Цветной TN дисплей 3,5 дюйма, односторонняя плата с SoC- каплей, микросхема флэш памяти на плате переходнике, немного рассыпухи, простой аккумулятор от старых телефонов Nokia, корпус из дешевого пластика и дополнительный джойстик. Так же консоль может выводить изображение и звук на телевизор посредством композитного видеосигнала и имела на борту аж 400 игр. Что ж, не самый плохой набор.
Набор, технически, может и не плохой. А вот с играми беда. Как это часто бывает с китайскими многоигровками, многие игры представляли собой хаки какой -либо одной игры, например Super Mario или Contra, а также набор странных игр, о которых, лично я, не знал до этого момента. Возможно очередные поделки мастеров ассемблерного кунг-фу, хотя попалась даже одна игра на русском языке. Начались поиски по форумам возможности разнообразить азиатское меню. Сильно давало надежду наличие Micro USB разъема в устройстве (прошу заметить, именно разъема, а не порта, как оказалось позже). Другими словами, встал вопрос - а можно ли заменить игры в этом чуде? Скажу сразу - можно, правда с несколькими НО.
Для начала разборок нужен дамп микросхемы, а чтоб получить дамп нужен дампер. Самое просто, что пришло в голову, это взять Arduino Mega 2560, так как у нее достаточное количество ног, чтоб подключить все имеющиеся пины микросхемы памяти, есть порт для связи с компьютером и возможно питание 3.3В, что освобождало от согласования уровней, хотя микросхема вполне толерантна к 5В уровню. В моем случае была микросхема K5L2731CAA-D770 фирмы Samsung. Недолгое гугление преподнесло мне даташит на блюдечке с цифровой каемочкой, началось увлекательное чтение материала. Микросхема представляла собой параллельную NOR флеш объемом 128 MBit со встроенной оперативной памятью 32 MBit(которые в SUP не используются). выяснилось, что прочитать микросхему довольно просто - выставляем адрес, читаем данные. Но вот беда, микросхема то BGA, и припаяна на плату SUP с помощью платы-переходника. Как понять распиновку?
Было сделано следующее. Отпаян переходник с микросхемой, отпаяна сама микросхема, прозвонил каждый пятачок BGA к какому выводу переходника он идет, нарисовал распиновку и припаял микросхему обратно на плату. Все-таки паяться к переходнику несколько проще, чем к пятачкам микросхемы. Спаял на макетке платку-шилд и приступил к программированию. Но писать скетч в Arduino IDE не хотелось, так как не без того медленное решение стало бы еще медленнее. Потому я начал писать прошивку в IAR, загружая прошивку через родной бутлоадер ардуинки. Кстати довольно удобно, как мне показалось.
Микросхема на выходе имела слово размеров 16 бит или 2 байта, кому как удобнее, следовательно вывод через com порт я сделал так - сначала младший байт, потом старший и читаем следующий адрес. Чтоб не заморачиваться с программой, которая принимала бы данные, был взят Hercules, выставлен в нем режим записи лога, и началась передача данных. На скорости 115200 бод, 16 мегабайт данных из микросхемы передавалось примерно 45 минут… Как будто снова вернулся в детство и в процессе получения дампа в голове неоднократно проигрывался звук подключающегося модема, в очередной раз сводя олдскулы и вспоминались слова Масяни: “Только не дисконнект, только не дисконнект…” Наконец счетчик входящих байт в Hercules остановился, файл дампа был готов и открыт в HEX редакторе. При просмотре файла в нем явно были видны и названия игр и тексты из игр. А открыв тайловым редактором дамп отчетливо были видны те самый тайлы. Счастью небыло предела! Но что со всем этим делать?
Эмулятор, конечно же, не открыл дамп, так как тот был чисто бинарный, а не в формате nes. Знаток платформы Famicom из меня так себе, потому было принято решение написать небезызвестному многим гуру фамикомостроения ClusterM и передать ему дамп. Алексей ответил мне в тот же вечер, чему я был несказанно рад, завязалась активная переписка. Буквально в течении часа дамп Алексеем был препарирован, преобразован в формат nes, выдвинуты предположения, что за SoC на плате, какие мапперы поддерживаются и создан ROM для записи. Осталось этот ROM, для проверки, зашить обратно в микросхему памяти. К такому быстрому повороту событий жизнь меня не готовила…
Как прочитать флешь было понятно, а вот как её записать? Пришлось снова лезть в даташит. Процесс записи несколько сложнее. Во-первых флеш записывается рядом служебных команд и дерганьем дополнительных пинов, прежде чем в нее передаются, собственно, данные на запись. Да, надо разрезать перемычки на плате переходнике на точках WE и WP, так как они намертво притянуты к плюсу питания. Во-вторых, микросхему нужно сначала стереть, прежде чем записывать, так как записываются в нее по сути только 0, переписывая 1, а обратно 0 на 1 переписать не получится, только полностью стирать страницу памяти или микросхему целиком специальной командой. Да да, в чистой микросхеме все ячейки заполнены единицами. Поигравшись с командами и записав пару раз текстовые документы во флеш и убедившись, что данные записаны, в микросхему был прошит полученный от Кластера ROM, отпаяны все провода и переходник с платой были припаяны на свое место в SUP. Настал момент истины и питание было подано. В ответ SUP радостно зажег зеленый индикатор питания и… и больше ничего не случилось, даже подсветка экрана на зажглась. Наступила пора экспериментов.
Для начала экспериментов, прежде всего надо было решить вопрос пайки 45 проводов, потому было принято решение немного модернизировать SUP и плату микросхемы, путем установки разъемов. Сказано - сделано. Теперь микросхема легко отключалась от SUP и легко подключалась к программатору и наоборот. Едем дальше.
О безуспешной попытке запуска, было рассказано Алексею. Просмотрев лог запуска на эмуляторе, было выдвинуто предположение, что дисплей и периферия активируется каким-то набором команд. Алексей выделил эти обращения и добавил в свой ROM. Прошиваем его в микросхему, подключаем к плате и… и дисплей включился ровным белым фоном. Что ж, уже прогресс! Значит предположения были верны. Потом начались эксперименты с размерами файла, с разными частями кода, но эффект был один и тот же - белый экран. А чтоб прошить каждый ROM во флеш, требовалось от 5 до 40 минут, в зависимости от размера. Приставка никак не хотела оживать. И тут меня черт дернул, нажал на кнопку управления, кажется вниз. Из динамика раздался звук перемещения курсора по меню. Значит код ROMа запускается и работает?! После нажатия кнопки старт из динамика заиграла до боли знакомая мелодия Контры. Это была, маленькая, но победа.
Я сообщил об этом Кластеру и пошел на кухню за телевизором, у которого был композитный видеовход. Подключив приставку по композитному входу, телевизор показал, пусть и яркую, пересвеченную, с ядреными цветами, но вполне узнаваемому картинку меню. Да, прошивка работала, игры запускались. Мы виртуально пожали с Алексеем друг другу руки, поздравили с успехом.
Теперь стало ясно, что прошивка явно должна инициализировать дисплей, чтоб выводить на него картинку. Снова начались эксперименты. Пока Алексей колдовал над кодом, вспомнилось, что отправлял то я дампы двух микросхем, хоть и одинаковых, но дисплеи у консолей были разные. Попросил Алексея подкинуть код инициализации от другого дампа в ROM, прошил микросхему и в счастливой эйфории, поделившись ей с камрадом по ту сторону экрана, отправился в царство Морфея, так как дисплей включился и отобразил картинку игр. Следовательно вывод, что на одинаковых по железу консолях, программы слегка отличаются для разных дисплеев, дамп от одной приставки может не подойти для другой приставки. Это самое большое НО при замене игры в SUP.
Небольшие технические заметки:
Микросхема-капля на плате консоли - это процессор типа VTxx компании V.R. Technology. Какой именно не удалось определить. Но есть одно интересное наблюдение. Из всех 3 имеющихся у меня работоспособных консолей, ни у одной не работал 3й канал звука, тот самый, который генерирует пилу. Алексей тоже приобрел несколько штук, и только у одной работали все каналы звука. Если поможете мне найти полностью функциональную версию SUP, буду очень благодарен. Дампы можно напрямую запускать в родном эмуляторе от V.R. Technology. Программой для домашнего создания ромсетов для это процессора называется NESMaker от самого производителя. Единственно, без кода инициализации дисплея, ромсет будет работать только через видео выход. Как достать код из дампа, увы, моих знаний пока не достаточно, это прерогатива Кластера.
Исходя из первого пункта и исследований Кластера, выяснилось, что консоль поддерживает игры с мапперами: OneBus, MMC3, UNROM(возможно) и игры без маппера. Это еще одно серьезное НО в прошивке консоли.
Разъем MicroUSB - это просто разъем. Никакого USB там и в помине нет. Китайцам видимо все- равно на стандарты. В себе разъем содержит шину питания, а остальные три вывода используются для связи с внешним джойстиком для второго игрока. Протокол связи - классический Famicom. Ничего нового или необычного. Так что для прошивки нужно выпаивать чип памяти из консоли и паять его потом обратно. Еще одно НО в копилку.
При выводе композитного сигнала совершенно не соблюдаются стандарты размаха видеосигнала, из-за чего картинка выглядит очень яркой, с ненатуральными цветами. Способом лечения стало включение последовательно в цепь резистора. Нужно в среднем 50 Ом, но необходимо подбирать. В моем случае одному подопытному хватило 33 Ом, а другому 47 Ом и все стало на свои места.
Контроллер заряда батареи в схеме отвратный, если там он вообще есть. Рекомендуется поменять.
Со временем получилось улучшить программатор. Были добавлены разбиения данных на фрагменты, подсчет и проверка контрольных сумм при передачи данных в программатор, а так же верификация записанного блока. Время чтения 16 мегабайт с 40 минут уменьшилось до 8, а время записи уменьшилось до 13 минут. Быстрее не получится - ограничения в скорости Atmega и его USART порта. Думаю это тоже заслуживает статуса НО.
Чисто теоретически прочитать таким программатором можно любую микросхему памяти из SUP, скорее всего механизм чтение у них у всех одинаков, а вот процесс записи может различаться. Проверить не на чем. В дальнейшем есть планы улучшить программатор, заменив процессор и сделав все-таки нормальную плату, что позволит программировать микросхему быстро, прямо на плате. Главное найти на это средства, силы и время.
Всем кому интересны исходный код программатора, схема, описание протокола, скомпилированные прошивки и простые утилиты работы с программатором, добро пожаловать на Github. Всё представленное здесь предоставляется как есть и конечно же хотелось бы напомнить, что всё описано в этой статье делается Вами на Ваш страх и риск.
PS. Огромное спасибо Алексею @ClusterM за помощь в разборе железа и создание работоспособного ROM, подтверждающий факт, что заменить игры в SUP представляется возможным, хоть и сложным путем. Без его вклада, создание этой статьи было бы невозможным.