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();
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);
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;