画面右上下に触れたときに現在のマップ位置($38)を知るためにこの処理が呼ばれる 829C: A4 38   ldy CurrentOrderNum [$0038] A=00 X=2A Y=03 S=FD P=27 現在のマップ位置をチェックする 829E: 20 A1 C7   jsr $C7A1 [$C7A1] A=00 X=2A Y=0E S=FD P=25 $C7A1へジャンプ C7A1: A5 2A  lda $2A [$002A] A=00 X=2A Y=0E S=FB P=25 C7A3: 29 07  and #$07 A=08 X=2A Y=0E S=FB P=25 C7A5: 20 00 C0 jsr SwitchBank [$C000] A=00 X=2A Y=0E S=FB P=27 $C000へジャンプ バンクチェンジプログラム(マッパー再構築) C000: 85 29 sta DesiredMapperPage [$0029] A=0E X=2A Y=00 S=F9 P=24 C002: 85 69 sta CurrentMapperPage [$0069] A=0E X=2A Y=00 S=F9 P=24 C004: E6 68 inc MapperProgramming [$0068] A=0E X=2A Y=00 S=F9 P=24 C006: 8D F0 FF sta $FFF0 [$FFF0] A=0E X=2A Y=00 S=F9 P=24 C009: 4A lsr A=0E X=2A Y=00 S=F9 P=24 C00A: 8D F0 FF sta $FFF0 [$FFF0] A=07 X=2A Y=00 S=F9 P=24 C00D: 4A lsr A=07 X=2A Y=00 S=F9 P=24 C00E: 8D F0 FF sta $FFF0 [$FFF0] A=03 X=2A Y=00 S=F9 P=25 C011: 4A lsr A=03 X=2A Y=00 S=F9 P=25 C012: 8D F0 FF sta $FFF0 [$FFF0] A=01 X=2A Y=00 S=F9 P=25 C015: 4A lsr A=01 X=2A Y=00 S=F9 P=25 C016: 8D F0 FF sta $FFF0 [$FFF0] A=00 X=2A Y=00 S=F9 P=27 C019: A9 00 lda #$00 A=00 X=2A Y=00 S=F9 P=27 C01B: 85 68 sta MapperProgramming [$0068] A=00 X=2A Y=00 S=F9 P=27 C01D: A5 67 lda SoundCodeSkipped [$0067] A=00 X=2A Y=00 S=F9 P=27 サウンドコードをスキップするかどうか($67の値をAへロード) $C006〜$C019が実行中のときにディレイによってNMIがコールされていたら $0067=1となる。($0067≠0だったらZフラグがクリアされる) C01F: D0 01 bne $C022 A=00 X=2A Y=00 S=F9 P=27 Zフラグがクリアされていれば分岐。$C022へ Zフラグがクリアされていないとき C021: 60 rts マッパー再構築サブルーチンから抜ける(Zフラグが立っているとき) Zフラグがクリアされているとき C022: A9 0C lda #$0C C024: 8D F0 FF sta $FFF0 [$FFF0] A=0C X=2A Y=0E S=F9 P=24 C027: 4A lsr A=0C X=2A Y=0E S=F9 P=24 C028: 8D F0 FF sta $FFF0 [$FFF0] A=06 X=2A Y=0E S=F9 P=24 C02B: 4A lsr A=06 X=2A Y=0E S=F9 P=24 C02C: 8D F0 FF sta $FFF0 [$FFF0] A=03 X=2A Y=0E S=F9 P=24 C02F: 4A lsr A=03 X=2A Y=0E S=F9 P=24 C030: 8D F0 FF sta $FFF0 [$FFF0] A=01 X=2A Y=0E S=F9 P=25 C033: 4A lsr A=01 X=2A Y=0E S=F9 P=25 C034: 8D F0 FF sta $FFF0 [$FFF0] A=00 X=2A Y=0E S=F9 P=27 C037: 20 00 80 jsr SoundCode このサウンドコードのサブルーチンによってYの値が異常になる Y=1Cのときスクロール処理直前でY=FFなどになり ビットマスクで全てをカバーしていることから 全スクロールが可能となりディレイスクロールが生じる。 1Cはサウンドコードによって一番生じやすい値ではある。 (なお、サウンドコードは09, 0B, 0Fなども良く生じさせるが予後がよくない) スクロール方向はビットマスクにより20=右 40=上 80=下 C03A: A6 66 ldx $66 [$0066] A=00 X=0E Y=1C S=F9 P=26 次のフレームの処理のときにスクロールするかどうかの判定の際にFFが読み込まれる 828B: A4 37 ldy ScrollControl37 [$0037] A=FF X=00 Y=FF S=FD P=A5 まとめ ディレイスクロールが生じるには以下の条件を満たす必要がある ・C006〜C019の間にNMIがコールされる必要がある ・非常に小さいラグが必要とされる。  Y=FFが読み込まれる前に次のNMIがコールされると再度Yの値が正常なものに戻ってしまうため。  25処理後にはラグでないフレームになっている必要がある ・サウンドコードが運良くY=1Cを生成する必要がある おまけ ディレイスクロールを修正するにはサウンドコードによって狂ったYの値を復旧すればいい。 完全に復旧するにはYの値を復旧しないといけないので以下のようになるが、 アドレスのずれのおかげで修正が難しい気がする。 C037:jsr $8000; ↓ tya; YをAへコピー pha; Aをスタックにプッシュダウン jsr $8000; pla; スタックからAにポップアップ tay  AをYへコピー ディレイ中のサウンドコードが多少狂ってもいいなら値を狂わす マッパー構築中にNMIが呼ばれた場合に呼ばれるサウンドコードを呼ばなくすればいいので C037: 20 00 80 jsr SoundCode ↓ nop nop nop に書き換える。 バイナリの3C047からの 「20 00 80」を 「EA EA EA」に変えるというのが簡単でよい気がする