mirror of https://github.com/stella-emu/stella.git
Setup ARM for execution.
This commit is contained in:
parent
7d55b98f29
commit
92bd56f4ec
|
@ -189,8 +189,6 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
|
|||
|
||||
parseAndLinkElf();
|
||||
setupMemoryMap();
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -230,6 +228,8 @@ void CartridgeELF::reset()
|
|||
myVcsLib.vcsStartOverblank();
|
||||
myVcsLib.vcsEndOverblank();
|
||||
myVcsLib.vcsNop2n(1024);
|
||||
|
||||
jumpToMain();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -277,6 +277,11 @@ bool CartridgeELF::poke(uInt16 address, uInt8 value)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CartridgeELF::consoleChanged(ConsoleTiming timing)
|
||||
{
|
||||
myConsoleTiming = timing;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const ByteBuffer& CartridgeELF::getImage(size_t& size) const
|
||||
{
|
||||
|
@ -284,6 +289,7 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const
|
|||
return myImage;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
||||
{
|
||||
value = driveBus(address, value);
|
||||
|
@ -296,11 +302,13 @@ uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
|||
return value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
|
||||
{
|
||||
return driveBus(address, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
||||
{
|
||||
auto* nextTransaction = myTransactionQueue.getNextTransaction(address);
|
||||
|
@ -311,6 +319,7 @@ inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
|||
return value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeELF::parseAndLinkElf()
|
||||
{
|
||||
ElfParser elfParser;
|
||||
|
@ -359,6 +368,7 @@ void CartridgeELF::parseAndLinkElf()
|
|||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeELF::setupMemoryMap()
|
||||
{
|
||||
mySectionStack = make_unique<uInt8[]>(STACK_SIZE);
|
||||
|
@ -382,4 +392,63 @@ void CartridgeELF::setupMemoryMap()
|
|||
STUB_SIZE / CortexM0::PAGE_SIZE, true, &myVcsLib);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeELF::getCoreClock() const
|
||||
{
|
||||
switch (myConsoleTiming) {
|
||||
case ConsoleTiming::ntsc:
|
||||
return myArmCyclesPer6502Cycle * 262 * 76 * 60;
|
||||
|
||||
case ConsoleTiming::pal:
|
||||
case ConsoleTiming::secam:
|
||||
return myArmCyclesPer6502Cycle * 312 * 76 * 50;
|
||||
|
||||
default:
|
||||
throw runtime_error("invalid console timing");
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeELF::getSystemType() const
|
||||
{
|
||||
switch (myConsoleTiming) {
|
||||
case ConsoleTiming::ntsc:
|
||||
return ST_NTSC_2600;
|
||||
|
||||
// Use frame layout here instead
|
||||
case ConsoleTiming::pal:
|
||||
case ConsoleTiming::secam:
|
||||
return ST_PAL_2600;
|
||||
|
||||
default:
|
||||
throw runtime_error("invalid console timing");
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeELF::jumpToMain()
|
||||
{
|
||||
if (!mySystem) throw runtime_error("cartridge not installed");
|
||||
|
||||
uInt32 sp = ADDR_STACK_BASE + STACK_SIZE;
|
||||
CortexM0::err_t err = 0;
|
||||
|
||||
// Feature flags
|
||||
sp -= 4;
|
||||
err |= myCortexEmu.write32(sp, 0);
|
||||
|
||||
sp -= 4;
|
||||
err |= myCortexEmu.write32(sp, getCoreClock());
|
||||
|
||||
sp -= 4;
|
||||
err |= myCortexEmu.write32(sp, getSystemType());
|
||||
|
||||
if (err) throw runtime_error("unable to setup main args");
|
||||
|
||||
myCortexEmu
|
||||
.setRegister(0, sp )
|
||||
.setRegister(14, RETURN_ADDR_MAIN)
|
||||
.setRegister(15, myArmEntrypoint);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ class CartridgeELF: public Cartridge {
|
|||
|
||||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
void consoleChanged(ConsoleTiming timing) override;
|
||||
|
||||
// Methods from Cartridge
|
||||
public:
|
||||
bool bankChanged() override { return false; }
|
||||
|
@ -66,10 +68,13 @@ class CartridgeELF: public Cartridge {
|
|||
private:
|
||||
uInt8 driveBus(uInt16 address, uInt8 value);
|
||||
|
||||
private:
|
||||
void parseAndLinkElf();
|
||||
void setupMemoryMap();
|
||||
|
||||
uInt32 getCoreClock() const;
|
||||
uInt32 getSystemType() const;
|
||||
void jumpToMain();
|
||||
|
||||
private:
|
||||
ByteBuffer myImage;
|
||||
size_t myImageSize{0};
|
||||
|
@ -94,6 +99,9 @@ class CartridgeELF: public Cartridge {
|
|||
unique_ptr<uInt8[]> mySectionTables;
|
||||
|
||||
VcsLib myVcsLib;
|
||||
|
||||
ConsoleTiming myConsoleTiming{ConsoleTiming::ntsc};
|
||||
uInt32 myArmCyclesPer6502Cycle{80};
|
||||
};
|
||||
|
||||
#endif // CARTRIDGE_ELF
|
||||
|
|
|
@ -105,6 +105,14 @@ class CortexM0
|
|||
|
||||
err_t run(uInt32 maxCycles, uInt32& cycles);
|
||||
|
||||
err_t read32(uInt32 address, uInt32& value);
|
||||
err_t read16(uInt32 address, uInt16& value);
|
||||
err_t read8(uInt32 address, uInt8& value);
|
||||
|
||||
err_t write32(uInt32 address, uInt32 value);
|
||||
err_t write16(uInt32 address, uInt16 value);
|
||||
err_t write8(uInt32 address, uInt8 value);
|
||||
|
||||
private:
|
||||
|
||||
enum class MemoryRegionType : uInt8 {
|
||||
|
@ -154,14 +162,6 @@ class CortexM0
|
|||
MemoryRegion& setupMapping(uInt32 pageBase, uInt32 pageCount,
|
||||
bool readOnly, MemoryRegionType type);
|
||||
|
||||
err_t read32(uInt32 address, uInt32& value);
|
||||
err_t read16(uInt32 address, uInt16& value);
|
||||
err_t read8(uInt32 address, uInt8& value);
|
||||
|
||||
err_t write32(uInt32 address, uInt32 value);
|
||||
err_t write16(uInt32 address, uInt16 value);
|
||||
err_t write8(uInt32 address, uInt8 value);
|
||||
|
||||
err_t fetch16(uInt32 address, uInt16& value, uInt8& op);
|
||||
|
||||
void do_cvflag(uInt32 a, uInt32 b, uInt32 c);
|
||||
|
|
|
@ -106,6 +106,12 @@ namespace elfEnvironment {
|
|||
extern const uInt8 OVERBLANK_PROGRAM[];
|
||||
extern const uInt32 OVERBLANK_PROGRAM_SIZE;
|
||||
|
||||
constexpr uInt32 ST_NTSC_2600 = 0;
|
||||
constexpr uInt32 ST_PAL_2600 = 1;
|
||||
constexpr uInt32 ST_PAL60_2600 = 2;
|
||||
|
||||
constexpr uInt32 RETURN_ADDR_MAIN = 0xffffdead;
|
||||
|
||||
enum class Palette: uInt8 {pal, ntsc};
|
||||
|
||||
vector<ElfLinker::ExternalSymbol> externalSymbols(Palette palette);
|
||||
|
|
|
@ -55,6 +55,7 @@ void VcsLib::vcsStartOverblank()
|
|||
.yield(0x0080);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VcsLib::vcsEndOverblank()
|
||||
{
|
||||
myTransactionQueue
|
||||
|
@ -63,6 +64,7 @@ void VcsLib::vcsEndOverblank()
|
|||
.setNextInjectAddress(0x1000);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VcsLib::vcsNop2n(uInt16 n)
|
||||
{
|
||||
if (n == 0) return;
|
||||
|
|
Loading…
Reference in New Issue