Modified most of the cart classes to properly set the 'page dirty' flag

when their address space has been modified by poke.  Any writes done
inadvertently by reading from the write port are also flagged.  This flag
is used by CartDebug to determine if cart address space has changed.
For now, it uses this information to do a complete re-disassembly.
Entire bank changes are signaled by setting myBankChanged to true,
which overrides the page dirty flag and short-circuits testing for it.

Still TODO is add support for 'AR' bankswitching, and fix the patch
method for several schemes.

Added latest DPC+ updates from Spiceware and Batari.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1976 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-03-28 03:13:10 +00:00
parent 80dbfd6dfa
commit 6fee79ddff
65 changed files with 663 additions and 524 deletions

View File

@ -288,6 +288,8 @@ void Cartridge::triggerReadFromWritePort(uInt16 address)
#ifdef DEBUGGER_SUPPORT
if(&Debugger::debugger().cartDebug())
Debugger::debugger().cartDebug().triggerReadFromWritePort(address);
mySystem->setDirtyPage(address);
#endif
}
@ -366,7 +368,7 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
else
type = "F6";
}
else if(size == 28*1024) // 28K
else if(size == 29*1024) // 29K
{
type = "DPC+";
}

View File

@ -131,8 +131,6 @@ class Cartridge : public Device
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank() = 0;

View File

@ -113,7 +113,7 @@ uInt8 Cartridge0840::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge0840::poke(uInt16 address, uInt8 value)
bool Cartridge0840::poke(uInt16 address, uInt8 value)
{
address &= 0x1840;
@ -141,6 +141,7 @@ void Cartridge0840::poke(uInt16 address, uInt8 value)
int hotspot = ((address & 0x0F00) >> 8) - 8;
myHotSpotPageAccess[hotspot].device->poke(address, value);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -128,8 +128,9 @@ class Cartridge0840 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// The 8K ROM image of the cartridge

View File

@ -91,9 +91,10 @@ uInt8 Cartridge2K::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge2K::poke(uInt16, uInt8)
bool Cartridge2K::poke(uInt16, uInt8)
{
// This is ROM so poking has no effect :-)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -132,8 +132,9 @@ class Cartridge2K : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Pointer to a dynamically allocated ROM image of the cartridge

View File

@ -131,7 +131,7 @@ uInt8 Cartridge3E::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge3E::poke(uInt16 address, uInt8 value)
bool Cartridge3E::poke(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
@ -151,6 +151,8 @@ void Cartridge3E::poke(uInt16 address, uInt8 value)
// 64-byte chunk of address space is "owned" by only one device. If we
// don't chain the poke to the TIA, then the TIA can't see it...
mySystem->tia().poke(address, value);
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -80,7 +80,7 @@ class Cartridge3E : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -88,26 +88,24 @@ class Cartridge3E : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -116,7 +114,7 @@ class Cartridge3E : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -124,7 +122,7 @@ class Cartridge3E : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -132,7 +130,7 @@ class Cartridge3E : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -140,14 +138,14 @@ class Cartridge3E : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "Cartridge3E"; }
string name() const { return "Cartridge3E"; }
public:
/**
@ -155,15 +153,16 @@ class Cartridge3E : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active for the first segment

View File

@ -102,7 +102,7 @@ uInt8 Cartridge3F::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge3F::poke(uInt16 address, uInt8 value)
bool Cartridge3F::poke(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
@ -117,6 +117,8 @@ void Cartridge3F::poke(uInt16 address, uInt8 value)
// 64-byte chunk of address space is "owned" by only one device. If we
// don't chain the poke to the TIA, then the TIA can't see it...
mySystem->tia().poke(address, value);
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -139,8 +139,9 @@ class Cartridge3F : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active for the first segment

View File

@ -24,11 +24,6 @@
#include "TIA.hxx"
#include "Cart4A50.hxx"
// TODO - properly handle read from write port functionality
// Note: do r/w port restrictions even exist for this scheme??
// Port to new CartDebug/disassembler scheme
// Add bankchanged code
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4A50::Cartridge4A50(const uInt8* image, uInt32 size)
{
@ -58,6 +53,8 @@ void Cartridge4A50::reset()
myLastData = 0xff;
myLastAddress = 0xffff;
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -136,7 +133,7 @@ uInt8 Cartridge4A50::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::poke(uInt16 address, uInt8 value)
bool Cartridge4A50::poke(uInt16 address, uInt8 value)
{
if(!(address & 0x1000)) // Hotspots below 0x1000
{
@ -154,29 +151,43 @@ void Cartridge4A50::poke(uInt16 address, uInt8 value)
if((address & 0x1800) == 0x1000) // 2K region at 0x1000 - 0x17ff
{
if(!myIsRomLow)
{
myRAM[(address & 0x7ff) + mySliceLow] = value;
myBankChanged = true;
}
}
else if(((address & 0x1fff) >= 0x1800) && // 1.5K region at 0x1800 - 0x1dff
((address & 0x1fff) <= 0x1dff))
{
if(!myIsRomMiddle)
{
myRAM[(address & 0x7ff) + mySliceMiddle] = value;
myBankChanged = true;
}
}
else if((address & 0x1f00) == 0x1e00) // 256B region at 0x1e00 - 0x1eff
{
if(!myIsRomHigh)
{
myRAM[(address & 0xff) + mySliceHigh] = value;
myBankChanged = true;
}
}
else if((address & 0x1f00) == 0x1f00) // 256B region at 0x1f00 - 0x1fff
{
if(!bankLocked() && ((myLastData & 0xe0) == 0x60) &&
((myLastAddress >= 0x1000) || (myLastAddress < 0x200)))
{
mySliceHigh = (mySliceHigh & 0xf0ff) | ((address & 0x8) << 8) |
((address & 0x70) << 4);
myBankChanged = true;
}
}
}
myLastData = value;
myLastAddress = address & 0x1fff;
return myBankChanged;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -193,49 +204,59 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
{
myIsRomHigh = true;
mySliceHigh = (address & 0xff) << 8;
myBankChanged = true;
}
else if((address & 0x0f00) == 0x0d00) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
myIsRomHigh = false;
mySliceHigh = (address & 0x7f) << 8;
myBankChanged = true;
}
else if((address & 0x0f40) == 0x0e00) // Enable 2K of ROM at 0x1000 - 0x17ff
{
myIsRomLow = true;
mySliceLow = (address & 0x1f) << 11;
myBankChanged = true;
}
else if((address & 0x0f40) == 0x0e40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
myIsRomLow = false;
mySliceLow = (address & 0xf) << 11;
myBankChanged = true;
}
else if((address & 0x0f40) == 0x0f00) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
myIsRomMiddle = true;
mySliceMiddle = (address & 0x1f) << 11;
myBankChanged = true;
}
else if((address & 0x0f50) == 0x0f40) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
myIsRomMiddle = false;
mySliceMiddle = (address & 0xf) << 11;
myBankChanged = true;
}
// Stella helper functions
else if((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
{
mySliceLow = mySliceLow ^ 0x800;
myBankChanged = true;
}
else if((address & 0x0f00) == 0x0500) // Toggle bit A12 of lower block address
{
mySliceLow = mySliceLow ^ 0x1000;
myBankChanged = true;
}
else if((address & 0x0f00) == 0x0800) // Toggle bit A11 of middle block address
{
mySliceMiddle = mySliceMiddle ^ 0x800;
myBankChanged = true;
}
else if((address & 0x0f00) == 0x0900) // Toggle bit A12 of middle block address
{
mySliceMiddle = mySliceMiddle ^ 0x1000;
myBankChanged = true;
}
}
@ -247,11 +268,13 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
{
myIsRomHigh = true;
mySliceHigh = value << 8;
myBankChanged = true;
}
else if((address & 0xf75) == 0x75) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
myIsRomHigh = false;
mySliceHigh = (value & 0x7f) << 8;
myBankChanged = true;
}
// Zero-page hotspots for lower and middle blocks
@ -263,21 +286,25 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
{
myIsRomLow = true;
mySliceLow = (value & 0xf) << 11;
myBankChanged = true;
}
else if((value & 0xf0) == 0x40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
myIsRomLow = false;
mySliceLow = (value & 0xf) << 11;
myBankChanged = true;
}
else if((value & 0xf0) == 0x90) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
myIsRomMiddle = true;
mySliceMiddle = ((value & 0xf) | 0x10) << 11;
myBankChanged = true;
}
else if((value & 0xf0) == 0xc0) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
myIsRomMiddle = false;
mySliceMiddle = (value & 0xf) << 11;
myBankChanged = true;
}
}
}
@ -286,14 +313,12 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
void Cartridge4A50::bank(uInt16)
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Cartridge4A50::bank()
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
return 0;
}
@ -301,7 +326,6 @@ int Cartridge4A50::bank()
int Cartridge4A50::bankCount()
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
return 1;
}

View File

@ -36,7 +36,13 @@ class System;
RAM or ROM. The last 256 byte segment always points to the last 256
bytes of ROM.
@author Stephen Anthony & Eckhard Stolberg
Because of the complexity of this scheme, the cart reports having
only one actual bank, in which pieces of it can be swapped out in
many different ways. It contains so many hotspots and possibilities
for the ROM address space to change that we just consider the bank to
have changed on every poke operation (for any RAM) or an actual bankswitch.
@author Eckhard Stolberg & Stephen Anthony
@version $Id$
*/
class Cartridge4A50 : public Cartridge
@ -59,7 +65,7 @@ class Cartridge4A50 : public Cartridge
/**
Reset cartridge to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -67,26 +73,24 @@ class Cartridge4A50 : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -95,7 +99,7 @@ class Cartridge4A50 : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -103,7 +107,7 @@ class Cartridge4A50 : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -111,7 +115,7 @@ class Cartridge4A50 : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -119,14 +123,14 @@ class Cartridge4A50 : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "Cartridge4A50"; }
string name() const { return "Cartridge4A50"; }
public:
/**
@ -134,15 +138,16 @@ class Cartridge4A50 : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**

View File

@ -69,9 +69,10 @@ uInt8 Cartridge4K::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4K::poke(uInt16, uInt8)
bool Cartridge4K::poke(uInt16, uInt8)
{
// This is ROM so poking has no effect :-)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -69,8 +69,6 @@ class Cartridge4K : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -132,8 +130,9 @@ class Cartridge4K : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// The 4K ROM image for the cartridge

View File

@ -161,7 +161,7 @@ uInt8 CartridgeAR::peek(uInt16 addr)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeAR::poke(uInt16 addr, uInt8)
bool CartridgeAR::poke(uInt16 addr, uInt8)
{
// Cancel any pending write if more than 5 distinct accesses have occurred
// TODO: Modify to handle when the distinct counter wraps around...
@ -195,6 +195,8 @@ void CartridgeAR::poke(uInt16 addr, uInt8)
myImage[(addr & 0x07FF) + myImageOffset[1]] = myDataHoldRegister;
myWritePending = false;
}
return false; // FIXME
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -59,14 +59,14 @@ class CartridgeAR : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary
to override this method for devices that remember cycle counts.
*/
virtual void systemCyclesReset();
void systemCyclesReset();
/**
Install cartridge in the specified system. Invoked by the system
@ -74,26 +74,24 @@ class CartridgeAR : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -102,7 +100,7 @@ class CartridgeAR : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -110,7 +108,7 @@ class CartridgeAR : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -118,7 +116,7 @@ class CartridgeAR : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -126,14 +124,14 @@ class CartridgeAR : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeAR"; }
string name() const { return "CartridgeAR"; }
public:
/**
@ -141,15 +139,16 @@ class CartridgeAR : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Handle a change to the bank configuration

View File

@ -27,11 +27,26 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeCV::CartridgeCV(const uInt8* image, uInt32 size)
: myROM(0),
: myInitialRAM(0),
mySize(size)
{
myROM = new uInt8[mySize];
memcpy(myROM, image, mySize);
if(mySize == 2048)
{
// Copy the ROM data into my buffer
memcpy(myImage, image, 2048);
}
else if(mySize == 4096)
{
// The game has something saved in the RAM
// Useful for MagiCard program listings
// Copy the ROM data into my buffer
memcpy(myImage, image + 2048, 2048);
// Copy the RAM image into a buffer for use in reset()
myInitialRAM = new uInt8[1024];
memcpy(myInitialRAM, image, 1024);
}
// This cart contains 1024 bytes extended RAM @ 0x1000
registerRamArea(0x1000, 1024, 0x00, 0x400);
@ -40,32 +55,23 @@ CartridgeCV::CartridgeCV(const uInt8* image, uInt32 size)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeCV::~CartridgeCV()
{
delete[] myROM;
delete[] myInitialRAM;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCV::reset()
{
if(mySize == 2048)
if(myInitialRAM)
{
// Copy the RAM image into my buffer
memcpy(myRAM, myInitialRAM, 1024);
}
else
{
// Copy the ROM data into my buffer
memcpy(myImage, myROM, 2048);
// Initialize RAM with random values
for(uInt32 i = 0; i < 1024; ++i)
myRAM[i] = mySystem->randGenerator().next();
}
else if(mySize == 4096)
{
// The game has something saved in the RAM
// Useful for MagiCard program listings
// Copy the ROM data into my buffer
memcpy(myImage, myROM + 2048, 2048);
// Copy the RAM image into my buffer
memcpy(myRAM, myROM, 1024);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -131,9 +137,10 @@ uInt8 CartridgeCV::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCV::poke(uInt16, uInt8)
bool CartridgeCV::poke(uInt16, uInt8)
{
// This is ROM so poking has no effect :-)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -158,6 +165,7 @@ int CartridgeCV::bankCount()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeCV::patch(uInt16 address, uInt8 value)
{
// TODO - ROM vs RAM in patching
myImage[address & 0x07FF] = value;
return true;
}

View File

@ -53,7 +53,7 @@ class CartridgeCV : public Cartridge
/**
Reset cartridge to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -61,26 +61,24 @@ class CartridgeCV : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -89,7 +87,7 @@ class CartridgeCV : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -97,7 +95,7 @@ class CartridgeCV : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -105,7 +103,7 @@ class CartridgeCV : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -113,14 +111,14 @@ class CartridgeCV : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeCV"; }
string name() const { return "CartridgeCV"; }
public:
/**
@ -128,19 +126,21 @@ class CartridgeCV : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Pointer to the initial cart data
uInt8* myROM;
// Pointer to the initial RAM data from the cart
// This doesn't always exist, so we don't pre-allocate it
uInt8* myInitialRAM;
// Initial size of the cart data
uInt32 mySize;

View File

@ -23,11 +23,6 @@
#include "System.hxx"
#include "CartDPC.hxx"
// TODO - properly handle read from write port functionality
// Note: do r/w port restrictions even exist for this scheme??
// Port to new CartDebug/disassembler scheme
// Add bankchanged code
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDPC::CartridgeDPC(const uInt8* image, uInt32 size)
{
@ -114,8 +109,8 @@ void CartridgeDPC::install(System& system)
mySystem->setPageAccess(j >> shift, access);
}
// Install pages for bank 1
bank(1);
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -309,12 +304,12 @@ uInt8 CartridgeDPC::peek(uInt16 address)
default:
break;
}
return myProgramImage[myCurrentBank * 4096 + address];
return myProgramImage[(myCurrentBank << 12) + address];
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPC::poke(uInt16 address, uInt8 value)
bool CartridgeDPC::poke(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
@ -416,6 +411,7 @@ void CartridgeDPC::poke(uInt16 address, uInt8 value)
break;
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -441,6 +437,7 @@ void CartridgeDPC::bank(uInt16 bank)
access.directPeekBase = &myProgramImage[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -452,14 +449,12 @@ int CartridgeDPC::bank()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartridgeDPC::bankCount()
{
// TODO - add support for debugger (support the display ROM somehow)
return 2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDPC::patch(uInt16 address, uInt8 value)
{
// TODO - check if this actually works
myProgramImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
return true;
}
@ -468,15 +463,7 @@ bool CartridgeDPC::patch(uInt16 address, uInt8 value)
uInt8* CartridgeDPC::getImage(int& size)
{
size = 8192 + 2048 + 255;
int i;
for(i = 0; i < 8192; i++)
myImageCopy[i] = myProgramImage[i];
for(i = 0; i < 2048; i++)
myImageCopy[i + 8192] = myDisplayImage[i];
return &myImageCopy[0];
return myImageCopy;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -51,14 +51,14 @@ class CartridgeDPC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary
to override this method for devices that remember cycle counts.
*/
virtual void systemCyclesReset();
void systemCyclesReset();
/**
Install cartridge in the specified system. Invoked by the system
@ -66,26 +66,24 @@ class CartridgeDPC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -94,7 +92,7 @@ class CartridgeDPC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -102,7 +100,7 @@ class CartridgeDPC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -110,7 +108,7 @@ class CartridgeDPC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -118,14 +116,14 @@ class CartridgeDPC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeDPC"; }
string name() const { return "CartridgeDPC"; }
public:
/**
@ -133,15 +131,16 @@ class CartridgeDPC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**

View File

@ -18,21 +18,17 @@
#include <cassert>
#include <cstring>
#include <iostream>
#include "System.hxx"
#include "CartDPCPlus.hxx"
// TODO - properly handle read from write port functionality
// Note: do r/w port restrictions even exist for this scheme??
// Port to new CartDebug/disassembler scheme
// Add bankchanged code
// TODO - INC AUDV0+$40 music support
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size)
{
// Make a copy of the entire image as-is, for use by getImage()
// (this wastes 28K of RAM, should be controlled by a #ifdef)
// (this wastes 29K of RAM, should be controlled by a #ifdef)
memcpy(myImageCopy, image, size);
// Copy the program ROM image into my buffer
@ -40,23 +36,26 @@ CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size)
// Copy the display ROM image into my buffer
memcpy(myDisplayImage, image + 4096 * 6, 4096);
// Copy the Frequency ROM image into my buffer
memcpy(myFrequencyImage, image + 4096 * 6 + 4096, 1024);
// Initialize the DPC data fetcher registers
for(uInt16 i = 0; i < 8; ++i)
myTops[i] = myBottoms[i] = myCounters[i] = myFlags[i] = 0;
myTops[i] = myBottoms[i] = myCounters[i] = myFlags[i] = myFractionalIncrements[i] = 0;
// None of the data fetchers are in music mode
myMusicMode[0] = myMusicMode[1] = myMusicMode[2] = false;
// Initialize the DPC's random number generator register (must be non-zero)
myRandomNumber = 1;
myRandomNumber = 0x2B435044; // "DPC+"
// Initialize the system cycles counter & fractional clock values
mySystemCycles = 0;
myFractionalClocks = 0.0;
// Remember startup bank
myStartBank = 1;
myStartBank = 5;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -114,26 +113,23 @@ void CartridgeDPCPlus::install(System& system)
mySystem->setPageAccess(j >> shift, access);
}
// Install pages for bank 5
bank(5);
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void CartridgeDPCPlus::clockRandomNumberGenerator()
{
// Table for computing the input bit of the random number generator's
// shift register (it's the NOT of the EOR of four bits)
static const uInt8 f[16] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
// Update random number generator (32-bit LFSR)
myRandomNumber = ((myRandomNumber & 1) ? 0xa260012b: 0x00) ^
((myRandomNumber >> 1) & 0x7FFFFFFF);
}
// Using bits 7, 5, 4, & 3 of the shift register compute the input
// bit for the shift register
uInt8 bit = f[((myRandomNumber >> 3) & 0x07) |
((myRandomNumber & 0x80) ? 0x08 : 0x00)];
// Update the shift register
myRandomNumber = (myRandomNumber << 1) | bit;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void CartridgeDPCPlus::priorClockRandomNumberGenerator()
{
// Update random number generator (32-bit LFSR, reversed)
myRandomNumber = ((myRandomNumber & (1<<31)) ? 0x44c00257: 0x00) ^ (myRandomNumber << 1);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -159,33 +155,7 @@ inline void CartridgeDPCPlus::updateMusicModeDataFetchers()
// Update only if the data fetcher is in music mode
if(myMusicMode[x - 5])
{
Int32 top = myTops[x] + 1;
Int32 newLow = (Int32)(myCounters[x] & 0x00ff);
if(myTops[x] != 0)
{
newLow -= (wholeClocks % top);
if(newLow < 0)
{
newLow += top;
}
}
else
{
newLow = 0;
}
// Update flag register for this data fetcher
if(newLow <= myBottoms[x])
{
myFlags[x] = 0x00;
}
else if(newLow <= myTops[x])
{
myFlags[x] = 0xff;
}
myCounters[x] = (myCounters[x] & 0x0F00) | (uInt16)newLow;
myMusicCounter[x - 5] += myMusicFrequency[x - 5];
}
}
}
@ -195,11 +165,6 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
{
address &= 0x0FFF;
// Clock the random number generator. This should be done for every
// cartridge access, however, we're only doing it for the DPC and
// hot-spot accesses to save time.
clockRandomNumberGenerator();
if(address < 0x0040)
{
uInt8 result = 0;
@ -209,11 +174,11 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
uInt32 function = (address >> 3) & 0x07;
// Update flag register for selected data fetcher
if((myCounters[index] & 0x00ff) == myTops[index])
if(((myCounters[index] & 0x00ff00) >> 8) == ((myTops[index]+1) & 0xff))
{
myFlags[index] = 0xff;
}
else if((myCounters[index] & 0x00ff) == myBottoms[index])
else if(((myCounters[index] & 0x00ff00) >> 8) == myBottoms[index])
{
myFlags[index] = 0x00;
}
@ -222,36 +187,59 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
{
case 0x00:
{
// Is this a random number read
if(index < 4)
switch(index)
{
result = myRandomNumber;
}
// No, it's a music read
else
{
static const uInt8 musicAmplitudes[8] = {
case 0x00: //advance and return byte 0 of random
clockRandomNumberGenerator();
result = myRandomNumber & 0xFF;
break;
case 0x01: // return to prior and return byte 0 of random
priorClockRandomNumberGenerator();
result = myRandomNumber & 0xFF;
break;
case 0x02:
result = (myRandomNumber>>8) & 0xFF;
break;
case 0x03:
result = (myRandomNumber>>16) & 0xFF;
break;
case 0x04:
result = (myRandomNumber>>24) & 0xFF;
break;
case 0x05:
case 0x06:
case 0x07:
// No, it's a music read
{
static const uInt8 musicAmplitudes[8] = {
0x00, 0x04, 0x05, 0x09, 0x06, 0x0a, 0x0b, 0x0f
};
};
// Update the music data fetchers (counter & flag)
updateMusicModeDataFetchers();
// Update the music data fetchers (counter & flag)
updateMusicModeDataFetchers();
uInt8 i = 0;
if(myMusicMode[0] && myFlags[5])
{
i |= 0x01;
}
if(myMusicMode[1] && myFlags[6])
{
i |= 0x02;
}
if(myMusicMode[2] && myFlags[7])
{
i |= 0x04;
}
uInt8 i = 0;
if(myMusicMode[0] && (myMusicCounter[0]>>31))
{
i |= 0x01;
}
if(myMusicMode[1] && (myMusicCounter[1]>>31))
{
i |= 0x02;
}
if(myMusicMode[2] && (myMusicCounter[2]>>31))
{
i |= 0x04;
}
result = musicAmplitudes[i];
result = musicAmplitudes[i];
}
break;
}
break;
}
@ -259,36 +247,34 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
// DFx display data read
case 0x01:
{
result = myDisplayImage[ /* 4095 - */ myCounters[index]];
result = myDisplayImage[myCounters[index] >> 8];
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff;
break;
}
// DFx display data read AND'd w/flag
case 0x02:
{
result = myDisplayImage[ /* 4095 - */ myCounters[index]] & myFlags[index];
result = myDisplayImage[myCounters[index] >> 8] & myFlags[index];
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff;
break;
}
// DFx flag
case 0x07:
// DFx display data read w/fractional increment
case 0x03:
{
result = myFlags[index];
result = myDisplayImage[myCounters[index] >> 8];
myCounters[index] = (myCounters[index] + myFractionalIncrements[index]) & 0x0fffff;
break;
}
}
default:
{
result = 0;
break;
}
}
// Clock the selected data fetcher's counter if needed
if((index < 5) || ((index >= 5) && (!myMusicMode[index - 5])))
{
myCounters[index] = (myCounters[index] /*-*/ + 1) & 0x0fff;
}
return result;
}
else
@ -300,26 +286,32 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
// Set the current bank to the first 4k bank
bank(0);
break;
case 0x0FF7:
// Set the current bank to the second 4k bank
bank(1);
break;
case 0x0FF8:
// Set the current bank to the third 4k bank
bank(2);
break;
case 0x0FF9:
// Set the current bank to the fourth 4k bank
bank(3);
break;
case 0x0FFA:
// Set the current bank to the fifth 4k bank
bank(4);
break;
case 0x0FFB:
// Set the current bank to the last 4k bank
bank(5);
break;
default:
break;
}
@ -328,25 +320,27 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
// Clock the random number generator. This should be done for every
// cartridge access, however, we're only doing it for the DPC and
// hot-spot accesses to save time.
clockRandomNumberGenerator();
if((address >= 0x0040) && (address < 0x0080))
if((address >= 0x0038) && (address < 0x0080))
{
// Get the index of the data fetcher that's being accessed
uInt32 index = address & 0x07;
uInt32 function = (address >> 3) & 0x07;
uInt32 function = ((address - 0x38) >> 3) & 0x0f;
switch(function)
{
// DFx top count
case 0x00:
{
myFractionalIncrements[index] = value;
myCounters[index] = myCounters[index] & 0x0FFF00;
break;
}
// DFx top count
case 0x01:
{
myTops[index] = value;
myFlags[index] = 0x00;
@ -354,38 +348,24 @@ void CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
}
// DFx bottom count
case 0x01:
case 0x02:
{
myBottoms[index] = value;
break;
}
// DFx counter low
case 0x02:
case 0x03:
{
if((index >= 5) && myMusicMode[index - 5])
{
// Data fecther is in music mode so its low counter value
// should be loaded from the top register not the poked value
myCounters[index] = (myCounters[index] & 0x0F00) |
(uInt16)myTops[index];
}
else
{
// Data fecther is either not a music mode data fecther or it
// isn't in music mode so it's low counter value should be loaded
// with the poked value
myCounters[index] = (myCounters[index] & 0x0F00) | (uInt16)value;
}
myCounters[index] = (myCounters[index] & 0x0F0000) | ((uInt16)value << 8);
break;
}
// DFx counter high
case 0x03:
case 0x04:
{
myCounters[index] = (((uInt16)value & 0x0F) << 8) |
(myCounters[index] & 0x00ff);
myCounters[index] = (((uInt16)value & 0x0F) << 16) | (myCounters[index] & 0x00ffff);
// Execute special code for music mode data fetchers
if(index >= 5)
{
@ -398,17 +378,78 @@ void CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
break;
}
// Random Number Generator Reset
// DF Push
case 0x05:
{
myCounters[index] = (myCounters[index] - 0x100) & 0x0fffff;
myDisplayImage[myCounters[index] >> 8] = value;
break;
}
// DFx counter hi, same as counter high, but w/out music mode
case 0x06:
{
myRandomNumber = 1;
myCounters[index] = (((uInt16)value & 0x0F) << 16) | (myCounters[index] & 0x00ffff);
break;
}
// Random Number Generator Reset
case 0x07:
{
switch (index)
{
case 0x00:
{
myRandomNumber = 0x2B435044; // "DPC+"
break;
}
case 0x01:
{
myRandomNumber = (myRandomNumber & 0xFFFFFF00) | value;
break;
}
case 0x02:
{
myRandomNumber = (myRandomNumber & 0xFFFF00FF) | (value<<8);
break;
}
case 0x03:
{
myRandomNumber = (myRandomNumber & 0xFF00FFFF) | (value<<16);
break;
}
case 0x04:
{
myRandomNumber = (myRandomNumber & 0x00FFFFFF) | (value<<24);
break;
}
case 0x05:
case 0x06:
case 0x07:
{
myMusicFrequency[index-5] = myFrequencyImage[(value<<2)] +
(myFrequencyImage[(value<<2)+1]<<8) +
(myFrequencyImage[(value<<2)+2]<<16) +
(myFrequencyImage[(value<<2)+3]<<24);
break;
}
default:
break;
}
break;
}
default:
// DF Write
case 0x08:
{
myDisplayImage[myCounters[index] >> 8] = value;
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff;
break;
}
default:
break;
}
}
else
@ -420,30 +461,37 @@ void CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
// Set the current bank to the first 4k bank
bank(0);
break;
case 0x0FF7:
// Set the current bank to the second 4k bank
bank(1);
break;
case 0x0FF8:
// Set the current bank to the third 4k bank
bank(2);
break;
case 0x0FF9:
// Set the current bank to the fourth 4k bank
bank(3);
break;
case 0x0FFA:
// Set the current bank to the fifth 4k bank
bank(4);
break;
case 0x0FFB:
// Set the current bank to the last 4k bank
bank(5);
break;
default:
break;
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -469,6 +517,7 @@ void CartridgeDPCPlus::bank(uInt16 bank)
access.directPeekBase = &myProgramImage[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -480,30 +529,20 @@ int CartridgeDPCPlus::bank()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartridgeDPCPlus::bankCount()
{
// TODO - add support for debugger (support the display ROM somehow)
return 6;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDPCPlus::patch(uInt16 address, uInt8 value)
{
// TODO - check if this actually works
myProgramImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
return true;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8* CartridgeDPCPlus::getImage(int& size)
{
size = 4096 * 6 + 4096 + 255;
int i;
for(i = 0; i < 4096 * 6; i++)
myImageCopy[i] = myProgramImage[i];
for(i = 0; i < 4096; i++)
myImageCopy[i + 4096 * 6] = myDisplayImage[i];
return myImageCopy;
}
@ -535,6 +574,11 @@ bool CartridgeDPCPlus::save(Serializer& out) const
out.putInt(8);
for(i = 0; i < 8; ++i)
out.putInt(myCounters[i]);
// The fractional registers for the data fetchers
out.putInt(8);
for(i = 0; i < 8; ++i)
out.putByte((char)myFractionalIncrements[i]);
// The flag registers for the data fetchers
out.putInt(8);
@ -545,9 +589,19 @@ bool CartridgeDPCPlus::save(Serializer& out) const
out.putInt(3);
for(i = 0; i < 3; ++i)
out.putBool(myMusicMode[i]);
// The music mode counters for the data fetchers
out.putInt(3);
for(i = 0; i < 3; ++i)
out.putInt(myMusicCounter[i]);
// The music mode frequency addends for the data fetchers
out.putInt(3);
for(i = 0; i < 3; ++i)
out.putInt(myMusicFrequency[i]);
// The random number generator register
out.putByte((char)myRandomNumber);
out.putByte((uInt32)myRandomNumber);
out.putInt(mySystemCycles);
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
@ -589,7 +643,12 @@ bool CartridgeDPCPlus::load(Serializer& in)
// The counter registers for the data fetchers
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myCounters[i] = (uInt16) in.getInt();
myCounters[i] = (uInt32) in.getInt();
// The fractional registers for the data fetchers
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myFractionalIncrements[i] = (uInt8) in.getByte();
// The flag registers for the data fetchers
limit = (uInt32) in.getInt();
@ -600,9 +659,19 @@ bool CartridgeDPCPlus::load(Serializer& in)
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myMusicMode[i] = in.getBool();
// The music mode counters for the data fetchers
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myMusicCounter[i] = (uInt32) in.getInt();
// The music mode frequency addends for the data fetchers
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myMusicFrequency[i] = (uInt32) in.getInt();
// The random number generator register
myRandomNumber = (uInt8) in.getByte();
myRandomNumber = (uInt32) in.getInt();
// Get system cycles and fractional clocks
mySystemCycles = in.getInt();

View File

@ -29,7 +29,7 @@ class System;
4K display bank, and the DPC chip. For complete details on the DPC chip
see David P. Crane's United States Patent Number 4,644,495.
@author Spiceware, Batari, Stephen Anthony
@author Darrell Spice Jr, Fred Quimby, Stephen Anthony
@version $Id$
*/
class CartridgeDPCPlus : public Cartridge
@ -51,14 +51,14 @@ class CartridgeDPCPlus : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary
to override this method for devices that remember cycle counts.
*/
virtual void systemCyclesReset();
void systemCyclesReset();
/**
Install cartridge in the specified system. Invoked by the system
@ -66,26 +66,24 @@ class CartridgeDPCPlus : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -94,7 +92,7 @@ class CartridgeDPCPlus : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -102,7 +100,7 @@ class CartridgeDPCPlus : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -110,7 +108,7 @@ class CartridgeDPCPlus : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -118,14 +116,14 @@ class CartridgeDPCPlus : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeDPCPlus"; }
string name() const { return "CartridgeDPCPlus"; }
public:
/**
@ -133,40 +131,49 @@ class CartridgeDPCPlus : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**
Clocks the random number generator to move it to its next state
*/
void clockRandomNumberGenerator();
inline void clockRandomNumberGenerator();
/**
Clocks the random number generator to move it to its prior state
*/
inline void priorClockRandomNumberGenerator();
/**
Updates any data fetchers in music mode based on the number of
CPU cycles which have passed since the last update.
*/
void updateMusicModeDataFetchers();
inline void updateMusicModeDataFetchers();
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 8K program ROM image of the cartridge
// The 24K program ROM image of the cartridge
uInt8 myProgramImage[4096 * 6];
// The 2K display ROM image of the cartridge
// The 4K display ROM image of the cartridge
uInt8 myDisplayImage[4096];
// The 1K frequency table
uInt8 myFrequencyImage[1024];
// Copy of the raw image, for use by getImage()
uInt8 myImageCopy[4096 * 6 + 4096 + 255];
uInt8 myImageCopy[4096 * 6 + 4096 + 1024 + 255];
// The top registers for the data fetchers
uInt8 myTops[8];
@ -175,7 +182,10 @@ class CartridgeDPCPlus : public Cartridge
uInt8 myBottoms[8];
// The counter registers for the data fetchers
uInt16 myCounters[8];
uInt32 myCounters[8];
// The fractional increments for the data fetchers
uInt8 myFractionalIncrements[8];
// The flag registers for the data fetchers
uInt8 myFlags[8];
@ -183,8 +193,14 @@ class CartridgeDPCPlus : public Cartridge
// The music mode DF5, DF6, & DF7 enabled flags
bool myMusicMode[3];
// The music mode counters
uInt32 myMusicCounter[3];
// The music frequency addends
uInt32 myMusicFrequency[3];
// The random number generator register
uInt8 myRandomNumber;
uInt32 myRandomNumber;
// System cycle count when the last update to music data fetchers occurred
Int32 mySystemCycles;

View File

@ -22,9 +22,6 @@
#include "System.hxx"
#include "CartE0.hxx"
// TODO - Port to new CartDebug/disassembler scheme
// Add bankchanged code
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeE0::CartridgeE0(const uInt8* image)
{
@ -44,6 +41,8 @@ void CartridgeE0::reset()
segmentZero(4);
segmentOne(5);
segmentTwo(6);
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -106,7 +105,7 @@ uInt8 CartridgeE0::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeE0::poke(uInt16 address, uInt8)
bool CartridgeE0::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -123,6 +122,7 @@ void CartridgeE0::poke(uInt16 address, uInt8)
{
segmentTwo(address & 0x0007);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -145,6 +145,7 @@ void CartridgeE0::segmentZero(uInt16 slice)
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -167,6 +168,7 @@ void CartridgeE0::segmentOne(uInt16 slice)
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -189,20 +191,19 @@ void CartridgeE0::segmentTwo(uInt16 slice)
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeE0::bank(uInt16)
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartridgeE0::bank()
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
return 0;
}
@ -210,7 +211,6 @@ int CartridgeE0::bank()
int CartridgeE0::bankCount()
{
// Doesn't support bankswitching in the normal sense
// TODO - add support for debugger
return 1;
}
@ -226,7 +226,7 @@ bool CartridgeE0::patch(uInt16 address, uInt8 value)
uInt8* CartridgeE0::getImage(int& size)
{
size = 8192;
return &myImage[0];
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -33,6 +33,10 @@ class System;
1FF8 selects the slice for the third 1K. The last 1K segment
always points to the last 1K of the ROM image.
Because of the complexity of this scheme, the cart reports having
only one actual bank, in which pieces of it can be swapped out in
many different ways.
@author Bradford W. Mott
@version $Id$
*/
@ -55,7 +59,7 @@ class CartridgeE0 : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -63,26 +67,24 @@ class CartridgeE0 : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -91,7 +93,7 @@ class CartridgeE0 : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -99,7 +101,7 @@ class CartridgeE0 : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -107,7 +109,7 @@ class CartridgeE0 : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -115,14 +117,14 @@ class CartridgeE0 : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeE0"; }
string name() const { return "CartridgeE0"; }
public:
/**
@ -130,15 +132,16 @@ class CartridgeE0 : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**

View File

@ -22,10 +22,6 @@
#include "System.hxx"
#include "CartE7.hxx"
// TODO - Port to new CartDebug/disassembler scheme
// I'm not sure patch is working, since it doesn't consider RAM areas
// Add bankchanged code
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeE7::CartridgeE7(const uInt8* image)
{
@ -58,6 +54,8 @@ void CartridgeE7::reset()
// Install some default banks for the RAM and first segment
bankRAM(0);
bank(myStartBank);
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -143,7 +141,7 @@ uInt8 CartridgeE7::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeE7::poke(uInt16 address, uInt8)
bool CartridgeE7::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -160,6 +158,7 @@ void CartridgeE7::poke(uInt16 address, uInt8)
// NOTE: This does not handle writing to RAM, however, this
// function should never be called for RAM because of the
// way page accessing has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -193,6 +192,7 @@ void CartridgeE7::bankRAM(uInt16 bank)
access.directPokeBase = 0;
mySystem->setPageAccess(k >> shift, access);
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -239,6 +239,7 @@ void CartridgeE7::bank(uInt16 slice)
mySystem->setPageAccess(k >> shift, access);
}
}
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -265,7 +266,7 @@ bool CartridgeE7::patch(uInt16 address, uInt8 value)
uInt8* CartridgeE7::getImage(int& size)
{
size = 16384;
return &myImage[0];
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,6 +50,10 @@ class System;
read port. You select which 256 byte block appears
here by accessing 1FE8 to 1FEB.
This cart reports having 8 banks; 1 for each of the possible 7
slices in the lower 2K area, and the last for RAM in the lower
2K area.
@author Bradford W. Mott
@version $Id$
*/
@ -72,7 +76,7 @@ class CartridgeE7 : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -80,26 +84,24 @@ class CartridgeE7 : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -108,7 +110,7 @@ class CartridgeE7 : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -116,7 +118,7 @@ class CartridgeE7 : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -124,7 +126,7 @@ class CartridgeE7 : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -132,14 +134,14 @@ class CartridgeE7 : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeE7"; }
string name() const { return "CartridgeE7"; }
public:
/**
@ -147,15 +149,16 @@ class CartridgeE7 : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**

View File

@ -81,13 +81,15 @@ uInt8 CartridgeEF::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEF::poke(uInt16 address, uInt8)
bool CartridgeEF::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0FE0) && (address <= 0x0FEF))
bank(address - 0x0FE0);
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -73,8 +73,6 @@ class CartridgeEF : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -136,8 +134,9 @@ class CartridgeEF : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -121,7 +121,7 @@ uInt8 CartridgeEFSC::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEFSC::poke(uInt16 address, uInt8)
bool CartridgeEFSC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -132,6 +132,7 @@ void CartridgeEFSC::poke(uInt16 address, uInt8)
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -54,7 +54,7 @@ class CartridgeEFSC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -62,26 +62,24 @@ class CartridgeEFSC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -90,7 +88,7 @@ class CartridgeEFSC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -98,7 +96,7 @@ class CartridgeEFSC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -106,7 +104,7 @@ class CartridgeEFSC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -114,14 +112,14 @@ class CartridgeEFSC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeEFSC"; }
string name() const { return "CartridgeEFSC"; }
public:
/**
@ -129,15 +127,16 @@ class CartridgeEFSC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -83,13 +83,15 @@ uInt8 CartridgeF0::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF0::poke(uInt16 address, uInt8)
bool CartridgeF0::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch to next bank
if(address == 0x0FF0)
incbank();
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -70,8 +70,6 @@ class CartridgeF0 : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -133,8 +131,9 @@ class CartridgeF0 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
/**

View File

@ -84,7 +84,7 @@ uInt8 CartridgeF4::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF4::poke(uInt16 address, uInt8)
bool CartridgeF4::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -93,6 +93,8 @@ void CartridgeF4::poke(uInt16 address, uInt8)
{
bank(address - 0x0FF4);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -69,8 +69,6 @@ class CartridgeF4 : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -132,8 +130,9 @@ class CartridgeF4 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -124,7 +124,7 @@ uInt8 CartridgeF4SC::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF4SC::poke(uInt16 address, uInt8)
bool CartridgeF4SC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -135,6 +135,7 @@ void CartridgeF4SC::poke(uInt16 address, uInt8)
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,7 +50,7 @@ class CartridgeF4SC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -58,26 +58,24 @@ class CartridgeF4SC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -86,7 +84,7 @@ class CartridgeF4SC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -94,7 +92,7 @@ class CartridgeF4SC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -102,7 +100,7 @@ class CartridgeF4SC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -110,14 +108,14 @@ class CartridgeF4SC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeF4SC"; }
string name() const { return "CartridgeF4SC"; }
public:
/**
@ -125,15 +123,16 @@ class CartridgeF4SC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -104,7 +104,7 @@ uInt8 CartridgeF6::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF6::poke(uInt16 address, uInt8)
bool CartridgeF6::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -134,6 +134,7 @@ void CartridgeF6::poke(uInt16 address, uInt8)
default:
break;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -69,8 +69,6 @@ class CartridgeF6 : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -132,8 +130,9 @@ class CartridgeF6 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -144,7 +144,7 @@ uInt8 CartridgeF6SC::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF6SC::poke(uInt16 address, uInt8)
bool CartridgeF6SC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -178,6 +178,7 @@ void CartridgeF6SC::poke(uInt16 address, uInt8)
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,7 +50,7 @@ class CartridgeF6SC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -58,26 +58,24 @@ class CartridgeF6SC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -86,7 +84,7 @@ class CartridgeF6SC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -94,7 +92,7 @@ class CartridgeF6SC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -102,7 +100,7 @@ class CartridgeF6SC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -110,14 +108,14 @@ class CartridgeF6SC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeF6SC"; }
string name() const { return "CartridgeF6SC"; }
public:
/**
@ -125,15 +123,16 @@ class CartridgeF6SC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -95,7 +95,7 @@ uInt8 CartridgeF8::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF8::poke(uInt16 address, uInt8)
bool CartridgeF8::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -115,6 +115,7 @@ void CartridgeF8::poke(uInt16 address, uInt8)
default:
break;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -70,8 +70,6 @@ class CartridgeF8 : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -133,8 +131,9 @@ class CartridgeF8 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -134,7 +134,7 @@ uInt8 CartridgeF8SC::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF8SC::poke(uInt16 address, uInt8)
bool CartridgeF8SC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -158,6 +158,7 @@ void CartridgeF8SC::poke(uInt16 address, uInt8)
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,7 +50,7 @@ class CartridgeF8SC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -58,26 +58,24 @@ class CartridgeF8SC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -86,7 +84,7 @@ class CartridgeF8SC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -94,7 +92,7 @@ class CartridgeF8SC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -102,7 +100,7 @@ class CartridgeF8SC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -110,14 +108,14 @@ class CartridgeF8SC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeF8SC"; }
string name() const { return "CartridgeF8SC"; }
public:
/**
@ -125,15 +123,16 @@ class CartridgeF8SC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -139,7 +139,7 @@ uInt8 CartridgeFA::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeFA::poke(uInt16 address, uInt8)
bool CartridgeFA::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
@ -168,6 +168,7 @@ void CartridgeFA::poke(uInt16 address, uInt8)
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,7 +50,7 @@ class CartridgeFA : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -58,26 +58,24 @@ class CartridgeFA : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -86,7 +84,7 @@ class CartridgeFA : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -94,7 +92,7 @@ class CartridgeFA : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -102,7 +100,7 @@ class CartridgeFA : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -110,14 +108,14 @@ class CartridgeFA : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeFA"; }
string name() const { return "CartridgeFA"; }
public:
/**
@ -125,15 +123,16 @@ class CartridgeFA : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -54,13 +54,11 @@ void CartridgeFE::install(System& system)
// Map all of the accesses to call peek and poke
System::PageAccess access;
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
{
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(i >> shift, access);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,8 +75,9 @@ uInt8 CartridgeFE::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeFE::poke(uInt16, uInt8)
bool CartridgeFE::poke(uInt16, uInt8)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -40,6 +40,9 @@ class System;
There is *no* way to determine which bank you want to be in from
monitoring the bus.
This cart reports having 2 banks, even though this cannot be
determined on a real system.
@author Bradford W. Mott
@version $Id$
*/
@ -81,8 +84,6 @@ class CartridgeFE : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -152,8 +153,9 @@ class CartridgeFE : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// The 8K ROM image of the cartridge

View File

@ -25,8 +25,8 @@
// TODO - much more testing of this scheme is required
// No test ROMs exist as of 2009-11-08, so we can't be sure how
// accurate the emulation is
// Port to new CartDebug/disassembler scheme
// Add bankchanged code
// Bankchange and RAM modification cannot be completed until
// adequate test ROMs are available
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeMC::CartridgeMC(const uInt8* image, uInt32 size)
@ -53,6 +53,8 @@ void CartridgeMC::reset()
// Initialize RAM with random values
for(uInt32 i = 0; i < 32768; ++i)
myRAM[i] = mySystem->randGenerator().next();
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -74,27 +76,21 @@ void CartridgeMC::install(System& system)
// 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;
for(uInt32 i = 0x00; i < 0x40; i += (1 << shift))
{
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(i >> shift, access);
}
// Map the cartridge into the system
for(uInt32 j = 0x1000; j < 0x2000; j += (1 << shift))
{
access.device = this;
access.directPeekBase = 0;
access.directPokeBase = 0;
mySystem->setPageAccess(j >> shift, access);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeMC::peek(uInt16 address)
{
uInt16 peekAddress = address;
address &= 0x1FFF;
// Accessing the RESET vector so lets handle the powerup special case
@ -148,15 +144,20 @@ uInt8 CartridgeMC::peek(uInt16 address)
// Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF);
if(bankLocked()) return value;
else return myRAM[(uInt32)((block & 0x3F) << 9) + (address & 0x01FF)] = value;
if(bankLocked())
return value;
else
{
triggerReadFromWritePort(peekAddress);
return myRAM[(uInt32)((block & 0x3F) << 9) + (address & 0x01FF)] = value;
}
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeMC::poke(uInt16 address, uInt8 value)
bool CartridgeMC::poke(uInt16 address, uInt8 value)
{
address &= 0x1FFF;
@ -196,14 +197,16 @@ void CartridgeMC::poke(uInt16 address, uInt8 value)
{
// Handle the write to RAM
myRAM[(uInt32)((block & 0x3F) << 9) + (address & 0x01FF)] = value;
return true;
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeMC::bank(uInt16 b)
{
// TODO - add support for debugger
// Doesn't support bankswitching in the normal sense
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -231,7 +234,7 @@ bool CartridgeMC::patch(uInt16 address, uInt8 value)
uInt8* CartridgeMC::getImage(int& size)
{
size = 128 * 1024; // FIXME: keep track of original size
return &myImage[0];
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -157,7 +157,7 @@ class CartridgeMC : public Cartridge
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install cartridge in the specified system. Invoked by the system
@ -165,26 +165,24 @@ class CartridgeMC : public Cartridge
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
virtual void bank(uInt16 bank);
void bank(uInt16 bank);
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
virtual int bank();
int bank();
/**
Query the number of banks supported by the cartridge.
*/
virtual int bankCount();
int bankCount();
/**
Patch the cartridge ROM.
@ -193,7 +191,7 @@ class CartridgeMC : public Cartridge
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@ -201,7 +199,7 @@ class CartridgeMC : public Cartridge
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
virtual uInt8* getImage(int& size);
uInt8* getImage(int& size);
/**
Save the current state of this cart to the given Serializer.
@ -209,7 +207,7 @@ class CartridgeMC : public Cartridge
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@ -217,14 +215,14 @@ class CartridgeMC : public Cartridge
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "CartridgeMC"; }
string name() const { return "CartridgeMC"; }
public:
/**
@ -232,15 +230,16 @@ class CartridgeMC : public Cartridge
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// The 128K ROM image for the cartridge

View File

@ -105,7 +105,7 @@ uInt8 CartridgeSB::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeSB::poke(uInt16 address, uInt8 value)
bool CartridgeSB::poke(uInt16 address, uInt8 value)
{
address = address & (0x17FF + (mySize >> 12));
@ -120,6 +120,7 @@ void CartridgeSB::poke(uInt16 address, uInt8 value)
int hotspot = ((address & 0x0F00) >> 8) - 8;
myHotSpotPageAccess[hotspot].device->poke(address, value);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -67,8 +67,6 @@ class CartridgeSB : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -130,8 +128,9 @@ class CartridgeSB : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// The 128-256K ROM image and size of the cartridge

View File

@ -103,7 +103,7 @@ uInt8 CartridgeUA::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeUA::poke(uInt16 address, uInt8 value)
bool CartridgeUA::poke(uInt16 address, uInt8 value)
{
address &= 0x1FFF;
@ -128,6 +128,7 @@ void CartridgeUA::poke(uInt16 address, uInt8 value)
{
myHotSpotPageAccess.device->poke(address, value);
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -70,8 +70,6 @@ class CartridgeUA : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -133,8 +131,9 @@ class CartridgeUA : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -97,7 +97,7 @@ uInt8 CartridgeX07::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeX07::poke(uInt16 address, uInt8 value)
bool CartridgeX07::poke(uInt16 address, uInt8 value)
{
// Check for RAM or TIA mirroring
uInt16 lowAddress = address & 0x3ff;
@ -114,6 +114,7 @@ void CartridgeX07::poke(uInt16 address, uInt8 value)
if((myCurrentBank & 0xe) == 0xe)
bank(((address & 0x40) >> 6) | (myCurrentBank & 0xe));
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -79,8 +79,6 @@ class CartridgeX07 : public Cartridge
/**
Get the current bank.
@return The current bank, or -1 if bankswitching not supported
*/
int bank();
@ -142,8 +140,9 @@ class CartridgeX07 : public Cartridge
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active

View File

@ -105,8 +105,10 @@ class Device : public Serializable
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value) = 0;
virtual bool poke(uInt16 address, uInt8 value) = 0;
protected:
/// Pointer to the system the device is installed in or the null pointer

View File

@ -204,7 +204,7 @@ uInt8 M6532::peek(uInt16 addr)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6532::poke(uInt16 addr, uInt8 value)
bool M6532::poke(uInt16 addr, uInt8 value)
{
// Access RAM directly. Originally, accesses to RAM could bypass
// this method and its pages could be installed directly into the
@ -213,7 +213,7 @@ void M6532::poke(uInt16 addr, uInt8 value)
if((addr & 0x1080) == 0x0080 && (addr & 0x0200) == 0x0000)
{
myRAM[addr & 0x007f] = value;
return;
return true;
}
// A2 distinguishes I/O registers from the timer
@ -244,9 +244,10 @@ void M6532::poke(uInt16 addr, uInt8 value)
}
default: // Port B I/O & DDR Registers (Console switches)
break; // hardwired as read-only
return false; // hardwired as read-only
}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -57,14 +57,14 @@ class M6532 : public Device
/**
Reset cartridge to its power-on state
*/
virtual void reset();
void reset();
/**
Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary
to override this method for devices that remember cycle counts.
*/
virtual void systemCyclesReset();
void systemCyclesReset();
/**
Install 6532 in the specified system. Invoked by the system
@ -72,7 +72,7 @@ class M6532 : public Device
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Install 6532 in the specified system and device. Invoked by
@ -83,7 +83,7 @@ class M6532 : public Device
@param system The system the device should install itself in
@param device The device responsible for this address space
*/
virtual void install(System& system, Device& device);
void install(System& system, Device& device);
/**
Save the current state of this device to the given Serializer.
@ -91,7 +91,7 @@ class M6532 : public Device
@param out The Serializer object to use
@return False on any errors, else true
*/
virtual bool save(Serializer& out) const;
bool save(Serializer& out) const;
/**
Load the current state of this device from the given Serializer.
@ -99,14 +99,14 @@ class M6532 : public Device
@param in The Serializer object to use
@return False on any errors, else true
*/
virtual bool load(Serializer& in);
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
virtual string name() const { return "M6532"; }
string name() const { return "M6532"; }
public:
/**
@ -114,15 +114,17 @@ class M6532 : public Device
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
private:
inline Int32 timerClocks()

View File

@ -48,9 +48,10 @@ uInt8 NullDevice::peek(uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NullDevice::poke(uInt16 address, uInt8 value)
bool NullDevice::poke(uInt16 address, uInt8 value)
{
cerr << hex << "NullDevice: poke(" << address << "," << value << ")" << endl;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -49,7 +49,7 @@ class NullDevice : public Device
/**
Reset device to its power-on state
*/
virtual void reset();
void reset();
/**
Install device in the specified system. Invoked by the system
@ -57,7 +57,7 @@ class NullDevice : public Device
@param system The system the device should install itself in
*/
virtual void install(System& system);
void install(System& system);
/**
Save the current state of this device to the given Serializer.
@ -88,15 +88,17 @@ class NullDevice : public Device
@return The byte at the specified address
*/
virtual uInt8 peek(uInt16 address);
uInt8 peek(uInt16 address);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
virtual void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
};
#endif

View File

@ -258,10 +258,8 @@ void System::poke(uInt16 addr, uInt8 value)
}
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);
// The specific device informs us if the poke succeeded
myPageIsDirtyTable[page] = access.device->poke(addr, value);
}
#ifdef DEBUGGER_SUPPORT

View File

@ -166,7 +166,7 @@ class System : public Serializable
@return The total number of pages available
*/
uInt16 numberOfPages() const
inline uInt16 numberOfPages() const
{
return myNumberOfPages;
}
@ -176,7 +176,7 @@ class System : public Serializable
@return The amount to right shift an address by to get its page
*/
uInt16 pageShift() const
inline uInt16 pageShift() const
{
return myPageShift;
}
@ -186,7 +186,7 @@ class System : public Serializable
@return The mask to apply to an address to obtain its page offset
*/
uInt16 pageMask() const
inline uInt16 pageMask() const
{
return myPageMask;
}
@ -198,7 +198,7 @@ class System : public Serializable
@return The number of system cycles which have passed
*/
uInt32 cycles() const
inline uInt32 cycles() const
{
return myCycles;
}
@ -269,10 +269,10 @@ class System : public Serializable
No masking of the address occurs before it's sent to the device
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().
This method sets the 'page dirty' if the write succeeds. In the
case of direct-access pokes, the write always succeeds. Otherwise,
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

View File

@ -1252,7 +1252,7 @@ uInt8 TIA::peek(uInt16 addr)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::poke(uInt16 addr, uInt8 value)
bool TIA::poke(uInt16 addr, uInt8 value)
{
addr = addr & 0x003f;
@ -2036,6 +2036,7 @@ void TIA::poke(uInt16 addr, uInt8 value)
break;
}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -155,8 +155,10 @@ class TIA : public Device
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
void poke(uInt16 address, uInt8 value);
bool poke(uInt16 address, uInt8 value);
/**
This method should be called at an interval corresponding to the