diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index caf595351..f95b2cf7f 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -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+"; } diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 0383b05d3..70d41456d 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -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; diff --git a/src/emucore/Cart0840.cxx b/src/emucore/Cart0840.cxx index 66916d528..1cb2474b5 100644 --- a/src/emucore/Cart0840.cxx +++ b/src/emucore/Cart0840.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart0840.hxx b/src/emucore/Cart0840.hxx index 7762de8e1..8621020e5 100644 --- a/src/emucore/Cart0840.hxx +++ b/src/emucore/Cart0840.hxx @@ -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 diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index 0c7c42d42..899f24ae0 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index 5b9b16c03..13a78dc60 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -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 diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index d4fc63f59..90ef00731 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 2cf249f53..a8d052857 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -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 diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 1c8a70358..330e408ae 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index 45a89ae08..e14f916e4 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -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 diff --git a/src/emucore/Cart4A50.cxx b/src/emucore/Cart4A50.cxx index 87ce6718e..291110cd1 100644 --- a/src/emucore/Cart4A50.cxx +++ b/src/emucore/Cart4A50.cxx @@ -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; } diff --git a/src/emucore/Cart4A50.hxx b/src/emucore/Cart4A50.hxx index 272298f95..46d146391 100644 --- a/src/emucore/Cart4A50.hxx +++ b/src/emucore/Cart4A50.hxx @@ -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: /** diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index 6029c82ba..0ee016780 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart4K.hxx b/src/emucore/Cart4K.hxx index e4c9ce728..0f0aa2c47 100644 --- a/src/emucore/Cart4K.hxx +++ b/src/emucore/Cart4K.hxx @@ -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 diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index cc1cc6f9a..b71a856a7 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -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 } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 4766e627d..38144efd9 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -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 diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index cbb440806..972dfb4cd 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -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; } diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index 00decd512..462fb5f35 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -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; diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index 4ec02ed80..88e9fec7f 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index 0e0cb6efc..383a6bdc3 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -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: /** diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 84c00b6cd..23b49dd00 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -18,21 +18,17 @@ #include #include -#include #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(); diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 02b7e5275..e09547dee 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -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; diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index a3bb7c2c0..1ac6c68e6 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 71e675190..8457c206c 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -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: /** diff --git a/src/emucore/CartE7.cxx b/src/emucore/CartE7.cxx index c23d959cc..4af29577b 100644 --- a/src/emucore/CartE7.cxx +++ b/src/emucore/CartE7.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartE7.hxx b/src/emucore/CartE7.hxx index 2f6e68fad..b6b30de75 100644 --- a/src/emucore/CartE7.hxx +++ b/src/emucore/CartE7.hxx @@ -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: /** diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index a390f4be7..17cfd47ea 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEF.hxx b/src/emucore/CartEF.hxx index f890c4028..ca23c71ff 100644 --- a/src/emucore/CartEF.hxx +++ b/src/emucore/CartEF.hxx @@ -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 diff --git a/src/emucore/CartEFSC.cxx b/src/emucore/CartEFSC.cxx index 744821024..8424bb7da 100644 --- a/src/emucore/CartEFSC.cxx +++ b/src/emucore/CartEFSC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEFSC.hxx b/src/emucore/CartEFSC.hxx index 8e1df5bc3..54ac263a8 100644 --- a/src/emucore/CartEFSC.hxx +++ b/src/emucore/CartEFSC.hxx @@ -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 diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index 7e76a03a4..b2ab28434 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index 95c8f77f8..059fa9634 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -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: /** diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index b18590547..c837b80de 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index 371716905..4bcf7fdea 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -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 diff --git a/src/emucore/CartF4SC.cxx b/src/emucore/CartF4SC.cxx index fcb1c93ef..4dd49fd87 100644 --- a/src/emucore/CartF4SC.cxx +++ b/src/emucore/CartF4SC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index ce0cb632f..4658f43a5 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -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 diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 0ca513d34..6e708c8e1 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 5ed8bc7ca..149ef03ac 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -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 diff --git a/src/emucore/CartF6SC.cxx b/src/emucore/CartF6SC.cxx index 85d6ed27c..50ab59325 100644 --- a/src/emucore/CartF6SC.cxx +++ b/src/emucore/CartF6SC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index c0ef36412..dab3b0514 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -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 diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index 0616ad98a..76a91b522 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index 4706a8330..7e33fce9a 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -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 diff --git a/src/emucore/CartF8SC.cxx b/src/emucore/CartF8SC.cxx index d5d454c4d..e282b19f7 100644 --- a/src/emucore/CartF8SC.cxx +++ b/src/emucore/CartF8SC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index 20c4c185d..45cf40b9e 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -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 diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index a51965400..08cd7f3dc 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index 209247bc1..b5c5c3c44 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -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 diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 138a0bb24..3d21cb9b9 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index 0a317b2d0..f56df0b54 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -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 diff --git a/src/emucore/CartMC.cxx b/src/emucore/CartMC.cxx index 36d4b44fc..fcca1fcc1 100644 --- a/src/emucore/CartMC.cxx +++ b/src/emucore/CartMC.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartMC.hxx b/src/emucore/CartMC.hxx index 25b6dc64e..eb0536a7e 100644 --- a/src/emucore/CartMC.hxx +++ b/src/emucore/CartMC.hxx @@ -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 diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 2042ed30b..7ab9de97e 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index abd02755d..07c32d99f 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -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 diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 6314ffb49..8f0d6dfd0 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 8a4c60646..52542ccff 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -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 diff --git a/src/emucore/CartX07.cxx b/src/emucore/CartX07.cxx index 06f1a3d15..483776220 100644 --- a/src/emucore/CartX07.cxx +++ b/src/emucore/CartX07.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartX07.hxx b/src/emucore/CartX07.hxx index c1caae364..cbb5e30c0 100644 --- a/src/emucore/CartX07.hxx +++ b/src/emucore/CartX07.hxx @@ -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 diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx index fef165119..3c95b4655 100644 --- a/src/emucore/Device.hxx +++ b/src/emucore/Device.hxx @@ -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 diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index d41e5667a..66e7c8198 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index c9b43a97f..449b5632e 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -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() diff --git a/src/emucore/NullDev.cxx b/src/emucore/NullDev.cxx index b922e41f7..45ef6006d 100644 --- a/src/emucore/NullDev.cxx +++ b/src/emucore/NullDev.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/NullDev.hxx b/src/emucore/NullDev.hxx index e49246c4b..383385197 100644 --- a/src/emucore/NullDev.hxx +++ b/src/emucore/NullDev.hxx @@ -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 diff --git a/src/emucore/System.cxx b/src/emucore/System.cxx index 814f37105..f576dcbcf 100644 --- a/src/emucore/System.cxx +++ b/src/emucore/System.cxx @@ -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 diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index 84cbc6d87..ca4bd8353 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -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 diff --git a/src/emucore/TIA.cxx b/src/emucore/TIA.cxx index 58c99072d..7828eaca2 100644 --- a/src/emucore/TIA.cxx +++ b/src/emucore/TIA.cxx @@ -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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/TIA.hxx b/src/emucore/TIA.hxx index bb39c3b0e..ac89d9e88 100644 --- a/src/emucore/TIA.hxx +++ b/src/emucore/TIA.hxx @@ -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