From a8d4f0d2c7ec70f22b1fb4a7614ebd076a2916cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Mon, 15 Jan 2018 15:07:01 +0100 Subject: Emit byte_change when byte is written to memory --- qtmips_machine/memory.cpp | 24 +++++++++++++++--------- qtmips_machine/memory.h | 23 +++++++++++++---------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp index 69f7d54..eec9f8c 100644 --- a/qtmips_machine/memory.cpp +++ b/qtmips_machine/memory.cpp @@ -2,8 +2,10 @@ using namespace machine; -// Note about endianness: Current memory implementation is expected to be a big endian. -// But we can be running on little endian so we should do conversion from bytes to word according that. +void MemoryAccess::write_byte(std::uint32_t offset, std::uint8_t value) { + emit byte_change(offset, value); + wbyte(offset, value); +} void MemoryAccess::write_hword(std::uint32_t offset, std::uint16_t value) { #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -29,7 +31,11 @@ void MemoryAccess::write_word(std::uint32_t offset, std::uint32_t value) { #endif } -std::uint16_t MemoryAccess::read_hword(std::uint32_t offset) { +std::uint8_t MemoryAccess::read_byte(std::uint32_t offset) const { + return rbyte(offset); +} + +std::uint16_t MemoryAccess::read_hword(std::uint32_t offset) const { std::uint16_t dt = 0; #if __BYTE_ORDER == __LITTLE_ENDIAN dt |= (this->read_byte(offset++) << 8); @@ -41,7 +47,7 @@ std::uint16_t MemoryAccess::read_hword(std::uint32_t offset) { return dt; } -std::uint32_t MemoryAccess::read_word(std::uint32_t offset) { +std::uint32_t MemoryAccess::read_word(std::uint32_t offset) const { std::uint32_t dt = 0; #if __BYTE_ORDER == __LITTLE_ENDIAN dt |= ((std::uint32_t)this->read_byte(offset++) << 24); @@ -77,7 +83,7 @@ void MemoryAccess::write_ctl(enum MemoryAccess::AccessControl ctl, std::uint32_t } } -std::uint32_t MemoryAccess::read_ctl(enum MemoryAccess::AccessControl ctl, std::uint32_t offset) { +std::uint32_t MemoryAccess::read_ctl(enum MemoryAccess::AccessControl ctl, std::uint32_t offset) const { switch (ctl) { case AC_NONE: return 0; @@ -116,13 +122,13 @@ MemorySection::~MemorySection() { delete this->dt; } -void MemorySection::write_byte(std::uint32_t offset, std::uint8_t value) { +void MemorySection::wbyte(std::uint32_t offset, std::uint8_t value) { if (offset >= this->len) throw QTMIPS_EXCEPTION(OutOfMemoryAccess, "Trying to write outside of the memory section", QString("Accessing using offset: ") + QString(offset)); this->dt[offset] = value; } -std::uint8_t MemorySection::read_byte(std::uint32_t offset) const { +std::uint8_t MemorySection::rbyte(std::uint32_t offset) const { if (offset >= this->len) throw QTMIPS_EXCEPTION(OutOfMemoryAccess, "Trying to read outside of the memory section", QString("Accessing using offset: ") + QString(offset)); return this->dt[offset]; @@ -223,12 +229,12 @@ MemorySection *Memory::get_section(std::uint32_t address, bool create) const { // for section lookup. We do it using (2^BITS - 1). #define SECTION_ADDRESS(ADDR) ((ADDR) & ADDRESS_MASK(MEMORY_SECTION_BITS)) -void Memory::write_byte(std::uint32_t address, std::uint8_t value) { +void Memory::wbyte(std::uint32_t address, std::uint8_t value) { MemorySection *section = this->get_section(address, true); section->write_byte(SECTION_ADDRESS(address), value); } -std::uint8_t Memory::read_byte(std::uint32_t address) const { +std::uint8_t Memory::rbyte(std::uint32_t address) const { MemorySection *section = this->get_section(address, false); if (section == nullptr) return 0; diff --git a/qtmips_machine/memory.h b/qtmips_machine/memory.h index 3bd1060..d1fa2e7 100644 --- a/qtmips_machine/memory.h +++ b/qtmips_machine/memory.h @@ -11,13 +11,13 @@ namespace machine { class MemoryAccess : public QObject { Q_OBJECT public: - virtual void write_byte(std::uint32_t offset, std::uint8_t value) = 0; + void write_byte(std::uint32_t offset, std::uint8_t value); void write_hword(std::uint32_t offset, std::uint16_t value); void write_word(std::uint32_t offset, std::uint32_t value); - virtual std::uint8_t read_byte(std::uint32_t offset) const = 0; - std::uint16_t read_hword(std::uint32_t offset); - std::uint32_t read_word(std::uint32_t offset); + std::uint8_t read_byte(std::uint32_t offset) const; + std::uint16_t read_hword(std::uint32_t offset) const; + std::uint32_t read_word(std::uint32_t offset) const; enum AccessControl { AC_NONE, @@ -28,11 +28,14 @@ public: 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); + std::uint32_t read_ctl(enum AccessControl ctl, std::uint32_t offset) const; signals: - // TODO trigger void byte_change(std::uint32_t address, std::uint32_t value); + +protected: + virtual void wbyte(std::uint32_t offset, std::uint8_t value) = 0; + virtual std::uint8_t rbyte(std::uint32_t offset) const = 0; }; class MemorySection : public MemoryAccess { @@ -41,8 +44,8 @@ public: MemorySection(const MemorySection&); ~MemorySection(); - void write_byte(std::uint32_t offset, std::uint8_t value); - std::uint8_t read_byte(std::uint32_t offset) const; + void wbyte(std::uint32_t offset, std::uint8_t value); + std::uint8_t rbyte(std::uint32_t offset) const; void merge(MemorySection&); std::uint32_t length() const; @@ -76,8 +79,8 @@ public: void reset(const Memory&); MemorySection *get_section(std::uint32_t address, bool create) const; // returns section containing given address - void write_byte(std::uint32_t address, std::uint8_t value); - std::uint8_t read_byte(std::uint32_t address) const; + void wbyte(std::uint32_t address, std::uint8_t value); + std::uint8_t rbyte(std::uint32_t address) const; bool operator==(const Memory&) const; bool operator!=(const Memory&) const; -- cgit v1.2.3