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();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue