目的
任天堂GBA向けにOSを作ろうと思います。(OSと言ってもPSPのメニュー画面や、マジコンのROM選択画面のようなもの)
文字表示等は完成しています。
任天堂GBAでASCII全文字を表示
カーネル(と言ってもいい?)を実行する前にPCBIOSのようにメモリとレジスタが壊れていないかを点検する処理を入れようと思います。
そこで今回は自己点検の処理のみ書きました。DMAや音声はまだ使用しないので入れていません。
実装
レジスタ点検はr0→r1→...→r12と同じ値を渡していき、r0とr12レジスタの値が一致すれば壊れていないものとします。
メモリ点検は書き込んだ値と読みだした値が一致していれば壊れていないものとします。
全て壊れていなければ画面全体を青くします。
分かりづらいですが、筆者の実機では画面全体が青くなりました。
rm -rf tmp
mkdir tmp
arm-none-eabi-as header.s -o tmp/header.o
arm-none-eabi-ld tmp/header.o -T link.ld -o tmp/out.elf
arm-none-eabi-objcopy -O binary tmp/out.elf tmp/out.gba
link.ld
link.ld
ENTRY(_start)
SECTIONS
{
. = 0x08000000;
.text :
{
*(.text)
*(.rodata)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss)
*(COMMON)
}
}
header.s
.arm
.section .text
.global _start
.global ResetHandler
.org 0x00000000
_start:
b ResetHandler
/* 商標 */
.incbin "logo.bin" @ 0x0004-0x009F
/* --- ゲームに関する情報(0x00A0〜0x00BF) --- */
.org 0x000000A0
.ascii "GBADEMO " @ 名前 12文字
.byte 0x00,0x00,0x00,0x00 @ ゲームコード 4バイト
.byte 0x00,0x00 @ メーカーコード 2バイト
.byte 0x96 @ 固定値
.byte 0x00 @ メインユニットコード
.byte 0x00 @ 機器の種類
.space 7 @ 予約領域
.byte 0x00,0x00 @ 補完チェック・マスクROMバージョン
.space 2 @ 残り予約領域
.align 2
ResetHandler:
@ モード3(240x160 ビットマップ)
ldr r0, =0x04000000
mov r1, #0x0403
str r1, [r0] @ DISPCNT = Mode3 + BG2
reg_post:
@ 1通り目
ldr r0, =0xAAAAAAAA
mov r1, r0
mov r2, r1
mov r3, r2
mov r4, r3
mov r5, r4
mov r6, r5
mov r7, r6
mov r8, r7
mov r9, r8
mov r10, r9
mov r11, r10
mov r12, r11
cmp r12, r0
bne fail
@ 2通り目
ldr r0, =0x55555555
mov r1, r0
mov r2, r1
mov r3, r2
mov r4, r3
mov r5, r4
mov r6, r5
mov r7, r6
mov r8, r7
mov r9, r8
mov r10, r9
mov r11, r10
mov r12, r11
cmp r12, r0
bne fail
@ IWRAM Test: 0x03000000 - 0x03008000 (32KB 全部)
ldr r0, =0x03000000 @ IWRAM先頭
ldr r1, =0x03008000 @ IWRAM終端(32KB)
ldr r2, =0xAAAAAAAA @ 10101010
ldr r3, =0x55555555 @ 01010101
iram_loop:
str r2, [r0] @ 0xAAAAAAAAをメモリへ書き込む
ldr r4, [r0] @ メモリから読み出す
cmp r4, r2 @ 書出と読出を比較してメモリ動作を確認
bne fail
str r3, [r0] @ 0x55555555で同じ処理
ldr r4, [r0]
cmp r4, r3
bne fail
add r0, r0, #4 @ 32ビット幅なので+4
cmp r0, r1 @ メモリ末端まで点検したか判定
blt iram_loop
@ EWRAM Test: 0x02000000 - 0x02040000 (256KB 全部)
ldr r0, =0x02000000
ldr r1, =0x02040000
eram_loop:
str r2, [r0]
ldr r4, [r0]
cmp r4, r2
bne fail
str r3, [r0]
ldr r4, [r0]
cmp r4, r3
bne fail
add r0, r0, #4
cmp r0, r1
blt eram_loop
@ SUCCESS: 青画面
success:
ldr r0, =0x05000000
mov r1, #0x7C00 @ 青 (BGR555: 0,0,31)
strh r1, [r0]
ldr r0, =0x06000000
mov r1, #0x0000
mov r2, #0x9600
succ_fill:
strh r1, [r0], #2
subs r2, r2, #1
bne succ_fill
ldr r0, =0x04000000
mov r1, #0x0400 @ BG2 enable
strh r1, [r0]
done:
b done
ldr sp, =0x03007F00
@ bl main @ Cへ 跳ぶ
fail:
ldr r0, =0x05000000
mov r1, #0x001F
strh r1, [r0] @ パレット0 = 赤
ldr r0, =0x06000000
mov r1, #0
mov r2, #0x6000 @ 19200 * 2bytes = 38400 ≒ 0x9600
fill_loop:
strh r1, [r0], #2
subs r2, r2, #1
bne fill_loop
ldr r0, =0x04000000
mov r1, #0x0400
strh r1, [r0]
hang:
b hang
InfiniteLoop:
b InfiniteLoop