added that digital audio considers console timing

added a 10% factor to ARM cycle count when digital audio is enabled
This commit is contained in:
Thomas Jentzsch 2021-06-25 09:18:26 +02:00
parent 0bbf9ce945
commit acbfad3e56
14 changed files with 118 additions and 67 deletions

View File

@ -43,6 +43,24 @@ void CartridgeARM::setInitialState()
enableCycleCount(devSettings);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeARM::consoleChanged(ConsoleTiming timing)
{
myThumbEmulator->setConsoleTiming(timing);
constexpr double NTSC = 1193191.66666667; // NTSC 6507 clock rate
constexpr double PAL = 1182298; // PAL 6507 clock rate
constexpr double SECAM = 1187500; // SECAM 6507 clock rate
switch(timing)
{
case ConsoleTiming::ntsc: myClockRate = NTSC; break;
case ConsoleTiming::pal: myClockRate = PAL; break;
case ConsoleTiming::secam: myClockRate = SECAM; break;
default: break; // satisfy compiler
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeARM::updateCycles(int cycles)
{

View File

@ -35,6 +35,15 @@ class CartridgeARM : public Cartridge
~CartridgeARM() override = default;
protected:
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Save the current state of this cart to the given Serializer.
@ -69,7 +78,7 @@ class CartridgeARM : public Cartridge
void incCycles(bool enable);
void cycleFactor(double factor);
double cycleFactor() const { return myThumbEmulator->cycleFactor(); }
void setChipType(Thumbulator::ChipType armType) { myThumbEmulator->setChipType(armType); }
void setChipType(Thumbulator::ChipType chipType) { myThumbEmulator->setChipType(chipType); }
void lockMamMode(bool lock) { myThumbEmulator->lockMamMode(lock); }
void setMamMode(Thumbulator::MamModeType mamMode) { myThumbEmulator->setMamMode(mamMode); }
Thumbulator::MamModeType mamMode() const { return myThumbEmulator->mamMode(); }
@ -80,6 +89,9 @@ class CartridgeARM : public Cartridge
// ARM code increases 6507 cycles
bool myIncCycles{false};
// Console clock rate
double myClockRate{1193191.66666667};
#ifdef DEBUGGER_SUPPORT
Thumbulator::Stats myStats{0};
Thumbulator::Stats myPrevStats{0};

View File

@ -116,12 +116,6 @@ void CartridgeBUS::setInitialState()
CartridgeARM::setInitialState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBUS::consoleChanged(ConsoleTiming timing)
{
myThumbEmulator->setConsoleTiming(timing);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBUS::install(System& system)
{
@ -149,7 +143,7 @@ inline void CartridgeBUS::updateMusicModeDataFetchers()
myAudioCycles = mySystem->cycles();
// Calculate the number of BUS OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
double clocks = ((20000.0 * cycles) / myClockRate) + myFractionalClocks;
uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks);
@ -172,7 +166,7 @@ inline void CartridgeBUS::callFunction(uInt8 value)
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
myARMCycles = mySystem->cycles();
myThumbEmulator->run(cycles);
myThumbEmulator->run(cycles, value == 254);
updateCycles(cycles);
}
catch(const runtime_error& e) {

View File

@ -64,15 +64,6 @@ class CartridgeBUS : public CartridgeARM
*/
void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.

View File

@ -149,12 +149,6 @@ void CartridgeCDF::setInitialState()
CartridgeARM::setInitialState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCDF::consoleChanged(ConsoleTiming timing)
{
myThumbEmulator->setConsoleTiming(timing);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCDF::install(System& system)
{
@ -177,7 +171,7 @@ inline void CartridgeCDF::updateMusicModeDataFetchers()
myAudioCycles = mySystem->cycles();
// Calculate the number of CDF OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
double clocks = ((20000.0 * cycles) / myClockRate) + myFractionalClocks;
uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks);
@ -200,7 +194,7 @@ inline void CartridgeCDF::callFunction(uInt8 value)
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
myARMCycles = mySystem->cycles();
myThumbEmulator->run(cycles);
myThumbEmulator->run(cycles, value == 254);
updateCycles(cycles);
}
catch(const runtime_error& e) {

View File

@ -85,15 +85,6 @@ class CartridgeCDF : public CartridgeARM
*/
void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.

View File

@ -64,6 +64,22 @@ void CartridgeCTY::reset()
bank(startBank());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCTY::consoleChanged(ConsoleTiming timing)
{
constexpr double NTSC = 1193191.66666667; // NTSC 6507 clock rate
constexpr double PAL = 1182298.0; // PAL 6507 clock rate
constexpr double SECAM = 1187500.0; // SECAM 6507 clock rate
switch(timing)
{
case ConsoleTiming::ntsc: myClockRate = NTSC; break;
case ConsoleTiming::pal: myClockRate = PAL; break;
case ConsoleTiming::secam: myClockRate = SECAM; break;
default: break; // satisfy compiler
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCTY::install(System& system)
{
@ -573,7 +589,7 @@ inline void CartridgeCTY::updateMusicModeDataFetchers()
myAudioCycles = mySystem->cycles();
// Calculate the number of CTY OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
double clocks = ((20000.0 * cycles) / myClockRate) + myFractionalClocks;
uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks);

View File

@ -128,6 +128,15 @@ class CartridgeCTY : public Cartridge
*/
void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.
@ -271,6 +280,9 @@ class CartridgeCTY : public Cartridge
// The 64 bytes of RAM accessible at $1000 - $1080
std::array<uInt8, 64> myRAM;
// Console clock rate
double myClockRate{1193191.66666667};
// Operation type (written to $1000, used by hotspot $1FF4)
uInt8 myOperationType{0};

View File

@ -38,6 +38,22 @@ void CartridgeDPC::reset()
myDpcPitch = mySettings.getInt(AudioSettings::SETTING_DPC_PITCH);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPC::consoleChanged(ConsoleTiming timing)
{
constexpr double NTSC = 1193191.66666667; // NTSC 6507 clock rate
constexpr double PAL = 1182298.0; // PAL 6507 clock rate
constexpr double SECAM = 1187500.0; // SECAM 6507 clock rate
switch(timing)
{
case ConsoleTiming::ntsc: myClockRate = NTSC; break;
case ConsoleTiming::pal: myClockRate = PAL; break;
case ConsoleTiming::secam: myClockRate = SECAM; break;
default: break; // satisfy compiler
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPC::install(System& system)
{
@ -82,7 +98,7 @@ inline void CartridgeDPC::updateMusicModeDataFetchers()
myAudioCycles = mySystem->cycles();
// Calculate the number of DPC OSC clocks since the last update
double clocks = ((myDpcPitch * cycles) / 1193191.66666667) + myFractionalClocks;
double clocks = ((myDpcPitch * cycles) / myClockRate) + myFractionalClocks;
uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks);

View File

@ -53,18 +53,28 @@ class CartridgeDPC : public CartridgeF8
~CartridgeDPC() override = default;
public:
/**
Reset device to its power-on state
*/
void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.
@param system The system the device should install itself in
*/
void install(System& system) override;
/**
Reset device to its power-on state
*/
void reset() override;
void install(System& system) override;
/**
Patch the cartridge ROM.
@ -147,6 +157,9 @@ class CartridgeDPC : public CartridgeF8
void updateMusicModeDataFetchers();
private:
// Console clock rate
double myClockRate{1193191.66666667};
// Pointer to the 2K display ROM image of the cartridge
uInt8* myDisplayImage{nullptr};

View File

@ -122,12 +122,6 @@ void CartridgeDPCPlus::setInitialState()
CartridgeARM::setInitialState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::consoleChanged(ConsoleTiming timing)
{
myThumbEmulator->setConsoleTiming(timing);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlus::install(System& system)
{
@ -167,7 +161,7 @@ inline void CartridgeDPCPlus::updateMusicModeDataFetchers()
myAudioCycles = mySystem->cycles();
// Calculate the number of DPC+ OSC clocks since the last update
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
double clocks = ((20000.0 * cycles) / myClockRate) + myFractionalClocks;
uInt32 wholeClocks = uInt32(clocks);
myFractionalClocks = clocks - double(wholeClocks);
@ -205,7 +199,7 @@ inline void CartridgeDPCPlus::callFunction(uInt8 value)
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
myARMCycles = mySystem->cycles();
myThumbEmulator->run(cycles);
myThumbEmulator->run(cycles, value == 254);
updateCycles(cycles);
}
catch(const runtime_error& e) {

View File

@ -65,15 +65,6 @@ class CartridgeDPCPlus : public CartridgeARM
*/
void reset() override;
/**
Notification method invoked by the system when the console type
has changed. We need this to inform the Thumbulator that the
timing has changed.
@param timing Enum representing the new console type
*/
void consoleChanged(ConsoleTiming timing) override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.

View File

@ -105,8 +105,9 @@ Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Thumbulator::doRun(uInt32& cycles)
string Thumbulator::doRun(uInt32& cycles, bool irqDrivenAudio)
{
_irqDrivenAudio = irqDrivenAudio;
reset();
for(;;)
{
@ -118,6 +119,12 @@ string Thumbulator::doRun(uInt32& cycles)
}
#ifdef THUMB_CYCLE_COUNT
_totalCycles *= _armCyclesFactor;
// assuming 10% per scanline is spend for audio updates
// (equals 5 cycles 6507 code + ~130-155 cycles ARM code)
if(_irqDrivenAudio)
_totalCycles *= 1.10;
//_totalCycles = 127148; // VB during Turbo start sequence
cycles = _totalCycles / timing_factor;
#else
@ -137,9 +144,9 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
{
// this sets how many ticks of the Harmony/Melody clock
// will occur per tick of the 6507 clock
constexpr double NTSC = 1.193182; // NTSC 6507 clock rate
constexpr double PAL = 1.182298; // PAL 6507 clock rate
constexpr double SECAM = 1.187500; // SECAM 6507 clock rate
constexpr double NTSC = 1.19318166666667; // NTSC 6507 clock rate
constexpr double PAL = 1.182298; // PAL 6507 clock rate
constexpr double SECAM = 1.187500; // SECAM 6507 clock rate
_consoleTiming = timing;
switch(timing)
@ -169,10 +176,10 @@ void Thumbulator::updateTimer(uInt32 cycles)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Thumbulator::run(uInt32& cycles)
string Thumbulator::run(uInt32& cycles, bool irqDrivenAudio)
{
updateTimer(cycles);
return doRun(cycles);
return doRun(cycles, irqDrivenAudio);
}
#ifndef UNSAFE_OPTIMIZATIONS
@ -1595,6 +1602,7 @@ int Thumbulator::execute()
rc += 2;
//rc &= ~1;
write_register(15, rc);
//_totalCycles += 100; // just a wild guess
return 0;
}
return 1;

View File

@ -104,8 +104,7 @@ class Thumbulator
@return The results of any debugging output (if enabled),
otherwise an empty string
*/
string doRun(uInt32& cycles);
string run(uInt32& cycles);
string run(uInt32& cycles, bool irqDrivenAudio);
void enableCycleCount(bool enable) { _countCycles = enable; }
const Stats& stats() const { return _stats; }
const uInt32 cycles() const { return _totalCycles; }
@ -207,6 +206,7 @@ class Thumbulator
#endif
private:
string doRun(uInt32& cycles, bool irqDrivenAudio);
uInt32 read_register(uInt32 reg);
void write_register(uInt32 reg, uInt32 data, bool isFlowBreak = true);
uInt32 fetch16(uInt32 addr);
@ -268,6 +268,7 @@ class Thumbulator
uInt32 _flashCycles{4};
uInt32 _flashBanks{1};
Stats _stats{0};
bool _irqDrivenAudio{false};
uInt32 _totalCycles{0};
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.