CartCDF and friends refactoring (have similar functionality):

- rework music fetcher code; there can never be a negative cycle count
- use get/put double Serializer methods for doubles.
This commit is contained in:
Stephen Anthony 2017-09-08 18:36:06 -02:30
parent b6907d0d8a
commit c4d04ffe26
10 changed files with 68 additions and 95 deletions

View File

@ -43,7 +43,7 @@
CartridgeBUS::CartridgeBUS(const BytePtr& image, uInt32 size, CartridgeBUS::CartridgeBUS(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
mySystemCycles(0), myAudioCycles(0),
myARMCycles(0), myARMCycles(0),
myFractionalClocks(0.0) myFractionalClocks(0.0)
{ {
@ -77,8 +77,7 @@ void CartridgeBUS::reset()
initializeRAM(myBUSRAM+2048, 8192-2048); initializeRAM(myBUSRAM+2048, 8192-2048);
// Update cycles to the current system cycles // Update cycles to the current system cycles
mySystemCycles = mySystem->cycles(); myAudioCycles = myARMCycles = 0;
myARMCycles = mySystem->cycles();
myFractionalClocks = 0.0; myFractionalClocks = 0.0;
setInitialState(); setInitialState();
@ -135,18 +134,16 @@ 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 = Int32(mySystem->cycles() - mySystemCycles); uInt32 cycles = uInt32(mySystem->cycles() - myAudioCycles);
mySystemCycles = mySystem->cycles(); myAudioCycles = mySystem->cycles();
// Calculate the number of BUS OSC clocks since the last update // Calculate the number of BUS OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks; double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
Int32 wholeClocks = Int32(clocks); uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0)
return;
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
if(wholeClocks > 0)
for(int x = 0; x <= 2; ++x) for(int x = 0; x <= 2; ++x)
myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks; myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
} }
@ -562,8 +559,8 @@ bool CartridgeBUS::save(Serializer& out) const
out.putShort(myJMPoperandAddress); out.putShort(myJMPoperandAddress);
// Save cycles and clocks // Save cycles and clocks
out.putLong(mySystemCycles); out.putLong(myAudioCycles);
out.putInt((uInt32)(myFractionalClocks * 100000000.0)); out.putDouble(myFractionalClocks);
out.putLong(myARMCycles); out.putLong(myARMCycles);
// Audio info // Audio info
@ -606,8 +603,8 @@ bool CartridgeBUS::load(Serializer& in)
myJMPoperandAddress = in.getShort(); myJMPoperandAddress = in.getShort();
// Get system cycles and fractional clocks // Get system cycles and fractional clocks
mySystemCycles = in.getLong(); myAudioCycles = in.getLong();
myFractionalClocks = (double)in.getInt() / 100000000.0; myFractionalClocks = in.getDouble();
myARMCycles = in.getLong(); myARMCycles = in.getLong();
// Audio info // Audio info

View File

@ -244,8 +244,8 @@ class CartridgeBUS : public Cartridge
// *and* the next two bytes in ROM are 00 00 // *and* the next two bytes in ROM are 00 00
uInt16 myJMPoperandAddress; uInt16 myJMPoperandAddress;
// System cycle count when the last update to music data fetchers occurred // System cycle count from when the last update to music data fetchers occurred
uInt64 mySystemCycles; uInt64 myAudioCycles;
// ARM cycle count from when the last callFunction() occurred // ARM cycle count from when the last callFunction() occurred
uInt64 myARMCycles; uInt64 myARMCycles;

View File

@ -81,9 +81,7 @@ void CartridgeCDF::reset()
{ {
initializeRAM(myCDFRAM+2048, 8192-2048); initializeRAM(myCDFRAM+2048, 8192-2048);
// Update cycles to the current system cycles myAudioCycles = myARMCycles = 0;
myAudioCycles = mySystem->cycles();
myARMCycles = mySystem->cycles();
myFractionalClocks = 0.0; myFractionalClocks = 0.0;
setInitialState(); setInitialState();
@ -137,18 +135,16 @@ 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 = Int32(mySystem->cycles() - myAudioCycles); uInt32 cycles = uInt32(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
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks; double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
Int32 wholeClocks = Int32(clocks); uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0)
return;
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
if(wholeClocks > 0)
for(int x = 0; x <= 2; ++x) for(int x = 0; x <= 2; ++x)
myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks; myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
} }
@ -512,7 +508,7 @@ bool CartridgeCDF::save(Serializer& out) const
// Save cycles and clocks // Save cycles and clocks
out.putLong(myAudioCycles); out.putLong(myAudioCycles);
out.putInt((uInt32)(myFractionalClocks * 100000000.0)); out.putDouble(myFractionalClocks);
out.putLong(myARMCycles); out.putLong(myARMCycles);
} }
catch(...) catch(...)
@ -555,7 +551,7 @@ bool CartridgeCDF::load(Serializer& in)
// Get cycles and clocks // Get cycles and clocks
myAudioCycles = in.getLong(); myAudioCycles = in.getLong();
myFractionalClocks = (double)in.getInt() / 100000000.0; myFractionalClocks = in.getDouble();
myARMCycles = in.getLong(); myARMCycles = in.getLong();
} }
catch(...) catch(...)

