Implemented console timing changes in a more general way.

There is now a virtual consoleChanged() method called on
a device when the console changes.  If the device is
interested in this notification, it simply has to implement
the method.

Updated DPC+ scheme to implement this method, so that the
Thumbulator object is automatically told whenever the console
changes, and can adjust its internal timing accordingly.
This commit is contained in:
Stephen Anthony 2017-03-22 15:46:48 -02:30
parent ee1fdfa565
commit db3ce957a5
6 changed files with 55 additions and 18 deletions

View File

@ -104,6 +104,14 @@ void CartridgeDPCPlus::setInitialState()
myRandomNumber = 0x2B435044; // "DPC+" myRandomNumber = 0x2B435044; // "DPC+"
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::consoleChanged(ConsoleTiming timing)
{
#ifdef THUMB_SUPPORT
myThumbEmulator->setConsoleTiming(timing);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::systemCyclesReset() void CartridgeDPCPlus::systemCyclesReset()
{ {
@ -194,17 +202,7 @@ inline void CartridgeDPCPlus::callFunction(uInt8 value)
try { try {
Int32 cycles = mySystem->cycles() - myARMCycles; Int32 cycles = mySystem->cycles() - myARMCycles;
myARMCycles = mySystem->cycles(); myARMCycles = mySystem->cycles();
// setConsoleTiming should go elsewhere for one-time-setup, but doesn't
// work in install()
//
// if put in setInitialState() Stella ends up crashing in System.hxx at
// TIA& tia() const { return myTIA; }
// with error
// "Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)"
myThumbEmulator->setConsoleTiming(mySystem->tia().consoleTiming());
myThumbEmulator->run(cycles); myThumbEmulator->run(cycles);
} }
catch(const runtime_error& e) { catch(const runtime_error& e) {
@ -700,8 +698,8 @@ bool CartridgeDPCPlus::save(Serializer& out) const
// Get system cycles and fractional clocks // Get system cycles and fractional clocks
out.putInt(mySystemCycles); out.putInt(mySystemCycles);
out.putInt(uInt32(myFractionalClocks * 100000000.0)); out.putInt(uInt32(myFractionalClocks * 100000000.0));
// clock info for Thumbulator // Clock info for Thumbulator
out.putInt(myARMCycles); out.putInt(myARMCycles);
} }
catch(...) catch(...)
@ -764,9 +762,9 @@ bool CartridgeDPCPlus::load(Serializer& in)
// Get system cycles and fractional clocks // Get system cycles and fractional clocks
mySystemCycles = in.getInt(); mySystemCycles = in.getInt();
myFractionalClocks = double(in.getInt()) / 100000000.0; myFractionalClocks = double(in.getInt()) / 100000000.0;
// clock info for Thumbulator // Clock info for Thumbulator
myARMCycles = (Int32)in.getInt(); myARMCycles = in.getInt();
} }
catch(...) catch(...)
{ {

View File

@ -62,6 +62,15 @@ class CartridgeDPCPlus : public Cartridge
*/ */
void reset() override; void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/** /**
Notification method invoked by the system right before the Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary system resets its cycle counter to zero. It may be necessary
@ -259,8 +268,8 @@ class CartridgeDPCPlus : public Cartridge
// Fractional DPC music OSC clocks unused during the last update // Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks; double myFractionalClocks;
// System cycle count when the last Thumbulator->Run() occurred // System cycle count when the last Thumbulator::run() occurred
Int32 myARMCycles; Int32 myARMCycles;
// Indicates which bank is currently active // Indicates which bank is currently active

View File

@ -201,6 +201,9 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
myConsoleInfo.BankSwitch = myCart->about(); myConsoleInfo.BankSwitch = myCart->about();
myCart->setRomName(myConsoleInfo.CartName); myCart->setRomName(myConsoleInfo.CartName);
// Let the other devices know about the new console
mySystem->consoleChanged(myConsoleTiming);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -316,6 +319,9 @@ void Console::toggleFormat(int direction)
initializeVideo(); // takes care of refreshing the screen initializeVideo(); // takes care of refreshing the screen
myOSystem.frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
// Let the other devices know about the console change
mySystem->consoleChanged(myConsoleTiming);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -20,6 +20,7 @@
class System; class System;
#include "Console.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
#include "bspf.hxx" #include "bspf.hxx"
@ -45,6 +46,15 @@ class Device : public Serializable
*/ */
virtual void reset() = 0; virtual void reset() = 0;
/**
Notification method invoked by the system when the console type
has changed. It may be necessary to override this method for
devices that want to know about console changes.
@param timing Enum representing the new console type
*/
virtual void consoleChanged(ConsoleTiming timing) { }
/** /**
Notification method invoked by the system right before the Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary system resets its cycle counter to zero. It may be necessary
@ -107,6 +117,7 @@ class Device : public Serializable
@param address The address to modify @param address The address to modify
*/ */
virtual uInt8 getAccessFlags(uInt16 address) const { return 0; } virtual uInt8 getAccessFlags(uInt16 address) const { return 0; }
/** /**
Change the given address type to use the given disassembly flags Change the given address type to use the given disassembly flags

View File

@ -94,6 +94,14 @@ void System::resetCycles()
myCycles = 0; myCycles = 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::consoleChanged(ConsoleTiming timing)
{
myM6532.consoleChanged(timing);
myTIA.consoleChanged(timing);
myCart.consoleChanged(timing);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool System::isPageDirty(uInt16 start_addr, uInt16 end_addr) const bool System::isPageDirty(uInt16 start_addr, uInt16 end_addr) const
{ {

View File

@ -148,6 +148,11 @@ class System : public Serializable
*/ */
void resetCycles(); void resetCycles();
/**
Informs all attached devices that the console type has changed.
*/
void consoleChanged(ConsoleTiming timing);
/** /**
Answers whether the system is currently in device autodetect mode. Answers whether the system is currently in device autodetect mode.
*/ */