www.nesdev.org

このマッパーはCPUサイクルによるIRQが使える。


.inesmap 069    
にすると、いつもは$8000から開始にするところを

.org $6000 ; $6000から開始

にしないと動かない


gimmicと同様に$e000 にプログラムを配置しようとすると、.bank 1 にしないといけないらしい

NESASM3 - Reset code compiled to wrong location - nesdev.org


それでもCLIIRQを有効にした瞬間にIRQに飛んで、rtiした瞬間にまたIRQが呼ばれる挙動は変わらなかった

IRQが無限ループする原因が分かった

  LDA #$C0                 
  STA Ctrl2_FrameCtr_4017  

$4017にC0を書き込まないと、IRQのFrameCounterのフラグが立ちっぱなしになっていて、この状態でCLIするとIRQが無限ループする

 

$4017 は、NES の APU (Audio Processing Unit) の制御レジスタです。このレジスタは、音声合成やタイマーの動作を制御します。特に、$4017 はフレームカウンタの制御レジスタとして機能します。

$4017 への書き込み内容のビット設定により、以下のような動作が決定されます:

arduino
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 #$C0STA $4017 の命令は、フレームカウンタの制御レジスタ$C0を書き込んでいます。これは、フレーム割り込みを禁止し (I ビットをセット)、フレームカウンタを4ステップモードで動作させることを意味します。

あなたが遭遇した問題は、フレーム割り込みが有効な状態でゲームが動作していたことに起因する可能性が高いです。フレーム割り込みは、特定のタイミングでAPUからCPUに割り込みを送ることができる機能です。この割り込みは、例えばサウンドの同期やタイマー関連の動作に使われることがあります。

したがって、フレーム割り込みを無効にすることで、これによる不必要なIRQを防ぐことができます。これは、ゲームやアプリケーションによっては必要な初期化手順の一部となります。

 

NMI

IRQ

色々試してみたけど、CPUサイクルベースの割り込みは複数かけるとだんだんずれる問題が回避しづらいので、今回のアプローチには向いていないっぽいことがわかった。
しかし、製品でも数回程度はラスターしていそうなので、どうやって回避してるんだろう?