#include #include #include #include "database-segment.h" Segment::Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size, const Byte * data) : plainmemory(0), patches(0), size(size), extra_size(extra_size), id(id), cpu_base(cpu_base) { Uint64 fullsize = size + extra_size; assert(size); if (data || !size) { plainmemory = (Byte *) data; loaded = true; allocated = false; } else { plainmemory = Allocator::alloc(size); loaded = false; allocated = true; } tags = Allocator::alloc(fullsize); refData = Allocator::alloc(fullsize); } Segment::~Segment() { if (allocated) Allocator::free(plainmemory); if (patches) Allocator::free(patches); if (patchesmap) Allocator::free(patchesmap); Allocator::free(tags); Allocator::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::alloc(size); patchesmap = Allocator::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 Segment::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 Segment::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; }