summaryrefslogtreecommitdiff
path: root/Database/internals/database-segment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Database/internals/database-segment.cpp')
-rw-r--r--Database/internals/database-segment.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/Database/internals/database-segment.cpp b/Database/internals/database-segment.cpp
new file mode 100644
index 0000000..4b94000
--- /dev/null
+++ b/Database/internals/database-segment.cpp
@@ -0,0 +1,119 @@
+#include "database-segment.h"
+
+Segment::Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size, const Byte * data) : patches(0), plainmemory(0), size(size), extra_size(extra_size), id(id), cpu_base(cpu_base) {
+ Uint64 fullsize = size + extra_size;
+
+ assert(size);
+
+ if (data) {
+ plainmemory = (Byte *) data;
+ loaded = true;
+ allocated = false
+ } else {
+ plainmemory = Allocator<Byte>::alloc(size);
+ loaded = false;
+ allocated = true;
+ }
+ tags = Allocator<memory_tags_t>::alloc(fullsize);
+ refData = Allocator<SegmentRefData *>::alloc(fullsize);
+}
+
+Segment::~Segment() {
+ if (allocated)
+ Allocator<Byte>::free(plainmemory);
+ if (patches)
+ Allocator<Byte>::free(patches);
+ if (patchesmemory)
+ Allocator<Byte>::free(patchesmap);
+ Allocator<memory_tags_t>::free(tags);
+ Allocator<SegmentRefData *>::free(refData);
+}
+
+short Segment::Read(Uint32 ptr) {
+ if (ptr >= size) {
+ LOG(CONSOLE, ERROR, "Out of bound read attempt in segment %i at %08X\n", id, ptr);
+ return -1;
+ }
+ if (IsPatched(ptr))
+ return patches[ptr];
+ return plainmemory[ptr];
+}
+
+short Segment::RawRead(Uint32 ptr) {
+ if (ptr >= size) {
+ LOG(CONSOLE, ERROR, "Out of bound rawread attempt in segment %i at %08X\n", id, ptr);
+ return -1;
+ }
+ return plainmemory[ptr];
+}
+
+void Segment::Patch(Uint32 ptr, Byte val) {
+ if (!patchesmap) {
+ patches = Allocator<Byte>::alloc(size);
+ patchesmap = Allocator<Byte>::alloc((size << 3) + ((size & 7) ? 1 : 0));
+ }
+ if (ptr >= size) {
+ LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr);
+ return;
+ }
+ patches[ptr] = val;
+ patchesmap[ptr / 8] |= (1 << ptr % 8);
+}
+
+void Segment::Restore(Uint32 ptr) {
+ if (!patchesmap)
+ return;
+ if (ptr >= size) {
+ LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr);
+ return;
+ }
+ patchesmap[ptr / 8] &= ~(1 << (ptr % 8));
+}
+
+bool Segment::IsPatched(Uint32 ptr) {
+ if (!patchesmap)
+ return false;
+ return patchesmap[ptr / 8] & (1 << (ptr % 8));
+}
+
+void Segment::LoadMemory(Handle * src) {
+ if (loaded) {
+ LOG(CONSOLE, WARNING, "Memory segment already loaded, second attempt ignored.");
+ return;
+ }
+
+ src->Read(plainmemory, size);
+}
+
+void setTag(Uint32 ptr, memory_tags_t tag) {
+ if (ptr >= (size + extra_size)) {
+ LOG(CONSOLE, ERROR, "Out of bound setTag attempt in segment %i at %08X\n", id, ptr);
+ return;
+ }
+ tags[ptr] = tag;
+}
+
+memory_tags_t getTag(Uint32 ptr) {
+ if (ptr >= (size + extra_size)) {
+ memory_tags_t z = { 0, 0 };
+ LOG(CONSOLE, ERROR, "Out of bound getTag attempt in segment %i at %08X\n", id, ptr);
+ return z;
+ }
+ return tags[ptr];
+}
+
+SegmentRefData * Segment::getSegmentRefData(Uint32 ptr) {
+ if (ptr >= (size + extra_size)) {
+ LOG(CONSOLE, ERROR, "Out of bound getSegmentRefData attempt in segment %i at %08X\n", id, ptr);
+ return 0;
+ }
+ return refData[ptr];
+}
+
+void Segment::setSegmentRefData(Uint32 ptr, SegmentRefData * data) {
+ if (ptr >= (size + extra_size)) {
+ LOG(CONSOLE, ERROR, "Out of bound setSegmentRefData attempt in segment %i at %08X\n", id, ptr);
+ return;
+ }
+ refData[ptr] = data;
+}