Doc.10 エミュレータのデバッグコンソール

エミュレータにはとても嬉しいことにデバッグ用のコンソールがついています(Tools->Logging)。
このコンソールを使えば処理の順番が正しく行われたかのチェックや、変数の値を見ることが可能になります。

clip_1.png

VBA方式とMappy方式の2種類あり、
今はMappy方式の方が優れているのでこちらを利用します。

  • vba.h
    #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
  • vba.s
    @ 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
    
    
    	.data

VBA方式はswi命令を呼び出し、エミュレータの独自処理にフックさせています。
実機で動かすと素直にswi命令が動いてしまい、破綻しますので注意してください。

対するMappy方式はldr、andなどの無意味なシグネチャ処理によって実現しています。
とても行儀が良いです。

発展方法

sprintf関数と併用すれば、文字列の中に16進数表記なども扱えるようになります。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void mappylog(char* buf)
{
	asm("mov r2, %0; ldr r0,=0xc0ded00d; and r0,r0" :: "r"(buf) : "r2", "r0");
}

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]が壊れる場合もありえます。
妙な挙動をした場合はこのあたりを疑ってみてください。

履歴

  • 2014/11/14
  • 2007/09/28

添付ファイル: fileclip_1.png 261件 [詳細]

Last-modified: 2015-10-11 (日) 21:14:02 (2202d)