EXCEEDの同人ソフト開発日記という名の備忘録

趣味のゲームソフト開発人。プロなのかアマなのかは不明(不定)らしい。

任天堂のソフトはいつも予定通りに出てこないって言われるけど、
ソフト作りっていうのは、そういうもの。
ゲームソフトは、期限までにやれと言われて、徹夜したり死に物狂いでやったからといって、
期待通りのものにはならない。そういうふうにすると、
結局、チームは妥協しなければならなくなる。
妥協させられて、できたものは、粗くなってしまう。
ユーザーは目が肥えていますから、受け付けてもらえない

山内 薄

割り込み

EXCEED2005-02-07

ちょっと気になったので、もう一度(だけ)最後の見直しをしてみる。あった!あった! VCOUNT 割り込みという 任意ラインで HBLANK割り込みを発生させる機構がやっぱりあった。HBLANK で、Witch の SYS_INT_DISPLINE をエミュレートするという荒業は止めにして、早速実装。軽くなった!!!

しかし、 REG_IME = IRQ_MASTER_ON; をした後に、REG_IE と REG_DISPSTAT の値が変更できなくなってしまうような気がする・・・仕方がないんで、該当割り込みをかけっぱなしにして、自前フラグで、該当割り込みの処理を行うor行わないを振り分けているが、どちらにせよ、該当割り込み未使用時でも事実上、無駄な割り込みがかかってしまうワケで・・・う〜ん・・・・

そもそも、REG_IE と REG_DISPSTAT が、どう違うのか全くの謎だったりする。ネット上の様々なサンプルを見ても、その違い(使い分け)が全くわからない。WonderGhost の割り込み機構は、そう考えると、いわば、「なんちゃって動作」に他ならなかったりする・・・。REG_IF も「割り込み発生時の要因識別レジスタ(割り込みリクエストフラグレジスタ?)」と位置づけられているようだが、例外処理を抜ける時は、リクエストフラグはクリアしないといけないんじゃないか?とか思うが、正式な手続きは実際の所、どうなのだろう・・・?

市販ソフトを dis るしかないのか・・・(嫌

メモ1


static void IRQ_Handler()
{
vu16 Int_Flag;
void (*func)();

REG_IME = IRQ_MASTER_OFF;
Int_Flag = REG_IF;

if(REG_IF & IRQ_BIT_VBLANK)
{
// VBLANK 発生
frame_count++;

if( irq_enable[TIMER_VBLANK]!=0 )
{
func = vector[SYS_INT_VBLANK_COUNTUP].callback;
if(func!=NULL)func();
}

}

if(REG_IF & IRQ_BIT_VCOUNT){

// VCOUNT 発生
if( irq_enable[TIMER_HBLANK]!=0 )
{
func = vector[SYS_INT_DISPLINE].callback;
if(func!=NULL)func();
}

}

REG_IF = Int_Flag; // 割り込みリクエストクリア?
REG_IME = IRQ_MASTER_ON;

}

メモ2


■GBAプログラミング研究所さんの所にある VisualHAM 用
 テンプレートを使用する場合は、makefile
 -Ttext 0x08000000 -Tbss 0x03000000 をそのまま使用すると、
 .bss と .data が衝突を起こして、大変なことになってしまうので、
 devkitadv-r5-beta-3/crtls/lnkscript をローカルディレクトリとかに
 コピーするなりして、-Tlnkscript として、リンカスクリプトファイルを
 参照するようにしないといけない。

■DevKitaAvance r5 beta3 の標準 lnkscript ファイルには、
 __iwram_overlay_lma の定義が見当たらないので、以下のものを
 付け加えてみたが、

__iwram_overlay_lma = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + SIZEOF(.iwram) + SIZEOF(.data);

 どうも、アドレスが、80 バイトずれるらしいので、応急処置として、

extern u8 __iwram_overlay_lma;
u8 *pROMBottom = &__iwram_overlay_lma + 80;

 な使い方で誤魔化している。

■DevKitaAvance r5 beta3 では、__iwram_overlay_lma の定義が廃止
 されており、代わりに __load_start_appended が用意されるように
 なった。具体的な使用方法は以下の通り

extern u8 __load_start_appended;
u8 *pROMBottom = &__load_start_appended;

 ただし、オーバーレイ領域を使うと、本来の目的のアドレスが
 ずれることになるので、注意。

■古い gba.h (等)のヘッダファイルは、レジスタアドレスの宣言が、
 volatile されていないものが存在するので、要注意。

(例)

  誤)
#define REG_INTERUPT *(u32*)0x3007FFC

  正)
#define REG_INTERUPT *(volatile u32*)0x3007FFC

 I/O アクセスをする場合は、volatile 宣言は必須。
 volatile しないと、コンパイラの最適化の煽りを受けて、
 ハマるので注意。