Internal Ram revamped
I decided to revamp my enhancement to Stella to make it easier to implement Internal RAM for additional cartridge types. In my original enhancement you needed to add 2 additional source files for each cartridge type. The 2 files would derive a new class from the base class CartRamWidget:
-
base class file
- CartRamWidget.hxx
-
DPC Plus class files
- CartRamDPCPlusWidget.cxx
- CartRamDPCPlusWidget.hxx
-
F8SC class files
- CartRamF8SCWidget.cxx
- CartRamF8SCWidget.hxx
-
etc.
- CartRam_etc_Widget.cxx
- CartRam_etc_Widget.hxx
Note: Only cartridge types with internal RAM need those files, so files like Cart4KWidget.cxx and Cart4KWidget.hxx (for 4K games) would never be needed.
In the new routines there's just the CartRamWidget class (now using 2 files):
- CartRamWidget.cxx
- CartRamWidget.hxx
The existing CartDebugWidget base class was updated with 6 additional functions:
virtual bool internalRam() { return false; } virtual int internalRamSize() { return 0; } virtual string internalRamDescription(){ return ""; } virtual ByteArray internalRamOld(int start, int count) { ByteArray ba; return ba; } virtual ByteArray internalRamCurrent(int start, int count) { ByteArray ba; return ba; } virtual void internalRamSetValue(int addr, uInt8 value) { };
Each type of cartridge has a derived class from CartDebugWidget, such as CartDPCPlusWidget for DPC+ and CartF8SCWidget for 8K with Super Chip RAM. If a cartridge does not have extra RAM, nothing needs to be done because the default internalRam() function returns false. For cartridges with extra RAM, they just need to add those 6 functions and the RAM will automatically show up in Stella's Debug Window. For DPC+ those functions are:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDPCPlusWidget::internalRam() { return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int CartridgeDPCPlusWidget::internalRamSize() { return 5*1024; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartridgeDPCPlusWidget::internalRamDescription() { ostringstream desc; desc << "0000-0FFF - 4K display data\n" << " indirectly accessible to 6507\n" << " via DPC+'s Data Fetcher registers\n" << "1000-13FF - 1K frequency table,\n" << " C variables and C stack\n" << " not accessible to 6507"; return desc.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ByteArray CartridgeDPCPlusWidget::internalRamOld(int start, int count) { ByteArray ram; ram.clear(); for (int i = 0;i<count;i++) ram.push_back(myOldState.internalram[start + i]); return ram; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ByteArray CartridgeDPCPlusWidget::internalRamCurrent(int start, int count) { ByteArray ram; ram.clear(); for (int i = 0;i<count;i++) ram.push_back(myCart.myDisplayImage[start + i]); return ram; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeDPCPlusWidget::internalRamSetValue(int addr, uInt8 value) { myCart.myDisplayImage[addr] = value; }
Here's an example of hacking the score to ABCDEF in Frantic:
New score (look at the TIA Display in top-left)
The new CartRamWidget can also handle RAM quantities of less than 256. It does that by shrinking the RAM grid:
There's plenty more to do, but I'm quite happy with the results so far.
- 1
2 Comments
Recommended Comments