-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInterruptMenu.cpp
107 lines (94 loc) · 2.54 KB
/
InterruptMenu.cpp
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "InterruptMenu.hpp"
#include "implot.h"
#include "SystemControlCoprocessor.hpp"
#include "Cpu.hpp"
InterruptMenu::InterruptMenu()
{
for (int idx = 0; idx < NUM_IRQS; idx++)
{
i_stat_irqs[idx] = new CircularBuffer<float>(MAX_VALUE_COUNT);
i_mask_irqs[idx] = new CircularBuffer<float>(MAX_VALUE_COUNT);
}
}
InterruptMenu::~InterruptMenu()
{
for (int idx = 0; idx < NUM_IRQS; idx++)
{
delete i_stat_irqs[idx];
delete i_mask_irqs[idx];
}
}
void InterruptMenu::draw_in_category(menubar_category category)
{
if (category == menubar_category::VIEW)
{
ImGui::Checkbox("Show Interrupts", &is_visible);
}
}
void InterruptMenu::draw_menu()
{
if (is_visible == false)
{
return;
}
ImGui::Begin("Interrupt");
ImPlot::SetNextPlotLimits(0, MAX_VALUE_COUNT, -0.1f, 1.1f, ImGuiCond_Always);
if (ImPlot::BeginPlot("I_STAT", "ticks", nullptr, ImVec2(0, 0)))
{
for (int idx = 0; idx < NUM_IRQS; idx++)
{
ImPlot::PlotLine(labels[idx],
[](void *data, int _idx) {
CircularBuffer<float> * values = static_cast<CircularBuffer<float>*>(data);
ImPlotPoint result;
result.x = _idx;
result.y = values->get(_idx);
return result;
},
reinterpret_cast<void*>(i_stat_irqs[idx]), MAX_VALUE_COUNT);
}
ImPlot::EndPlot();
}
ImGui::SameLine();
ImPlot::SetNextPlotLimits(0, MAX_VALUE_COUNT, -0.1f, 1.1f, ImGuiCond_Always);
if (ImPlot::BeginPlot("I_MASK", "ticks", nullptr, ImVec2(0,0)))
{
for (int idx = 0; idx < NUM_IRQS; idx++)
{
ImPlot::PlotLine(labels[idx],
[](void *data, int _idx) {
CircularBuffer<float> * values = static_cast<CircularBuffer<float>*>(data);
ImPlotPoint result;
result.x = _idx;
result.y = values->get(_idx);
return result;
},
reinterpret_cast<void*>(i_mask_irqs[idx]), MAX_VALUE_COUNT);
}
ImPlot::EndPlot();
}
ImGui::End();
}
void InterruptMenu::tick()
{
if (is_visible == false)
{
return;
}
Cpu * cpu = Cpu::get_instance();
SystemControlCoprocessor * cop0 = SystemControlCoprocessor::get_instance();
system_control::interrupt_register i_stat = cop0->interrupt_status_register;
system_control::interrupt_register i_mask = cop0->interrupt_mask_register;
unsigned int i_stat_bits = i_stat.IRQ_BITS;
unsigned int i_mask_bits = i_mask.IRQ_BITS;
for (int idx = 0; idx < NUM_IRQS; idx++)
{
bool i_stat_for_idx = i_stat_bits & 0x1;
bool i_mask_for_idx = i_mask_bits & 0x1;
i_stat_irqs[idx]->push(i_stat_for_idx ? 1.f : 0.f);
i_mask_irqs[idx]->push(i_mask_for_idx ? 1.f : 0.f);
// shift to next irq bit to check
i_stat_bits >>= 1;
i_mask_bits >>= 1;
}
}