diff --git a/src/common/SoundNull.hxx b/src/common/SoundNull.hxx index cda9ab671..768da91d5 100644 --- a/src/common/SoundNull.hxx +++ b/src/common/SoundNull.hxx @@ -56,14 +56,6 @@ class SoundNull : public Sound */ void setEnabled(bool enable) override { } - /** - The system cycle counter is being adjusting by the specified amount. Any - members using the system cycle counter should be adjusted as needed. - - @param amount The amount the cycle counter is being adjusted by - */ - void adjustCycleCounter(Int32 amount) override { } - /** Sets the number of channels (mono or stereo sound). @@ -110,7 +102,7 @@ class SoundNull : public Sound @param value The value to save into the register @param cycle The system cycle at which the register is being updated */ - void set(uInt16 addr, uInt8 value, Int32 cycle) override { } + void set(uInt16 addr, uInt8 value, uInt64 cycle) override { } /** Sets the volume of the sound device to the specified level. The diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 04e37ca99..34fe07b16 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -226,12 +226,6 @@ void SoundSDL2::adjustVolume(Int8 direction) myOSystem.frameBuffer().showMessage(message); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SoundSDL2::adjustCycleCounter(Int32 amount) -{ - myLastRegisterSetCycle += amount; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SoundSDL2::setChannels(uInt32 channels) { @@ -249,7 +243,7 @@ void SoundSDL2::setFrameRate(float framerate) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SoundSDL2::set(uInt16 addr, uInt8 value, Int32 cycle) +void SoundSDL2::set(uInt16 addr, uInt8 value, uInt64 cycle) { SDL_LockAudio(); @@ -386,7 +380,7 @@ bool SoundSDL2::save(Serializer& out) const for(int i = 0; i < 6; ++i) out.putByte(0); - out.putInt(myLastRegisterSetCycle); + out.putLong(myLastRegisterSetCycle); } catch(...) { @@ -423,7 +417,7 @@ bool SoundSDL2::load(Serializer& in) for(int i = 0; i < 6; ++i) in.getByte(); - myLastRegisterSetCycle = in.getInt(); + myLastRegisterSetCycle = in.getLong(); } catch(...) { diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 914a7150d..faa9a72b9 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -55,14 +55,6 @@ class SoundSDL2 : public Sound */ void setEnabled(bool state) override; - /** - The system cycle counter is being adjusting by the specified amount. Any - members using the system cycle counter should be adjusted as needed. - - @param amount The amount the cycle counter is being adjusted by - */ - void adjustCycleCounter(Int32 amount) override; - /** Sets the number of channels (mono or stereo sound). Note that this determines how the emulation should 'mix' the channels of the TIA sound @@ -113,7 +105,7 @@ class SoundSDL2 : public Sound @param value The value to save into the register @param cycle The system cycle at which the register is being updated */ - void set(uInt16 addr, uInt8 value, Int32 cycle) override; + void set(uInt16 addr, uInt8 value, uInt64 cycle) override; /** Sets the volume of the sound device to the specified level. The @@ -258,7 +250,7 @@ class SoundSDL2 : public Sound bool myIsInitializedFlag; // Indicates the cycle when a sound register was last set - Int32 myLastRegisterSetCycle; + uInt64 myLastRegisterSetCycle; // Indicates the number of channels (mono or stereo) uInt32 myNumChannels; diff --git a/src/common/StateManager.cxx b/src/common/StateManager.cxx index b22b34ce1..f1073f5d6 100644 --- a/src/common/StateManager.cxx +++ b/src/common/StateManager.cxx @@ -28,7 +28,7 @@ #include "StateManager.hxx" -#define STATE_HEADER "05000300state" +#define STATE_HEADER "05000301state" #define MOVIE_HEADER "03030000movie" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 21e72f619..b5154c37e 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -99,6 +99,7 @@ static const char* const pseudo_registers[][2] = { { "_rwport", "Address at which a read from a write port occurred" }, { "_scan", "Current scanline count" }, { "_fcount", "Number of frames since emulation started" }, +//FIXME { "_fcycles", "Number of cycles since frame started" }, { "_cclocks", "Color clocks on current scanline" }, { "_vsync", "Whether vertical sync is enabled (1 or 0)" }, { "_vblank", "Whether vertical blank is enabled (1 or 0)" }, @@ -302,13 +303,13 @@ int Debugger::step() saveOldState(); mySystem.clearDirtyPages(); - int cyc = mySystem.cycles(); + uInt64 startCycle = mySystem.cycles(); unlockBankswitchState(); myOSystem.console().tia().updateScanlineByStep().flushLineCache(); lockBankswitchState(); - return mySystem.cycles() - cyc; + return int(mySystem.cycles() - startCycle); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -330,14 +331,14 @@ int Debugger::trace() saveOldState(); mySystem.clearDirtyPages(); - int cyc = mySystem.cycles(); + uInt64 startCycle = mySystem.cycles(); int targetPC = myCpuDebug->pc() + 3; // return address unlockBankswitchState(); myOSystem.console().tia().updateScanlineByTrace(targetPC).flushLineCache(); lockBankswitchState(); - return mySystem.cycles() - cyc; + return int(mySystem.cycles() - startCycle); } else return step(); diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 2a9bda8e5..0cc3731f1 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -153,11 +153,6 @@ class Debugger : public DialogContainer */ const string run(const string& command); - /** - The current cycle count of the System. - */ - int cycles() const { return int(mySystem.cycles()); } - string autoExec(); string showWatches(); diff --git a/src/debugger/TIADebug.cxx b/src/debugger/TIADebug.cxx index 982632e05..86aae9bcf 100644 --- a/src/debugger/TIADebug.cxx +++ b/src/debugger/TIADebug.cxx @@ -694,6 +694,12 @@ int TIADebug::frameCount() const return myTIA.myFrameManager.frameCount(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int TIADebug::frameCycles() const +{ + return myTIA.frameCycles(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int TIADebug::scanlines() const { diff --git a/src/debugger/TIADebug.hxx b/src/debugger/TIADebug.hxx index 1a33c262b..cdebc0878 100644 --- a/src/debugger/TIADebug.hxx +++ b/src/debugger/TIADebug.hxx @@ -159,6 +159,7 @@ class TIADebug : public DebuggerSystem int scanlines() const; int scanlinesLastFrame() const; int frameCount() const; + int frameCycles() const; int clocksThisLine() const; bool vsync() const; bool vblank() const; diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index ba444a561..f42d5abd8 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -129,7 +129,7 @@ void TiaInfoWidget::loadConfig() TIADebug& tia = dbg.tiaDebug(); myFrameCount->setText(Common::Base::toString(tia.frameCount(), Common::Base::F_10)); - myFrameCycles->setText(Common::Base::toString(dbg.cycles(), Common::Base::F_10)); + myFrameCycles->setText(Common::Base::toString(tia.frameCycles(), Common::Base::F_10)); myVSync->setState(tia.vsync()); myVBlank->setState(tia.vblank()); diff --git a/src/emucore/AtariVox.cxx b/src/emucore/AtariVox.cxx index 55e417d54..e990775e4 100644 --- a/src/emucore/AtariVox.cxx +++ b/src/emucore/AtariVox.cxx @@ -99,13 +99,12 @@ void AtariVox::write(DigitalPin pin, bool value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AtariVox::clockDataIn(bool value) { - uInt32 cycle = mySystem.cycles(); - if(value && (myShiftCount == 0)) return; // If this is the first write this frame, or if it's been a long time // since the last write, start a new data byte. + uInt64 cycle = mySystem.cycles(); if((cycle < myLastDataWriteCycle) || (cycle > myLastDataWriteCycle + 1000)) { myShiftRegister = 0; @@ -138,6 +137,13 @@ void AtariVox::clockDataIn(bool value) myLastDataWriteCycle = cycle; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void AtariVox::reset() +{ + myLastDataWriteCycle = mySystem.cycles(); + myEEPROM->systemReset(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AtariVox::close() { @@ -145,16 +151,6 @@ void AtariVox::close() myEEPROM.reset(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void AtariVox::systemCyclesReset() -{ - myLastDataWriteCycle -= mySystem.cycles(); - - // The EEPROM keeps track of cycle counts, and needs to know when the - // cycles are reset - myEEPROM->systemCyclesReset(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string AtariVox::about() const { diff --git a/src/emucore/AtariVox.hxx b/src/emucore/AtariVox.hxx index 323925d2b..2992b052d 100644 --- a/src/emucore/AtariVox.hxx +++ b/src/emucore/AtariVox.hxx @@ -79,6 +79,13 @@ class AtariVox : public Controller */ void update() override { } + /** + Notification method invoked by the system after its reset method has + been called. It may be necessary to override this method for + controllers that need to know a reset has occurred. + */ + void reset() override; + /** Notification method invoked by the system indicating that the console is about to be destroyed. It may be necessary to override @@ -86,13 +93,6 @@ class AtariVox : public Controller */ void close() override; - /** - 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. - */ - void systemCyclesReset() override; - string about() const override; private: @@ -121,7 +121,7 @@ class AtariVox : public Controller // The real SpeakJet chip reads data at 19200 bits/sec. Alex's // driver code sends data at 62 CPU cycles per bit, which is // "close enough". - uInt32 myLastDataWriteCycle; + uInt64 myLastDataWriteCycle; // Holds information concerning serial port usage string myAboutString; diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index ca0a0346c..6b3025ea0 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -26,7 +26,6 @@ CartridgeAR::CartridgeAR(const BytePtr& image, uInt32 size, mySize(std::max(size, 8448u)), myWriteEnabled(false), myPower(true), - myPowerRomCycle(0), myDataHoldRegister(0), myNumberOfDistinctAccesses(0), myWritePending(false), @@ -64,7 +63,6 @@ void CartridgeAR::reset() myWriteEnabled = false; myPower = true; - myPowerRomCycle = mySystem->cycles(); myDataHoldRegister = 0; myNumberOfDistinctAccesses = 0; @@ -74,13 +72,6 @@ void CartridgeAR::reset() bankConfiguration(0); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeAR::systemCyclesReset() -{ - // Adjust cycle values - myPowerRomCycle -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeAR::install(System& system) { @@ -243,11 +234,6 @@ bool CartridgeAR::bankConfiguration(uInt8 configuration) // Handle ROM power configuration myPower = !(configuration & 0x01); - if(myPower) - { - myPowerRomCycle = mySystem->cycles(); - } - myWriteEnabled = configuration & 0x02; switch((configuration >> 2) & 0x07) @@ -474,9 +460,6 @@ bool CartridgeAR::save(Serializer& out) const // Indicates if the ROM's power is on or off out.putBool(myPower); - // Indicates when the power was last turned on - out.putInt(myPowerRomCycle); - // Data hold register used for writing out.putByte(myDataHoldRegister); @@ -525,9 +508,6 @@ bool CartridgeAR::load(Serializer& in) // Indicates if the ROM's power is on or off myPower = in.getBool(); - // Indicates when the power was last turned on - myPowerRomCycle = in.getInt(); - // Data hold register used for writing myDataHoldRegister = in.getByte(); diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index c7f13d57d..9e33ee1d1 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -60,13 +60,6 @@ class CartridgeAR : public Cartridge */ void reset() override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -208,9 +201,6 @@ class CartridgeAR : public Cartridge // Indicates if the ROM's power is on or off bool myPower; - // Indicates when the power was last turned on - Int32 myPowerRomCycle; - // Data hold register used for writing uInt8 myDataHoldRegister; diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index cb733b47b..8b89f0d9d 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -112,14 +112,6 @@ void CartridgeBUS::consoleChanged(ConsoleTiming timing) #endif } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBUS::systemCyclesReset() -{ - // Adjust the cycle counter so that it reflects the new value - mySystemCycles -= mySystem->cycles(); - myARMCycles -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeBUS::install(System& system) { @@ -143,7 +135,7 @@ void CartridgeBUS::install(System& system) inline void CartridgeBUS::updateMusicModeDataFetchers() { // Calculate the number of cycles since the last update - Int32 cycles = mySystem->cycles() - mySystemCycles; + Int32 cycles = Int32(mySystem->cycles() - mySystemCycles); mySystemCycles = mySystem->cycles(); // Calculate the number of BUS OSC clocks since the last update @@ -170,7 +162,7 @@ inline void CartridgeBUS::callFunction(uInt8 value) // time for Stella as ARM code "runs in zero 6507 cycles". case 255: // call without IRQ driven audio try { - Int32 cycles = mySystem->cycles() - myARMCycles; + Int32 cycles = Int32(mySystem->cycles() - myARMCycles); myARMCycles = mySystem->cycles(); myThumbEmulator->run(cycles); @@ -570,9 +562,9 @@ bool CartridgeBUS::save(Serializer& out) const out.putShort(myJMPoperandAddress); // Save cycles and clocks - out.putInt(mySystemCycles); + out.putLong(mySystemCycles); out.putInt((uInt32)(myFractionalClocks * 100000000.0)); - out.putInt(myARMCycles); + out.putLong(myARMCycles); // Audio info out.putIntArray(myMusicCounters, 3); @@ -614,9 +606,9 @@ bool CartridgeBUS::load(Serializer& in) myJMPoperandAddress = in.getShort(); // Get system cycles and fractional clocks - mySystemCycles = (Int32)in.getInt(); + mySystemCycles = in.getLong(); myFractionalClocks = (double)in.getInt() / 100000000.0; - myARMCycles = (Int32)in.getInt(); + myARMCycles = in.getLong(); // Audio info in.getIntArray(myMusicCounters, 3); diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 58f335e7a..ce8dc161a 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -73,13 +73,6 @@ class CartridgeBUS : public Cartridge */ void consoleChanged(ConsoleTiming timing) override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -252,10 +245,10 @@ class CartridgeBUS : public Cartridge uInt16 myJMPoperandAddress; // System cycle count when the last update to music data fetchers occurred - Int32 mySystemCycles; + uInt64 mySystemCycles; // ARM cycle count from when the last callFunction() occurred - Int32 myARMCycles; + uInt64 myARMCycles; // The music mode counters uInt32 myMusicCounters[3]; diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 7c1f1c2c7..1c55bf0da 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -119,14 +119,6 @@ void CartridgeCDF::consoleChanged(ConsoleTiming timing) #endif } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCDF::systemCyclesReset() -{ - // Adjust the cycle counter so that it reflects the new value - myAudioCycles -= mySystem->cycles(); - myARMCycles -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDF::install(System& system) { @@ -145,7 +137,7 @@ void CartridgeCDF::install(System& system) inline void CartridgeCDF::updateMusicModeDataFetchers() { // Calculate the number of cycles since the last update - Int32 cycles = mySystem->cycles() - myAudioCycles; + Int32 cycles = Int32(mySystem->cycles() - myAudioCycles); myAudioCycles = mySystem->cycles(); // Calculate the number of CDF OSC clocks since the last update @@ -172,7 +164,7 @@ inline void CartridgeCDF::callFunction(uInt8 value) // time for Stella as ARM code "runs in zero 6507 cycles". case 255: // call without IRQ driven audio try { - Int32 cycles = mySystem->cycles() - myARMCycles; + Int32 cycles = Int32(mySystem->cycles() - myARMCycles); myARMCycles = mySystem->cycles(); myThumbEmulator->run(cycles); @@ -519,9 +511,9 @@ bool CartridgeCDF::save(Serializer& out) const out.putByteArray(myMusicWaveformSize, 3); // Save cycles and clocks - out.putInt(myAudioCycles); + out.putLong(myAudioCycles); out.putInt((uInt32)(myFractionalClocks * 100000000.0)); - out.putInt(myARMCycles); + out.putLong(myARMCycles); } catch(...) { @@ -562,9 +554,9 @@ bool CartridgeCDF::load(Serializer& in) in.getByteArray(myMusicWaveformSize, 3); // Get cycles and clocks - myAudioCycles = (Int32)in.getInt(); + myAudioCycles = in.getLong(); myFractionalClocks = (double)in.getInt() / 100000000.0; - myARMCycles = (Int32)in.getInt(); + myARMCycles = in.getLong(); } catch(...) { diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 02f4298ac..bdb08cbd2 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -73,13 +73,6 @@ class CartridgeCDF : public Cartridge */ void consoleChanged(ConsoleTiming timing) override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -239,10 +232,10 @@ class CartridgeCDF : public Cartridge uInt16 myBankOffset; // System cycle count from when the last update to music data fetchers occurred - Int32 myAudioCycles; + uInt64 myAudioCycles; // ARM cycle count from when the last callFunction() occurred - Int32 myARMCycles; + uInt64 myARMCycles; // The audio routines in the driver run in 32-bit mode and take advantage // of the FIQ Shadow Registers which are not accessible to 16-bit thumb diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index f1110dd37..cf26e2dff 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -61,13 +61,6 @@ void CartridgeCTY::reset() bank(myStartBank); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCTY::systemCyclesReset() -{ - // Adjust the cycle counter so that it reflects the new value - mySystemCycles -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCTY::install(System& system) { @@ -296,7 +289,7 @@ bool CartridgeCTY::save(Serializer& out) const out.putShort(myCounter); out.putBool(myLDAimmediate); out.putInt(myRandomNumber); - out.putInt(mySystemCycles); + out.putLong(mySystemCycles); out.putInt(uInt32(myFractionalClocks * 100000000.0)); } @@ -325,7 +318,7 @@ bool CartridgeCTY::load(Serializer& in) myCounter = in.getShort(); myLDAimmediate = in.getBool(); myRandomNumber = in.getInt(); - mySystemCycles = in.getInt(); + mySystemCycles = in.getLong(); myFractionalClocks = double(in.getInt()) / 100000000.0; } catch(...) @@ -513,7 +506,7 @@ void CartridgeCTY::wipeAllScores() inline void CartridgeCTY::updateMusicModeDataFetchers() { // Calculate the number of cycles since the last update - Int32 cycles = mySystem->cycles() - mySystemCycles; + Int32 cycles = Int32(mySystem->cycles() - mySystemCycles); mySystemCycles = mySystem->cycles(); // Calculate the number of DPC OSC clocks since the last update diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index 81e524744..1e37a6e62 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -130,13 +130,6 @@ class CartridgeCTY : public Cartridge */ void reset() override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -300,7 +293,7 @@ class CartridgeCTY : public Cartridge string myEEPROMFile; // System cycle count when the last update to music data fetchers occurred - Int32 mySystemCycles; + uInt64 mySystemCycles; // Fractional DPC music OSC clocks unused during the last update double myFractionalClocks; diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index 948ac7260..06b19588c 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -62,13 +62,6 @@ void CartridgeDPC::reset() bank(myStartBank); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDPC::systemCyclesReset() -{ - // Adjust the cycle counter so that it reflects the new value - mySystemCycles -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeDPC::install(System& system) { @@ -105,7 +98,7 @@ inline void CartridgeDPC::clockRandomNumberGenerator() inline void CartridgeDPC::updateMusicModeDataFetchers() { // Calculate the number of cycles since the last update - Int32 cycles = mySystem->cycles() - mySystemCycles; + Int32 cycles = Int32(mySystem->cycles() - mySystemCycles); mySystemCycles = mySystem->cycles(); // Calculate the number of DPC OSC clocks since the last update @@ -481,7 +474,7 @@ bool CartridgeDPC::save(Serializer& out) const // The random number generator register out.putByte(myRandomNumber); - out.putInt(mySystemCycles); + out.putLong(mySystemCycles); out.putInt(uInt32(myFractionalClocks * 100000000.0)); } catch(...) @@ -524,7 +517,7 @@ bool CartridgeDPC::load(Serializer& in) myRandomNumber = in.getByte(); // Get system cycles and fractional clocks - mySystemCycles = Int32(in.getInt()); + mySystemCycles = in.getLong(); myFractionalClocks = double(in.getInt()) / 100000000.0; } catch(...) diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index c1b53ba23..2b4838bc0 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -58,13 +58,6 @@ class CartridgeDPC : public Cartridge */ void reset() override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -203,7 +196,7 @@ class CartridgeDPC : public Cartridge uInt8 myRandomNumber; // System cycle count when the last update to music data fetchers occurred - Int32 mySystemCycles; + uInt64 mySystemCycles; // Fractional DPC music OSC clocks unused during the last update double myFractionalClocks; diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 864ede1d6..9188014c0 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -110,14 +110,6 @@ void CartridgeDPCPlus::consoleChanged(ConsoleTiming timing) #endif } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDPCPlus::systemCyclesReset() -{ - // Adjust the cycle counter so that it reflects the new value - mySystemCycles -= mySystem->cycles(); - myARMCycles -= mySystem->cycles(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeDPCPlus::install(System& system) { @@ -153,7 +145,7 @@ inline void CartridgeDPCPlus::priorClockRandomNumberGenerator() inline void CartridgeDPCPlus::updateMusicModeDataFetchers() { // Calculate the number of cycles since the last update - Int32 cycles = mySystem->cycles() - mySystemCycles; + Int32 cycles = Int32(mySystem->cycles() - mySystemCycles); mySystemCycles = mySystem->cycles(); // Calculate the number of DPC OSC clocks since the last update @@ -195,7 +187,7 @@ inline void CartridgeDPCPlus::callFunction(uInt8 value) // time for Stella as ARM code "runs in zero 6507 cycles". case 255: // call without IRQ driven audio try { - Int32 cycles = mySystem->cycles() - myARMCycles; + Int32 cycles = Int32(mySystem->cycles() - myARMCycles); myARMCycles = mySystem->cycles(); myThumbEmulator->run(cycles); @@ -690,11 +682,11 @@ bool CartridgeDPCPlus::save(Serializer& out) const out.putInt(myRandomNumber); // Get system cycles and fractional clocks - out.putInt(mySystemCycles); + out.putLong(mySystemCycles); out.putInt(uInt32(myFractionalClocks * 100000000.0)); // Clock info for Thumbulator - out.putInt(myARMCycles); + out.putLong(myARMCycles); } catch(...) { @@ -754,11 +746,11 @@ bool CartridgeDPCPlus::load(Serializer& in) myRandomNumber = in.getInt(); // Get system cycles and fractional clocks - mySystemCycles = in.getInt(); + mySystemCycles = in.getLong(); myFractionalClocks = double(in.getInt()) / 100000000.0; // Clock info for Thumbulator - myARMCycles = in.getInt(); + myARMCycles = in.getLong(); } catch(...) { diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 15e064a3f..3007c5b8c 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -74,13 +74,6 @@ class CartridgeDPCPlus : public Cartridge */ void consoleChanged(ConsoleTiming timing) override; - /** - 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. - */ - void systemCyclesReset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -267,13 +260,13 @@ class CartridgeDPCPlus : public Cartridge uInt32 myRandomNumber; // System cycle count when the last update to music data fetchers occurred - Int32 mySystemCycles; + uInt64 mySystemCycles; // Fractional DPC music OSC clocks unused during the last update double myFractionalClocks; // System cycle count when the last Thumbulator::run() occurred - Int32 myARMCycles; + uInt64 myARMCycles; // Indicates the offset into the ROM image (aligns to current bank) uInt16 myBankOffset; diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index 89a395a9e..f7504cb61 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -275,7 +275,7 @@ bool CartridgeWD::save(Serializer& out) const out.putString(name()); out.putShort(myCurrentBank); out.putByteArray(myRAM, 64); - out.putInt(myCyclesAtBankswitchInit); + out.putLong(myCyclesAtBankswitchInit); out.putShort(myPendingBank); } catch(...) @@ -297,7 +297,7 @@ bool CartridgeWD::load(Serializer& in) myCurrentBank = in.getShort(); in.getByteArray(myRAM, 64); - myCyclesAtBankswitchInit = in.getInt(); + myCyclesAtBankswitchInit = in.getLong(); myPendingBank = in.getShort(); bank(myCurrentBank); diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index b9596537b..b40a9c287 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -224,7 +224,7 @@ class CartridgeWD : public Cartridge uInt16 myOffset[4]; // Indicates the cycle at which a bankswitch was initiated - uInt32 myCyclesAtBankswitchInit; + uInt64 myCyclesAtBankswitchInit; // Indicates the bank we wish to switch to in the future uInt16 myPendingBank; diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index 86112e261..418a56227 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -171,6 +171,13 @@ class Controller : public Serializable */ virtual void update() = 0; + /** + Notification method invoked by the system after its reset method has + been called. It may be necessary to override this method for + controllers that need to know a reset has occurred. + */ + virtual void reset() { } + /** Notification method invoked by the system indicating that the console is about to be destroyed. It may be necessary to override @@ -178,13 +185,6 @@ class Controller : public Serializable */ virtual void close() { }; - /** - 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 controllers that remember cycle counts. - */ - virtual void systemCyclesReset() { } - /** Determines how this controller will treat values received from the X/Y axis and left/right buttons of the mouse. Since not all controllers diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx index 35bc48b77..68c4fe802 100644 --- a/src/emucore/Device.hxx +++ b/src/emucore/Device.hxx @@ -55,13 +55,6 @@ class Device : public Serializable */ virtual void consoleChanged(ConsoleTiming timing) { } - /** - 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() { } - /** Install device in the specified system. Invoked by the system when the device is attached to it. diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index b495f222c..c5c0b4b50 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -68,19 +68,10 @@ void M6532::reset() // Edge-detect set to negative (high to low) myEdgeDetectPositive = false; -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void M6532::systemCyclesReset() -{ - // System cycles are being reset to zero so we need to adjust - // the cycle count we remembered when the timer was last set - myLastCycle -= mySystem->cycles(); - mySetTimerCycle -= mySystem->cycles(); - - // We should also inform any 'smart' controllers as well - myConsole.leftController().systemCyclesReset(); - myConsole.rightController().systemCyclesReset(); + // Let the controllers know about the reset + myConsole.leftController().reset(); + myConsole.rightController().reset(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -109,7 +100,7 @@ void M6532::update() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void M6532::updateEmulation() { - uInt32 cycles = mySystem->cycles() - myLastCycle; + uInt32 cycles = uInt32(mySystem->cycles() - myLastCycle); uInt32 subTimer = mySubTimer; // Guard against further state changes if the debugger alread forwarded emulation @@ -361,8 +352,8 @@ bool M6532::save(Serializer& out) const out.putInt(myDivider); out.putBool(myTimerWrapped); out.putBool(myWrappedThisCycle); - out.putInt(myLastCycle); - out.putInt(mySetTimerCycle); + out.putLong(myLastCycle); + out.putLong(mySetTimerCycle); out.putByte(myDDRA); out.putByte(myDDRB); @@ -397,8 +388,8 @@ bool M6532::load(Serializer& in) myDivider = in.getInt(); myTimerWrapped = in.getBool(); myWrappedThisCycle = in.getBool(); - myLastCycle = in.getInt(); - mySetTimerCycle = in.getInt(); + myLastCycle = in.getLong(); + mySetTimerCycle = in.getLong(); myDDRA = in.getByte(); myDDRB = in.getByte(); @@ -449,5 +440,5 @@ Int32 M6532::intimClocks() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 M6532::timerClocks() const { - return mySystem->cycles() - mySetTimerCycle; + return uInt32(mySystem->cycles() - mySetTimerCycle); } diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index a42ebeb81..eff2ed92a 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -60,13 +60,6 @@ class M6532 : public Device */ void reset() override; - /** - 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. - */ - void systemCyclesReset() override; - /** Update the entire digital and analog pin state of ports A and B. */ @@ -178,7 +171,7 @@ class M6532 : public Device bool myWrappedThisCycle; // Cycle when the timer set. Debugging only. - Int32 mySetTimerCycle; + uInt64 mySetTimerCycle; // Last cycle considered in emu updates Int32 myLastCycle; diff --git a/src/emucore/MT24LC256.cxx b/src/emucore/MT24LC256.cxx index b2dad531f..4f4305e2c 100644 --- a/src/emucore/MT24LC256.cxx +++ b/src/emucore/MT24LC256.cxx @@ -144,6 +144,13 @@ void MT24LC256::update() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MT24LC256::systemReset() +{ + myCyclesWhenSDASet = myCyclesWhenSCLSet = myCyclesWhenTimerSet = + mySystem.cycles(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::erase() { @@ -151,17 +158,6 @@ void MT24LC256::erase() myDataChanged = true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void MT24LC256::systemCyclesReset() -{ - // System cycles are being reset to zero so we need to adjust - // the cycle counts we remembered - uInt32 cycles = mySystem.cycles(); - myCyclesWhenSDASet -= cycles; - myCyclesWhenSCLSet -= cycles; - myCyclesWhenTimerSet -= cycles; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::jpee_init() { @@ -366,7 +362,7 @@ bool MT24LC256::jpee_timercheck(int mode) { if(myTimerActive) { - uInt32 elapsed = mySystem.cycles() - myCyclesWhenTimerSet; + uInt32 elapsed = uInt32(mySystem.cycles() - myCyclesWhenTimerSet); myTimerActive = elapsed < uInt32(5000000.0 / 838.0); } return myTimerActive; diff --git a/src/emucore/MT24LC256.hxx b/src/emucore/MT24LC256.hxx index 9fd246d9c..1f110aea9 100644 --- a/src/emucore/MT24LC256.hxx +++ b/src/emucore/MT24LC256.hxx @@ -50,16 +50,12 @@ class MT24LC256 void writeSDA(bool state); void writeSCL(bool state); + /** Called when the system is being reset */ + void systemReset(); + /** Erase entire EEPROM to known state ($FF) */ void erase(); - /** - 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. - */ - void systemCyclesReset(); - private: // I2C access code provided by Supercat void jpee_init(); @@ -85,10 +81,10 @@ class MT24LC256 bool myTimerActive; // Indicates when the timer was set - uInt32 myCyclesWhenTimerSet; + uInt64 myCyclesWhenTimerSet; // Indicates when the SDA and SCL pins were set/written - uInt32 myCyclesWhenSDASet, myCyclesWhenSCLSet; + uInt64 myCyclesWhenSDASet, myCyclesWhenSCLSet; // The file containing the EEPROM data string myDataFile; diff --git a/src/emucore/SaveKey.cxx b/src/emucore/SaveKey.cxx index 24823c760..725737ca8 100644 --- a/src/emucore/SaveKey.cxx +++ b/src/emucore/SaveKey.cxx @@ -72,17 +72,15 @@ void SaveKey::write(DigitalPin pin, bool value) } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void SaveKey::reset() +{ + myEEPROM->systemReset(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SaveKey::close() { // Force the EEPROM object to cleanup myEEPROM.reset(); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SaveKey::systemCyclesReset() -{ - // The EEPROM keeps track of cycle counts, and needs to know when the - // cycles are reset - myEEPROM->systemCyclesReset(); -} diff --git a/src/emucore/SaveKey.hxx b/src/emucore/SaveKey.hxx index 91a27f9da..c53062517 100644 --- a/src/emucore/SaveKey.hxx +++ b/src/emucore/SaveKey.hxx @@ -74,6 +74,13 @@ class SaveKey : public Controller */ void update() override { } + /** + Notification method invoked by the system after its reset method has + been called. It may be necessary to override this method for + controllers that need to know a reset has occurred. + */ + void reset() override; + /** Notification method invoked by the system indicating that the console is about to be destroyed. It may be necessary to override @@ -81,13 +88,6 @@ class SaveKey : public Controller */ void close() override; - /** - 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. - */ - void systemCyclesReset() override; - private: // The EEPROM used in the SaveKey unique_ptr myEEPROM; diff --git a/src/emucore/Serializer.cxx b/src/emucore/Serializer.cxx index c880bf8c0..193560649 100644 --- a/src/emucore/Serializer.cxx +++ b/src/emucore/Serializer.cxx @@ -133,6 +133,15 @@ void Serializer::getIntArray(uInt32* array, uInt32 size) const myStream->read(reinterpret_cast(array), sizeof(uInt32)*size); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt64 Serializer::getLong() const +{ + uInt64 val = 0; + myStream->read(reinterpret_cast(&val), sizeof(uInt64)); + + return val; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double Serializer::getDouble() const { @@ -195,6 +204,12 @@ void Serializer::putIntArray(const uInt32* array, uInt32 size) myStream->write(reinterpret_cast(array), sizeof(uInt32)*size); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Serializer::putLong(uInt64 value) +{ + myStream->write(reinterpret_cast(&value), sizeof(uInt64)); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Serializer::putDouble(double value) { diff --git a/src/emucore/Serializer.hxx b/src/emucore/Serializer.hxx index e956a158c..03acbc852 100644 --- a/src/emucore/Serializer.hxx +++ b/src/emucore/Serializer.hxx @@ -27,12 +27,9 @@ stream can be either an actual file, or an in-memory structure. Bytes are written as characters, shorts as 2 characters (16-bits), - integers as 4 characters (32-bits), strings are written as characters - prepended by the length of the string, boolean values are written using - a special character pattern. - - All bytes, shorts and ints should be cast to their appropriate data type upon - method return. + integers as 4 characters (32-bits), long integers as 8 bytes (64-bits), + strings are written as characters prepended by the length of the string, + boolean values are written using a special character pattern. @author Stephen Anthony */ @@ -110,6 +107,13 @@ class Serializer */ void getIntArray(uInt32* array, uInt32 size) const; + /** + Reads a long int value (unsigned 64-bit) from the current input stream. + + @result The long int value which has been read from the stream. + */ + uInt64 getLong() const; + /** Reads a double value (signed 64-bit) from the current input stream. @@ -176,6 +180,13 @@ class Serializer */ void putIntArray(const uInt32* array, uInt32 size); + /** + Writes a long int value (unsigned 64-bit) to the current output stream. + + @param value The long int value to write to the output stream. + */ + void putLong(uInt64 value); + /** Writes a double value (signed 64-bit) to the current output stream. diff --git a/src/emucore/Sound.hxx b/src/emucore/Sound.hxx index 0aa52faa1..a46afe114 100644 --- a/src/emucore/Sound.hxx +++ b/src/emucore/Sound.hxx @@ -47,14 +47,6 @@ class Sound : public Serializable */ virtual void setEnabled(bool enable) = 0; - /** - The system cycle counter is being adjusting by the specified amount. Any - members using the system cycle counter should be adjusted as needed. - - @param amount The amount the cycle counter is being adjusted by - */ - virtual void adjustCycleCounter(Int32 amount) = 0; - /** Sets the number of channels (mono or stereo sound). @@ -101,7 +93,7 @@ class Sound : public Serializable @param value The value to save into the register @param cycle The system cycle at which the register is being updated */ - virtual void set(uInt16 addr, uInt8 value, Int32 cycle) = 0; + virtual void set(uInt16 addr, uInt8 value, uInt64 cycle) = 0; /** Sets the volume of the sound device to the specified level. The diff --git a/src/emucore/System.cxx b/src/emucore/System.cxx index 688ba4ae3..7399e98d6 100644 --- a/src/emucore/System.cxx +++ b/src/emucore/System.cxx @@ -69,10 +69,8 @@ void System::reset(bool autodetect) // Provide hint to devices that autodetection is active (or not) mySystemInAutodetect = autodetect; - // Reset system cycle counter - resetCycles(); - // Reset all devices + myCycles = 0; // Must be done first (the reset() methods use its value) myM6532.reset(); myTIA.reset(); myCart.reset(); @@ -82,18 +80,6 @@ void System::reset(bool autodetect) clearDirtyPages(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void System::resetCycles() -{ - // First we let all of the device attached to me know about the reset - myM6532.systemCyclesReset(); - myTIA.systemCyclesReset(); - myCart.systemCyclesReset(); - - // Now, we reset cycle count to zero - myCycles = 0; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void System::consoleChanged(ConsoleTiming timing) { @@ -209,7 +195,7 @@ bool System::save(Serializer& out) const try { out.putString(name()); - out.putInt(myCycles); + out.putLong(myCycles); out.putByte(myDataBusState); // Save the state of each device @@ -241,7 +227,7 @@ bool System::load(Serializer& in) if(in.getString() != name()) return false; - myCycles = in.getInt(); + myCycles = in.getLong(); myDataBusState = in.getByte(); // Load the state of each device diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index d62f36fec..9c224027f 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -126,12 +126,12 @@ class System : public Serializable public: /** - Get the number of system cycles which have passed since the last - time cycles were reset or the system was reset. + Get the number of system cycles which have passed since the + system was created. @return The number of system cycles which have passed */ - uInt32 cycles() const { return myCycles; } + uInt64 cycles() const { return myCycles; } /** Increment the system cycles by the specified number of cycles. @@ -140,14 +140,6 @@ class System : public Serializable */ void incrementCycles(uInt32 amount) { myCycles += amount; } - /** - Reset the system cycle count to zero. The first thing that - happens is that all devices are notified of the reset by invoking - their systemCyclesReset method then the system cycle count is - reset to zero. - */ - void resetCycles(); - /** Informs all attached devices that the console type has changed. */ @@ -396,8 +388,8 @@ class System : public Serializable // Cartridge device attached to the system Cartridge& myCart; - // Number of system cycles executed since the last reset - uInt32 myCycles; + // Number of system cycles executed since instantiation + uInt64 myCycles; // Null device to use for page which are not installed NullDevice myNullDevice; diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index dadfc5075..dc76f195b 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -145,6 +145,8 @@ void TIA::reset() myDelayQueue.reset(); myFrameManager.reset(); + myCyclesAtFrameStart = 0; + frameReset(); // Recalculate the size of the display // Must be done last, after all other items have reset @@ -160,16 +162,6 @@ void TIA::frameReset() enableColorLoss(mySettings.getBool("colorloss")); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TIA::systemCyclesReset() -{ - const uInt32 cycles = mySystem->cycles(); - - myLastCycle -= cycles; - - mySound.adjustCycleCounter(-1 * cycles); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::install(System& system) { @@ -243,7 +235,7 @@ bool TIA::save(Serializer& out) const out.putInt(int(myPriority)); out.putByte(mySubClock); - out.putInt(myLastCycle); + out.putLong(myLastCycle); out.putByte(mySpriteEnabledBits); out.putByte(myCollisionsEnabledBits); @@ -255,6 +247,8 @@ bool TIA::save(Serializer& out) const out.putBool(myAutoFrameEnabled); out.putByteArray(myShadowRegisters, 64); + + out.putLong(myCyclesAtFrameStart); } catch(...) { @@ -312,7 +306,7 @@ bool TIA::load(Serializer& in) myPriority = Priority(in.getInt()); mySubClock = in.getByte(); - myLastCycle = in.getInt(); + myLastCycle = in.getLong(); mySpriteEnabledBits = in.getByte(); myCollisionsEnabledBits = in.getByte(); @@ -324,6 +318,8 @@ bool TIA::load(Serializer& in) myAutoFrameEnabled = in.getBool(); in.getByteArray(myShadowRegisters, 64); + + myCyclesAtFrameStart = in.getLong(); } catch(...) { @@ -811,6 +807,12 @@ bool TIA::enableColorLoss(bool enabled) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 TIA::frameCycles() const +{ + return uInt32(mySystem->cycles() - myCyclesAtFrameStart); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIA::electronBeamPos(uInt32& x, uInt32& y) const { @@ -1055,12 +1057,12 @@ uInt8 TIA::registerValue(uInt8 reg) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::updateEmulation() { - const uInt32 systemCycles = mySystem->cycles(); + const uInt64 systemCycles = mySystem->cycles(); if (mySubClock > 2) throw runtime_error("subclock exceeds range"); - const uInt32 cyclesToRun = 3 * (systemCycles - myLastCycle) + mySubClock; + const uInt32 cyclesToRun = 3 * uInt32(systemCycles - myLastCycle) + mySubClock; mySubClock = 0; myLastCycle = systemCycles; @@ -1103,7 +1105,7 @@ void TIA::onRenderingStart() void TIA::onFrameComplete() { mySystem->m6502().stop(); - mySystem->resetCycles(); + myCyclesAtFrameStart = mySystem->cycles(); if (myXAtRenderingStart > 0) memset(myFramebuffer, 0, myXAtRenderingStart); diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 0f0cad02a..0df2a6cc1 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -112,12 +112,6 @@ class TIA : public Device */ void frameReset(); - /** - Notification method invoked by the system right before the - system resets its cycle counter to zero. - */ - void systemCyclesReset() override; - /** Install TIA in the specified system. Invoked by the system when the TIA is attached to it. @@ -264,6 +258,11 @@ class TIA : public Device */ uInt32 scanlinesLastFrame() const { return myFrameManager.scanlinesLastFrame(); } + /** + Answers the system cycles from the start of the current frame. + */ + uInt32 frameCycles() const; + /** Answers whether the TIA is currently in being rendered (we're in between the start and end of drawing a frame). @@ -707,6 +706,11 @@ class TIA : public Device bool myColorLossEnabled; bool myColorLossActive; + /** + * System cycles at the end of the previous frame / beginning of next frame + */ + uInt64 myCyclesAtFrameStart; + private: TIA() = delete; TIA(const TIA&) = delete;