GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
timer.cpp
1#include "../../include/timer.hpp"
2#include "../../include/interrupt_controller.hpp"
3
4Timer::Timer(InterruptController& interrupt_controller)
5 : ic(interrupt_controller)
6{
7}
8
9void Timer::step(int cycles) {
10 div_counter += cycles;
11
12 if (tac & 0x04) { // Timer enabled
13 tima_counter += cycles;
14 int threshold = 0;
15 switch (tac & 0x03) {
16 case 0: threshold = 1024; break; // 4096 Hz
17 case 1: threshold = 16; break; // 262144 Hz
18 case 2: threshold = 64; break; // 65536 Hz
19 case 3: threshold = 256; break; // 16384 Hz
20 }
21
22 while (tima_counter >= threshold) {
23 tima_counter -= threshold;
24 if (tima == 0xFF) {
25 tima = tma;
26 // Request Timer Interrupt
27 ic.request_interrupt(InterruptType::Timer);
28 } else {
29 tima++;
30 }
31 }
32 }
33}
34
35u8 Timer::read(u16 address) const {
36 switch (address) {
37 case 0xFF04: return (div_counter >> 8) & 0xFF;
38 case 0xFF05: return tima;
39 case 0xFF06: return tma;
40 case 0xFF07: return tac;
41 }
42 return 0xFF;
43}
44
45void Timer::write(u16 address, u8 value) {
46 switch (address) {
47 case 0xFF04: div_counter = 0; break;
48 case 0xFF05: tima = value; break;
49 case 0xFF06: tma = value; break;
50 case 0xFF07: tac = value; break;
51 }
52}
53
54void Timer::reset() {
55 div_counter = 0;
56 tima = 0;
57 tma = 0;
58 tac = 0;
59 tima_counter = 0;
60}