mirror of https://github.com/stella-emu/stella.git
added ARM chip type auto detection (resolves #873)
This commit is contained in:
parent
f7895e53b8
commit
5b5eccf28f
|
@ -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());
|
||||||
|
|
||||||
|
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -46,6 +46,7 @@ void CartridgeARM::setInitialState()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myIncCycles = false;
|
myIncCycles = false;
|
||||||
|
myThumbEmulator->setChipType();
|
||||||
}
|
}
|
||||||
enableCycleCount(devSettings);
|
enableCycleCount(devSettings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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};
|
||||||
|
|
Loading…
Reference in New Issue