VBLANK
基本形は以下
JSR WAIT_VBLANK
; 何らかの描画処理
JSR $F3C6
NMI割り込みオンにして無限ループに入る
どうやって出るかというと……
WAIT_VBLANK:
LDA $2002 ; PPU_STATUS
PHA
LDA L_0100
PHA
LDA #$00
STA L_0100 ; VBLANK待ちしている間は0にする
; VBlank時にNMI割込オン
LDA L_FF
ORA #$80
STA L_FF
STA $2000 ; PPU_CONTROL1
@LOOP:
BNE @LOOP ; 割り込みが来るまでループ
NMI割り込み時にプッシュされたリターンアドレスをポップして、
WAIT_VBLANK呼び出し時にプッシュしたリターンアドレスだけに置き換える!
RTSから抜けると、WAIT_VBLANKの次の命令から実行が再開される
(注:NMI_HANDLERには$FF1Eが入っている)
L_NMI_FE80:
BIT L_0100
BPL L_FE88 ; VBLANK待ちしてれば飛ぶ
JMP (NMI_HANDLER)
L_FE88:
; VBlank時にNMI割込オフ
LDA L_FF
AND #$7F
STA L_FF
STA $2000 ; PPU_CONTROL1
LDA $2002 ; PPU_STATUS
PLA ; NMI割り込み発生でプッシュされたPC(LOW)
PLA ; NMI割り込み発生でプッシュされたPC(HIGH)
PLA ; NMI割り込み発生でプッシュされたP
PLA ; WAIT_VBLANKでPHAしたL_0100
STA L_0100
PLA ; WAIT_VBLANKでPHAした$2000
CLI
RTS ; WAIT_VBLANKから抜ける
描画処理が終わったら必ず呼ぶ必要がある
L_F3C6:
; スクロール位置を戻す
LDA #$00
STA $2005 ; PPU_BG_SCROLL(H)
STA $2005 ; PPU_BG_SCROLL(V)
; VBlank時にNMI割込オン
LDA L_FF
ORA #$80
STA L_FF
STA $2000 ; PPU_CONTROL1
; X,Yをスタックに保存
TXA
PHA
TYA
PHA
JSR SND_PLAY_FRAME
; X,Yをスタックから戻す
PLA
TAY
PLA
TAX
; Aは0クリア
LDA #$00
RTS
WAIT_VBLANKが呼ばれない時のNMI割り込みは、小細工抜きで普通にRTI
L_FF1E:
PHP
PHA
LDA $2002 ; PPU_STATUS
TXA
PHA
TYA
PHA
CLI
JSR SND_PLAY_FRAME
LDA L_FF
STA $2000 ; PPU_CONTROL1
PLA
TAY
PLA
TAX
PLA
PLP
RTI
視界
左上ウィンドウに表示される縦16横16の視界は、$0700にバッファリングされる。
最終更新:2025年08月02日 17:07