View File

@ -138,8 +138,6 @@ class CartridgeCDF : public Cartridge
*/ */
string name() const override { return "CartridgeCDF"; } string name() const override { return "CartridgeCDF"; }
// uInt8 busOverdrive(uInt16 address) override;
/** /**
Used for Thumbulator to pass values back to the cartridge Used for Thumbulator to pass values back to the cartridge
*/ */

View File

@ -31,7 +31,7 @@ CartridgeCTY::CartridgeCTY(const BytePtr& image, uInt32 size,
myLDAimmediate(false), myLDAimmediate(false),
myRandomNumber(0x2B435044), myRandomNumber(0x2B435044),
myRamAccessTimeout(0), myRamAccessTimeout(0),
mySystemCycles(0), myAudioCycles(0),
myFractionalClocks(0.0), myFractionalClocks(0.0),
myBankOffset(0) myBankOffset(0)
{ {
@ -53,8 +53,7 @@ void CartridgeCTY::reset()
myRAM[0] = myRAM[1] = myRAM[2] = myRAM[3] = 0xFF; myRAM[0] = myRAM[1] = myRAM[2] = myRAM[3] = 0xFF;
// Update cycles to the current system cycles myAudioCycles = 0;
mySystemCycles = mySystem->cycles();
myFractionalClocks = 0.0; myFractionalClocks = 0.0;
// Upon reset we switch to the startup bank // Upon reset we switch to the startup bank
@ -289,8 +288,8 @@ 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.putLong(mySystemCycles); out.putLong(myAudioCycles);
out.putInt(uInt32(myFractionalClocks * 100000000.0)); out.putDouble(myFractionalClocks);
} }
catch(...) catch(...)
@ -318,8 +317,8 @@ 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.getLong(); myAudioCycles = in.getLong();
myFractionalClocks = double(in.getInt()) / 100000000.0; myFractionalClocks = in.getDouble();
} }
catch(...) catch(...)
{ {
@ -506,18 +505,16 @@ 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 = Int32(mySystem->cycles() - mySystemCycles); uInt32 cycles = uInt32(mySystem->cycles() - myAudioCycles);
mySystemCycles = mySystem->cycles(); myAudioCycles = mySystem->cycles();
// Calculate the number of DPC OSC clocks since the last update // Calculate the number of CTY OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks; double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
Int32 wholeClocks = Int32(clocks); uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0)
return;
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
if(wholeClocks > 0)
for(int x = 0; x <= 2; ++x) for(int x = 0; x <= 2; ++x)
; // myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks; ; //myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
} }

View File

@ -292,8 +292,8 @@ class CartridgeCTY : public Cartridge
// of internal RAM to Harmony cart EEPROM // of internal RAM to Harmony cart EEPROM
string myEEPROMFile; string myEEPROMFile;
// System cycle count when the last update to music data fetchers occurred // System cycle count from when the last update to music data fetchers occurred
uInt64 mySystemCycles; uInt64 myAudioCycles;
// Fractional DPC music OSC clocks unused during the last update // Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks; double myFractionalClocks;

View File

@ -23,7 +23,7 @@ CartridgeDPC::CartridgeDPC(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
mySize(size), mySize(size),
mySystemCycles(0), myAudioCycles(0),
myFractionalClocks(0.0), myFractionalClocks(0.0),
myBankOffset(0) myBankOffset(0)
{ {
@ -54,8 +54,7 @@ CartridgeDPC::CartridgeDPC(const BytePtr& image, uInt32 size,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPC::reset() void CartridgeDPC::reset()
{ {
// Update cycles to the current system cycles myAudioCycles = 0;
mySystemCycles = mySystem->cycles();
myFractionalClocks = 0.0; myFractionalClocks = 0.0;
// Upon reset we switch to the startup bank // Upon reset we switch to the startup bank
@ -98,18 +97,16 @@ 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 = Int32(mySystem->cycles() - mySystemCycles); uInt32 cycles = uInt32(mySystem->cycles() - myAudioCycles);
mySystemCycles = mySystem->cycles(); myAudioCycles = mySystem->cycles();
// Calculate the number of DPC OSC clocks since the last update // Calculate the number of DPC OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks; double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
Int32 wholeClocks = Int32(clocks); uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0) if(wholeClocks <= 0)
{
return; return;
}
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
for(int x = 5; x <= 7; ++x) for(int x = 5; x <= 7; ++x)
@ -124,24 +121,16 @@ inline void CartridgeDPC::updateMusicModeDataFetchers()
{ {
newLow -= (wholeClocks % top); newLow -= (wholeClocks % top);
if(newLow < 0) if(newLow < 0)
{
newLow += top; newLow += top;
} }
}
else else
{
newLow = 0; newLow = 0;
}
// Update flag register for this data fetcher // Update flag register for this data fetcher
if(newLow <= myBottoms[x]) if(newLow <= myBottoms[x])
{
myFlags[x] = 0x00; myFlags[x] = 0x00;
}
else if(newLow <= myTops[x]) else if(newLow <= myTops[x])
{
myFlags[x] = 0xff; myFlags[x] = 0xff;
}
myCounters[x] = (myCounters[x] & 0x0700) | uInt16(newLow); myCounters[x] = (myCounters[x] & 0x0700) | uInt16(newLow);
} }
@ -474,8 +463,8 @@ bool CartridgeDPC::save(Serializer& out) const
// The random number generator register // The random number generator register
out.putByte(myRandomNumber); out.putByte(myRandomNumber);
out.putLong(mySystemCycles); out.putLong(myAudioCycles);
out.putInt(uInt32(myFractionalClocks * 100000000.0)); out.putDouble(myFractionalClocks);
} }
catch(...) catch(...)
{ {
@ -517,8 +506,8 @@ bool CartridgeDPC::load(Serializer& in)
myRandomNumber = in.getByte(); myRandomNumber = in.getByte();
// Get system cycles and fractional clocks // Get system cycles and fractional clocks
mySystemCycles = in.getLong(); myAudioCycles = in.getLong();
myFractionalClocks = double(in.getInt()) / 100000000.0; myFractionalClocks = in.getDouble();
} }
catch(...) catch(...)
{ {

View File

@ -195,8 +195,8 @@ class CartridgeDPC : public Cartridge
// The random number generator register // The random number generator register
uInt8 myRandomNumber; uInt8 myRandomNumber;
// System cycle count when the last update to music data fetchers occurred // System cycle count from when the last update to music data fetchers occurred
uInt64 mySystemCycles; uInt64 myAudioCycles;
// Fractional DPC music OSC clocks unused during the last update // Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks; double myFractionalClocks;

View File

@ -30,9 +30,9 @@ CartridgeDPCPlus::CartridgeDPCPlus(const BytePtr& image, uInt32 size,
myFastFetch(false), myFastFetch(false),
myLDAimmediate(false), myLDAimmediate(false),
myParameterPointer(0), myParameterPointer(0),
mySystemCycles(0), myAudioCycles(0),
myFractionalClocks(0.0),
myARMCycles(0), myARMCycles(0),
myFractionalClocks(0.0),
myBankOffset(0) myBankOffset(0)
{ {
// Image is always 32K, but in the case of ROM > 29K, the image is // Image is always 32K, but in the case of ROM > 29K, the image is
@ -70,9 +70,7 @@ CartridgeDPCPlus::CartridgeDPCPlus(const BytePtr& image, uInt32 size,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::reset() void CartridgeDPCPlus::reset()
{ {
// Update cycles to the current system cycles myAudioCycles = myARMCycles = 0;
mySystemCycles = mySystem->cycles();
myARMCycles = mySystem->cycles();
myFractionalClocks = 0.0; myFractionalClocks = 0.0;
setInitialState(); setInitialState();
@ -145,18 +143,16 @@ 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 = Int32(mySystem->cycles() - mySystemCycles); uInt32 cycles = uInt32(mySystem->cycles() - myAudioCycles);
mySystemCycles = mySystem->cycles(); myAudioCycles = mySystem->cycles();
// Calculate the number of DPC OSC clocks since the last update // Calculate the number of DPC+ OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks; double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
Int32 wholeClocks = Int32(clocks); uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0)
return;
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
if(wholeClocks > 0)
for(int x = 0; x <= 2; ++x) for(int x = 0; x <= 2; ++x)
myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks; myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
} }
@ -682,8 +678,8 @@ 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.putLong(mySystemCycles); out.putLong(myAudioCycles);
out.putInt(uInt32(myFractionalClocks * 100000000.0)); out.putDouble(myFractionalClocks);
// Clock info for Thumbulator // Clock info for Thumbulator
out.putLong(myARMCycles); out.putLong(myARMCycles);
@ -745,9 +741,9 @@ bool CartridgeDPCPlus::load(Serializer& in)
// The random number generator register // The random number generator register
myRandomNumber = in.getInt(); myRandomNumber = in.getInt();
// Get system cycles and fractional clocks // Get audio cycles and fractional clocks
mySystemCycles = in.getLong(); myAudioCycles = in.getLong();
myFractionalClocks = double(in.getInt()) / 100000000.0; myFractionalClocks = in.getDouble();
// Clock info for Thumbulator // Clock info for Thumbulator
myARMCycles = in.getLong(); myARMCycles = in.getLong();

View File

@ -259,15 +259,15 @@ class CartridgeDPCPlus : public Cartridge
// The random number generator register // The random number generator register
uInt32 myRandomNumber; uInt32 myRandomNumber;
// System cycle count when the last update to music data fetchers occurred // System cycle count from when the last update to music data fetchers occurred
uInt64 mySystemCycles; uInt64 myAudioCycles;
// Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks;
// System cycle count when the last Thumbulator::run() occurred // System cycle count when the last Thumbulator::run() occurred
uInt64 myARMCycles; uInt64 myARMCycles;
// Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks;
// 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;