Added 4A50 scheme to the debugger ROM tab. They're starting to get

a lot more complex ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2699 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-04-18 15:30:19 +00:00
parent df77cc8997
commit ff09b61c55
5 changed files with 413 additions and 62 deletions

View File

@ -0,0 +1,277 @@
//============================================================================
//
// 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-2013 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.
//
// $Id$
//============================================================================
#include "Cart4A50.hxx"
#include "PopUpWidget.hxx"
#include "Cart4A50Widget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4A50Widget::Cartridge4A50Widget(
GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, Cartridge4A50& cart)
: CartDebugWidget(boss, font, x, y, w, h),
myCart(cart)
{
string info =
"4A50 cartridge - 128K ROM and 32K RAM, split in various bank configurations\n"
"Multiple hotspots, see documentation for further details\n"
"Lower bank region (2K) : $F000 - $F7FF\n"
"Middle bank region (1.5K): $F800 - $FDFF\n"
"High bank region (256B) : $FE00 - $FEFF\n"
"Fixed (last 256B of ROM) : $FF00 - $FFFF\n";
int xpos = 10,
ypos = addBaseInformation(cart.mySize, "John Payson / Supercat", info) +
myLineHeight;
StringMap items16, items32, items128, items256;
for(uInt32 i = 0; i < 16; ++i)
{
const string& b = BSPF_toString(i);
items16.push_back(b, b);
}
items16.push_back("Inactive", "");
for(uInt32 i = 0; i < 32; ++i)
{
const string& b = BSPF_toString(i);
items32.push_back(b, b);
}
items32.push_back("Inactive", "");
for(uInt32 i = 0; i < 128; ++i)
{
const string& b = BSPF_toString(i);
items128.push_back(b, b);
}
items128.push_back("Inactive", "");
for(uInt32 i = 0; i < 256; ++i)
{
const string& b = BSPF_toString(i);
items256.push_back(b, b);
}
items256.push_back("Inactive", "");
string lowerlabel = "Set lower 2K region ($F000 - $F7FF): ";
string middlelabel = "Set middle 1.5K region ($F800 - $FDFF): ";
string highlabel = "Set high 256B region ($FE00 - $FEFF): ";
const int lwidth = font.getStringWidth(middlelabel),
fwidth = font.getStringWidth("Inactive"),
flwidth = font.getStringWidth("ROM: ");
// Lower bank/region configuration
xpos = 10;
new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
myFontHeight, lowerlabel, kTextAlignLeft);
ypos += myLineHeight + 8;
xpos += 40;
myROMLower =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items32, "ROM: ", flwidth, kROMLowerChanged);
myROMLower->setTarget(this);
addFocusWidget(myROMLower);
xpos += myROMLower->getWidth() + 20;
myRAMLower =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items16, "RAM: ", flwidth, kRAMLowerChanged);
myRAMLower->setTarget(this);
addFocusWidget(myRAMLower);
// Middle bank/region configuration
xpos = 10; ypos += myLineHeight + 14;
new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
myFontHeight, middlelabel, kTextAlignLeft);
ypos += myLineHeight + 8;
xpos += 40;
myROMMiddle =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items32, "ROM: ", flwidth, kROMMiddleChanged);
myROMMiddle->setTarget(this);
addFocusWidget(myROMMiddle);
xpos += myROMMiddle->getWidth() + 20;
myRAMMiddle =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items16, "RAM: ", flwidth, kRAMMiddleChanged);
myRAMMiddle->setTarget(this);
addFocusWidget(myRAMMiddle);
// High bank/region configuration
xpos = 10; ypos += myLineHeight + 14;
new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
myFontHeight, highlabel, kTextAlignLeft);
ypos += myLineHeight + 8;
xpos += 40;
myROMHigh =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items256, "ROM: ", flwidth, kROMHighChanged);
myROMHigh->setTarget(this);
addFocusWidget(myROMHigh);
xpos += myROMHigh->getWidth() + 20;
myRAMHigh =
new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight,
items128, "RAM: ", flwidth, kRAMHighChanged);
myRAMHigh->setTarget(this);
addFocusWidget(myRAMHigh);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50Widget::loadConfig()
{
// Lower bank
if(myCart.myIsRomLow) // ROM active
{
myROMLower->setSelected((myCart.mySliceLow >> 11) & 0x1F);
myRAMLower->setSelectedMax();
}
else // RAM active
{
myROMLower->setSelectedMax();
myRAMLower->setSelected((myCart.mySliceLow >> 11) & 0x0F);
}
// Middle bank
if(myCart.myIsRomMiddle) // ROM active
{
myROMMiddle->setSelected((myCart.mySliceMiddle >> 11) & 0x1F);
myRAMMiddle->setSelectedMax();
}
else // RAM active
{
myROMMiddle->setSelectedMax();
myRAMMiddle->setSelected((myCart.mySliceMiddle >> 11) & 0x0F);
}
// High bank
if(myCart.myIsRomHigh) // ROM active
{
myROMHigh->setSelected((myCart.mySliceHigh >> 11) & 0xFF);
myRAMHigh->setSelectedMax();
}
else // RAM active
{
myROMHigh->setSelectedMax();
myRAMHigh->setSelected((myCart.mySliceHigh >> 11) & 0x7F);
}
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50Widget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
myCart.unlockBank();
switch(cmd)
{
case kROMLowerChanged:
if(myROMLower->getSelected() < 32)
{
myCart.bankROMLower(myROMLower->getSelected());
myRAMLower->setSelectedMax();
}
else
{
// default to first RAM bank
myRAMLower->setSelected(0);
myCart.bankRAMLower(0);
}
break;
case kRAMLowerChanged:
if(myRAMLower->getSelected() < 16)
{
myROMLower->setSelectedMax();
myCart.bankRAMLower(myRAMLower->getSelected());
}
else
{
// default to first ROM bank
myROMLower->setSelected(0);
myCart.bankROMLower(0);
}
break;
case kROMMiddleChanged:
if(myROMMiddle->getSelected() < 32)
{
myCart.bankROMMiddle(myROMMiddle->getSelected());
myRAMMiddle->setSelectedMax();
}
else
{
// default to first RAM bank
myRAMMiddle->setSelected(0);
myCart.bankRAMMiddle(0);
}
break;
case kRAMMiddleChanged:
if(myRAMMiddle->getSelected() < 16)
{
myROMMiddle->setSelectedMax();
myCart.bankRAMMiddle(myRAMMiddle->getSelected());
}
else
{
// default to first ROM bank
myROMMiddle->setSelected(0);
myCart.bankROMMiddle(0);
}
break;
case kROMHighChanged:
if(myROMHigh->getSelected() < 256)
{
myCart.bankROMHigh(myROMHigh->getSelected());
myRAMHigh->setSelectedMax();
}
else
{
// default to first RAM bank
myRAMHigh->setSelected(0);
myCart.bankRAMHigh(0);
}
break;
case kRAMHighChanged:
if(myRAMHigh->getSelected() < 128)
{
myROMHigh->setSelectedMax();
myCart.bankRAMHigh(myRAMHigh->getSelected());
}
else
{
// default to first ROM bank
myROMHigh->setSelected(0);
myCart.bankROMHigh(0);
}
break;
}
myCart.lockBank();
invalidate();
}

