mirror of https://github.com/stella-emu/stella.git
switched ARM cycle counting to "real" cycles
This commit is contained in:
parent
fc9490deca
commit
f87aafb3e9
|
@ -53,19 +53,19 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
|
|||
addFocusWidget(myCycleFactor);
|
||||
|
||||
ypos += myLineHeight + VGAP;
|
||||
StaticTextWidget* s = new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Mem. cycles ");
|
||||
StaticTextWidget* s = new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Cycles ");
|
||||
|
||||
myPrevThumbMemCycles = new EditTextWidget(_boss, _font, s->getRight(), ypos - 1,
|
||||
myPrevThumbCycles = new EditTextWidget(_boss, _font, s->getRight(), ypos - 1,
|
||||
EditTextWidget::calcWidth(_font, 6), myLineHeight, "");
|
||||
myPrevThumbMemCycles->setEditable(false);
|
||||
myPrevThumbMemCycles->setToolTip("Number of memory cycles of last but one ARM run.");
|
||||
myPrevThumbCycles->setEditable(false);
|
||||
myPrevThumbCycles->setToolTip("Number of approximated CPU cycles of last but one ARM run.");
|
||||
|
||||
myThumbMemCycles = new EditTextWidget(_boss, _font, myPrevThumbMemCycles->getRight() + _fontWidth / 2, ypos - 1,
|
||||
myThumbCycles = new EditTextWidget(_boss, _font, myPrevThumbCycles->getRight() + _fontWidth / 2, ypos - 1,
|
||||
EditTextWidget::calcWidth(_font, 6), myLineHeight, "");
|
||||
myThumbMemCycles->setEditable(false);
|
||||
myThumbMemCycles->setToolTip("Number of memory cycles of last ARM run.");
|
||||
myThumbCycles->setEditable(false);
|
||||
myThumbCycles->setToolTip("Number of approximated CPU cycles of last ARM run.");
|
||||
|
||||
s = new StaticTextWidget(_boss, _font, myThumbMemCycles->getRight() + _fontWidth * 2, ypos + 1, "Fetches ");
|
||||
s = new StaticTextWidget(_boss, _font, myThumbCycles->getRight() + _fontWidth * 2, ypos + 1, "Fetches ");
|
||||
myPrevThumbFetches = new EditTextWidget(_boss, _font, s->getRight(), ypos - 1,
|
||||
EditTextWidget::calcWidth(_font, 6), myLineHeight, "");
|
||||
myPrevThumbFetches->setEditable(false);
|
||||
|
@ -79,12 +79,12 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
|
|||
ypos += myLineHeight + VGAP;
|
||||
s = new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Reads ");
|
||||
|
||||
myPrevThumbReads = new EditTextWidget(_boss, _font, myPrevThumbMemCycles->getLeft(), ypos - 1,
|
||||
myPrevThumbReads = new EditTextWidget(_boss, _font, myPrevThumbCycles->getLeft(), ypos - 1,
|
||||
EditTextWidget::calcWidth(_font, 6), myLineHeight, "");
|
||||
myPrevThumbReads->setEditable(false);
|
||||
myPrevThumbReads->setToolTip("Number of reads of last but one ARM run.");
|
||||
|
||||
myThumbReads = new EditTextWidget(_boss, _font, myThumbMemCycles->getLeft(), ypos - 1,
|
||||
myThumbReads = new EditTextWidget(_boss, _font, myThumbCycles->getLeft(), ypos - 1,
|
||||
EditTextWidget::calcWidth(_font, 6), myLineHeight, "");
|
||||
myThumbReads->setEditable(false);
|
||||
myThumbReads->setToolTip("Number of reads of last ARM run.");
|
||||
|
@ -105,20 +105,18 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeARMWidget::saveOldState()
|
||||
{
|
||||
myOldState.armStats.clear();
|
||||
myOldState.armPrevStats.clear();
|
||||
myOldState.armStats.clear();
|
||||
|
||||
myOldState.armStats.push_back(myCart.stats().fetches
|
||||
+ myCart.stats().reads + myCart.stats().writes);
|
||||
myOldState.armStats.push_back(myCart.stats().fetches);
|
||||
myOldState.armStats.push_back(myCart.stats().reads);
|
||||
myOldState.armStats.push_back(myCart.stats().writes);
|
||||
|
||||
myOldState.armPrevStats.push_back(myCart.prevStats().fetches
|
||||
+ myCart.prevStats().reads + myCart.prevStats().writes);
|
||||
myOldState.armPrevStats.push_back(myCart.prevStats().cycles);
|
||||
myOldState.armPrevStats.push_back(myCart.prevStats().fetches);
|
||||
myOldState.armPrevStats.push_back(myCart.prevStats().reads);
|
||||
myOldState.armPrevStats.push_back(myCart.prevStats().writes);
|
||||
|
||||
myOldState.armStats.push_back(myCart.stats().cycles);
|
||||
myOldState.armStats.push_back(myCart.stats().fetches);
|
||||
myOldState.armStats.push_back(myCart.stats().reads);
|
||||
myOldState.armStats.push_back(myCart.stats().writes);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -131,10 +129,8 @@ void CartridgeARMWidget::loadConfig()
|
|||
|
||||
bool isChanged;
|
||||
|
||||
isChanged = myCart.prevStats().fetches + myCart.prevStats().reads + myCart.prevStats().writes
|
||||
!= myOldState.armPrevStats[0];
|
||||
myPrevThumbMemCycles->setText(Common::Base::toString(myCart.prevStats().fetches
|
||||
+ myCart.prevStats().reads + myCart.prevStats().writes,
|
||||
isChanged = myCart.prevStats().cycles != myOldState.armPrevStats[0];
|
||||
myPrevThumbCycles->setText(Common::Base::toString(myCart.prevStats().cycles,
|
||||
Common::Base::Fmt::_10_6), isChanged);
|
||||
isChanged = myCart.prevStats().fetches != myOldState.armPrevStats[1];
|
||||
myPrevThumbFetches->setText(Common::Base::toString(myCart.prevStats().fetches,
|
||||
|
@ -146,10 +142,8 @@ void CartridgeARMWidget::loadConfig()
|
|||
myPrevThumbWrites->setText(Common::Base::toString(myCart.prevStats().writes,
|
||||
Common::Base::Fmt::_10_6), isChanged);
|
||||
|
||||
isChanged = myCart.stats().fetches + myCart.stats().reads + myCart.stats().writes
|
||||
!= myOldState.armStats[0];
|
||||
myThumbMemCycles->setText(Common::Base::toString(myCart.stats().fetches
|
||||
+ myCart.stats().reads + myCart.stats().writes,
|
||||
isChanged = myCart.stats().cycles != myOldState.armStats[0];
|
||||
myThumbCycles->setText(Common::Base::toString(myCart.stats().cycles,
|
||||
Common::Base::Fmt::_10_6), isChanged);
|
||||
isChanged = myCart.stats().fetches != myOldState.armStats[1];
|
||||
myThumbFetches->setText(Common::Base::toString(myCart.stats().fetches,
|
||||
|
|
|
@ -60,11 +60,11 @@ class CartridgeARMWidget : public CartDebugWidget
|
|||
|
||||
CheckboxWidget* myIncCycles{nullptr};
|
||||
SliderWidget* myCycleFactor{nullptr};
|
||||
EditTextWidget* myPrevThumbMemCycles{nullptr};
|
||||
EditTextWidget* myPrevThumbCycles{nullptr};
|
||||
EditTextWidget* myPrevThumbFetches{nullptr};
|
||||
EditTextWidget* myPrevThumbReads{nullptr};
|
||||
EditTextWidget* myPrevThumbWrites{nullptr};
|
||||
EditTextWidget* myThumbMemCycles{nullptr};
|
||||
EditTextWidget* myThumbCycles{nullptr};
|
||||
EditTextWidget* myThumbFetches{nullptr};
|
||||
EditTextWidget* myThumbReads{nullptr};
|
||||
EditTextWidget* myThumbWrites{nullptr};
|
||||
|
|
|
@ -31,10 +31,7 @@ CartridgeARM::CartridgeARM(const string& md5, const Settings& settings)
|
|||
void CartridgeARM::updateCycles(int cycles)
|
||||
{
|
||||
if(myIncCycles)
|
||||
{
|
||||
mySystem->incrementCycles(cycles); // * ~1.79 is the limit for ZEVIOUZ title screen (~88,000 cycles)
|
||||
cerr << cycles << " ";
|
||||
}
|
||||
mySystem->incrementCycles(cycles); // * ~1.11 is the limit for ZEVIOUZ title screen (~142,000 cycles)
|
||||
myStats = myThumbEmulator->stats();
|
||||
myPrevStats = myThumbEmulator->prevStats();
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ string Thumbulator::doRun(uInt32& cycles)
|
|||
#endif
|
||||
}
|
||||
#ifndef NO_THUMB_STATS
|
||||
cycles = uInt32((_stats.fetches + _stats.reads + _stats.writes) * arm_cycle_factor / timing_factor);
|
||||
cycles = _stats.cycles * arm_cycle_factor / timing_factor;
|
||||
#else
|
||||
cycles = 0;
|
||||
#endif
|
||||
|
@ -204,6 +204,7 @@ uInt32 Thumbulator::fetch16(uInt32 addr)
|
|||
{
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.fetches;
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
|
||||
#ifndef UNSAFE_OPTIMIZATIONS
|
||||
|
@ -562,7 +563,13 @@ void Thumbulator::write_register(uInt32 reg, uInt32 data)
|
|||
|
||||
DO_DBUG(statusMsg << "write_register(" << dec << reg << "," << Base::HEX8 << data << ")" << endl);
|
||||
//#ifndef UNSAFE_OPTIMIZATIONS // this fails when combined with read_register UNSAFE_OPTIMIZATIONS
|
||||
if(reg == 15) data &= ~1;
|
||||
if(reg == 15)
|
||||
{
|
||||
data &= ~1;
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
}
|
||||
//#endif
|
||||
reg_norm[reg] = data;
|
||||
}
|
||||
|
@ -622,7 +629,7 @@ void Thumbulator::do_vflag_bit(uInt32 x)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Thumbulator::Op Thumbulator::decodeInstructionWord(uint16_t inst) {
|
||||
//ADC
|
||||
//ADC add with carry
|
||||
if((inst & 0xFFC0) == 0x4140) return Op::adc;
|
||||
|
||||
//ADD(1) small immediate two registers
|
||||
|
@ -838,7 +845,7 @@ Thumbulator::Op Thumbulator::decodeInstructionWord(uint16_t inst) {
|
|||
//UXTB
|
||||
if((inst & 0xFFC0) == 0xB2C0) return Op::uxtb;
|
||||
|
||||
//UXTH
|
||||
//UXTH Zero extend Halfword
|
||||
if((inst & 0xFFC0) == 0xB280) return Op::uxth;
|
||||
|
||||
return Op::invalid;
|
||||
|
@ -872,6 +879,9 @@ int Thumbulator::execute()
|
|||
decodedOp = decodedRom[(instructionPtr & ROMADDMASK) >> 1];
|
||||
#endif
|
||||
|
||||
#ifdef COUNT_OPS
|
||||
++opCount[int(decodedOp)];
|
||||
#endif
|
||||
switch (decodedOp) {
|
||||
//ADC
|
||||
case Op::adc: {
|
||||
|
@ -1028,6 +1038,9 @@ int Thumbulator::execute()
|
|||
|
||||
//ASR(1) two register immediate
|
||||
case Op::asr1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rm = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1062,6 +1075,9 @@ int Thumbulator::execute()
|
|||
|
||||
//ASR(2) two register
|
||||
case Op::asr2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rs = (inst >> 3) & 0x07;
|
||||
DO_DISS(statusMsg << "asrs r" << dec << rd << ",r" << dec << rs << endl);
|
||||
|
@ -1102,6 +1118,9 @@ int Thumbulator::execute()
|
|||
|
||||
//B(1) conditional branch
|
||||
case Op::b1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rb = (inst >> 0) & 0xFF;
|
||||
if(rb & 0x80)
|
||||
rb |= (~0U) << 8;
|
||||
|
@ -1219,6 +1238,9 @@ int Thumbulator::execute()
|
|||
|
||||
//B(2) unconditional branch
|
||||
case Op::b2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rb = (inst >> 0) & 0x7FF;
|
||||
if(rb & (1 << 10))
|
||||
rb |= (~0U) << 11;
|
||||
|
@ -1255,6 +1277,9 @@ int Thumbulator::execute()
|
|||
|
||||
//BL/BLX(1)
|
||||
case Op::blx1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
if((inst & 0x1800) == 0x1000) //H=b10
|
||||
{
|
||||
DO_DISS(statusMsg << endl);
|
||||
|
@ -1295,6 +1320,9 @@ int Thumbulator::execute()
|
|||
|
||||
//BLX(2)
|
||||
case Op::blx2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rm = (inst >> 3) & 0xF;
|
||||
DO_DISS(statusMsg << "blx r" << dec << rm << endl);
|
||||
rc = read_register(rm);
|
||||
|
@ -1317,6 +1345,9 @@ int Thumbulator::execute()
|
|||
|
||||
//BX
|
||||
case Op::bx: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rm = (inst >> 3) & 0xF;
|
||||
DO_DISS(statusMsg << "bx r" << dec << rm << endl);
|
||||
rc = read_register(rm);
|
||||
|
@ -1648,6 +1679,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDMIA
|
||||
case Op::ldmia: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rn = (inst >> 8) & 0x7;
|
||||
#if defined(THUMB_DISS)
|
||||
statusMsg << "ldmia r" << dec << rn << "!,{";
|
||||
|
@ -1667,6 +1701,9 @@ int Thumbulator::execute()
|
|||
{
|
||||
if(inst & rb)
|
||||
{
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
write_register(ra, read32(sp));
|
||||
sp += 4;
|
||||
}
|
||||
|
@ -1680,6 +1717,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDR(1) two register immediate
|
||||
case Op::ldr1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1693,6 +1733,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDR(2) three register
|
||||
case Op::ldr2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -1705,6 +1748,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDR(3)
|
||||
case Op::ldr3: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rb = (inst >> 0) & 0xFF;
|
||||
rd = (inst >> 8) & 0x07;
|
||||
rb <<= 2;
|
||||
|
@ -1720,6 +1766,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDR(4)
|
||||
case Op::ldr4: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rb = (inst >> 0) & 0xFF;
|
||||
rd = (inst >> 8) & 0x07;
|
||||
rb <<= 2;
|
||||
|
@ -1734,6 +1783,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRB(1)
|
||||
case Op::ldrb1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1757,6 +1809,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRB(2)
|
||||
case Op::ldrb2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -1777,6 +1832,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRH(1)
|
||||
case Op::ldrh1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1790,6 +1848,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRH(2)
|
||||
case Op::ldrh2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -1802,6 +1863,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRSB
|
||||
case Op::ldrsb: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -1825,6 +1889,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LDRSH
|
||||
case Op::ldrsh: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
_stats.cycles += 2;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -1840,6 +1907,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LSL(1)
|
||||
case Op::lsl1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rm = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1865,6 +1935,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LSL(2) two register
|
||||
case Op::lsl2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rs = (inst >> 3) & 0x07;
|
||||
DO_DISS(statusMsg << "lsls r" << dec << rd << ",r" << dec << rs << endl);
|
||||
|
@ -1897,6 +1970,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LSR(1) two register immediate
|
||||
case Op::lsr1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rm = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -1920,6 +1996,9 @@ int Thumbulator::execute()
|
|||
|
||||
//LSR(2) two register
|
||||
case Op::lsr2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rs = (inst >> 3) & 0x07;
|
||||
DO_DISS(statusMsg << "lsrs r" << dec << rd << ",r" << dec << rs << endl);
|
||||
|
@ -1999,6 +2078,9 @@ 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);
|
||||
|
@ -2193,6 +2275,9 @@ int Thumbulator::execute()
|
|||
|
||||
//ROR
|
||||
case Op::ror: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rs = (inst >> 3) & 0x7;
|
||||
DO_DISS(statusMsg << "rors r" << dec << rd << ",r" << dec << rs << endl);
|
||||
|
@ -2278,6 +2363,9 @@ int Thumbulator::execute()
|
|||
{
|
||||
if(inst & rb)
|
||||
{
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
write32(sp, read_register(ra));
|
||||
sp += 4;
|
||||
}
|
||||
|
@ -2288,6 +2376,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STR(1)
|
||||
case Op::str1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -2301,6 +2392,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STR(2)
|
||||
case Op::str2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -2313,6 +2407,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STR(3)
|
||||
case Op::str3: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rb = (inst >> 0) & 0xFF;
|
||||
rd = (inst >> 8) & 0x07;
|
||||
rb <<= 2;
|
||||
|
@ -2326,6 +2423,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STRB(1)
|
||||
case Op::strb1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -2353,6 +2453,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STRB(2)
|
||||
case Op::strb2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -2380,6 +2483,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STRH(1)
|
||||
case Op::strh1: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x07;
|
||||
rn = (inst >> 3) & 0x07;
|
||||
rb = (inst >> 6) & 0x1F;
|
||||
|
@ -2393,6 +2499,9 @@ int Thumbulator::execute()
|
|||
|
||||
//STRH(2)
|
||||
case Op::strh2: {
|
||||
#ifndef NO_THUMB_STATS
|
||||
++_stats.cycles;
|
||||
#endif
|
||||
rd = (inst >> 0) & 0x7;
|
||||
rn = (inst >> 3) & 0x7;
|
||||
rm = (inst >> 6) & 0x7;
|
||||
|
@ -2583,9 +2692,12 @@ int Thumbulator::reset()
|
|||
_prevStats.fetches = _stats.fetches;
|
||||
_prevStats.reads = _stats.reads;
|
||||
_prevStats.writes = _stats.writes;
|
||||
_stats.fetches = _stats.reads = _stats.writes = 0;
|
||||
_prevStats.cycles = _stats.cycles;
|
||||
_stats.fetches = _stats.reads = _stats.writes = _stats.cycles = 0;
|
||||
#endif
|
||||
#ifdef COUNT_OPS
|
||||
//memset(opCount, 0, sizeof(opCount));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ class Cartridge;
|
|||
#define CPSR_V (1u<<28)
|
||||
|
||||
//#define TIMER_0 // enable timer 0 support
|
||||
//#define COUNT_OPS
|
||||
|
||||
class Thumbulator
|
||||
{
|
||||
|
@ -65,6 +66,7 @@ class Thumbulator
|
|||
struct Stats {
|
||||
#ifndef NO_THUMB_STATS
|
||||
uInt32 fetches{0}, reads{0}, writes{0};
|
||||
uInt32 cycles{0};
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -166,7 +168,8 @@ class Thumbulator
|
|||
sxth,
|
||||
tst,
|
||||
uxtb,
|
||||
uxth
|
||||
uxth,
|
||||
numOps
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -219,8 +222,10 @@ class Thumbulator
|
|||
#ifndef UNSAFE_OPTIMIZATIONS
|
||||
uInt32 instructions{0};
|
||||
#endif
|
||||
#ifndef NO_THUMB_STATS
|
||||
Stats _stats;
|
||||
Stats _prevStats;
|
||||
#endif
|
||||
|
||||
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
||||
// Register names from documentation:
|
||||
|
@ -241,6 +246,9 @@ class Thumbulator
|
|||
#ifndef NO_THUMB_STATS
|
||||
static double arm_cycle_factor;
|
||||
#endif
|
||||
#ifdef COUNT_OPS
|
||||
uInt32 opCount[size_t(Op::numOps)]{0};
|
||||
#endif
|
||||
|
||||
ConfigureFor configuration;
|
||||
|
||||
|
|
Loading…
Reference in New Issue