mirror of https://github.com/stella-emu/stella.git
add RAM bank support to CartEnhanced
refactor Cart3E differentiate between ROM and RAM banks (TODO: check debugger)
This commit is contained in:
parent
ca5b6a6fe7
commit
00e67f1a51
|
@ -72,12 +72,18 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
|
|||
|
||||
// Create bank information for each potential bank, and an extra one for ZP RAM
|
||||
BankInfo info;
|
||||
for(uInt32 i = 0; i < myConsole.cartridge().bankCount(); ++i)
|
||||
for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i)
|
||||
{
|
||||
info.size = myConsole.cartridge().bankSize(i);
|
||||
myBankInfo.push_back(info);
|
||||
}
|
||||
|
||||
for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i)
|
||||
{
|
||||
info.size = myConsole.cartridge().bankSize(i) >> 1;
|
||||
myBankInfo.push_back(info);
|
||||
}
|
||||
|
||||
info.size = 128; // ZP RAM
|
||||
myBankInfo.push_back(info);
|
||||
|
||||
|
@ -235,9 +241,10 @@ string CartDebug::toString()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartDebug::disassemble(bool force)
|
||||
bool CartDebug::disassemblePC(bool force)
|
||||
{
|
||||
uInt16 PC = myDebugger.cpuDebug().pc();
|
||||
// ROM/RAM bank or ZP-RAM?
|
||||
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
|
||||
|
||||
return disassemble(bank, PC, force);
|
||||
|
@ -414,7 +421,7 @@ bool CartDebug::addDirective(Device::AccessType type,
|
|||
bank = (myDebugger.cpuDebug().pc() & 0x1000) ?
|
||||
getBank(myDebugger.cpuDebug().pc()) : int(myBankInfo.size())-1;
|
||||
|
||||
bank = std::min(bank, bankCount());
|
||||
bank = std::min(bank, romBankCount());
|
||||
BankInfo& info = myBankInfo[bank];
|
||||
DirectiveList& list = info.directiveList;
|
||||
|
||||
|
@ -546,9 +553,9 @@ int CartDebug::getPCBank()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int CartDebug::bankCount() const
|
||||
int CartDebug::romBankCount() const
|
||||
{
|
||||
return myConsole.cartridge().bankCount();
|
||||
return myConsole.cartridge().romBankCount();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -955,7 +962,7 @@ string CartDebug::loadConfigFile()
|
|||
myDebugger.rom().invalidate();
|
||||
|
||||
stringstream retVal;
|
||||
if(myConsole.cartridge().bankCount() > 1)
|
||||
if(myConsole.cartridge().romBankCount() > 1)
|
||||
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
||||
retVal << "config file '" << node.getShortPath() << "' loaded OK";
|
||||
return retVal.str();
|
||||
|
@ -990,14 +997,14 @@ string CartDebug::saveConfigFile()
|
|||
out << "// Stella.pro: \"" << name << "\"" << endl
|
||||
<< "// MD5: " << md5 << endl
|
||||
<< endl;
|
||||
for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b)
|
||||
for(uInt32 b = 0; b < myConsole.cartridge().romBankCount(); ++b)
|
||||
{
|
||||
out << "[" << b << "]" << endl;
|
||||
getBankDirectives(out, myBankInfo[b]);
|
||||
}
|
||||
|
||||
stringstream retVal;
|
||||
if(myConsole.cartridge().bankCount() > 1)
|
||||
if(myConsole.cartridge().romBankCount() > 1)
|
||||
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
||||
retVal << "config file '" << cfg.getShortPath() << "' saved OK";
|
||||
return retVal.str();
|
||||
|
@ -1058,14 +1065,14 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
Disassembly disasm;
|
||||
disasm.list.reserve(2048);
|
||||
uInt16 bankCount = myConsole.cartridge().bankCount();
|
||||
uInt16 romBankCount = myConsole.cartridge().romBankCount();
|
||||
uInt16 oldBank = myConsole.cartridge().getBank();
|
||||
|
||||
// prepare for switching banks
|
||||
myConsole.cartridge().unlockBank();
|
||||
uInt32 origin = 0;
|
||||
|
||||
for(int bank = 0; bank < bankCount; ++bank)
|
||||
for(int bank = 0; bank < romBankCount; ++bank)
|
||||
{
|
||||
// TODO: not every CartDebugWidget does it like that, we need a method
|
||||
myConsole.cartridge().unlockBank();
|
||||
|
@ -1082,8 +1089,8 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
buf << "\n\n;***********************************************************\n"
|
||||
<< "; Bank " << bank;
|
||||
if (bankCount > 1)
|
||||
buf << " / 0.." << bankCount - 1;
|
||||
if (romBankCount > 1)
|
||||
buf << " / 0.." << romBankCount - 1;
|
||||
buf << "\n;***********************************************************\n\n";
|
||||
|
||||
|
||||
|
@ -1097,7 +1104,7 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
buf << " SEG CODE\n";
|
||||
|
||||
if(bankCount == 1)
|
||||
if(romBankCount == 1)
|
||||
buf << " ORG $" << Base::HEX4 << info.offset << "\n\n";
|
||||
else
|
||||
buf << " ORG $" << Base::HEX4 << origin << "\n"
|
||||
|
@ -1327,7 +1334,7 @@ string CartDebug::saveDisassembly()
|
|||
out << buf.str();
|
||||
|
||||
stringstream retVal;
|
||||
if(myConsole.cartridge().bankCount() > 1)
|
||||
if(myConsole.cartridge().romBankCount() > 1)
|
||||
retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n");
|
||||
retVal << "saved " << node.getShortPath() << " OK";
|
||||
return retVal.str();
|
||||
|
@ -1367,8 +1374,8 @@ string CartDebug::saveAccessFile()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartDebug::listConfig(int bank)
|
||||
{
|
||||
uInt32 startbank = 0, endbank = bankCount();
|
||||
if(bank >= 0 && bank < bankCount())
|
||||
uInt32 startbank = 0, endbank = romBankCount();
|
||||
if(bank >= 0 && bank < romBankCount())
|
||||
{
|
||||
startbank = bank;
|
||||
endbank = startbank + 1;
|
||||
|
@ -1392,7 +1399,7 @@ string CartDebug::listConfig(int bank)
|
|||
getBankDirectives(buf, info);
|
||||
}
|
||||
|
||||
if(myConsole.cartridge().bankCount() > 1)
|
||||
if(myConsole.cartridge().romBankCount() > 1)
|
||||
buf << DebuggerParser::red("config file for multi-bank ROM not fully supported") << endl;
|
||||
|
||||
return buf.str();
|
||||
|
@ -1401,8 +1408,8 @@ string CartDebug::listConfig(int bank)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartDebug::clearConfig(int bank)
|
||||
{
|
||||
uInt32 startbank = 0, endbank = bankCount();
|
||||
if(bank >= 0 && bank < bankCount())
|
||||
uInt32 startbank = 0, endbank = romBankCount();
|
||||
if(bank >= 0 && bank < romBankCount())
|
||||
{
|
||||
startbank = bank;
|
||||
endbank = startbank + 1;
|
||||
|
|
|
@ -95,7 +95,7 @@ class CartDebug : public DebuggerSystem
|
|||
int lastWriteBaseAddress();
|
||||
|
||||
// TODO
|
||||
bool disassemble(bool force = false);
|
||||
bool disassemblePC(bool force = false);
|
||||
bool disassembleBank(int bank);
|
||||
|
||||
// First, a call is made to disassemble(), which updates the disassembly
|
||||
|
@ -159,7 +159,7 @@ class CartDebug : public DebuggerSystem
|
|||
/**
|
||||
Get the total number of banks supported by the cartridge.
|
||||
*/
|
||||
int bankCount() const;
|
||||
int romBankCount() const;
|
||||
|
||||
/**
|
||||
Add a label and associated address.
|
||||
|
|
|
@ -763,7 +763,7 @@ void DebuggerParser::executeBreak()
|
|||
{
|
||||
uInt16 addr;
|
||||
uInt8 bank;
|
||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
||||
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||
|
||||
if(argCount == 0)
|
||||
addr = debugger.cpuDebug().pc();
|
||||
|
@ -775,7 +775,7 @@ void DebuggerParser::executeBreak()
|
|||
else
|
||||
{
|
||||
bank = args[1];
|
||||
if(bank >= bankCount && bank != 0xff)
|
||||
if(bank >= romBankCount && bank != 0xff)
|
||||
{
|
||||
commandResult << red("invalid bank");
|
||||
return;
|
||||
|
@ -791,12 +791,12 @@ void DebuggerParser::executeBreak()
|
|||
commandResult << "cleared";
|
||||
|
||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||
if(bankCount > 1)
|
||||
if(romBankCount > 1)
|
||||
commandResult << " in bank #" << std::dec << int(bank);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < debugger.cartDebug().bankCount(); ++i)
|
||||
for(int i = 0; i < debugger.cartDebug().romBankCount(); ++i)
|
||||
{
|
||||
bool set = debugger.toggleBreakPoint(addr, i);
|
||||
|
||||
|
@ -809,7 +809,7 @@ void DebuggerParser::executeBreak()
|
|||
commandResult << "cleared";
|
||||
|
||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||
if(bankCount > 1)
|
||||
if(romBankCount > 1)
|
||||
commandResult << " in bank #" << std::dec << int(bank);
|
||||
}
|
||||
}
|
||||
|
@ -1459,11 +1459,11 @@ void DebuggerParser::executeListbreaks()
|
|||
{
|
||||
stringstream buf;
|
||||
int count = 0;
|
||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
||||
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||
|
||||
for(const auto& bp : debugger.breakPoints().getBreakpoints())
|
||||
{
|
||||
if(bankCount == 1)
|
||||
if(romBankCount == 1)
|
||||
{
|
||||
buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " ";
|
||||
if(!(++count % 8)) buf << endl;
|
||||
|
|
|
@ -25,8 +25,8 @@ Cartridge3EWidget::Cartridge3EWidget(
|
|||
int x, int y, int w, int h, Cartridge3E& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart),
|
||||
myNumRomBanks(uInt32(cart.mySize >> 11)),
|
||||
myNumRamBanks(32)
|
||||
myNumRomBanks(myCart.romBankCount()),
|
||||
myNumRamBanks(myCart.ramBankCount())
|
||||
{
|
||||
size_t size = cart.mySize;
|
||||
|
||||
|
@ -93,21 +93,21 @@ void Cartridge3EWidget::saveOldState()
|
|||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
|
||||
myOldState.bank = myCart.myCurrentBank;
|
||||
myOldState.bank = myCart.getBank();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EWidget::loadConfig()
|
||||
{
|
||||
if(myCart.myCurrentBank < 256)
|
||||
if(myCart.getBank() < myCart.romBankCount())
|
||||
{
|
||||
myROMBank->setSelectedIndex(myCart.myCurrentBank % myNumRomBanks, myOldState.bank != myCart.myCurrentBank);
|
||||
myRAMBank->setSelectedMax(myOldState.bank >= 256);
|
||||
myROMBank->setSelectedIndex(myCart.getBank() % myNumRomBanks, myOldState.bank != myCart.getBank());
|
||||
myRAMBank->setSelectedMax(myOldState.bank >= myCart.romBankCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
myROMBank->setSelectedMax(myOldState.bank < 256);
|
||||
myRAMBank->setSelectedIndex(myCart.myCurrentBank - 256, myOldState.bank != myCart.myCurrentBank);
|
||||
myROMBank->setSelectedMax(myOldState.bank < myCart.romBankCount());
|
||||
myRAMBank->setSelectedIndex(myCart.getBank() - myCart.romBankCount(), myOldState.bank != myCart.getBank());
|
||||
}
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
|
@ -128,7 +128,7 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
|||
}
|
||||
else
|
||||
{
|
||||
bank = 256; // default to first RAM bank
|
||||
bank = myCart.romBankCount(); // default to first RAM bank
|
||||
myRAMBank->setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
|||
if(myRAMBank->getSelected() < int(myNumRamBanks))
|
||||
{
|
||||
myROMBank->setSelectedMax();
|
||||
bank = myRAMBank->getSelected() + 256;
|
||||
bank = myRAMBank->getSelected() + myCart.romBankCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -157,8 +157,8 @@ string Cartridge3EWidget::bankState()
|
|||
{
|
||||
ostringstream& buf = buffer();
|
||||
|
||||
uInt16& bank = myCart.myCurrentBank;
|
||||
if(bank < 256)
|
||||
uInt16 bank = myCart.getBank();
|
||||
if(bank < myCart.romBankCount())
|
||||
buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive";
|
||||
else
|
||||
buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRomBanks;
|
||||
|
|
|
@ -44,7 +44,7 @@ Cartridge3FWidget::Cartridge3FWidget(
|
|||
ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight;
|
||||
|
||||
VariantList items;
|
||||
for(uInt16 i = 0; i < cart.bankCount(); ++i)
|
||||
for(uInt16 i = 0; i < cart.romBankCount(); ++i)
|
||||
VarList::push_back(items, Variant(i).toString() + " ($3F)");
|
||||
|
||||
ostringstream label;
|
||||
|
|
|
@ -38,7 +38,7 @@ CartridgeFA2Widget::CartridgeFA2Widget(
|
|||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.bankCount();
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.romBankCount();
|
||||
++i, offset += 0x1000)
|
||||
{
|
||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
||||
|
@ -58,7 +58,7 @@ CartridgeFA2Widget::CartridgeFA2Widget(
|
|||
VarList::push_back(items, "3 ($FFF8)");
|
||||
VarList::push_back(items, "4 ($FFF9)");
|
||||
VarList::push_back(items, "5 ($FFFA)");
|
||||
if(cart.bankCount() == 7)
|
||||
if(cart.romBankCount() == 7)
|
||||
VarList::push_back(items, "6 ($FFFB)");
|
||||
|
||||
myBank =
|
||||
|
|
|
@ -26,7 +26,7 @@ CartridgeFCWidget::CartridgeFCWidget(
|
|||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
{
|
||||
uInt16 size = cart.bankCount() * 4096;
|
||||
uInt16 size = cart.romBankCount() * 4096;
|
||||
|
||||
ostringstream info;
|
||||
info << "FC cartridge, up to eight 4K banks\n"
|
||||
|
@ -42,7 +42,7 @@ CartridgeFCWidget::CartridgeFCWidget(
|
|||
ypos = addBaseInformation(size, "Amiga Corp.", info.str()) + myLineHeight;
|
||||
|
||||
VariantList items;
|
||||
for (uInt16 i = 0; i < cart.bankCount(); ++i)
|
||||
for (uInt16 i = 0; i < cart.romBankCount(); ++i)
|
||||
VarList::push_back(items, Variant(i).toString() +
|
||||
" ($FFF8 = " + Variant(i & 0b11).toString() +
|
||||
"/$FFF9 = " + Variant(i >> 2).toString() +")");
|
||||
|
|
|
@ -40,7 +40,7 @@ CartridgeMDMWidget::CartridgeMDMWidget(
|
|||
ypos = addBaseInformation(size, "Edwin Blink", info.str(), 15) + myLineHeight;
|
||||
|
||||
VariantList items;
|
||||
for(uInt32 i = 0x800; i < (0x800U + myCart.bankCount()); ++i)
|
||||
for(uInt32 i = 0x800; i < (0x800U + myCart.romBankCount()); ++i)
|
||||
{
|
||||
info.str("");
|
||||
info << std::dec << (i & 0xFF) << " ($" << Common::Base::HEX4 << i << ")";
|
||||
|
|
|
@ -35,14 +35,14 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget(
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info)
|
||||
{
|
||||
uInt32 size = cart.bankCount() * cart.BANK_SIZE;
|
||||
uInt32 size = cart.romBankCount() * cart.BANK_SIZE;
|
||||
|
||||
int xpos = 2,
|
||||
ypos = addBaseInformation(size, "M-Network", info.str(), 15) +
|
||||
myLineHeight;
|
||||
|
||||
VariantList items0, items1;
|
||||
for(int i = 0; i < cart.bankCount(); ++i)
|
||||
for(int i = 0; i < cart.romBankCount(); ++i)
|
||||
VarList::push_back(items0, getSpotLower(i));
|
||||
for(int i = 0; i < 4; ++i)
|
||||
VarList::push_back(items1, getSpotUpper(i));
|
||||
|
|
|
@ -33,12 +33,12 @@ CartridgeSBWidget::CartridgeSBWidget(
|
|||
myCart.getImage(size);
|
||||
info << "SB SUPERbanking, 32 or 64 4K banks\n"
|
||||
<< "Hotspots are from $800 to $"
|
||||
<< Common::Base::HEX2 << (0x800 + myCart.bankCount() - 1) << ", including\n"
|
||||
<< Common::Base::HEX2 << (0x800 + myCart.romBankCount() - 1) << ", including\n"
|
||||
<< "mirrors ($900, $A00, $B00, ...)\n"
|
||||
<< "Startup bank = " << std::dec << cart.startBank() << "\n";
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.bankCount();
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.romBankCount();
|
||||
++i, offset += 0x1000, ++spot)
|
||||
{
|
||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
||||
|
|
|
@ -68,7 +68,7 @@ void RomWidget::loadConfig()
|
|||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
||||
|
||||
// Fill romlist the current bank of source or disassembly
|
||||
myListIsDirty |= cart.disassemble(myListIsDirty);
|
||||
myListIsDirty |= cart.disassemblePC(myListIsDirty);
|
||||
if(myListIsDirty)
|
||||
{
|
||||
myRomList->setList(cart.disassembly());
|
||||
|
|
|
@ -83,7 +83,7 @@ uInt16 Cartridge::bankSize(uInt16 bank) const
|
|||
|
||||
getImage(size);
|
||||
|
||||
return std::min(uInt32(size) / bankCount(), 4_KB); // assuming that each bank has the same size
|
||||
return std::min(uInt32(size) / romBankCount(), 4_KB); // assuming that each bank has the same size
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -145,13 +145,13 @@ string Cartridge::getAccessCounters() const
|
|||
ostringstream out;
|
||||
uInt32 offset = 0;
|
||||
|
||||
for(uInt16 bank = 0; bank < bankCount(); ++bank)
|
||||
for(uInt16 bank = 0; bank < romBankCount(); ++bank)
|
||||
{
|
||||
uInt16 origin = bankOrigin(bank);
|
||||
uInt16 bankSize = this->bankSize(bank);
|
||||
|
||||
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
||||
<< Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n";
|
||||
<< Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n";
|
||||
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
||||
{
|
||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||
|
@ -159,7 +159,7 @@ string Cartridge::getAccessCounters() const
|
|||
}
|
||||
out << "\n";
|
||||
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
||||
<< Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n";
|
||||
<< Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n";
|
||||
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
||||
{
|
||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||
|
@ -230,11 +230,11 @@ uInt16 Cartridge::initializeStartBank(uInt16 defaultBank)
|
|||
int propsBank = myStartBankFromPropsFunc();
|
||||
|
||||
if(randomStartBank())
|
||||
return myStartBank = mySystem->randGenerator().next() % bankCount();
|
||||
return myStartBank = mySystem->randGenerator().next() % romBankCount();
|
||||
else if(propsBank >= 0)
|
||||
return myStartBank = BSPF::clamp(propsBank, 0, bankCount() - 1);
|
||||
return myStartBank = BSPF::clamp(propsBank, 0, romBankCount() - 1);
|
||||
else
|
||||
return myStartBank = BSPF::clamp(int(defaultBank), 0, bankCount() - 1);
|
||||
return myStartBank = BSPF::clamp(int(defaultBank), 0, romBankCount() - 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -180,7 +180,7 @@ class Cartridge : public Device
|
|||
virtual uInt16 getBank(uInt16 address = 0) const { return 0; }
|
||||
|
||||
/**
|
||||
Query the number of 'banks' supported by the cartridge. Note that
|
||||
Query the number of ROM 'banks' supported by the cartridge. Note that
|
||||
this information is cart-specific, where each cart basically defines
|
||||
what a 'bank' is.
|
||||
|
||||
|
@ -192,7 +192,15 @@ class Cartridge : public Device
|
|||
RAM slices at multiple access points) is so complicated that the
|
||||
cart will report having only one 'virtual' bank.
|
||||
*/
|
||||
virtual uInt16 bankCount() const { return 1; }
|
||||
virtual uInt16 romBankCount() const { return 1; }
|
||||
|
||||
|
||||
/**
|
||||
Query the number of RAM 'banks' supported by the cartridge. Note that
|
||||
this information is cart-specific, where each cart basically defines
|
||||
what a 'bank' is.
|
||||
*/
|
||||
virtual uInt16 ramBankCount() const { return 0; }
|
||||
|
||||
/**
|
||||
Get the size of a bank.
|
||||
|
|
|
@ -22,52 +22,42 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size,
|
||||
const string& md5, const Settings& settings)
|
||||
: Cartridge(settings, md5),
|
||||
mySize(size),
|
||||
myRomBanks(256/*uInt16(size) >> 11*/)
|
||||
: CartridgeEnhanced(image, size, md5, settings)
|
||||
{
|
||||
// Allocate array for the ROM image
|
||||
myImage = make_unique<uInt8[]>(mySize);
|
||||
|
||||
// Copy the ROM image into my buffer
|
||||
std::copy_n(image.get(), mySize, myImage.get());
|
||||
createRomAccessArrays(mySize + myRAM.size());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3E::reset()
|
||||
{
|
||||
initializeRAM(myRAM.data(), myRAM.size());
|
||||
initializeStartBank(0);
|
||||
|
||||
// We'll map the startup bank into the first segment upon reset
|
||||
bank(startBank());
|
||||
myBankShift = BANK_SHIFT;
|
||||
myRamSize = RAM_SIZE;
|
||||
myRamBankCount = RAM_BANKS;
|
||||
myRamWpHigh = RAM_HIGH_WP;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3E::install(System& system)
|
||||
{
|
||||
mySystem = &system;
|
||||
CartridgeEnhanced::install(system);
|
||||
|
||||
System::PageAccess access(this, System::PageAccessType::READWRITE);
|
||||
|
||||
// The hotspots ($3E and $3F) are in TIA address space, so we claim it here
|
||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
access.type = System::PageAccessType::READ;
|
||||
for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
||||
{
|
||||
// Switch banks if necessary
|
||||
if(address == 0x003F) {
|
||||
// Switch ROM bank into segment 0
|
||||
bank(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Install pages for the startup bank into the first segment
|
||||
bank(startBank());
|
||||
else if(address == 0x003E)
|
||||
{
|
||||
// Switch RAM bank into segment 0
|
||||
bank(value + romBankCount());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -76,215 +66,8 @@ uInt8 Cartridge3E::peek(uInt16 address)
|
|||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Due to the way paging is set up, the only way to get here is a TIA read or
|
||||
// attempting to read from the RAM write port
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
return mySystem->tia().peek(address);
|
||||
else if(myCurrentBank >= myRomBanks)
|
||||
{
|
||||
// Reading from the write port triggers an unwanted write
|
||||
return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)], peekAddress);
|
||||
}
|
||||
|
||||
// Make compiler happy; should never get here
|
||||
return myImage[(address & 0x07FF) + mySize - 2048];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
uInt16 pokeAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
// Switch banks if necessary. Armin (Kroko) says there are no mirrored
|
||||
// hotspots.
|
||||
if(address < 0x0040)
|
||||
{
|
||||
if(address == 0x003F)
|
||||
bank(value);
|
||||
else if(address == 0x003E)
|
||||
bank(value + myRomBanks);
|
||||
|
||||
return mySystem->tia().poke(address, value);
|
||||
}
|
||||
else if(myCurrentBank >= myRomBanks)
|
||||
{
|
||||
if(address & 0x0400)
|
||||
{
|
||||
pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)],
|
||||
pokeAddress, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
||||
uInt8 dummy;
|
||||
|
||||
pokeRAM(dummy, pokeAddress, value);
|
||||
myRamWriteAccess = pokeAddress;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::bank(uInt16 bank)
|
||||
{
|
||||
if(bankLocked()) return false;
|
||||
|
||||
if(bank < myRomBanks)
|
||||
{
|
||||
// Make sure the bank they're asking for is reasonable
|
||||
if((uInt32(bank) << 11) < mySize)
|
||||
{
|
||||
myCurrentBank = bank;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oops, the bank they're asking for isn't valid so let's wrap it
|
||||
// around to a valid bank number
|
||||
myCurrentBank = bank % (mySize >> 11);
|
||||
}
|
||||
|
||||
uInt32 offset = myCurrentBank << 11;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access(this, System::PageAccessType::READ);
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (addr & 0x07FF)];
|
||||
access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)];
|
||||
access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x07FF)];
|
||||
access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x07FF) + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bank -= myRomBanks;
|
||||
bank %= myRamBanks;
|
||||
myCurrentBank = bank + myRomBanks;
|
||||
|
||||
uInt32 offset = bank << 10;
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access(this, System::PageAccessType::READ);
|
||||
|
||||
// Map read-port RAM image into the system
|
||||
// Writes are mapped to poke(), to check for write to the read port
|
||||
for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myRAM[offset + (addr & 0x03FF)];
|
||||
access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)];
|
||||
access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)];
|
||||
access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
access.directPeekBase = nullptr;
|
||||
access.type = System::PageAccessType::WRITE;
|
||||
|
||||
// Map write-port RAM image into the system
|
||||
// Reads are mapped to peek(), to check for read from write port
|
||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)];
|
||||
access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)];
|
||||
access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 Cartridge3E::getBank(uInt16 address) const
|
||||
{
|
||||
if (address & 0x800)
|
||||
return myRomBanks - 1; // 2K slices, fixed bank
|
||||
else
|
||||
return myCurrentBank;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 Cartridge3E::bankCount() const
|
||||
{
|
||||
// Because the RAM banks always start at 256 and above, we require the
|
||||
// number of ROM banks to be 256
|
||||
// If the RAM banks were simply appended to the number of actual
|
||||
// ROM banks, bank numbers would be ambiguous (ie, would bank 128 be
|
||||
// the last bank of ROM, or one of the banks of RAM?)
|
||||
return myRomBanks + myRamBanks;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 Cartridge3E::bankSize(uInt16 bank) const
|
||||
{
|
||||
return 2_KB; // we cannot use bankCount() here, because it delivers wrong numbers
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::patch(uInt16 address, uInt8 value)
|
||||
{
|
||||
address &= 0x0FFF;
|
||||
|
||||
if(address < 0x0800)
|
||||
{
|
||||
if(myCurrentBank < myRomBanks)
|
||||
myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value;
|
||||
else
|
||||
myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)] = value;
|
||||
}
|
||||
else
|
||||
myImage[(address & 0x07FF) + mySize - 2048] = value;
|
||||
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt8* Cartridge3E::getImage(size_t& size) const
|
||||
{
|
||||
size = mySize;
|
||||
return myImage.get();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::save(Serializer& out) const
|
||||
{
|
||||
try
|
||||
{
|
||||
out.putShort(myCurrentBank);
|
||||
out.putByteArray(myRAM.data(), myRAM.size());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: Cartridge3E::save" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::load(Serializer& in)
|
||||
{
|
||||
try
|
||||
{
|
||||
myCurrentBank = in.getShort();
|
||||
in.getByteArray(myRAM.data(), myRAM.size());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "ERROR: Cartridge3E::load" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, go to the current bank
|
||||
bank(myCurrentBank);
|
||||
|
||||
return true;
|
||||
return CartridgeEnhanced::peek(peekAddress);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
class System;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartEnhanced.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "Cart3EWidget.hxx"
|
||||
#endif
|
||||
|
@ -47,10 +47,8 @@ class System;
|
|||
by storing its value into $3F. To map RAM in the first 2K segment
|
||||
instead, store the RAM bank number into $3E.
|
||||
|
||||
This implementation of 3E bankswitching numbers the ROM banks 0 to
|
||||
255, and the RAM banks 256 to 287. This is done because the public
|
||||
bankswitching interface requires us to use one bank number, not one
|
||||
bank number plus the knowledge of whether it's RAM or ROM.
|
||||
This implementation of 3E bankswitching numbers the RAM banks (up to 32)
|
||||
after the ROM banks (up to 256).
|
||||
|
||||
All 32K of potential RAM is available to a game using this class, even
|
||||
though real cartridges might not have the full 32K: We have no way to
|
||||
|
@ -58,10 +56,10 @@ class System;
|
|||
may add a stella.pro property for this), but for now it shouldn't cause
|
||||
any problems. (Famous last words...)
|
||||
|
||||
@author B. Watson
|
||||
@author B. Watson, Thomas Jentzsch
|
||||
*/
|
||||
|
||||
class Cartridge3E : public Cartridge
|
||||
class Cartridge3E : public CartridgeEnhanced
|
||||
{
|
||||
friend class Cartridge3EWidget;
|
||||
|
||||
|
@ -79,10 +77,6 @@ class Cartridge3E : public Cartridge
|
|||
virtual ~Cartridge3E() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device to its power-on state
|
||||
*/
|
||||
void reset() override;
|
||||
|
||||
/**
|
||||
Install cartridge in the specified system. Invoked by the system
|
||||
|
@ -92,66 +86,6 @@ class Cartridge3E : public Cartridge
|
|||
*/
|
||||
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.
|
||||
|
||||
@param address The address to use when querying the bank
|
||||
*/
|
||||
uInt16 getBank(uInt16 address = 0) const override;
|
||||
|
||||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
|
||||
/**
|
||||
Get the size of a bank.
|
||||
|
||||
@param bank The bank to get the size for
|
||||
@return The bank's size
|
||||
*/
|
||||
virtual uInt16 bankSize(uInt16 bank = 0) const;
|
||||
|
||||
/**
|
||||
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(size_t& 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).
|
||||
|
||||
|
@ -179,33 +113,21 @@ class Cartridge3E : public Cartridge
|
|||
*/
|
||||
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:
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||
|
||||
private:
|
||||
// Pointer to a dynamically allocated ROM image of the cartridge
|
||||
ByteBuffer myImage;
|
||||
// log(ROM bank segment size) / log(2)
|
||||
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
||||
|
||||
// RAM contents. For now every ROM gets all 32K of potential RAM
|
||||
std::array<uInt8, 32_KB> myRAM;
|
||||
// The size of extra RAM in ROM address space
|
||||
static constexpr uInt16 RAM_BANKS = 32;
|
||||
|
||||
// Size of the ROM image
|
||||
size_t mySize{0};
|
||||
// RAM size
|
||||
static constexpr uInt16 RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000;
|
||||
|
||||
// Size of the ROM image
|
||||
uInt16 myRomBanks{0};
|
||||
|
||||
// Size of the ROM image
|
||||
uInt16 myRamBanks{32};
|
||||
|
||||
// Indicates which bank is currently active for the first segment
|
||||
uInt16 myCurrentBank{0};
|
||||
// Write port for extra RAM is at high address
|
||||
static constexpr bool RAM_HIGH_WP = true;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -85,7 +85,7 @@ uInt16 Cartridge3EPlus::getBank(uInt16 address) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 Cartridge3EPlus::bankCount() const
|
||||
uInt16 Cartridge3EPlus::romBankCount() const
|
||||
{
|
||||
return uInt16(mySize >> 10); // 1K slices
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ class Cartridge3EPlus: public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -46,7 +46,7 @@ bool Cartridge3F::checkSwitchBank(uInt16 address, uInt8 value)
|
|||
if(address <= 0x003F)
|
||||
{
|
||||
// Make sure the bank they're asking for is reasonable
|
||||
bank(value % bankCount(), 0);
|
||||
bank(value % romBankCount(), 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -406,7 +406,7 @@ uInt16 CartridgeAR::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeAR::bankCount() const
|
||||
uInt16 CartridgeAR::romBankCount() const
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ class CartridgeAR : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -457,7 +457,7 @@ uInt16 CartridgeBUS::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeBUS::bankCount() const
|
||||
uInt16 CartridgeBUS::romBankCount() const
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ class CartridgeBUS : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -430,7 +430,7 @@ uInt16 CartridgeCDF::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeCDF::bankCount() const
|
||||
uInt16 CartridgeCDF::romBankCount() const
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ class CartridgeCDF : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -163,7 +163,7 @@ uInt16 CartridgeCM::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeCM::bankCount() const
|
||||
uInt16 CartridgeCM::romBankCount() const
|
||||
{
|
||||
// We report 4 banks (of ROM), even though RAM can overlap the upper 2K
|
||||
// of cart address space at some times
|
||||
|
|
|
@ -155,7 +155,7 @@ class CartridgeCM : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -255,7 +255,7 @@ uInt16 CartridgeCTY::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeCTY::bankCount() const
|
||||
uInt16 CartridgeCTY::romBankCount() const
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ class CartridgeCTY : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -399,7 +399,7 @@ uInt16 CartridgeDPC::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeDPC::bankCount() const
|
||||
uInt16 CartridgeDPC::romBankCount() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ class CartridgeDPC : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -619,7 +619,7 @@ uInt16 CartridgeDPCPlus::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeDPCPlus::bankCount() const
|
||||
uInt16 CartridgeDPCPlus::romBankCount() const
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ class CartridgeDPCPlus : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -34,16 +34,19 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEnhanced::install(System& system)
|
||||
{
|
||||
// Copy the ROM image into my buffer
|
||||
createRomAccessArrays(mySize);
|
||||
// limit banked RAM size to the size of one RAM bank
|
||||
uInt16 ramSize = myRamBankCount ? 1 << (myBankShift - 1) : myRamSize;
|
||||
|
||||
// calculate bank switching and RAM sizes and masks
|
||||
myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000
|
||||
myBankMask = myBankSize - 1; // e.g. = 0x0FFF
|
||||
myBankSegs = 1 << (12 - myBankShift); // e.g. = 1
|
||||
myRamMask = myRamSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0)
|
||||
myWriteOffset = myRamWpHigh ? myRamSize : 0;
|
||||
myReadOffset = myRamWpHigh ? 0 : myRamSize;
|
||||
myRomOffset = myRamBankCount ? 0 : myRamSize * 2;
|
||||
myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0)
|
||||
myWriteOffset = myRamWpHigh ? ramSize : 0;
|
||||
myReadOffset = myRamWpHigh ? 0 : ramSize;
|
||||
|
||||
createRomAccessArrays(mySize + (myRomOffset ? 0 : myRamSize));
|
||||
|
||||
// Allocate array for the current bank segments slices
|
||||
myCurrentSegOffset = make_unique<uInt32[]>(myBankSegs);
|
||||
|
@ -51,41 +54,44 @@ void CartridgeEnhanced::install(System& system)
|
|||
// Allocate array for the RAM area
|
||||
myRAM = make_unique<uInt8[]>(myRamSize);
|
||||
|
||||
// Setup page access
|
||||
mySystem = &system;
|
||||
|
||||
System::PageAccess access(this, System::PageAccessType::READ);
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.type = System::PageAccessType::WRITE;
|
||||
for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE)
|
||||
if(myRomOffset)
|
||||
{
|
||||
uInt16 offset = addr & myRamMask;
|
||||
access.romAccessBase = &myRomAccessBase[myWriteOffset + offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset];
|
||||
access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
// Setup page access for extended RAM; banked RAM will be setup in bank()
|
||||
System::PageAccess access(this, System::PageAccessType::READ);
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.type = System::PageAccessType::READ;
|
||||
for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE)
|
||||
{
|
||||
uInt16 offset = addr & myRamMask;
|
||||
access.directPeekBase = &myRAM[offset];
|
||||
access.romAccessBase = &myRomAccessBase[myReadOffset + offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset];
|
||||
access.romPokeCounter = &myRomAccessCounter[myReadOffset + offset + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
// Map access to this class, since we need to inspect all accesses to
|
||||
// check if RWP happens
|
||||
access.type = System::PageAccessType::WRITE;
|
||||
for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE)
|
||||
{
|
||||
uInt16 offset = addr & myRamMask;
|
||||
access.romAccessBase = &myRomAccessBase[myWriteOffset + offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset];
|
||||
access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
access.type = System::PageAccessType::READ;
|
||||
for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE)
|
||||
{
|
||||
uInt16 offset = addr & myRamMask;
|
||||
access.directPeekBase = &myRAM[offset];
|
||||
access.romAccessBase = &myRomAccessBase[myReadOffset + offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset];
|
||||
access.romPokeCounter = &myRomAccessCounter[myReadOffset + offset + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
|
||||
// Install pages for the startup bank (TODO: currently only in first bank segment)
|
||||
bank(startBank(), 0);
|
||||
if(mySize >= 4_KB && myBankSegs > 1)
|
||||
// Setup the last bank segment to always point to the last ROM segment
|
||||
bank(bankCount() - 1, myBankSegs - 1);
|
||||
bank(romBankCount() - 1, myBankSegs - 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -106,63 +112,103 @@ uInt8 CartridgeEnhanced::peek(uInt16 address)
|
|||
|
||||
if (hotspot())
|
||||
checkSwitchBank(address & 0x0FFF);
|
||||
address &= myBankMask;
|
||||
|
||||
// Write port is e.g. at 0xF000 - 0xF07F (128 bytes)
|
||||
if(address < myReadOffset + myRamSize && address >= myReadOffset)
|
||||
if(isRamBank(address))
|
||||
{
|
||||
address &= myRamMask;
|
||||
|
||||
// This is a read access to a write port!
|
||||
return peekRAM(myRAM[address], peekAddress);
|
||||
// Reading from the write port triggers an unwanted write
|
||||
// The RAM banks follow the ROM banks and are half the size of a ROM bank
|
||||
return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address],
|
||||
peekAddress);
|
||||
}
|
||||
else
|
||||
return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address];
|
||||
{
|
||||
address &= myBankMask;
|
||||
|
||||
// Write port is e.g. at 0xF000 - 0xF07F (128 bytes)
|
||||
if(address < myReadOffset + myRamSize && address >= myReadOffset)
|
||||
// This is a read access to a write port!
|
||||
// Reading from the write port triggers an unwanted write
|
||||
return peekRAM(myRAM[address], peekAddress);
|
||||
else
|
||||
return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address];
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEnhanced::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
uInt16 pokeAddress = address;
|
||||
|
||||
// Switch banks if necessary
|
||||
// Note: (TODO?)
|
||||
// The checkSwitchBank() call makes no difference between ROM and e.g TIA space
|
||||
// Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug???
|
||||
if (checkSwitchBank(address & 0x0FFF, value))
|
||||
return false;
|
||||
address &= myBankMask;
|
||||
|
||||
if(myRamSize)
|
||||
{
|
||||
if(bool(address & myRamSize) == myRamWpHigh)
|
||||
uInt16 pokeAddress = address;
|
||||
|
||||
if(isRamBank(address))
|
||||
{
|
||||
pokeRAM(myRAM[address & myRamMask], pokeAddress, value);
|
||||
return true;
|
||||
if(bool(address & (myBankSize >> 1)) == myRamWpHigh)
|
||||
{
|
||||
address &= myRamMask;
|
||||
// The RAM banks follow the ROM banks and are half the size of a ROM bank
|
||||
pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address],
|
||||
pokeAddress, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
||||
uInt8 dummy;
|
||||
|
||||
pokeRAM(dummy, pokeAddress, value);
|
||||
myRamWriteAccess = pokeAddress;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
||||
uInt8 dummy;
|
||||
//address &= myBankMask;
|
||||
if(bool(address & myRamSize) == myRamWpHigh)
|
||||
{
|
||||
pokeRAM(myRAM[address & myRamMask], pokeAddress, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
||||
uInt8 dummy;
|
||||
|
||||
pokeRAM(dummy, pokeAddress, value);
|
||||
myRamWriteAccess = pokeAddress;
|
||||
pokeRAM(dummy, pokeAddress, value);
|
||||
myRamWriteAccess = pokeAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM)
|
||||
bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
|
||||
{
|
||||
if(bankLocked()) return false;
|
||||
|
||||
uInt16 segmentOffset = segment << myBankShift;
|
||||
|
||||
if(!isRAM)
|
||||
if(!myRamBankCount || bank < romBankCount())
|
||||
{
|
||||
// Setup ROM bank
|
||||
// Remember what bank is in which segment
|
||||
uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift;
|
||||
|
||||
uInt16 romBank = bank % romBankCount();
|
||||
// Remember what bank is in this segment
|
||||
uInt32 bankOffset = myCurrentSegOffset[segment] = romBank << myBankShift;
|
||||
uInt16 hotspot = this->hotspot();
|
||||
uInt16 hotSpotAddr;
|
||||
uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK;
|
||||
uInt16 fromAddr = (0x1000 + segmentOffset + myRomOffset) & ~System::PAGE_MASK;
|
||||
// for ROMs < 4_KB, the whole address space will be mapped.
|
||||
uInt16 toAddr = (segmentOffset + 0x1000 + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK;
|
||||
uInt16 toAddr = (0x1000 + segmentOffset + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK;
|
||||
|
||||
if(hotspot)
|
||||
hotSpotAddr = (hotspot & ~System::PAGE_MASK);
|
||||
|
@ -185,24 +231,24 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM)
|
|||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}
|
||||
/*else
|
||||
else
|
||||
{
|
||||
// Setup RAM bank
|
||||
// TODO: define offsets on init
|
||||
uInt16 myWriteBankOffset = myBankSize >> 1;
|
||||
uInt16 myReadBankOffset = 0;
|
||||
uInt16 ramBank = (bank - romBankCount()) % myRamBankCount;
|
||||
// The RAM banks follow the ROM banks and are half the size of a ROM bank
|
||||
uInt32 bankOffset = uInt32(mySize) + (ramBank << (myBankShift - 1));
|
||||
|
||||
// Remember what bank is in which segment
|
||||
uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift;
|
||||
// Remember what bank is in this segment
|
||||
myCurrentSegOffset[segment] = bank << myBankShift;
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
uInt16 fromAddr = (segmentOffset + myWriteBankOffset + 0x1000) & ~System::PAGE_MASK;
|
||||
uInt16 toAddr = (segmentOffset + myWriteBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK;
|
||||
uInt16 fromAddr = (0x1000 + segmentOffset + myWriteOffset) & ~System::PAGE_MASK;
|
||||
uInt16 toAddr = (0x1000 + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK;
|
||||
System::PageAccess access(this, System::PageAccessType::WRITE);
|
||||
|
||||
for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)
|
||||
{
|
||||
uInt32 offset = bankOffset + (addr & myBankMask);
|
||||
uInt32 offset = bankOffset + (addr & myRamMask);
|
||||
|
||||
access.romAccessBase = &myRomAccessBase[offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[offset];
|
||||
|
@ -211,25 +257,23 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM)
|
|||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
fromAddr = (segmentOffset + myReadBankOffset + 0x1000) & ~System::PAGE_MASK;
|
||||
toAddr = (segmentOffset + myReadBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK;
|
||||
|
||||
fromAddr = (0x1000 + segmentOffset + myReadOffset) & ~System::PAGE_MASK;
|
||||
toAddr = (0x1000 + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK;
|
||||
access.type = System::PageAccessType::READ;
|
||||
|
||||
for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)
|
||||
{
|
||||
uInt32 offset = bankOffset + (addr & myBankMask);
|
||||
uInt32 offset = bankOffset + (addr & myRamMask);
|
||||
|
||||
|
||||
|
||||
uInt16 offset = addr & myRamMask;
|
||||
access.directPeekBase = &myBankRAM[offset];
|
||||
access.directPeekBase = &myRAM[offset - mySize];
|
||||
access.romAccessBase = &myRomAccessBase[offset];
|
||||
access.romPeekCounter = &myRomAccessCounter[offset];
|
||||
access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
|
@ -246,23 +290,42 @@ uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeEnhanced::bankCount() const
|
||||
uInt16 CartridgeEnhanced::romBankCount() const
|
||||
{
|
||||
return uInt16(mySize >> myBankShift);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeEnhanced::ramBankCount() const
|
||||
{
|
||||
return myRamBankCount;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEnhanced::isRamBank(uInt16 address) const
|
||||
{
|
||||
return myRamBankCount ? getBank(address) >= romBankCount() : false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEnhanced::patch(uInt16 address, uInt8 value)
|
||||
{
|
||||
if((address & myBankMask) < myRamSize * 2)
|
||||
if(isRamBank(address))
|
||||
{
|
||||
// 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 & myRamMask] = value;
|
||||
myRAM[((myCurrentSegOffset[(address & 0xFFF) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value;
|
||||
}
|
||||
else
|
||||
myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value;
|
||||
{
|
||||
if((address & myBankMask) < myRamSize * 2)
|
||||
{
|
||||
// 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 & myRamMask] = value;
|
||||
}
|
||||
else
|
||||
myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value;
|
||||
}
|
||||
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
|
|
@ -62,11 +62,10 @@ class CartridgeEnhanced : public Cartridge
|
|||
|
||||
@param bank The bank that should be installed in the system
|
||||
@param segment The segment the bank should be using
|
||||
@param isRAM True if the bank is a RAM bank
|
||||
|
||||
@return true, if bank has changed
|
||||
*/
|
||||
bool bank(uInt16 bank, uInt16 segment, bool isRAM = false);
|
||||
bool bank(uInt16 bank, uInt16 segment);
|
||||
|
||||
/**
|
||||
Install pages for the specified bank in the system.
|
||||
|
@ -94,7 +93,21 @@ class CartridgeEnhanced : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Query the number of RAM 'banks' supported by the cartridge.
|
||||
*/
|
||||
uInt16 ramBankCount() const override;
|
||||
|
||||
/**
|
||||
Check if the segment at that address contains a RAM bank
|
||||
|
||||
@param address The address which defines the segment
|
||||
|
||||
@return true, if the segment is currently mapped to a RAM bank
|
||||
*/
|
||||
bool isRamBank(uInt16 address) const;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
@ -162,9 +175,19 @@ class CartridgeEnhanced : public Cartridge
|
|||
// The extra RAM size
|
||||
uInt16 myRamSize{RAM_SIZE}; // default 0
|
||||
|
||||
// The number of RAM banks
|
||||
uInt16 myRamBankCount{RAM_BANKS}; // default 0
|
||||
|
||||
// The mask for the extra RAM
|
||||
uInt16 myRamMask{0}; // RAM_SIZE - 1, but doesn't matter when RAM_SIZE is 0
|
||||
|
||||
// The offset into ROM space for reading from ROM
|
||||
// This is zero for types without RAM and with banked RAM
|
||||
// - xxSC = 0x0100
|
||||
// - FA(2) = 0x0200
|
||||
// - CV = 0x0800
|
||||
uInt16 myRomOffset{0};
|
||||
|
||||
// The offset into ROM space for writing to RAM
|
||||
// - xxSC = 0x0000
|
||||
// - FA(2) = 0x0000
|
||||
|
@ -202,6 +225,9 @@ class CartridgeEnhanced : public Cartridge
|
|||
// The size of extra RAM in ROM address space
|
||||
static constexpr uInt16 RAM_SIZE = 0; // default = none
|
||||
|
||||
// The size of extra RAM in ROM address space
|
||||
static constexpr uInt16 RAM_BANKS = 0;
|
||||
|
||||
// Write port for extra RAM is at low address by default
|
||||
static constexpr bool RAM_HIGH_WP = false;
|
||||
|
||||
|
|
|
@ -61,14 +61,14 @@ bool CartridgeFC::poke(uInt16 address, uInt8 value)
|
|||
|
||||
case 0x0FF9:
|
||||
// Set the high bits of target 4k bank
|
||||
if (value << 2 < bankCount())
|
||||
if (value << 2 < romBankCount())
|
||||
{
|
||||
myTargetBank += value << 2;
|
||||
myTargetBank %= bankCount();
|
||||
myTargetBank %= romBankCount();
|
||||
}
|
||||
else
|
||||
// special handling when both values are identical (e.g. 4/4 or 5/5)
|
||||
myTargetBank = value % bankCount();
|
||||
myTargetBank = value % romBankCount();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -36,7 +36,7 @@ void CartridgeMNetwork::initialize(const ByteBuffer& image, size_t size)
|
|||
std::copy_n(image.get(), std::min<size_t>(romSize(), size), myImage.get());
|
||||
createRomAccessArrays(romSize() + myRAM.size());
|
||||
|
||||
myRAMSlice = bankCount() - 1;
|
||||
myRAMSlice = romBankCount() - 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -265,7 +265,7 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt8* CartridgeMNetwork::getImage(size_t& size) const
|
||||
{
|
||||
size = bankCount() * BANK_SIZE;
|
||||
size = romBankCount() * BANK_SIZE;
|
||||
return myImage.get();
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ bool CartridgeMNetwork::load(Serializer& in)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeMNetwork::bankCount() const
|
||||
uInt16 CartridgeMNetwork::romBankCount() const
|
||||
{
|
||||
return uInt16(mySize >> 11);
|
||||
}
|
||||
|
@ -318,5 +318,5 @@ uInt16 CartridgeMNetwork::bankCount() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeMNetwork::romSize() const
|
||||
{
|
||||
return bankCount() * BANK_SIZE;
|
||||
return romBankCount() * BANK_SIZE;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ class CartridgeMNetwork : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -64,7 +64,7 @@ bool CartridgeSB::checkSwitchBank(uInt16 address, uInt8)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeSB::peek(uInt16 address)
|
||||
{
|
||||
address &= (0x17FF + bankCount());
|
||||
address &= (0x17FF + romBankCount());
|
||||
|
||||
checkSwitchBank(address);
|
||||
|
||||
|
@ -82,7 +82,7 @@ uInt8 CartridgeSB::peek(uInt16 address)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeSB::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
address &= (0x17FF + bankCount());
|
||||
address &= (0x17FF + romBankCount());
|
||||
|
||||
checkSwitchBank(address);
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ class CartridgeSB : public CartridgeEnhanced
|
|||
|
||||
uInt16 hotspot() const override { return 0x0840; }
|
||||
|
||||
uInt16 getStartBank() const override { return bankCount() - 1; }
|
||||
uInt16 getStartBank() const override { return romBankCount() - 1; }
|
||||
|
||||
private:
|
||||
// Previous Device's page access
|
||||
|
|
|
@ -250,7 +250,7 @@ uInt16 CartridgeWD::getBank(uInt16) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeWD::bankCount() const
|
||||
uInt16 CartridgeWD::romBankCount() const
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ class CartridgeWD : public Cartridge
|
|||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
uInt16 bankCount() const override;
|
||||
uInt16 romBankCount() const override;
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
|
|
@ -445,7 +445,7 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
|||
VarList::push_back(items, "Auto", "AUTO");
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
uInt16 numBanks = instance().console().cartridge().bankCount();
|
||||
uInt16 numBanks = instance().console().cartridge().romBankCount();
|
||||
|
||||
for(uInt16 i = 0; i < numBanks; ++i)
|
||||
VarList::push_back(items, i, i);
|
||||
|
|
Loading…
Reference in New Issue