GBA ASM - День 3: Больше ассемблера и помещение картинки на экран — Архив WASM.RU

Все статьи

GBA ASM - День 3: Больше ассемблера и помещение картинки на экран — Архив WASM.RU

Во-первых, инструкции ADD и SUB расшифровываются как сложение (addition) и вычитание (substraction). Они обе могут иметь суффикс установки флагов, что особенно полезно, когда надо узнать, был ли результат операции равен нулю (0).

	У обеих инструкций 3 операнда (параметра):
	
	ADD r0, r1, 1

		r0 = r1 + 1   

Инструкция ADD складывает последние два параметра и помещает их в первый.

ПРИМЕЧАНИЕ: я думаю, что первые два параметра должны быть регистрами, но я не уверен.

	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 и откройте

	Теперь идёт сам код:

	; --Начинайте копировать здесь--

	@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, напечатайте:

Visualboyadvance picscrn.gba

Посмотрите на свою прелестную картинку на эмуляторе.

Поздра... Нет, есть ещё несколько вещей, которые требуют объяснений.

Вот эти 2 строки:

	ldr r2,[r1]+4!  
	str r2,[r0]+4! 

Вы, вероятно, интересуетесь, что такое +4!, правильно? Я тоже не знал, что это такое, пока не провёл некоторые исследования. '!' означает хитрую вещь под названием "write-back", поэтому строка 'ldr r2,[r1]+4!' на самом деле означает следующее:

Загрузить в регистр r2 содержимое того, на что указывает r1, а затем, после того как всё сделано, добавить 4 к r1. Чтобы добавить 4 к r1 до того, как произойдёт загрузка в r2, необходимо составить инструкцию следующим образом:

ldr r2,[r1+4]!

	   * +4 внутри скобок '[]' означает "добавьте 4 к r1 ДО выполнения инструкции"
	     
	     * Восклицательный знак должен находится в конце всей инструкции и 
	       означает 'write-back'.

Причина для делания 'write-back' на +4 заключается в том, что мы загружаем 2 пикселя за раз, а каждый пиксель равен 2 байтам (2*2=4). И помните, что мы обрабатываем 2 пикселя за раз, потому что каждый пиксель занимает 2 байта, а инструкции загрузки и сохранения 32-х битны.

Ух! Это была тяжёлая работа! Поздравляю! Вы прошли безжалостный День 3.

Я не знаю ещё о чём будет День 4, либо об обработке нажатия на клавиатуру, либо о БИОСе GBA.

- Надеюсь, вам понравилось.

2002-2013 (c) wasm.ru