mirror of https://github.com/stella-emu/stella.git
First pass at adding a 'dirty page' infrastructure to the System class.
The idea is that all direct-access pokes will set a flag indicating that the page containing the poked address is set to be dirty. Devices that handle their own pokes will have to be updated to set this dirty flag too. Overall, the point is to enable the debugger to know whether cart space has been modified, and use that knowledge to selectively do a re-disassembly. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1973 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
4ca87ba76b
commit
2b384e2353
|
@ -44,8 +44,9 @@ System::System(uInt16 n, uInt16 m)
|
||||||
// Create a new random number generator
|
// Create a new random number generator
|
||||||
myRandom = new Random();
|
myRandom = new Random();
|
||||||
|
|
||||||
// Allocate page table
|
// Allocate page table and dirty list
|
||||||
myPageAccessTable = new PageAccess[myNumberOfPages];
|
myPageAccessTable = new PageAccess[myNumberOfPages];
|
||||||
|
myPageIsDirtyTable = new bool[myNumberOfPages];
|
||||||
|
|
||||||
// Initialize page access table
|
// Initialize page access table
|
||||||
PageAccess access;
|
PageAccess access;
|
||||||
|
@ -73,8 +74,9 @@ System::~System()
|
||||||
// Free the M6502 that I own
|
// Free the M6502 that I own
|
||||||
delete myM6502;
|
delete myM6502;
|
||||||
|
|
||||||
// Free my page access table
|
// Free my page access table and dirty list
|
||||||
delete[] myPageAccessTable;
|
delete[] myPageAccessTable;
|
||||||
|
delete[] myPageIsDirtyTable;
|
||||||
|
|
||||||
// Free the random number generator
|
// Free the random number generator
|
||||||
delete myRandom;
|
delete myRandom;
|
||||||
|
@ -172,6 +174,32 @@ const System::PageAccess& System::getPageAccess(uInt16 page)
|
||||||
return myPageAccessTable[page];
|
return myPageAccessTable[page];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void System::setDirtyAddress(uInt16 addr)
|
||||||
|
{
|
||||||
|
myPageIsDirtyTable[(addr & myAddressMask) >> myPageShift] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool System::isDirtyRange(uInt16 start_addr, uInt16 end_addr)
|
||||||
|
{
|
||||||
|
uInt16 start_page = (start_addr & myAddressMask) >> myPageShift;
|
||||||
|
uInt16 end_page = (end_addr & myAddressMask) >> myPageShift;
|
||||||
|
|
||||||
|
for(uInt16 page = start_page; page <= end_page; ++page)
|
||||||
|
if(myPageIsDirtyTable[page])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void System::clearDirtyAddresses()
|
||||||
|
{
|
||||||
|
for(uInt32 i = 0; i < myNumberOfPages; ++i)
|
||||||
|
myPageIsDirtyTable[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
System::System(const System& s)
|
System::System(const System& s)
|
||||||
: myAddressMask(s.myAddressMask),
|
: myAddressMask(s.myAddressMask),
|
||||||
|
@ -218,15 +246,21 @@ uInt8 System::peek(uInt16 addr)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void System::poke(uInt16 addr, uInt8 value)
|
void System::poke(uInt16 addr, uInt8 value)
|
||||||
{
|
{
|
||||||
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
|
uInt16 page = (addr & myAddressMask) >> myPageShift;
|
||||||
|
PageAccess& access = myPageAccessTable[page];
|
||||||
|
|
||||||
// See if this page uses direct accessing or not
|
// See if this page uses direct accessing or not
|
||||||
if(access.directPokeBase != 0)
|
if(access.directPokeBase != 0)
|
||||||
{
|
{
|
||||||
|
// Since we have direct access to this poke, we can dirty its page
|
||||||
|
myPageIsDirtyTable[page] = true;
|
||||||
*(access.directPokeBase + (addr & myPageMask)) = value;
|
*(access.directPokeBase + (addr & myPageMask)) = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// The specific device is responsible for setting the dirty flag
|
||||||
|
// We can't automatically set it, since not all pokes actually
|
||||||
|
// succeed and modify a page
|
||||||
access.device->poke(addr, value);
|
access.device->poke(addr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,6 +269,11 @@ class System : public Serializable
|
||||||
No masking of the address occurs before it's sent to the device
|
No masking of the address occurs before it's sent to the device
|
||||||
mapped at the address.
|
mapped at the address.
|
||||||
|
|
||||||
|
This method sets the 'page dirty' flag for direct-access pokes.
|
||||||
|
If the device has taken responsibility for handling the poke,
|
||||||
|
it must also update the 'page dirty' flag with a call to
|
||||||
|
System::setDirtyAddress().
|
||||||
|
|
||||||
@param address The address where the value should be stored
|
@param address The address where the value should be stored
|
||||||
@param value The value to be stored at the address
|
@param value The value to be stored at the address
|
||||||
*/
|
*/
|
||||||
|
@ -331,6 +336,27 @@ class System : public Serializable
|
||||||
*/
|
*/
|
||||||
const PageAccess& getPageAccess(uInt16 page);
|
const PageAccess& getPageAccess(uInt16 page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark the page containing this address as being dirty.
|
||||||
|
|
||||||
|
@param addr Determines the page that is dirty
|
||||||
|
*/
|
||||||
|
void setDirtyAddress(uInt16 addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Answer whether any pages in given range of addresses have been
|
||||||
|
marked as dirty.
|
||||||
|
|
||||||
|
@param start_addr The start address; determines the start page
|
||||||
|
@param end_addr The end address; determines the end page
|
||||||
|
*/
|
||||||
|
bool isDirtyRange(uInt16 start_addr, uInt16 end_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark all pages as clean (ie, turn off the dirty flag).
|
||||||
|
*/
|
||||||
|
void clearDirtyAddresses();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Save the current state of this system to the given Serializer.
|
Save the current state of this system to the given Serializer.
|
||||||
|
|
||||||
|
@ -370,6 +396,9 @@ class System : public Serializable
|
||||||
// Pointer to a dynamically allocated array of PageAccess structures
|
// Pointer to a dynamically allocated array of PageAccess structures
|
||||||
PageAccess* myPageAccessTable;
|
PageAccess* myPageAccessTable;
|
||||||
|
|
||||||
|
// Pointer to a dynamically allocated array for dirty pages
|
||||||
|
bool* myPageIsDirtyTable;
|
||||||
|
|
||||||
// Array of all the devices attached to the system
|
// Array of all the devices attached to the system
|
||||||
Device* myDevices[100];
|
Device* myDevices[100];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue