mirror of https://github.com/stella-emu/stella.git
Hook up ARM emulation. Crashes and dies right now.
This commit is contained in:
parent
39eb36083b
commit
32b8bbd32e
|
@ -35,6 +35,8 @@ using namespace elfEnvironment;
|
|||
|
||||
namespace {
|
||||
constexpr size_t TRANSACTION_QUEUE_CAPACITY = 16384;
|
||||
constexpr uInt32 ARM_RUNAHED_MIN = 3;
|
||||
constexpr uInt32 ARM_RUNAHED_MAX = 6;
|
||||
|
||||
#ifdef DUMP_ELF
|
||||
void dumpElf(const ElfFile& elf)
|
||||
|
@ -201,6 +203,7 @@ void CartridgeELF::reset()
|
|||
std::fill_n(myLastPeekResult.get(), 0x1000, 0);
|
||||
myIsBusDriven = false;
|
||||
myDriveBusValue = 0;
|
||||
myArmCycles = 0;
|
||||
|
||||
std::memset(mySectionStack.get(), 0, STACK_SIZE);
|
||||
std::memset(mySectionText.get(), 0, TEXT_SIZE);
|
||||
|
@ -292,6 +295,8 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
||||
{
|
||||
runArm();
|
||||
|
||||
value = driveBus(address, value);
|
||||
|
||||
if (address & 0x1000) {
|
||||
|
@ -305,6 +310,8 @@ uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
|
||||
{
|
||||
runArm();
|
||||
|
||||
return driveBus(address, value);
|
||||
}
|
||||
|
||||
|
@ -452,4 +459,18 @@ void CartridgeELF::jumpToMain()
|
|||
.setRegister(15, myArmEntrypoint);
|
||||
}
|
||||
|
||||
void CartridgeELF::runArm()
|
||||
{
|
||||
if (myArmCycles >= (mySystem->cycles() + ARM_RUNAHED_MIN) * myArmCyclesPer6502Cycle) return;
|
||||
|
||||
const uInt32 cyclesGoal =
|
||||
(mySystem->cycles() + ARM_RUNAHED_MAX) * myArmCyclesPer6502Cycle - myArmCycles;
|
||||
uInt32 cycles;
|
||||
|
||||
const CortexM0::err_t err = myCortexEmu.run(cyclesGoal, cycles);
|
||||
myArmCycles += cycles;
|
||||
|
||||
if (err != 0) FatalEmulationError::raise("error executing ARM code: " + CortexM0::describeError(err));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ class CartridgeELF: public Cartridge {
|
|||
uInt32 getSystemType() const;
|
||||
void jumpToMain();
|
||||
|
||||
void runArm();
|
||||
|
||||
private:
|
||||
ByteBuffer myImage;
|
||||
size_t myImageSize{0};
|
||||
|
@ -102,6 +104,8 @@ class CartridgeELF: public Cartridge {
|
|||
|
||||
ConsoleTiming myConsoleTiming{ConsoleTiming::ntsc};
|
||||
uInt32 myArmCyclesPer6502Cycle{80};
|
||||
|
||||
uInt64 myArmCycles{0};
|
||||
};
|
||||
|
||||
#endif // CARTRIDGE_ELF
|
||||
|
|
|
@ -411,6 +411,64 @@ namespace {
|
|||
|
||||
return Op::invalid;
|
||||
}
|
||||
|
||||
string describeErrorCode(CortexM0::err_t err) {
|
||||
if (CortexM0::isErrCustom(err)) {
|
||||
ostringstream s;
|
||||
s << "custom error " << CortexM0::getErrCustom(err);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
switch (CortexM0::getErrInstrinsic(err)) {
|
||||
case CortexM0::ERR_UNMAPPED_READ32:
|
||||
return "unmapped read32";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_READ16:
|
||||
return "unmapped read16";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_READ8:
|
||||
return "unmapped read8";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_WRITE32:
|
||||
return "unmapped write32";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_WRITE16:
|
||||
return "unmapped write16";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_WRITE8:
|
||||
return "unmapped write8";
|
||||
|
||||
case CortexM0::ERR_UNMAPPED_FETCH16:
|
||||
return "unmapped fetch";
|
||||
|
||||
case CortexM0::ERR_WRITE_ACCESS_DENIED:
|
||||
return "write access denied";
|
||||
|
||||
case CortexM0::ERR_ACCESS_ALIGNMENT_FAULT:
|
||||
return "alignment fault";
|
||||
|
||||
case CortexM0::ERR_BKPT:
|
||||
return "breakpoint encountered";
|
||||
|
||||
case CortexM0::ERR_INVALID_OPERATING_MODE:
|
||||
return "invalid operation mode";
|
||||
|
||||
case CortexM0::ERR_UNIMPLEMENTED_INST:
|
||||
return "instruction not implemented";
|
||||
|
||||
case CortexM0::ERR_SWI:
|
||||
return "supervisor call";
|
||||
|
||||
case CortexM0::ERR_UNDEFINED_INST:
|
||||
return "undefined instruction";
|
||||
}
|
||||
|
||||
ostringstream s;
|
||||
s << "unknown instrinsic error " << CortexM0::getErrInstrinsic(err);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
}
|
||||
|
||||
CortexM0::err_t CortexM0::BusTransactionDelegate::read32(uInt32 address, uInt32& value, CortexM0& cortex)
|
||||
|
@ -454,6 +512,19 @@ CortexM0::err_t CortexM0::BusTransactionDelegate::fetch16(
|
|||
return 0;
|
||||
}
|
||||
|
||||
string CortexM0::describeError(err_t err) {
|
||||
if (err == ERR_NONE) return "no error";
|
||||
|
||||
ostringstream s;
|
||||
s
|
||||
<< describeErrorCode(err) << " : 0x"
|
||||
<< std::hex << std::setw(8) << std::setfill('0')
|
||||
<< getErrExtra(err);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
CortexM0::CortexM0()
|
||||
{
|
||||
myPageMap = make_unique<uInt8[]>(PAGEMAP_SIZE);
|
||||
|
|
|
@ -71,6 +71,10 @@ class CortexM0
|
|||
return (err & 0xffffffff) >> 8;
|
||||
}
|
||||
|
||||
static inline uInt8 getErrInstrinsic(err_t err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline uInt32 getErrExtra(err_t err) {
|
||||
return err >> 32;
|
||||
}
|
||||
|
@ -83,6 +87,8 @@ class CortexM0
|
|||
return static_cast<uInt64>(code) | (static_cast<uInt64>(extra) << 32);
|
||||
}
|
||||
|
||||
static string describeError(err_t error);
|
||||
|
||||
public:
|
||||
CortexM0();
|
||||
|
||||
|
|
Loading…
Reference in New Issue