Improved cycle counting for MUL instruction

Made ARM Timers functional
This commit is contained in:
Thomas Jentzsch 2021-06-15 18:55:32 +02:00
parent f87aafb3e9
commit b07c74d5e5
3 changed files with 26 additions and 9 deletions

View File

@ -247,7 +247,7 @@ Settings::Settings()
// Thumb ARM emulation options
setPermanent("dev.thumb.trapfatal", "true");
setPermanent("dev.thumb.inccycles", "true");
setPermanent("dev.thumb.cyclefactor", "1.25");
setPermanent("dev.thumb.cyclefactor", "1.05");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -132,10 +132,16 @@ void Thumbulator::updateTimer(uInt32 cycles)
{
#ifdef TIMER_0
if(T0TCR & 1) // bit 0 controls timer on/off
{
T0TC += uInt32(cycles * timing_factor);
tim0Cycles = 0;
}
#endif
if (T1TCR & 1) // bit 0 controls timer on/off
if(T1TCR & 1) // bit 0 controls timer on/off
{
T1TC += uInt32(cycles * timing_factor);
tim1Cycles = 0;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -312,6 +318,7 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
case 0xE0004008: // T0TC - Timer 0 Counter
T0TC = data;
tim1Cycles = _stats.cycles;
break;
#endif
case 0xE0008004: // T1TCR - Timer 1 Control Register
@ -320,6 +327,7 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
case 0xE0008008: // T1TC - Timer 1 Counter
T1TC = data;
tim1Cycles = _stats.cycles;
break;
case 0xE000E010:
@ -497,7 +505,7 @@ uInt32 Thumbulator::read32(uInt32 addr)
return data;
case 0xE0004008: // T0TC - Timer 0 Counter
data = T0TC;
data = T0TC + _stats.cycles - tim0Cycles;
break;
#endif
case 0xE0008004: // T1TCR - Timer 1 Control Register
@ -505,7 +513,7 @@ uInt32 Thumbulator::read32(uInt32 addr)
return data;
case 0xE0008008: // T1TC - Timer 1 Counter
data = T1TC;
data = T1TC + _stats.cycles - tim1Cycles;
return data;
case 0xE000E010:
@ -2078,14 +2086,21 @@ int Thumbulator::execute()
//MUL
case Op::mul: {
#ifndef NO_THUMB_STATS
_stats.cycles += 2; // asuming 16 bits TODO: check bits set
#endif
rd = (inst >> 0) & 0x7;
rm = (inst >> 3) & 0x7;
DO_DISS(statusMsg << "muls r" << dec << rd << ",r" << dec << rm << endl);
ra = read_register(rd);
rb = read_register(rm);
#ifndef NO_THUMB_STATS
if((rb & 0xffffff00) == 0 || (rb & 0xffffff00) == 0xffffff00) // -2^8 <= rb < 2^8
++_stats.cycles;
else if((rb & 0xffff0000) == 0 || (rb & 0xffff0000) == 0xffff0000) // -2^16 <= rb < 2^16
_stats.cycles += 2;
else if((rb & 0xff000000) == 0 || (rb & 0xff000000) == 0xff000000) // -2^24 <= rb < 2^24
_stats.cycles += 3;
else
_stats.cycles += 4;
#endif
rc = ra * rb;
write_register(rd, rc);
do_nflag(rc);
@ -2704,5 +2719,5 @@ int Thumbulator::reset()
#ifndef UNSAFE_OPTIMIZATIONS
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Thumbulator::trapOnFatal = true;
double Thumbulator::arm_cycle_factor = 1.25;
double Thumbulator::arm_cycle_factor = 1.05;
#endif

View File

@ -46,7 +46,7 @@ class Cartridge;
#define CPSR_C (1u<<29)
#define CPSR_V (1u<<28)
//#define TIMER_0 // enable timer 0 support
#define TIMER_0 // enable timer 0 support
//#define COUNT_OPS
class Thumbulator
@ -233,9 +233,11 @@ class Thumbulator
#ifdef TIMER_0
uInt32 T0TCR{0}; // Timer 0 Timer Control Register
uInt32 T0TC{0}; // Timer 0 Timer Counter
uInt32 tim0Cycles{0};
#endif
uInt32 T1TCR{0}; // Timer 1 Timer Control Register
uInt32 T1TC{0}; // Timer 1 Timer Counter
uInt32 tim1Cycles{0};
double timing_factor{0.0};
#ifndef UNSAFE_OPTIMIZATIONS