summaryrefslogtreecommitdiff
path: root/tb/interrupt.cpp
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-12-13 21:43:25 -0600
committerAlejandro Soto <alejandro@34project.org>2022-12-16 16:29:10 -0600
commit0c63c46e31642d0102542a745af6b445a9d22b3b (patch)
tree0e8b6db18829e4a3d6c894af206f2b5257815827 /tb/interrupt.cpp
parentd564e3538a3654facc94bb4cd1ee021830dfcf52 (diff)
Implement interrupt controller
Diffstat (limited to '')
-rw-r--r--tb/interrupt.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/tb/interrupt.cpp b/tb/interrupt.cpp
new file mode 100644
index 0000000..4164bb7
--- /dev/null
+++ b/tb/interrupt.cpp
@@ -0,0 +1,63 @@
+#include <cstdint>
+
+#include "avalon.hpp"
+
+namespace taller::avalon
+{
+ interrupt_controller::interrupt_controller(std::uint32_t base) noexcept
+ : slave(base, 8, 4)
+ {}
+
+ bool interrupt_controller::read(std::uint32_t addr, std::uint32_t &data) noexcept
+ {
+ switch(addr)
+ {
+ case 0:
+ data = status();
+ break;
+
+ case 1:
+ data = mask;
+ break;
+ }
+
+ return true;
+ }
+
+ bool interrupt_controller::write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept
+ {
+ switch(addr)
+ {
+ case 0:
+ break;
+
+ case 1:
+ mask = data;
+ break;
+ }
+
+ return true;
+ }
+
+ bool interrupt_controller::irq() noexcept
+ {
+ return status() != 0;
+ }
+
+ std::uint32_t interrupt_controller::status() noexcept
+ {
+ std::uint32_t lines = 0;
+
+ if(irqs.timer)
+ {
+ lines |= irqs.timer->irq() << 0;
+ }
+
+ if(irqs.jtaguart)
+ {
+ lines |= irqs.jtaguart->irq() << 1;
+ }
+
+ return lines & mask;
+ }
+}