В 1998 году люди соревновались, кто напишет самую короткую игру для DOS. Позже этот вид соревнования назвали «код-гольфингом». Я решил вернуться к такому кусочку кода (nibbles.asm) и превратить его в загрузочный образ дискеты, который бы умещался в твит, то есть в 140 символов.
В некоторых системах (например, Linux) ключ -D пишется в нижнем регистре (base64 -d).
INFO
Это адаптированный перевод двух статей Алока Менхраджани: Bootloader + retro game in a tweet и Bootable CD + retro game in a tweet. Публикуется с разрешения автора. Перевел Андрей Письменный.
Образ загрузочной дискеты со «Змейкой»
Технически мой код — это не бутлоадер. Настоящий бутлоадер переводит машину с x86 в защищенный режим, загружает данные с диска (BIOS загружает только первые 512 байт) и так далее. Я пропустил все это и вместо этого задаю некоторые регистры и прыгаю прямо в игру.
hugi.de
Один из популярных сайтов, где проходили эти соревнования, назывался Hugi, и игра Nibbles, которую Altair и ODDS entertainment уместили в 48 байт, была одним из моих любимых творений. Эта игра также широко известна как Tron и «Змейка».
К сожалению, старый код оказалось не так-то просто заставить работать. Нужен DOS, и если работать с эмулятором, то приходится гадать, какое железо могло тогда быть у разработчиков и на какой частоте оно работало.
Поэтому я решил взять код Altair и превратить его в загрузочную дискету. Заодно сделал несколько изменений, чтобы можно было нормально играть.
floppy.asm
Итак, давай разберем код.
Для запуска кода нужно сначала скомпилировать его:
nasm floppy.asm -o floppy.img [/code]
а затем запустить в QEMU, если у тебя по каким-то причинам нет возможности записать на настоящую дискету:
qemu-system-i386 -fda floppy.img [/code]
Код начинается с прагмы, которая сообщает процессору, что нужно перейти в шестнадцатиразрядный режим (в нем машина x86 изначально находится при загрузке с флоппи).
[bits 16]
Еще одна прагма сообщает ассемблеру, где находится код, который нужно загрузить.
[org 0x7C00]
Задаем начальную позицию для нашей змейки.
mov bl, 1
Загружаем адрес VRAM в регистр ES.
push 0xa000
pop es
Теперь задаем позицию змейки в центре экрана и переключаем видеорежим. Режим 13h — это VGA (1 байт на пиксель, тогда как настоящий цвет хранится в палитре), общий размер 320 на 200. При рестарте сразу же очищаем экран.
restart_game:
mov
si, 320*100+160
mov
ax, 0x0013
int
0x10
Рисуем границы. Предполагаем, что палитра по умолчанию нас устроит. Также предполагаем, что если мы начнем снизу и закрасим 2176 пикселей, то получатся границы снизу и сверху.
Обрати внимание на переход в середине инструкции rep stosb.
В основном цикле мы читаем ввод с клавиатуры на порте 0x60. Сюда же попадает ввод мыши, но нам нужно обрабатывать только «вверх» (0x48), «влево» (0x4b), «вправо» (0x4d) и «вниз» (0x50).