GBA ASM - День 3: Больше ассемблера и помещение картинки на экран — Архив WASM.RU
Во-первых, инструкции ADD и SUB расшифровываются как сложение (addition) и вычитание (substraction). Они обе могут иметь суффикс установки флагов, что особенно полезно, когда надо узнать, был ли результат операции равен нулю (0).
Код (Text):
У обеих инструкций 3 операнда (параметра): ADD r0, r1, 1 r0 = r1 + 1Инструкция ADD складывает последние два параметра и помещает их в первый.
ПРИМЕЧАНИЕ: я думаю, что первые два параметра должны быть регистрами, но я не уверен.
Код (Text):
SUB r0, r1, 2 r0 = r1 - 2Инструкция SUB вычитает третий операнд из первого и помещает результат в первый.
Теперь, когда вы поняли, что такое ADD и SUB, давайте поместим на экран GBA картинку.
Используемый инструмент
Я использовал программу под названием Bimbo для экспорта картинки размером 240x160 в asm-формат. Скачайте её из раздела gfx-утилит на GBADev.Org. Теперь идите в Microsoft Paint (а лучше в какой-нибудь более приличный редактор - прим. пер.) и нарисуйте картинку размером 240 на 160 и сохраните её как 256-ти цветный битмап. Запустите Bimbo и нажмите кнопку "Открыть".
Нажмите кнопку "Export". При сохранение укажите "Assembler Source". Теперь начинается самое интересное. Bimbo не помещает '@' перед директивами в коде, который он генерирует, поэтому мы должны открыть наш любимый текстовый редактор и заменить DCW на @DCW. Чтобы сделать это как можно быстрее используйте функцию 'Replace All'.
Ок, теперь давайте напишем код для вывода нашей картинки на экран:
Замечание: переименуйте ваш asm-файл, в котором задана картинка, в pic.asm и откройте
Код (Text):
Теперь идёт сам код: ; --Начинайте копировать здесь-- @include screen.h ; подключаем screen.h b start ; перепрыгиваем через картинку (вы ведь не хотите, ; чтобы GBA попытался её выполнить? :) ) @include pic.asm ; подключаем картинку start ; метка по имени start @textarea ; код начинается после этой директивы ; Так же как и в День 1 устанавливаем режим 3 с фоном 2 ldr r1,=REG_DISPCNT ; также как и в День 1 ldr r0,=(MODE_3|BG2_ENABLE) str r0,[r1] ; Приготовляемся к помещению картинки в VRAM (видеопамять) ldr r0,=VRAM ; делаем r0 указателем на VRAM (0x06000000). ldr r1,=picBitmap ; делаем r1 указателем на данные с вашей картинкой ldr r3,=19200 ; мы хотим получить доступ к памяти 19200 раз ; цвет экрана в режиме 3 16-ти битен, ; 240x160 pixels = 38400 ; 19200, так как за раз мы копируем 2 пиксела ; (инструкция сохранения 32-х битна) label1 ; метка по имени label1 ldr r2,[r1]+4! ; загружает в r2 следующие два (2) пикселя из данных с ; с картинкой (на которые указывает r1). str r2,[r0]+4! ; сохраняет содержимое r2 (в нём 2 пикселя) в VRAM. subs r3,r3,1 ; вычитает 1 количества раз, которое мы хотим получить ; доступ к видеопамяти (VRAM). ; обратите внимание на суффикс S в инструкции SUB - здесь ; мы задаём состояние флагов. bne label1 ; эта инструкция перехода проверяет, указывает ли ; состояние флагов на нулевой результат. Если количество ; раз, которое мы хотим получить доступ к VRAM, не равно ; нулю (0), тогда продолжаем выполнение цикла. infin ; метка под названием infin b infin ; переход на infin ; предыдущие 2 строки являются бесконечным циклом. :) while(1) {} ; сохраните этот файл как picscrn.asm ;--Заканчивайте копировать здесь--Вы посмотрели код. Теперь давайте сассемблируем его!
Поместите pic.asm, screen.h и picscrn.asm в папку Goldroad. Сначала попытайтесь перетащить picscrn.asm в goldroad.exe, если он не создаст файл .GBA, тогда откройте DOS-окно, смените директорию на папку Goldroad'а и напечатайте:
Goldroad picscrn.asm и нажмите ввод
Эмулятор тоже должен быть в папке ассемблера, поэтому если это VisualboyAdvance, напечатайте:
Код (Text):
Visualboyadvance picscrn.gbaПосмотрите на свою прелестную картинку на эмуляторе.
Поздра... Нет, есть ещё несколько вещей, которые требуют объяснений.
Вот эти 2 строки:
Код (Text):
ldr r2,[r1]+4! str r2,[r0]+4!Вы, вероятно, интересуетесь, что такое +4!, правильно? Я тоже не знал, что это такое, пока не провёл некоторые исследования. '!' означает хитрую вещь под названием "write-back", поэтому строка 'ldr r2,[r1]+4!' на самом деле означает следующее:
Загрузить в регистр r2 содержимое того, на что указывает r1, а затем, после того как всё сделано, добавить 4 к r1. Чтобы добавить 4 к r1 до того, как произойдёт загрузка в r2, необходимо составить инструкцию следующим образом:
Код (Text):
ldr r2,[r1+4]! * +4 внутри скобок '[]' означает "добавьте 4 к r1 ДО выполнения инструкции" * Восклицательный знак должен находится в конце всей инструкции и означает 'write-back'.Причина для делания 'write-back' на +4 заключается в том, что мы загружаем 2 пикселя за раз, а каждый пиксель равен 2 байтам (2*2=4). И помните, что мы обрабатываем 2 пикселя за раз, потому что каждый пиксель занимает 2 байта, а инструкции загрузки и сохранения 32-х битны.
Ух! Это была тяжёлая работа! Поздравляю! Вы прошли безжалостный День 3.
Я не знаю ещё о чём будет День 4, либо об обработке нажатия на клавиатуру, либо о БИОСе GBA.
- Надеюсь, вам понравилось. © Mike H, пер. Aquila
GBA ASM - День 3: Больше ассемблера и помещение картинки на экран
Дата публикации 30 июл 2003