mirror of https://github.com/stella-emu/stella.git
Greatly improved the disassembler output, but having Stella keep track of
addresses used as part of code execution (ie, from the PC) during emulation. This gives Distella much more information than can be determined from a static analysis alone, resulting in an extremely accurate disassembly. This also allows to generate very accurate debugger .cfg files. Not all carts have been ported to this new scheme yet, particularly ones having extended RAM that can be mapped out dynamically. Note that this new scheme doubles the amount of RAM used for storing ROM images, so up to 128KB extra will be used. There's also a small runtime check for each instruction executed. Preliminary testing doesn't show any slowdowns, but we'll see how it goes. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2138 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
d6a38c8e44
commit
5fe91e2841
|
@ -53,6 +53,7 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
|
|||
myBankInfo.push_back(info);
|
||||
|
||||
// We know the address for the startup bank right now
|
||||
cerr << "start @ " << HEX4 << myDebugger.dpeek(0xfffc) << endl;
|
||||
myBankInfo[myConsole.cartridge().startBank()].addressList.push_back(myDebugger.dpeek(0xfffc));
|
||||
addLabel("START", myDebugger.dpeek(0xfffc));
|
||||
|
||||
|
|
|
@ -284,6 +284,7 @@ class Debugger : public DialogContainer
|
|||
/* These are now exposed so Expressions can use them. */
|
||||
int peek(int addr) { return mySystem->peek(addr); }
|
||||
int dpeek(int addr) { return mySystem->peek(addr) | (mySystem->peek(addr+1) << 8); }
|
||||
int isCode(int addr) { return mySystem->isCode(addr); }
|
||||
|
||||
void setBreakPoint(int bp, bool set);
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
|
|||
|
||||
if(resolvedata)
|
||||
{
|
||||
// After we've disassembled from the start address, use all access points
|
||||
// determined by Stella during emulation
|
||||
int codeAccessPoint = 0;
|
||||
|
||||
while(!myAddressQueue.empty())
|
||||
{
|
||||
myPC = myAddressQueue.front();
|
||||
|
@ -99,31 +103,29 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
|
|||
for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
|
||||
mark(k, REACHABLE);
|
||||
|
||||
// When we get to this point, all addresses have been processed
|
||||
// starting from the initial one in the address list
|
||||
// If so, process the next one in the list that hasn't already
|
||||
// been marked as REACHABLE
|
||||
// If it *has* been marked, it can be removed from consideration
|
||||
// in all subsequent passes
|
||||
// When we get to this point, the 'start' address has been processed
|
||||
// Next we process all addresses determined during emulation to represent
|
||||
// code, which *haven't* already been considered
|
||||
//
|
||||
// Note that we can't simply add all addresses right away, since
|
||||
// the processing of a single address from the address list can
|
||||
// cause others to be added in the ::disasm method
|
||||
// All of these have to be exhausted before consulting the address
|
||||
// list again
|
||||
// the processing of a single address can cause others to be added in
|
||||
// the ::disasm method
|
||||
// All of these have to be exhausted before considering a new address
|
||||
if(myAddressQueue.empty())
|
||||
{
|
||||
while(it != addresses.end())
|
||||
// Stella itself can provide hints on whether an address has ever
|
||||
// been referenced as CODE
|
||||
while(codeAccessPoint <= myAppData.end)
|
||||
{
|
||||
uInt16 addr = *it;
|
||||
if(!check_bit(labels[addr-myOffset], REACHABLE))
|
||||
if(Debugger::debugger().isCode(codeAccessPoint+myOffset) &&
|
||||
!check_bit(labels[codeAccessPoint], REACHABLE))
|
||||
{
|
||||
myAddressQueue.push(addr);
|
||||
++it;
|
||||
cerr << "marking " << hex << (codeAccessPoint+myOffset) << " as CODE\n";
|
||||
myAddressQueue.push(codeAccessPoint+myOffset);
|
||||
++codeAccessPoint;
|
||||
break;
|
||||
}
|
||||
else // remove this address, it is redundant
|
||||
it = addresses.erase(it);
|
||||
++codeAccessPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ Cartridge::Cartridge(const Settings& settings)
|
|||
: mySettings(settings),
|
||||
myStartBank(0),
|
||||
myBankChanged(true),
|
||||
myCodeAccessBase(NULL),
|
||||
myBankLocked(false)
|
||||
{
|
||||
}
|
||||
|
@ -238,6 +239,8 @@ Cartridge::Cartridge(const Settings& settings)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge::~Cartridge()
|
||||
{
|
||||
if(myCodeAccessBase)
|
||||
delete[] myCodeAccessBase;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -294,6 +297,17 @@ void Cartridge::triggerReadFromWritePort(uInt16 address)
|
|||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge::createCodeAccessBase(uInt32 size)
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myCodeAccessBase = new uInt8[size];
|
||||
memset(myCodeAccessBase, 0, size);
|
||||
#else
|
||||
myCodeAccessBase = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
||||
{
|
||||
|
|
|
@ -207,6 +207,15 @@ class Cartridge : public Device
|
|||
*/
|
||||
void triggerReadFromWritePort(uInt16 address);
|
||||
|
||||
/**
|
||||
Create an array that holds code-access information for every byte
|
||||
of the ROM (indicated by 'size'). Note that this is only used by
|
||||
the debugger, and is unavailable otherwise.
|
||||
|
||||
@param size The size of the code-access array to create
|
||||
*/
|
||||
void createCodeAccessBase(uInt32 size);
|
||||
|
||||
private:
|
||||
/**
|
||||
Get an image pointer and size for a ROM that is part of a larger,
|
||||
|
@ -332,6 +341,10 @@ class Cartridge : public Device
|
|||
// Indicates if the bank has changed somehow (a bankswitch has occurred)
|
||||
bool myBankChanged;
|
||||
|
||||
// The array containing information about every byte of ROM indicating
|
||||
// whether it is used as code.
|
||||
uInt8* myCodeAccessBase;
|
||||
|
||||
private:
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// Contains RamArea entries for those carts with accessible RAM.
|
||||
|
|
|
@ -29,6 +29,7 @@ Cartridge0840::Cartridge0840(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 8192);
|
||||
createCodeAccessBase(8192);
|
||||
|
||||
// Remember startup bank
|
||||
myStartBank = 0;
|
||||
|
@ -68,11 +69,7 @@ void Cartridge0840::install(System& system)
|
|||
myHotSpotPageAccess[7] = mySystem->getPageAccess(0x0F00 >> shift);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
for(uInt32 i = 0x0800; i < 0x0FFF; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
@ -157,15 +154,13 @@ bool Cartridge0840::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -47,6 +47,7 @@ Cartridge2K::Cartridge2K(const uInt8* image, uInt32 size, const Settings& settin
|
|||
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, size);
|
||||
createCodeAccessBase(mySize);
|
||||
|
||||
// Set mask for accessing the image buffer
|
||||
// This is guaranteed to work, as mySize is a power of two
|
||||
|
@ -76,14 +77,12 @@ void Cartridge2K::install(System& system)
|
|||
assert((0x1000 & mask) == 0);
|
||||
|
||||
// Map ROM image into the system
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[address & myMask];
|
||||
access.codeAccessBase = &myCodeAccessBase[address & myMask];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "TIA.hxx"
|
||||
#include "Cart3E.hxx"
|
||||
|
||||
// TODO - add support for code stored in RAM
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size,
|
||||
const Settings& settings)
|
||||
|
@ -35,6 +37,7 @@ Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size,
|
|||
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, mySize);
|
||||
createCodeAccessBase(mySize);
|
||||
|
||||
// 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)
|
||||
|
@ -75,26 +78,21 @@ void Cartridge3E::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1800 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READWRITE);
|
||||
|
||||
// Set the page accessing methods for the hot spots (for 100% emulation
|
||||
// we need to chain any accesses below 0x40 to the TIA. Our poke() method
|
||||
// does this via mySystem->tiaPoke(...), at least until we come up with a
|
||||
// cleaner way to do it).
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READWRITE;
|
||||
for(uInt32 i = 0x00; i < 0x40; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 j = 0x1800; j < 0x2000; j += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[(mySize - 2048) + (j & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[(mySize - 2048) + (j & 0x07FF)];
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -185,15 +183,13 @@ bool Cartridge3E::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x1800; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x07FF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
}
|
||||
|
@ -208,10 +204,7 @@ bool Cartridge3E::bank(uInt16 bank)
|
|||
uInt32 address;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map read-port RAM image into the system
|
||||
for(address = 0x1000; address < 0x1400; address += (1 << shift))
|
||||
|
|
|
@ -35,6 +35,7 @@ Cartridge3F::Cartridge3F(const uInt8* image, uInt32 size,
|
|||
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, mySize);
|
||||
createCodeAccessBase(mySize);
|
||||
|
||||
// Remember startup bank
|
||||
myStartBank = 0;
|
||||
|
@ -63,25 +64,21 @@ void Cartridge3F::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1800 & mask) == 0);
|
||||
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READWRITE);
|
||||
|
||||
// Set the page accessing methods for the hot spots (for 100% emulation
|
||||
// we need to chain any accesses below 0x40 to the TIA. Our poke() method
|
||||
// does this via mySystem->tiaPoke(...), at least until we come up with a
|
||||
// cleaner way to do it).
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READWRITE;
|
||||
for(uInt32 i = 0x00; i < 0x40; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 j = 0x1800; j < 0x2000; j += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[(mySize - 2048) + (j & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[(mySize - 2048) + (j & 0x07FF)];
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -145,15 +142,13 @@ bool Cartridge3F::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x1800; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x07FF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -73,12 +73,8 @@ void Cartridge4A50::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
// Map all of the accesses to call peek and poke
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ; // We don't yet indicate RAM areas
|
||||
// Map all of the accesses to call peek and poke (We don't yet indicate RAM areas)
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
|
|
@ -29,6 +29,7 @@ Cartridge4K::Cartridge4K(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 4096);
|
||||
createCodeAccessBase(4096);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -52,15 +53,13 @@ void Cartridge4K::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[address & 0x0FFF];
|
||||
access.codeAccessBase = &myCodeAccessBase[address & 0x0FFF];
|
||||
mySystem->setPageAccess(address >> mySystem->pageShift(), access);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,12 +96,8 @@ void CartridgeAR::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
// Map all of the accesses to call peek and poke
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ; // We don't yet indicate RAM areas
|
||||
// Map all of the accesses to call peek and poke (we don't yet indicate RAM areas)
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
|
|
@ -47,6 +47,7 @@ CartridgeCV::CartridgeCV(const uInt8* image, uInt32 size,
|
|||
myInitialRAM = new uInt8[1024];
|
||||
memcpy(myInitialRAM, image, 1024);
|
||||
}
|
||||
createCodeAccessBase(2048+1024);
|
||||
|
||||
// This cart contains 1024 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 1024, 0x00, 0x400);
|
||||
|
@ -89,21 +90,19 @@ void CartridgeCV::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1800 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 address = 0x1800; address < 0x2000; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[address & 0x07FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[address & 0x07FF];
|
||||
mySystem->setPageAccess(address >> mySystem->pageShift(), access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.codeAccessBase = 0;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1400; j < 0x1800; j += (1 << shift))
|
||||
{
|
||||
|
@ -113,11 +112,11 @@ void CartridgeCV::install(System& system)
|
|||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1000; k < 0x1400; k += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x03FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[2048 + (k & 0x03FF)];
|
||||
mySystem->setPageAccess(k >> shift, access);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,20 +89,13 @@ void CartridgeDPC::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the DPC reading & writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READWRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
|
@ -429,10 +422,7 @@ bool CartridgeDPC::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map Program ROM image into the system
|
||||
for(uInt32 address = 0x1080; address < (0x1FF8U & ~mask);
|
||||
|
|
|
@ -109,12 +109,9 @@ void CartridgeDPCPlus::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
|
||||
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map all of the accesses to call peek and poke
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
|
|
@ -58,12 +58,9 @@ void CartridgeE0::install(System& system)
|
|||
assert(((0x1000 & mask) == 0) && ((0x1400 & mask) == 0) &&
|
||||
((0x1800 & mask) == 0) && ((0x1C00 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page acessing methods for the first part of the last segment
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = 0x1C00; i < (0x1FE0U & ~mask); i += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[7168 + (i & 0x03FF)];
|
||||
|
@ -73,8 +70,6 @@ void CartridgeE0::install(System& system)
|
|||
|
||||
// Set the page accessing methods for the hot spots in the last segment
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 j = (0x1FE0 & ~mask); j < 0x2000; j += (1 << shift))
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
|
@ -139,10 +134,7 @@ void CartridgeE0::segmentZero(uInt16 slice)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1000; address < 0x1400; address += (1 << shift))
|
||||
{
|
||||
|
@ -163,10 +155,7 @@ void CartridgeE0::segmentOne(uInt16 slice)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1400; address < 0x1800; address += (1 << shift))
|
||||
{
|
||||
|
@ -187,10 +176,7 @@ void CartridgeE0::segmentTwo(uInt16 slice)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1800; address < 0x1C00; address += (1 << shift))
|
||||
{
|
||||
|
|
|
@ -74,20 +74,13 @@ void CartridgeE7::install(System& system)
|
|||
assert(((0x1400 & mask) == 0) && ((0x1800 & mask) == 0) &&
|
||||
((0x1900 & mask) == 0) && ((0x1A00 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 j = 0x1A00; j < (0x1FE0U & ~mask); j += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[7 * 2048 + (j & 0x07FF)];
|
||||
|
@ -178,12 +171,9 @@ void CartridgeE7::bankRAM(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_WRITE);
|
||||
|
||||
// Set the page accessing method for the 256 bytes of RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1800; j < 0x1900; j += (1 << shift))
|
||||
{
|
||||
access.directPokeBase = &myRAM[1024 + offset + (j & 0x00FF)];
|
||||
|
@ -192,7 +182,6 @@ void CartridgeE7::bankRAM(uInt16 bank)
|
|||
|
||||
// Set the page accessing method for the 256 bytes of RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1900; k < 0x1A00; k += (1 << shift))
|
||||
{
|
||||
|
@ -212,15 +201,12 @@ bool CartridgeE7::bank(uInt16 slice)
|
|||
uInt16 offset = slice << 11;
|
||||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
System::PageAccess access;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
if(slice != 7)
|
||||
{
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into first segment
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 address = 0x1000; address < 0x1800; address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x07FF)];
|
||||
|
@ -229,10 +215,9 @@ bool CartridgeE7::bank(uInt16 slice)
|
|||
}
|
||||
else
|
||||
{
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_WRITE);
|
||||
|
||||
// Set the page accessing method for the 1K slice of RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1400; j += (1 << shift))
|
||||
{
|
||||
access.directPokeBase = &myRAM[j & 0x03FF];
|
||||
|
@ -241,7 +226,6 @@ bool CartridgeE7::bank(uInt16 slice)
|
|||
|
||||
// Set the page accessing method for the 1K slice of RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1400; k < 0x1800; k += (1 << shift))
|
||||
{
|
||||
|
|
|
@ -56,13 +56,9 @@ void CartridgeEF::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -105,12 +101,8 @@ bool CartridgeEF::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
System::PageAccess access;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FE0U & ~mask);
|
||||
|
|
|
@ -66,19 +66,13 @@ void CartridgeEFSC::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
|
||||
{
|
||||
|
@ -88,7 +82,6 @@ void CartridgeEFSC::install(System& system)
|
|||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
|
||||
{
|
||||
|
@ -154,10 +147,7 @@ bool CartridgeEFSC::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1100; address < (0x1FE0U & ~mask);
|
||||
|
|
|
@ -57,13 +57,9 @@ void CartridgeF0::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF0 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -109,10 +105,7 @@ void CartridgeF0::incbank()
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FF0U & ~mask);
|
||||
|
|
|
@ -30,6 +30,7 @@ CartridgeF4::CartridgeF4(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 32768);
|
||||
createCodeAccessBase(32768);
|
||||
|
||||
// Remember startup bank
|
||||
myStartBank = 0;
|
||||
|
@ -57,13 +58,9 @@ void CartridgeF4::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -111,16 +108,14 @@ bool CartridgeF4::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FF4U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -29,6 +29,7 @@ CartridgeF4SC::CartridgeF4SC(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 32768);
|
||||
createCodeAccessBase(32768);
|
||||
|
||||
// This cart contains 128 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 128, 0x80, 0x00);
|
||||
|
@ -66,19 +67,13 @@ void CartridgeF4SC::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
|
||||
{
|
||||
|
@ -88,11 +83,11 @@ void CartridgeF4SC::install(System& system)
|
|||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x007F];
|
||||
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
|
||||
mySystem->setPageAccess(k >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -157,16 +152,14 @@ bool CartridgeF4SC::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1100; address < (0x1FF4U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -29,6 +29,7 @@ CartridgeF6::CartridgeF6(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 16384);
|
||||
createCodeAccessBase(16384);
|
||||
|
||||
// Remember startup bank
|
||||
myStartBank = 0;
|
||||
|
@ -56,13 +57,9 @@ void CartridgeF6::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -151,16 +148,14 @@ bool CartridgeF6::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FF6U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -29,6 +29,7 @@ CartridgeF6SC::CartridgeF6SC(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 16384);
|
||||
createCodeAccessBase(16384);
|
||||
|
||||
// This cart contains 128 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 128, 0x80, 0x00);
|
||||
|
@ -66,19 +67,13 @@ void CartridgeF6SC::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
|
||||
{
|
||||
|
@ -88,11 +83,11 @@ void CartridgeF6SC::install(System& system)
|
|||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x007F];
|
||||
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
|
||||
mySystem->setPageAccess(k >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -200,16 +195,14 @@ bool CartridgeF6SC::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1100; address < (0x1FF6U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -30,6 +30,7 @@ CartridgeF8::CartridgeF8(const uInt8* image, const string& md5,
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 8192);
|
||||
createCodeAccessBase(8192);
|
||||
|
||||
// Normally bank 1 is the reset bank, unless we're dealing with ROMs
|
||||
// that have been incorrectly created with banks in the opposite order
|
||||
|
@ -63,13 +64,9 @@ void CartridgeF8::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -138,16 +135,14 @@ bool CartridgeF8::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FF8U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -29,6 +29,7 @@ CartridgeF8SC::CartridgeF8SC(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 8192);
|
||||
createCodeAccessBase(8192);
|
||||
|
||||
// This cart contains 128 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 128, 0x80, 0x00);
|
||||
|
@ -66,33 +67,27 @@ void CartridgeF8SC::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
|
||||
{
|
||||
access.directPokeBase = &myRAM[j & 0x007F];
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
}
|
||||
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x007F];
|
||||
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
|
||||
mySystem->setPageAccess(k >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -180,16 +175,14 @@ bool CartridgeF8SC::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1100; address < (0x1FF8U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -29,6 +29,7 @@ CartridgeFA::CartridgeFA(const uInt8* image, const Settings& settings)
|
|||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 12288);
|
||||
createCodeAccessBase(12288);
|
||||
|
||||
// This cart contains 256 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 256, 0x100, 0x00);
|
||||
|
@ -66,19 +67,13 @@ void CartridgeFA::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1100 & mask) == 0) && ((0x1200 & mask) == 0));
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.directPeekBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_WRITE;
|
||||
for(uInt32 j = 0x1000; j < 0x1100; j += (1 << shift))
|
||||
{
|
||||
|
@ -88,11 +83,11 @@ void CartridgeFA::install(System& system)
|
|||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1100; k < 0x1200; k += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x00FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[0x100 + (k & 0x00FF)];
|
||||
mySystem->setPageAccess(k >> shift, access);
|
||||
}
|
||||
|
||||
|
@ -190,16 +185,14 @@ bool CartridgeFA::bank(uInt16 bank)
|
|||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1200; address < (0x1FF8U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
|
|
@ -54,12 +54,9 @@ void CartridgeFE::install(System& system)
|
|||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map all of the accesses to call peek and poke
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
}
|
||||
|
|
|
@ -81,18 +81,12 @@ void CartridgeMC::install(System& system)
|
|||
// TODO: These TIA accesses may need to be chained, however, at this
|
||||
// point Chris isn't sure if the hardware will allow it or not
|
||||
//
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READWRITE;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READWRITE);
|
||||
|
||||
for(uInt32 i = 0x00; i < 0x40; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
// Map the cartridge into the system
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ; // We don't yet indicate RAM areas
|
||||
for(uInt32 j = 0x1000; j < 0x2000; j += (1 << shift))
|
||||
mySystem->setPageAccess(j >> shift, access);
|
||||
|
|
|
@ -73,13 +73,9 @@ void CartridgeSB::install(System& system)
|
|||
myHotSpotPageAccess[6] = mySystem->getPageAccess(0x0E00 >> shift);
|
||||
myHotSpotPageAccess[7] = mySystem->getPageAccess(0x0F00 >> shift);
|
||||
|
||||
System::PageAccess access;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 i = 0x0800; i < 0x0FFF; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -137,10 +133,7 @@ bool CartridgeSB::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
|
|
|
@ -61,11 +61,7 @@ void CartridgeUA::install(System& system)
|
|||
myHotSpotPageAccess = mySystem->getPageAccess(0x0220 >> shift);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
mySystem->setPageAccess(0x0220 >> shift, access);
|
||||
mySystem->setPageAccess(0x0240 >> shift, access);
|
||||
|
||||
|
@ -145,10 +141,7 @@ bool CartridgeUA::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
|
|
|
@ -61,11 +61,7 @@ void CartridgeX07::install(System& system)
|
|||
// Set the page accessing methods for the hot spots
|
||||
// The hotspots use almost all addresses below 0x1000, so we simply grab them
|
||||
// all and forward the TIA/RIOT calls from the peek and poke methods.
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READWRITE;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READWRITE);
|
||||
for(uInt32 i = 0x00; i < 0x1000; i += (1 << shift))
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
|
||||
|
@ -129,10 +125,7 @@ bool CartridgeX07::bank(uInt16 bank)
|
|||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
access.type = System::PA_READ;
|
||||
System::PageAccess access(0, 0, myCodeAccessBase, this, System::PA_READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift))
|
||||
|
|
|
@ -152,7 +152,7 @@ void M6502::PS(uInt8 ps)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline uInt8 M6502::peek(uInt16 address)
|
||||
inline uInt8 M6502::peek(uInt16 address, bool isCode)
|
||||
{
|
||||
if(address != myLastAddress)
|
||||
{
|
||||
|
@ -170,7 +170,7 @@ inline uInt8 M6502::peek(uInt16 address)
|
|||
}
|
||||
#endif
|
||||
|
||||
uInt8 result = mySystem->peek(address);
|
||||
uInt8 result = mySystem->peek(address, isCode);
|
||||
myLastAccessWasRead = true;
|
||||
myLastPeekAddress = address;
|
||||
return result;
|
||||
|
@ -245,7 +245,7 @@ bool M6502::execute(uInt32 number)
|
|||
myLastPeekAddress = myLastPokeAddress = 0;
|
||||
|
||||
// Fetch instruction at the program counter
|
||||
IR = peek(PC++);
|
||||
IR = peek(PC++, true); // This address represents a code section
|
||||
|
||||
#ifdef DEBUG_OUTPUT
|
||||
debugStream << ::hex << setw(2) << (int)A << " "
|
||||
|
@ -256,7 +256,7 @@ bool M6502::execute(uInt32 number)
|
|||
<< setw(2) << (int)IR << " "
|
||||
// << "<" << ourAddressingModeTable[IR] << " ";
|
||||
// debugStream << hex << setw(4) << operandAddress << " ";
|
||||
<< setw(3) << ourInstructionMnemonicTable[IR]
|
||||
// << setw(3) << ourInstructionMnemonicTable[IR]
|
||||
|
||||
// debugStream << "PS=" << ::hex << setw(2) << (int)PS() << " ";
|
||||
|
||||
|
@ -274,7 +274,6 @@ bool M6502::execute(uInt32 number)
|
|||
// Oops, illegal instruction executed so set fatal error flag
|
||||
myExecutionStatus |= FatalErrorBit;
|
||||
}
|
||||
|
||||
myTotalInstructionCount++;
|
||||
}
|
||||
|
||||
|
|
|
@ -206,17 +206,23 @@ class M6502 : public Serializable
|
|||
private:
|
||||
/**
|
||||
Get the byte at the specified address and update the cycle count.
|
||||
Addresses marked as code are hints to the debugger/disassembler to
|
||||
conclusively determine code sections, even if the disassembler cannot
|
||||
find them itself.
|
||||
|
||||
@param address The address from which the value should be loaded
|
||||
@param isCode Indicates that this address is part of an instruction
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
inline uInt8 peek(uInt16 address);
|
||||
inline uInt8 peek(uInt16 address, bool isCode);
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value and
|
||||
update the cycle count.
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
*/
|
||||
inline void poke(uInt16 address, uInt8 value);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,197 +32,197 @@
|
|||
#endif
|
||||
|
||||
define(M6502_IMPLIED, `{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
}')
|
||||
|
||||
define(M6502_IMMEDIATE_READ, `{
|
||||
operand = peek(PC++);
|
||||
operand = peek(PC++, true);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTE_READ, `{
|
||||
uInt16 address = peek(PC++);
|
||||
address |= ((uInt16)peek(PC++) << 8);
|
||||
operand = peek(address);
|
||||
uInt16 address = peek(PC++, true);
|
||||
address |= ((uInt16)peek(PC++, true) << 8);
|
||||
operand = peek(address, false);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTE_WRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
operandAddress |= ((uInt16)peek(PC++) << 8);
|
||||
operandAddress = peek(PC++, true);
|
||||
operandAddress |= ((uInt16)peek(PC++, true) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTE_READMODIFYWRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
operandAddress |= ((uInt16)peek(PC++) << 8);
|
||||
operand = peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
operandAddress |= ((uInt16)peek(PC++, true) << 8);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEX_READ, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
operand = peek(high | (uInt8)(low + X));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
operand = peek(high | (uInt8)(low + X), false);
|
||||
if((low + X) > 0xFF)
|
||||
operand = peek((high | low) + X);
|
||||
operand = peek((high | low) + X, false);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEX_WRITE, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
peek(high | (uInt8)(low + X));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
peek(high | (uInt8)(low + X), false);
|
||||
operandAddress = (high | low) + X;
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEX_READMODIFYWRITE, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
peek(high | (uInt8)(low + X));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
peek(high | (uInt8)(low + X), false);
|
||||
operandAddress = (high | low) + X;
|
||||
operand = peek(operandAddress);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEY_READ, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
operand = peek(high | (uInt8)(low + Y));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
operand = peek(high | (uInt8)(low + Y), false);
|
||||
if((low + Y) > 0xFF)
|
||||
operand = peek((high | low) + Y);
|
||||
operand = peek((high | low) + Y, false);
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEY_WRITE, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
peek(high | (uInt8)(low + Y));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
peek(high | (uInt8)(low + Y), false);
|
||||
operandAddress = (high | low) + Y;
|
||||
}')
|
||||
|
||||
define(M6502_ABSOLUTEY_READMODIFYWRITE, `{
|
||||
uInt16 low = peek(PC++);
|
||||
uInt16 high = ((uInt16)peek(PC++) << 8);
|
||||
peek(high | (uInt8)(low + Y));
|
||||
uInt16 low = peek(PC++, true);
|
||||
uInt16 high = ((uInt16)peek(PC++, true) << 8);
|
||||
peek(high | (uInt8)(low + Y), false);
|
||||
operandAddress = (high | low) + Y;
|
||||
operand = peek(operandAddress);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_ZERO_READ, `{
|
||||
operand = peek(peek(PC++));
|
||||
operand = peek(peek(PC++, true), false);
|
||||
}')
|
||||
|
||||
define(M6502_ZERO_WRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
operandAddress = peek(PC++, true);
|
||||
}')
|
||||
|
||||
define(M6502_ZERO_READMODIFYWRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
operand = peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_ZEROX_READ, `{
|
||||
uInt8 address = peek(PC++);
|
||||
peek(address);
|
||||
uInt8 address = peek(PC++, true);
|
||||
peek(address, false);
|
||||
address += X;
|
||||
operand = peek(address);
|
||||
operand = peek(address, false);
|
||||
}')
|
||||
|
||||
define(M6502_ZEROX_WRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
peek(operandAddress, false);
|
||||
operandAddress = (operandAddress + X) & 0xFF;
|
||||
}')
|
||||
|
||||
define(M6502_ZEROX_READMODIFYWRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
peek(operandAddress, false);
|
||||
operandAddress = (operandAddress + X) & 0xFF;
|
||||
operand = peek(operandAddress);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_ZEROY_READ, `{
|
||||
uInt8 address = peek(PC++);
|
||||
peek(address);
|
||||
uInt8 address = peek(PC++, true);
|
||||
peek(address, false);
|
||||
address += Y;
|
||||
operand = peek(address);
|
||||
operand = peek(address, false);
|
||||
}')
|
||||
|
||||
define(M6502_ZEROY_WRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
peek(operandAddress, false);
|
||||
operandAddress = (operandAddress + Y) & 0xFF;
|
||||
}')
|
||||
|
||||
define(M6502_ZEROY_READMODIFYWRITE, `{
|
||||
operandAddress = peek(PC++);
|
||||
peek(operandAddress);
|
||||
operandAddress = peek(PC++, true);
|
||||
peek(operandAddress, false);
|
||||
operandAddress = (operandAddress + Y) & 0xFF;
|
||||
operand = peek(operandAddress);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECT, `{
|
||||
uInt16 addr = peek(PC++);
|
||||
addr |= ((uInt16)peek(PC++) << 8);
|
||||
uInt16 addr = peek(PC++, true);
|
||||
addr |= ((uInt16)peek(PC++, true) << 8);
|
||||
|
||||
// Simulate the error in the indirect addressing mode!
|
||||
uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1);
|
||||
|
||||
operandAddress = peek(addr);
|
||||
operandAddress |= ((uInt16)peek(high) << 8);
|
||||
operandAddress = peek(addr, false);
|
||||
operandAddress |= ((uInt16)peek(high, false) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTX_READ, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
peek(pointer);
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
peek(pointer, false);
|
||||
pointer += X;
|
||||
uInt16 address = peek(pointer++);
|
||||
address |= ((uInt16)peek(pointer) << 8);
|
||||
operand = peek(address);
|
||||
uInt16 address = peek(pointer++, false);
|
||||
address |= ((uInt16)peek(pointer, false) << 8);
|
||||
operand = peek(address, false);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTX_WRITE, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
peek(pointer);
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
peek(pointer, false);
|
||||
pointer += X;
|
||||
operandAddress = peek(pointer++);
|
||||
operandAddress |= ((uInt16)peek(pointer) << 8);
|
||||
operandAddress = peek(pointer++, false);
|
||||
operandAddress |= ((uInt16)peek(pointer, false) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTX_READMODIFYWRITE, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
peek(pointer);
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
peek(pointer, false);
|
||||
pointer += X;
|
||||
operandAddress = peek(pointer++);
|
||||
operandAddress |= ((uInt16)peek(pointer) << 8);
|
||||
operand = peek(operandAddress);
|
||||
operandAddress = peek(pointer++, false);
|
||||
operandAddress |= ((uInt16)peek(pointer, false) << 8);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTY_READ, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
uInt16 low = peek(pointer++);
|
||||
uInt16 high = ((uInt16)peek(pointer) << 8);
|
||||
operand = peek(high | (uInt8)(low + Y));
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
uInt16 low = peek(pointer++, false);
|
||||
uInt16 high = ((uInt16)peek(pointer, false) << 8);
|
||||
operand = peek(high | (uInt8)(low + Y), false);
|
||||
if((low + Y) > 0xFF)
|
||||
operand = peek((high | low) + Y);
|
||||
operand = peek((high | low) + Y, false);
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTY_WRITE, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
uInt16 low = peek(pointer++);
|
||||
uInt16 high = ((uInt16)peek(pointer) << 8);
|
||||
peek(high | (uInt8)(low + Y));
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
uInt16 low = peek(pointer++, false);
|
||||
uInt16 high = ((uInt16)peek(pointer, false) << 8);
|
||||
peek(high | (uInt8)(low + Y), false);
|
||||
operandAddress = (high | low) + Y;
|
||||
}')
|
||||
|
||||
define(M6502_INDIRECTY_READMODIFYWRITE, `{
|
||||
uInt8 pointer = peek(PC++);
|
||||
uInt16 low = peek(pointer++);
|
||||
uInt16 high = ((uInt16)peek(pointer) << 8);
|
||||
peek(high | (uInt8)(low + Y));
|
||||
uInt8 pointer = peek(PC++, true);
|
||||
uInt16 low = peek(pointer++, false);
|
||||
uInt16 high = ((uInt16)peek(pointer, false) << 8);
|
||||
peek(high | (uInt8)(low + Y), false);
|
||||
operandAddress = (high | low) + Y;
|
||||
operand = peek(operandAddress);
|
||||
operand = peek(operandAddress, false);
|
||||
poke(operandAddress, operand);
|
||||
}')
|
||||
|
||||
|
@ -230,10 +230,10 @@ define(M6502_INDIRECTY_READMODIFYWRITE, `{
|
|||
define(M6502_BCC, `{
|
||||
if(!C)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -241,10 +241,10 @@ define(M6502_BCC, `{
|
|||
define(M6502_BCS, `{
|
||||
if(C)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -252,10 +252,10 @@ define(M6502_BCS, `{
|
|||
define(M6502_BEQ, `{
|
||||
if(!notZ)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -263,10 +263,10 @@ define(M6502_BEQ, `{
|
|||
define(M6502_BMI, `{
|
||||
if(N)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -274,10 +274,10 @@ define(M6502_BMI, `{
|
|||
define(M6502_BNE, `{
|
||||
if(notZ)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -285,10 +285,10 @@ define(M6502_BNE, `{
|
|||
define(M6502_BPL, `{
|
||||
if(!N)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -296,10 +296,10 @@ define(M6502_BPL, `{
|
|||
define(M6502_BVC, `{
|
||||
if(!V)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -307,10 +307,10 @@ define(M6502_BVC, `{
|
|||
define(M6502_BVS, `{
|
||||
if(V)
|
||||
{
|
||||
peek(PC);
|
||||
peek(PC, false);
|
||||
uInt16 address = PC + (Int8)operand;
|
||||
if(NOTSAMEPAGE(PC, address))
|
||||
peek((PC & 0xFF00) | (address & 0x00FF));
|
||||
peek((PC & 0xFF00) | (address & 0x00FF), false);
|
||||
PC = address;
|
||||
}
|
||||
}')
|
||||
|
@ -449,7 +449,7 @@ define(M6502_BIT, `{
|
|||
}')
|
||||
|
||||
define(M6502_BRK, `{
|
||||
peek(PC++);
|
||||
peek(PC++, true);
|
||||
|
||||
B = true;
|
||||
|
||||
|
@ -459,8 +459,8 @@ define(M6502_BRK, `{
|
|||
|
||||
I = true;
|
||||
|
||||
PC = peek(0xfffe);
|
||||
PC |= ((uInt16)peek(0xffff) << 8);
|
||||
PC = peek(0xfffe, false);
|
||||
PC |= ((uInt16)peek(0xffff, false) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_CLC, `{
|
||||
|
@ -598,8 +598,8 @@ define(M6502_JMP, `{
|
|||
}')
|
||||
|
||||
define(M6502_JSR, `{
|
||||
uInt8 low = peek(PC++);
|
||||
peek(0x0100 + SP);
|
||||
uInt8 low = peek(PC++, true);
|
||||
peek(0x0100 + SP, false);
|
||||
|
||||
// It seems that the 650x does not push the address of the next instruction
|
||||
// on the stack it actually pushes the address of the next instruction
|
||||
|
@ -607,7 +607,7 @@ define(M6502_JSR, `{
|
|||
poke(0x0100 + SP--, PC >> 8);
|
||||
poke(0x0100 + SP--, PC & 0xff);
|
||||
|
||||
PC = low | ((uInt16)peek(PC++) << 8);
|
||||
PC = low | ((uInt16)peek(PC++, true) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_LAS, `{
|
||||
|
@ -689,15 +689,15 @@ define(M6502_PHP, `{
|
|||
}')
|
||||
|
||||
define(M6502_PLA, `{
|
||||
peek(0x0100 + SP++);
|
||||
A = peek(0x0100 + SP);
|
||||
peek(0x0100 + SP++, false);
|
||||
A = peek(0x0100 + SP, false);
|
||||
notZ = A;
|
||||
N = A & 0x80;
|
||||
}')
|
||||
|
||||
define(M6502_PLP, `{
|
||||
peek(0x0100 + SP++);
|
||||
PS(peek(0x0100 + SP));
|
||||
peek(0x0100 + SP++, false);
|
||||
PS(peek(0x0100 + SP, false));
|
||||
}')
|
||||
|
||||
define(M6502_RLA, `{
|
||||
|
@ -800,17 +800,17 @@ define(M6502_RRA, `{
|
|||
}')
|
||||
|
||||
define(M6502_RTI, `{
|
||||
peek(0x0100 + SP++);
|
||||
PS(peek(0x0100 + SP++));
|
||||
PC = peek(0x0100 + SP++);
|
||||
PC |= ((uInt16)peek(0x0100 + SP) << 8);
|
||||
peek(0x0100 + SP++, false);
|
||||
PS(peek(0x0100 + SP++, false));
|
||||
PC = peek(0x0100 + SP++, false);
|
||||
PC |= ((uInt16)peek(0x0100 + SP, false) << 8);
|
||||
}')
|
||||
|
||||
define(M6502_RTS, `{
|
||||
peek(0x0100 + SP++);
|
||||
PC = peek(0x0100 + SP++);
|
||||
PC |= ((uInt16)peek(0x0100 + SP) << 8);
|
||||
peek(PC++);
|
||||
peek(0x0100 + SP++, false);
|
||||
PC = peek(0x0100 + SP++, false);
|
||||
PC |= ((uInt16)peek(0x0100 + SP, false) << 8);
|
||||
peek(PC++, true);
|
||||
}')
|
||||
|
||||
define(M6502_SAX, `{
|
||||
|
|
|
@ -95,11 +95,7 @@ void M6532::install(System& system, Device& device)
|
|||
assert((0x1080 & mask) == 0);
|
||||
|
||||
// All accesses are to the given device
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = &device;
|
||||
access.type = System::PA_READWRITE;
|
||||
System::PageAccess access(0, 0, 0, &device, System::PA_READWRITE);
|
||||
|
||||
// We're installing in a 2600 system
|
||||
for(int address = 0; address < 8192; address += (1 << shift))
|
||||
|
|
|
@ -212,14 +212,14 @@ void System::clearDirtyPages()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 System::peek(uInt16 addr)
|
||||
uInt8 System::peek(uInt16 addr, bool isCode)
|
||||
{
|
||||
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
|
||||
|
||||
uInt8 result;
|
||||
|
||||
// See if this page uses direct accessing or not
|
||||
if(access.directPeekBase != 0)
|
||||
if(access.directPeekBase)
|
||||
{
|
||||
result = *(access.directPeekBase + (addr & myPageMask));
|
||||
}
|
||||
|
@ -230,8 +230,15 @@ uInt8 System::peek(uInt16 addr)
|
|||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
if(!myDataBusLocked)
|
||||
#endif
|
||||
{
|
||||
if(access.codeAccessBase)
|
||||
*(access.codeAccessBase + (addr & myPageMask)) = isCode;
|
||||
|
||||
myDataBusState = result;
|
||||
}
|
||||
#else
|
||||
myDataBusState = result;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -261,6 +268,21 @@ void System::poke(uInt16 addr, uInt8 value)
|
|||
myDataBusState = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool System::isCode(uInt16 addr)
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
|
||||
|
||||
if(access.codeAccessBase)
|
||||
return *(access.codeAccessBase + (addr & myPageMask)) ? true : false;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void System::lockDataBus()
|
||||
{
|
||||
|
|
|
@ -255,9 +255,12 @@ class System : public Serializable
|
|||
address occurs before it's sent to the device mapped at
|
||||
the address.
|
||||
|
||||
@param address The address from which the value should be loaded
|
||||
@param isCode Indicates that this address is part of an instruction
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
uInt8 peek(uInt16 address);
|
||||
uInt8 peek(uInt16 address, bool isCode = false);
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value.
|
||||
|
@ -269,8 +272,8 @@ class System : public Serializable
|
|||
if the device is handling the poke, we depend on its return value
|
||||
for this information.
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
*/
|
||||
void poke(uInt16 address, uInt8 value);
|
||||
|
||||
|
@ -286,6 +289,13 @@ class System : public Serializable
|
|||
void lockDataBus();
|
||||
void unlockDataBus();
|
||||
|
||||
/**
|
||||
Answer whether or not the given address has ever been used as
|
||||
code. That is, it has ever been stored in either the IR or the PC,
|
||||
or otherwise been executed.
|
||||
*/
|
||||
bool isCode(uInt16 address);
|
||||
|
||||
public:
|
||||
/**
|
||||
Describes how a page can be accessed
|
||||
|
@ -317,6 +327,15 @@ class System : public Serializable
|
|||
*/
|
||||
uInt8* directPokeBase;
|
||||
|
||||
/**
|
||||
Pointer to a lookup table for marking an address as CODE. A CODE
|
||||
section is defined as any address that appears in the program
|
||||
counter. Currently, this is used by the debugger/disassembler to
|
||||
conclusively determine if a section of address space is CODE, even
|
||||
if the disassembler failed to mark it as such.
|
||||
*/
|
||||
uInt8* codeAccessBase;
|
||||
|
||||
/**
|
||||
Pointer to the device associated with this page or to the system's
|
||||
null device if the page hasn't been mapped to a device.
|
||||
|
@ -328,7 +347,23 @@ class System : public Serializable
|
|||
(READ, WRITE, READWRITE)
|
||||
*/
|
||||
PageAccessType type;
|
||||
};
|
||||
|
||||
// Constructors
|
||||
PageAccess()
|
||||
: directPeekBase(0),
|
||||
directPokeBase(0),
|
||||
codeAccessBase(0),
|
||||
device(0),
|
||||
type(System::PA_READ) { }
|
||||
|
||||
PageAccess(uInt8* peek, uInt8* poke, uInt8* code, Device* dev,
|
||||
PageAccessType access)
|
||||
: directPeekBase(peek),
|
||||
directPokeBase(poke),
|
||||
codeAccessBase(code),
|
||||
device(dev),
|
||||
type(access) { }
|
||||
};
|
||||
|
||||
/**
|
||||
Set the page accessing method for the specified page.
|
||||
|
|
|
@ -293,11 +293,7 @@ void TIA::install(System& system, Device& device)
|
|||
mySystem->resetCycles();
|
||||
|
||||
// All accesses are to the given device
|
||||
System::PageAccess access;
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = &device;
|
||||
access.type = System::PA_READWRITE;
|
||||
System::PageAccess access(0, 0, 0, &device, System::PA_READWRITE);
|
||||
|
||||
// We're installing in a 2600 system
|
||||
for(uInt32 i = 0; i < 8192; i += (1 << shift))
|
||||
|
|
|
@ -1503,7 +1503,14 @@
|
|||
};
|
||||
buildConfigurationList = 2D91752109BA903B0026E9FF /* Build configuration list for PBXProject "stella_intel" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
Japanese,
|
||||
French,
|
||||
German,
|
||||
);
|
||||
mainGroup = 29B97314FDCFA39411CA2CEA /* «PROJECTNAMEASXML» */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
|
|
Loading…
Reference in New Issue