Содержание статьи
Вот как выглядит результат.
$ perl -E"say'swFoAKAHvqB9uBMAzRC/wPi5gAjzqqqBxz4Bc/jkYDxIchE8UHcNN5hISHIFLAJrwLCJwwHetIa2780VtEUmMCR72uv','B'x589,'Vao='"|base64 -D>boot.img
В некоторых системах (например, 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
а затем запустить в QEMU, если у тебя по каким-то причинам нет возможности записать на настоящую дискету:
qemu-system-i386 -fda floppy.img
Код начинается с прагмы, которая сообщает процессору, что нужно перейти в шестнадцатиразрядный режим (в нем машина 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 пикселей, то получатся границы снизу и сверху.
mov di, 320*199
mov cx, 2176
rep
draw_loop:
stosb
stosb
add di, 318
jnc draw_loop
Обрати внимание на переход в середине инструкции rep stosb
.
В основном цикле мы читаем ввод с клавиатуры на порте 0x60. Сюда же попадает ввод мыши, но нам нужно обрабатывать только «вверх» (0x48), «влево» (0x4b), «вправо» (0x4d) и «вниз» (0x50).
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»