From a6bec42db74b476c1037ea44052189508843cef5 Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 17 Apr 2013 22:32:49 +0000 Subject: [PATCH] Well, that didn't take long. I went ahead and added the ability to erase/load/save the Flash memory in the FA2 scheme (it's stored in the Harmony cart, but emulated with a file). This is a debugger, so it might as well have access to all the lower-level stuff in the cart. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2697 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/debugger/gui/CartDebugWidget.hxx | 5 ++- src/debugger/gui/CartFA2Widget.cxx | 55 ++++++++++++++++++++++++---- src/debugger/gui/CartFA2Widget.hxx | 9 ++++- src/emucore/CartFA2.cxx | 44 ++++++++++++++++++++++ src/emucore/CartFA2.hxx | 9 +++++ 5 files changed, 112 insertions(+), 10 deletions(-) diff --git a/src/debugger/gui/CartDebugWidget.hxx b/src/debugger/gui/CartDebugWidget.hxx index bbf3e9875..732d6b338 100644 --- a/src/debugger/gui/CartDebugWidget.hxx +++ b/src/debugger/gui/CartDebugWidget.hxx @@ -41,7 +41,8 @@ class CartDebugWidget : public Widget, public CommandSender CommandSender(boss), myFontWidth(font.getMaxCharWidth()), myFontHeight(font.getFontHeight()), - myLineHeight(font.getLineHeight()) + myLineHeight(font.getLineHeight()), + myButtonHeight(myLineHeight + 4) { _type = kCartDebugWidget; } @@ -108,7 +109,7 @@ class CartDebugWidget : public Widget, public CommandSender protected: // These will be needed by most of the child classes; // we may as well make them protected variables - int myFontWidth, myFontHeight, myLineHeight; + int myFontWidth, myFontHeight, myLineHeight, myButtonHeight; private: StringListWidget* myDesc; diff --git a/src/debugger/gui/CartFA2Widget.cxx b/src/debugger/gui/CartFA2Widget.cxx index 55e6e75a6..6c85b457d 100644 --- a/src/debugger/gui/CartFA2Widget.cxx +++ b/src/debugger/gui/CartFA2Widget.cxx @@ -34,8 +34,7 @@ CartridgeFA2Widget::CartridgeFA2Widget( info << "Modified FA RAM+, six or seven 4K banks\n" << "256 bytes RAM @ $F000 - $F1FF\n" << " $F100 - $F1FF (R), $F000 - $F0FF (W)\n" - << "RAM can be loaded/saved to Harmony flash by accessing $FF4 " - "(not currently accessible)\n" + << "RAM can be loaded/saved to Harmony flash by accessing $FF4\n" << "Startup bank = " << cart.myStartBank << "\n"; // Eventually, we should query this from the debugger/disassembler @@ -68,6 +67,34 @@ CartridgeFA2Widget::CartridgeFA2Widget( font.getStringWidth("Set bank: "), kBankChanged); myBank->setTarget(this); addFocusWidget(myBank); + ypos += myLineHeight + 20; + + const int bwidth = font.getStringWidth("Erase") + 20; + + StaticTextWidget* t = new StaticTextWidget(boss, font, xpos, ypos, + font.getStringWidth("Harmony Flash: "), + myFontHeight, "Harmony Flash: ", kTextAlignLeft); + + xpos += t->getWidth() + 4; + myFlashErase = + new ButtonWidget(boss, font, xpos, ypos-4, bwidth, myButtonHeight, + "Erase", kFlashErase); + myFlashErase->setTarget(this); + addFocusWidget(myFlashErase); + xpos += myFlashErase->getWidth() + 8; + + myFlashLoad = + new ButtonWidget(boss, font, xpos, ypos-4, bwidth, myButtonHeight, + "Load", kFlashLoad); + myFlashLoad->setTarget(this); + addFocusWidget(myFlashLoad); + xpos += myFlashLoad->getWidth() + 8; + + myFlashSave = + new ButtonWidget(boss, font, xpos, ypos-4, bwidth, myButtonHeight, + "Save", kFlashSave); + myFlashSave->setTarget(this); + addFocusWidget(myFlashSave); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -82,11 +109,25 @@ void CartridgeFA2Widget::loadConfig() void CartridgeFA2Widget::handleCommand(CommandSender* sender, int cmd, int data, int id) { - if(cmd == kBankChanged) + switch(cmd) { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); + case kBankChanged: + myCart.unlockBank(); + myCart.bank(myBank->getSelected()); + myCart.lockBank(); + invalidate(); + break; + + case kFlashErase: + myCart.flash(0); + break; + + case kFlashLoad: + myCart.flash(1); + break; + + case kFlashSave: + myCart.flash(2); + break; } } diff --git a/src/debugger/gui/CartFA2Widget.hxx b/src/debugger/gui/CartFA2Widget.hxx index a6111dfb3..be22aaee9 100644 --- a/src/debugger/gui/CartFA2Widget.hxx +++ b/src/debugger/gui/CartFA2Widget.hxx @@ -21,6 +21,7 @@ #define CARTRIDGEFA2_WIDGET_HXX class CartridgeFA2; +class ButtonWidget; class PopUpWidget; #include "CartDebugWidget.hxx" @@ -39,8 +40,14 @@ class CartridgeFA2Widget : public CartDebugWidget private: CartridgeFA2& myCart; PopUpWidget* myBank; + ButtonWidget *myFlashErase, *myFlashLoad, *myFlashSave; - enum { kBankChanged = 'bkCH' }; + enum { + kBankChanged = 'bkCH', + kFlashErase = 'flER', + kFlashLoad = 'flLD', + kFlashSave = 'flSV' + }; }; #endif diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 163348586..ce634a591 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -432,3 +432,47 @@ uInt8 CartridgeFA2::ramReadWrite() return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40; } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeFA2::flash(uInt8 operation) +{ + Serializer serializer(myFlashFile); + if(serializer.isValid()) + { + if(operation == 0) // erase + { + try + { + uInt8 buf[256]; + memset(buf, 0, 256); + serializer.putByteArray(buf, 256); + } + catch(...) + { + } + } + else if(operation == 1) // read + { + try + { + serializer.getByteArray(myRAM, 256); + } + catch(...) + { + memset(myRAM, 0, 256); + } + } + else if(operation == 2) // write + { + try + { + serializer.putByteArray(myRAM, 256); + } + catch(...) + { + // Maybe add logging here that save failed? + cerr << name() << ": ERROR saving score table" << endl; + } + } + } +} diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index 9d47506f1..c30f88b67 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -180,6 +180,15 @@ class CartridgeFA2 : public Cartridge */ uInt8 ramReadWrite(); + /** + Modify Harmony flash directly (represented by a file in emulation), + ignoring any timing emulation. This is for use strictly in the + debugger, so you can have low-level access to the Flash media. + + @param operation 0 for erase, 1 for read, 2 for write + */ + void flash(uInt8 operation); + private: // OSsytem currently in use const OSystem& myOSystem;