View File

@ -0,0 +1,55 @@
//============================================================================
//
// 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-2013 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.
//
// $Id$
//============================================================================
#ifndef CARTRIDGE4A50_WIDGET_HXX
#define CARTRIDGE4A50_WIDGET_HXX
class Cartridge4A50;
class PopUpWidget;
#include "CartDebugWidget.hxx"
class Cartridge4A50Widget : public CartDebugWidget
{
public:
Cartridge4A50Widget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h,
Cartridge4A50& cart);
virtual ~Cartridge4A50Widget() { }
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
private:
Cartridge4A50& myCart;
PopUpWidget *myROMLower, *myRAMLower;
PopUpWidget *myROMMiddle, *myRAMMiddle;
PopUpWidget *myROMHigh, *myRAMHigh;
enum {
kROMLowerChanged = 'rmLW',
kRAMLowerChanged = 'raLW',
kROMMiddleChanged = 'rmMD',
kRAMMiddleChanged = 'raMD',
kROMHighChanged = 'rmHI',
kRAMHighChanged = 'raHI'
};
};
#endif

View File

@ -23,6 +23,7 @@ MODULE_OBJS := \
src/debugger/gui/Cart2KWidget.o \
src/debugger/gui/Cart3EWidget.o \
src/debugger/gui/Cart3FWidget.o \
src/debugger/gui/Cart4A50Widget.o \
src/debugger/gui/Cart4KWidget.o \
src/debugger/gui/CartCVWidget.o \
src/debugger/gui/CartE0Widget.o \

View File

