このマッパーはCPUサイクルによるIRQが使える。
.inesmap 069
にすると、いつもは$8000から開始にするところを
.org $6000 ; $6000から開始
にしないと動かない
gimmicと同様に$e000 にプログラムを配置しようとすると、.bank 1 にしないといけないらしい
NESASM3 - Reset code compiled to wrong location - nesdev.org
それでもCLIでIRQを有効にした瞬間にIRQに飛んで、rtiした瞬間にまたIRQが呼ばれる挙動は変わらなかった
IRQが無限ループする原因が分かった
LDA #$C0
STA Ctrl2_FrameCtr_4017
$4017にC0を書き込まないと、IRQのFrameCounterのフラグが立ちっぱなしになっていて、この状態でCLIするとIRQが無限ループする
$4017
は、NES の APU (Audio Processing Unit) の制御レジスタです。このレジスタは、音声合成やタイマーの動作を制御します。特に、$4017
はフレームカウンタの制御レジスタとして機能します。
$4017
への書き込み内容のビット設定により、以下のような動作が決定されます:
7 bit 0
---- ----
IMMM IRQM
-
I (bit 7): インヒビット (Inhibit frame interrupt)
- 0: Frame interrupt is active
- 1: Frame interrupt is inhibited
-
M (bits 6-4): モード (Mode)
- 000: 4-step sequence
- 001: 5-step sequence
-
IRQM (bits 3-0): これらのビットは未使用ですが、多くのAPUのリファレンスでは全てのビットをセット($C0)することが推奨されています。
LDA #$C0
と STA $4017
の命令は、フレームカウンタの制御レジスタに$C0
を書き込んでいます。これは、フレーム割り込みを禁止し (I
ビットをセット)、フレームカウンタを4ステップモードで動作させることを意味します。
あなたが遭遇した問題は、フレーム割り込みが有効な状態でゲームが動作していたことに起因する可能性が高いです。フレーム割り込みは、特定のタイミングでAPUからCPUに割り込みを送ることができる機能です。この割り込みは、例えばサウンドの同期やタイマー関連の動作に使われることがあります。
したがって、フレーム割り込みを無効にすることで、これによる不必要なIRQを防ぐことができます。これは、ゲームやアプリケーションによっては必要な初期化手順の一部となります。
色々試してみたけど、CPUサイクルベースの割り込みは複数かけるとだんだんずれる問題が回避しづらいので、今回のアプローチには向いていないっぽいことがわかった。
しかし、製品でも数回程度はラスターしていそうなので、どうやって回避してるんだろう?