
| タイマー |
![]() |
内蔵のタイマーをカスケード接続して、正確に時間を計るプログラムの例です。screen 構造体のx-y座標に値を代入すると、エミュレータ上で正しく動作しないようなので、実機で動作テストしてください。もし、原因が解ったら教えてください。座標の保存のために配列を使用しなければ、エミュレータでも動作するようですが、マルチタスクOS上のエミュレータでは、正確な時間は計れません。 |
/****************************************************************/ /* Timer control */ /****************************************************************/ #include "gba.h" #include "FontC64-08.c" void init_screen(void); void location(int, int); void scroll(void); void print(const char*); void print_hex8(int); void print_hex16(int); |
| FontC64-08.c は、キー入力と複数画面合成で使用したものと同じフォントデータ。 |
// Background palette base address pointer 0x05000000
hword* bcolor = (hword*) BG_PALETTE;
// Screen structures
screen plane[ 1 ] = {
{ (hword*) VRAM_MAP(16), (hword*) VRAM_TILE(0), 0, 0},
};
int page = 0; // page number
|
| 背景パレットのポインタ設定と、文字表示画面用のscreen型構造体を用意します。ここでは、背景を使用しないため、画面は1枚だけ必要なので、画面番号は page = 0 のみを使用します。 |
int main() {
// Initialize screen
init_screen();
|
| init_screen 関数で、フォントデータの設定と画面の初期設定を行います。 | // Initialize timers gba_reg(TIMER_CNT0) = 0x0000; gba_reg(TIMER_CNT1) = 0x0000; |
| タイマー0とタイマー1のタイマー設定レジスタを16 bit の 0 に設定しています。これで、カウント初期値が、0になります。 | gba_reg(TIMER_CTL0) = TIMER_ENABLE + TIMER_PRE256; gba_reg(TIMER_CTL1) = TIMER_ENABLE + TIMER_CASCADE; |
| タイマー0とタイマー1のタイマー制御レジスタの値を、タイマー動作開始にすると同時に、タイマー1のプリスケーラ(分周器)を、256 = 28 周期に設定しています。これで、16 bit フルカウントすると、216 + 8 = 224となります。GBAのシステムクロックの周波数は、224Hz に設定されているため、16bit フルカウントすると、丁度1秒に相当します。ハードウエアの概要のページで確認してください。タイマー0だけでは、1秒までしかカウントできないので、タイマー1をカスケードモードにして1秒単位でカウントアップさせます。カスケードモードでは、前の番号のタイマーがオーバフローする毎に、1カウントするモードです。この設定方法も、ハードウエアの概要のページで確認してください。 |
// Print loop
while (1) {
location(8, 7);
print("Timer 0 : ");
location(18, 7);
print_hex16(gba_reg(TIMER_CNT0));
location(8, 8);
print("Timer 1 : ");
location(18, 8);
print_hex16(gba_reg(TIMER_CNT1));
}
}
|
| location 関数で、文字を出力する座標を指定し、タイマー0とタイマー1のカウント値を16進数4桁で表示します。 |
// Screen Initialization
void init_screen(void) {
int i, row, col, bit, val;
// Initialize palettes
bcolor[ 0 ] = RGB(0, 0, 0); // Black
bcolor[ 1 ] = RGB(0, 31, 25); // Green
// Setup tiles of font set
for (i = 0; i < 96; i++) {
for (row = 0; row < 8; row++) {
for (col = 7; col >= 0; col--) {
bit = (Font[ i ][ row ] & (1 << col)) ? 1 : 0;
if (col % 2)
val = bit;
else
plane[ 0 ].tile[((i + 32) * 32) + (row * 4) + \
((7 - col)/2)] = val + (bit << 8);
}
}
}
|
| フォントデータをタイルに読み込みます。この処理は、テキスト表示のページと同じです。 | //Setup background mode and LCD control register gba_reg(BG0_CTL) = LCD_SIZE00 | LCD_COLOR256 | LCD_BGTILE(0)| LCD_BGMAP(16); gba_reg(LCD_CTL) = LCD_BG0 | LCD_MODE0; } |
| 文字表示用に背景コントロールレジスタとLCDコントロールレジスタを設定します。これまでに、何度も出てきたので、説明を省略します。 |
// Present position of tile character
void location(int xx, int yy) {
if (xx < 0)
plane[ page ].x = 0;
else if (xx >= 30)
plane[ page ].x = 30 - 1;
else
plane[ page ].x = xx;
if (yy < 0)
plane[ page ].y = 0;
else if (yy >= 20)
plane[ page ].y = 20 - 1;
else
plane[ page ].y = yy;
}
|
| 文字出力座標(タイル単位)を指定する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
// Scroll up
void scroll(void) {
int i, j;
// Scroll
for (i = 1; i < 20; i++) {
for (j = 0; j < 30; j++)
plane[ page ].map[ (i - 1) * 32 + j ] = \
plane[ page ].map[ i * 32 + j ];
}
// End line
for (j = 0; j < 30; j++)
plane[ page ].map[ 19 * 32 + j ] = 0x20; // SP in bottom line
}
|
| 文字出力画面をスクロールさせる関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
// Print function
void print(const char* str) {
const char* pt = str;
while (*pt) {
if (*pt == '\n') {
plane[ page ].x = 0;
if (plane[ page ].y < (20 - 1))
plane[ page ].y++;
else
scroll();
pt++;
continue;
}
plane[ page ].map[ plane[ page ].y * 32 + plane[ page ].x ] = *pt++;
if (plane[ page ].x < (30 - 1))
plane[ page ].x++;
else {
plane[ page ].x = 0;
if (plane[ page ].y < (20 - 1))
plane[ page ].y++;
else
scroll();
}
}
}
|
| 文字列を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
// Print 1Byte HEX
void print_hex8(int val) {
char buf[ 3 ];
buf[ 0 ] = "0123456789ABCDEF"[ (val & 0xF0) >> 4 ];
buf[ 1 ] = "0123456789ABCDEF"[ val & 0x0F ];
buf[ 2 ] = 0; // Null
print(buf);
}
|
| 16進2桁の数値を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
// Print 2Byte HEX
void print_hex16(int val) {
print_hex8((val & 0xFF00) >> 8);
print_hex8(val & 0x00FF);
}
|
| 16進4桁の数値を表示する関数です。キー入力と複数画面合成のページと同じものですから、内容説明は省略します。 |
(c) Kanazawa Univ., 2004