This repository was archived by the owner on Feb 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathintc.cpp
More file actions
55 lines (41 loc) · 1.2 KB
/
intc.cpp
File metadata and controls
55 lines (41 loc) · 1.2 KB
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
#include <intc.hpp>
#include <EE.hpp>
static const char* REGS[2] =
{
"INTC_STAT",
"INTC_MASK"
};
INTC::INTC(EmotionEngine* ee)
: cpu(ee)
{
regs = {};
}
uint64_t INTC::read(uint32_t addr)
{
uint8_t offset = (addr >> 4) & 0xf;
uint32_t* ptr = (uint32_t*)®s + offset;
return *ptr;
}
void INTC::write(uint32_t addr, uint64_t data)
{
uint8_t offset = (addr >> 4) & 0xf;
uint32_t* ptr = (uint32_t*)®s + offset;
*ptr = (offset ? *ptr ^ data : *ptr & ~data);
cpu->cop0.cause.ip0_pending = (regs.intc_mask & regs.intc_stat);
printf("[INTC]: Writing 0x%08lX to %s\n", data, REGS[offset]);
}
void INTC::trigger(uint32_t intr)
{
//printf("[INTC]: Triggering interrupt %d\n", intr);
regs.intc_stat |= (1 << intr);
cpu->cop0.cause.ip0_pending = (regs.intc_mask & regs.intc_stat);
}
bool INTC::int_pending()
{
auto& cop0 = cpu->cop0;
bool int_enabled = cop0.status.eie && cop0.status.ie && !cop0.status.erl && !cop0.status.exl;
bool pending = (cop0.cause.ip0_pending && cop0.status.im0) ||
(cop0.cause.ip1_pending && cop0.status.im1) ||
(cop0.cause.timer_ip_pending && cop0.status.im7);
return int_enabled && pending;
}