mirror of https://github.com/stella-emu/stella.git
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:
parent
0bbf9ce945
commit
acbfad3e56
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue