diff --git a/src/vm.cpp b/src/vm.cpp index 20ab3e8..13ac3e4 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -13,7 +13,11 @@ inline int32_t sign_extend(int32_t value, int bits) { } VM::VM(const std::vector& memory, const std::string& file_path) - : ram(memory), pc(PROGRAM_ADDR), file_path(file_path) {} + : ram(memory), pc(PROGRAM_ADDR), file_path(file_path) { + devices = std::vector(2, 0); + devices[0] = &ram; + devices[1] = &uart; +} void VM::setreg(int regnum, uint32_t value) { if (regnum == 0) { @@ -70,22 +74,23 @@ void UART::write_mem(uint8_t* src, size_t addr, size_t size) { } void VM::read_mem(uint8_t* dst, size_t addr, size_t size) { - if (addr >= PROGRAM_ADDR) { - ram.read_mem(dst, addr, size); + for (Device* dev : devices) { + if (addr >= dev->base() && addr + size <= dev->base() + dev->size()) { + dev->read_mem(dst, addr, size); + return; + } } + throw std::runtime_error("Memory access out of bounds"); } void VM::write_mem(uint8_t* src, size_t addr, size_t size) { - if (addr >= PROGRAM_ADDR) { - ram.write_mem(src, addr, size); - } - - if (is_mmap(addr, size)) { - if (addr >= UART_ADDR && addr < UART_ADDR + 8) { - uart.write_mem(src, addr, size); + for (Device* dev : devices) { + if (addr >= dev->base() && addr + size <= dev->base() + dev->size()) { + dev->write_mem(src, addr, size); + return; } - return; } + throw std::runtime_error("Memory access out of bounds"); } std::vector VM::read_memory(size_t start, size_t size) { diff --git a/src/vm.hpp b/src/vm.hpp index ede64a0..53c5083 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -24,13 +24,16 @@ class Device { virtual void write_mem(uint8_t *src, size_t addr, size_t size); virtual void read_mem(uint8_t *dst, size_t addr, size_t size); + uint32_t base() { return base_addr; } + uint32_t size() { return mem_size; } + private: uint32_t base_addr = 0; uint32_t mem_size = 0; std::vector mem; }; -class UART : public Device { +class UART final : public Device { public: UART() : Device(UART_ADDR, 8) {} @@ -48,7 +51,7 @@ class UART : public Device { enum LSRBits { LSR_TRANSMITTER_EMPTY = 0x20 }; }; -class RAM : public Device { +class RAM final : public Device { public: RAM(const std::vector &memory) : Device(PROGRAM_ADDR, memory) {} }; @@ -81,4 +84,5 @@ class VM { std::string file_path; UART uart; + std::vector devices; };