From 197322bcf1d3a6b05ea4e41c699306b9e68973a3 Mon Sep 17 00:00:00 2001 From: gocha Date: Thu, 8 Oct 2009 08:06:45 +0000 Subject: [PATCH] win32: fix new ramsearch --- src/drivers/win/ram_search.cpp | 145 ++++++++++----------------------- src/state.cpp | 10 +++ 2 files changed, 55 insertions(+), 100 deletions(-) diff --git a/src/drivers/win/ram_search.cpp b/src/drivers/win/ram_search.cpp index 1a7a0d58..188a3c8d 100644 --- a/src/drivers/win/ram_search.cpp +++ b/src/drivers/win/ram_search.cpp @@ -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; } diff --git a/src/state.cpp b/src/state.cpp index 6ab99cfe..7a6a0f48 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -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