mirror of https://github.com/stella-emu/stella.git
fixed ARM branch cycles (not taken = 1)
added cycle change tracking
This commit is contained in:
parent
b07c74d5e5
commit
b1e9572186
|
@ -46,7 +46,7 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
|
||||||
myCycleFactor = new SliderWidget(_boss, _font, myIncCycles->getRight() + _fontWidth * 2, ypos - 1,
|
myCycleFactor = new SliderWidget(_boss, _font, myIncCycles->getRight() + _fontWidth * 2, ypos - 1,
|
||||||
_fontWidth * 10, _lineHeight, "Factor ", _fontWidth * 7,
|
_fontWidth * 10, _lineHeight, "Factor ", _fontWidth * 7,
|
||||||
kFactorChanged, _fontWidth * 4, "%");
|
kFactorChanged, _fontWidth * 4, "%");
|
||||||
myCycleFactor->setMinValue(100); myCycleFactor->setMaxValue(200);
|
myCycleFactor->setMinValue(90); myCycleFactor->setMaxValue(110);
|
||||||
myCycleFactor->setTickmarkIntervals(4);
|
myCycleFactor->setTickmarkIntervals(4);
|
||||||
myCycleFactor->setToolTip("Multiply approximated ARM cycles by factor.");
|
myCycleFactor->setToolTip("Multiply approximated ARM cycles by factor.");
|
||||||
myCycleFactor->setTarget(this);
|
myCycleFactor->setTarget(this);
|
||||||
|
|
|
@ -53,9 +53,11 @@ bool CartridgeARM::save(Serializer& out) const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
out.putInt(myPrevStats.cycles);
|
||||||
out.putInt(myPrevStats.fetches);
|
out.putInt(myPrevStats.fetches);
|
||||||
out.putInt(myPrevStats.reads);
|
out.putInt(myPrevStats.reads);
|
||||||
out.putInt(myPrevStats.writes);
|
out.putInt(myPrevStats.writes);
|
||||||
|
out.putInt(myStats.cycles);
|
||||||
out.putInt(myStats.fetches);
|
out.putInt(myStats.fetches);
|
||||||
out.putInt(myStats.reads);
|
out.putInt(myStats.reads);
|
||||||
out.putInt(myStats.writes);
|
out.putInt(myStats.writes);
|
||||||
|
@ -73,9 +75,11 @@ bool CartridgeARM::load(Serializer& in)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
myPrevStats.cycles = in.getInt();
|
||||||
myPrevStats.fetches = in.getInt();
|
myPrevStats.fetches = in.getInt();
|
||||||
myPrevStats.reads = in.getInt();
|
myPrevStats.reads = in.getInt();
|
||||||
myPrevStats.writes = in.getInt();
|
myPrevStats.writes = in.getInt();
|
||||||
|
myStats.cycles = in.getInt();
|
||||||
myStats.fetches = in.getInt();
|
myStats.fetches = in.getInt();
|
||||||
myStats.reads = in.getInt();
|
myStats.reads = in.getInt();
|
||||||
myStats.writes = in.getInt();
|
myStats.writes = in.getInt();
|
||||||
|
|
|
@ -1126,9 +1126,6 @@ int Thumbulator::execute()
|
||||||
|
|
||||||
//B(1) conditional branch
|
//B(1) conditional branch
|
||||||
case Op::b1: {
|
case Op::b1: {
|
||||||
#ifndef NO_THUMB_STATS
|
|
||||||
++_stats.cycles;
|
|
||||||
#endif
|
|
||||||
rb = (inst >> 0) & 0xFF;
|
rb = (inst >> 0) & 0xFF;
|
||||||
if(rb & 0x80)
|
if(rb & 0x80)
|
||||||
rb |= (~0U) << 8;
|
rb |= (~0U) << 8;
|
||||||
|
@ -1141,75 +1138,133 @@ int Thumbulator::execute()
|
||||||
case 0x0: //b eq z set
|
case 0x0: //b eq z set
|
||||||
DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_Z)
|
if(cpsr & CPSR_Z)
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x1: //b ne z clear
|
case 0x1: //b ne z clear
|
||||||
DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_Z))
|
if(!(cpsr & CPSR_Z))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x2: //b cs c set
|
case 0x2: //b cs c set
|
||||||
DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_C)
|
if(cpsr & CPSR_C)
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x3: //b cc c clear
|
case 0x3: //b cc c clear
|
||||||
DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_C))
|
if(!(cpsr & CPSR_C))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x4: //b mi n set
|
case 0x4: //b mi n set
|
||||||
DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_N)
|
if(cpsr & CPSR_N)
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x5: //b pl n clear
|
case 0x5: //b pl n clear
|
||||||
DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_N))
|
if(!(cpsr & CPSR_N))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x6: //b vs v set
|
case 0x6: //b vs v set
|
||||||
DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_V)
|
if(cpsr & CPSR_V)
|
||||||
write_register(15,rb);
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x7: //b vc v clear
|
case 0x7: //b vc v clear
|
||||||
DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_V))
|
if(!(cpsr & CPSR_V))
|
||||||
|
{
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x8: //b hi c set z clear
|
case 0x8: //b hi c set z clear
|
||||||
DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((cpsr & CPSR_C) && (!(cpsr & CPSR_Z)))
|
if((cpsr & CPSR_C) && (!(cpsr & CPSR_Z)))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x9: //b ls c clear or z set
|
case 0x9: //b ls c clear or z set
|
||||||
DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((cpsr & CPSR_Z) || (!(cpsr & CPSR_C)))
|
if((cpsr & CPSR_Z) || (!(cpsr & CPSR_C)))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0xA: //b ge N == V
|
case 0xA: //b ge N == V
|
||||||
DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
||||||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0xB: //b lt N != V
|
case 0xB: //b lt N != V
|
||||||
DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if((!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
||||||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0xC: //b gt Z==0 and N == V
|
case 0xC: //b gt Z==0 and N == V
|
||||||
|
@ -1218,7 +1273,12 @@ int Thumbulator::execute()
|
||||||
{
|
{
|
||||||
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
||||||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
||||||
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1227,7 +1287,12 @@ int Thumbulator::execute()
|
||||||
if((cpsr & CPSR_Z) ||
|
if((cpsr & CPSR_Z) ||
|
||||||
(!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
(!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
||||||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
||||||
write_register(15, rb);
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
++_stats.cycles;
|
||||||
|
#endif
|
||||||
|
write_register(15, rb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
|
|
Loading…
Reference in New Issue