@@ -69,10 +69,13 @@ impl Ppu {
69
69
self . clock_cycles += cycles;
70
70
// each scanline lasts for 341 PPU clock cycles
71
71
let scanline = cycles / 341 ;
72
- if self . scanline < 241 && scanline >= 241 && self
72
+ if self . scanline < 241
73
+ && scanline >= 241
74
+ && self
73
75
. registers
74
76
. control
75
- . contains ( ControlRegister :: VBLANK_NMI_ENABLE ) {
77
+ . contains ( ControlRegister :: VBLANK_NMI_ENABLE )
78
+ {
76
79
// upon entering scanline 241, PPU triggers NMI interrupt
77
80
self . nmi_interrupt = true ;
78
81
// The VBlank flag of the PPU is set at tick 1 (the second tick) of scanline 241
@@ -96,8 +99,19 @@ impl Ppu {
96
99
}
97
100
98
101
pub fn write_to_ctrl ( & mut self , data : u8 ) {
99
- // TODO: bugzmanov book sets ctrl.bits directly vs recreating .. I hit an error attempting that
100
- self . registers . control = ControlRegister :: from_bits_truncate ( data) ;
102
+ let before = & self . registers . control ;
103
+ let after = ControlRegister :: from_bits_truncate ( data) ;
104
+
105
+ // should we toggle an NMI interrupt?
106
+ let is_vblank_state = self . registers . status . contains ( StatusRegister :: VBLANK_FLAG ) ;
107
+ let enabled_vblank_nmi = after. contains ( ControlRegister :: VBLANK_NMI_ENABLE )
108
+ && !before. contains ( ControlRegister :: VBLANK_NMI_ENABLE ) ;
109
+ if is_vblank_state && enabled_vblank_nmi {
110
+ self . nmi_interrupt = true ;
111
+ }
112
+
113
+ // update the register's value
114
+ self . registers . control = after;
101
115
}
102
116
103
117
pub fn write_to_mask ( & mut self , data : u8 ) {
0 commit comments