ちょっと気になったので、もう一度(だけ)最後の見直しをしてみる。あった!あった! 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*)0x3007FFCI/O アクセスをする場合は、volatile 宣言は必須。
volatile しないと、コンパイラの最適化の煽りを受けて、
ハマるので注意。