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 }, // _WF8
|
||||
{ 64_KB, 64_KB }, // _X07
|
||||
{ 4_KB, Bankswitch::any_KB }, // ELF
|
||||
{ Bankswitch::any_KB, Bankswitch::any_KB }, // ELF
|
||||
#if defined(CUSTOM_ARM)
|
||||
{ Bankswitch::any_KB, Bankswitch::any_KB }
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
|
|||
// Guess type based on size
|
||||
Bankswitch::Type type = Bankswitch::Type::_AUTO;
|
||||
|
||||
if (size >= 4_KB && isProbablyELF(image, size)) {
|
||||
if (size >= 128 && isProbablyELF(image, size)) {
|
||||
type =Bankswitch::Type::_ELF;
|
||||
}
|
||||
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
|
||||
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
|
||||
if (image[0x05] != 1) return false;
|
||||
|
|
|
@ -15,8 +15,17 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "System.hxx"
|
||||
#include "exception/FatalEmulationError.hxx"
|
||||
|
||||
#include "CartELF.hxx"
|
||||
|
||||
namespace {
|
||||
constexpr size_t READ_STREAM_CAPACITY = 512;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5,
|
||||
const Settings& settings)
|
||||
|
@ -24,6 +33,8 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
|
|||
{
|
||||
myImage = make_unique<uInt8[]>(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() {}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
|
@ -51,7 +76,7 @@ bool CartridgeELF::load(Serializer& in)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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;
|
||||
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"; };
|
||||
|
||||
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:
|
||||
ByteBuffer myImage;
|
||||
size_t myImageSize{0};
|
||||
|
||||
System* mySystem{nullptr};
|
||||
|
||||
ReadStream myReadStream;
|
||||
};
|
||||
|
||||
#endif // CARTRIDGE_ELF
|
||||
|
|
Loading…
Reference in New Issue