mirror of https://github.com/stella-emu/stella.git
added command line options to include (coarse) ARM cycles into system cycles
This commit is contained in:
parent
c02fc531aa
commit
0c511805c7
|
@ -3541,6 +3541,16 @@
|
||||||
fatal errors are simply logged, and emulation continues. Do not use this
|
fatal errors are simply logged, and emulation continues. Do not use this
|
||||||
unless you know exactly what you're doing, as it changes the behaviour as
|
unless you know exactly what you're doing, as it changes the behaviour as
|
||||||
compared to real hardware.</td>
|
compared to real hardware.</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td><pre>-dev.thumb.incycles <1|0></pre></td>
|
||||||
|
<td>When enabled, ARM emulation cycles are added to system cycles. This
|
||||||
|
allows detecting timer overruns.</br>
|
||||||
|
Note: The ARM emulation cycles are only a coarse approximation.
|
||||||
|
</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td><pre>-dev.thumb.cyclefactor <float></pre></td>
|
||||||
|
<td>Adjust ARM emulation cycles by a factor (1.25 = default).
|
||||||
|
</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><pre>-<plr.|dev.>eepromaccess <1|0></pre></td>
|
<td><pre>-<plr.|dev.>eepromaccess <1|0></pre></td>
|
||||||
<td>When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
|
<td>When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
|
||||||
|
|
|
@ -72,9 +72,12 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size,
|
||||||
0x00000808,
|
0x00000808,
|
||||||
0x40001FDC,
|
0x40001FDC,
|
||||||
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
||||||
|
devSettings ? settings.getFloat("dev.thumb.cyclefactor") : 1.0,
|
||||||
Thumbulator::ConfigureFor::BUS,
|
Thumbulator::ConfigureFor::BUS,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
myIncCycles = devSettings ? settings.getBool("dev.thumb.inccycles") : false,
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,10 +170,12 @@ 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 = Int32(mySystem->cycles() - myARMCycles);
|
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
|
||||||
|
|
||||||
|
myARMCycles = mySystem->cycles();
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
if(myIncCycles)
|
||||||
|
mySystem->incrementCycles(cycles);
|
||||||
}
|
}
|
||||||
catch(const runtime_error& e) {
|
catch(const runtime_error& e) {
|
||||||
if(!mySystem->autodetectMode())
|
if(!mySystem->autodetectMode())
|
||||||
|
|
|
@ -299,6 +299,9 @@ class CartridgeBUS : public Cartridge
|
||||||
|
|
||||||
uInt8 myFastJumpActive{false};
|
uInt8 myFastJumpActive{false};
|
||||||
|
|
||||||
|
// ARM code increases 6507 cycles
|
||||||
|
bool myIncCycles{false};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeBUS() = delete;
|
CartridgeBUS() = delete;
|
||||||
|
|
|
@ -108,9 +108,12 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size,
|
||||||
static_cast<uInt32>(mySize),
|
static_cast<uInt32>(mySize),
|
||||||
cBase, cStart, cStack,
|
cBase, cStart, cStack,
|
||||||
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
||||||
|
devSettings ? settings.getFloat("dev.thumb.cyclefactor") : 1.0,
|
||||||
thumulatorConfiguration(myCDFSubtype),
|
thumulatorConfiguration(myCDFSubtype),
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
myIncCycles = devSettings ? settings.getBool("dev.thumb.inccycles") : false,
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,10 +198,12 @@ 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 = Int32(mySystem->cycles() - myARMCycles);
|
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
|
||||||
|
|
||||||
|
myARMCycles = mySystem->cycles();
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
if(myIncCycles)
|
||||||
|
mySystem->incrementCycles(cycles); // * ~1.79 is the limit for ZEVIOUZ title screen
|
||||||
}
|
}
|
||||||
catch(const runtime_error& e) {
|
catch(const runtime_error& e) {
|
||||||
if(!mySystem->autodetectMode())
|
if(!mySystem->autodetectMode())
|
||||||
|
|
|
@ -369,6 +369,9 @@ class CartridgeCDF : public Cartridge
|
||||||
// CDF subtype
|
// CDF subtype
|
||||||
CDFSubtype myCDFSubtype{CDFSubtype::CDF0};
|
CDFSubtype myCDFSubtype{CDFSubtype::CDF0};
|
||||||
|
|
||||||
|
// ARM code increases 6507 cycles
|
||||||
|
bool myIncCycles{false};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCDF() = delete;
|
CartridgeCDF() = delete;
|
||||||
|
|
|
@ -58,6 +58,7 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size,
|
||||||
0x00000C08,
|
0x00000C08,
|
||||||
0x40001FDC,
|
0x40001FDC,
|
||||||
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
|
||||||
|
devSettings ? settings.getFloat("dev.thumb.cyclefactor") : 1.0,
|
||||||
Thumbulator::ConfigureFor::DPCplus,
|
Thumbulator::ConfigureFor::DPCplus,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
@ -77,6 +78,8 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size,
|
||||||
myDriverMD5 == "8dd73b44fd11c488326ce507cbeb19d1" )
|
myDriverMD5 == "8dd73b44fd11c488326ce507cbeb19d1" )
|
||||||
myFractionalLowMask = 0x0F0000;
|
myFractionalLowMask = 0x0F0000;
|
||||||
|
|
||||||
|
myIncCycles = devSettings ? settings.getBool("dev.thumb.inccycles") : false,
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,10 +203,12 @@ 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 = Int32(mySystem->cycles() - myARMCycles);
|
uInt32 cycles = uInt32(mySystem->cycles() - myARMCycles);
|
||||||
myARMCycles = mySystem->cycles();
|
|
||||||
|
|
||||||
|
myARMCycles = mySystem->cycles();
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
|
if(myIncCycles)
|
||||||
|
mySystem->incrementCycles(cycles);
|
||||||
}
|
}
|
||||||
catch(const runtime_error& e) {
|
catch(const runtime_error& e) {
|
||||||
if(!mySystem->autodetectMode())
|
if(!mySystem->autodetectMode())
|
||||||
|
|
|
@ -312,6 +312,9 @@ class CartridgeDPCPlus : public Cartridge
|
||||||
// For current versions, this is 0x0F00FF; older versions need 0x0F0000
|
// For current versions, this is 0x0F00FF; older versions need 0x0F0000
|
||||||
uInt32 myFractionalLowMask{0x0F00FF};
|
uInt32 myFractionalLowMask{0x0F00FF};
|
||||||
|
|
||||||
|
// ARM code increases 6507 cycles
|
||||||
|
bool myIncCycles{false};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeDPCPlus() = delete;
|
CartridgeDPCPlus() = delete;
|
||||||
|
|
|
@ -242,10 +242,12 @@ Settings::Settings()
|
||||||
setPermanent("dev.tm.uncompressed", 600);
|
setPermanent("dev.tm.uncompressed", 600);
|
||||||
setPermanent("dev.tm.interval", "1f"); // = 1 frame
|
setPermanent("dev.tm.interval", "1f"); // = 1 frame
|
||||||
setPermanent("dev.tm.horizon", "30s"); // = ~30 seconds
|
setPermanent("dev.tm.horizon", "30s"); // = ~30 seconds
|
||||||
// Thumb ARM emulation options
|
|
||||||
setPermanent("dev.thumb.trapfatal", "true");
|
|
||||||
setPermanent("dev.detectedinfo", "true");
|
setPermanent("dev.detectedinfo", "true");
|
||||||
setPermanent("dev.eepromaccess", "true");
|
setPermanent("dev.eepromaccess", "true");
|
||||||
|
// Thumb ARM emulation options
|
||||||
|
setPermanent("dev.thumb.trapfatal", "true");
|
||||||
|
setPermanent("dev.thumb.inccycles", "true");
|
||||||
|
setPermanent("dev.thumb.cyclefactor", "1.25");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -683,6 +685,8 @@ void Settings::usage() const
|
||||||
#endif
|
#endif
|
||||||
<< " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation\n"
|
<< " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation\n"
|
||||||
<< " throw an exception\n"
|
<< " throw an exception\n"
|
||||||
|
<< " -dev.thumb.inccycles <1|0> Determines whether ARM emulation cycles\n"
|
||||||
|
<< " increase system cycles\n"
|
||||||
<< " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
|
<< " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
|
||||||
<< " messages\n"
|
<< " messages\n"
|
||||||
<< " -dev.tia.type <standard|custom| Selects a TIA type\n"
|
<< " -dev.tia.type <standard|custom| Selects a TIA type\n"
|
||||||
|
|
|
@ -52,10 +52,13 @@ using Common::Base;
|
||||||
#define CONV_RAMROM(d) (d)
|
#define CONV_RAMROM(d) (d)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CYCLE_FACTOR 1.25 // coarse ARM cycle multiplier
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
||||||
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
||||||
bool traponfatal, Thumbulator::ConfigureFor configurefor,
|
bool traponfatal, double cyclefactor,
|
||||||
|
Thumbulator::ConfigureFor configurefor,
|
||||||
Cartridge* cartridge)
|
Cartridge* cartridge)
|
||||||
: rom{rom_ptr},
|
: rom{rom_ptr},
|
||||||
romSize{rom_size},
|
romSize{rom_size},
|
||||||
|
@ -73,12 +76,15 @@ Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size
|
||||||
setConsoleTiming(ConsoleTiming::ntsc);
|
setConsoleTiming(ConsoleTiming::ntsc);
|
||||||
#ifndef UNSAFE_OPTIMIZATIONS
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
trapFatalErrors(traponfatal);
|
trapFatalErrors(traponfatal);
|
||||||
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
cycleFactor(cyclefactor);
|
||||||
#endif
|
#endif
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string Thumbulator::run()
|
string Thumbulator::doRun(uInt32& cycles)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
for(;;)
|
for(;;)
|
||||||
|
@ -89,6 +95,11 @@ string Thumbulator::run()
|
||||||
throw runtime_error("instructions > 500000");
|
throw runtime_error("instructions > 500000");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
cycles = uInt32((_stats.fetches + _stats.reads + _stats.writes) * arm_cycle_factor / timing_factor);
|
||||||
|
#else
|
||||||
|
cycles = 0;
|
||||||
|
#endif
|
||||||
#if defined(THUMB_DISS) || defined(THUMB_DBUG)
|
#if defined(THUMB_DISS) || defined(THUMB_DBUG)
|
||||||
dump_counters();
|
dump_counters();
|
||||||
cout << statusMsg.str() << endl;
|
cout << statusMsg.str() << endl;
|
||||||
|
@ -119,15 +130,19 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::updateTimer(uInt32 cycles)
|
void Thumbulator::updateTimer(uInt32 cycles)
|
||||||
{
|
{
|
||||||
|
#ifdef TIMER_0
|
||||||
|
if(T0TCR & 1) // bit 0 controls timer on/off
|
||||||
|
T0TC += uInt32(cycles * timing_factor);
|
||||||
|
#endif
|
||||||
if (T1TCR & 1) // bit 0 controls timer on/off
|
if (T1TCR & 1) // bit 0 controls timer on/off
|
||||||
T1TC += uInt32(cycles * timing_factor);
|
T1TC += uInt32(cycles * timing_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string Thumbulator::run(uInt32 cycles)
|
string Thumbulator::run(uInt32& cycles)
|
||||||
{
|
{
|
||||||
updateTimer(cycles);
|
updateTimer(cycles);
|
||||||
return run();
|
return doRun(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef UNSAFE_OPTIMIZATIONS
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
|
@ -289,7 +304,15 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
|
||||||
DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]" << endl);
|
DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]" << endl);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TIMER_0
|
||||||
|
case 0xE0004004: // T0TCR - Timer 0 Control Register
|
||||||
|
T0TCR = data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xE0004008: // T0TC - Timer 0 Counter
|
||||||
|
T0TC = data;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
||||||
T1TCR = data;
|
T1TCR = data;
|
||||||
break;
|
break;
|
||||||
|
@ -467,6 +490,15 @@ uInt32 Thumbulator::read32(uInt32 addr)
|
||||||
{
|
{
|
||||||
switch(addr)
|
switch(addr)
|
||||||
{
|
{
|
||||||
|
#ifdef TIMER_0
|
||||||
|
case 0xE0004004: // T0TCR - Timer 0 Control Register
|
||||||
|
data = T0TCR;
|
||||||
|
return data;
|
||||||
|
|
||||||
|
case 0xE0004008: // T0TC - Timer 0 Counter
|
||||||
|
data = T0TC;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
||||||
data = T1TCR;
|
data = T1TCR;
|
||||||
return data;
|
return data;
|
||||||
|
@ -2560,4 +2592,5 @@ int Thumbulator::reset()
|
||||||
#ifndef UNSAFE_OPTIMIZATIONS
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Thumbulator::trapOnFatal = true;
|
bool Thumbulator::trapOnFatal = true;
|
||||||
|
double Thumbulator::arm_cycle_factor = 1.25;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -46,6 +46,8 @@ class Cartridge;
|
||||||
#define CPSR_C (1u<<29)
|
#define CPSR_C (1u<<29)
|
||||||
#define CPSR_V (1u<<28)
|
#define CPSR_V (1u<<28)
|
||||||
|
|
||||||
|
//#define TIMER_0 // enable timer 0 support
|
||||||
|
|
||||||
class Thumbulator
|
class Thumbulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -68,7 +70,8 @@ class Thumbulator
|
||||||
|
|
||||||
Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
||||||
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
||||||
bool traponfatal, Thumbulator::ConfigureFor configurefor,
|
bool traponfatal, double cyclefactor,
|
||||||
|
Thumbulator::ConfigureFor configurefor,
|
||||||
Cartridge* cartridge);
|
Cartridge* cartridge);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,8 +82,8 @@ class Thumbulator
|
||||||
@return The results of any debugging output (if enabled),
|
@return The results of any debugging output (if enabled),
|
||||||
otherwise an empty string
|
otherwise an empty string
|
||||||
*/
|
*/
|
||||||
string run();
|
string doRun(uInt32& cycles);
|
||||||
string run(uInt32 cycles);
|
string run(uInt32& cycles);
|
||||||
const Stats& stats() const { return _stats; }
|
const Stats& stats() const { return _stats; }
|
||||||
const Stats& prevStats() const { return _prevStats; }
|
const Stats& prevStats() const { return _prevStats; }
|
||||||
|
|
||||||
|
@ -99,6 +102,9 @@ class Thumbulator
|
||||||
*/
|
*/
|
||||||
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
static void cycleFactor(double factor) { arm_cycle_factor = factor; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Inform the Thumbulator class about the console currently in use,
|
Inform the Thumbulator class about the console currently in use,
|
||||||
|
@ -215,6 +221,10 @@ class Thumbulator
|
||||||
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
||||||
// Register names from documentation:
|
// Register names from documentation:
|
||||||
// http://www.nxp.com/documents/user_manual/UM10161.pdf
|
// http://www.nxp.com/documents/user_manual/UM10161.pdf
|
||||||
|
#ifdef TIMER_0
|
||||||
|
uInt32 T0TCR{0}; // Timer 0 Timer Control Register
|
||||||
|
uInt32 T0TC{0}; // Timer 0 Timer Counter
|
||||||
|
#endif
|
||||||
uInt32 T1TCR{0}; // Timer 1 Timer Control Register
|
uInt32 T1TCR{0}; // Timer 1 Timer Control Register
|
||||||
uInt32 T1TC{0}; // Timer 1 Timer Counter
|
uInt32 T1TC{0}; // Timer 1 Timer Counter
|
||||||
double timing_factor{0.0};
|
double timing_factor{0.0};
|
||||||
|
@ -224,6 +234,9 @@ class Thumbulator
|
||||||
|
|
||||||
static bool trapOnFatal;
|
static bool trapOnFatal;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
static double arm_cycle_factor;
|
||||||
|
#endif
|
||||||
|
|
||||||
ConfigureFor configuration;
|
ConfigureFor configuration;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue