win32: fix new ramsearch
This commit is contained in:
parent
585cb80257
commit
197322bcf1
|
@ -44,27 +44,22 @@
|
|||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
// TODO: cleanups :/
|
||||
static inline uint8* HardwareToSoftwareAddress(HWAddressType address)
|
||||
bool IsHardwareAddressValid(HWAddressType address)
|
||||
{
|
||||
if (!GameInfo || address < 0x0000 || address > 0xffff)
|
||||
return NULL;
|
||||
if (!GameInfo)
|
||||
return false;
|
||||
|
||||
// for some reasons, it looks not so easy to return direct pointer.
|
||||
// so we copy a part of RAM to a temporary buffer and return it.
|
||||
static uint8 tempBuf[0x10000];
|
||||
for (int i = 0; i <= 4 && (address+i) <= 0xffff; i++) {
|
||||
tempBuf[address+i] = GetMem(address+i);
|
||||
}
|
||||
return &tempBuf[address];
|
||||
if (address >= 0x0000 && address <= 0xffff)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#define INVALID_HARDWARE_ADDRESS ((HWAddressType) -1)
|
||||
|
||||
struct MemoryRegion
|
||||
{
|
||||
HWAddressType hardwareAddress; // hardware address of the start of this region
|
||||
unsigned int size; // number of bytes to the end of this region
|
||||
unsigned char* softwareAddress; // pointer to the start of the live emulator source values for this region
|
||||
|
||||
unsigned int virtualIndex; // index into s_prevValues, s_curValues, and s_numChanges, valid after being initialized in ResetMemoryRegions()
|
||||
unsigned int itemIndex; // index into listbox items, valid when s_itemIndicesInvalid is false
|
||||
|
@ -105,65 +100,32 @@ void ResetMemoryRegions()
|
|||
|
||||
s_activeMemoryRegions.clear();
|
||||
|
||||
// use HardwareToSoftwareAddress to figure out what all the possible memory regions are,
|
||||
// use IsHardwareAddressValid to figure out what all the possible memory regions are,
|
||||
// split up wherever there's a discontinuity in the address in our software RAM.
|
||||
static const int regionSearchGranularity = 0x100; // if this is too small, we'll waste time (in this function only), but if any region in RAM isn't evenly divisible by this, we might crash.
|
||||
HWAddressType hwRegionStart = 0;
|
||||
uint8* regionStart = NULL;
|
||||
uint8* regionEnd = NULL;
|
||||
for(HWAddressType addr = 0; addr != 0x10000000+regionSearchGranularity; addr += regionSearchGranularity)
|
||||
static const int regionSearchGranularity = 1; // if this is too small, we'll waste time (in this function only), but if any region in RAM isn't evenly divisible by this, we might crash.
|
||||
HWAddressType hwRegionStart = INVALID_HARDWARE_ADDRESS;
|
||||
HWAddressType hwRegionEnd = INVALID_HARDWARE_ADDRESS;
|
||||
for(HWAddressType addr = 0; addr != 0x10000+regionSearchGranularity; addr += regionSearchGranularity)
|
||||
{
|
||||
uint8* swAddr = HardwareToSoftwareAddress(addr);
|
||||
if(regionEnd && swAddr != regionEnd+regionSearchGranularity)
|
||||
{
|
||||
// hit end of region
|
||||
// check to see if it mirrors an existing one (in which case we discard it)
|
||||
bool discard = false;
|
||||
for(MemoryList::iterator iter = s_activeMemoryRegions.begin(); iter != s_activeMemoryRegions.end(); ++iter)
|
||||
{
|
||||
MemoryRegion& region = *iter;
|
||||
if(region.softwareAddress == regionStart)
|
||||
{
|
||||
unsigned int size = regionSearchGranularity + (regionEnd - regionStart);
|
||||
if(size <= region.size)
|
||||
{
|
||||
discard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hwRegionStart += region.size;
|
||||
regionStart += region.size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: don't include ROM in our RAM search (it's too huge)
|
||||
|
||||
if (!IsHardwareAddressValid(addr)) {
|
||||
// create the region
|
||||
if(!discard)
|
||||
{
|
||||
MemoryRegion region = { hwRegionStart, regionSearchGranularity + (regionEnd - regionStart), regionStart };
|
||||
if (hwRegionStart != INVALID_HARDWARE_ADDRESS && hwRegionEnd != INVALID_HARDWARE_ADDRESS) {
|
||||
MemoryRegion region = { hwRegionStart, regionSearchGranularity + (hwRegionEnd - hwRegionStart) };
|
||||
s_activeMemoryRegions.push_back(region);
|
||||
}
|
||||
|
||||
hwRegionStart = 0;
|
||||
regionStart = NULL;
|
||||
regionEnd = NULL;
|
||||
hwRegionStart = INVALID_HARDWARE_ADDRESS;
|
||||
hwRegionEnd = INVALID_HARDWARE_ADDRESS;
|
||||
}
|
||||
if(swAddr)
|
||||
{
|
||||
if(regionStart)
|
||||
{
|
||||
else {
|
||||
if (hwRegionStart != INVALID_HARDWARE_ADDRESS) {
|
||||
// continue region
|
||||
regionEnd = swAddr;
|
||||
hwRegionEnd = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// start new region
|
||||
hwRegionStart = addr;
|
||||
regionStart = swAddr;
|
||||
regionEnd = swAddr;
|
||||
hwRegionEnd = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +136,6 @@ void ResetMemoryRegions()
|
|||
{
|
||||
MemoryRegion& region = *iter;
|
||||
region.virtualIndex = nextVirtualIndex;
|
||||
assert(((intptr_t)region.softwareAddress & 1) == 0 && "somebody needs to reimplement ReadValueAtSoftwareAddress()");
|
||||
nextVirtualIndex = region.virtualIndex + region.size;
|
||||
}
|
||||
//assert(nextVirtualIndex <= MAX_RAM_SIZE);
|
||||
|
@ -223,7 +184,6 @@ int DeactivateRegion(MemoryRegion& region, MemoryList::iterator& iter, HWAddress
|
|||
int eraseSize = (hardwareAddress + size) - region.hardwareAddress;
|
||||
region.hardwareAddress += eraseSize;
|
||||
region.size -= eraseSize;
|
||||
region.softwareAddress += eraseSize;
|
||||
region.virtualIndex += eraseSize;
|
||||
return 1;
|
||||
}
|
||||
|
@ -238,7 +198,7 @@ int DeactivateRegion(MemoryRegion& region, MemoryList::iterator& iter, HWAddress
|
|||
{
|
||||
// split region
|
||||
int eraseSize = (hardwareAddress + size) - region.hardwareAddress;
|
||||
MemoryRegion region2 = {region.hardwareAddress + eraseSize, region.size - eraseSize, region.softwareAddress + eraseSize, region.virtualIndex + eraseSize};
|
||||
MemoryRegion region2 = {region.hardwareAddress + eraseSize, region.size - eraseSize, region.virtualIndex + eraseSize};
|
||||
region.size = hardwareAddress - region.hardwareAddress;
|
||||
iter = s_activeMemoryRegions.insert(++iter, region2);
|
||||
s_itemIndicesInvalid = TRUE;
|
||||
|
@ -298,7 +258,7 @@ void UpdateRegionT(const MemoryRegion& region, const MemoryRegion* nextRegionPtr
|
|||
unsigned int startSkipSize = ((unsigned int)(sizeof(stepType) - region.hardwareAddress)) % sizeof(stepType);
|
||||
|
||||
|
||||
unsigned char* sourceAddr = region.softwareAddress - region.virtualIndex;
|
||||
HWAddressType hwSourceAddr = region.hardwareAddress - region.virtualIndex;
|
||||
|
||||
unsigned int indexStart = region.virtualIndex + startSkipSize;
|
||||
unsigned int indexEnd = region.virtualIndex + region.size;
|
||||
|
@ -307,9 +267,9 @@ void UpdateRegionT(const MemoryRegion& region, const MemoryRegion* nextRegionPtr
|
|||
{
|
||||
for(unsigned int i = indexStart; i < indexEnd; i++)
|
||||
{
|
||||
if(s_curValues[i] != sourceAddr[i]) // if value changed
|
||||
if(s_curValues[i] != ReadValueAtHardwareAddress(hwSourceAddr+i, 1)) // if value changed
|
||||
{
|
||||
s_curValues[i] = sourceAddr[i]; // update value
|
||||
s_curValues[i] = ReadValueAtHardwareAddress(hwSourceAddr+i, 1); // update value
|
||||
//if(s_numChanges[i] != 0xFFFF)
|
||||
s_numChanges[i]++; // increase change count
|
||||
}
|
||||
|
@ -338,10 +298,10 @@ void UpdateRegionT(const MemoryRegion& region, const MemoryRegion* nextRegionPtr
|
|||
|
||||
for(unsigned int i = indexStart, j = 0; i < lastIndexToRead; i++, j++)
|
||||
{
|
||||
if(s_curValues[i] != sourceAddr[i]) // if value of this byte changed
|
||||
if(s_curValues[i] != ReadValueAtHardwareAddress(hwSourceAddr+i, 1)) // if value of this byte changed
|
||||
{
|
||||
if(i < lastIndexToCopy)
|
||||
s_curValues[i] = sourceAddr[i]; // update value
|
||||
s_curValues[i] = ReadValueAtHardwareAddress(hwSourceAddr+i, 1); // update value
|
||||
for(int k = 0; k < sizeof(compareType); k++) // loop through the previous entries that contain this byte
|
||||
{
|
||||
if(i >= indexEnd+k)
|
||||
|
@ -425,7 +385,6 @@ void ItemIndexToVirtualRegion(unsigned int itemIndex, MemoryRegion& virtualRegio
|
|||
|
||||
virtualRegion.size = sizeof(compareType);
|
||||
virtualRegion.hardwareAddress = region.hardwareAddress + bytesWithinRegion;
|
||||
virtualRegion.softwareAddress = region.softwareAddress + bytesWithinRegion;
|
||||
virtualRegion.virtualIndex = region.virtualIndex + bytesWithinRegion;
|
||||
virtualRegion.itemIndex = itemIndex;
|
||||
return;
|
||||
|
@ -948,55 +907,41 @@ bool IsSatisfied(int itemIndex)
|
|||
|
||||
|
||||
|
||||
unsigned int ReadValueAtSoftwareAddress(const unsigned char* address, unsigned int size, int byteSwapped = false)
|
||||
unsigned int ReadValueAtSoftwareAddress(const unsigned char* address, unsigned int size)
|
||||
{
|
||||
unsigned int value = 0;
|
||||
if(!byteSwapped)
|
||||
//if(!byteSwapped)
|
||||
{
|
||||
// assumes we're little-endian
|
||||
memcpy(&value, address, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// byte-swap and convert to current endianness at the same time
|
||||
for(unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
value <<= 8;
|
||||
value |= *((unsigned char*)((intptr_t)address++^1));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
void WriteValueAtSoftwareAddress(unsigned char* address, unsigned int value, unsigned int size, int byteSwapped = false)
|
||||
void WriteValueAtSoftwareAddress(unsigned char* address, unsigned int value, unsigned int size)
|
||||
{
|
||||
if(!byteSwapped)
|
||||
//if(!byteSwapped)
|
||||
{
|
||||
// assumes we're little-endian
|
||||
memcpy(address, &value, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// write as big endian
|
||||
for(int i = size-1; i >= 0; i--)
|
||||
{
|
||||
address[i] = value & 0xFF;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned int ReadValueAtHardwareAddress(HWAddressType address, unsigned int size)
|
||||
{
|
||||
return ReadValueAtSoftwareAddress(HardwareToSoftwareAddress(address), size);
|
||||
unsigned int value = 0;
|
||||
|
||||
// read as little endian
|
||||
for(unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
value <<= 8;
|
||||
value |= (IsHardwareAddressValid(address) ? GetMem(address) : 0);
|
||||
address++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
bool WriteValueAtHardwareAddress(HWAddressType address, unsigned int value, unsigned int size)
|
||||
{
|
||||
// FIXME: doesn't work for now. see HardwareToSoftwareAddress to know why.
|
||||
WriteValueAtSoftwareAddress(HardwareToSoftwareAddress(address), value, size);
|
||||
return true;
|
||||
}
|
||||
bool IsHardwareAddressValid(HWAddressType address)
|
||||
{
|
||||
return HardwareToSoftwareAddress(address) != NULL;
|
||||
// TODO: NYI
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,13 @@
|
|||
#include "zlib.h"
|
||||
#include "driver.h"
|
||||
|
||||
//TODO - we really need some kind of global platform-specific options api
|
||||
#ifdef WIN32
|
||||
#include "drivers/win/main.h"
|
||||
#include "drivers/win/ram_search.h"
|
||||
#include "drivers/win/ramwatch.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void (*SPreSave)(void);
|
||||
|
@ -703,6 +710,9 @@ bool FCEUSS_Load(const char *fname)
|
|||
SaveStateStatus[CurrentState]=1;
|
||||
}
|
||||
delete st;
|
||||
#ifdef WIN32
|
||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue