another fix for MAMCR

further improved merged I-S cycles
This commit is contained in:
Thomas Jentzsch 2021-07-02 17:40:30 +02:00
parent 8d9ca0657a
commit a872c8fb42
2 changed files with 45 additions and 9 deletions

View File

@ -316,8 +316,18 @@ void Thumbulator::write16(uInt32 addr, uInt32 data)
ram[addr] = CONV_DATA(data); ram[addr] = CONV_DATA(data);
return; return;
#ifndef UNSAFE_OPTIMIZATIONS
case 0xE0000000: //MAMCR
#else
default: default:
break; #endif
if(addr == 0xE01FC000)
{
DO_DBUG(statusMsg << "write16(" << Base::HEX8 << "MAMCR" << "," << Base::HEX8 << data << ") *" << endl);
if(!_lockMamcr)
mamcr = static_cast<MamModeType>(data);
return;
}
} }
#ifndef UNSAFE_OPTIMIZATIONS #ifndef UNSAFE_OPTIMIZATIONS
fatalError("write16", addr, data, "abort"); fatalError("write16", addr, data, "abort");
@ -536,7 +546,17 @@ uInt32 Thumbulator::read16(uInt32 addr)
DO_DBUG(statusMsg << "read16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl); DO_DBUG(statusMsg << "read16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
return data; return data;
default: break; case 0xe0000000: //peripherals
#ifdef THUMB_CYCLE_COUNT
if(addr == 0xE01FC000) //MAMCR
#else
default:
#endif
{
DO_DBUG(statusMsg << "read32(" << "MAMCR" << addr << ")=" << mamcr << " *");
data = static_cast<uInt32>(mamcr);
return data;
}
} }
#ifndef UNSAFE_OPTIMIZATIONS #ifndef UNSAFE_OPTIMIZATIONS
return fatalError("read16", addr, "abort"); return fatalError("read16", addr, "abort");
@ -3024,6 +3044,13 @@ void Thumbulator::incCycles(AccessType accessType, uInt32 cycles)
} }
}; };
#endif #endif
//#ifdef MERGE_I_S
// TODO
// if(accessType == AccessType::branch)
// _lastCycleType[2] = _lastCycleType[1] = _lastCycleType[0] = CycleType::S;
//#endif
_totalCycles += cycles; _totalCycles += cycles;
} }
@ -3048,15 +3075,22 @@ void Thumbulator::incSCycles(uInt32 addr, AccessType accessType)
} }
#ifdef MERGE_I_S #ifdef MERGE_I_S
if(_lastCycleType[1] == CycleType::I) if(accessType != AccessType::prefetch)
{
if(_lastCycleType[0] == CycleType::I)
{
_lastCycleType[0] = CycleType::S; // merge cannot be used twice!
--cycles;
}
}
else if(_lastCycleType[2] == CycleType::I)
--cycles; --cycles;
#endif
incCycles(accessType, cycles); _lastCycleType[2] = _lastCycleType[1];
#ifdef MERGE_I_S
_lastCycleType[1] = _lastCycleType[0]; _lastCycleType[1] = _lastCycleType[0];
_lastCycleType[0] = CycleType::S; _lastCycleType[0] = CycleType::S;
#endif #endif
incCycles(accessType, cycles);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -3076,11 +3110,12 @@ void Thumbulator::incNCycles(uInt32 addr, AccessType accessType)
else else
cycles = _flashCycles; cycles = _flashCycles;
} }
incCycles(accessType, cycles);
#ifdef MERGE_I_S #ifdef MERGE_I_S
_lastCycleType[2] = _lastCycleType[1];
_lastCycleType[1] = _lastCycleType[0]; _lastCycleType[1] = _lastCycleType[0];
_lastCycleType[0] = CycleType::N; _lastCycleType[0] = CycleType::N;
#endif #endif
incCycles(accessType, cycles);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -3101,11 +3136,12 @@ void Thumbulator::incICycles(uInt32 m)
++_memory0Pipeline; // == 1 ++_memory0Pipeline; // == 1
} }
#endif #endif
_totalCycles += m;
#ifdef MERGE_I_S #ifdef MERGE_I_S
_lastCycleType[2] = _lastCycleType[1];
_lastCycleType[1] = _lastCycleType[0]; _lastCycleType[1] = _lastCycleType[0];
_lastCycleType[0] = CycleType::I; _lastCycleType[0] = CycleType::I;
#endif #endif
_totalCycles += m;
} }
#endif // THUMB_CYCLE_COUNT #endif // THUMB_CYCLE_COUNT

View File

@ -304,7 +304,7 @@ class Thumbulator
#ifdef THUMB_CYCLE_COUNT #ifdef THUMB_CYCLE_COUNT
double _armCyclesFactor{1.05}; double _armCyclesFactor{1.05};
CycleType _prefetchCycleType{CycleType::S}; CycleType _prefetchCycleType{CycleType::S};
CycleType _lastCycleType[2]{CycleType::S}; CycleType _lastCycleType[3]{CycleType::S};
#ifdef EMULATE_PIPELINE #ifdef EMULATE_PIPELINE
uInt32 _fetchPipeline{0}; // reserve fetch cycles resulting from pipelining (execution stage) uInt32 _fetchPipeline{0}; // reserve fetch cycles resulting from pipelining (execution stage)
uInt32 _memory0Pipeline{0}, _memory1Pipeline{0}; uInt32 _memory0Pipeline{0}, _memory1Pipeline{0};