mirror of https://github.com/stella-emu/stella.git
Fix ELF signature detection, read value stream.
This commit is contained in:
parent
8eb0d72eac
commit
41c8bff0c6
|
@ -199,7 +199,7 @@ Bankswitch::Sizes = {{
|
||||||
{ 8_KB, 8_KB+5 }, // _WDSW
|
{ 8_KB, 8_KB+5 }, // _WDSW
|
||||||
{ 8_KB, 8_KB }, // _WF8
|
{ 8_KB, 8_KB }, // _WF8
|
||||||
{ 64_KB, 64_KB }, // _X07
|
{ 64_KB, 64_KB }, // _X07
|
||||||
{ 4_KB, Bankswitch::any_KB }, // ELF
|
{ Bankswitch::any_KB, Bankswitch::any_KB }, // ELF
|
||||||
#if defined(CUSTOM_ARM)
|
#if defined(CUSTOM_ARM)
|
||||||
{ Bankswitch::any_KB, Bankswitch::any_KB }
|
{ Bankswitch::any_KB, Bankswitch::any_KB }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,7 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
|
||||||
// Guess type based on size
|
// Guess type based on size
|
||||||
Bankswitch::Type type = Bankswitch::Type::_AUTO;
|
Bankswitch::Type type = Bankswitch::Type::_AUTO;
|
||||||
|
|
||||||
if (size >= 4_KB && isProbablyELF(image, size)) {
|
if (size >= 128 && isProbablyELF(image, size)) {
|
||||||
type =Bankswitch::Type::_ELF;
|
type =Bankswitch::Type::_ELF;
|
||||||
}
|
}
|
||||||
else if ((size % 8448) == 0 || size == 6_KB)
|
else if ((size % 8448) == 0 || size == 6_KB)
|
||||||
|
@ -865,7 +865,7 @@ bool CartDetector::isProbablyELF(const ByteBuffer& image, size_t size) {
|
||||||
|
|
||||||
// Must start with ELF magic
|
// Must start with ELF magic
|
||||||
static constexpr uInt8 signature[] = { 0x7f, 'E', 'L', 'F' };
|
static constexpr uInt8 signature[] = { 0x7f, 'E', 'L', 'F' };
|
||||||
if (!searchForBytes(image, sizeof(signature), signature, sizeof(signature), 1)) return false;
|
if (!searchForBytes(image, 2 * sizeof(signature), signature, sizeof(signature), 1)) return false;
|
||||||
|
|
||||||
// We require little endian
|
// We require little endian
|
||||||
if (image[0x05] != 1) return false;
|
if (image[0x05] != 1) return false;
|
||||||
|
|
|
@ -15,8 +15,17 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "System.hxx"
|
||||||
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
#include "CartELF.hxx"
|
#include "CartELF.hxx"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr size_t READ_STREAM_CAPACITY = 512;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5,
|
CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
|
@ -24,6 +33,8 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
|
||||||
{
|
{
|
||||||
myImage = make_unique<uInt8[]>(size);
|
myImage = make_unique<uInt8[]>(size);
|
||||||
std::memcpy(myImage.get(), image.get(), size);
|
std::memcpy(myImage.get(), image.get(), size);
|
||||||
|
|
||||||
|
createRomAccessArrays(0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,10 +42,24 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
|
||||||
CartridgeELF::~CartridgeELF() {}
|
CartridgeELF::~CartridgeELF() {}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeELF::reset() {}
|
void CartridgeELF::reset()
|
||||||
|
{
|
||||||
|
myReadStream.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeELF::install(System& system) {}
|
void CartridgeELF::install(System& system)
|
||||||
|
{
|
||||||
|
mySystem = &system;
|
||||||
|
|
||||||
|
for (size_t addr = 0; addr < 0x1000; addr += System::PAGE_SIZE) {
|
||||||
|
System::PageAccess access(this, System::PageAccessType::READ);
|
||||||
|
access.romPeekCounter = &myRomAccessCounter[addr];
|
||||||
|
access.romPokeCounter = &myRomAccessCounter[addr];
|
||||||
|
|
||||||
|
mySystem->setPageAccess(0x1000 + addr, access);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeELF::save(Serializer& out) const
|
bool CartridgeELF::save(Serializer& out) const
|
||||||
|
@ -51,7 +76,7 @@ bool CartridgeELF::load(Serializer& in)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeELF::peek(uInt16 address)
|
uInt8 CartridgeELF::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
return 0;
|
return myReadStream.Pop(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -66,3 +91,69 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const
|
||||||
size = myImageSize;
|
size = myImageSize;
|
||||||
return myImage;
|
return myImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
CartridgeELF::ReadStream::ReadStream()
|
||||||
|
{
|
||||||
|
myStream = make_unique<ScheduledRead[]>(READ_STREAM_CAPACITY);
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeELF::ReadStream::Reset()
|
||||||
|
{
|
||||||
|
myStreamNext = myStreamSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeELF::ReadStream::Push(uInt8 value)
|
||||||
|
{
|
||||||
|
if (myNextReadAddress == 0xfff)
|
||||||
|
throw FatalEmulationError("read stream has reached the end of address space");
|
||||||
|
|
||||||
|
Push(value, myNextReadAddress + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeELF::ReadStream::Push(uInt8 value, uInt8 address)
|
||||||
|
{
|
||||||
|
if (myStreamSize == READ_STREAM_CAPACITY)
|
||||||
|
throw FatalEmulationError("read stream overflow");
|
||||||
|
|
||||||
|
address &= 0xfff;
|
||||||
|
|
||||||
|
myStream[(myStreamNext + myStreamSize++) % READ_STREAM_CAPACITY] =
|
||||||
|
{.address = address, .value = value};
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeELF::ReadStream::HasPendingRead() const
|
||||||
|
{
|
||||||
|
return myStreamSize > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt16 CartridgeELF::ReadStream::GetNextReadAddress() const
|
||||||
|
{
|
||||||
|
return myNextReadAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt8 CartridgeELF::ReadStream::Pop(uInt16 readAddress)
|
||||||
|
{
|
||||||
|
if (myStreamSize == 0)
|
||||||
|
throw FatalEmulationError("read stream underflow");
|
||||||
|
|
||||||
|
if ((readAddress & 0xfff) != myNextReadAddress)
|
||||||
|
{
|
||||||
|
ostringstream s;
|
||||||
|
s << "unexcpected cartridge read from 0x" << std::hex << std::setw(4) << readAddress;
|
||||||
|
|
||||||
|
throw FatalEmulationError(s.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const uInt8 value = myStream[myStreamNext++].value;
|
||||||
|
myStreamNext %= READ_STREAM_CAPACITY;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -51,9 +51,40 @@ class CartridgeELF: public Cartridge {
|
||||||
|
|
||||||
string name() const override { return "CartridgeELF"; };
|
string name() const override { return "CartridgeELF"; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ScheduledRead {
|
||||||
|
uInt16 address;
|
||||||
|
uInt8 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReadStream {
|
||||||
|
public:
|
||||||
|
ReadStream();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void Push(uInt8 value);
|
||||||
|
void Push(uInt8 value, uInt8 address);
|
||||||
|
|
||||||
|
bool HasPendingRead() const;
|
||||||
|
uInt16 GetNextReadAddress() const;
|
||||||
|
uInt8 Pop(uInt16 readAddress);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unique_ptr<ScheduledRead[]> myStream;
|
||||||
|
size_t myStreamNext{0};
|
||||||
|
size_t myStreamSize{0};
|
||||||
|
|
||||||
|
uInt16 myNextReadAddress{0};
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ByteBuffer myImage;
|
ByteBuffer myImage;
|
||||||
size_t myImageSize{0};
|
size_t myImageSize{0};
|
||||||
|
|
||||||
|
System* mySystem{nullptr};
|
||||||
|
|
||||||
|
ReadStream myReadStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CARTRIDGE_ELF
|
#endif // CARTRIDGE_ELF
|
||||||
|
|
Loading…
Reference in New Issue