@@ -127,17 +127,18 @@ bool CPU::get_timer_enable_bit(uint16_t counter, uint8_t tac) {
127127void CPU::tick_timers (uint8_t cycles) {
128128 for (int i = 0 ; i < cycles; i++) {
129129 // Handle pending reloads
130+ bool in_reload = false ;
131+
130132 if (tima_reload_delay > 0 ) {
133+ in_reload = true ;
131134 tima_reload_delay--;
132135
133136 // If delay hits 0, then reload TIMA from TMA
134137 if (tima_reload_delay == 0 ) {
135138 uint8_t tma = mmu->read_byte (0xFF06 );
136139 mmu->write_byte (0xFF05 , tma);
137-
138- // Request timer interrupt (bit 2)
139- uint8_t if_reg = mmu->read_byte (0xFF0F );
140- mmu->write_byte (0xFF0F , if_reg | 0x04 );
140+
141+ in_reload = false ;
141142 }
142143 }
143144
@@ -150,16 +151,19 @@ void CPU::tick_timers(uint8_t cycles) {
150151 bool new_signal = get_timer_enable_bit (internal_counter, tac);
151152
152153 // Increment TIMA on falling edge
153- if (old_signal && !new_signal) {
154+ if (old_signal && !new_signal && !in_reload ) {
154155 uint8_t tima = mmu->read_byte (0xFF05 );
155156
156157 // Increment TIMA
157158 tima++;
158159
159160 // If timer overflowed to 0, then reload after 4 cycle delay
160161 if (tima == 0x00 ) {
161- tima_reload_delay = 4 ;
162162 mmu->write_byte (0xFF05 , 0x00 );
163+ tima_reload_delay = 4 ;
164+
165+ uint8_t if_reg = mmu->read_byte (0xFF0F );
166+ mmu->write_byte (0xFF0F , if_reg | 0x04 );
163167 } else {
164168 mmu->write_byte (0xFF05 , tima);
165169 }
@@ -181,7 +185,8 @@ void CPU::sync_timer_on_div_write() {
181185 tima++;
182186 if (tima == 0x00 ) {
183187 tima_reload_delay = 4 ;
184- mmu->write_byte (0xFF05 , 0x00 );
188+ uint8_t if_reg = mmu->read_byte (0xFF0F );
189+ mmu->write_byte (0xFF0F , if_reg | 0x04 );
185190 } else {
186191 mmu->write_byte (0xFF05 , tima);
187192 }
@@ -199,26 +204,27 @@ void CPU::sync_timer_on_tac_write(uint8_t new_tac) {
199204 tima++;
200205 if (tima == 0x00 ) {
201206 tima_reload_delay = 4 ;
202- mmu->write_byte (0xFF05 , 0x00 );
207+ uint8_t if_reg = mmu->read_byte (0xFF0F );
208+ mmu->write_byte (0xFF0F , if_reg | 0x04 );
203209 } else {
204210 mmu->write_byte (0xFF05 , tima);
205211 }
206212 }
207213}
208214
215+ void CPU::sync_timer_on_tma_write (uint8_t value) {
216+ // Placeholder for any future behavior needed when TMA is written to
217+ }
218+
209219void CPU::sync_timer_on_tima_write (uint8_t value) {
210220 // Edge case - write ignored when delay == 1 (TIMA will be reloaded to TMA next cycle)
211221 if (tima_reload_delay == 1 ) {
212- mmu->write_byte (0xFF05 , 0x00 );
213222 return ;
214223 }
215224
216225 // Normal case - If reload is pending (> 1 cycle left), writing cancels the reload.
217226 if (tima_reload_delay > 1 ) {
218227 tima_reload_delay = 0 ;
219-
220- uint8_t if_reg = mmu->read_byte (0xFF0F );
221- mmu->write_byte (0xFF0F , if_reg | 0x04 );
222228 }
223229}
224230
0 commit comments