1 / 704
Версия для печати
Сборка образа картриджа приставки «Эльф»
Адаптация игры
Для каждой игры процесс адаптации строго индивидуальный (творческий), не может быть описан конкретными правилами, и для него не может быть строго заданного алгоритма действий. Я лишь кратко коснусь сути адаптации.
Очень упрощённо, приставка «Эльф» - это по сути ZX-Spectrum, из которого убрали клавиатуру и оставили Kempston-джойстик. Абсолютное большинство игр для ZX-Spectrum рассчитаны на работу с клавиатурой. Наша цель - сделать так, чтобы игра сразу опрашивала Kempston джойстик и позволяла при запуске при его помощи выбирать нужные опции и играть.
Для этого надо переделать управление самой игрой для Kempston джойстика, затем изменить управление в меню игры на Kempston джойстик, при необходимости изменить текст меню игры, выкинув из него ненужные опции типа выбора управления. Да, всё это описано одним предложением, однако потребует много времени.
В качестве примера я приведу процесс переделки игры Star Raiders II под управление приставки «Эльф». Конечно же, вы видите финальный результат, когда всё понятно что надо менять. Но процесс анализа и поиска занял примерно один вечер.
Пример адаптации кодового блока игры Star Raiders II
Раскрыв загрузчик игры мы «достаём» из него кодовый блок игры длиной #765C байт и со стартовым адресом #7514. Старт игры производится по тому же адресу - #7514.
Ищем, где в игре производится опрос клавиатуры и Kempston джойстика. Находим следующий кусок кода:
#7ED3 LD A,(#FF02)
OR A
JP NZ,#98BF
LD A,1
LD (#FF2A),A
LD A,%10111111 ;опрос полуряда клавиатуры HJKL Enter
IN A,(#FE)
AND 8 ;состояние кнопки "J" - смена управления
CP 8
JR Z,#7F19 ;кнопка не нажата
LD (#7EE6),A
Далее опытным путём устанавливаем, что при старте игры сразу выбрано управление Kempston джойстик. Значит приведенный код неактуален - нам не надо менять управление. Убираем из него смену управления, и меняем код на:
#7ED3 LD A,(#FF02)
OR A
JP NZ,#98BF
LD A,1
LD (#FF2A),A
JP #7F19
Далее ищем, где отображается текст "KEMPSTON". Для начала находим таблицы управления в игре и адреса текстовых сообщений для выбранного управления:
#B24E DEFW #99D0 ;Адрес обработчика Kempston Joystick
DEFW #B1F8 ;Адрес текстового сообщения "KEMPSTON"
DEFW #99D6 ;Адрес обработчика Interface II Joystick
DEFW #B203 ;Адрес текстового сообщения "INTERFACE 2"
DEFW #99F1 ;Адрес обработкичка клавиш
DEFW #B20E ;Адрес текстового сообщения "KEYBOARD"
Отсюда нам надо текстовое сообщение по адресу #B1F8:
#B1F8 DEFM "KEMPSTON@@@" ;Пробелы отображаются символом "@"
Меняем этот текст на:
#B1F8 DEFM "JOYSTICK 1@"
В игре кроме Kempston ещё есть множество других кнопок управления. Ищем, где бы они могли опрашиваться. Находим следующий кусок кода:
#7F7A LD HL,#7FA6 ;Таблица обработчика дополнительных клавиш
LD C,7 ;Опрашиваем 7 клавиш
#7F7F LD A,(HL) ;Первый байт таблицы - старший байт адреса порта клавиатуры
INC HL
IN A,(#FE) ;Считываем состояние клавиш нужного полуряда клавиатуры
AND (HL) ;Маскируем бит нужной клавиши
JR Z,#7F8D ;Если клавиша нажата, переходим
DEC C ;Клавиша не нажата, уменьшаем счётчик опрашиваемых клавиш
JR NZ,#7F7F ;Считываем состояние следующей клавиши
LD A,C
JR #7F95
#7F8D LD A,C
CP 0
#7F8F EQU $-1
JR Z,#7F98
LD (#63EC),A
#7F95 LD (#7F8F),A
;Таблица для 7 дополнительных клавиш.
;Первый байт - старший байт порта клавиатуры для опроса клавиши.
;Второй байт - маска для выделения нажатия нужной клавиши.
#7FA6 DEFB #FD,#02 ;Клавиша S - вкл/выкл защитного поля
DEFB #FB,#02 ;Клавиша W - смена оружия
DEFB #BF,#01 ;Клавиша Enter - вызов карты
DEFB #FB,#10 ;Клавиша T - радар
DEFB #DF,#04 ;Клавиша I - пауза
DEFB #BF,#02 ;Клавиша L - выбор сложности игры
DEFB #FE,#01 ;Клавиша Caps Shift - старт игры/выход в главное меню
Все эти 7 клавиш надо переопределить на имеющие 7 свободных кнопок в приставке. Плюс дополнительная сложность - если в игре опрашивается только клавиатура, где нажатая кнопка даёт 0 в нужном бите, у нас смесь кнопок, которые в нажатом состоянии могут быть как в 0, так и в 1, поэтому таблицу кнопок придётся расширить, введя ещё один байт, который будет указывать надо ли инвертировать считанное значение из порта, чтобы привести бит нажатой кнопки к 0.
Так как таблица при этом увеличится в размере, мы не сможем использовать её нынешнее место в памяти. Смотрим, куда бы можно было поместить и таблицу и новый обработчик этих семи дополнительных кнопок игры. У нас есть ненужное место, где находятся обработчики Interface II и клавиатуры для игры. Это область памяти с адреса #99D6 и длиной #42 байта.
Пишем в эту область памяти свой обработчик и таблицу:
;Опрос дополнительных кнопок
ORG #99D6
LD HL,TABLE
LD C,7
A1 LD A,(HL) ;номер порта
LD (A2),A
INC HL
LD A,(HL) ;признак инверсии значения
LD (A3),A
INC HL
XOR A
IN A,(0)
A2 EQU $-1
XOR 0
A3 EQU $-1
AND (HL) ;AND с маской нужного бита
INC HL
JP Z,#7F8D ;было нажатие кнопки
DEC C
JR NZ,A1
LD A,C
JP #7F95
;7 записей в таблице
;порт, биты для инверсии (0-не надо, FF-инвертируем), маска для выделения значащего бита
;Кнопка считается нажатой, если AND с маской даст 0
;Для битов, активных в 1, надо делать инверсию по XOR
TABLE DEFB #1F,#00,%00100000 ;FIRE A - защитное поле вкл/выкл
DEFB #1F,#00,%10000000 ;SELECT - смена оружия
DEFB #1F,#FF,%01000000 ;START - карта/битва
;Джойстик 2
DEFB #FE,#00,%00000010 ;DOWN - радар корабля/состояние систем
DEFB #FE,#00,%00000100 ;RIGHT - пауза
DEFB #FE,#00,%00010000 ;LEFT - выбор уровня сложности
DEFB #FE,#00,%00000001 ;FIRE B - выход в меню/старт игры
Дальше надо поменять вызов обработчика дополнительных кнопок на новый адрес #99D6:
#7F7A JP #99D6
Сохраняем изменённый кодовый блок игры. А дальше надо из него получить файл, который можно прошить в ПЗУ картриджа и запустить на приставке.
Процесс получения образа картриджа можно разделить на два этапа: сборка одной игры и сборка образа картриджа из уже собранных игр.
Сборка одной игры
Конечно же, для этого можно воспользоваться информацией по программированию приставки, однако вам быстро надоест для каждой игры высчитывать адреса для размещения в ПЗУ, перекодировать описание игры в формат приставки, писать каждый раз меню, собирать всё это в один готовый файл для прошивки в ПЗУ. На самом деле, это приличный объём работы. И в отличие от процесса адаптации игры, эта часть работы может быть автоматизирована.
Мне удалось решить проблему автоматизации размещения игр на картридже. Для этого пришлось написать несколько утилит на Python, которые позволят всё сделать быстро.
Вам потребуется установить Python (я проверял на версии 3.10).
Кроме того нужно скачать и распаковать архив с утилитами (и заодно всеми пригодными для сборки в образ картриджа играми).
Допустим, что после адаптации у нас есть кодовый блок игры (или несколько кодовых блоков). Для запуска всё это надо поместить в определённое место ОЗУ и выполнить переход на определённый адрес в памяти. Помимо кодовых блоков у нас может быть заставка, которую тоже можно вывести на экран в процессе загрузки.
Все эти блоки можно поместить в один большой файл, добавить к нему загрузчик игры, и мы получим готовый файл игры, из которого впоследствии можно компоновать образ картриджа. Для удобства я дал таким файлам игр расширение *.alf.
Чтобы не забивать себе голову расчётом где и в каком банке ПЗУ должен располагаться конкретный блок игры, как его загружать, как считать все смещения адресов внутри образа ПЗУ, написана программа, которая всё это делает за вас. От вас лишь потребуется написать загрузчик и указать программе какие файлы должны быть включены в игру.
Для примера возьмём игру Bruce Lee из уже скачанного ранее архива. Переходим в папку Games\Bruce_Lee.
Игра состоит из заставки (scr.pak) и главного блока игры (main.pak). Расширение *.pak - это если блок запакован при помощи HRUST 1.3. Для экономии места все блоки игры пакуются. Распаковщик уже встроен в ПЗУ с картриджем, и при загрузке игры блоки распаковываются. Однако ничто не мешает не паковать данные и собирать игру из непакованных блоков. Кроме увеличения места в ПЗУ это ничего не поменяет.
Конфигурирование списка файлов, входящих в игру
Для начала надо сконфигурировать список файлов, входящих в игру. Открываем файл BruceLee.ini.
# Первый файл - всегда описание игры
OPIS.COD
# Второй файл - всегда загрузчик
LOADER.COD
# Дальше располагаются кодовые блоки игры
MAIN.PAK
SCR.PAK
В этом ini-файле просто перечисляются те файлы, которые будут включены в игру. В файле допускаются пустые строки и строки, начинающиеся с символа "#" - они считаются как комментарии.
Первый по счёту файл всегда будет файл с описанием игры. В нашем случае это opis.cod. Как его получить, вы узнаете чуть ниже по тексту страницы. А пока просто укажем его, чтобы был.
Второй по порядку файл - всегда будет скомпилированный загрузчик. В нашем случае это loader.cod. Как его получить вы узнаете чуть позже.
А вот за ними начинают перечисляться уже сами файлы, из которых состоит игра. Как мы видим, это main.pak - упакованный главный файл игры и scr.pak - упакованный файл с заставкой.
Список файлов для игры сформирован, закрываем ini-файл и переходим к формированию описания игры.
Описание игры
Как вы уже могли узнать из статьи с описанием программирования приставки, у каждой игры на картридже есть описание. Оно представляет собой текстовый блок длиной #02F4 байта в специфической кодировке.
От вас не потребуется корпеть над написанием этого файла. Вам надо только создать текстовый файл (opis.txt) с описанием игры на обычном русском языке, и этот файл в процессе сборки игры перекодируется в нужную для приставки «Эльф» кодировку.
Требования к текстовому файлу:
- кодировка UTF-8 c BOM;
- слова в строках должны быть выровнены по правой границе 28 символов;
- так как файл opis.cod не может быть длиной больше, чем #02F4 байт, все лишние символы в нём обрезаются. Если такое произойдёт, в процессе сборки игры будет выведено соответствующее сообщение ("Warning! Description file length overflow! Some symbols are excluded from the description"), чтобы вы знали, что не весь указанный вами текст поместился в описание.
Загрузчик
Исходный код загрузчика находится в файле loader.asm. Сам загрузчик представляет собой небольшую (порядка 400-500 байт) программу, которая при выполнении возьмёт из ПЗУ картриджа нужные кодовые блоки игры, разместит их в памяти и запустит на выполнение.
В загрузчик входит подпрограмма, которая по номеру кодового блока игры сама загружает его из ПЗУ в память. Напомню, что порядок блоков игр задаётся в ini-файле, при этом блоки нумеруются по порядку, начиная с 1 (в нашем случае файл main.pak будет иметь номер 1, файл scr.pak - номер 2, а файлы opis.cod и loader.cod не включаются в общую нумерацию файлов).
Так как загрузчик занимает какое-то место в памяти, нужно предусмотреть его размещение и стартовый адрес таким образом, чтобы он не "пересёкся" с загружаемыми файлами игры. То есть для загрузчика должно быть отдельное место в памяти. В случае, когда для загрузчика просто нет места (такое случается, когда игра занимает всю доступную память от #5B00 до #FFFF, загрузчик можно разместить в экранной области ОЗУ (но нельзя занимать место с #4000 по #4004 включительно - это ограничение ПЗУ приставки!). Для различных случаев нужен индивидуальный подход.
Из загрузчика могут быть вызваны дополнительные модули. На данный момент написаны 3 модуля - меню читов, модуль проверки наличия 128К RAM и модуль проверки приставки на «новодельность». Модули представляют собой автономные программы, которые после завершения своей работы отдают управление обратно в загрузчик. На этапе сборки образа картриджа все модули помещаются в 0-й банк ПЗУ и могут быть оттуда вызваны загрузчиком.
Пример загрузчика loader.asm
Далее разберу по порядку загрузчик игры Bruce Lee:
;Загрузчик должен иметь длину 256 байт или более!!!
;Адрес загрузчика выбирается так, чтобы он не пересёкся с кодовыми блоками игры.
ORG #5F00
JR BEGIN
DEFW #5F00 ;адрес компиляции загрузчика - должен совпадать с ORG!!!
;Этот адрес используется в дальнейшем сборщиком программ в картридж.
;--- РЕЗЕРВИРОВАНИЕ МЕСТА ДЛЯ ОПИСАТЕЛЯ ФАЙЛОВ, ВХОДЯЩИХ В ИГРУ ---
;--- В ЭТОМ БЛОКЕ КОДА НЕ НАДО НИЧЕГО МЕНЯТЬ ---
;В начале загрузчика при сборке файла с игрой создаётся таблица смещений
;каждого из файлов игры. На этапе написания загрузчика мы просто
;тут резервируем место под нужное количество файлов.
$TABLE
DEFS 3 ;сюда пишется адрес игры в ПЗУ
;Сюда надо записать количество файлов, из которых будет состоять игра.
;Сам загрузчик не включается в этот список.
;Сам список файлов задаётся в ini-файле
FILES EQU 2 ;Сколько файлов будем подгружать (без учёта загрузчика)
DEFS FILES*6+6+1 ;Резервируем место для таблицы файлов
BNK DEFB #80 ;Значение порта для включения первого банка ПЗУ с играми
;Может принимать значения #80 (в случае работы с картриджем)
;либо #02 (для работы в режиме ПЗУ Эльф). Этот байт
;изменяется внешней программой при сборке игр в образ.
;---- КОНЕЦ ОПИСАТЕЛЯ ФАЙЛОВ ------
;--- НАЧАЛО КОДА ЗАГРУЗЧИКА -----
BEGIN
LD SP,#5DF7 ;Задаём стек, обычно он располагается до начала загрузчика
LD A,(BNK) ;Включаем 0-й банк ПЗУ картриджа
OUT (#5F),A ;В нём на этапе сборки образа картриджа помещается
;распаковщик HRUST длиной 256 байт.
;Берём рапаковщик из ПЗУ картриджа и переносим в память.
;По умолчанию распаковщик переносится в адрес #5B00 (он задан в переменной DEPACK)
;Если нужен другой адрес для распаковщика, то в регистр DE вписываем нужный адрес.
LD HL,HRUST ;адрес распаковщика в ПЗУ картриджа
LD DE,DEPACK
LD BC,LENDEP ;длина распаковщика
LDIR ;переносим в ОЗУ
LD HL,MENU ;Адрес модуля меню с читами в ПЗУ
LD DE,MODADR ;Адрес компиляции модуля (на данный момент это #7000)
LD BC,LENMENU ;Длина модуля
LDIR ;Переносим модуль из в ПЗУ в ОЗУ
;Задание параметров вызова меню с читами
LD HL,STRMENU ;Адрес массива строк меню.
LD DE,OPTIONS ;Адрес массива, куда будут помещены результаты выбора опций меню
CALL MODADR ;Вызов меню с читами
;Загрузка заставки игры
LD A,2 ;Заставка (scr.pak) является 2-м файлом в ini-файле
LD DE,#61A8 ;Адрес для загрузки упакованной заставки.
;Может быть любым, лишь бы не испортил загрузчик
;и распаковщик
CALL LDBLK ;Загрузка файла заставки
;Распаковка заставки
LD HL,#61A8 ;Адрес загруженной заставки
LD DE,#4000 ;Адрес, куда распаковываем заставку
CALL DEPACK ;Вызов распаковщика, расположенного в #5B00
;Заставку, равно как и другие файлы, можно не паковать. Это необязательное
;требование. В этом случае кодовые блоки с вызовом распаковщика можно убрать.
;Загрузка основного блока игры
;В нашем случае игры состоит из одного файла.
LD A,1 ;Главный кодовый блок (main.pak) записан как файл №1
;в ini-файле
LD DE,#61A8 ;В нашем случае кодовый блок располагается с адреса #61A8
CALL LDBLK ;Загрузка файла
LD A,1 ;Выключаем ПЗУ картриджа и включаем вместо него ПЗУ Basic-48
OUT (#5F),A
LD HL,#61A8 ;распаковка основного блока игры
LD DE,#61A8 ;с адреса #61A8 в тот же адрес.
CALL DEPACK
;Пауза перед запуском игры, чтобы полюбоваться заставкой, иначе заставка
;быстро исчезнет
LD A,(BNK)
OUT (#5F),A
CALL FUNC+0 ;Функция 0 - Any key
LD A,1 ;После паузы включаем ПЗУ с BASIC-48
OUT (#5F),A
;--------- ЭТОТ БЛОК ИСПОЛЬЗУЕТСЯ ТОЛЬКО ЕСЛИ У НАС ЕСТЬ МЕНЮ С ЧИТАМИ --------
;В процессе своей работы меню с читами помещает результат выбора опций
;в память в массив OPTIONS.
LD IX,OPTIONS ;Адрес опций меню
LD A,(IX+0) ;Первая опция
OR A
JR Z,OPT2 ;Первая опция в меню не была выбрана, пропускаем её обработку.
;Действия для первой опции - бесконечные жизни в игре
XOR A
LD (51795),A
;Проверка второй опции. В данном случае в меню только одна опция, поэтому данный
;блок просто закомментирован.
OPT2 ; LD A,(IX+1) ;Вторая опция
; OR A
; JR Z,START
;Действия для второй опции - тут тоже пусто.
;------ КОНЕЦ БЛОКА ДЛЯ МЕНЮ С ЧИТАМИ -------------
;Старт игры
START JP #E4DE
;Массив, куда помещаются результаты выбора опций меню.
;Число после DEFS - количество опций.
OPTIONS DEFS 1
;Массив строк меню с читами. У нас тут одна строка.
STRMENU
DEFM "BESKONE^NYE VIZNI"
DEFB 0 ;признак конца строки.
DEFB #FF ;признак конца массива строк
;Вставка в загрузчик внешних переменных (vars.asm) и процедуры загрузки одного блока игры (ldblk.asm)
INCLUDE "../../files/vars.asm"
INCLUDE "../../files/ldblk.asm"
Модуль для меню с читами
Этот модуль представляет собой отдельно работающую автономную программу, которая выводит на экран меню, обеспечивает выбор нужного пункта меню (или нескольких пунктов) и выход обратно. Данные о выбранных пунктах меню сохраняются в указанный при вызове меню адрес.
Модуль размещается в ПЗУ картриджа. При необходимости его можно скопировать из ПЗУ в память и запустить. Пример запуска меню:
;Перед этим надо убедиться, что включен 0-й банк ПЗУ картриджа.
;Модуль хранится в 0-м банке ПЗУ картриджа по адресу $MENU
;Включить 0-й банк ПЗУ можно командами LD A,#80: OUT (#5F),A
LD HL,MENU ;Адрес модуля меню с читами в ПЗУ
LD DE,MODADR ;Адрес компиляции модуля (на данный момент это #7000)
LD BC,LENMENU ;Максимальная длина модуля
LDIR ;Переносим модуль из в ПЗУ в ОЗУ
;Задание параметров вызова меню с читами
LD HL,STRMENU ;Адрес массива строк меню.
LD DE,OPTIONS ;Адрес массива, куда будут помещены результаты выбора опций меню
CALL MODADR ;Вызов меню с читами
При запуске меню проверяется - нажата ли хотя бы одна клавиша джойстика 1 (кроме Огонь). Если нет, то меню не запускается, управление отдаётся обратно в загрузчик.
Если нажата какая-нибудь клавиша, запускается меню и на экран выводятся строки из массива строк в регистре HL. Пример массива строк:
MENU DEFM "BESKONE^NYE VIZNI"
DEFB 0 ;признак конца строки.
DEFB #FF ;признак конца массива строк
У нас тут одна строка - выбор бесконечных жизней. Если выбрать эту строку, то в массив OPTIONS по смещению +0 запишется значение #FF. Если опция не будет выбрана, то в массив запишется значение 0. Если в меню будут заданы несколько строк, то для второй строки смещение в массиве OPTIONS будет +1, для третьей - +2 и так далее. Соответственно массив OPTIONS должен быть задан такого размера, сколько у нас планируется опций в меню. Кодировка символов строк - такая же, как кодировка сообщений в ПЗУ приставки:
Пример задания OPTIONS для одной строки:
OPTIONS DEFS 1 ;резервируем 1 байт.
Модуль проверки ОЗУ на 128К
Располагается в 0-м банке ПЗУ картриджа по адресу CH128. Длина модуля - не более #0100 байт.
Можно использовать при запуске игр, которые требуют наличия 128К ОЗУ. Если всё нормально, то после запуска модуля он сразу же отдаст управление обратно. Если же память 128К не будет найдена, модуль выведет на экран соответствующее сообщение и остановит работу.
Модуль компилируется в адрес #7000, и по этому же адресу выпускается на выполнение.
Пример вызова блока проверки ОЗУ на объём 128К:
;Перед этим надо убедиться, что включен 0-й банк ПЗУ картриджа.
;Модуль хранится в 0-м банке ПЗУ картриджа по адресу CH128
;Включить 0-й банк ПЗУ можно командами LD A,(BNK): OUT (#5F),A
LD HL,CH128 ;Адрес модуля в ПЗУ
LD DE,MODADR ;Адрес компиляции модуля (на данный момент это #7000)
LD BC,#0100 ;Максимальная длина модуля
LDIR ;Переносим модуль из в ПЗУ в ОЗУ
CALL MODADR ;Запускаем модуль
.... ;Продолжение работы загрузчика
Модуль проверки приставки на «новодельность»
Располагается в 0-м банке ПЗУ картриджа по адресу CHNOV. Длина модуля - не более #0100 байт.
Можно использовать при запуске игр, которые будут работать только на «новодельных» приставках. Если всё нормально, то после запуска модуля он сразу же отдаст управление обратно. В противном случае модуль выведет на экран соответствующее сообщение и остановит работу.
Модуль компилируется в адрес #7000, и по этому же адресу выпускается на выполнение.
Пример вызова блока проверки ОЗУ на «новодельность»:
;Перед этим надо убедиться, что включен 0-й банк ПЗУ картриджа.
;Модуль хранится в 0-м банке ПЗУ картриджа по адресу CHNOV
;Включить 0-й банк ПЗУ можно командами LD A,(BNK): OUT (#5F),A
LD HL,CHNOV ;Адрес модуля в ПЗУ
LD DE,MODADR ;Адрес компиляции модуля (на данный момент это #7000)
LD BC,#0100 ;Максимальная длина модуля
LDIR ;Переносим модуль из в ПЗУ в ОЗУ
CALL MODADR ;Запускаем модуль
.... ;Продолжение работы загрузчика
Окончательная сборка игры
Итак, все файлы (opis.txt, loader.asm, ini-файл, кодовые блоки игры) подготовлены, наступает время собрать их воедино. Для этого надо запустить файл _createGameImage.bat в папке с игрой. Файл состоит из трёх строк:
..\..\sjasmplus loader.asm --raw=loader.cod
python ..\..\descriptionBuilder.py opis.cod opis.txt
python ..\..\AlfBuilder.py BruceLee.alf BruceLee.ini
Первая строка - компиляция загрузчика из исходника loader.asm в loader.cod
Вторая строка - перекодировка описания игры из opis.txt в файл opis.cod
Третья строка - сборка всех файлов из BruceLee.ini в один файл BruceLee.alf
В процессе сборки обращайте внимания на выводимые сообщения, на случай ошибки.
Сборка образа картриджа
Имея файлы игр в формате *.alf из них можно собрать образ картриджа для приставки «Эльф».
Для этого надо:
- один или несколько файлов *.alf;
- текстовый файл (в кодировке UTF-8!), в котором будет список игр, помещаемых на картридж.
Текстовый файл (spisok.txt) состоит просто из списка названий игр и названий файлов игр. Например:
Брюс Ли, games\Bruce_Lee\BruceLee.alf
Диззи-Х, games\Dizzy-X\Dizzy-X.alf
Диззи-У, games\Dizzy-Y\Dizzy-Y.alf
Сначала указываем название игры на кириллице. Из названия берётся 13 символов, остальные игнорируются. Дальше через запятую и пробел указываем файл с игрой. Одна игра - одна строка.
Для сборки образа картриджа выполняем файл runMe.bat:
python ALFimageBuilder.py ROM0.bin spisok.txt
Где spisok.txt - список игр для помещения на картридж, ROM0.bin - образ картриджа, который будет создан в результате работы скрипта ALFimageBuilder.py.
Возможные ошибки при выполнении скрипта:
- Invalid command line syntax - недостаточное количество аргументов командной строки;
- Not enough arguments - не указаны входной или выходной файлы;
- File size is not supported by ALF! - если в процессе сборки файл прошивки превысит объём 1МБ (для варианта сборки образа картриджа) или 128КБ (для варианта сборки образа ПЗУ на плату приставки);
- No games detected in file - если во входном файле не обнаружено ни одной игры;
- Internal catalog end marker error - ошибка в структуре внутреннего каталога обрабатываемого файла *.alf. Если во внутреннем каталоге больше 18 файлов, или если не найден маркер конца каталога;
- File structure error - Если в заголовке alf-файла отсутствует байт #02 или #80 после окончания внутреннего каталога файлов. Ошибка появляется при попытке собрать прошивку ПЗУ для платы Эльф (ключ /R) из неадаптированных для подобной сборки файлов игр.
И финальный аккорд - проверка собранного образа картриджа ROM0.bin на эмуляторе. Запускаем файл EMU.bat. В архиве расположен эмулятор приставки «Эльф» сконфигурированный так, чтобы в качестве образа картриджа ипользовать файл ROM0.bin
Утилиты и игры
|
|
Утилиты для сборки игры и образа картриджа приставки «Эльф», а также игры для сборки в образ картриджа (дата сборки 31.07.2025)В архиве содержатся скрипты на Python для сборки одной игры, для сборки образа картриджа, все имеющиеся на данный момент игры для приставки, адаптированные для сборки, а также исходники их загрузчиков и кодовые блоки игр. В архиве содержатся адаптации игр от san0101010, KRT17 и Prusak
|