diff options
-rw-r--r-- | qtmips_machine/memory.cpp | 41 | ||||
-rw-r--r-- | qtmips_machine/memory.h | 12 |
2 files changed, 53 insertions, 0 deletions
diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp index 282a9e9..fd1dbb4 100644 --- a/qtmips_machine/memory.cpp +++ b/qtmips_machine/memory.cpp @@ -55,6 +55,47 @@ std::uint32_t MemoryAccess::read_word(std::uint32_t offset) { return dt; } +void MemoryAccess::write_ctl(enum MemoryAccess::AccessControl ctl, std::uint32_t offset, std::uint32_t value) { + switch (ctl) { + case AC_BYTE: + case AC_BYTE_UNSIGNED: + this->write_byte(offset, value); + break; + case AC_HALFWORD: + case AC_HALFWORD_UNSIGNED: + this->write_hword(offset, value); + break; + case AC_WORD: + this->write_word(offset, value); + break; + default: + throw QTMIPS_EXCEPTION(UnknownMemoryControl, "Trying to write to memory with unknown ctl", QString::number(ctl)); + } +} + +std::uint32_t MemoryAccess::read_ctl(enum MemoryAccess::AccessControl ctl, std::uint32_t offset) { + switch (ctl) { + case AC_BYTE: + { + std::uint8_t b = this->read_byte(offset); + return ((b & 0x80) << 24) | (b & 0x7F); // Sign extend + } + case AC_HALFWORD: + { + std::uint16_t h = this->read_hword(offset); + return ((h & 0x8000) << 16) | (h & 0x7FFF); // Sign extend + } + case AC_WORD: + return this->read_word(offset); + case AC_BYTE_UNSIGNED: + return this->read_byte(offset); + case AC_HALFWORD_UNSIGNED: + return this->read_hword(offset); + default: + throw QTMIPS_EXCEPTION(UnknownMemoryControl, "Trying to read from memory with unknown ctl", QString::number(ctl)); + } +} + MemorySection::MemorySection(std::uint32_t length) { this->len = length; this->dt = new std::uint8_t[length]; diff --git a/qtmips_machine/memory.h b/qtmips_machine/memory.h index 1b56d7c..90fda1b 100644 --- a/qtmips_machine/memory.h +++ b/qtmips_machine/memory.h @@ -18,11 +18,23 @@ public: std::uint16_t read_hword(std::uint32_t offset); std::uint32_t read_word(std::uint32_t offset); + enum AccessControl { + AC_BYTE, + AC_HALFWORD, + AC_WORD, + AC_BYTE_UNSIGNED, + AC_HALFWORD_UNSIGNED + }; + void write_ctl(enum AccessControl ctl, std::uint32_t offset, std::uint32_t value); + std::uint32_t read_ctl(enum AccessControl ctl, std::uint32_t offset); + signals: // TODO trigger void byte_change(std::uint32_t address, std::uint32_t value); }; +Q_DECLARE_METATYPE(MemoryAccess::AccessControl) + class MemorySection : public MemoryAccess { public: MemorySection(std::uint32_t length); |