mirror of https://github.com/stella-emu/stella.git
Further refactoring of bankswitching schemes, and removal of 'MC' scheme.
- MC is being removed, since the code has never been tested, and a test ROM has never been created
This commit is contained in:
parent
31907f4be1
commit
6cf4aa4832
|
@ -77,7 +77,7 @@ void CartridgeF4SCWidget::saveOldState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF4SCWidget::loadConfig()
|
void CartridgeF4SCWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,8 @@ string CartridgeF4SCWidget::bankState()
|
||||||
static const char* const spot[] = {
|
static const char* const spot[] = {
|
||||||
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
||||||
};
|
};
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ CartridgeF4Widget::CartridgeF4Widget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF4Widget::loadConfig()
|
void CartridgeF4Widget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,8 @@ string CartridgeF4Widget::bankState()
|
||||||
static const char* const spot[] = {
|
static const char* const spot[] = {
|
||||||
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
||||||
};
|
};
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ void CartridgeF6SCWidget::saveOldState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF6SCWidget::loadConfig()
|
void CartridgeF6SCWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -97,8 +97,8 @@ string CartridgeF6SCWidget::bankState()
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* const spot[] = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
static const char* const spot[] = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ CartridgeF6Widget::CartridgeF6Widget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF6Widget::loadConfig()
|
void CartridgeF6Widget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,8 @@ string CartridgeF6Widget::bankState()
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* const spot[] = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
static const char* const spot[] = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ void CartridgeF8SCWidget::saveOldState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF8SCWidget::loadConfig()
|
void CartridgeF8SCWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -95,8 +95,8 @@ string CartridgeF8SCWidget::bankState()
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* const spot[] = { "$FFF8", "$FFF9" };
|
static const char* const spot[] = { "$FFF8", "$FFF9" };
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ CartridgeF8Widget::CartridgeF8Widget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeF8Widget::loadConfig()
|
void CartridgeF8Widget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,8 @@ string CartridgeF8Widget::bankState()
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* const spot[] = { "$FFF8", "$FFF9" };
|
static const char* const spot[] = { "$FFF8", "$FFF9" };
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,14 +109,14 @@ void CartridgeFA2Widget::saveOldState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFA2Widget::loadConfig()
|
void CartridgeFA2Widget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFA2Widget::handleCommand(CommandSender* sender,
|
void CartridgeFA2Widget::handleCommand(CommandSender* sender,
|
||||||
int cmd, int data, int id)
|
int cmd, int data, int id)
|
||||||
{
|
{
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
|
@ -149,8 +149,8 @@ string CartridgeFA2Widget::bankState()
|
||||||
static const char* const spot[] = {
|
static const char* const spot[] = {
|
||||||
"$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
"$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
||||||
};
|
};
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ void CartridgeFAWidget::saveOldState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFAWidget::loadConfig()
|
void CartridgeFAWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,8 @@ string CartridgeFAWidget::bankState()
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* const spot[] = { "$FFF8", "$FFF9", "$FFFA" };
|
static const char* const spot[] = { "$FFF8", "$FFF9", "$FFFA" };
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.getBank()];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "CartMC.hxx"
|
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartMCWidget.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeMCWidget::CartridgeMCWidget(
|
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
|
||||||
int x, int y, int w, int h, CartridgeMC& cart)
|
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
|
||||||
myCart(cart)
|
|
||||||
{
|
|
||||||
uInt32 size = 128 * 1024;
|
|
||||||
|
|
||||||
string info =
|
|
||||||
"MC cartridge, 128 1K slices ROM + 32 1K RAM\n"
|
|
||||||
"Write $80 - $FF into a hotspot for ROM (128)\n"
|
|
||||||
"Write $00 - $3F into a hotspot for RAM (32)\n"
|
|
||||||
"Segment 0 @ $F000 - $F3FF (hotspot = $3C)\n"
|
|
||||||
"Segment 1 @ $F400 - $F7FF (hotspot = $3D)\n"
|
|
||||||
"Segment 2 @ $F800 - $FBFF (hotspot = $3E)\n"
|
|
||||||
"Segment 3 @ $FC00 - $FFFF (hotspot = $3F)\n"
|
|
||||||
"\nTHIS SCHEME IS NOT FULLY IMPLEMENTED OR TESTED\n";
|
|
||||||
|
|
||||||
int xpos = 10,
|
|
||||||
ypos = addBaseInformation(size, "Chris Wilkson's Megacart", info) +
|
|
||||||
myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
// Add 128 1K 'ROM' blocks
|
|
||||||
for(uInt32 i = 0x80; i <= 0xFF; ++i)
|
|
||||||
{
|
|
||||||
const string& b = Variant(i).toString();
|
|
||||||
VarList::push_back(items, b + " (ROM)", b);
|
|
||||||
}
|
|
||||||
// Add 64 512B 'RAM' blocks
|
|
||||||
for(uInt32 i = 0x00; i <= 0x3F; ++i)
|
|
||||||
{
|
|
||||||
const string& b = Variant(i).toString();
|
|
||||||
VarList::push_back(items, b + " (RAM)", b);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int lwidth = _font.getStringWidth("Set slice for segment X ($3X) "),
|
|
||||||
fwidth = _font.getStringWidth("255 (ROM)");
|
|
||||||
|
|
||||||
mySlice0 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth,
|
|
||||||
myLineHeight, items, "Set slice for segment 0 ($3C) ",
|
|
||||||
lwidth, kSlice0Changed);
|
|
||||||
mySlice0->setTarget(this);
|
|
||||||
addFocusWidget(mySlice0);
|
|
||||||
ypos += mySlice0->getHeight() + 4;
|
|
||||||
|
|
||||||
mySlice1 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth,
|
|
||||||
myLineHeight, items, "Set slice for segment 1 ($3D) ",
|
|
||||||
lwidth, kSlice1Changed);
|
|
||||||
mySlice1->setTarget(this);
|
|
||||||
addFocusWidget(mySlice1);
|
|
||||||
ypos += mySlice1->getHeight() + 4;
|
|
||||||
|
|
||||||
mySlice2 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth,
|
|
||||||
myLineHeight, items, "Set slice for segment 2 ($3E) ",
|
|
||||||
lwidth, kSlice2Changed);
|
|
||||||
mySlice2->setTarget(this);
|
|
||||||
addFocusWidget(mySlice2);
|
|
||||||
ypos += mySlice2->getHeight() + 4;
|
|
||||||
|
|
||||||
mySlice3 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, fwidth,
|
|
||||||
myLineHeight, items, "Set slice for segment 3 ($3F) ",
|
|
||||||
lwidth, kSlice3Changed);
|
|
||||||
mySlice3->setTarget(this);
|
|
||||||
addFocusWidget(mySlice3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeMCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
mySlice0->setSelectedIndex(myCart.myCurrentBlock[0]);
|
|
||||||
mySlice1->setSelectedIndex(myCart.myCurrentBlock[1]);
|
|
||||||
mySlice2->setSelectedIndex(myCart.myCurrentBlock[2]);
|
|
||||||
mySlice3->setSelectedIndex(myCart.myCurrentBlock[3]);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeMCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
|
|
||||||
switch(cmd)
|
|
||||||
{
|
|
||||||
case kSlice0Changed:
|
|
||||||
myCart.myCurrentBlock[0] = mySlice0->getSelectedTag().toInt();
|
|
||||||
break;
|
|
||||||
case kSlice1Changed:
|
|
||||||
myCart.myCurrentBlock[1] = mySlice1->getSelectedTag().toInt();
|
|
||||||
break;
|
|
||||||
case kSlice2Changed:
|
|
||||||
myCart.myCurrentBlock[2] = mySlice2->getSelectedTag().toInt();
|
|
||||||
break;
|
|
||||||
case kSlice3Changed:
|
|
||||||
myCart.myCurrentBlock[3] = mySlice3->getSelectedTag().toInt();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeMCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Slices: " << std::dec
|
|
||||||
<< myCart.myCurrentBlock[0] << " / "
|
|
||||||
<< myCart.myCurrentBlock[1] << " / "
|
|
||||||
<< myCart.myCurrentBlock[2] << " / "
|
|
||||||
<< myCart.myCurrentBlock[3];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef CARTRIDGEMC_WIDGET_HXX
|
|
||||||
#define CARTRIDGEMC_WIDGET_HXX
|
|
||||||
|
|
||||||
class CartridgeMC;
|
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
|
||||||
|
|
||||||
class CartridgeMCWidget : public CartDebugWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CartridgeMCWidget(GuiObject* boss, const GUI::Font& lfont,
|
|
||||||
const GUI::Font& nfont,
|
|
||||||
int x, int y, int w, int h,
|
|
||||||
CartridgeMC& cart);
|
|
||||||
virtual ~CartridgeMCWidget() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CartridgeMC& myCart;
|
|
||||||
PopUpWidget *mySlice0, *mySlice1, *mySlice2, *mySlice3;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kSlice0Changed = 's0CH',
|
|
||||||
kSlice1Changed = 's1CH',
|
|
||||||
kSlice2Changed = 's2CH',
|
|
||||||
kSlice3Changed = 's3CH'
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
|
||||||
CartridgeMCWidget() = delete;
|
|
||||||
CartridgeMCWidget(const CartridgeMCWidget&) = delete;
|
|
||||||
CartridgeMCWidget(CartridgeMCWidget&&) = delete;
|
|
||||||
CartridgeMCWidget& operator=(const CartridgeMCWidget&) = delete;
|
|
||||||
CartridgeMCWidget& operator=(CartridgeMCWidget&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -64,7 +64,7 @@ CartridgeMDMWidget::CartridgeMDMWidget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeMDMWidget::loadConfig()
|
void CartridgeMDMWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
myBankDisabled->setState(myCart.myBankingDisabled);
|
myBankDisabled->setState(myCart.myBankingDisabled);
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
|
@ -92,9 +92,9 @@ string CartridgeMDMWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = " << "$" << Common::Base::HEX4
|
<< ", hotspot = " << "$" << Common::Base::HEX4
|
||||||
<< (myCart.myCurrentBank+0x800);
|
<< (myCart.getBank()+0x800);
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ CartridgeSBWidget::CartridgeSBWidget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeSBWidget::loadConfig()
|
void CartridgeSBWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.getBank());
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,8 @@ string CartridgeSBWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.getBank()
|
||||||
<< ", hotspot = $" << Common::Base::HEX2 << (myCart.myCurrentBank + 0x800);
|
<< ", hotspot = $" << Common::Base::HEX2 << (myCart.getBank() + 0x800);
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ MODULE_OBJS := \
|
||||||
src/debugger/gui/CartFAWidget.o \
|
src/debugger/gui/CartFAWidget.o \
|
||||||
src/debugger/gui/CartFA2Widget.o \
|
src/debugger/gui/CartFA2Widget.o \
|
||||||
src/debugger/gui/CartFEWidget.o \
|
src/debugger/gui/CartFEWidget.o \
|
||||||
src/debugger/gui/CartMCWidget.o \
|
|
||||||
src/debugger/gui/CartMDMWidget.o \
|
src/debugger/gui/CartMDMWidget.o \
|
||||||
src/debugger/gui/CartSBWidget.o \
|
src/debugger/gui/CartSBWidget.o \
|
||||||
src/debugger/gui/CartUAWidget.o \
|
src/debugger/gui/CartUAWidget.o \
|
||||||
|
|
|
@ -28,8 +28,7 @@ enum class BSType {
|
||||||
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
|
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
|
||||||
_DPC, _DPCP, _E0, _E7, _EF, _EFSC, _F0,
|
_DPC, _DPCP, _E0, _E7, _EF, _EFSC, _F0,
|
||||||
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
|
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
|
||||||
_FA2, _FE, _MC, _MDM, _SB, _UA, _WD,
|
_FA2, _FE, _MDM, _SB, _UA, _WD, _X07,
|
||||||
_X07,
|
|
||||||
NumSchemes
|
NumSchemes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,7 +84,6 @@ static BSDescription BSList[int(BSType::NumSchemes)] = {
|
||||||
{ "FA", "FA (CBS RAM Plus)" },
|
{ "FA", "FA (CBS RAM Plus)" },
|
||||||
{ "FA2", "FA2 (CBS RAM Plus 24/28K)" },
|
{ "FA2", "FA2 (CBS RAM Plus 24/28K)" },
|
||||||
{ "FE", "FE (8K Decathlon)" },
|
{ "FE", "FE (8K Decathlon)" },
|
||||||
{ "MC", "MC (C. Wilkson Megacart)" },
|
|
||||||
{ "MDM", "MDM (Menu Driven Megacart)" },
|
{ "MDM", "MDM (Menu Driven Megacart)" },
|
||||||
{ "SB", "SB (128-256K SUPERbank)" },
|
{ "SB", "SB (128-256K SUPERbank)" },
|
||||||
{ "UA", "UA (8K UA Ltd.)" },
|
{ "UA", "UA (8K UA Ltd.)" },
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "CartFA.hxx"
|
#include "CartFA.hxx"
|
||||||
#include "CartFA2.hxx"
|
#include "CartFA2.hxx"
|
||||||
#include "CartFE.hxx"
|
#include "CartFE.hxx"
|
||||||
#include "CartMC.hxx"
|
|
||||||
#include "CartMDM.hxx"
|
#include "CartMDM.hxx"
|
||||||
#include "CartSB.hxx"
|
#include "CartSB.hxx"
|
||||||
#include "CartUA.hxx"
|
#include "CartUA.hxx"
|
||||||
|
@ -310,8 +309,6 @@ CartDetector::createFromImage(const BytePtr& image, uInt32 size, BSType type,
|
||||||
return make_unique<CartridgeFA2>(image, size, osystem);
|
return make_unique<CartridgeFA2>(image, size, osystem);
|
||||||
case BSType::_FE:
|
case BSType::_FE:
|
||||||
return make_unique<CartridgeFE>(image, size, osystem.settings());
|
return make_unique<CartridgeFE>(image, size, osystem.settings());
|
||||||
case BSType::_MC:
|
|
||||||
return make_unique<CartridgeMC>(image, size, osystem.settings());
|
|
||||||
case BSType::_MDM:
|
case BSType::_MDM:
|
||||||
return make_unique<CartridgeMDM>(image, size, osystem.settings());
|
return make_unique<CartridgeMDM>(image, size, osystem.settings());
|
||||||
case BSType::_UA:
|
case BSType::_UA:
|
||||||
|
@ -470,8 +467,6 @@ BSType CartDetector::autodetectType(const BytePtr& image, uInt32 size)
|
||||||
type = BSType::_4A50;
|
type = BSType::_4A50;
|
||||||
else if(isProbablySB(image, size))
|
else if(isProbablySB(image, size))
|
||||||
type = BSType::_SB;
|
type = BSType::_SB;
|
||||||
else
|
|
||||||
type = BSType::_MC;
|
|
||||||
}
|
}
|
||||||
else if(size == 256*1024) // 256K
|
else if(size == 256*1024) // 256K
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
CartridgeF4::CartridgeF4(const BytePtr& image, uInt32 size,
|
CartridgeF4::CartridgeF4(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(32768u, size));
|
memcpy(myImage, image.get(), std::min(32768u, size));
|
||||||
|
@ -60,7 +60,7 @@ uInt8 CartridgeF4::peek(uInt16 address)
|
||||||
bank(address - 0x0FF4);
|
bank(address - 0x0FF4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -83,8 +83,7 @@ bool CartridgeF4::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ bool CartridgeF4::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +99,8 @@ bool CartridgeF4::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1000; address < (0x1FF4U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1000; address < (0x1FF4U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -110,7 +109,7 @@ bool CartridgeF4::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF4::getBank() const
|
uInt16 CartridgeF4::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -122,7 +121,7 @@ uInt16 CartridgeF4::bankCount() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeF4::patch(uInt16 address, uInt8 value)
|
bool CartridgeF4::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
|
myImage[myBankOffset + (address & 0x0FFF)] = value;
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +138,7 @@ bool CartridgeF4::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +157,7 @@ bool CartridgeF4::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +166,7 @@ bool CartridgeF4::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,8 +151,8 @@ class CartridgeF4 : public Cartridge
|
||||||
// The 32K ROM image of the cartridge
|
// The 32K ROM image of the cartridge
|
||||||
uInt8 myImage[32768];
|
uInt8 myImage[32768];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeF4SC::CartridgeF4SC(const BytePtr& image, uInt32 size,
|
CartridgeF4SC::CartridgeF4SC(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(32768u, size));
|
memcpy(myImage, image.get(), std::min(32768u, size));
|
||||||
|
@ -98,7 +98,7 @@ uInt8 CartridgeF4SC::peek(uInt16 address)
|
||||||
// NOTE: This does not handle accessing RAM, however, this function
|
// NOTE: This does not handle accessing RAM, however, this function
|
||||||
// should never be called for RAM because of the way page accessing
|
// should never be called for RAM because of the way page accessing
|
||||||
// has been setup
|
// has been setup
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -122,8 +122,7 @@ bool CartridgeF4SC::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -131,7 +130,7 @@ bool CartridgeF4SC::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,8 +138,8 @@ bool CartridgeF4SC::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1100; address < (0x1FF4U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1100; address < (0x1FF4U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -149,7 +148,7 @@ bool CartridgeF4SC::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF4SC::getBank() const
|
uInt16 CartridgeF4SC::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -171,7 +170,7 @@ bool CartridgeF4SC::patch(uInt16 address, uInt8 value)
|
||||||
myRAM[address & 0x007F] = value;
|
myRAM[address & 0x007F] = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myImage[(myCurrentBank << 12) + address] = value;
|
myImage[myBankOffset + address] = value;
|
||||||
|
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +188,7 @@ bool CartridgeF4SC::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
out.putByteArray(myRAM, 128);
|
out.putByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -209,7 +208,7 @@ bool CartridgeF4SC::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
in.getByteArray(myRAM, 128);
|
in.getByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -219,7 +218,7 @@ bool CartridgeF4SC::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class System;
|
||||||
/**
|
/**
|
||||||
Cartridge class used for Atari's 32K bankswitched games with
|
Cartridge class used for Atari's 32K bankswitched games with
|
||||||
128 bytes of RAM. There are eight 4K banks.
|
128 bytes of RAM. There are eight 4K banks.
|
||||||
|
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@author Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
|
@ -154,8 +155,8 @@ class CartridgeF4SC : public Cartridge
|
||||||
// The 128 bytes of RAM
|
// The 128 bytes of RAM
|
||||||
uInt8 myRAM[128];
|
uInt8 myRAM[128];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeF6::CartridgeF6(const BytePtr& image, uInt32 size,
|
CartridgeF6::CartridgeF6(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(16384u, size));
|
memcpy(myImage, image.get(), std::min(16384u, size));
|
||||||
|
@ -80,7 +80,7 @@ uInt8 CartridgeF6::peek(uInt16 address)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -123,8 +123,7 @@ bool CartridgeF6::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ bool CartridgeF6::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF6 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF6 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,8 +139,8 @@ bool CartridgeF6::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1000; address < (0x1FF6U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1000; address < (0x1FF6U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -150,7 +149,7 @@ bool CartridgeF6::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF6::getBank() const
|
uInt16 CartridgeF6::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -162,7 +161,7 @@ uInt16 CartridgeF6::bankCount() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeF6::patch(uInt16 address, uInt8 value)
|
bool CartridgeF6::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
|
myImage[myBankOffset + (address & 0x0FFF)] = value;
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +178,7 @@ bool CartridgeF6::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +197,7 @@ bool CartridgeF6::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -207,7 +206,7 @@ bool CartridgeF6::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,8 +151,8 @@ class CartridgeF6 : public Cartridge
|
||||||
// The 16K ROM image of the cartridge
|
// The 16K ROM image of the cartridge
|
||||||
uInt8 myImage[16384];
|
uInt8 myImage[16384];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeF6SC::CartridgeF6SC(const BytePtr& image, uInt32 size,
|
CartridgeF6SC::CartridgeF6SC(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(16384u, size));
|
memcpy(myImage, image.get(), std::min(16384u, size));
|
||||||
|
@ -118,7 +118,7 @@ uInt8 CartridgeF6SC::peek(uInt16 address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -165,8 +165,7 @@ bool CartridgeF6SC::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -174,7 +173,7 @@ bool CartridgeF6SC::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF6 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF6 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +181,8 @@ bool CartridgeF6SC::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1100; address < (0x1FF6U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1100; address < (0x1FF6U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -192,7 +191,7 @@ bool CartridgeF6SC::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF6SC::getBank() const
|
uInt16 CartridgeF6SC::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -214,7 +213,7 @@ bool CartridgeF6SC::patch(uInt16 address, uInt8 value)
|
||||||
myRAM[address & 0x007F] = value;
|
myRAM[address & 0x007F] = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myImage[(myCurrentBank << 12) + address] = value;
|
myImage[myBankOffset + address] = value;
|
||||||
|
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +231,7 @@ bool CartridgeF6SC::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
out.putByteArray(myRAM, 128);
|
out.putByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -252,7 +251,7 @@ bool CartridgeF6SC::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
in.getByteArray(myRAM, 128);
|
in.getByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -262,7 +261,7 @@ bool CartridgeF6SC::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class System;
|
||||||
/**
|
/**
|
||||||
Cartridge class used for Atari's 16K bankswitched games with
|
Cartridge class used for Atari's 16K bankswitched games with
|
||||||
128 bytes of RAM. There are four 4K banks.
|
128 bytes of RAM. There are four 4K banks.
|
||||||
|
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@author Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
|
@ -154,8 +155,8 @@ class CartridgeF6SC : public Cartridge
|
||||||
// The 128 bytes of RAM
|
// The 128 bytes of RAM
|
||||||
uInt8 myRAM[128];
|
uInt8 myRAM[128];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeF8::CartridgeF8(const BytePtr& image, uInt32 size, const string& md5,
|
CartridgeF8::CartridgeF8(const BytePtr& image, uInt32 size, const string& md5,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(8192u, size));
|
memcpy(myImage, image.get(), std::min(8192u, size));
|
||||||
|
@ -78,7 +78,7 @@ uInt8 CartridgeF8::peek(uInt16 address)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -111,8 +111,7 @@ bool CartridgeF8::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -120,7 +119,7 @@ bool CartridgeF8::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +127,8 @@ bool CartridgeF8::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1000; address < (0x1FF8U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1000; address < (0x1FF8U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -138,7 +137,7 @@ bool CartridgeF8::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF8::getBank() const
|
uInt16 CartridgeF8::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -150,7 +149,7 @@ uInt16 CartridgeF8::bankCount() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeF8::patch(uInt16 address, uInt8 value)
|
bool CartridgeF8::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
|
myImage[myBankOffset + (address & 0x0FFF)] = value;
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +166,7 @@ bool CartridgeF8::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +185,7 @@ bool CartridgeF8::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -195,7 +194,7 @@ bool CartridgeF8::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,8 @@ class CartridgeF8 : public Cartridge
|
||||||
// The 8K ROM image of the cartridge
|
// The 8K ROM image of the cartridge
|
||||||
uInt8 myImage[8192];
|
uInt8 myImage[8192];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeF8SC::CartridgeF8SC(const BytePtr& image, uInt32 size,
|
CartridgeF8SC::CartridgeF8SC(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(8192u, size));
|
memcpy(myImage, image.get(), std::min(8192u, size));
|
||||||
|
@ -108,7 +108,7 @@ uInt8 CartridgeF8SC::peek(uInt16 address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -145,8 +145,7 @@ bool CartridgeF8SC::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -154,7 +153,7 @@ bool CartridgeF8SC::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +161,8 @@ bool CartridgeF8SC::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1100; address < (0x1FF8U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1100; address < (0x1FF8U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -172,7 +171,7 @@ bool CartridgeF8SC::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeF8SC::getBank() const
|
uInt16 CartridgeF8SC::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -194,7 +193,7 @@ bool CartridgeF8SC::patch(uInt16 address, uInt8 value)
|
||||||
myRAM[address & 0x007F] = value;
|
myRAM[address & 0x007F] = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myImage[(myCurrentBank << 12) + address] = value;
|
myImage[myBankOffset + address] = value;
|
||||||
|
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +211,7 @@ bool CartridgeF8SC::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
out.putByteArray(myRAM, 128);
|
out.putByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -232,7 +231,7 @@ bool CartridgeF8SC::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
in.getByteArray(myRAM, 128);
|
in.getByteArray(myRAM, 128);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -242,7 +241,7 @@ bool CartridgeF8SC::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class System;
|
||||||
/**
|
/**
|
||||||
Cartridge class used for Atari's 8K bankswitched games with
|
Cartridge class used for Atari's 8K bankswitched games with
|
||||||
128 bytes of RAM. There are two 4K banks.
|
128 bytes of RAM. There are two 4K banks.
|
||||||
|
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@author Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
|
@ -154,8 +155,8 @@ class CartridgeF8SC : public Cartridge
|
||||||
// The 128 bytes of RAM
|
// The 128 bytes of RAM
|
||||||
uInt8 myRAM[128];
|
uInt8 myRAM[128];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
CartridgeFA::CartridgeFA(const BytePtr& image, uInt32 size,
|
CartridgeFA::CartridgeFA(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image.get(), std::min(12288u, size));
|
memcpy(myImage, image.get(), std::min(12288u, size));
|
||||||
|
@ -113,7 +113,7 @@ uInt8 CartridgeFA::peek(uInt16 address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -155,8 +155,7 @@ bool CartridgeFA::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -164,7 +163,7 @@ bool CartridgeFA::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,8 +171,8 @@ bool CartridgeFA::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1200; address < (0x1FF8U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1200; address < (0x1FF8U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -182,7 +181,7 @@ bool CartridgeFA::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeFA::getBank() const
|
uInt16 CartridgeFA::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -204,7 +203,7 @@ bool CartridgeFA::patch(uInt16 address, uInt8 value)
|
||||||
myRAM[address & 0x00FF] = value;
|
myRAM[address & 0x00FF] = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myImage[(myCurrentBank << 12) + address] = value;
|
myImage[myBankOffset + address] = value;
|
||||||
|
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -222,7 +221,7 @@ bool CartridgeFA::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
out.putByteArray(myRAM, 256);
|
out.putByteArray(myRAM, 256);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -242,7 +241,7 @@ bool CartridgeFA::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
in.getByteArray(myRAM, 256);
|
in.getByteArray(myRAM, 256);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -252,7 +251,7 @@ bool CartridgeFA::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class System;
|
||||||
/**
|
/**
|
||||||
Cartridge class used for CBS' RAM Plus cartridges. There are
|
Cartridge class used for CBS' RAM Plus cartridges. There are
|
||||||
three 4K banks and 256 bytes of RAM.
|
three 4K banks and 256 bytes of RAM.
|
||||||
|
RAM read port is $1100 - $11FF, write port is $1000 - $10FF.
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@author Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
|
@ -154,8 +155,8 @@ class CartridgeFA : public Cartridge
|
||||||
// The 256 bytes of RAM on the cartridge
|
// The 256 bytes of RAM on the cartridge
|
||||||
uInt8 myRAM[256];
|
uInt8 myRAM[256];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -27,7 +27,7 @@ CartridgeFA2::CartridgeFA2(const BytePtr& image, uInt32 size,
|
||||||
myOSystem(osystem),
|
myOSystem(osystem),
|
||||||
mySize(28 * 1024),
|
mySize(28 * 1024),
|
||||||
myRamAccessTimeout(0),
|
myRamAccessTimeout(0),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// 29/32K version of FA2 has valid data @ 1K - 29K
|
// 29/32K version of FA2 has valid data @ 1K - 29K
|
||||||
const uInt8* img_ptr = image.get();
|
const uInt8* img_ptr = image.get();
|
||||||
|
@ -152,7 +152,7 @@ uInt8 CartridgeFA2::peek(uInt16 address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return myImage[(myCurrentBank << 12) + address];
|
return myImage[myBankOffset + address];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -221,8 +221,7 @@ bool CartridgeFA2::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
|
@ -230,7 +229,7 @@ bool CartridgeFA2::bank(uInt16 bank)
|
||||||
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
for(uInt32 i = (0x1FF4 & ~System::PAGE_MASK); i < 0x2000;
|
||||||
i += (1 << System::PAGE_SHIFT))
|
i += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,8 +237,8 @@ bool CartridgeFA2::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1200; address < (0x1FF4U & ~System::PAGE_MASK);
|
for(uInt32 address = 0x1200; address < (0x1FF4U & ~System::PAGE_MASK);
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -248,7 +247,7 @@ bool CartridgeFA2::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeFA2::getBank() const
|
uInt16 CartridgeFA2::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -270,7 +269,7 @@ bool CartridgeFA2::patch(uInt16 address, uInt8 value)
|
||||||
myRAM[address & 0x00FF] = value;
|
myRAM[address & 0x00FF] = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myImage[(myCurrentBank << 12) + address] = value;
|
myImage[myBankOffset + address] = value;
|
||||||
|
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +287,7 @@ bool CartridgeFA2::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myBankOffset);
|
||||||
out.putByteArray(myRAM, 256);
|
out.putByteArray(myRAM, 256);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -308,7 +307,7 @@ bool CartridgeFA2::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getShort();
|
||||||
in.getByteArray(myRAM, 256);
|
in.getByteArray(myRAM, 256);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -318,7 +317,7 @@ bool CartridgeFA2::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +387,7 @@ uInt8 CartridgeFA2::ramReadWrite()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bit 6 is 1, busy
|
// Bit 6 is 1, busy
|
||||||
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;
|
return myImage[myBankOffset + 0xFF4] | 0x40;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -399,11 +398,11 @@ uInt8 CartridgeFA2::ramReadWrite()
|
||||||
myRAM[255] = 0; // Successful operation
|
myRAM[255] = 0; // Successful operation
|
||||||
|
|
||||||
// Bit 6 is 0, ready/success
|
// Bit 6 is 0, ready/success
|
||||||
return myImage[(myCurrentBank << 12) + 0xFF4] & ~0x40;
|
return myImage[myBankOffset + 0xFF4] & ~0x40;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// Bit 6 is 1, busy
|
// Bit 6 is 1, busy
|
||||||
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;
|
return myImage[myBankOffset + 0xFF4] | 0x40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,8 +205,8 @@ class CartridgeFA2 : public Cartridge
|
||||||
// of internal RAM to Harmony cart flash
|
// of internal RAM to Harmony cart flash
|
||||||
string myFlashFile;
|
string myFlashFile;
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt16 myBankOffset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -1,270 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "System.hxx"
|
|
||||||
#include "CartMC.hxx"
|
|
||||||
|
|
||||||
// TODO - much more testing of this scheme is required
|
|
||||||
// No test ROMs exist as of 2009-11-08, so we can't be sure how
|
|
||||||
// accurate the emulation is
|
|
||||||
// Bankchange and RAM modification cannot be completed until
|
|
||||||
// adequate test ROMs are available
|
|
||||||
// TODO (2010-10-03) - support CodeAccessBase functionality somehow
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeMC::CartridgeMC(const BytePtr& image, uInt32 size,
|
|
||||||
const Settings& settings)
|
|
||||||
: Cartridge(settings),
|
|
||||||
mySlot3Locked(false)
|
|
||||||
{
|
|
||||||
// Make sure size is reasonable
|
|
||||||
assert(size <= 131072);
|
|
||||||
|
|
||||||
// Set the contents of the entire ROM to 0
|
|
||||||
memset(myImage, 0, 131072);
|
|
||||||
|
|
||||||
// Copy the ROM image to the end of the ROM buffer
|
|
||||||
memcpy(myImage + 131072 - size, image.get(), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeMC::reset()
|
|
||||||
{
|
|
||||||
initializeRAM(myRAM, 32768);
|
|
||||||
|
|
||||||
myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeMC::install(System& system)
|
|
||||||
{
|
|
||||||
mySystem = &system;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Make sure the system we're being installed in has a page size that'll work
|
|
||||||
assert(((0x1000 & mask) == 0) && ((0x1400 & mask) == 0) &&
|
|
||||||
((0x1800 & mask) == 0) && ((0x1C00 & mask) == 0));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set the page accessing methods for the hot spots in the TIA. For
|
|
||||||
// correct emulation I would need to chain any accesses below 0x40 to
|
|
||||||
// the TIA but for now I'll just forget about them.
|
|
||||||
//
|
|
||||||
// TODO: These TIA accesses may need to be chained, however, at this
|
|
||||||
// point Chris isn't sure if the hardware will allow it or not
|
|
||||||
//
|
|
||||||
System::PageAccess access(this, System::PA_READWRITE);
|
|
||||||
|
|
||||||
for(uInt32 i = 0x00; i < 0x40; i += (1 << System::PAGE_SHIFT))
|
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
|
||||||
|
|
||||||
// Map the cartridge into the system
|
|
||||||
access.type = System::PA_READ; // We don't yet indicate RAM areas
|
|
||||||
for(uInt32 j = 0x1000; j < 0x2000; j += (1 << System::PAGE_SHIFT))
|
|
||||||
mySystem->setPageAccess(j >> System::PAGE_SHIFT, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeMC::peek(uInt16 address)
|
|
||||||
{
|
|
||||||
uInt16 peekAddress = address;
|
|
||||||
address &= 0x1FFF;
|
|
||||||
|
|
||||||
// Accessing the RESET vector so lets handle the powerup special case
|
|
||||||
if((address == 0x1FFC) || (address == 0x1FFD))
|
|
||||||
{
|
|
||||||
// Indicate that slot 3 is locked for now
|
|
||||||
mySlot3Locked = true;
|
|
||||||
}
|
|
||||||
// Should we unlock slot 3?
|
|
||||||
else if(mySlot3Locked && (address >= 0x1000) && (address <= 0x1BFF))
|
|
||||||
{
|
|
||||||
// Indicate that slot 3 is unlocked now
|
|
||||||
mySlot3Locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle reads made to the TIA addresses
|
|
||||||
if(address < 0x1000)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uInt8 block;
|
|
||||||
|
|
||||||
if(mySlot3Locked && ((address & 0x0C00) == 0x0C00))
|
|
||||||
{
|
|
||||||
block = 0xFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
block = myCurrentBlock[(address & 0x0C00) >> 10];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this a RAM or a ROM access
|
|
||||||
if(block & 0x80)
|
|
||||||
{
|
|
||||||
// ROM access
|
|
||||||
return myImage[uInt32((block & 0x7F) << 10) + (address & 0x03FF)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This is a RAM access, however, is it to the read or write port?
|
|
||||||
if(address & 0x0200)
|
|
||||||
{
|
|
||||||
// Reading from the read port of the RAM block
|
|
||||||
return myRAM[uInt32((block & 0x3F) << 9) + (address & 0x01FF)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Oops, reading from the write port of the RAM block!
|
|
||||||
// Reading from the write port triggers an unwanted write
|
|
||||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
|
||||||
|
|
||||||
if(bankLocked())
|
|
||||||
return value;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
triggerReadFromWritePort(peekAddress);
|
|
||||||
return myRAM[uInt32((block & 0x3F) << 9) + (address & 0x01FF)] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool CartridgeMC::poke(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
address &= 0x1FFF;
|
|
||||||
|
|
||||||
// Accessing the RESET vector so lets handle the powerup special case
|
|
||||||
if((address == 0x1FFC) || (address == 0x1FFD))
|
|
||||||
{
|
|
||||||
// Indicate that slot 3 is locked for now
|
|
||||||
mySlot3Locked = true;
|
|
||||||
}
|
|
||||||
// Should we unlock slot 3?
|
|
||||||
else if(mySlot3Locked && (address >= 0x1000) && (address <= 0x1BFF))
|
|
||||||
{
|
|
||||||
// Indicate that slot 3 is unlocked now
|
|
||||||
mySlot3Locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle bank-switching writes
|
|
||||||
if((address >= 0x003C) && (address <= 0x003F))
|
|
||||||
{
|
|
||||||
myCurrentBlock[address - 0x003C] = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uInt8 block;
|
|
||||||
|
|
||||||
if(mySlot3Locked && ((address & 0x0C00) == 0x0C00))
|
|
||||||
{
|
|
||||||
block = 0xFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
block = myCurrentBlock[(address & 0x0C00) >> 10];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this a RAM write access
|
|
||||||
if(!(block & 0x80) && !(address & 0x0200))
|
|
||||||
{
|
|
||||||
// Handle the write to RAM
|
|
||||||
myRAM[uInt32((block & 0x3F) << 9) + (address & 0x01FF)] = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 CartridgeMC::getBank() const
|
|
||||||
{
|
|
||||||
// TODO - add support for debugger
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 CartridgeMC::bankCount() const
|
|
||||||
{
|
|
||||||
// TODO - add support for debugger
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool CartridgeMC::patch(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
// TODO - add support for debugger
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const uInt8* CartridgeMC::getImage(int& size) const
|
|
||||||
{
|
|
||||||
size = 128 * 1024;
|
|
||||||
return myImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool CartridgeMC::save(Serializer& out) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
out.putString(name());
|
|
||||||
|
|
||||||
// The currentBlock array
|
|
||||||
out.putByteArray(myCurrentBlock, 4);
|
|
||||||
|
|
||||||
// The 32K of RAM
|
|
||||||
out.putByteArray(myRAM, 32 * 1024);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: CartridgeMC::save" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool CartridgeMC::load(Serializer& in)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(in.getString() != name())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// The currentBlock array
|
|
||||||
in.getByteArray(myCurrentBlock, 4);
|
|
||||||
|
|
||||||
// The 32K of RAM
|
|
||||||
in.getByteArray(myRAM, 32 * 1024);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: CartridgeMC::load" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,271 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef CARTRIDGEMC_HXX
|
|
||||||
#define CARTRIDGEMC_HXX
|
|
||||||
|
|
||||||
class System;
|
|
||||||
|
|
||||||
#include "bspf.hxx"
|
|
||||||
#include "Cart.hxx"
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
#include "CartMCWidget.hxx"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
This is the cartridge class for Chris Wilkson's Megacart. It does not
|
|
||||||
handle battery-backed RAM at this time and the code could use some serious
|
|
||||||
speed improvements. It is based on the following Megacart specification:
|
|
||||||
|
|
||||||
|
|
||||||
Megacart Specification, Rev1.1
|
|
||||||
(c) 1997 Chris Wilkson
|
|
||||||
cwilkson@mit.edu
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The Megacart is an external memory cartridge for the Atari 2600 and compatible
|
|
||||||
home video game consoles. It plugs into the standard cartridge port, and
|
|
||||||
contains a total of 128K bytes of ROM storage and 32K bytes of battery-backed
|
|
||||||
RAM storage.
|
|
||||||
|
|
||||||
General Operation
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The Megacart uses "bank switching" to fit the 160K bytes of physical memory
|
|
||||||
into the console's available 4K address space. Physical memory is divided
|
|
||||||
into 64 RAM blocks of 512 bytes each, and 128 ROM blocks of 1K bytes each.
|
|
||||||
RAM blocks are numbered $00 through $3F, and ROM blocks are numbered $80
|
|
||||||
through $FF.
|
|
||||||
|
|
||||||
The console's address space is divided into 4 slots of 1K each. Any physical
|
|
||||||
memory block can be switched into any memory slot by writing its block number
|
|
||||||
to the "hot address" for the desired slot. Memory locations $3C through $3F
|
|
||||||
serve as "hot addresses" for memory slots 0 through 3, respectively.
|
|
||||||
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
To make ROM addresses $1A400-$1A7FF (block $E9) available to the console at
|
|
||||||
memory locations $F800-$FBFF (slot 2), write $E9 to memory location $3e.
|
|
||||||
|
|
||||||
Caution:
|
|
||||||
|
|
||||||
Note that these memory locations are write only. Trying to read the contents
|
|
||||||
of memory locations $3C through $3F will not only return invalid data, but
|
|
||||||
will also corrupt the contents causing the software to crash. Reading these
|
|
||||||
addresses should not be attempted.
|
|
||||||
|
|
||||||
Special Case - RAM
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
RAM blocks differ from ROM blocks in that one of the console's address lines,
|
|
||||||
A9 in this case, must be used as a read/write select. Because of this, RAM
|
|
||||||
blocks are limited to 512 bytes each, yet still occupy an entire 1K slot.
|
|
||||||
To store a value A9 must be low. To retrieve a value A9 must high.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
First, let's set slot 0 (console addresses $F000-$F3FF) to point to RAM
|
|
||||||
block $9 (RAM $1200-$13ff). To do this, write $9 to console address $3c.
|
|
||||||
To store the value $69 in RAM location $1234, write $69 to console address
|
|
||||||
$F034 (A9=0). To retrieve the value of RAM location $1234, read from console
|
|
||||||
address $F234 (A9=1).
|
|
||||||
|
|
||||||
Special Case - Powerup
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Because the console's memory is randomized at powerup, there is no way to
|
|
||||||
predict the data initially contained in the "hot addresses". Therefore,
|
|
||||||
hardware will force slot 3 to always point to ROM block $FF immediately
|
|
||||||
after any read or write to the RESET vector at $FFFC-$FFFD. Block $FF
|
|
||||||
must contain code to initialize the 4 memory slots to point to the desired
|
|
||||||
physical memory blocks before any other code can be executed. After program
|
|
||||||
execution jumps out of the boot code, the hardware will release slot 3 and
|
|
||||||
it will function just like any other slot.
|
|
||||||
|
|
||||||
Example (the first column is the physical ROM address):
|
|
||||||
|
|
||||||
$00C00 JUNK ... ; random code and data
|
|
||||||
...
|
|
||||||
...
|
|
||||||
...
|
|
||||||
...
|
|
||||||
$1F400 START ... ; program starts here
|
|
||||||
... ; slot 3 now points to rom block $83
|
|
||||||
...
|
|
||||||
...
|
|
||||||
...
|
|
||||||
$1FFDD BOOT SEI ; disable interrupts
|
|
||||||
$1FFDE CLD ; set hexadecimal arithmetic mode
|
|
||||||
$1FFDF LDX #$FF ;
|
|
||||||
$1FFE1 TXS ; set stack pointer to $ff
|
|
||||||
$1FFE2 LDA #$00
|
|
||||||
$1FFE4 ZERO STA 00,X ; clear RIOT and TIA -BEFORE- setting
|
|
||||||
$1FFE6 DEX ; up banks
|
|
||||||
$1FFE7 BNE ZERO
|
|
||||||
$1FFE9 BANKS LDA #$00 ; ram block 0 ($0000-$01ff)
|
|
||||||
$1FFEB STA SLOT0 ; slot 0 points to ram block 0
|
|
||||||
$1FFED LDA #$34 ; ram block $34 ($6800-$69ff)
|
|
||||||
$1FFEF STA SLOT1 ; slot 1 points to ram block $34
|
|
||||||
$1FFF1 LDA #$FD ; rom block $fd ($1f400-$1f7ff)
|
|
||||||
$1FFF3 STA SLOT2 ; slot 2 points to rom block $fd
|
|
||||||
$1FFF5 LDA #$83 ; rom block $83 ($00C00-$01000)
|
|
||||||
$1FFF7 STA SLOT3 ; slot 3 points to bootcode
|
|
||||||
; (rom block $ff)
|
|
||||||
; until jumping out of slot 3
|
|
||||||
$1FFF9 JMP $F800 ; jump to slot 2
|
|
||||||
$1FFFC RESET .WORD $FFDD ; powerup reset vector
|
|
||||||
$1FFFE SWI .WORD $FFDD ; software interrupt vector (BRK)
|
|
||||||
|
|
||||||
|
|
||||||
@author Bradford W. Mott
|
|
||||||
*/
|
|
||||||
class CartridgeMC : public Cartridge
|
|
||||||
{
|
|
||||||
friend class CartridgeMCWidget;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
Create a new cartridge using the specified image and size. If the
|
|
||||||
size of the image is less than 128K then the cartridge will pad the
|
|
||||||
beginning of the 128K ROM with zeros.
|
|
||||||
|
|
||||||
@param image Pointer to the ROM image
|
|
||||||
@param size The size of the ROM image
|
|
||||||
@param settings A reference to the various settings (read-only)
|
|
||||||
*/
|
|
||||||
CartridgeMC(const BytePtr& image, uInt32 size, const Settings& settings);
|
|
||||||
virtual ~CartridgeMC() = 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
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(int& 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).
|
|
||||||
|
|
||||||
@return The name of the object
|
|
||||||
*/
|
|
||||||
string name() const override { return "CartridgeMC"; }
|
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
|
||||||
/**
|
|
||||||
Get debugger widget responsible for accessing the inner workings
|
|
||||||
of the cart.
|
|
||||||
*/
|
|
||||||
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
|
|
||||||
const GUI::Font& nfont, int x, int y, int w, int h) override
|
|
||||||
{
|
|
||||||
return new CartridgeMCWidget(boss, lfont, nfont, x, y, w, h, *this);
|
|
||||||
}
|
|
||||||
#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:
|
|
||||||
// The 128K ROM image for the cartridge
|
|
||||||
uInt8 myImage[131072];
|
|
||||||
|
|
||||||
// The 32K of RAM for the cartridge
|
|
||||||
uInt8 myRAM[32768];
|
|
||||||
|
|
||||||
// Indicates which block is currently active for the four segments
|
|
||||||
uInt8 myCurrentBlock[4];
|
|
||||||
|
|
||||||
// Indicates if slot 3 is locked to block $FF or not
|
|
||||||
bool mySlot3Locked;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Following constructors and assignment operators not supported
|
|
||||||
CartridgeMC() = delete;
|
|
||||||
CartridgeMC(const CartridgeMC&) = delete;
|
|
||||||
CartridgeMC(CartridgeMC&&) = delete;
|
|
||||||
CartridgeMC& operator=(const CartridgeMC&) = delete;
|
|
||||||
CartridgeMC& operator=(CartridgeMC&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -23,7 +23,7 @@ CartridgeMDM::CartridgeMDM(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
mySize(size),
|
mySize(size),
|
||||||
myCurrentBank(0),
|
myBankOffset(0),
|
||||||
myBankingDisabled(false)
|
myBankingDisabled(false)
|
||||||
{
|
{
|
||||||
// Allocate array for the ROM image
|
// Allocate array for the ROM image
|
||||||
|
@ -105,8 +105,7 @@ bool CartridgeMDM::bank(uInt16 bank)
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
// Wrap around to a valid bank number if necessary
|
// Wrap around to a valid bank number if necessary
|
||||||
myCurrentBank = bank % bankCount();
|
myBankOffset = (bank % bankCount()) << 12;
|
||||||
uInt32 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
// Setup the page access methods for the current bank
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
@ -115,8 +114,8 @@ bool CartridgeMDM::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1000; address < 0x2000;
|
for(uInt32 address = 0x1000; address < 0x2000;
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +128,7 @@ bool CartridgeMDM::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeMDM::getBank() const
|
uInt16 CartridgeMDM::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -141,7 +140,7 @@ uInt16 CartridgeMDM::bankCount() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeMDM::patch(uInt16 address, uInt8 value)
|
bool CartridgeMDM::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
|
myImage[myBankOffset + (address & 0x0FFF)] = value;
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +157,7 @@ bool CartridgeMDM::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putInt(myBankOffset);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -177,7 +176,7 @@ bool CartridgeMDM::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getInt();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +185,7 @@ bool CartridgeMDM::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,8 +169,8 @@ class CartridgeMDM : public Cartridge
|
||||||
// Previous Device's page access
|
// Previous Device's page access
|
||||||
System::PageAccess myHotSpotPageAccess[8];
|
System::PageAccess myHotSpotPageAccess[8];
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt32 myBankOffset;
|
||||||
|
|
||||||
// Indicates whether banking has been disabled due to a bankswitch
|
// Indicates whether banking has been disabled due to a bankswitch
|
||||||
// above bank 127
|
// above bank 127
|
||||||
|
|
|
@ -23,7 +23,7 @@ CartridgeSB::CartridgeSB(const BytePtr& image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
mySize(size),
|
mySize(size),
|
||||||
myCurrentBank(0)
|
myBankOffset(0)
|
||||||
{
|
{
|
||||||
// Allocate array for the ROM image
|
// Allocate array for the ROM image
|
||||||
myImage = make_unique<uInt8[]>(mySize);
|
myImage = make_unique<uInt8[]>(mySize);
|
||||||
|
@ -114,8 +114,7 @@ bool CartridgeSB::bank(uInt16 bank)
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myBankOffset = bank << 12;
|
||||||
uInt32 offset = myCurrentBank << 12;
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
// Setup the page access methods for the current bank
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
@ -124,8 +123,8 @@ bool CartridgeSB::bank(uInt16 bank)
|
||||||
for(uInt32 address = 0x1000; address < 0x2000;
|
for(uInt32 address = 0x1000; address < 0x2000;
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
{
|
{
|
||||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
|
||||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
|
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||||
}
|
}
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
|
@ -134,7 +133,7 @@ bool CartridgeSB::bank(uInt16 bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 CartridgeSB::getBank() const
|
uInt16 CartridgeSB::getBank() const
|
||||||
{
|
{
|
||||||
return myCurrentBank;
|
return myBankOffset >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -146,7 +145,7 @@ uInt16 CartridgeSB::bankCount() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeSB::patch(uInt16 address, uInt8 value)
|
bool CartridgeSB::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
|
myImage[myBankOffset + (address & 0x0FFF)] = value;
|
||||||
return myBankChanged = true;
|
return myBankChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +162,7 @@ bool CartridgeSB::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
out.putShort(myCurrentBank);
|
out.putInt(myBankOffset);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -182,7 +181,7 @@ bool CartridgeSB::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCurrentBank = in.getShort();
|
myBankOffset = in.getInt();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -191,7 +190,7 @@ bool CartridgeSB::load(Serializer& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember what bank we were in
|
// Remember what bank we were in
|
||||||
bank(myCurrentBank);
|
bank(myBankOffset >> 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,8 @@ class CartridgeSB : public Cartridge
|
||||||
BytePtr myImage;
|
BytePtr myImage;
|
||||||
uInt32 mySize;
|
uInt32 mySize;
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates the offset into the ROM image (aligns to current bank)
|
||||||
uInt16 myCurrentBank;
|
uInt32 myBankOffset;
|
||||||
|
|
||||||
// Previous Device's page access
|
// Previous Device's page access
|
||||||
System::PageAccess myHotSpotPageAccess[8];
|
System::PageAccess myHotSpotPageAccess[8];
|
||||||
|
|
|
@ -41,7 +41,6 @@ MODULE_OBJS := \
|
||||||
src/emucore/CartFA.o \
|
src/emucore/CartFA.o \
|
||||||
src/emucore/CartFA2.o \
|
src/emucore/CartFA2.o \
|
||||||
src/emucore/CartFE.o \
|
src/emucore/CartFE.o \
|
||||||
src/emucore/CartMC.o \
|
|
||||||
src/emucore/CartMDM.o \
|
src/emucore/CartMDM.o \
|
||||||
src/emucore/CartSB.o \
|
src/emucore/CartSB.o \
|
||||||
src/emucore/CartUA.o \
|
src/emucore/CartUA.o \
|
||||||
|
|
Loading…
Reference in New Issue