mirror of https://github.com/stella-emu/stella.git
defined UNSAFE_OPTIMIZATIONS in Thumbulator
This commit is contained in:
parent
bac5a86832
commit
486494eb7a
|
@ -68,7 +68,9 @@ Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 romSize,
|
||||||
decodedRom[i] = decodeInstructionWord(CONV_RAMROM(rom[i]));
|
decodedRom[i] = decodeInstructionWord(CONV_RAMROM(rom[i]));
|
||||||
|
|
||||||
setConsoleTiming(ConsoleTiming::ntsc);
|
setConsoleTiming(ConsoleTiming::ntsc);
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
trapFatalErrors(traponfatal);
|
trapFatalErrors(traponfatal);
|
||||||
|
#endif
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +81,10 @@ string Thumbulator::run()
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(execute()) break;
|
if(execute()) break;
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if(instructions > 500000) // way more than would otherwise be possible
|
if(instructions > 500000) // way more than would otherwise be possible
|
||||||
throw runtime_error("instructions > 500000");
|
throw runtime_error("instructions > 500000");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if defined(THUMB_DISS) || defined(THUMB_DBUG)
|
#if defined(THUMB_DISS) || defined(THUMB_DBUG)
|
||||||
dump_counters();
|
dump_counters();
|
||||||
|
@ -105,6 +109,7 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
||||||
case ConsoleTiming::pal: timing_factor = PAL; break;
|
case ConsoleTiming::pal: timing_factor = PAL; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::updateTimer(uInt32 cycles)
|
void Thumbulator::updateTimer(uInt32 cycles)
|
||||||
{
|
{
|
||||||
|
@ -119,6 +124,7 @@ string Thumbulator::run(uInt32 cycles)
|
||||||
return run();
|
return run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
inline int Thumbulator::fatalError(const char* opcode, uInt32 v1, const char* msg)
|
inline int Thumbulator::fatalError(const char* opcode, uInt32 v1, const char* msg)
|
||||||
{
|
{
|
||||||
|
@ -150,8 +156,7 @@ void Thumbulator::dump_counters()
|
||||||
<< "fetches " << fetches << endl
|
<< "fetches " << fetches << endl
|
||||||
<< "reads " << reads << endl
|
<< "reads " << reads << endl
|
||||||
<< "writes " << writes << endl
|
<< "writes " << writes << endl
|
||||||
<< "memcycles " << (fetches+reads+writes) << endl
|
<< "memcycles " << (fetches+reads+writes) << endl;
|
||||||
<< "systick_ints " << systick_ints << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -168,33 +173,42 @@ void Thumbulator::dump_regs()
|
||||||
<< "PC = " << Base::HEX8 << reg_norm[15] << " "
|
<< "PC = " << Base::HEX8 << reg_norm[15] << " "
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 Thumbulator::fetch16(uInt32 addr)
|
uInt32 Thumbulator::fetch16(uInt32 addr)
|
||||||
{
|
{
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
++fetches;
|
++fetches;
|
||||||
|
#endif
|
||||||
|
|
||||||
uInt32 data;
|
uInt32 data;
|
||||||
switch(addr & 0xF0000000)
|
switch(addr & 0xF0000000)
|
||||||
{
|
{
|
||||||
case 0x00000000: //ROM
|
case 0x00000000: //ROM
|
||||||
addr &= ROMADDMASK;
|
addr &= ROMADDMASK;
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if(addr < 0x50)
|
if(addr < 0x50)
|
||||||
fatalError("fetch16", addr, "abort");
|
fatalError("fetch16", addr, "abort");
|
||||||
|
#endif
|
||||||
addr >>= 1;
|
addr >>= 1;
|
||||||
data = CONV_RAMROM(rom[addr]);
|
data = CONV_RAMROM(rom[addr]);
|
||||||
DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
|
DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
|
||||||
return data;
|
return data;
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0x40000000: //RAM
|
case 0x40000000: //RAM
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
addr &= RAMADDMASK;
|
addr &= RAMADDMASK;
|
||||||
addr >>= 1;
|
addr >>= 1;
|
||||||
data=CONV_RAMROM(ram[addr]);
|
data=CONV_RAMROM(ram[addr]);
|
||||||
DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
|
DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
return fatalError("fetch16", addr, "abort");
|
return fatalError("fetch16", addr, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -210,22 +224,33 @@ uInt32 Thumbulator::fetch32(uInt32 addr)
|
||||||
DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
||||||
if(addr == 0x00000000) return data;
|
if(addr == 0x00000000) return data;
|
||||||
if(addr == 0x00000004) return data;
|
if(addr == 0x00000004) return data;
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if(addr == 0x0000003C) return data;
|
if(addr == 0x0000003C) return data;
|
||||||
fatalError("fetch32", addr, "abort");
|
fatalError("fetch32", addr, "abort");
|
||||||
|
#else
|
||||||
|
return data;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0x40000000: //RAM
|
case 0x40000000: //RAM
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
data = read32(addr);
|
data = read32(addr);
|
||||||
DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
return fatalError("fetch32", addr, "abort");
|
return fatalError("fetch32", addr, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::write16(uInt32 addr, uInt32 data)
|
void Thumbulator::write16(uInt32 addr, uInt32 data)
|
||||||
{
|
{
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if((addr > 0x40001fff) && (addr < 0x50000000))
|
if((addr > 0x40001fff) && (addr < 0x50000000))
|
||||||
fatalError("write16", addr, "abort - out of range");
|
fatalError("write16", addr, "abort - out of range");
|
||||||
|
|
||||||
|
@ -233,8 +258,10 @@ void Thumbulator::write16(uInt32 addr, uInt32 data)
|
||||||
|
|
||||||
if(addr & 1)
|
if(addr & 1)
|
||||||
fatalError("write16", addr, "abort - misaligned");
|
fatalError("write16", addr, "abort - misaligned");
|
||||||
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
++writes;
|
++writes;
|
||||||
|
#endif
|
||||||
|
|
||||||
DO_DBUG(statusMsg << "write16(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
|
DO_DBUG(statusMsg << "write16(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
|
||||||
|
|
||||||
|
@ -246,7 +273,11 @@ 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
|
case 0xE0000000: //MAMCR
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
if(addr == 0xE01FC000)
|
if(addr == 0xE01FC000)
|
||||||
{
|
{
|
||||||
DO_DBUG(statusMsg << "write16(" << Base::HEX8 << "MAMCR" << "," << Base::HEX8 << data << ") *" << endl);
|
DO_DBUG(statusMsg << "write16(" << Base::HEX8 << "MAMCR" << "," << Base::HEX8 << data << ") *" << endl);
|
||||||
|
@ -254,23 +285,29 @@ void Thumbulator::write16(uInt32 addr, uInt32 data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
fatalError("write16", addr, data, "abort");
|
fatalError("write16", addr, data, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::write32(uInt32 addr, uInt32 data)
|
void Thumbulator::write32(uInt32 addr, uInt32 data)
|
||||||
{
|
{
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if(addr & 3)
|
if(addr & 3)
|
||||||
fatalError("write32", addr, "abort - misaligned");
|
fatalError("write32", addr, "abort - misaligned");
|
||||||
|
|
||||||
if (isProtected(addr)) fatalError("write32", addr, "to driver area");
|
if (isProtected(addr)) fatalError("write32", addr, "to driver area");
|
||||||
|
#endif
|
||||||
DO_DBUG(statusMsg << "write32(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
|
DO_DBUG(statusMsg << "write32(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
|
||||||
|
|
||||||
switch(addr & 0xF0000000)
|
switch(addr & 0xF0000000)
|
||||||
{
|
{
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0xF0000000: //halt
|
case 0xF0000000: //halt
|
||||||
dump_counters();
|
dump_counters();
|
||||||
throw runtime_error("HALT");
|
throw runtime_error("HALT");
|
||||||
|
#endif
|
||||||
|
|
||||||
case 0xE0000000: //periph
|
case 0xE0000000: //periph
|
||||||
switch(addr)
|
switch(addr)
|
||||||
|
@ -314,6 +351,7 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0xD0000000: //debug
|
case 0xD0000000: //debug
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
switch(addr & 0xFF)
|
switch(addr & 0xFF)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
@ -329,16 +367,24 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
|
||||||
statusMsg << Base::HEX8 << data << endl;
|
statusMsg << Base::HEX8 << data << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0x40000000: //RAM
|
case 0x40000000: //RAM
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
write16(addr+0, (data >> 0) & 0xFFFF);
|
write16(addr+0, (data >> 0) & 0xFFFF);
|
||||||
write16(addr+2, (data >> 16) & 0xFFFF);
|
write16(addr+2, (data >> 16) & 0xFFFF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
fatalError("write32", addr, data, "abort");
|
fatalError("write32", addr, data, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Thumbulator::isProtected(uInt32 addr)
|
bool Thumbulator::isProtected(uInt32 addr)
|
||||||
{
|
{
|
||||||
|
@ -361,20 +407,23 @@ bool Thumbulator::isProtected(uInt32 addr)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 Thumbulator::read16(uInt32 addr)
|
uInt32 Thumbulator::read16(uInt32 addr)
|
||||||
{
|
{
|
||||||
uInt32 data;
|
uInt32 data;
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if((addr > 0x40001fff) && (addr < 0x50000000))
|
if((addr > 0x40001fff) && (addr < 0x50000000))
|
||||||
fatalError("read16", addr, "abort - out of range");
|
fatalError("read16", addr, "abort - out of range");
|
||||||
else if((addr > 0x7fff) && (addr < 0x10000000))
|
else if((addr > 0x7fff) && (addr < 0x10000000))
|
||||||
fatalError("read16", addr, "abort - out of range");
|
fatalError("read16", addr, "abort - out of range");
|
||||||
if(addr & 1)
|
if(addr & 1)
|
||||||
fatalError("read16", addr, "abort - misaligned");
|
fatalError("read16", addr, "abort - misaligned");
|
||||||
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
++reads;
|
++reads;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch(addr & 0xF0000000)
|
switch(addr & 0xF0000000)
|
||||||
{
|
{
|
||||||
|
@ -392,21 +441,29 @@ 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;
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0xE0000000: //MAMCR
|
case 0xE0000000: //MAMCR
|
||||||
if(addr == 0xE01FC000)
|
if(addr == 0xE01FC000)
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
DO_DBUG(statusMsg << "read16(" << "MAMCR" << addr << ")=" << mamcr << " *");
|
DO_DBUG(statusMsg << "read16(" << "MAMCR" << addr << ")=" << mamcr << " *");
|
||||||
return mamcr;
|
return mamcr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
return fatalError("read16", addr, "abort");
|
return fatalError("read16", addr, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 Thumbulator::read32(uInt32 addr)
|
uInt32 Thumbulator::read32(uInt32 addr)
|
||||||
{
|
{
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if(addr & 3)
|
if(addr & 3)
|
||||||
fatalError("read32", addr, "abort - misaligned");
|
fatalError("read32", addr, "abort - misaligned");
|
||||||
|
#endif
|
||||||
|
|
||||||
uInt32 data;
|
uInt32 data;
|
||||||
switch(addr & 0xF0000000)
|
switch(addr & 0xF0000000)
|
||||||
|
@ -418,7 +475,11 @@ uInt32 Thumbulator::read32(uInt32 addr)
|
||||||
DO_DBUG(statusMsg << "read32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
DO_DBUG(statusMsg << "read32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0xE0000000:
|
case 0xE0000000:
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
switch(addr)
|
switch(addr)
|
||||||
{
|
{
|
||||||
|
@ -443,13 +504,19 @@ uInt32 Thumbulator::read32(uInt32 addr)
|
||||||
data = systick_count;
|
data = systick_count;
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case 0xE000E01C:
|
case 0xE000E01C:
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
data = systick_calibrate;
|
data = systick_calibrate;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
return fatalError("read32", addr, "abort");
|
return fatalError("read32", addr, "abort");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -771,7 +838,9 @@ int Thumbulator::execute()
|
||||||
write_register(15, pc);
|
write_register(15, pc);
|
||||||
DO_DISS(statusMsg << Base::HEX8 << (pc-5) << ": " << Base::HEX4 << inst << " ");
|
DO_DISS(statusMsg << Base::HEX8 << (pc-5) << ": " << Base::HEX4 << inst << " ");
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
++instructions;
|
++instructions;
|
||||||
|
#endif
|
||||||
|
|
||||||
Op decodedOp;
|
Op decodedOp;
|
||||||
if ((instructionPtr & 0xF0000000) == 0 && instructionPtr < romSize)
|
if ((instructionPtr & 0xF0000000) == 0 && instructionPtr < romSize)
|
||||||
|
@ -872,9 +941,10 @@ int Thumbulator::execute()
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
if(rd == 15)
|
if(rd == 15)
|
||||||
{
|
{
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
if((rc & 1) == 0)
|
if((rc & 1) == 0)
|
||||||
fatalError("add pc", pc, rc, " produced an arm address");
|
fatalError("add pc", pc, rc, " produced an arm address");
|
||||||
|
#endif
|
||||||
//rc &= ~1; //write_register may do this as well
|
//rc &= ~1; //write_register may do this as well
|
||||||
rc += 2; //The program counter is special
|
rc += 2; //The program counter is special
|
||||||
}
|
}
|
||||||
|
@ -1148,12 +1218,14 @@ int Thumbulator::execute()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
//BKPT
|
//BKPT
|
||||||
case Op::bkpt: {
|
case Op::bkpt: {
|
||||||
rb = (inst >> 0) & 0xFF;
|
rb = (inst >> 0) & 0xFF;
|
||||||
statusMsg << "bkpt 0x" << Base::HEX2 << rb << endl;
|
statusMsg << "bkpt 0x" << Base::HEX2 << rb << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//BL/BLX(1)
|
//BL/BLX(1)
|
||||||
case Op::blx1: {
|
case Op::blx1: {
|
||||||
|
@ -1514,11 +1586,13 @@ int Thumbulator::execute()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
//CPS
|
//CPS
|
||||||
case Op::cps: {
|
case Op::cps: {
|
||||||
DO_DISS(statusMsg << "cps TODO" << endl);
|
DO_DISS(statusMsg << "cps TODO" << endl);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//CPY copy high register
|
//CPY copy high register
|
||||||
case Op::cpy: {
|
case Op::cpy: {
|
||||||
|
@ -2142,11 +2216,13 @@ int Thumbulator::execute()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
//SETEND
|
//SETEND
|
||||||
case Op::setend: {
|
case Op::setend: {
|
||||||
statusMsg << "setend not implemented" << endl;
|
statusMsg << "setend not implemented" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//STMIA
|
//STMIA
|
||||||
case Op::stmia: {
|
case Op::stmia: {
|
||||||
|
@ -2424,11 +2500,15 @@ int Thumbulator::execute()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
case Op::invalid:
|
case Op::invalid:
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
statusMsg << "invalid instruction " << Base::HEX8 << pc << " " << Base::HEX4 << inst << endl;
|
statusMsg << "invalid instruction " << Base::HEX8 << pc << " " << Base::HEX4 << inst << endl;
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2464,12 +2544,19 @@ int Thumbulator::reset()
|
||||||
systick_calibrate = 0x00ABCDEF;
|
systick_calibrate = 0x00ABCDEF;
|
||||||
|
|
||||||
// fxq: don't care about below so much (maybe to guess timing???)
|
// fxq: don't care about below so much (maybe to guess timing???)
|
||||||
instructions = fetches = reads = writes = systick_ints = 0;
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
|
instructions = 0;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
fetches = reads = writes = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
statusMsg.str("");
|
statusMsg.str("");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Thumbulator::trapOnFatal = true;
|
bool Thumbulator::trapOnFatal = true;
|
||||||
|
#endif
|
||||||
|
|
|
@ -30,6 +30,12 @@ class Cartridge;
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Console.hxx"
|
#include "Console.hxx"
|
||||||
|
|
||||||
|
#define RETRON77
|
||||||
|
#ifdef RETRON77
|
||||||
|
#define UNSAFE_OPTIMIZATIONS
|
||||||
|
#define NO_THUMB_STATS
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ROMADDMASK 0x7FFF
|
#define ROMADDMASK 0x7FFF
|
||||||
#define RAMADDMASK 0x1FFF
|
#define RAMADDMASK 0x1FFF
|
||||||
|
|
||||||
|
@ -67,6 +73,7 @@ class Thumbulator
|
||||||
string run();
|
string run();
|
||||||
string run(uInt32 cycles);
|
string run(uInt32 cycles);
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
/**
|
/**
|
||||||
Normally when a fatal error is encountered, the ARM emulation
|
Normally when a fatal error is encountered, the ARM emulation
|
||||||
immediately throws an exception and exits. This method allows execution
|
immediately throws an exception and exits. This method allows execution
|
||||||
|
@ -80,6 +87,7 @@ class Thumbulator
|
||||||
@param enable Enable (the default) or disable exceptions on fatal errors
|
@param enable Enable (the default) or disable exceptions on fatal errors
|
||||||
*/
|
*/
|
||||||
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Inform the Thumbulator class about the console currently in use,
|
Inform the Thumbulator class about the console currently in use,
|
||||||
|
@ -147,7 +155,9 @@ class Thumbulator
|
||||||
uInt32 fetch32(uInt32 addr);
|
uInt32 fetch32(uInt32 addr);
|
||||||
uInt32 read16(uInt32 addr);
|
uInt32 read16(uInt32 addr);
|
||||||
uInt32 read32(uInt32 addr);
|
uInt32 read32(uInt32 addr);
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
bool isProtected(uInt32 addr);
|
bool isProtected(uInt32 addr);
|
||||||
|
#endif
|
||||||
void write16(uInt32 addr, uInt32 data);
|
void write16(uInt32 addr, uInt32 data);
|
||||||
void write32(uInt32 addr, uInt32 data);
|
void write32(uInt32 addr, uInt32 data);
|
||||||
void updateTimer(uInt32 cycles);
|
void updateTimer(uInt32 cycles);
|
||||||
|
@ -161,6 +171,7 @@ class Thumbulator
|
||||||
void do_cflag_bit(uInt32 x);
|
void do_cflag_bit(uInt32 x);
|
||||||
void do_vflag_bit(uInt32 x);
|
void do_vflag_bit(uInt32 x);
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// Throw a runtime_error exception containing an error referencing the
|
// Throw a runtime_error exception containing an error referencing the
|
||||||
// given message and variables
|
// given message and variables
|
||||||
// Note that the return value is never used in these methods
|
// Note that the return value is never used in these methods
|
||||||
|
@ -169,6 +180,7 @@ class Thumbulator
|
||||||
|
|
||||||
void dump_counters();
|
void dump_counters();
|
||||||
void dump_regs();
|
void dump_regs();
|
||||||
|
#endif
|
||||||
int execute();
|
int execute();
|
||||||
int reset();
|
int reset();
|
||||||
|
|
||||||
|
@ -182,7 +194,12 @@ class Thumbulator
|
||||||
uInt32 cpsr, mamcr;
|
uInt32 cpsr, mamcr;
|
||||||
bool handler_mode;
|
bool handler_mode;
|
||||||
uInt32 systick_ctrl, systick_reload, systick_count, systick_calibrate;
|
uInt32 systick_ctrl, systick_reload, systick_count, systick_calibrate;
|
||||||
uInt64 instructions, fetches, reads, writes, systick_ints;
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
|
uInt64 instructions;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_THUMB_STATS
|
||||||
|
uInt64 fetches, reads, writes;
|
||||||
|
#endif
|
||||||
|
|
||||||
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
||||||
// Register names from documentation:
|
// Register names from documentation:
|
||||||
|
@ -193,7 +210,9 @@ class Thumbulator
|
||||||
|
|
||||||
ostringstream statusMsg;
|
ostringstream statusMsg;
|
||||||
|
|
||||||
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
static bool trapOnFatal;
|
static bool trapOnFatal;
|
||||||
|
#endif
|
||||||
|
|
||||||
ConfigureFor configuration;
|
ConfigureFor configuration;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue