1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#include <assert.h>
#include <allocator.h>
#include <log.h>
#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<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 (patchesmap)
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 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;
}
|