mirror of https://github.com/stella-emu/stella.git
Refactor System::myCycles to be 64-bit instead of 32-bit.
- The cycles counter is now essentially monotonically increasing (ie, we never need to worry about it going backwards and giving a negative difference, simplifying a lot of code - There are now reset() methods in all places that keep track of system cycles, but they are used for a full reset only; not called each frame like before (which had to be done to prevent overflow).
This commit is contained in:
parent
fc104c3b4a
commit
ebb8725126
|
@ -56,14 +56,6 @@ class SoundNull : public Sound
|
||||||
*/
|
*/
|
||||||
void setEnabled(bool enable) override { }
|
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).
|
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 value The value to save into the register
|
||||||
@param cycle The system cycle at which the register is being updated
|
@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
|
Sets the volume of the sound device to the specified level. The
|
||||||
|
|
|
@ -226,12 +226,6 @@ void SoundSDL2::adjustVolume(Int8 direction)
|
||||||
myOSystem.frameBuffer().showMessage(message);
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void SoundSDL2::adjustCycleCounter(Int32 amount)
|
|
||||||
{
|
|
||||||
myLastRegisterSetCycle += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::setChannels(uInt32 channels)
|
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();
|
SDL_LockAudio();
|
||||||
|
|
||||||
|
@ -386,7 +380,7 @@ bool SoundSDL2::save(Serializer& out) const
|
||||||
for(int i = 0; i < 6; ++i)
|
for(int i = 0; i < 6; ++i)
|
||||||
out.putByte(0);
|
out.putByte(0);
|
||||||
|
|
||||||
out.putInt(myLastRegisterSetCycle);
|
out.putLong(myLastRegisterSetCycle);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -423,7 +417,7 @@ bool SoundSDL2::load(Serializer& in)
|
||||||
for(int i = 0; i < 6; ++i)
|
for(int i = 0; i < 6; ++i)
|
||||||
in.getByte();
|
in.getByte();
|
||||||
|
|
||||||
myLastRegisterSetCycle = in.getInt();
|
myLastRegisterSetCycle = in.getLong();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,14 +55,6 @@ class SoundSDL2 : public Sound
|
||||||
*/
|
*/
|
||||||
void setEnabled(bool state) override;
|
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
|
Sets the number of channels (mono or stereo sound). Note that this
|
||||||
determines how the emulation should 'mix' the channels of the TIA sound
|
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 value The value to save into the register
|
||||||
@param cycle The system cycle at which the register is being updated
|
@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
|
Sets the volume of the sound device to the specified level. The
|
||||||
|
@ -258,7 +250,7 @@ class SoundSDL2 : public Sound
|
||||||
bool myIsInitializedFlag;
|
bool myIsInitializedFlag;
|
||||||
|
|
||||||
// Indicates the cycle when a sound register was last set
|
// Indicates the cycle when a sound register was last set
|
||||||
Int32 myLastRegisterSetCycle;
|
uInt64 myLastRegisterSetCycle;
|
||||||
|
|
||||||
// Indicates the number of channels (mono or stereo)
|
// Indicates the number of channels (mono or stereo)
|
||||||
uInt32 myNumChannels;
|
uInt32 myNumChannels;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
|
|
||||||
#define STATE_HEADER "05000300state"
|
#define STATE_HEADER "05000301state"
|
||||||
#define MOVIE_HEADER "03030000movie"
|
#define MOVIE_HEADER "03030000movie"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -99,6 +99,7 @@ static const char* const pseudo_registers[][2] = {
|
||||||
{ "_rwport", "Address at which a read from a write port occurred" },
|
{ "_rwport", "Address at which a read from a write port occurred" },
|
||||||
{ "_scan", "Current scanline count" },
|
{ "_scan", "Current scanline count" },
|
||||||
{ "_fcount", "Number of frames since emulation started" },
|
{ "_fcount", "Number of frames since emulation started" },
|
||||||
|
//FIXME { "_fcycles", "Number of cycles since frame started" },
|
||||||
{ "_cclocks", "Color clocks on current scanline" },
|
{ "_cclocks", "Color clocks on current scanline" },
|
||||||
{ "_vsync", "Whether vertical sync is enabled (1 or 0)" },
|
{ "_vsync", "Whether vertical sync is enabled (1 or 0)" },
|
||||||
{ "_vblank", "Whether vertical blank is enabled (1 or 0)" },
|
{ "_vblank", "Whether vertical blank is enabled (1 or 0)" },
|
||||||
|
@ -302,13 +303,13 @@ int Debugger::step()
|
||||||
saveOldState();
|
saveOldState();
|
||||||
mySystem.clearDirtyPages();
|
mySystem.clearDirtyPages();
|
||||||
|
|
||||||
int cyc = mySystem.cycles();
|
uInt64 startCycle = mySystem.cycles();
|
||||||
|
|
||||||
unlockBankswitchState();
|
unlockBankswitchState();
|
||||||
myOSystem.console().tia().updateScanlineByStep().flushLineCache();
|
myOSystem.console().tia().updateScanlineByStep().flushLineCache();
|
||||||
lockBankswitchState();
|
lockBankswitchState();
|
||||||
|
|
||||||
return mySystem.cycles() - cyc;
|
return int(mySystem.cycles() - startCycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -330,14 +331,14 @@ int Debugger::trace()
|
||||||
saveOldState();
|
saveOldState();
|
||||||
mySystem.clearDirtyPages();
|
mySystem.clearDirtyPages();
|
||||||
|
|
||||||
int cyc = mySystem.cycles();
|
uInt64 startCycle = mySystem.cycles();
|
||||||
int targetPC = myCpuDebug->pc() + 3; // return address
|
int targetPC = myCpuDebug->pc() + 3; // return address
|
||||||
|
|
||||||
unlockBankswitchState();
|
unlockBankswitchState();
|
||||||
myOSystem.console().tia().updateScanlineByTrace(targetPC).flushLineCache();
|
myOSystem.console().tia().updateScanlineByTrace(targetPC).flushLineCache();
|
||||||
lockBankswitchState();
|
lockBankswitchState();
|
||||||
|
|
||||||
return mySystem.cycles() - cyc;
|
return int(mySystem.cycles() - startCycle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return step();
|
return step();
|
||||||
|
|
|
@ -153,11 +153,6 @@ class Debugger : public DialogContainer
|
||||||
*/
|
*/
|
||||||
const string run(const string& command);
|
const string run(const string& command);
|
||||||
|
|
||||||
/**
|
|
||||||
The current cycle count of the System.
|
|
||||||
*/
|
|
||||||
int cycles() const { return int(mySystem.cycles()); }
|
|
||||||
|
|
||||||
string autoExec();
|
string autoExec();
|
||||||
|
|
||||||
string showWatches();
|
string showWatches();
|
||||||
|
|
|
@ -694,6 +694,12 @@ int TIADebug::frameCount() const
|
||||||
return myTIA.myFrameManager.frameCount();
|
return myTIA.myFrameManager.frameCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int TIADebug::frameCycles() const
|
||||||
|
{
|
||||||
|
return myTIA.frameCycles();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int TIADebug::scanlines() const
|
int TIADebug::scanlines() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -159,6 +159,7 @@ class TIADebug : public DebuggerSystem
|
||||||
int scanlines() const;
|
int scanlines() const;
|
||||||
int scanlinesLastFrame() const;
|
int scanlinesLastFrame() const;
|
||||||
int frameCount() const;
|
int frameCount() const;
|
||||||
|
int frameCycles() const;
|
||||||
int clocksThisLine() const;
|
int clocksThisLine() const;
|
||||||
bool vsync() const;
|
bool vsync() const;
|
||||||
bool vblank() const;
|
bool vblank() const;
|
||||||
|
|
|
@ -129,7 +129,7 @@ void TiaInfoWidget::loadConfig()
|
||||||
TIADebug& tia = dbg.tiaDebug();
|
TIADebug& tia = dbg.tiaDebug();
|
||||||
|
|
||||||
myFrameCount->setText(Common::Base::toString(tia.frameCount(), Common::Base::F_10));
|
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());
|
myVSync->setState(tia.vsync());
|
||||||
myVBlank->setState(tia.vblank());
|
myVBlank->setState(tia.vblank());
|
||||||
|
|
|
@ -99,13 +99,12 @@ void AtariVox::write(DigitalPin pin, bool value)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AtariVox::clockDataIn(bool value)
|
void AtariVox::clockDataIn(bool value)
|
||||||
{
|
{
|
||||||
uInt32 cycle = mySystem.cycles();
|
|
||||||
|
|
||||||
if(value && (myShiftCount == 0))
|
if(value && (myShiftCount == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If this is the first write this frame, or if it's been a long time
|
// 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.
|
// since the last write, start a new data byte.
|
||||||
|
uInt64 cycle = mySystem.cycles();
|
||||||
if((cycle < myLastDataWriteCycle) || (cycle > myLastDataWriteCycle + 1000))
|
if((cycle < myLastDataWriteCycle) || (cycle > myLastDataWriteCycle + 1000))
|
||||||
{
|
{
|
||||||
myShiftRegister = 0;
|
myShiftRegister = 0;
|
||||||
|
@ -138,6 +137,13 @@ void AtariVox::clockDataIn(bool value)
|
||||||
myLastDataWriteCycle = cycle;
|
myLastDataWriteCycle = cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void AtariVox::reset()
|
||||||
|
{
|
||||||
|
myLastDataWriteCycle = mySystem.cycles();
|
||||||
|
myEEPROM->systemReset();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AtariVox::close()
|
void AtariVox::close()
|
||||||
{
|
{
|
||||||
|
@ -145,16 +151,6 @@ void AtariVox::close()
|
||||||
myEEPROM.reset();
|
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
|
string AtariVox::about() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,13 @@ class AtariVox : public Controller
|
||||||
*/
|
*/
|
||||||
void update() override { }
|
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
|
Notification method invoked by the system indicating that the
|
||||||
console is about to be destroyed. It may be necessary to override
|
console is about to be destroyed. It may be necessary to override
|
||||||
|
@ -86,13 +93,6 @@ class AtariVox : public Controller
|
||||||
*/
|
*/
|
||||||
void close() override;
|
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;
|
string about() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -121,7 +121,7 @@ class AtariVox : public Controller
|
||||||
// The real SpeakJet chip reads data at 19200 bits/sec. Alex's
|
// The real SpeakJet chip reads data at 19200 bits/sec. Alex's
|
||||||
// driver code sends data at 62 CPU cycles per bit, which is
|
// driver code sends data at 62 CPU cycles per bit, which is
|
||||||
// "close enough".
|
// "close enough".
|
||||||
uInt32 myLastDataWriteCycle;
|
uInt64 myLastDataWriteCycle;
|
||||||
|
|
||||||
// Holds information concerning serial port usage
|
// Holds information concerning serial port usage
|
||||||
string myAboutString;
|
string myAboutString;
|
||||||
|
|
|
@ -26,7 +26,6 @@ CartridgeAR::CartridgeAR(const BytePtr& image, uInt32 size,
|
||||||
mySize(std::max(size, 8448u)),
|
mySize(std::max(size, 8448u)),
|
||||||
myWriteEnabled(false),
|
myWriteEnabled(false),
|
||||||
myPower(true),
|
myPower(true),
|
||||||
myPowerRomCycle(0),
|
|
||||||
myDataHoldRegister(0),
|
myDataHoldRegister(0),
|
||||||
myNumberOfDistinctAccesses(0),
|
myNumberOfDistinctAccesses(0),
|
||||||
myWritePending(false),
|
myWritePending(false),
|
||||||
|
@ -64,7 +63,6 @@ void CartridgeAR::reset()
|
||||||
|
|
||||||
myWriteEnabled = false;
|
myWriteEnabled = false;
|
||||||
myPower = true;
|
myPower = true;
|
||||||
myPowerRomCycle = mySystem->cycles();
|
|
||||||
|
|
||||||
myDataHoldRegister = 0;
|
myDataHoldRegister = 0;
|
||||||
myNumberOfDistinctAccesses = 0;
|
myNumberOfDistinctAccesses = 0;
|
||||||
|
@ -74,13 +72,6 @@ void CartridgeAR::reset()
|
||||||
bankConfiguration(0);
|
bankConfiguration(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeAR::systemCyclesReset()
|
|
||||||
{
|
|
||||||
// Adjust cycle values
|
|
||||||
myPowerRomCycle -= mySystem->cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeAR::install(System& system)
|
void CartridgeAR::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -243,11 +234,6 @@ bool CartridgeAR::bankConfiguration(uInt8 configuration)
|
||||||
// Handle ROM power configuration
|
// Handle ROM power configuration
|
||||||
myPower = !(configuration & 0x01);
|
myPower = !(configuration & 0x01);
|
||||||
|
|
||||||
if(myPower)
|
|
||||||
{
|
|
||||||
myPowerRomCycle = mySystem->cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
myWriteEnabled = configuration & 0x02;
|
myWriteEnabled = configuration & 0x02;
|
||||||
|
|
||||||
switch((configuration >> 2) & 0x07)
|
switch((configuration >> 2) & 0x07)
|
||||||
|
@ -474,9 +460,6 @@ bool CartridgeAR::save(Serializer& out) const
|
||||||
// Indicates if the ROM's power is on or off
|
// Indicates if the ROM's power is on or off
|
||||||
out.putBool(myPower);
|
out.putBool(myPower);
|
||||||
|
|
||||||
// Indicates when the power was last turned on
|
|
||||||
out.putInt(myPowerRomCycle);
|
|
||||||
|
|
||||||
// Data hold register used for writing
|
// Data hold register used for writing
|
||||||
out.putByte(myDataHoldRegister);
|
out.putByte(myDataHoldRegister);
|
||||||
|
|
||||||
|
@ -525,9 +508,6 @@ bool CartridgeAR::load(Serializer& in)
|
||||||
// Indicates if the ROM's power is on or off
|
// Indicates if the ROM's power is on or off
|
||||||
myPower = in.getBool();
|
myPower = in.getBool();
|
||||||
|
|
||||||
// Indicates when the power was last turned on
|
|
||||||
myPowerRomCycle = in.getInt();
|
|
||||||
|
|
||||||
// Data hold register used for writing
|
// Data hold register used for writing
|
||||||
myDataHoldRegister = in.getByte();
|
myDataHoldRegister = in.getByte();
|
||||||
|
|
||||||
|
|
|
@ -60,13 +60,6 @@ class CartridgeAR : public Cartridge
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
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
|
// Indicates if the ROM's power is on or off
|
||||||
bool myPower;
|
bool myPower;
|
||||||
|
|
||||||
// Indicates when the power was last turned on
|
|
||||||
Int32 myPowerRomCycle;
|
|
||||||
|
|
||||||
// Data hold register used for writing
|
// Data hold register used for writing
|
||||||
uInt8 myDataHoldRegister;
|
uInt8 myDataHoldRegister;
|
||||||
|
|
||||||
|
|
|
@ -112,14 +112,6 @@ void CartridgeBUS::consoleChanged(ConsoleTiming timing)
|
||||||
#endif
|
#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)
|
void CartridgeBUS::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -143,7 +135,7 @@ void CartridgeBUS::install(System& system)
|
||||||
inline void CartridgeBUS::updateMusicModeDataFetchers()
|
inline void CartridgeBUS::updateMusicModeDataFetchers()
|
||||||
{
|
{
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
Int32 cycles = Int32(mySystem->cycles() - mySystemCycles);
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of BUS OSC clocks since the last update
|
// 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".
|
// time for Stella as ARM code "runs in zero 6507 cycles".
|
||||||
case 255: // call without IRQ driven audio
|
case 255: // call without IRQ driven audio
|
||||||
try {
|
try {
|
||||||
Int32 cycles = mySystem->cycles() - myARMCycles;
|
Int32 cycles = Int32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
myARMCycles = mySystem->cycles();
|
||||||
|
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
@ -570,9 +562,9 @@ bool CartridgeBUS::save(Serializer& out) const
|
||||||
out.putShort(myJMPoperandAddress);
|
out.putShort(myJMPoperandAddress);
|
||||||
|
|
||||||
// Save cycles and clocks
|
// Save cycles and clocks
|
||||||
out.putInt(mySystemCycles);
|
out.putLong(mySystemCycles);
|
||||||
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
||||||
out.putInt(myARMCycles);
|
out.putLong(myARMCycles);
|
||||||
|
|
||||||
// Audio info
|
// Audio info
|
||||||
out.putIntArray(myMusicCounters, 3);
|
out.putIntArray(myMusicCounters, 3);
|
||||||
|
@ -614,9 +606,9 @@ bool CartridgeBUS::load(Serializer& in)
|
||||||
myJMPoperandAddress = in.getShort();
|
myJMPoperandAddress = in.getShort();
|
||||||
|
|
||||||
// Get system cycles and fractional clocks
|
// Get system cycles and fractional clocks
|
||||||
mySystemCycles = (Int32)in.getInt();
|
mySystemCycles = in.getLong();
|
||||||
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
||||||
myARMCycles = (Int32)in.getInt();
|
myARMCycles = in.getLong();
|
||||||
|
|
||||||
// Audio info
|
// Audio info
|
||||||
in.getIntArray(myMusicCounters, 3);
|
in.getIntArray(myMusicCounters, 3);
|
||||||
|
|
|
@ -73,13 +73,6 @@ class CartridgeBUS : public Cartridge
|
||||||
*/
|
*/
|
||||||
void consoleChanged(ConsoleTiming timing) override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -252,10 +245,10 @@ class CartridgeBUS : public Cartridge
|
||||||
uInt16 myJMPoperandAddress;
|
uInt16 myJMPoperandAddress;
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// 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
|
// ARM cycle count from when the last callFunction() occurred
|
||||||
Int32 myARMCycles;
|
uInt64 myARMCycles;
|
||||||
|
|
||||||
// The music mode counters
|
// The music mode counters
|
||||||
uInt32 myMusicCounters[3];
|
uInt32 myMusicCounters[3];
|
||||||
|
|
|
@ -119,14 +119,6 @@ void CartridgeCDF::consoleChanged(ConsoleTiming timing)
|
||||||
#endif
|
#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)
|
void CartridgeCDF::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +137,7 @@ void CartridgeCDF::install(System& system)
|
||||||
inline void CartridgeCDF::updateMusicModeDataFetchers()
|
inline void CartridgeCDF::updateMusicModeDataFetchers()
|
||||||
{
|
{
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - myAudioCycles;
|
Int32 cycles = Int32(mySystem->cycles() - myAudioCycles);
|
||||||
myAudioCycles = mySystem->cycles();
|
myAudioCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of CDF OSC clocks since the last update
|
// 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".
|
// time for Stella as ARM code "runs in zero 6507 cycles".
|
||||||
case 255: // call without IRQ driven audio
|
case 255: // call without IRQ driven audio
|
||||||
try {
|
try {
|
||||||
Int32 cycles = mySystem->cycles() - myARMCycles;
|
Int32 cycles = Int32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
myARMCycles = mySystem->cycles();
|
||||||
|
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
@ -519,9 +511,9 @@ bool CartridgeCDF::save(Serializer& out) const
|
||||||
out.putByteArray(myMusicWaveformSize, 3);
|
out.putByteArray(myMusicWaveformSize, 3);
|
||||||
|
|
||||||
// Save cycles and clocks
|
// Save cycles and clocks
|
||||||
out.putInt(myAudioCycles);
|
out.putLong(myAudioCycles);
|
||||||
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
||||||
out.putInt(myARMCycles);
|
out.putLong(myARMCycles);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -562,9 +554,9 @@ bool CartridgeCDF::load(Serializer& in)
|
||||||
in.getByteArray(myMusicWaveformSize, 3);
|
in.getByteArray(myMusicWaveformSize, 3);
|
||||||
|
|
||||||
// Get cycles and clocks
|
// Get cycles and clocks
|
||||||
myAudioCycles = (Int32)in.getInt();
|
myAudioCycles = in.getLong();
|
||||||
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
||||||
myARMCycles = (Int32)in.getInt();
|
myARMCycles = in.getLong();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,13 +73,6 @@ class CartridgeCDF : public Cartridge
|
||||||
*/
|
*/
|
||||||
void consoleChanged(ConsoleTiming timing) override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -239,10 +232,10 @@ class CartridgeCDF : public Cartridge
|
||||||
uInt16 myBankOffset;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
// System cycle count from when the last update to music data fetchers occurred
|
// 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
|
// 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
|
// 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
|
// of the FIQ Shadow Registers which are not accessible to 16-bit thumb
|
||||||
|
|
|
@ -61,13 +61,6 @@ void CartridgeCTY::reset()
|
||||||
bank(myStartBank);
|
bank(myStartBank);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCTY::systemCyclesReset()
|
|
||||||
{
|
|
||||||
// Adjust the cycle counter so that it reflects the new value
|
|
||||||
mySystemCycles -= mySystem->cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCTY::install(System& system)
|
void CartridgeCTY::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -296,7 +289,7 @@ bool CartridgeCTY::save(Serializer& out) const
|
||||||
out.putShort(myCounter);
|
out.putShort(myCounter);
|
||||||
out.putBool(myLDAimmediate);
|
out.putBool(myLDAimmediate);
|
||||||
out.putInt(myRandomNumber);
|
out.putInt(myRandomNumber);
|
||||||
out.putInt(mySystemCycles);
|
out.putLong(mySystemCycles);
|
||||||
out.putInt(uInt32(myFractionalClocks * 100000000.0));
|
out.putInt(uInt32(myFractionalClocks * 100000000.0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -325,7 +318,7 @@ bool CartridgeCTY::load(Serializer& in)
|
||||||
myCounter = in.getShort();
|
myCounter = in.getShort();
|
||||||
myLDAimmediate = in.getBool();
|
myLDAimmediate = in.getBool();
|
||||||
myRandomNumber = in.getInt();
|
myRandomNumber = in.getInt();
|
||||||
mySystemCycles = in.getInt();
|
mySystemCycles = in.getLong();
|
||||||
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -513,7 +506,7 @@ void CartridgeCTY::wipeAllScores()
|
||||||
inline void CartridgeCTY::updateMusicModeDataFetchers()
|
inline void CartridgeCTY::updateMusicModeDataFetchers()
|
||||||
{
|
{
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
Int32 cycles = Int32(mySystem->cycles() - mySystemCycles);
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of DPC OSC clocks since the last update
|
// Calculate the number of DPC OSC clocks since the last update
|
||||||
|
|
|
@ -130,13 +130,6 @@ class CartridgeCTY : public Cartridge
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -300,7 +293,7 @@ class CartridgeCTY : public Cartridge
|
||||||
string myEEPROMFile;
|
string myEEPROMFile;
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// 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
|
// Fractional DPC music OSC clocks unused during the last update
|
||||||
double myFractionalClocks;
|
double myFractionalClocks;
|
||||||
|
|
|
@ -62,13 +62,6 @@ void CartridgeDPC::reset()
|
||||||
bank(myStartBank);
|
bank(myStartBank);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDPC::systemCyclesReset()
|
|
||||||
{
|
|
||||||
// Adjust the cycle counter so that it reflects the new value
|
|
||||||
mySystemCycles -= mySystem->cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeDPC::install(System& system)
|
void CartridgeDPC::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +98,7 @@ inline void CartridgeDPC::clockRandomNumberGenerator()
|
||||||
inline void CartridgeDPC::updateMusicModeDataFetchers()
|
inline void CartridgeDPC::updateMusicModeDataFetchers()
|
||||||
{
|
{
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
Int32 cycles = Int32(mySystem->cycles() - mySystemCycles);
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of DPC OSC clocks since the last update
|
// 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
|
// The random number generator register
|
||||||
out.putByte(myRandomNumber);
|
out.putByte(myRandomNumber);
|
||||||
|
|
||||||
out.putInt(mySystemCycles);
|
out.putLong(mySystemCycles);
|
||||||
out.putInt(uInt32(myFractionalClocks * 100000000.0));
|
out.putInt(uInt32(myFractionalClocks * 100000000.0));
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -524,7 +517,7 @@ bool CartridgeDPC::load(Serializer& in)
|
||||||
myRandomNumber = in.getByte();
|
myRandomNumber = in.getByte();
|
||||||
|
|
||||||
// Get system cycles and fractional clocks
|
// Get system cycles and fractional clocks
|
||||||
mySystemCycles = Int32(in.getInt());
|
mySystemCycles = in.getLong();
|
||||||
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
|
|
@ -58,13 +58,6 @@ class CartridgeDPC : public Cartridge
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -203,7 +196,7 @@ class CartridgeDPC : public Cartridge
|
||||||
uInt8 myRandomNumber;
|
uInt8 myRandomNumber;
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// 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
|
// Fractional DPC music OSC clocks unused during the last update
|
||||||
double myFractionalClocks;
|
double myFractionalClocks;
|
||||||
|
|
|
@ -110,14 +110,6 @@ void CartridgeDPCPlus::consoleChanged(ConsoleTiming timing)
|
||||||
#endif
|
#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)
|
void CartridgeDPCPlus::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -153,7 +145,7 @@ inline void CartridgeDPCPlus::priorClockRandomNumberGenerator()
|
||||||
inline void CartridgeDPCPlus::updateMusicModeDataFetchers()
|
inline void CartridgeDPCPlus::updateMusicModeDataFetchers()
|
||||||
{
|
{
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
Int32 cycles = Int32(mySystem->cycles() - mySystemCycles);
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of DPC OSC clocks since the last update
|
// 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".
|
// time for Stella as ARM code "runs in zero 6507 cycles".
|
||||||
case 255: // call without IRQ driven audio
|
case 255: // call without IRQ driven audio
|
||||||
try {
|
try {
|
||||||
Int32 cycles = mySystem->cycles() - myARMCycles;
|
Int32 cycles = Int32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
myARMCycles = mySystem->cycles();
|
||||||
|
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
@ -690,11 +682,11 @@ bool CartridgeDPCPlus::save(Serializer& out) const
|
||||||
out.putInt(myRandomNumber);
|
out.putInt(myRandomNumber);
|
||||||
|
|
||||||
// Get system cycles and fractional clocks
|
// Get system cycles and fractional clocks
|
||||||
out.putInt(mySystemCycles);
|
out.putLong(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.putLong(myARMCycles);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -754,11 +746,11 @@ bool CartridgeDPCPlus::load(Serializer& in)
|
||||||
myRandomNumber = in.getInt();
|
myRandomNumber = in.getInt();
|
||||||
|
|
||||||
// Get system cycles and fractional clocks
|
// Get system cycles and fractional clocks
|
||||||
mySystemCycles = in.getInt();
|
mySystemCycles = in.getLong();
|
||||||
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
myFractionalClocks = double(in.getInt()) / 100000000.0;
|
||||||
|
|
||||||
// Clock info for Thumbulator
|
// Clock info for Thumbulator
|
||||||
myARMCycles = in.getInt();
|
myARMCycles = in.getLong();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,13 +74,6 @@ class CartridgeDPCPlus : public Cartridge
|
||||||
*/
|
*/
|
||||||
void consoleChanged(ConsoleTiming timing) override;
|
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
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -267,13 +260,13 @@ class CartridgeDPCPlus : public Cartridge
|
||||||
uInt32 myRandomNumber;
|
uInt32 myRandomNumber;
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// 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
|
// 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;
|
uInt64 myARMCycles;
|
||||||
|
|
||||||
// Indicates the offset into the ROM image (aligns to current bank)
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myBankOffset;
|
uInt16 myBankOffset;
|
||||||
|
|
|
@ -275,7 +275,7 @@ bool CartridgeWD::save(Serializer& out) const
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myCurrentBank);
|
||||||
out.putByteArray(myRAM, 64);
|
out.putByteArray(myRAM, 64);
|
||||||
out.putInt(myCyclesAtBankswitchInit);
|
out.putLong(myCyclesAtBankswitchInit);
|
||||||
out.putShort(myPendingBank);
|
out.putShort(myPendingBank);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -297,7 +297,7 @@ bool CartridgeWD::load(Serializer& in)
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myCurrentBank = in.getShort();
|
||||||
in.getByteArray(myRAM, 64);
|
in.getByteArray(myRAM, 64);
|
||||||
myCyclesAtBankswitchInit = in.getInt();
|
myCyclesAtBankswitchInit = in.getLong();
|
||||||
myPendingBank = in.getShort();
|
myPendingBank = in.getShort();
|
||||||
|
|
||||||
bank(myCurrentBank);
|
bank(myCurrentBank);
|
||||||
|
|
|
@ -224,7 +224,7 @@ class CartridgeWD : public Cartridge
|
||||||
uInt16 myOffset[4];
|
uInt16 myOffset[4];
|
||||||
|
|
||||||
// Indicates the cycle at which a bankswitch was initiated
|
// Indicates the cycle at which a bankswitch was initiated
|
||||||
uInt32 myCyclesAtBankswitchInit;
|
uInt64 myCyclesAtBankswitchInit;
|
||||||
|
|
||||||
// Indicates the bank we wish to switch to in the future
|
// Indicates the bank we wish to switch to in the future
|
||||||
uInt16 myPendingBank;
|
uInt16 myPendingBank;
|
||||||
|
|
|
@ -171,6 +171,13 @@ class Controller : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual void update() = 0;
|
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
|
Notification method invoked by the system indicating that the
|
||||||
console is about to be destroyed. It may be necessary to override
|
console is about to be destroyed. It may be necessary to override
|
||||||
|
@ -178,13 +185,6 @@ class Controller : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual void close() { };
|
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
|
Determines how this controller will treat values received from the
|
||||||
X/Y axis and left/right buttons of the mouse. Since not all controllers
|
X/Y axis and left/right buttons of the mouse. Since not all controllers
|
||||||
|
|
|
@ -55,13 +55,6 @@ class Device : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual void consoleChanged(ConsoleTiming timing) { }
|
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
|
Install device in the specified system. Invoked by the system
|
||||||
when the device is attached to it.
|
when the device is attached to it.
|
||||||
|
|
|
@ -68,19 +68,10 @@ void M6532::reset()
|
||||||
|
|
||||||
// Edge-detect set to negative (high to low)
|
// Edge-detect set to negative (high to low)
|
||||||
myEdgeDetectPositive = false;
|
myEdgeDetectPositive = false;
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Let the controllers know about the reset
|
||||||
void M6532::systemCyclesReset()
|
myConsole.leftController().reset();
|
||||||
{
|
myConsole.rightController().reset();
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -109,7 +100,7 @@ void M6532::update()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void M6532::updateEmulation()
|
void M6532::updateEmulation()
|
||||||
{
|
{
|
||||||
uInt32 cycles = mySystem->cycles() - myLastCycle;
|
uInt32 cycles = uInt32(mySystem->cycles() - myLastCycle);
|
||||||
uInt32 subTimer = mySubTimer;
|
uInt32 subTimer = mySubTimer;
|
||||||
|
|
||||||
// Guard against further state changes if the debugger alread forwarded emulation
|
// 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.putInt(myDivider);
|
||||||
out.putBool(myTimerWrapped);
|
out.putBool(myTimerWrapped);
|
||||||
out.putBool(myWrappedThisCycle);
|
out.putBool(myWrappedThisCycle);
|
||||||
out.putInt(myLastCycle);
|
out.putLong(myLastCycle);
|
||||||
out.putInt(mySetTimerCycle);
|
out.putLong(mySetTimerCycle);
|
||||||
|
|
||||||
out.putByte(myDDRA);
|
out.putByte(myDDRA);
|
||||||
out.putByte(myDDRB);
|
out.putByte(myDDRB);
|
||||||
|
@ -397,8 +388,8 @@ bool M6532::load(Serializer& in)
|
||||||
myDivider = in.getInt();
|
myDivider = in.getInt();
|
||||||
myTimerWrapped = in.getBool();
|
myTimerWrapped = in.getBool();
|
||||||
myWrappedThisCycle = in.getBool();
|
myWrappedThisCycle = in.getBool();
|
||||||
myLastCycle = in.getInt();
|
myLastCycle = in.getLong();
|
||||||
mySetTimerCycle = in.getInt();
|
mySetTimerCycle = in.getLong();
|
||||||
|
|
||||||
myDDRA = in.getByte();
|
myDDRA = in.getByte();
|
||||||
myDDRB = in.getByte();
|
myDDRB = in.getByte();
|
||||||
|
@ -449,5 +440,5 @@ Int32 M6532::intimClocks()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 M6532::timerClocks() const
|
uInt32 M6532::timerClocks() const
|
||||||
{
|
{
|
||||||
return mySystem->cycles() - mySetTimerCycle;
|
return uInt32(mySystem->cycles() - mySetTimerCycle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,6 @@ class M6532 : public Device
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
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.
|
Update the entire digital and analog pin state of ports A and B.
|
||||||
*/
|
*/
|
||||||
|
@ -178,7 +171,7 @@ class M6532 : public Device
|
||||||
bool myWrappedThisCycle;
|
bool myWrappedThisCycle;
|
||||||
|
|
||||||
// Cycle when the timer set. Debugging only.
|
// Cycle when the timer set. Debugging only.
|
||||||
Int32 mySetTimerCycle;
|
uInt64 mySetTimerCycle;
|
||||||
|
|
||||||
// Last cycle considered in emu updates
|
// Last cycle considered in emu updates
|
||||||
Int32 myLastCycle;
|
Int32 myLastCycle;
|
||||||
|
|
|
@ -144,6 +144,13 @@ void MT24LC256::update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void MT24LC256::systemReset()
|
||||||
|
{
|
||||||
|
myCyclesWhenSDASet = myCyclesWhenSCLSet = myCyclesWhenTimerSet =
|
||||||
|
mySystem.cycles();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void MT24LC256::erase()
|
void MT24LC256::erase()
|
||||||
{
|
{
|
||||||
|
@ -151,17 +158,6 @@ void MT24LC256::erase()
|
||||||
myDataChanged = true;
|
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()
|
void MT24LC256::jpee_init()
|
||||||
{
|
{
|
||||||
|
@ -366,7 +362,7 @@ bool MT24LC256::jpee_timercheck(int mode)
|
||||||
{
|
{
|
||||||
if(myTimerActive)
|
if(myTimerActive)
|
||||||
{
|
{
|
||||||
uInt32 elapsed = mySystem.cycles() - myCyclesWhenTimerSet;
|
uInt32 elapsed = uInt32(mySystem.cycles() - myCyclesWhenTimerSet);
|
||||||
myTimerActive = elapsed < uInt32(5000000.0 / 838.0);
|
myTimerActive = elapsed < uInt32(5000000.0 / 838.0);
|
||||||
}
|
}
|
||||||
return myTimerActive;
|
return myTimerActive;
|
||||||
|
|
|
@ -50,16 +50,12 @@ class MT24LC256
|
||||||
void writeSDA(bool state);
|
void writeSDA(bool state);
|
||||||
void writeSCL(bool state);
|
void writeSCL(bool state);
|
||||||
|
|
||||||
|
/** Called when the system is being reset */
|
||||||
|
void systemReset();
|
||||||
|
|
||||||
/** Erase entire EEPROM to known state ($FF) */
|
/** Erase entire EEPROM to known state ($FF) */
|
||||||
void erase();
|
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:
|
private:
|
||||||
// I2C access code provided by Supercat
|
// I2C access code provided by Supercat
|
||||||
void jpee_init();
|
void jpee_init();
|
||||||
|
@ -85,10 +81,10 @@ class MT24LC256
|
||||||
bool myTimerActive;
|
bool myTimerActive;
|
||||||
|
|
||||||
// Indicates when the timer was set
|
// Indicates when the timer was set
|
||||||
uInt32 myCyclesWhenTimerSet;
|
uInt64 myCyclesWhenTimerSet;
|
||||||
|
|
||||||
// Indicates when the SDA and SCL pins were set/written
|
// Indicates when the SDA and SCL pins were set/written
|
||||||
uInt32 myCyclesWhenSDASet, myCyclesWhenSCLSet;
|
uInt64 myCyclesWhenSDASet, myCyclesWhenSCLSet;
|
||||||
|
|
||||||
// The file containing the EEPROM data
|
// The file containing the EEPROM data
|
||||||
string myDataFile;
|
string myDataFile;
|
||||||
|
|
|
@ -72,17 +72,15 @@ void SaveKey::write(DigitalPin pin, bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void SaveKey::reset()
|
||||||
|
{
|
||||||
|
myEEPROM->systemReset();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SaveKey::close()
|
void SaveKey::close()
|
||||||
{
|
{
|
||||||
// Force the EEPROM object to cleanup
|
// Force the EEPROM object to cleanup
|
||||||
myEEPROM.reset();
|
myEEPROM.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void SaveKey::systemCyclesReset()
|
|
||||||
{
|
|
||||||
// The EEPROM keeps track of cycle counts, and needs to know when the
|
|
||||||
// cycles are reset
|
|
||||||
myEEPROM->systemCyclesReset();
|
|
||||||
}
|
|
||||||
|
|
|
@ -74,6 +74,13 @@ class SaveKey : public Controller
|
||||||
*/
|
*/
|
||||||
void update() override { }
|
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
|
Notification method invoked by the system indicating that the
|
||||||
console is about to be destroyed. It may be necessary to override
|
console is about to be destroyed. It may be necessary to override
|
||||||
|
@ -81,13 +88,6 @@ class SaveKey : public Controller
|
||||||
*/
|
*/
|
||||||
void close() override;
|
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:
|
private:
|
||||||
// The EEPROM used in the SaveKey
|
// The EEPROM used in the SaveKey
|
||||||
unique_ptr<MT24LC256> myEEPROM;
|
unique_ptr<MT24LC256> myEEPROM;
|
||||||
|
|
|
@ -133,6 +133,15 @@ void Serializer::getIntArray(uInt32* array, uInt32 size) const
|
||||||
myStream->read(reinterpret_cast<char*>(array), sizeof(uInt32)*size);
|
myStream->read(reinterpret_cast<char*>(array), sizeof(uInt32)*size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt64 Serializer::getLong() const
|
||||||
|
{
|
||||||
|
uInt64 val = 0;
|
||||||
|
myStream->read(reinterpret_cast<char*>(&val), sizeof(uInt64));
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
double Serializer::getDouble() const
|
double Serializer::getDouble() const
|
||||||
{
|
{
|
||||||
|
@ -195,6 +204,12 @@ void Serializer::putIntArray(const uInt32* array, uInt32 size)
|
||||||
myStream->write(reinterpret_cast<const char*>(array), sizeof(uInt32)*size);
|
myStream->write(reinterpret_cast<const char*>(array), sizeof(uInt32)*size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Serializer::putLong(uInt64 value)
|
||||||
|
{
|
||||||
|
myStream->write(reinterpret_cast<char*>(&value), sizeof(uInt64));
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Serializer::putDouble(double value)
|
void Serializer::putDouble(double value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,12 +27,9 @@
|
||||||
stream can be either an actual file, or an in-memory structure.
|
stream can be either an actual file, or an in-memory structure.
|
||||||
|
|
||||||
Bytes are written as characters, shorts as 2 characters (16-bits),
|
Bytes are written as characters, shorts as 2 characters (16-bits),
|
||||||
integers as 4 characters (32-bits), strings are written as characters
|
integers as 4 characters (32-bits), long integers as 8 bytes (64-bits),
|
||||||
prepended by the length of the string, boolean values are written using
|
strings are written as characters prepended by the length of the string,
|
||||||
a special character pattern.
|
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.
|
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
|
@ -110,6 +107,13 @@ class Serializer
|
||||||
*/
|
*/
|
||||||
void getIntArray(uInt32* array, uInt32 size) const;
|
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.
|
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);
|
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.
|
Writes a double value (signed 64-bit) to the current output stream.
|
||||||
|
|
||||||
|
|
|
@ -47,14 +47,6 @@ class Sound : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual void setEnabled(bool enable) = 0;
|
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).
|
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 value The value to save into the register
|
||||||
@param cycle The system cycle at which the register is being updated
|
@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
|
Sets the volume of the sound device to the specified level. The
|
||||||
|
|
|
@ -69,10 +69,8 @@ void System::reset(bool autodetect)
|
||||||
// Provide hint to devices that autodetection is active (or not)
|
// Provide hint to devices that autodetection is active (or not)
|
||||||
mySystemInAutodetect = autodetect;
|
mySystemInAutodetect = autodetect;
|
||||||
|
|
||||||
// Reset system cycle counter
|
|
||||||
resetCycles();
|
|
||||||
|
|
||||||
// Reset all devices
|
// Reset all devices
|
||||||
|
myCycles = 0; // Must be done first (the reset() methods use its value)
|
||||||
myM6532.reset();
|
myM6532.reset();
|
||||||
myTIA.reset();
|
myTIA.reset();
|
||||||
myCart.reset();
|
myCart.reset();
|
||||||
|
@ -82,18 +80,6 @@ void System::reset(bool autodetect)
|
||||||
clearDirtyPages();
|
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)
|
void System::consoleChanged(ConsoleTiming timing)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +195,7 @@ bool System::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putInt(myCycles);
|
out.putLong(myCycles);
|
||||||
out.putByte(myDataBusState);
|
out.putByte(myDataBusState);
|
||||||
|
|
||||||
// Save the state of each device
|
// Save the state of each device
|
||||||
|
@ -241,7 +227,7 @@ bool System::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCycles = in.getInt();
|
myCycles = in.getLong();
|
||||||
myDataBusState = in.getByte();
|
myDataBusState = in.getByte();
|
||||||
|
|
||||||
// Load the state of each device
|
// Load the state of each device
|
||||||
|
|
|
@ -126,12 +126,12 @@ class System : public Serializable
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the number of system cycles which have passed since the last
|
Get the number of system cycles which have passed since the
|
||||||
time cycles were reset or the system was reset.
|
system was created.
|
||||||
|
|
||||||
@return The number of system cycles which have passed
|
@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.
|
Increment the system cycles by the specified number of cycles.
|
||||||
|
@ -140,14 +140,6 @@ class System : public Serializable
|
||||||
*/
|
*/
|
||||||
void incrementCycles(uInt32 amount) { myCycles += amount; }
|
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.
|
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 device attached to the system
|
||||||
Cartridge& myCart;
|
Cartridge& myCart;
|
||||||
|
|
||||||
// Number of system cycles executed since the last reset
|
// Number of system cycles executed since instantiation
|
||||||
uInt32 myCycles;
|
uInt64 myCycles;
|
||||||
|
|
||||||
// Null device to use for page which are not installed
|
// Null device to use for page which are not installed
|
||||||
NullDevice myNullDevice;
|
NullDevice myNullDevice;
|
||||||
|
|
|
@ -145,6 +145,8 @@ void TIA::reset()
|
||||||
myDelayQueue.reset();
|
myDelayQueue.reset();
|
||||||
myFrameManager.reset();
|
myFrameManager.reset();
|
||||||
|
|
||||||
|
myCyclesAtFrameStart = 0;
|
||||||
|
|
||||||
frameReset(); // Recalculate the size of the display
|
frameReset(); // Recalculate the size of the display
|
||||||
|
|
||||||
// Must be done last, after all other items have reset
|
// Must be done last, after all other items have reset
|
||||||
|
@ -160,16 +162,6 @@ void TIA::frameReset()
|
||||||
enableColorLoss(mySettings.getBool("colorloss"));
|
enableColorLoss(mySettings.getBool("colorloss"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void TIA::systemCyclesReset()
|
|
||||||
{
|
|
||||||
const uInt32 cycles = mySystem->cycles();
|
|
||||||
|
|
||||||
myLastCycle -= cycles;
|
|
||||||
|
|
||||||
mySound.adjustCycleCounter(-1 * cycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIA::install(System& system)
|
void TIA::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -243,7 +235,7 @@ bool TIA::save(Serializer& out) const
|
||||||
out.putInt(int(myPriority));
|
out.putInt(int(myPriority));
|
||||||
|
|
||||||
out.putByte(mySubClock);
|
out.putByte(mySubClock);
|
||||||
out.putInt(myLastCycle);
|
out.putLong(myLastCycle);
|
||||||
|
|
||||||
out.putByte(mySpriteEnabledBits);
|
out.putByte(mySpriteEnabledBits);
|
||||||
out.putByte(myCollisionsEnabledBits);
|
out.putByte(myCollisionsEnabledBits);
|
||||||
|
@ -255,6 +247,8 @@ bool TIA::save(Serializer& out) const
|
||||||
out.putBool(myAutoFrameEnabled);
|
out.putBool(myAutoFrameEnabled);
|
||||||
|
|
||||||
out.putByteArray(myShadowRegisters, 64);
|
out.putByteArray(myShadowRegisters, 64);
|
||||||
|
|
||||||
|
out.putLong(myCyclesAtFrameStart);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -312,7 +306,7 @@ bool TIA::load(Serializer& in)
|
||||||
myPriority = Priority(in.getInt());
|
myPriority = Priority(in.getInt());
|
||||||
|
|
||||||
mySubClock = in.getByte();
|
mySubClock = in.getByte();
|
||||||
myLastCycle = in.getInt();
|
myLastCycle = in.getLong();
|
||||||
|
|
||||||
mySpriteEnabledBits = in.getByte();
|
mySpriteEnabledBits = in.getByte();
|
||||||
myCollisionsEnabledBits = in.getByte();
|
myCollisionsEnabledBits = in.getByte();
|
||||||
|
@ -324,6 +318,8 @@ bool TIA::load(Serializer& in)
|
||||||
myAutoFrameEnabled = in.getBool();
|
myAutoFrameEnabled = in.getBool();
|
||||||
|
|
||||||
in.getByteArray(myShadowRegisters, 64);
|
in.getByteArray(myShadowRegisters, 64);
|
||||||
|
|
||||||
|
myCyclesAtFrameStart = in.getLong();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -811,6 +807,12 @@ bool TIA::enableColorLoss(bool enabled)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 TIA::frameCycles() const
|
||||||
|
{
|
||||||
|
return uInt32(mySystem->cycles() - myCyclesAtFrameStart);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool TIA::electronBeamPos(uInt32& x, uInt32& y) const
|
bool TIA::electronBeamPos(uInt32& x, uInt32& y) const
|
||||||
{
|
{
|
||||||
|
@ -1055,12 +1057,12 @@ uInt8 TIA::registerValue(uInt8 reg) const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIA::updateEmulation()
|
void TIA::updateEmulation()
|
||||||
{
|
{
|
||||||
const uInt32 systemCycles = mySystem->cycles();
|
const uInt64 systemCycles = mySystem->cycles();
|
||||||
|
|
||||||
if (mySubClock > 2)
|
if (mySubClock > 2)
|
||||||
throw runtime_error("subclock exceeds range");
|
throw runtime_error("subclock exceeds range");
|
||||||
|
|
||||||
const uInt32 cyclesToRun = 3 * (systemCycles - myLastCycle) + mySubClock;
|
const uInt32 cyclesToRun = 3 * uInt32(systemCycles - myLastCycle) + mySubClock;
|
||||||
|
|
||||||
mySubClock = 0;
|
mySubClock = 0;
|
||||||
myLastCycle = systemCycles;
|
myLastCycle = systemCycles;
|
||||||
|
@ -1103,7 +1105,7 @@ void TIA::onRenderingStart()
|
||||||
void TIA::onFrameComplete()
|
void TIA::onFrameComplete()
|
||||||
{
|
{
|
||||||
mySystem->m6502().stop();
|
mySystem->m6502().stop();
|
||||||
mySystem->resetCycles();
|
myCyclesAtFrameStart = mySystem->cycles();
|
||||||
|
|
||||||
if (myXAtRenderingStart > 0)
|
if (myXAtRenderingStart > 0)
|
||||||
memset(myFramebuffer, 0, myXAtRenderingStart);
|
memset(myFramebuffer, 0, myXAtRenderingStart);
|
||||||
|
|
|
@ -112,12 +112,6 @@ class TIA : public Device
|
||||||
*/
|
*/
|
||||||
void frameReset();
|
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
|
Install TIA in the specified system. Invoked by the system
|
||||||
when the TIA is attached to it.
|
when the TIA is attached to it.
|
||||||
|
@ -264,6 +258,11 @@ class TIA : public Device
|
||||||
*/
|
*/
|
||||||
uInt32 scanlinesLastFrame() const { return myFrameManager.scanlinesLastFrame(); }
|
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
|
Answers whether the TIA is currently in being rendered
|
||||||
(we're in between the start and end of drawing a frame).
|
(we're in between the start and end of drawing a frame).
|
||||||
|
@ -707,6 +706,11 @@ class TIA : public Device
|
||||||
bool myColorLossEnabled;
|
bool myColorLossEnabled;
|
||||||
bool myColorLossActive;
|
bool myColorLossActive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System cycles at the end of the previous frame / beginning of next frame
|
||||||
|
*/
|
||||||
|
uInt64 myCyclesAtFrameStart;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIA() = delete;
|
TIA() = delete;
|
||||||
TIA(const TIA&) = delete;
|
TIA(const TIA&) = delete;
|
||||||
|
|
Loading…
Reference in New Issue