Updated documentation for missing commandline arguments.

Added infrastructure to System and Device classes to deal with CodeAccessBase
even when the bankswitching scheme bypasses the normal System::PageAccess
way of reading ROM space.  This allows bankswitching schemes 2E, AR, FE and
4A50 to support emulation core 'hints' for more accurate disassembly.  The
only scheme not supported now is MC, which isn't really working anyway (I've
never actually had a test ROM for this scheme).

It's getting close, folks ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2184 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-11-11 22:24:51 +00:00
parent c9ab109524
commit ba1019a308
11 changed files with 183 additions and 23 deletions

View File

@ -2000,6 +2000,17 @@
disassembler. See the Debugger section for more information.</td>
</tr>
<tr>
<td><pre>-gfxformat &lt;2|16&gt;</pre></td>
<td>Sets the base to use for displaying GFX sections in the disassembler.
</td>
</tr>
<tr>
<td><pre>-showaddr &lt;1|0&gt;</pre></td>
<td>Shows/hides opcode addresses in the disassembler.</td>
</tr>
<tr>
<td><pre>-debuggerres &lt;WxH&gt;</pre></td>
<td>Set the size of the debugger window.</td>

View File

@ -24,8 +24,6 @@
#include "TIA.hxx"
#include "Cart3E.hxx"
// TODO (2010-10-10) - support CodeAccessBase functionality somehow
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size,
const Settings& settings)
@ -37,7 +35,7 @@ Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size,
// Copy the ROM image into my buffer
memcpy(myImage, image, mySize);
createCodeAccessBase(mySize);
createCodeAccessBase(mySize + 32768);
// This cart can address a 1024 byte bank of RAM @ 0x1000
// However, it may not be addressable all the time (it may be swapped out)
@ -210,6 +208,7 @@ bool Cartridge3E::bank(uInt16 bank)
for(address = 0x1000; address < 0x1400; address += (1 << shift))
{
access.directPeekBase = &myRam[offset + (address & 0x03FF)];
access.codeAccessBase = &myCodeAccessBase[mySize + offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
@ -220,6 +219,7 @@ bool Cartridge3E::bank(uInt16 bank)
for(address = 0x1400; address < 0x1800; address += (1 << shift))
{
access.directPokeBase = &myRam[offset + (address & 0x03FF)];
access.codeAccessBase = &myCodeAccessBase[mySize + offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
}

View File

@ -25,8 +25,6 @@
#include "TIA.hxx"
#include "Cart4A50.hxx"
// TODO (2010-10-03) - support CodeAccessBase functionality somehow
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4A50::Cartridge4A50(const uInt8* image, uInt32 size,
const Settings& settings)
@ -39,6 +37,15 @@ Cartridge4A50::Cartridge4A50(const uInt8* image, uInt32 size,
else size = 131072;
for(uInt32 slice = 0; slice < 131072 / size; ++slice)
memcpy(myImage + (slice*size), image, size);
// We use System::PageAccess.codeAccessBase, but don't allow its use
// through a pointer, since the address space of 4A50 carts can change
// at the instruction level, and PageAccess is normally defined at an
// interval of 64 bytes
//
// Instead, access will be through the getAccessFlags and setAccessFlags
// methods below
createCodeAccessBase(131072 + 32768);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -194,6 +201,69 @@ bool Cartridge4A50::poke(uInt16 address, uInt8 value)
return myBankChanged;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Cartridge4A50::getAccessFlags(uInt16 address)
{
if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff
{
if(myIsRomLow)
return myCodeAccessBase[(address & 0x7ff) + mySliceLow];
else
return myCodeAccessBase[131072 + (address & 0x7ff) + mySliceLow];
}
else if(((address & 0x1fff) >= 0x1800) && // 1.5K region from 0x1800 - 0x1dff
((address & 0x1fff) <= 0x1dff))
{
if(myIsRomMiddle)
return myCodeAccessBase[(address & 0x7ff) + mySliceMiddle + 0x10000];
else
return myCodeAccessBase[131072 + (address & 0x7ff) + mySliceMiddle];
}
else if((address & 0x1f00) == 0x1e00) // 256B region from 0x1e00 - 0x1eff
{
if(myIsRomHigh)
return myCodeAccessBase[(address & 0xff) + mySliceHigh + 0x10000];
else
return myCodeAccessBase[131072 + (address & 0xff) + mySliceHigh];
}
else if((address & 0x1f00) == 0x1f00) // 256B region from 0x1f00 - 0x1fff
{
return myCodeAccessBase[(address & 0xff) + 0x1ff00];
}
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::setAccessFlags(uInt16 address, uInt8 flags)
{
if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff
{
if(myIsRomLow)
myCodeAccessBase[(address & 0x7ff) + mySliceLow] |= flags;
else
myCodeAccessBase[131072 + (address & 0x7ff) + mySliceLow] |= flags;
}
else if(((address & 0x1fff) >= 0x1800) && // 1.5K region from 0x1800 - 0x1dff
((address & 0x1fff) <= 0x1dff))
{
if(myIsRomMiddle)
myCodeAccessBase[(address & 0x7ff) + mySliceMiddle + 0x10000] |= flags;
else
myCodeAccessBase[131072 + (address & 0x7ff) + mySliceMiddle] |= flags;
}
else if((address & 0x1f00) == 0x1e00) // 256B region from 0x1e00 - 0x1eff
{
if(myIsRomHigh)
myCodeAccessBase[(address & 0xff) + mySliceHigh + 0x10000] |= flags;
else
myCodeAccessBase[131072 + (address & 0xff) + mySliceHigh] |= flags;
}
else if((address & 0x1f00) == 0x1f00) // 256B region from 0x1f00 - 0x1fff
{
myCodeAccessBase[(address & 0xff) + 0x1ff00] |= flags;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
{

View File

@ -152,6 +152,15 @@ class Cartridge4A50 : public Cartridge
bool poke(uInt16 address, uInt8 value);
private:
/**
Query/change the given address type to use the given disassembly flags
@param address The address to modify
@param flags A bitfield of DisasmType directives for the given address
*/
uInt8 getAccessFlags(uInt16 address);
void setAccessFlags(uInt16 address, uInt8 flags);
/**
Check all possible hotspots
*/

View File

@ -24,25 +24,29 @@
#include "System.hxx"
#include "CartAR.hxx"
// TODO (2010-10-03) - support CodeAccessBase functionality somehow
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeAR::CartridgeAR(const uInt8* image, uInt32 size,
const Settings& settings)
: Cartridge(settings),
my6502(0)
my6502(0),
mySize(BSPF_max(size, 8448u))
{
// Minimum size supported internally is 8448 bytes
uInt32 minsize = BSPF_max(size, 8448u);
// Create a load image buffer and copy the given image
myLoadImages = new uInt8[minsize];
myNumberOfLoadImages = minsize / 8448;
myLoadImages = new uInt8[mySize];
myNumberOfLoadImages = mySize / 8448;
memcpy(myLoadImages, image, size);
// Add header if image doesn't include it
if(size < 8448)
memcpy(myLoadImages+8192, ourDefaultHeader, 256);
// We use System::PageAccess.codeAccessBase, but don't allow its use
// through a pointer, since the AR scheme doesn't support bankswitching
// in the normal sense
//
// Instead, access will be through the getAccessFlags and setAccessFlags
// methods below
createCodeAccessBase(mySize);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -216,6 +220,20 @@ bool CartridgeAR::poke(uInt16 addr, uInt8)
return modified;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeAR::getAccessFlags(uInt16 address)
{
return myCodeAccessBase[(address & 0x07FF) +
myImageOffset[(address & 0x0800) ? 1 : 0]];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeAR::setAccessFlags(uInt16 address, uInt8 flags)
{
myCodeAccessBase[(address & 0x07FF) +
myImageOffset[(address & 0x0800) ? 1 : 0]] |= flags;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeAR::bankConfiguration(uInt8 configuration)
{
@ -440,7 +458,7 @@ bool CartridgeAR::patch(uInt16 address, uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* CartridgeAR::getImage(int& size) const
{
size = myNumberOfLoadImages * 8448;
size = mySize;
return myLoadImages;
}

View File

@ -151,6 +151,15 @@ class CartridgeAR : public Cartridge
bool poke(uInt16 address, uInt8 value);
private:
/**
Query/change the given address type to use the given disassembly flags
@param address The address to modify
@param flags A bitfield of DisasmType directives for the given address
*/
uInt8 getAccessFlags(uInt16 address);
void setAccessFlags(uInt16 address, uInt8 flags);
// Handle a change to the bank configuration
bool bankConfiguration(uInt8 configuration);
@ -176,6 +185,9 @@ class CartridgeAR : public Cartridge
// The 256 byte header for the current 8448 byte load
uInt8 myHeader[256];
// Size of the ROM image
uInt32 mySize;
// All of the 8448 byte loads associated with the game
uInt8* myLoadImages;

View File

@ -23,8 +23,6 @@
#include "System.hxx"
#include "CartFE.hxx"
// TODO (2010-10-03) - support CodeAccessBase functionality somehow
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeFE::CartridgeFE(const uInt8* image, const Settings& settings)
: Cartridge(settings),
@ -34,6 +32,15 @@ CartridgeFE::CartridgeFE(const uInt8* image, const Settings& settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, 8192);
// We use System::PageAccess.codeAccessBase, but don't allow its use
// through a pointer, since the address space of FE carts can change
// at the instruction level, and PageAccess is normally defined at an
// interval of 64 bytes
//
// Instead, access will be through the getAccessFlags and setAccessFlags
// methods below
createCodeAccessBase(8192);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -82,6 +89,20 @@ bool CartridgeFE::poke(uInt16, uInt8)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeFE::getAccessFlags(uInt16 address)
{
return myCodeAccessBase[(address & 0x0FFF) +
(((address & 0x2000) == 0) ? 4096 : 0)];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeFE::setAccessFlags(uInt16 address, uInt8 flags)
{
myCodeAccessBase[(address & 0x0FFF) +
(((address & 0x2000) == 0) ? 4096 : 0)] |= flags;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeFE::bank(uInt16)
{

View File

@ -159,6 +159,16 @@ class CartridgeFE : public Cartridge
*/
bool poke(uInt16 address, uInt8 value);
private:
/**
Query/change the given address type to use the given disassembly flags
@param address The address to modify
@param flags A bitfield of DisasmType directives for the given address
*/
uInt8 getAccessFlags(uInt16 address);
void setAccessFlags(uInt16 address, uInt8 flags);
private:
// The 8K ROM image of the cartridge
uInt8 myImage[8192];

View File

@ -111,6 +111,15 @@ class Device : public Serializable
*/
virtual bool poke(uInt16 address, uInt8 value) = 0;
/**
Query/change the given address type to use the given disassembly flags
@param address The address to modify
@param flags A bitfield of DisasmType directives for the given address
*/
virtual uInt8 getAccessFlags(uInt16 address) { return 0; }
virtual void setAccessFlags(uInt16 address, uInt8 flags) { }
protected:
/// Pointer to the system the device is installed in or the null pointer
System* mySystem;

View File

@ -101,5 +101,5 @@ class NullDevice : public Device
*/
bool poke(uInt16 address, uInt8 value);
};
#endif

View File

@ -220,18 +220,16 @@ uInt8 System::peek(uInt16 addr, uInt8 flags)
// Set access type
if(access.codeAccessBase)
*(access.codeAccessBase + (addr & myPageMask)) |= flags;
else
access.device->setAccessFlags(addr, flags);
#endif
// See if this page uses direct accessing or not
uInt8 result;
if(access.directPeekBase)
{
result = *(access.directPeekBase + (addr & myPageMask));
}
else
{
result = access.device->peek(addr);
}
#ifdef DEBUGGER_SUPPORT
if(!myDataBusLocked)
@ -248,7 +246,7 @@ void System::poke(uInt16 addr, uInt8 value)
PageAccess& access = myPageAccessTable[page];
// See if this page uses direct accessing or not
if(access.directPokeBase != 0)
if(access.directPokeBase)
{
// Since we have direct access to this poke, we can dirty its page
*(access.directPokeBase + (addr & myPageMask)) = value;
@ -275,7 +273,7 @@ uInt8 System::getAddressDisasmType(uInt16 addr)
if(access.codeAccessBase)
return *(access.codeAccessBase + (addr & myPageMask));
else
return 0;
return access.device->getAccessFlags(addr);
#else
return 0;
#endif
@ -289,6 +287,8 @@ void System::setAddressDisasmType(uInt16 addr, uInt8 flags)
if(access.codeAccessBase)
*(access.codeAccessBase + (addr & myPageMask)) |= flags;
else
access.device->setAccessFlags(addr, flags);
#endif
}