@ -28,7 +28,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4A50::Cartridge4A50(const uInt8* image, uInt32 size,
const Settings& settings)
: Cartridge(settings)
: Cartridge(settings),
mySize(size)
{
// Copy the ROM image into my buffer
// Supported file sizes are 32/64/128K, which are duplicated if necessary
@ -275,41 +276,17 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
((myLastAddress >= 0x1000) || (myLastAddress < 0x200)))
{
if((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
myIsRomHigh = true;
mySliceHigh = (address & 0xff) << 8;
myBankChanged = true;
}
bankROMHigh(address & 0xff);
else if((address & 0x0f00) == 0x0d00) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
myIsRomHigh = false;
mySliceHigh = (address & 0x7f) << 8;
myBankChanged = true;
}
bankRAMHigh(address & 0x7f);
else if((address & 0x0f40) == 0x0e00) // Enable 2K of ROM at 0x1000 - 0x17ff
{
myIsRomLow = true;
mySliceLow = (address & 0x1f) << 11;
myBankChanged = true;
}
bankROMLower(address & 0x1f);
else if((address & 0x0f40) == 0x0e40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
myIsRomLow = false;
mySliceLow = (address & 0xf) << 11;
myBankChanged = true;
}
bankRAMLower(address & 0xf);
else if((address & 0x0f40) == 0x0f00) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
myIsRomMiddle = true;
mySliceMiddle = (address & 0x1f) << 11;
myBankChanged = true;
}
bankROMMiddle(address & 0x1f);
else if((address & 0x0f50) == 0x0f40) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
myIsRomMiddle = false;
mySliceMiddle = (address & 0xf) << 11;
myBankChanged = true;
}
bankRAMMiddle(address & 0xf);
// Stella helper functions
else if((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
@ -339,17 +316,9 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
// 0xf5, 0xf7, 0xfd, 0xff for RAM
// 0x74 - 0x7f (0x80 bytes lower)
if((address & 0xf75) == 0x74) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
myIsRomHigh = true;
mySliceHigh = value << 8;
myBankChanged = true;
}
bankROMHigh(value);
else if((address & 0xf75) == 0x75) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
myIsRomHigh = false;
mySliceHigh = (value & 0x7f) << 8;
myBankChanged = true;
}
bankRAMHigh(value & 0x7f);
// Zero-page hotspots for lower and middle blocks
// 0xf8, 0xf9, 0xfa, 0xfb
@ -357,29 +326,13 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value)
else if((address & 0xf7c) == 0x78)
{
if((value & 0xf0) == 0) // Enable 2K of ROM at 0x1000 - 0x17ff
{
myIsRomLow = true;
mySliceLow = (value & 0xf) << 11;
myBankChanged = true;
}
bankROMLower(value & 0xf);
else if((value & 0xf0) == 0x40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
myIsRomLow = false;
mySliceLow = (value & 0xf) << 11;
myBankChanged = true;
}
bankRAMLower(value & 0xf);
else if((value & 0xf0) == 0x90) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
myIsRomMiddle = true;
mySliceMiddle = ((value & 0xf) | 0x10) << 11;
myBankChanged = true;
}
bankROMMiddle((value & 0xf) | 0x10);
else if((value & 0xf0) == 0xc0) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
myIsRomMiddle = false;
mySliceMiddle = (value & 0xf) << 11;
myBankChanged = true;
}
bankRAMMiddle(value & 0xf);
}
}
@ -440,7 +393,7 @@ bool Cartridge4A50::patch(uInt16 address, uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* Cartridge4A50::getImage(int& size) const
{
size = 131072;
size = mySize;
return myImage;
}

View File

@ -24,6 +24,9 @@ class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "Cart4A50Widget.hxx"
#endif
/**
Bankswitching method as defined/created by John Payson (aka Supercat),
@ -48,6 +51,8 @@ class System;
*/
class Cartridge4A50 : public Cartridge
{
friend class Cartridge4A50Widget;
public:
/**
Create a new cartridge using the specified image
@ -134,6 +139,18 @@ class Cartridge4A50 : public Cartridge
*/
string name() const { return "Cartridge4A50"; }
#ifdef DEBUGGER_SUPPORT
/**
Get debugger widget responsible for accessing the inner workings
of the cart.
*/
CartDebugWidget* debugWidget(GuiObject* boss,
const GUI::Font& font, int x, int y, int w, int h)
{
return new Cartridge4A50Widget(boss, font, x, y, w, h, *this);
}
#endif
public:
/**
Get the byte at the specified address.
@ -166,6 +183,51 @@ class Cartridge4A50 : public Cartridge
*/
void checkBankSwitch(uInt16 address, uInt8 value);
/**
Methods to perform all the ways that banks can be switched
*/
inline void bankROMLower(uInt16 value)
{
myIsRomLow = true;
mySliceLow = value << 11;
myBankChanged = true;
}
inline void bankRAMLower(uInt16 value)
{
myIsRomLow = false;
mySliceLow = value << 11;
myBankChanged = true;
}
inline void bankROMMiddle(uInt16 value)
{
myIsRomMiddle = true;
mySliceMiddle = value << 11;
myBankChanged = true;
}
inline void bankRAMMiddle(uInt16 value)
{
myIsRomMiddle = false;
mySliceMiddle = value << 11;
myBankChanged = true;
}
inline void bankROMHigh(uInt16 value)
{
myIsRomHigh = true;
mySliceHigh = value << 8;
myBankChanged = true;
}
inline void bankRAMHigh(uInt16 value)
{
myIsRomHigh = false;
mySliceHigh = value << 8;
myBankChanged = true;
}
private:
// The 128K ROM image of the cartridge
uInt8 myImage[131072];
@ -173,6 +235,9 @@ class Cartridge4A50 : public Cartridge
// The 32K of RAM on the cartridge
uInt8 myRAM[32768];
// (Actual) Size of the ROM image
uInt32 mySize;
// Indicates the slice mapped into each of the three segments
uInt16 mySliceLow; /* index pointer for $1000-$17ff slice */
uInt16 mySliceMiddle; /* index pointer for $1800-$1dff slice */