mirror of https://github.com/stella-emu/stella.git
Implement ARM image export.
This commit is contained in:
parent
57d9e120ce
commit
493f56e86a
|
@ -22,7 +22,10 @@
|
|||
#include "StringParser.hxx"
|
||||
#include "ScrollBarWidget.hxx"
|
||||
#include "StringListWidget.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
#include "BrowserDialog.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
namespace {
|
||||
constexpr int SAVE_ARM_IMAGE_CMD = 'sarm';
|
||||
|
@ -66,24 +69,42 @@ void CartridgeELFWidget::initialize()
|
|||
logWidget->setList(logLines);
|
||||
|
||||
y += visibleLogLines * lineHeight + lineHeight / 2;
|
||||
const auto saveImageButtonWidth = 17 * _font.getMaxCharWidth();
|
||||
|
||||
WidgetArray wid;
|
||||
|
||||
const auto saveImageButton = new ButtonWidget(_boss, _font, x, y, "Save ARM image", SAVE_ARM_IMAGE_CMD);
|
||||
saveImageButton->setTarget(this);
|
||||
|
||||
const auto imageNameEdit = new EditTextWidget(
|
||||
_boss, _font, x + saveImageButtonWidth, y, width - saveImageButtonWidth, lineHeight + 2, "arm_image.bin"
|
||||
);
|
||||
|
||||
wid.push_back(saveImageButton);
|
||||
wid.push_back(imageNameEdit);
|
||||
|
||||
addToFocusList(wid);
|
||||
}
|
||||
|
||||
void CartridgeELFWidget::saveArmImage(const FSNode& node)
|
||||
{
|
||||
try {
|
||||
const auto [buffer, size] = myCart.getArmImage();
|
||||
|
||||
const size_t sizeWritten = node.write(buffer, size);
|
||||
if (sizeWritten != size) throw runtime_error("failed to write arm image");
|
||||
|
||||
instance().frameBuffer().showTextMessage("Successfully exported ARM executable image");
|
||||
}
|
||||
catch (...) {
|
||||
instance().frameBuffer().showTextMessage("Failed to export ARM executable image");
|
||||
}
|
||||
}
|
||||
|
||||
void CartridgeELFWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||
{
|
||||
if (cmd == SAVE_ARM_IMAGE_CMD) cout << "save image" << std::endl;
|
||||
if (cmd == SAVE_ARM_IMAGE_CMD)
|
||||
BrowserDialog::show(
|
||||
_boss,
|
||||
"Save ARM image",
|
||||
instance().userDir().getPath() + "arm_image.bin",
|
||||
BrowserDialog::Mode::FileSave,
|
||||
[this](bool ok, const FSNode& node) {
|
||||
if (ok) saveArmImage(node);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "CartDebugWidget.hxx"
|
||||
|
||||
class CartridgeELF;
|
||||
class EditTextWidget;
|
||||
class FSNode;
|
||||
|
||||
class CartridgeELFWidget: public CartDebugWidget
|
||||
{
|
||||
|
@ -34,6 +36,7 @@ class CartridgeELFWidget: public CartDebugWidget
|
|||
|
||||
private:
|
||||
void initialize();
|
||||
void saveArmImage(const FSNode& node);
|
||||
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
|
|
|
@ -397,6 +397,23 @@ string CartridgeELF::getDebugLog() const
|
|||
return s.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
std::pair<unique_ptr<uInt8[]>, size_t> CartridgeELF::getArmImage() const
|
||||
{
|
||||
const size_t imageSize = ADDR_TABLES_BASE + TABLES_SIZE;
|
||||
unique_ptr<uInt8[]> image = make_unique<uInt8[]>(imageSize);
|
||||
|
||||
memset(image.get(), 0, imageSize);
|
||||
|
||||
memcpy(image.get() + ADDR_STACK_BASE, mySectionStack.get(), STACK_SIZE);
|
||||
memcpy(image.get() + ADDR_TEXT_BASE, mySectionText.get(), TEXT_SIZE);
|
||||
memcpy(image.get() + ADDR_DATA_BASE, mySectionData.get(), DATA_SIZE);
|
||||
memcpy(image.get() + ADDR_RODATA_BASE, mySectionRodata.get(), RODATA_SIZE);
|
||||
memcpy(image.get() + ADDR_TABLES_BASE, mySectionTables.get(), TABLES_SIZE);
|
||||
|
||||
return std::pair(std::move(image), imageSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -444,6 +461,7 @@ void CartridgeELF::parseAndLinkElf()
|
|||
if (dump) dumpElf(myElfParser, cout);
|
||||
|
||||
myLinker = make_unique<ElfLinker>(ADDR_TEXT_BASE, ADDR_DATA_BASE, ADDR_RODATA_BASE, myElfParser);
|
||||
|
||||
try {
|
||||
myLinker->link(externalSymbols(SystemType::ntsc));
|
||||
} catch (const ElfLinker::ElfLinkError& e) {
|
||||
|
|
|
@ -89,6 +89,8 @@ class CartridgeELF: public Cartridge {
|
|||
public:
|
||||
string getDebugLog() const;
|
||||
|
||||
std::pair<unique_ptr<uInt8[]>, size_t> getArmImage() const;
|
||||
|
||||
private:
|
||||
class BusFallbackDelegate: public CortexM0::BusTransactionDelegate {
|
||||
public:
|
||||
|
|
|
@ -117,9 +117,16 @@ void BrowserDialog::show(GuiObject* parent, const GUI::Font& font,
|
|||
const Command& command,
|
||||
const FSNode::NameFilter& namefilter)
|
||||
{
|
||||
uInt32 w = 0, h = 0;
|
||||
uInt32 w, h;
|
||||
|
||||
const auto parentDialog = dynamic_cast<Dialog*>(parent);
|
||||
if (parentDialog) {
|
||||
parentDialog->getDynamicBounds(w, h);
|
||||
} else {
|
||||
w = FBMinimum::Width;
|
||||
h = FBMinimum::Height;
|
||||
}
|
||||
|
||||
static_cast<Dialog*>(parent)->getDynamicBounds(w, h);
|
||||
if(w > static_cast<uInt32>(font.getMaxCharWidth() * 80))
|
||||
w = font.getMaxCharWidth() * 80;
|
||||
|
||||
|
|
Loading…
Reference in New Issue