blob: 4ba07be6cbcb4868f4bf634992032233ee2886fb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
use crate::display::DisplayInterrupt;
use crate::serial::Serial;
use crate::state::{GBState, MemError};
const TIMA_TIMER_SPEEDS: [u64; 4] = [1024, 16, 64, 256];
impl GBState {
pub fn check_interrupts(&mut self) -> Result<(), MemError> {
if self.mem.ime {
let interrupts = self.mem.io[0x0f] & self.mem.interrupts_register & 0b11111;
for i in 0..5 {
if interrupts & (1 << i) != 0 {
self.push(self.cpu.pc)?;
self.mem.ime = false;
self.cpu.pc = 0x40 + (i << 3);
self.mem.halt = false;
self.mem.io[0x0f] &= !(1 << i);
break;
}
}
}
Ok(())
}
pub fn tima_timer(&mut self, c: u64) {
if self.mem.timer_enabled
&& self.tima_cycles >= TIMA_TIMER_SPEEDS[self.mem.timer_speed as usize]
{
if self.mem.tima == 0xff {
self.mem.io[0x0f] |= 0b100;
self.mem.tima = self.mem.tma;
} else {
self.mem.tima += 1;
}
self.tima_cycles %= TIMA_TIMER_SPEEDS[self.mem.timer_speed as usize];
}
self.tima_cycles += c;
}
pub fn update_display_interrupts(&mut self, c: u64) {
let interrupt = self.mem.display.update_display(c);
match interrupt {
DisplayInterrupt::Vblank => {
self.mem.io[0x0f] |= 1;
}
DisplayInterrupt::Stat => {
self.mem.io[0xf] |= 2;
}
DisplayInterrupt::Both => {
self.mem.io[0xf] |= 3;
}
_ => {}
}
}
pub fn div_timer(&mut self, c: u64) {
if self.div_cycles >= 256 {
self.mem.div += 1;
self.div_cycles = 0;
}
self.div_cycles += c;
}
}
|