win32: fix new ramsearch

This commit is contained in:
gocha 2009-10-08 08:06:45 +00:00
parent 585cb80257
commit 197322bcf1
2 changed files with 55 additions and 100 deletions

View File

@ -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;
}

View File

@ -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