アットウィキロゴ

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