diff --git a/include/io.hh b/include/io.hh new file mode 100644 index 0000000..dd41ae4 --- /dev/null +++ b/include/io.hh @@ -0,0 +1,20 @@ +#pragma once +#include + +// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays) + +namespace matar { +class IoRegisters { + public: + uint8_t read(uint32_t) const; + void write(uint32_t, uint8_t); + + private: + struct { + bool post_boot_flag = false; + bool interrupt_master_enabler = false; + } system; +}; +} + +// NOLINTEND(cppcoreguidelines-avoid-c-arrays) diff --git a/include/memory.hh b/include/memory.hh index 2f31ba7..bd2b250 100644 --- a/include/memory.hh +++ b/include/memory.hh @@ -1,6 +1,7 @@ #pragma once #include "header.hh" +#include "io.hh" #include #include #include @@ -51,6 +52,7 @@ class Memory { #undef MEMORY_REGION + IoRegisters io; std::unordered_map invalid_mem; std::vector rom; Header header; diff --git a/src/io.cc b/src/io.cc new file mode 100644 index 0000000..ae46e79 --- /dev/null +++ b/src/io.cc @@ -0,0 +1,40 @@ +#include "io.hh" +#include "util/log.hh" + +namespace matar { +#define ADDR static constexpr uint32_t + +ADDR POSTFLG = 0x4000300; +ADDR IME = 0x4000208; + +#undef ADDR + +uint8_t +IoRegisters::read(uint32_t address) const { + switch (address) { + case POSTFLG: + return system.post_boot_flag; + case IME: + return system.interrupt_master_enabler; + default: + glogger.warn("Unused IO address read at 0x{:08X}", address); + } + + return 0xFF; +} + +void +IoRegisters::write(uint32_t address, uint8_t byte) { + switch (address) { + case POSTFLG: + system.post_boot_flag = byte & 1; + break; + case IME: + system.interrupt_master_enabler = byte & 1; + break; + default: + glogger.warn("Unused IO address written at 0x{:08X}", address); + } + return; +} +} diff --git a/src/memory.cc b/src/memory.cc index 668c180..0d57ca6 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -41,6 +41,10 @@ Memory::read(uint32_t address) const { MATCHES(BIOS, bios) MATCHES(BOARD_WRAM, board_wram) MATCHES(CHIP_WRAM, chip_wram) + + if (address >= 0x04000000 && address <= 0x040003FE) + return io.read(address); + MATCHES(PALETTE_RAM, palette_ram) MATCHES(VRAM, vram) MATCHES(OAM_OBJ_ATTR, oam_obj_attr) @@ -64,6 +68,12 @@ Memory::write(uint32_t address, uint8_t byte) { MATCHES(BOARD_WRAM, board_wram) MATCHES(CHIP_WRAM, chip_wram) + + if (address >= 0x04000000 && address <= 0x040003FE) { + io.write(address, byte); + return; + } + MATCHES(PALETTE_RAM, palette_ram) MATCHES(VRAM, vram) MATCHES(OAM_OBJ_ATTR, oam_obj_attr) diff --git a/src/meson.build b/src/meson.build index e7ca05b..8dfdd6f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ lib_sources = files( 'memory.cc', - 'bus.cc' + 'bus.cc', + 'io.cc' ) subdir('util')