index
作業手順練習ソースプログラム解説

/****************************************/
/*	Test program using tile mode	*/
/****************************************/

#include "gba.h"
hword* map	= (hword*) VRAM_MAP(16);	// Map base address
hword* tile	= (hword*) VRAM_TILE(0);	// Tile base address
hword* color	= (hword*) BG_PALETTE;		// Palette
void waiting(int);
VRAM および背景パレットの使用領域を配列に割り当てます。gba.h に定義されている VRAM_MAP(16) = 0x0600 8000, VRAM_TILE(0) = 0x0600 0000, BG_PALETTE = 0x0500 0000 の数値を、ポインタとしてインデックスレジスタにセットしていると考えられます。
int main() {

	int i, j, k = 0, index;		// index: tile index

	// Background pallet color
	color[1] = RGB( 0,  0,  0);	// Black
	color[2] = RGB( 0,  0, 31);	// Blue
	color[3] = RGB( 0, 31,  0);	// Green
	color[4] = RGB( 0, 31, 31);	// Aqua
	color[5] = RGB(31,  0,  0);	// Red
	color[6] = RGB(31,  0, 31);	// Purple
	color[7] = RGB(31, 31,  0);	// Yellow
	color[8] = RGB(31, 31, 31);	// White
8色分のカラー値(ハードウエアの概要参照)を、パレットの先頭アドレスからパレットの配列に代入します。配列への代入は、ポインタ変数が指すアドレスへ書き込んだのと同じです。
具体的には、RGB(0, 0, 0) = ((0 << 10) + (0 << 5) + 0) = 0x0000(黒) を BG_PALETTE = 0x0500 0000 + 1 のアドレスに書き込んでいます。
Pallet
	// Tile data
	for (i = 0; i < 8; i++) {
		for (j = 0; j < 32; j++)
			tile[i * 32 + j] = ((i + 1) << 8) + (i + 1);
		}
タイルデータを初期化します。256色モードのパレットインデックスは、1Byteで表されるます、2Byte単位でまとめて同じ値(ex. i=0のとき 0x0101 = 0x01を2回分)を書き込んでいます。従って、32回のループで1タイル分(64pix)のデータが代入されます。これを8枚分繰り返しています。データ量は、64Byte x 8枚 = 512Byte 使用したことになります。従って、VRAMの 0x0600 0000 - 0x0600 01FFを使用しています。
Tile
	// Map data
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 15; j++) {
			index = ((k + i + j) % 8) + 1;
			map[(i * 32 + j) * 2	 ] = index;
			map[(i * 32 + j) * 2 + 1 ] = index;
			map[(i * 32 + j) * 2 + 32] = index;
			map[(i * 32 + j) * 2 + 33] = index;
		}
	}
	k++;
マップデータを初期化します。index の計算は、初期値を k, i, j で決めて、1〜8の数字を繰り返すようになっています。下図のように、(1, 2, 32, 33)のように4タイルづつ同じ index の値が書き込まれ、index 値を変えながら横15回(j)、縦10回(i)繰り返すことにより、30x20タイル分のLCD実画面上を埋め尽くします。変数 k は、画面全体に書き込んだ回数で、後の Resraw ルーチンで使用されます(ここでは、k=1 で終了)。32x32タイル分の仮想画面も使用しているとしていると見なすと、1Byte x 32タイル x 32タイル x 1枚 = 1024Byte のVRAMが必要となり、0x0600 8000 - 0x0600 03FF を使用します。
Map VRAM assign
	// Background control register & LCD control register & LCD ON
	load_ioreg(BG0_CTL) = 	LCD_SIZE00 |		// 32x32tile
				LCD_COLOR256 |		// 256color
				LCD_BGTILE(0) |		// Tile block 0
				LCD_BGMAP(16);		// Map block 16
BG0_CTL = 0x0400 0008 の BG0用背景コントロールレジスタに下記の背景設定を書き込んでいます。
LCD_SIZE000x00000000000000000000
LCD_COLOR2560x00800000000010000000
LCD_BGTITLE(0)0 << 20000000000000000
LCD_BGMAP(16)10000 << 80001000000000000
OR0001000010000000
この結果、仮想スクリーンサイズ00(32 x 32 タイル)、VRAMマップブロック開始アドレス16 (= 0x0600 8000)、カラーモード256色、VRAMタイルブロック開始アドレス0 (= 0x0600 0000)となります。ハードウエアの概要のページで確認しよう。
	gba_reg(LCD_CTL) = 	LCD_MODE0 | LCD_BG0;	// MODE 0 + BG0 ON
LCDコントロールレジスタに、モード0を指定し、背景BG0をONにしています。詳しくは、ハードウエアの概要のページで確認しよう。
	// Redraw LCD
	while (1) {
		waiting(128);
		for (i = 0; i <10; i++) {
			for (j = 0; j < 15; j++) {
				index = ((k + i + j) % 8) + 1;
				map[(i * 32 + j) * 2	 ] = index;
				map[(i * 32 + j) * 2 + 1 ] = index;
				map[(i * 32 + j) * 2 + 32] = index;
				map[(i * 32 + j) * 2 + 33] = index;
			}
		}
		k = (k < 15) ? k + 1 : 0;
	}
}
タイルインデックス index の値をマップに書き込み、これを15回毎に初期化します。waiting(128) は、引数に応じて時間待ちしています。
/***	Waiting rootine    ***/
void waiting(int t) {
	int i, j;
	for (i = 0; i < t; i++)
		for (j = 0; j < t; j++);
}
tの値に応じて待ち時間をカウントするループです。


お問い合わせはこちらまで: kitagawa@is.t.kanazawa-u.ac.jp

(c) Kanazawa Univ., 2004