VisualBoyAdvance-1.8.0-beta3にはとても嬉しいことにデバッグ用のコンソールがついています。メニューのTools->Loggingにあります。このコンソールを使えば処理の順番が正しく行われたかのチェックや、変数の値を見ることが可能になります。私の知る限りVBA方式とMappy方式の2種類がありますけれど、今はMappy方式を利用してください。
#ref(): File not found: "clip_1.png" at page "doc.10"
#ifndef VBA_H
#define VBA_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gba.h"
IWRAM_CODE void vbalog(const char* msg);
IWRAM_CODE void mappylog(const char* msg);
#ifdef __cplusplus
}
#endif
#endif@ Functions available to be used with VBA
@ Compile with GAS
.file "vba.s"
.section .iwram,"ax",%progbits
.code 16
.text
.align 2
.global vbalog
.thumb_func
.type vbalog,function
@ log a message to VBA's output console or GDB console
@ r0=message to log
vbalog:
swi 0xff
bx lr
.align 2
.global mappylog
.thumb_func
.type mappylog,function
mappylog:
mov r2,r0
ldr r0,=0xc0ded00d
mov r1,#0
and r0,r0
bx lr
.dataVBA方式はswi命令を呼び出し、エミュレータの独自処理にフックさせています。
実機で動かすと素直にswi命令が動いてしまい、破綻しますので注意してください。
対するMappy方式はldr、andなどの無意味なシグネチャ処理によって実現しています。
とても行儀が良いです。
sprintf関数と併用すれば、文字列の中に16進数表記なども扱えるようになります。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
int debug(char *fmt, ...)
{
char s[80];
va_list marker;
va_start(marker, fmt);
int r = vsprintf(s, fmt, marker);
va_end(marker);
mappylog(s);
return r;
}
意図しない長さの文字列を扱う場合、スタック変数のs[80]が壊れる場合もありえます。
妙な挙動をした場合はこのあたりを疑ってみてください。