aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-12-12 20:07:29 +0100
committerKarel Kočí <cynerd@email.cz>2017-12-12 20:07:29 +0100
commit535fe1cab28a630e311bcf82778f6d14f35c3ed0 (patch)
tree3cdbcb5f7edf64fc42ceae403daab5b0c486a819
parent15398c34d38489bf14a100bbf01fb9fb4c7e46cb (diff)
downloadqtmips-535fe1cab28a630e311bcf82778f6d14f35c3ed0.tar.gz
qtmips-535fe1cab28a630e311bcf82778f6d14f35c3ed0.tar.bz2
qtmips-535fe1cab28a630e311bcf82778f6d14f35c3ed0.zip
Add memory type abstract function
This functions can be used to write or read 32bit values from memory and memory on its own does signextends for example depending on passed control value.
-rw-r--r--qtmips_machine/memory.cpp41
-rw-r--r--qtmips_machine/memory.h12
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);