mirror of https://github.com/mgba-emu/mgba.git
Core: Start improving memory search
This commit is contained in:
parent
264f238ec3
commit
591ab468e9
|
@ -13,9 +13,7 @@ CXX_GUARD_START
|
||||||
#include <mgba-util/vector.h>
|
#include <mgba-util/vector.h>
|
||||||
|
|
||||||
enum mCoreMemorySearchType {
|
enum mCoreMemorySearchType {
|
||||||
mCORE_MEMORY_SEARCH_32,
|
mCORE_MEMORY_SEARCH_INT,
|
||||||
mCORE_MEMORY_SEARCH_16,
|
|
||||||
mCORE_MEMORY_SEARCH_8,
|
|
||||||
mCORE_MEMORY_SEARCH_STRING,
|
mCORE_MEMORY_SEARCH_STRING,
|
||||||
mCORE_MEMORY_SEARCH_GUESS,
|
mCORE_MEMORY_SEARCH_GUESS,
|
||||||
};
|
};
|
||||||
|
@ -23,11 +21,11 @@ enum mCoreMemorySearchType {
|
||||||
struct mCoreMemorySearchParams {
|
struct mCoreMemorySearchParams {
|
||||||
int memoryFlags;
|
int memoryFlags;
|
||||||
enum mCoreMemorySearchType type;
|
enum mCoreMemorySearchType type;
|
||||||
|
int align;
|
||||||
|
int width;
|
||||||
union {
|
union {
|
||||||
const char* valueStr;
|
const char* valueStr;
|
||||||
uint32_t value32;
|
uint32_t valueInt;
|
||||||
uint32_t value16;
|
|
||||||
uint32_t value8;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +33,9 @@ struct mCoreMemorySearchResult {
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
int segment;
|
int segment;
|
||||||
uint64_t guessDivisor;
|
uint64_t guessDivisor;
|
||||||
|
uint64_t guessMultiplier;
|
||||||
enum mCoreMemorySearchType type;
|
enum mCoreMemorySearchType type;
|
||||||
|
int width;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult);
|
DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult);
|
||||||
|
|
|
@ -29,33 +29,41 @@ static size_t _search32(const void* mem, size_t size, const struct mCoreMemoryBl
|
||||||
if ((mask & 1) && (!limit || found < limit)) {
|
if ((mask & 1) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i;
|
res->address = start + i;
|
||||||
res->type = mCORE_MEMORY_SEARCH_32;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 4;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 2) && (!limit || found < limit)) {
|
if ((mask & 2) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 4;
|
res->address = start + i + 4;
|
||||||
res->type = mCORE_MEMORY_SEARCH_32;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 4;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 4) && (!limit || found < limit)) {
|
if ((mask & 4) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 8;
|
res->address = start + i + 8;
|
||||||
res->type = mCORE_MEMORY_SEARCH_32;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 4;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 8) && (!limit || found < limit)) {
|
if ((mask & 8) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 12;
|
res->address = start + i + 12;
|
||||||
res->type = mCORE_MEMORY_SEARCH_32;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 4;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,65 +94,81 @@ static size_t _search16(const void* mem, size_t size, const struct mCoreMemoryBl
|
||||||
if ((mask & 1) && (!limit || found < limit)) {
|
if ((mask & 1) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i;
|
res->address = start + i;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 2) && (!limit || found < limit)) {
|
if ((mask & 2) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 2;
|
res->address = start + i + 2;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 4) && (!limit || found < limit)) {
|
if ((mask & 4) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 4;
|
res->address = start + i + 4;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 8) && (!limit || found < limit)) {
|
if ((mask & 8) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 6;
|
res->address = start + i + 6;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 16) && (!limit || found < limit)) {
|
if ((mask & 16) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 8;
|
res->address = start + i + 8;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 32) && (!limit || found < limit)) {
|
if ((mask & 32) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 10;
|
res->address = start + i + 10;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 64) && (!limit || found < limit)) {
|
if ((mask & 64) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 12;
|
res->address = start + i + 12;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 128) && (!limit || found < limit)) {
|
if ((mask & 128) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 14;
|
res->address = start + i + 14;
|
||||||
res->type = mCORE_MEMORY_SEARCH_16;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 2;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,65 +198,81 @@ static size_t _search8(const void* mem, size_t size, const struct mCoreMemoryBlo
|
||||||
if ((mask & 1) && (!limit || found < limit)) {
|
if ((mask & 1) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i;
|
res->address = start + i;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 2) && (!limit || found < limit)) {
|
if ((mask & 2) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 1;
|
res->address = start + i + 1;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 4) && (!limit || found < limit)) {
|
if ((mask & 4) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 2;
|
res->address = start + i + 2;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 8) && (!limit || found < limit)) {
|
if ((mask & 8) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 3;
|
res->address = start + i + 3;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 16) && (!limit || found < limit)) {
|
if ((mask & 16) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 4;
|
res->address = start + i + 4;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 32) && (!limit || found < limit)) {
|
if ((mask & 32) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 5;
|
res->address = start + i + 5;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 64) && (!limit || found < limit)) {
|
if ((mask & 64) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 6;
|
res->address = start + i + 6;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
if ((mask & 128) && (!limit || found < limit)) {
|
if ((mask & 128) && (!limit || found < limit)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i + 7;
|
res->address = start + i + 7;
|
||||||
res->type = mCORE_MEMORY_SEARCH_8;
|
res->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
res->width = 1;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
res->guessDivisor = 1;
|
res->guessDivisor = 1;
|
||||||
|
res->guessMultiplier = 1;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,18 +280,32 @@ static size_t _search8(const void* mem, size_t size, const struct mCoreMemoryBlo
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, struct mCoreMemorySearchResults* out, size_t limit) {
|
static size_t _searchInt(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) {
|
||||||
|
if (params->align == params->width || params->align == -1) {
|
||||||
|
switch (params->width) {
|
||||||
|
case 4:
|
||||||
|
return _search32(mem, size, block, params->valueInt, out, limit);
|
||||||
|
case 2:
|
||||||
|
return _search16(mem, size, block, params->valueInt, out, limit);
|
||||||
|
case 1:
|
||||||
|
return _search8(mem, size, block, params->valueInt, out, limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, int len, struct mCoreMemorySearchResults* out, size_t limit) {
|
||||||
const char* memStr = mem;
|
const char* memStr = mem;
|
||||||
size_t found = 0;
|
size_t found = 0;
|
||||||
size_t len = strlen(valueStr);
|
|
||||||
uint32_t start = block->start;
|
uint32_t start = block->start;
|
||||||
uint32_t end = size; // TODO: Segments
|
uint32_t end = size; // TODO: Segments
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; (!limit || found < limit) && i < end - len; ++i) {
|
for (i = 0; (!limit || found < limit) && i < end - len; ++i) {
|
||||||
if (!strncmp(valueStr, &memStr[i], len)) {
|
if (!memcmp(valueStr, &memStr[i], len)) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
|
||||||
res->address = start + i;
|
res->address = start + i;
|
||||||
res->type = mCORE_MEMORY_SEARCH_STRING;
|
res->type = mCORE_MEMORY_SEARCH_STRING;
|
||||||
|
res->width = len;
|
||||||
res->segment = -1; // TODO
|
res->segment = -1; // TODO
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
|
@ -342,14 +396,10 @@ static size_t _searchGuess(const void* mem, size_t size, const struct mCoreMemor
|
||||||
|
|
||||||
static size_t _search(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) {
|
static size_t _search(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) {
|
||||||
switch (params->type) {
|
switch (params->type) {
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
case mCORE_MEMORY_SEARCH_INT:
|
||||||
return _search32(mem, size, block, params->value32, out, limit);
|
return _searchInt(mem, size, block, params, out, limit);
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
|
||||||
return _search16(mem, size, block, params->value16, out, limit);
|
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
|
||||||
return _search8(mem, size, block, params->value8, out, limit);
|
|
||||||
case mCORE_MEMORY_SEARCH_STRING:
|
case mCORE_MEMORY_SEARCH_STRING:
|
||||||
return _searchStr(mem, size, block, params->valueStr, out, limit);
|
return _searchStr(mem, size, block, params->valueStr, params->width, out, limit);
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
case mCORE_MEMORY_SEARCH_GUESS:
|
||||||
return _searchGuess(mem, size, block, params->valueStr, out, limit);
|
return _searchGuess(mem, size, block, params->valueStr, out, limit);
|
||||||
}
|
}
|
||||||
|
@ -384,26 +434,26 @@ bool _testGuess(struct mCore* core, const struct mCoreMemorySearchResult* res, c
|
||||||
|
|
||||||
value = strtoull(params->valueStr, &end, 10);
|
value = strtoull(params->valueStr, &end, 10);
|
||||||
if (end) {
|
if (end) {
|
||||||
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = strtoull(params->valueStr, &end, 16);
|
value = strtoull(params->valueStr, &end, 16);
|
||||||
if (end) {
|
if (end) {
|
||||||
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) {
|
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,69 +465,27 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
|
||||||
for (i = 0; i < mCoreMemorySearchResultsSize(inout); ++i) {
|
for (i = 0; i < mCoreMemorySearchResultsSize(inout); ++i) {
|
||||||
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsGetPointer(inout, i);
|
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsGetPointer(inout, i);
|
||||||
switch (res->type) {
|
switch (res->type) {
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
case mCORE_MEMORY_SEARCH_INT:
|
||||||
switch (params->type) {
|
switch (params->width) {
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
case 1:
|
||||||
if (core->rawRead8(core, res->address, res->segment) != params->value8) {
|
if (core->rawRead8(core, res->address, res->segment) != params->valueInt) {
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
mCoreMemorySearchResultsShift(inout, i, 1);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
case 2:
|
||||||
if (core->rawRead8(core, res->address, res->segment) != params->value16) {
|
if (core->rawRead8(core, res->address, res->segment) != params->valueInt) {
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
mCoreMemorySearchResultsShift(inout, i, 1);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
case 4:
|
||||||
if (core->rawRead32(core, res->address, res->segment) != params->value32) {
|
if (core->rawRead32(core, res->address, res->segment) != params->valueInt) {
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
mCoreMemorySearchResultsShift(inout, i, 1);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
case -1:
|
||||||
if (!_testGuess(core, res, params)) {
|
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
|
||||||
switch (params->type) {
|
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
|
||||||
if (core->rawRead16(core, res->address, res->segment) != params->value16) {
|
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
if (core->rawRead32(core, res->address, res->segment) != params->value32) {
|
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
|
||||||
if (!_testGuess(core, res, params)) {
|
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
switch (params->type) {
|
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
if (core->rawRead32(core, res->address, res->segment) != params->value32) {
|
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
|
||||||
if (!_testGuess(core, res, params)) {
|
if (!_testGuess(core, res, params)) {
|
||||||
mCoreMemorySearchResultsShift(inout, i, 1);
|
mCoreMemorySearchResultsShift(inout, i, 1);
|
||||||
--i;
|
--i;
|
||||||
|
|
|
@ -41,49 +41,48 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
|
||||||
QByteArray string;
|
QByteArray string;
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (m_ui.typeNum->isChecked()) {
|
if (m_ui.typeNum->isChecked()) {
|
||||||
|
params->type = mCORE_MEMORY_SEARCH_INT;
|
||||||
|
params->align = -1;
|
||||||
if (m_ui.bits8->isChecked()) {
|
if (m_ui.bits8->isChecked()) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_8;
|
params->width = 1;
|
||||||
}
|
}
|
||||||
if (m_ui.bits16->isChecked()) {
|
if (m_ui.bits16->isChecked()) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_16;
|
params->width = 2;
|
||||||
}
|
}
|
||||||
if (m_ui.bits32->isChecked()) {
|
if (m_ui.bits32->isChecked()) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_32;
|
params->width = 4;
|
||||||
}
|
}
|
||||||
if (m_ui.numHex->isChecked()) {
|
if (m_ui.numHex->isChecked()) {
|
||||||
uint32_t v = m_ui.value->text().toUInt(&ok, 16);
|
uint32_t v = m_ui.value->text().toUInt(&ok, 16);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
switch (params->type) {
|
params->valueInt = v;
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
switch (params->width) {
|
||||||
|
case 1:
|
||||||
ok = v < 0x100;
|
ok = v < 0x100;
|
||||||
params->value8 = v;
|
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
case 2:
|
||||||
ok = v < 0x10000;
|
ok = v < 0x10000;
|
||||||
params->value16 = v;
|
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
case 4:
|
||||||
params->value32 = v;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = false;
|
ok = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_ui.numDec->isChecked()) {
|
if (m_ui.numDec->isChecked()) {
|
||||||
uint32_t v = m_ui.value->text().toUInt(&ok, 10);
|
uint32_t v = m_ui.value->text().toUInt(&ok, 10);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
switch (params->type) {
|
params->valueInt = v;
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
switch (params->width) {
|
||||||
|
case 1:
|
||||||
ok = v < 0x100;
|
ok = v < 0x100;
|
||||||
params->value8 = v;
|
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
case 2:
|
||||||
ok = v < 0x10000;
|
ok = v < 0x10000;
|
||||||
params->value16 = v;
|
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
case 4:
|
||||||
params->value32 = v;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = false;
|
ok = false;
|
||||||
|
@ -101,6 +100,7 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
|
||||||
params->type = mCORE_MEMORY_SEARCH_STRING;
|
params->type = mCORE_MEMORY_SEARCH_STRING;
|
||||||
m_string = m_ui.value->text().toLocal8Bit();
|
m_string = m_ui.value->text().toLocal8Bit();
|
||||||
params->valueStr = m_string.constData();
|
params->valueStr = m_string.constData();
|
||||||
|
params->width = m_ui.value->text().size();
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -145,61 +145,63 @@ void MemorySearch::refresh() {
|
||||||
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0')));
|
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0')));
|
||||||
m_ui.results->setItem(i, 0, item);
|
m_ui.results->setItem(i, 0, item);
|
||||||
QTableWidgetItem* type;
|
QTableWidgetItem* type;
|
||||||
if (m_ui.numHex->isChecked()) {
|
QByteArray string;
|
||||||
switch (result->type) {
|
if (result->type == mCORE_MEMORY_SEARCH_INT && m_ui.numHex->isChecked()) {
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
switch (result->width) {
|
||||||
|
case 1:
|
||||||
item = new QTableWidgetItem(QString("%1").arg(core->rawRead8(core, result->address, result->segment), 2, 16, QChar('0')));
|
item = new QTableWidgetItem(QString("%1").arg(core->rawRead8(core, result->address, result->segment), 2, 16, QChar('0')));
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
case 2:
|
||||||
item = new QTableWidgetItem(QString("%1").arg(core->rawRead16(core, result->address, result->segment), 4, 16, QChar('0')));
|
item = new QTableWidgetItem(QString("%1").arg(core->rawRead16(core, result->address, result->segment), 4, 16, QChar('0')));
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
case 4:
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
item = new QTableWidgetItem(QString("%1").arg(core->rawRead32(core, result->address, result->segment), 8, 16, QChar('0')));
|
item = new QTableWidgetItem(QString("%1").arg(core->rawRead32(core, result->address, result->segment), 8, 16, QChar('0')));
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_STRING:
|
|
||||||
item = new QTableWidgetItem("?"); // TODO
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (result->type) {
|
switch (result->type) {
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
case mCORE_MEMORY_SEARCH_INT:
|
||||||
|
switch (result->width) {
|
||||||
|
case 1:
|
||||||
item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment)));
|
item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment)));
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
case 2:
|
||||||
item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment)));
|
item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment)));
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
case 4:
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment)));
|
item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_STRING:
|
case mCORE_MEMORY_SEARCH_STRING:
|
||||||
item = new QTableWidgetItem("?"); // TODO
|
string.reserve(result->width);
|
||||||
|
for (int i = 0; i < result->width; ++i) {
|
||||||
|
string.append(core->rawRead8(core, result->address + i, result->segment));
|
||||||
|
}
|
||||||
|
item = new QTableWidgetItem(QLatin1String(string)); // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QString divisor;
|
QString divisor;
|
||||||
if (result->guessDivisor > 1) {
|
if (result->guessDivisor > 1) {
|
||||||
|
if (result->guessMultiplier > 1) {
|
||||||
|
divisor = tr(" (%0/%1×)").arg(result->guessMultiplier).arg(result->guessMultiplier);
|
||||||
|
} else {
|
||||||
divisor = tr(" (⅟%0×)").arg(result->guessDivisor);
|
divisor = tr(" (⅟%0×)").arg(result->guessDivisor);
|
||||||
}
|
}
|
||||||
|
} else if (result->guessMultiplier > 1) {
|
||||||
|
divisor = tr(" (%0×)").arg(result->guessMultiplier);
|
||||||
|
}
|
||||||
switch (result->type) {
|
switch (result->type) {
|
||||||
case mCORE_MEMORY_SEARCH_8:
|
case mCORE_MEMORY_SEARCH_INT:
|
||||||
type = new QTableWidgetItem(tr("1 byte%0").arg(divisor));
|
type = new QTableWidgetItem(tr("%1 byte%2").arg(result->width).arg(divisor));
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_16:
|
|
||||||
type = new QTableWidgetItem(tr("2 bytes%0").arg(divisor));
|
|
||||||
break;
|
|
||||||
case mCORE_MEMORY_SEARCH_GUESS:
|
|
||||||
case mCORE_MEMORY_SEARCH_32:
|
|
||||||
type = new QTableWidgetItem(tr("4 bytes%0").arg(divisor));
|
|
||||||
break;
|
break;
|
||||||
case mCORE_MEMORY_SEARCH_STRING:
|
case mCORE_MEMORY_SEARCH_STRING:
|
||||||
item = new QTableWidgetItem("?"); // TODO
|
type = new QTableWidgetItem("string");
|
||||||
}
|
}
|
||||||
m_ui.results->setItem(i, 1, item);
|
m_ui.results->setItem(i, 1, item);
|
||||||
m_ui.results->setItem(i, 2, type);
|
m_ui.results->setItem(i, 2, type);
|
||||||
}
|
}
|
||||||
m_ui.results->sortItems(0);
|
m_ui.results->sortItems(0);
|
||||||
m_ui.results->resizeColumnsToContents();
|
|
||||||
m_ui.results->resizeRowsToContents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemorySearch::openMemory() {
|
void MemorySearch::openMemory() {
|
||||||
|
|
Loading…
Reference in New Issue