ハードウエアの概要 |
このページは、何が書いてあるのかざっと目を通しておき、後でプログラミングするときに、必要個所を詳しく読んでください。
GBAの仕様
下図のように2プロセッサアーキテクチャとなっています。Z80はGameboyとの互換のために必要となります。ここでは、ARM7TDMIをターゲットとして開発を行います(TDMIのアーキテクチャについては各自で調べてみよう)。メモリは1クロックサイクルでアクセス可能な内部RAMと、アクセスに3クロックサイクル必要な外部RAM、およびLCD表示用のVRAM(Video RAM)に分かれています。プログラムは外部RAMに配置されます。
![]() | ![]() |
GBAの構造 | ARM7アーキテクチャ |
メモリマップ
GBAでは、IOの制御もメモリと同じアドレス空間上に配置されたIOレジスタを通して行います。下記のメモリマップを覚えているのはつらいので、ヘッダーファイルに記載して使用します。
種類 | 先頭アドレス | 容量 | バス幅 | 説明 |
---|---|---|---|---|
スプライト(OAM) | 0x0700 0000 | 1kB | 32bit | オブジェクトと背景を重ねる機能 |
VRAM | 0x0600 0000 | 96kB | 16bit | LCD に表示するデータを入れる |
パレット | 0x0500 0000 | 1kB | 16bit | 256色分色を記憶しておくことができる |
IOレジスタ | 0x0400 0000 | 1kB | 32bit | LCD などの IO 機能を制御するレジスタ |
内部RAM | 0x0300 0000 | 32kB | 32bit | ARM 内蔵の高速メモリ |
外部RAM | 0x0200 0000 | 256kB | 16bit | プログラムを入れる外部メモリ |
BIOS | 0x0000 0000 | 16kB | 32bit | 起動プログラムやファンクションコールを実装したROM |
グラフィクスの構成
LCDの背景表示方法には、ビットマップ・モード(各ピクセルに色を設定)とタイル・モード(8x8pixのタイルを並べる)があります。モードの種類は0〜5までありますが、ここではモード0(タイル)とモード3(ビットマップ)を使用します。
データ内容 | 先頭アドレス | 容量 | バス幅 |
---|---|---|---|
Objectデータ | 0x0614 0000 | 16kB | 2Byte |
BG2 RGBデータ | 0x0600 0000 | 80kB | 2Byte |
先頭アドレス (容量) | タイルデータブロック番号 | タイルデータブロック番号 | 先頭アドレス (容量) |
|
---|---|---|---|---|
0x0601 0000 (32k Byte) | オブジェクトデータ | |||
0x0600 C000 (16k Byte) | タイルブロック 3 | マップブロック 31 | 0x0600 F800 (2k Byte) | |
マップブロック 30 | 0x0600 F000 (2k Byte) | |||
マップブロック 29 | 0x0600 E800 (2k Byte) | |||
マップブロック 28 | 0x0600 E000 (2k Byte) | |||
マップブロック 27 | 0x0600 D800 (2k Byte) | |||
マップブロック 26 | 0x0600 D000 (2k Byte) | |||
マップブロック 25 | 0x0600 C800 (2k Byte) | |||
マップブロック 24 | 0x0600 C000 (2k Byte) | |||
0x0600 8000 (16k Byte) | タイルブロック 2 | マップブロック 23 | 0x0600 B800 (2k Byte) | |
マップブロック 22 | 0x0600 B000 (2k Byte) | |||
マップブロック 21 | 0x0600 A800 (2k Byte) | |||
マップブロック 20 | 0x0600 A000 (2k Byte) | |||
マップブロック 19 | 0x0600 9800 (2k Byte) | |||
マップブロック 18 | 0x0600 9000 (2k Byte) | |||
マップブロック 17 | 0x0600 8800 (2k Byte) | |||
マップブロック 16 | 0x0600 8000 (2k Byte) | |||
0x0600 4000 (16k Byte) | タイルブロック 1 | マップブロック 15 | 0x0600 7800 (2k Byte) | |
マップブロック 14 | 0x0600 7000 (2k Byte) | |||
マップブロック 13 | 0x0600 6800 (2k Byte) | |||
マップブロック 12 | 0x0600 6000 (2k Byte) | |||
マップブロック 11 | 0x0600 5800 (2k Byte) | |||
マップブロック 10 | 0x0600 5000 (2k Byte) | |||
マップブロック 9 | 0x0600 4800 (2k Byte) | |||
マップブロック 8 | 0x0600 4000 (2k Byte) | |||
0x0600 0000 (16k Byte) | タイルブロック 0 | マップブロック 7 | 0x0600 3800 (2k Byte) | |
マップブロック 6 | 0x0600 3000 (2k Byte) | |||
マップブロック 5 | 0x0600 2800 (2k Byte) | |||
マップブロック 4 | 0x0600 2000 (2k Byte) | |||
マップブロック 3 | 0x0600 1800 (2k Byte) | |||
マップブロック 2 | 0x0600 1000 (2k Byte) | |||
マップブロック 1 | 0x0600 0800 (2k Byte) | |||
マップブロック 0 | 0x0600 0000 (2k Byte) | |||
0x0500 0000 (512 Byte) | 背景パレットデータ (15bit BGR) |
LCDコントロールレジスタ
LCD表示モードの指定は、アドレス 0x0400 0000 のLCDコントロールレジスタで行います。また、同時に背景(BG0〜BG3)かオブジェクト(背景の上に表示するキャラクタ)かも指定します。
LCDコントロールレジスタの設定例
STATE | HEX | Binary | Description |
---|---|---|---|
Default | 0x0080 | 0000 0000 1000 0000 | bit7=1:強制白塗り |
MODE 3 | 0x0403 | 0000 0100 0000 0011 | bit10:BG2の背景を使用 bit0-2:モード3 |
MODE 0 | 0x0100 | 0000 0001 0000 0000 | bit8:BG0の背景を使用 bit0-2:モード0 |
LCDコントロールレジスタへの書き込み方法
定数・マクロ定義
typedef unsigned short hword; // 16bit integer #define gba_reg(p) *((volatile hword*) p) // load to conrtol register #define IO_BASE 0x0400 000 // IO base address #define LCD_CTL (IO_base + 0) // LCD control register address #define LCD_BG0 0x0100 // Enable BG0 plane #define LCD_BG2 0x0400 // Enable BG2 plane #define LCD_MODE0 0 // LCD mode 0 #define LCD_MODE3 3 // LCD mode 3 |
実行文の例
gba_reg(LCD_CTL) = LCD_BG2 | LCD_MODE3; // MODE 3 + BG2 ON |
上の実行文は gba_reg(p) マクロを利用して、*((volatile hword*) 0x04000000) = 0x0400|0x0003; に置き換えられます。ここで、
0x0400 == | 0000 0100 0000 0000 |
0x0003 == | 0000 0000 0000 0011 |
背景コントロールレジスタ
MODE 0 では、タイルやマップ(タイルを並べて作った背景画面)の使い方を指定するため、背景コントロールレジスタを設定します。背景はBG0〜BG3の4枚があり、それぞれに対応する背景コントロールレジスタがあります。
仮想スクリーンサイズの定義
bit 14-bit 15 | Virtual Screen Size |
---|---|
00 | 256x256pix (32x32 tiles) |
01 | 512x256pix (64x32 tiles) |
10 | 256x512pix (32x64 tiles) |
11 | 512x512pix (64x64 tiles) |
カラーモード
bit 14-bit 15 | Virtual Screen Size |
---|---|
0 | 16色x16パレット |
1 | 256色x1パレット |
表示優先順位
bit 0-bit 1 | Background priority |
---|---|
通常 BG0-BG3全て 00 で使用 | BG0 > BG1 > BG2 > BG3 |
設定例
STATE | HEX | Binary | Description |
---|---|---|---|
Default | 0x0000 | 0000 0000 0000 0000 | 仮想スクリーン32x32tile, カラー16色 |
example 1 | 0x1C80 | 0001 1100 1000 0000 | 仮想スクリーン32x32tile, カラー256色, タイルブロック0を使用, マップブロック28 (11100)を使用 |
背景コントロールレジスタへの書き込み方法は、LCDコントロールレジスタへの書き込みの場合と全く同じです。
定数・マクロ定義
typedef unsigned short hword; // 16bit integer #define gba_reg(p) *((volatile hword*) p) // load to conrtol register #define IO_BASE 0x0400 000 // IO base address #define LCD_CTL (IO_base + 0) // LCD control register address #define BG0_CTL (IO_base + 8) // BG0 control register address #define LCD_BG0 0x0100 // Enable BG0 plane #define LCD_BG2 0x0400 // Enable BG2 plane #define LCD_MODE0 0 // LCD mode 0 #define LCD_MODE3 3 // LCD mode 3 #define LCD_BGTILE(n) (n << 2) // BG tile base block #define LCD_BGMAP(n) (n << 8) // BG map base block #define LCD_SIZE00 0x0000 // BG size 32x32tiles #define LCD_COLOR256 0x0080 // BG 256color x 1 palette |
実行文の例
gba_reg(BG0_CTL) = LCD_SIZE00 | // 32x32tile LCD_COLOR256 | // 256color LCD_BGTILE(0) | // Tile block 0 LCD_BGMAP(28); // Map block 28 gba_reg(LCD_CTL) = LCD_MODE0 | LCD_BG0; // MODE 0 + BG0 ON |
オフセットレジスタ
LCDは、デフォルトで仮想画面の左上部分(x=0〜240pix, y=0〜160pix)を表示しています。オフセットレジスタに、LCD表示部の左上角の座標(0〜511 = 9bit)を書き込むと、LCD表示部が、仮想画面上の指定座標へ移動します。
スプライト(オブジェクト)
GBA には、ビットマップやタイルによる背景の上へ、オブジェクトを描く機能(所謂、スプライト)があります。オブジェクトのサイズは、8x8pix〜64x64pix までです。背景用のVRAMフレームバッファとは独立したメモリ領域を割り当ててあり、オブジェクトをピクセル単位で高速に移動・回転・拡大することができます。
サイズ (Attribute 1) | ||||||
---|---|---|---|---|---|---|
00 | 01 | 10 | 11 | |||
形状 (Attribute 0) | 00 | 8x8pix![]() | 16x16pix![]() | 32x32pix![]() | 64x64pix![]() | |
01 | 16x8pix![]() | 32x8pix![]() | 32x16pix![]() | 64x32pix![]() | ||
10 | 8x16pix![]() | 8x32pix![]() | 16x32pix![]() | 32x64pix![]() |
キーステータスレジスタ
GBA は、L, R, A, B, Start, Select, カーソルキー(上、下、左、右)の10個の入力キーを持っています。各キーの ON/OFF 状態は、キーステータスレジスタから読み取ることができます。
タイマー
GBA は、4個のタイマーを持っています。各タイマーは、システムクロック数をカウントする16bitカウンタとして動作します。タイマーの各種モード設定は、タイマー制御レジスタで行います。また、タイマーのカウント初期値 (16bit) の設定及び現在のカウント値の読み出しは、タイマー設定レジスタにより行います。プリスケーラ値は、システムクロック(16.78MHz = 1024Hz)を何クロック毎にカウントアップするか指定します。カスケードスイッチは、タイマーのオーバフロー(桁上がり)をカスケード接続して長時間のカウントを可能にします。この場合は、プリスケーラは無効です。また、オーバフローにより割り込み発生を行うかどうかも指定できます。
タイマーの構造:
タイマー制御レジスタ:
制御レジスタの設定ビット
カウントイネーブル | 割り込み発生 | カスケードスイッチ | |||
---|---|---|---|---|---|
0 | タイマー動作 | 0 | OFF | 0 | OFF |
1 | タイマー停止 | 1 | ON | 1 | ON |
プリスケーラと時間の関係(システムクロック 16.78MHz)
プリスケーラ (2bit) | カウントサイクル | 1サイクル時間 | 16bit カウント時間 |
---|---|---|---|
00(デフォルト) | 1 clock | 60ns | 3.9ms |
01 | 64 clock | 3.8us | 250ms |
10 | 256 clock | 15.3us | 1s |
11 | 1024 clock | 61us | 4s |
タイマー設定レジスタ:
(c) Kanazawa Univ., 2004