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

View File

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

View File

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