added ARM chip type auto detection (resolves #873)

This commit is contained in:
Thomas Jentzsch 2022-02-15 12:33:46 +01:00
parent f7895e53b8
commit 5b5eccf28f
4 changed files with 68 additions and 28 deletions

View File

@ -89,10 +89,11 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
- PopUpWidget::dropDownWidth(_font);
items.clear();
VarList::push_back(items, "LPC2101" + ELLIPSIS + "3", static_cast<uInt32>(Thumbulator::ChipType::LPC2101));
VarList::push_back(items, "LPC2104" + ELLIPSIS + "6 OC", static_cast<uInt32>(Thumbulator::ChipType::LPC2104_OC));
VarList::push_back(items, "LPC2104" + ELLIPSIS + "6", static_cast<uInt32>(Thumbulator::ChipType::LPC2104));
VarList::push_back(items, "LPC213x", static_cast<uInt32>(Thumbulator::ChipType::LPC213x));
VarList::push_back(items, "AUTO", static_cast<Int32>(Thumbulator::ChipType::AUTO));
VarList::push_back(items, "LPC2101" + ELLIPSIS + "3", static_cast<Int32>(Thumbulator::ChipType::LPC2101));
VarList::push_back(items, "LPC2104" + ELLIPSIS + "6 OC", static_cast<Int32>(Thumbulator::ChipType::LPC2104_OC));
VarList::push_back(items, "LPC2104" + ELLIPSIS + "6", static_cast<Int32>(Thumbulator::ChipType::LPC2104));
VarList::push_back(items, "LPC213x", static_cast<Int32>(Thumbulator::ChipType::LPC213x));
myChipType = new PopUpWidget(_boss, _font, xpos, ypos, pwidth, myLineHeight, items,
"Chip ", 0, kChipChanged);
myChipType->setToolTip("Select emulated ARM chip.");
@ -147,7 +148,8 @@ void CartridgeARMWidget::loadConfig()
IntArray vlist;
BoolArray changed;
myChipType->setSelectedIndex(static_cast<uInt32>(instance().settings().getInt("dev.thumb.chiptype")));
myChipType->setSelectedIndex(static_cast<Int32>(instance().settings().getInt("dev.thumb.chiptype")
- int(Thumbulator::ChipType::AUTO)));
handleChipType();
isChanged = static_cast<uInt32>(myCart.mamMode()) != myOldState.mamMode;
@ -217,25 +219,27 @@ void CartridgeARMWidget::handleChipType()
{
bool devSettings = instance().settings().getBool("dev.settings");
myChipType->setEnabled(devSettings);
if(devSettings)
{
instance().settings().setValue("dev.thumb.chiptype", myChipType->getSelectedTag().toInt());
Thumbulator::ChipPropsType chipProps
= myCart.setChipType(static_cast<Thumbulator::ChipType>(myChipType->getSelectedTag().toInt()));
// update tooltip with currently selecte chip's properties
string tip = myChipType->getToolTip(Common::Point(0, 0));
ostringstream buf;
tip = tip.substr(0, 25);
buf << tip << "\nCurrent: " << chipProps.name << "\n"
<< chipProps.flashBanks << " flash bank"
<< (chipProps.flashBanks > 1 ? "s" : "") << ", "
<< chipProps.MHz << " MHz, "
<< chipProps.flashCycles - 1 << " wait states";
myChipType->setToolTip(buf.str());
}
myChipType->setEnabled(devSettings);
Thumbulator::ChipPropsType chipProps = myCart.setChipType(static_cast<Thumbulator::ChipType>(myChipType->getSelectedTag().toInt()));
// update tooltip with currently selecte chip's properties
string tip = myChipType->getToolTip(Common::Point(0, 0));
ostringstream buf;
tip = tip.substr(0, 25);
buf << tip << "\nCurrent:\n"
<< chipProps.flashBanks << " flash bank"
<< (chipProps.flashBanks > 1 ? "s" : "") << ", "
<< chipProps.MHz << " MHz, "
<< chipProps.flashCycles - 1 << " wait states";
myChipType->setToolTip(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -46,6 +46,7 @@ void CartridgeARM::setInitialState()
else
{
myIncCycles = false;
myThumbEmulator->setChipType();
}
enableCycleCount(devSettings);
}

View File

@ -213,13 +213,13 @@ void Thumbulator::updateTimer(uInt32 cycles)
if(T0TCR & 1) // bit 0 controls timer on/off
{
T0TC += static_cast<uInt32>(cycles * timing_factor);
tim0Total = tim0Start;
tim0Total = tim0Start = 0;
}
#endif
if(T1TCR & 1) // bit 0 controls timer on/off
{
T1TC += static_cast<uInt32>(cycles * timing_factor);
tim1Total = tim1Start;
tim1Total = tim1Start = 0;
}
}
@ -2931,6 +2931,20 @@ int Thumbulator::reset()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Thumbulator::ChipPropsType Thumbulator::setChipType(ChipType type)
{
if(type == ChipType::AUTO)
{
if(_chipType != ChipType::AUTO)
type = _chipType;
else if(searchPattern(0x3016E5C0, 3)) // alternate bus location (standard = 0x3015E5C0)
type = ChipType::LPC213x;
else if(romSize <= 0x8000) // LPC2104.. is always > 32K
type = ChipType::LPC2101;
else if(searchPattern(0x1026E3A0)) // 70 MHz pattern (60 MHZ = 0x1025E3A0)
type = ChipType::LPC2104_OC;
else
type = ChipType::LPC2104;
}
ChipPropsType props = ChipProps[static_cast<uInt32>(type)];
_chipType = type;
@ -3283,3 +3297,21 @@ void Thumbulator::incICycles(uInt32 m)
}
#endif // THUMB_CYCLE_COUNT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Thumbulator::searchPattern(uInt32 pattern, uInt32 repeats) const
{
// Note: The pattern is defined in 1-0-3-2 byte order!
const uInt16 patternLo = pattern >> 16;
const uInt16 patternHi = pattern & 0xffff;
uInt32 count = 0;
// The pattern is always aligned to 4
for(uInt32 i = 0; i < romSize/2 - 2; i += 2)
{
if(rom[i] == patternLo && rom[i + 1] == patternHi)
if(++count == repeats)
return true;
}
return false;
}

View File

@ -70,6 +70,7 @@ class Thumbulator
DPCplus // cartridges of type DPC+
};
enum class ChipType {
AUTO = -1,
LPC2101, // Harmony (includes LPC2103)
LPC2104_OC, // Dev cart overclocked (includes LPC2105)
LPC2104, // Dev cart (includes LPC2105)
@ -80,6 +81,7 @@ class Thumbulator
mode0, mode1, mode2, modeX
};
struct ChipPropsType {
string name;
double MHz;
uInt32 flashCycles;
uInt32 flashBanks;
@ -114,7 +116,7 @@ class Thumbulator
void enableCycleCount(bool enable) { _countCycles = enable; }
const Stats& stats() const { return _stats; }
uInt32 cycles() const { return _totalCycles; }
ChipPropsType setChipType(ChipType type);
ChipPropsType setChipType(ChipType type = ChipType::AUTO);
void setMamMode(MamModeType mode) { mamcr = mode; }
void lockMamMode(bool lock) { _lockMamcr = lock; }
MamModeType mamMode() const { return static_cast<MamModeType>(mamcr); }
@ -212,10 +214,10 @@ class Thumbulator
#endif
const std::array<ChipPropsType, uInt32(ChipType::numTypes)> ChipProps =
{{
{ 70.0, 4, 1 }, // LPC2101_02_03
{ 70.0, 4, 2 }, // LPC2104_05_06 Overclocked
{ 60.0, 3, 2 }, // LPC2104_05_06
{ 60.0, 3, 1 }, // LPC2132..
{ "LPC2101..3", 70.0, 4, 1 }, // LPC2101_02_03
{ "LPC2104..6 OC", 70.0, 4, 2 }, // LPC2104_05_06 Overclocked
{ "LPC2104..6", 60.0, 3, 2 }, // LPC2104_05_06
{ "LPC213x", 60.0, 3, 1 }, // LPC2132..
}};
private:
@ -261,6 +263,7 @@ class Thumbulator
void incNCycles(uInt32 addr, AccessType = AccessType::data);
void incICycles(uInt32 m = 1);
#endif
bool searchPattern(uInt32 pattern, uInt32 repeats = 1) const;
private:
const uInt16* rom{nullptr};
@ -275,7 +278,7 @@ class Thumbulator
MamModeType mamcr{MamModeType::mode0};
bool handler_mode{false};
uInt32 systick_ctrl{0}, systick_reload{0}, systick_count{0}, systick_calibrate{0};
ChipType _chipType{ChipType::LPC2101};
ChipType _chipType{ChipType::AUTO};
ConsoleTiming _consoleTiming{ConsoleTiming::ntsc};
double _MHz{70.0};
uInt32 _flashCycles{4};