aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_machine/memory.cpp24
-rw-r--r--qtmips_machine/memory.h23
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;