mirror of https://github.com/stella-emu/stella.git
E7 bankswitching classes refactored
E78K bankswitching added
This commit is contained in:
parent
bcc2f3a463
commit
053b79fc3e
|
@ -15,27 +15,16 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "CartE7.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartMNetwork.hxx"
|
||||
#include "CartE7Widget.hxx"
|
||||
|
||||
static const char* const spot_lower[] = {
|
||||
"0 - ROM ($FFE0)", "1 - ROM ($FFE1)", "2 - ROM ($FFE2)", "3 - ROM ($FFE3)",
|
||||
"4 - ROM ($FFE4)", "5 - ROM ($FFE5)", "6 - ROM ($FFE6)", "7 - RAM ($FFE7)"
|
||||
};
|
||||
static const char* const spot_upper[] = {
|
||||
"0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)"
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeE7Widget::CartridgeE7Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeE7& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h,
|
||||
CartridgeMNetwork& cart)
|
||||
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 8 * 2048;
|
||||
|
||||
ostringstream info;
|
||||
info << "E7 cartridge, 8 2K slices ROM + 2 1K RAM\n"
|
||||
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
||||
|
@ -55,136 +44,27 @@ CartridgeE7Widget::CartridgeE7Widget(
|
|||
start -= start % 0x1000;
|
||||
info << "Bank RORG" << " = $" << HEX4 << start << "\n";
|
||||
#endif
|
||||
int xpos = 10,
|
||||
ypos = addBaseInformation(size, "M-Network", info.str(), 15) +
|
||||
myLineHeight;
|
||||
|
||||
VariantList items0, items1;
|
||||
for(int i = 0; i < 8; ++i)
|
||||
VarList::push_back(items0, spot_lower[i]);
|
||||
for(int i = 0; i < 4; ++i)
|
||||
VarList::push_back(items1, spot_upper[i]);
|
||||
|
||||
const int lwidth = _font.getStringWidth("Set slice for upper 256B "),
|
||||
fwidth = _font.getStringWidth("3 - RAM ($FFEB)");
|
||||
myLower2K =
|
||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight, items0,
|
||||
"Set slice for lower 2K ", lwidth, kLowerChanged);
|
||||
myLower2K->setTarget(this);
|
||||
addFocusWidget(myLower2K);
|
||||
ypos += myLower2K->getHeight() + 4;
|
||||
|
||||
myUpper256B =
|
||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight, items1,
|
||||
"Set slice for upper 256B ", lwidth, kUpperChanged);
|
||||
myUpper256B->setTarget(this);
|
||||
addFocusWidget(myUpper256B);
|
||||
initialize(boss, cart, info);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7Widget::saveOldState()
|
||||
const char* CartridgeE7Widget::getSpotLower(int idx)
|
||||
{
|
||||
myOldState.internalram.clear();
|
||||
static const char* const spot_lower[] = {
|
||||
"0 - ROM ($FFE0)", "1 - ROM ($FFE1)", "2 - ROM ($FFE2)", "3 - ROM ($FFE3)",
|
||||
"4 - ROM ($FFE4)", "5 - ROM ($FFE5)", "6 - ROM ($FFE6)", "7 - RAM ($FFE7)"
|
||||
};
|
||||
|
||||
for(uInt32 i = 0; i < this->internalRamSize();i++)
|
||||
{
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
}
|
||||
return spot_lower[idx];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7Widget::loadConfig()
|
||||
const char* CartridgeE7Widget::getSpotUpper(int idx)
|
||||
{
|
||||
myLower2K->setSelectedIndex(myCart.myCurrentSlice[0]);
|
||||
myUpper256B->setSelectedIndex(myCart.myCurrentRAM);
|
||||
static const char* const spot_upper[] = {
|
||||
"0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)"
|
||||
};
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7Widget::handleCommand(CommandSender* sender,
|
||||
int cmd, int data, int id)
|
||||
{
|
||||
myCart.unlockBank();
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case kLowerChanged:
|
||||
myCart.bank(myLower2K->getSelected());
|
||||
break;
|
||||
case kUpperChanged:
|
||||
myCart.bankRAM(myUpper256B->getSelected());
|
||||
break;
|
||||
}
|
||||
|
||||
myCart.lockBank();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeE7Widget::bankState()
|
||||
{
|
||||
ostringstream& buf = buffer();
|
||||
|
||||
buf << "Slices: " << std::dec
|
||||
<< spot_lower[myCart.myCurrentSlice[0]] << " / "
|
||||
<< spot_upper[myCart.myCurrentRAM];
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeE7Widget::internalRamSize()
|
||||
{
|
||||
return 2048;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeE7Widget::internalRamRPort(int start)
|
||||
{
|
||||
return 0x0000 + start;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeE7Widget::internalRamDescription()
|
||||
{
|
||||
ostringstream desc;
|
||||
desc << "First 1K accessible via:\n"
|
||||
<< " $F000 - $F3FF used for Write Access\n"
|
||||
<< " $F400 - $F7FF used for Read Access\n"
|
||||
<< "256K of second 1K accessible via:\n"
|
||||
<< " $F800 - $F8FF used for Write Access\n"
|
||||
<< " $F900 - $F9FF used for Read Access" ;
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const ByteArray& CartridgeE7Widget::internalRamOld(int start, int count)
|
||||
{
|
||||
myRamOld.clear();
|
||||
for(int i = 0; i < count; i++)
|
||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
||||
return myRamOld;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const ByteArray& CartridgeE7Widget::internalRamCurrent(int start, int count)
|
||||
{
|
||||
myRamCurrent.clear();
|
||||
for(int i = 0; i < count; i++)
|
||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||
return myRamCurrent;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7Widget::internalRamSetValue(int addr, uInt8 value)
|
||||
{
|
||||
myCart.myRAM[addr] = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeE7Widget::internalRamGetValue(int addr)
|
||||
{
|
||||
return myCart.myRAM[addr];
|
||||
return spot_upper[idx];
|
||||
}
|
||||
|
|
|
@ -18,51 +18,22 @@
|
|||
#ifndef CARTRIDGEE7_WIDGET_HXX
|
||||
#define CARTRIDGEE7_WIDGET_HXX
|
||||
|
||||
class CartridgeE7;
|
||||
class PopUpWidget;
|
||||
#include "CartMNetworkWidget.hxx"
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
|
||||
class CartridgeE7Widget : public CartDebugWidget
|
||||
class CartridgeE7Widget : public CartridgeMNetworkWidget
|
||||
{
|
||||
public:
|
||||
CartridgeE7Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
const GUI::Font& nfont,
|
||||
int x, int y, int w, int h,
|
||||
CartridgeE7& cart);
|
||||
CartridgeMNetwork& cart);
|
||||
virtual ~CartridgeE7Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeE7& myCart;
|
||||
PopUpWidget *myLower2K, *myUpper256B;
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum {
|
||||
kLowerChanged = 'lwCH',
|
||||
kUpperChanged = 'upCH'
|
||||
};
|
||||
protected:
|
||||
const char* getSpotLower(int idx);
|
||||
const char* getSpotUpper(int idx);
|
||||
|
||||
private:
|
||||
void saveOldState() override;
|
||||
void loadConfig() override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
string bankState() override;
|
||||
|
||||
// start of functions for Cartridge RAM tab
|
||||
uInt32 internalRamSize() override;
|
||||
uInt32 internalRamRPort(int start) override;
|
||||
string internalRamDescription() override;
|
||||
const ByteArray& internalRamOld(int start, int count) override;
|
||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
||||
void internalRamSetValue(int addr, uInt8 value) override;
|
||||
uInt8 internalRamGetValue(int addr) override;
|
||||
// end of functions for Cartridge RAM tab
|
||||
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeE7Widget() = delete;
|
||||
CartridgeE7Widget(const CartridgeE7Widget&) = delete;
|
||||
|
|
|
@ -29,7 +29,9 @@ MODULE_OBJS := \
|
|||
src/debugger/gui/CartDPCPlusWidget.o \
|
||||
src/debugger/gui/CartDPCWidget.o \
|
||||
src/debugger/gui/CartE0Widget.o \
|
||||
src/debugger/gui/CartMNetworkWidget.o \
|
||||
src/debugger/gui/CartE7Widget.o \
|
||||
src/debugger/gui/CartE78KWidget.o \
|
||||
src/debugger/gui/CartEFSCWidget.o \
|
||||
src/debugger/gui/CartEFWidget.o \
|
||||
src/debugger/gui/CartF0Widget.o \
|
||||
|
|
|
@ -26,9 +26,10 @@ enum class BSType {
|
|||
_64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50,
|
||||
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF,
|
||||
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
|
||||
_DPC, _DPCP, _E0, _E7, _EF, _EFSC, _F0,
|
||||
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
|
||||
_FA2, _FE, _MDM, _SB, _UA, _WD, _X07,
|
||||
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
|
||||
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
|
||||
_FA, _FA2, _FE, _MDM, _SB, _UA, _WD,
|
||||
_X07,
|
||||
#ifdef CUSTOM_ARM
|
||||
_CUSTOM,
|
||||
#endif
|
||||
|
@ -75,6 +76,7 @@ static BSDescription BSList[int(BSType::NumSchemes)] = {
|
|||
{ "DPC+", "DPC+ (Enhanced DPC)" },
|
||||
{ "E0", "E0 (8K Parker Bros)" },
|
||||
{ "E7", "E7 (16K M-network)" },
|
||||
{ "E78K", "E78K (8K M-network)" },
|
||||
{ "EF", "EF (64K H. Runner)" },
|
||||
{ "EFSC", "EFSC (64K H. Runner + ram)" },
|
||||
{ "F0", "F0 (Dynacom Megaboy)" },
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "CartDPCPlus.hxx"
|
||||
#include "CartE0.hxx"
|
||||
#include "CartE7.hxx"
|
||||
#include "CartE78K.hxx"
|
||||
#include "CartEF.hxx"
|
||||
#include "CartEFSC.hxx"
|
||||
#include "CartBF.hxx"
|
||||
|
@ -277,6 +278,8 @@ CartDetector::createFromImage(const BytePtr& image, uInt32 size, BSType type,
|
|||
return make_unique<CartridgeE0>(image, size, osystem.settings());
|
||||
case BSType::_E7:
|
||||
return make_unique<CartridgeE7>(image, size, osystem.settings());
|
||||
case BSType::_E78K:
|
||||
return make_unique<CartridgeE78K>(image, size, osystem.settings());
|
||||
case BSType::_EF:
|
||||
return make_unique<CartridgeEF>(image, size, osystem.settings());
|
||||
case BSType::_EFSC:
|
||||
|
@ -378,6 +381,8 @@ BSType CartDetector::autodetectType(const BytePtr& image, uInt32 size)
|
|||
type = BSType::_FE;
|
||||
else if(isProbably0840(image, size))
|
||||
type = BSType::_0840;
|
||||
else if(isProbablyE78K(image, size))
|
||||
type = BSType::_E78K;
|
||||
else
|
||||
type = BSType::_F8;
|
||||
}
|
||||
|
@ -749,6 +754,27 @@ bool CartDetector::isProbablyE7(const BytePtr& image, uInt32 size)
|
|||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDetector::isProbablyE78K(const BytePtr& image, uInt32 size)
|
||||
{
|
||||
// E7 cart bankswitching is triggered by accessing addresses
|
||||
// $FE0 to $FE6 using absolute non-indexed addressing
|
||||
// To eliminate false positives (and speed up processing), we
|
||||
// search for only certain known signatures
|
||||
// Thanks to "stella@casperkitty.com" for this advice
|
||||
// These signatures are attributed to the MESS project
|
||||
uInt8 signature[3][3] = {
|
||||
{ 0xAD, 0xE4, 0xFF }, // LDA $FFE4
|
||||
{ 0xAD, 0xE5, 0xFF }, // LDA $FFE5
|
||||
{ 0xAD, 0xE6, 0x1F }, // LDA $1FE6
|
||||
};
|
||||
for(uInt32 i = 0; i < 3; ++i)
|
||||
if(searchForBytes(image.get(), size, signature[i], 3, 1))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type)
|
||||
{
|
||||
|
|
|
@ -204,6 +204,11 @@ class CartDetector
|
|||
*/
|
||||
static bool isProbablyE7(const BytePtr& image, uInt32 size);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably a E78K bankswitching cartridge
|
||||
*/
|
||||
static bool isProbablyE78K(const BytePtr& image, uInt32 size);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably an EF/EFSC bankswitching cartridge
|
||||
*/
|
||||
|
@ -212,7 +217,7 @@ class CartDetector
|
|||
/**
|
||||
Returns true if the image is probably an F6 bankswitching cartridge
|
||||
*/
|
||||
static bool isProbablyF6(const BytePtr& image, uInt32 size);
|
||||
//static bool isProbablyF6(const BytePtr& image, uInt32 size);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably an FA2 bankswitching cartridge
|
||||
|
|
|
@ -21,65 +21,14 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeE7::CartridgeE7(const BytePtr& image, uInt32 size,
|
||||
const Settings& settings)
|
||||
: Cartridge(settings),
|
||||
myCurrentRAM(0)
|
||||
: CartridgeMNetwork(image, size, settings)
|
||||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image.get(), std::min(16384u, size));
|
||||
createCodeAccessBase(16384 + 2048);
|
||||
|
||||
// Remember startup bank
|
||||
myStartBank = 0;
|
||||
initialize(image, size);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7::reset()
|
||||
void CartridgeE7::checkSwitchBank(uInt16 address)
|
||||
{
|
||||
initializeRAM(myRAM, 2048);
|
||||
|
||||
// Install some default banks for the RAM and first segment
|
||||
bankRAM(0);
|
||||
bank(myStartBank);
|
||||
|
||||
myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7::install(System& system)
|
||||
{
|
||||
mySystem = &system;
|
||||
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000;
|
||||
addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.codeAccessBase = &myCodeAccessBase[8128];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
for(uInt16 addr = 0x1A00; addr < (0x1FE0U & ~System::PAGE_MASK);
|
||||
addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myImage[7 * 2048 + (addr & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[7 * 2048 + (addr & 0x07FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
myCurrentSlice[1] = 7;
|
||||
|
||||
// Install some default banks for the RAM and first segment
|
||||
bankRAM(0);
|
||||
bank(myStartBank);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeE7::peek(uInt16 address)
|
||||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
if((address >= 0x0FE0) && (address <= 0x0FE7))
|
||||
{
|
||||
|
@ -89,141 +38,6 @@ uInt8 CartridgeE7::peek(uInt16 address)
|
|||
{
|
||||
bankRAM(address & 0x0003);
|
||||
}
|
||||
|
||||
if((myCurrentSlice[0] == 7) && (address < 0x0400))
|
||||
{
|
||||
// Reading from the 1K write port @ $1000 triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return myRAM[address & 0x03FF] = value;
|
||||
}
|
||||
}
|
||||
else if((address >= 0x0800) && (address <= 0x08FF))
|
||||
{
|
||||
// Reading from the 256B write port @ $1800 triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return myRAM[1024 + (myCurrentRAM << 8) + (address & 0x00FF)] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeE7::poke(uInt16 address, uInt8)
|
||||
{
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
if((address >= 0x0FE0) && (address <= 0x0FE7))
|
||||
{
|
||||
bank(address & 0x0007);
|
||||
}
|
||||
else if((address >= 0x0FE8) && (address <= 0x0FEB))
|
||||
{
|
||||
bankRAM(address & 0x0003);
|
||||
}
|
||||
|
||||
// NOTE: This does not handle writing to RAM, however, this
|
||||
// method should never be called for RAM because of the
|
||||
// way page accessing has been setup
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7::bankRAM(uInt16 bank)
|
||||
{
|
||||
if(bankLocked()) return;
|
||||
|
||||
// Remember what bank we're in
|
||||
myCurrentRAM = bank;
|
||||
uInt16 offset = bank << 8;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access(this, System::PA_WRITE);
|
||||
|
||||
// Set the page accessing method for the 256 bytes of RAM writing pages
|
||||
for(uInt16 addr = 0x1800; addr < 0x1900; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[1024 + offset + (addr & 0x00FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (addr & 0x00FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the 256 bytes of RAM reading pages
|
||||
access.directPokeBase = nullptr;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt16 addr = 0x1900; addr < 0x1A00; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myRAM[1024 + offset + (addr & 0x00FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (addr & 0x00FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeE7::bank(uInt16 slice)
|
||||
{
|
||||
if(bankLocked()) return false;
|
||||
|
||||
// Remember what bank we're in
|
||||
myCurrentSlice[0] = slice;
|
||||
uInt16 offset = slice << 11;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
if(slice != 7)
|
||||
{
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
// Map ROM image into first segment
|
||||
for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (addr & 0x07FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (addr & 0x07FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System::PageAccess access(this, System::PA_WRITE);
|
||||
|
||||
// Set the page accessing method for the 1K slice of RAM writing pages
|
||||
for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPokeBase = &myRAM[addr & 0x03FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[8192 + (addr & 0x03FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the 1K slice of RAM reading pages
|
||||
access.directPokeBase = nullptr;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myRAM[addr & 0x03FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[8192 + (addr & 0x03FF)];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeE7::getBank() const
|
||||
{
|
||||
return myCurrentSlice[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -231,84 +45,3 @@ uInt16 CartridgeE7::bankCount() const
|
|||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeE7::patch(uInt16 address, uInt8 value)
|
||||
{
|
||||
address = address & 0x0FFF;
|
||||
|
||||
if(address < 0x0800)
|
||||
{
|
||||
if(myCurrentSlice[0] == 7)
|
||||
{
|
||||
// Normally, a write to the read port won't do anything
|
||||
// However, the patch command is special in that ignores such
|
||||
// cart restrictions
|
||||
myRAM[address & 0x03FF] = value;
|
||||
}
|
||||
else
|
||||
myImage[(myCurrentSlice[0] << 11) + (address & 0x07FF)] = value;
|
||||
}
|
||||
else if(address < 0x0900)
|
||||
{
|
||||
// Normally, a write to the read port won't do anything
|
||||
// However, the patch command is special in that ignores such
|
||||
// cart restrictions
|
||||
myRAM[1024 + (myCurrentRAM << 8) + (address & 0x00FF)] = value;
|
||||
}
|
||||
else
|
||||
myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)] = value;
|
||||
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt8* CartridgeE7::getImage(uInt32& size) const
|
||||
{
|
||||
size = 16384;
|
||||
return myImage;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeE7::save(Serializer& out) const
|
||||
{
|
||||
try
|
||||
{
|
||||
out.putString(name());
|
||||
out.putShortArray(myCurrentSlice, 2);
|
||||
out.putShort(myCurrentRAM);
|
||||
out.putByteArray(myRAM, 2048);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: CartridgeE7::save" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeE7::load(Serializer& in)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(in.getString() != name())
|
||||
return false;
|
||||
|
||||
in.getShortArray(myCurrentSlice, 2);
|
||||
myCurrentRAM = in.getShort();
|
||||
in.getByteArray(myRAM, 2048);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: CartridgeE7::load" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up the previously used banks for the RAM and segment
|
||||
bankRAM(myCurrentRAM);
|
||||
bank(myCurrentSlice[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,43 +25,15 @@ class System;
|
|||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "CartE7Widget.hxx"
|
||||
#endif
|
||||
#include "CartMNetwork.hxx"
|
||||
|
||||
/**
|
||||
This is the cartridge class for M-Network bankswitched games.
|
||||
In this bankswitching scheme the 2600's 4K cartridge address
|
||||
space is broken into two 2K segments.
|
||||
This is the cartridge class for 16K M-Network bankswitched games.
|
||||
|
||||
Kevin Horton describes E7 as follows:
|
||||
|
||||
Only M-Network used this scheme. This has to be the
|
||||
most complex method used in any cart! :-) It allows
|
||||
for the capability of 2K of RAM; although it doesn't
|
||||
have to be used (in fact, only one cart used it).
|
||||
There are now 8 2K banks, instead of 4. The last 2K
|
||||
in the cart always points to the last 2K of the ROM
|
||||
image, while the first 2K is selectable. You access
|
||||
1FE0 to 1FE6 to select which 2K bank. Note that you
|
||||
cannot select the last 2K of the ROM image into the
|
||||
lower 2K of the cart! Accessing 1FE7 selects 1K of
|
||||
RAM at 1000-17FF instead of ROM! The 2K of RAM is
|
||||
broken up into two 1K sections. One 1K section is
|
||||
mapped in at 1000-17FF if 1FE7 has been accessed.
|
||||
1000-13FF is the write port, while 1400-17FF is the
|
||||
read port. The second 1K of RAM appears at 1800-19FF.
|
||||
1800-18FF is the write port while 1900-19FF is the
|
||||
read port. You select which 256 byte block appears
|
||||
here by accessing 1FE8 to 1FEB.
|
||||
|
||||
This cart reports having 8 banks; 1 for each of the possible 7
|
||||
slices in the lower 2K area, and the last for RAM in the lower
|
||||
2K area.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@author Bradford W. Mott, Thomas Jentzsch
|
||||
*/
|
||||
class CartridgeE7 : public Cartridge
|
||||
class CartridgeE7 : public CartridgeMNetwork
|
||||
{
|
||||
friend class CartridgeE7Widget;
|
||||
|
||||
public:
|
||||
/**
|
||||
Create a new cartridge using the specified image
|
||||
|
@ -74,69 +46,11 @@ class CartridgeE7 : public Cartridge
|
|||
virtual ~CartridgeE7() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device to its power-on state
|
||||
*/
|
||||
void reset() override;
|
||||
|
||||
/**
|
||||
Install cartridge in the specified system. Invoked by the system
|
||||
when the cartridge is attached to it.
|
||||
|
||||
@param system The system the device should install itself in
|
||||
*/
|
||||
void install(System& system) override;
|
||||
|
||||
/**
|
||||
Install pages for the specified bank in the system.
|
||||
|
||||
@param bank The bank that should be installed in the system
|
||||
*/
|
||||
bool bank(uInt16 bank) override;
|
||||
|
||||
/**
|
||||
Get the current bank.
|
||||
*/
|
||||
uInt16 getBank() const override;
|
||||
|
||||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
||||
@param address The ROM address to patch
|
||||
@param value The value to place into the address
|
||||
@return Success or failure of the patch operation
|
||||
*/
|
||||
bool patch(uInt16 address, uInt8 value) override;
|
||||
|
||||
/**
|
||||
Access the internal ROM image for this cartridge.
|
||||
|
||||
@param size Set to the size of the internal ROM image data
|
||||
@return A pointer to the internal ROM image data
|
||||
*/
|
||||
const uInt8* getImage(uInt32& size) const override;
|
||||
|
||||
/**
|
||||
Save the current state of this cart to the given Serializer.
|
||||
|
||||
@param out The Serializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool save(Serializer& out) const override;
|
||||
|
||||
/**
|
||||
Load the current state of this cart from the given Serializer.
|
||||
|
||||
@param in The Serializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool load(Serializer& in) override;
|
||||
|
||||
/**
|
||||
Get a descriptor for the device name (used in error checking).
|
||||
|
||||
|
@ -156,43 +70,11 @@ class CartridgeE7 : public Cartridge
|
|||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the byte at the specified address.
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
uInt8 peek(uInt16 address) override;
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
@return True if the poke changed the device address space, else false
|
||||
*/
|
||||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
Install pages for the specified 256 byte bank of RAM
|
||||
|
||||
@param bank The bank that should be installed in the system
|
||||
Check hotspots and switch bank if triggered.
|
||||
*/
|
||||
void bankRAM(uInt16 bank);
|
||||
|
||||
private:
|
||||
// The 16K ROM image of the cartridge
|
||||
uInt8 myImage[16384];
|
||||
|
||||
// The 2048 bytes of RAM
|
||||
uInt8 myRAM[2048];
|
||||
|
||||
// Indicates which slice is in the segment
|
||||
uInt16 myCurrentSlice[2];
|
||||
|
||||
// Indicates which 256 byte bank of RAM is being used
|
||||
uInt16 myCurrentRAM;
|
||||
void checkSwitchBank(uInt16 address) override;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -24,7 +24,9 @@ MODULE_OBJS := \
|
|||
src/emucore/CartDPC.o \
|
||||
src/emucore/CartDPCPlus.o \
|
||||
src/emucore/CartE0.o \
|
||||
src/emucore/CartMNetwork.o \
|
||||
src/emucore/CartE7.o \
|
||||
src/emucore/CartE78K.o \
|
||||
src/emucore/CartEF.o \
|
||||
src/emucore/CartEFSC.o \
|
||||
src/emucore/CartBF.o \
|
||||
|
|
|
@ -268,6 +268,7 @@
|
|||
<ClCompile Include="..\debugger\gui\CartDPCPlusWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartDPCWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartE0Widget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartE78KWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartE7Widget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartEFSCWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartEFWidget.cxx" />
|
||||
|
@ -282,6 +283,7 @@
|
|||
<ClCompile Include="..\debugger\gui\CartFAWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartFEWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartMDMWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartMNetworkWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartRamWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartSBWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\CartUAWidget.cxx" />
|
||||
|
@ -314,6 +316,8 @@
|
|||
<ClCompile Include="..\emucore\CartDFSC.cxx" />
|
||||
<ClCompile Include="..\emucore\CartFA2.cxx" />
|
||||
<ClCompile Include="..\emucore\CartMDM.cxx" />
|
||||
<ClCompile Include="..\emucore\CartMNetwork.cxx" />
|
||||
<ClCompile Include="..\emucore\CartE78K.cxx" />
|
||||
<ClCompile Include="..\emucore\CartWD.cxx" />
|
||||
<ClCompile Include="..\emucore\CompuMate.cxx" />
|
||||
<ClCompile Include="..\emucore\EventJoyHandler.cxx" />
|
||||
|
@ -549,6 +553,7 @@
|
|||
<ClInclude Include="..\debugger\gui\CartDPCPlusWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartDPCWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartE0Widget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartE78KWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartE7Widget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartEFSCWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartEFWidget.hxx" />
|
||||
|
@ -563,6 +568,7 @@
|
|||
<ClInclude Include="..\debugger\gui\CartFAWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartFEWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartMDMWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartMNetworkWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartRamWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartSBWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\CartUAWidget.hxx" />
|
||||
|
@ -602,6 +608,8 @@
|
|||
<ClInclude Include="..\emucore\CartDFSC.hxx" />
|
||||
<ClInclude Include="..\emucore\CartFA2.hxx" />
|
||||
<ClInclude Include="..\emucore\CartMDM.hxx" />
|
||||
<ClInclude Include="..\emucore\CartMNetwork.hxx" />
|
||||
<ClInclude Include="..\emucore\CartE78K.hxx" />
|
||||
<ClInclude Include="..\emucore\CartWD.hxx" />
|
||||
<ClInclude Include="..\emucore\CompuMate.hxx" />
|
||||
<ClInclude Include="..\emucore\EventHandlerConstants.hxx" />
|
||||
|
|
|
@ -873,6 +873,18 @@
|
|||
<ClCompile Include="..\gui\RadioButtonWidget.cxx">
|
||||
<Filter>Source Files\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\emucore\CartMNetwork.cxx">
|
||||
<Filter>Source Files\emucore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\emucore\CartE78K.cxx">
|
||||
<Filter>Source Files\emucore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\debugger\gui\CartMNetworkWidget.cxx">
|
||||
<Filter>Source Files\debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\debugger\gui\CartE78KWidget.cxx">
|
||||
<Filter>Source Files\debugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\bspf.hxx">
|
||||
|
@ -1784,6 +1796,18 @@
|
|||
<ClInclude Include="..\emucore\FrameBufferConstants.hxx">
|
||||
<Filter>Header Files\emucore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\emucore\CartMNetwork.hxx">
|
||||
<Filter>Header Files\emucore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\emucore\CartE78K.hxx">
|
||||
<Filter>Header Files\emucore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\debugger\gui\CartMNetworkWidget.hxx">
|
||||
<Filter>Header Files\debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\debugger\gui\CartE78KWidget.hxx">
|
||||
<Filter>Header Files\debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="stella.ico">
|
||||
|
|
Loading…
Reference in New Issue