Setup ARM for execution.

This commit is contained in:
Christian Speckner 2024-07-27 10:56:40 +02:00
parent 7d55b98f29
commit 92bd56f4ec
5 changed files with 96 additions and 11 deletions

View File

@ -189,8 +189,6 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
parseAndLinkElf(); parseAndLinkElf();
setupMemoryMap(); setupMemoryMap();
reset();
} }
@ -230,6 +228,8 @@ void CartridgeELF::reset()
myVcsLib.vcsStartOverblank(); myVcsLib.vcsStartOverblank();
myVcsLib.vcsEndOverblank(); myVcsLib.vcsEndOverblank();
myVcsLib.vcsNop2n(1024); myVcsLib.vcsNop2n(1024);
jumpToMain();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -277,6 +277,11 @@ bool CartridgeELF::poke(uInt16 address, uInt8 value)
return false; return false;
} }
void CartridgeELF::consoleChanged(ConsoleTiming timing)
{
myConsoleTiming = timing;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const ByteBuffer& CartridgeELF::getImage(size_t& size) const const ByteBuffer& CartridgeELF::getImage(size_t& size) const
{ {
@ -284,6 +289,7 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const
return myImage; return myImage;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value) uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
{ {
value = driveBus(address, value); value = driveBus(address, value);
@ -296,11 +302,13 @@ uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
return value; return value;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value) uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
{ {
return driveBus(address, value); return driveBus(address, value);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value) inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
{ {
auto* nextTransaction = myTransactionQueue.getNextTransaction(address); auto* nextTransaction = myTransactionQueue.getNextTransaction(address);
@ -311,6 +319,7 @@ inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
return value; return value;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeELF::parseAndLinkElf() void CartridgeELF::parseAndLinkElf()
{ {
ElfParser elfParser; ElfParser elfParser;
@ -359,6 +368,7 @@ void CartridgeELF::parseAndLinkElf()
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeELF::setupMemoryMap() void CartridgeELF::setupMemoryMap()
{ {
mySectionStack = make_unique<uInt8[]>(STACK_SIZE); mySectionStack = make_unique<uInt8[]>(STACK_SIZE);
@ -382,4 +392,63 @@ void CartridgeELF::setupMemoryMap()
STUB_SIZE / CortexM0::PAGE_SIZE, true, &myVcsLib); 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);
}

View File

@ -47,6 +47,8 @@ class CartridgeELF: public Cartridge {
bool poke(uInt16 address, uInt8 value) override; bool poke(uInt16 address, uInt8 value) override;
void consoleChanged(ConsoleTiming timing) override;
// Methods from Cartridge // Methods from Cartridge
public: public:
bool bankChanged() override { return false; } bool bankChanged() override { return false; }
@ -66,10 +68,13 @@ class CartridgeELF: public Cartridge {
private: private:
uInt8 driveBus(uInt16 address, uInt8 value); uInt8 driveBus(uInt16 address, uInt8 value);
private:
void parseAndLinkElf(); void parseAndLinkElf();
void setupMemoryMap(); void setupMemoryMap();
uInt32 getCoreClock() const;
uInt32 getSystemType() const;
void jumpToMain();
private: private:
ByteBuffer myImage; ByteBuffer myImage;
size_t myImageSize{0}; size_t myImageSize{0};
@ -94,6 +99,9 @@ class CartridgeELF: public Cartridge {
unique_ptr<uInt8[]> mySectionTables; unique_ptr<uInt8[]> mySectionTables;
VcsLib myVcsLib; VcsLib myVcsLib;
ConsoleTiming myConsoleTiming{ConsoleTiming::ntsc};
uInt32 myArmCyclesPer6502Cycle{80};
}; };
#endif // CARTRIDGE_ELF #endif // CARTRIDGE_ELF

View File

@ -105,6 +105,14 @@ class CortexM0
err_t run(uInt32 maxCycles, uInt32& cycles); 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: private:
enum class MemoryRegionType : uInt8 { enum class MemoryRegionType : uInt8 {
@ -154,14 +162,6 @@ class CortexM0
MemoryRegion& setupMapping(uInt32 pageBase, uInt32 pageCount, MemoryRegion& setupMapping(uInt32 pageBase, uInt32 pageCount,
bool readOnly, MemoryRegionType type); 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); err_t fetch16(uInt32 address, uInt16& value, uInt8& op);
void do_cvflag(uInt32 a, uInt32 b, uInt32 c); void do_cvflag(uInt32 a, uInt32 b, uInt32 c);

View File

@ -106,6 +106,12 @@ namespace elfEnvironment {
extern const uInt8 OVERBLANK_PROGRAM[]; extern const uInt8 OVERBLANK_PROGRAM[];
extern const uInt32 OVERBLANK_PROGRAM_SIZE; 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}; enum class Palette: uInt8 {pal, ntsc};
vector<ElfLinker::ExternalSymbol> externalSymbols(Palette palette); vector<ElfLinker::ExternalSymbol> externalSymbols(Palette palette);

View File

@ -55,6 +55,7 @@ void VcsLib::vcsStartOverblank()
.yield(0x0080); .yield(0x0080);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VcsLib::vcsEndOverblank() void VcsLib::vcsEndOverblank()
{ {
myTransactionQueue myTransactionQueue
@ -63,6 +64,7 @@ void VcsLib::vcsEndOverblank()
.setNextInjectAddress(0x1000); .setNextInjectAddress(0x1000);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VcsLib::vcsNop2n(uInt16 n) void VcsLib::vcsNop2n(uInt16 n)
{ {
if (n == 0) return; if (n == 0) return;