1. メモリマップ
ROM
割り込みベクタ
割り込みが引き起こされたときの命令を記述する場所。アドレスは変更できない。
VBlank → 文字列表示へ Stat 不使用 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0040 00 00 00 00000000000000000000000000
Timer 不使用 Serial 不使用 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0050 00000000000000000000000000000000
Joypad 不使用 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0060 00000000000000000000000000000000
プログラムエントリ
ゲームボーイではプログラムエントリのアドレスは $0100 と決まっている。アドレスは変更できない。
続いてすぐ後にカートリッジヘッダ (固定値) が入る。
エントリ カートリッジヘッダ … +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0100 00 C3 50 01 000000000000000000000000
プログラム本体
メインプログラム … +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
RAM
カウ
ンタ文字列 終端子 不使用 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F C000 00 00 00 00 000000000000000000000000
スタック IE +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F FFF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2. プロジェクトディレクトリの作成
VS Code ではディレクトリを開くことにより、プロジェクトを切り替える。
2-1. ディレクトリを作成する。
ファイルエクスプローラーでディレクトリを作成する。(プロジェクトディレクトリとする)2-2. ハードウェア定数定義を設置する。
C:\Users\who\vsc-gba-bgdisplay\
GitHub から hardware.inc をダウンロードし、作成したディレクトリに設置する。2-3. プロジェクトディレクトリとしてディレクトリを開く。
(ダウンロード方法がわかりにくい)
直接ダウンロードするのはこちらから。
VS Code: メニュー > ファイル > フォルダーを開く (Ctrl+K Ctrl+O)
(上記プロジェクトディレクトリ : C:\Users\who\vsc-gba-bgdisplay\)
→ このディレクトリの中にあとで .vscode\ が作られる。「信頼します」ボタンをクリックする。
このフォルダー内のファイルの作成者を信頼しますか?
3. アセンブラの設定
上記 2 の操作のあとに実行する。
3-1. ひな形からビルド情報を記述する。(アセンブラ)VS Code: メニュー > ターミナル > タスクの構成...3-2. ひな形からデバッグの構成を記述する。
生成された .vscode\tasks.json にビルド情報を記述する。
検索: テンプレートから tasks.json を生成 ← 選択 Others 任意の外部コマンドを実行する例 ← 選択
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "Assemble a_bgdisplay", "type": "shell", "command": "cmd", "args": [ "/C", // アセンブルを指示 "rgbasm -o a_bgdisplay.obj a_bgdisplay.asm", // 実行ファイルを生成 (*.gb, *.sym を出力) "&& rgblink -n a_bgdisplay.sym -o a_bgdisplay.gb a_bgdisplay.obj", // シグネチャとパディングの書き込み (ROM+MBC5+RAM: -m 0x1A) "&& rgbfix -v -p 0xFF -C -m 0x1A a_bgdisplay.gb", ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": [] } ] }
変更が完了したら、ファイルを閉じる。
VS Code: メニュー > ファイル > エディターを閉じる Ctrl+F4 →
エミュレータ起動 / 接続の設定 (VS Code の「デバッグの実行」を選択すると呼ばれる)
VS Code: メニュー > 実行 > 構成の追加...
生成された .vscode\launch.json にデバッグ情報を記述する。
検索: Emulicious Debugger ← 選択
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "emulicious-debugger", "request": "launch", "name": "Launch in Emulicious", "program": "${workspaceFolder}/a_bgdisplay.gb", "port": 58870, "stopOnEntry": true } ] }
変更が完了したら、ファイルを閉じる。
VS Code: メニュー > ファイル > エディターを閉じる Ctrl+F4 →
4. アセンブラのプログラムを作成
VS Code: メニュー > ファイル > 新しいファイル Ctrl+Alt+Win+N
a_bgdisplay.asm (ソースコードデバッグはメインの *.gb と *.asm の名称を合わせる必要がある)プロジェクトディレクトリの直下に作成する。(.vscode\ ではない)
a_bgdisplay.asm
INCLUDE "hardware.inc" INCLUDE "bg.inc"
; 割り込みベクタ 5 種類 SECTION "Vector", ROM0[$0000] ds $0040 - @ ; 63bytes ここにプログラムを格納しない(できるけどしない) SECTION "VBlank", ROM0[$0040] jp display_info ; -> VBlank 処理へ ds $0048 - @ ; 5Bytes SECTION "Stat", ROM0[$0048] reti ds $0050 - @ ; 7Bytes SECTION "Timer", ROM0[$0050] reti ds $0058 - @ ; 7Bytes SECTION "Serial", ROM0[$0058] reti ds $0060 - @ ; 7Bytes SECTION "Joypad", ROM0[$0060] reti ds $0100 - @ ; 160bytes ここにプログラムを格納しない(できるけどしない)
; --- カートリッジのエントリ (本体タイトル表示の後に有効化) --- SECTION "Entry", ROM0[$0100] ; 自作プログラムは $0100 から記述する nop jp Start ; --- カートリッジヘッダ (0104h-014Fh) rgbfix がここを埋める --- ds $0150 - @ ; --- メインプログラム --- Start: di ; 割り込み禁止 lcd_OFF ; LCD を非表示 bg_VBK_SEL0 ; VRAM (8000-9FFF) をバンク 0 でアクセス call bg_Init ; バンク 0 で VRAM をゼロクリア bg_VBK_SEL1 ; VRAM (8000-9FFF) をバンク 1 でアクセス call bg_Init ; バンク 1 で VRAM をゼロクリア bg_VBK_SEL0 ; ここ以降のプログラムは VRAM をバンク 0 でアクセス call bg_InitFont ; タイルに文字の図形を転送 call bg_InitPalette_CGB ; カラーパレットを初期化 (BG 表示用) lcd_ON ; LCD を表示 ld sp, $FFFF ; スタックに HRAM を使用 (PUSH はプリデクリメント) ; VBlank 割り込みを許可 ld a, IE_VBLANK ld [rIE], a ; [FFFF] <- EnableINT ei ; 割り込み許可 Main_Loop: halt ; 省電力対策 jr Main_Loop
; --- 画面に文字を転送 --- display_info: ; 割り込み前のレジスタをすべて保存 push af push bc push de push hl ; カウンタをインクリメント ld a, [Dummy_CNT] inc a ld [Dummy_CNT], a ; カウンタの上位 4 ビットを文字に変換 swap a and $0F ld b, 0 ld c, a ld hl, hexDecStr add hl, bc ld a, [hl] ld [Dummy_Str + 0], a ; カウンタの下位 4 ビットを文字に変換 ld a, [Dummy_CNT] and $0F ld b, 0 ld c, a ld hl, hexDecStr add hl, bc ld a, [hl] ld [Dummy_Str + 1], a ; 文字列に終端子を追加 ld a, -1 ld [Dummy_Str + 2], a ld hl, Dummy_Str ld de, $9800 + 0 + 32 * 0 ; (x,y) = (0,0) call bg_DisplayMsg ; 割り込み前のレジスタをすべて復帰 pop hl pop de pop bc pop af reti ; 割り込みから復帰 (自動的に ei される)
; 10 進 -> 16 進文字の変換 ; SETCHARMAP によって、実際には {$10,$11,..,$19,$21,$22,..,$26} が並ぶ hexDecStr: SETCHARMAP bg_AsciiMap db "0123456789ABCDEF"
; --- RAM の定義 --- SECTION "Task_Control", WRAM0[$C000] ; WRAM バンク 0 として $C000 に配置 Dummy_CNT: db ; ダミーカウンタ Dummy_Str: ds 3 ; ダミー文字列
記述したら、ファイルを閉じる。
VS Code: メニュー > ファイル > エディターを閉じる Ctrl+F4 →
5. アセンブルとデバッグ
5-1. ソースをアセンブルする。
VS Code: メニュー > ターミナル > ビルドタスクの実行... Ctrl+Shift+B5-2. デバッグの実行
→ 上記 3-1 で定義した task.json が実行される。
VS Code: メニュー > 実行 > デバッグの開始 F55-3. デバッグの続行
→ 上記 3-2 で定義した launch.json が実行される。
Emulicious が起動し、VS Code の画面にはアセンブラのソース画面が表示される。
このとき、(上記 launch.json の "stopOnEntry": true により) $0100 の nop で実行が停止する。
上記 5-2 でプログラムが停止しているので、実行を再開する。5-4. 実行の確認
VS Code: メニュー > 実行 > 続行 F5
Emulicious: メニュー > Tools > Debugger F1
Memory タブ - RAM タブ
カウンタと文字列が頻繁に変更されていることを確認する。
カウ
ンタ文字列 終端子 不使用 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F C000 00 00 00 00 000000000000000000000000
これと同時に、Emulicious の画面にも同じ文字列が表示されていることを確認する。