Added Compumate to the debugger ROM tab, but there are still

a few UI items left to complete.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2704 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-04-22 16:41:05 +00:00
parent 777a6ceb8c
commit 9a8dc860c0
8 changed files with 306 additions and 14 deletions

View File

@ -0,0 +1,198 @@
//============================================================================
//
// 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 "CartCM.hxx"
#include "RiotDebug.hxx"
#include "DataGridWidget.hxx"
#include "PopUpWidget.hxx"
#include "ToggleBitWidget.hxx"
#include "CartCMWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeCMWidget::CartridgeCMWidget(
GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, CartridgeCM& cart)
: CartDebugWidget(boss, font, x, y, w, h),
myCart(cart)
{
uInt16 size = 4 * 4096;
string info =
"CM cartridge, four 4K banks + 2K RAM\n"
"2K RAM accessible @ $1800 - $1FFF in read or write-only mode "
"(no separate ports)\n"
"All TIA controller registers (INPT0-INPT5) and RIOT SWCHA are "
"used to control the cart functionality\n"
"Startup bank = 3 (ROM), RAM disabled\n";
int xpos = 10,
ypos = addBaseInformation(size, "CompuMate", info) + myLineHeight;
StringMap items;
items.push_back(" 0 ", "0");
items.push_back(" 1 ", "1");
items.push_back(" 2 ", "2");
items.push_back(" 3 ", "3");
myBank =
new PopUpWidget(boss, font, xpos, ypos-2, font.getStringWidth(" 0 "),
myLineHeight, items, "Set bank: ",
font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
// Raw SWCHA value (this will be broken down further in other UI elements)
int lwidth = font.getStringWidth("Current column: ");
ypos += myLineHeight + 8;
new StaticTextWidget(boss, font, xpos, ypos+2, lwidth, myFontHeight,
"Current SWCHA: ", kTextAlignLeft);
xpos += lwidth;
mySWCHA = new ToggleBitWidget(boss, font, xpos, ypos, 8, 1);
mySWCHA->setTarget(this);
mySWCHA->setEditable(false);
// Current column number
xpos = 10; ypos += myLineHeight + 5;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Current column: ", kTextAlignLeft);
xpos += lwidth;
myColumn = new DataGridWidget(boss, font, xpos, ypos-2, 1, 1, 2, 8, kBASE_16);
myColumn->setTarget(this);
myColumn->setEditable(false);
// Relevant pins of SWCHA
xpos = 30;
// D6 (column part)
ypos += myLineHeight + 8;
myIncrease = new CheckboxWidget(boss, font, xpos, ypos, "Increase Column");
myIncrease->setTarget(this);
myIncrease->setEditable(false);
int orig_ypos = ypos; // save for when we go to the next column
// D5 (column part)
ypos += myLineHeight + 4;
myReset = new CheckboxWidget(boss, font, xpos, ypos, "Reset Column");
myReset->setTarget(this);
myReset->setEditable(false);
// Row inputs
ypos += myLineHeight + 4;
myRow[0] = new CheckboxWidget(boss, font, xpos, ypos, "Row 0");
myRow[0]->setTarget(this);
myRow[0]->setEditable(false);
ypos += myLineHeight + 4;
myRow[1] = new CheckboxWidget(boss, font, xpos, ypos, "Row 1");
myRow[1]->setTarget(this);
myRow[1]->setEditable(false);
ypos += myLineHeight + 4;
myRow[2] = new CheckboxWidget(boss, font, xpos, ypos, "Row 2");
myRow[2]->setTarget(this);
myRow[2]->setEditable(false);
ypos += myLineHeight + 4;
myRow[3] = new CheckboxWidget(boss, font, xpos, ypos, "Row 3");
myRow[3]->setTarget(this);
myRow[3]->setEditable(false);
// Func and Shift keys
ypos += myLineHeight + 4;
myFunc = new CheckboxWidget(boss, font, xpos, ypos, "FUNC key pressed");
myFunc->setTarget(this);
myFunc->setEditable(false);
ypos += myLineHeight + 4;
myShift = new CheckboxWidget(boss, font, xpos, ypos, "Shift key pressed");
myShift->setTarget(this);
myShift->setEditable(false);
// Move to next column
xpos += myShift->getWidth() + 20; ypos = orig_ypos;
// D7
myAudIn = new CheckboxWidget(boss, font, xpos, ypos, "Audio Input");
myAudIn->setTarget(this);
myAudIn->setEditable(false);
// D6 (audio part)
ypos += myLineHeight + 4;
myAudOut = new CheckboxWidget(boss, font, xpos, ypos, "Audio Output");
myAudOut->setTarget(this);
myAudOut->setEditable(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCMWidget::saveOldState()
{
myOldState.swcha = myCart.mySWCHA;
myOldState.column = myCart.myColumn;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCMWidget::loadConfig()
{
myBank->setSelected(myCart.myCurrentBank);
RiotDebug& riot = Debugger::debugger().riotDebug();
const RiotState& state = (RiotState&) riot.getState();
uInt8 swcha = myCart.mySWCHA;
// SWCHA
BoolArray oldbits, newbits, changed;
Debugger::set_bits(myOldState.swcha, oldbits);
Debugger::set_bits(swcha, newbits);
for(uInt32 i = 0; i < oldbits.size(); ++i)
changed.push_back(oldbits[i] != newbits[i]);
mySWCHA->setState(newbits, changed);
// Column
myColumn->setList(0, myCart.myColumn, myCart.myColumn != myOldState.column);
// Various bits from SWCHA and INPTx
myIncrease->setState(swcha & 0x40);
myReset->setState(swcha & 0x20);
myRow[0]->setState(!(state.INPT4 & 0x80));
myRow[1]->setState(!(swcha & 0x04));
myRow[2]->setState(!(state.INPT5 & 0x80));
myRow[3]->setState(!(swcha & 0x08));
myFunc->setState(state.INPT0 & 0x80);
myShift->setState(state.INPT3 & 0x80);
myAudIn->setState(swcha & 0x80);
myAudOut->setState(swcha & 0x40);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeCMWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.mySWCHA &= 0xFC;
myCart.mySWCHA |= myBank->getSelected();
myCart.bank(myCart.mySWCHA & 0x03);
myCart.lockBank();
invalidate();
}
}

View File

@ -0,0 +1,66 @@
//============================================================================
//
// 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 CARTRIDGECM_WIDGET_HXX
#define CARTRIDGECM_WIDGET_HXX
class CartridgeCM;
class CheckboxWidget;
class DataGridWidget;
class PopUpWidget;
class ToggleBitWidget;
#include "CartDebugWidget.hxx"
class CartridgeCMWidget : public CartDebugWidget
{
public:
CartridgeCMWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h,
CartridgeCM& cart);
virtual ~CartridgeCMWidget() { }
void saveOldState();
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
private:
struct CartState {
uInt8 swcha;
uInt8 column;
};
private:
CartridgeCM& myCart;
PopUpWidget* myBank;
ToggleBitWidget* mySWCHA;
DataGridWidget* myColumn;
CheckboxWidget *myAudIn, *myAudOut, *myIncrease, *myReset;
CheckboxWidget* myRow[4];
CheckboxWidget *myFunc, *myShift;
PopUpWidget* myRAM;
CartState myOldState;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -60,7 +60,7 @@ class CartridgeDPCWidget : public CartDebugWidget
DataGridWidget* myMusicMode;
DataGridWidget* myRandom;
CartState myState, myOldState;
CartState myOldState;
enum { kBankChanged = 'bkCH' };
};

View File

@ -38,6 +38,16 @@ ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
_rowHeight = font.getLineHeight();
_colWidth = colchars * font.getMaxCharWidth() + 8;
// Make sure all lists contain some default values
int size = _rows * _cols;
while(size--)
{
_offList.push_back("0");
_onList.push_back("1");
_stateList.push_back(false);
_changedList.push_back(false);
}
// Calculate real dimensions
_w = _colWidth * cols + 1;
_h = _rowHeight * rows + 1;

View File

@ -25,6 +25,7 @@ MODULE_OBJS := \
src/debugger/gui/Cart3FWidget.o \
src/debugger/gui/Cart4A50Widget.o \
src/debugger/gui/Cart4KWidget.o \
src/debugger/gui/CartCMWidget.o \
src/debugger/gui/CartCVWidget.o \
src/debugger/gui/CartDPCWidget.o \
src/debugger/gui/CartDPCPlusWidget.o \

View File

@ -38,8 +38,8 @@ CartridgeCM::CartridgeCM(const uInt8* image, uInt32 size, const Settings& settin
// On powerup, portA is all 1's, so the last bank of ROM is enabled and
// RAM is disabled
myStartBank = 3;
myRamState = 0x10;
mySWCHA = 0xff;
myStartBank = mySWCHA & 0x3;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -97,8 +97,8 @@ bool CartridgeCM::poke(uInt16 address, uInt8 value)
// RIOT mirroring, check bankswitch
if(address == 0x280)
{
myRamState = value;
bank(myRamState & 0x3);
mySWCHA = value;
bank(mySWCHA & 0x3);
if(value & 0x20) myColumn = 0;
if(value & 0x40) myColumn = (myColumn + 1) % 10;
}
@ -140,7 +140,7 @@ bool CartridgeCM::bank(uInt16 bank)
{
access.type = System::PA_READWRITE;
if(myRamState & 0x10)
if(mySWCHA & 0x10)
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
@ -151,7 +151,7 @@ bool CartridgeCM::bank(uInt16 bank)
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x07FF)];
}
if((myRamState & 0x30) == 0x20)
if((mySWCHA & 0x30) == 0x20)
access.directPokeBase = &myRAM[address & 0x7FF];
else
access.directPokeBase = 0;
@ -181,7 +181,7 @@ uInt16 CartridgeCM::bankCount() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeCM::patch(uInt16 address, uInt8 value)
{
if((myRamState & 0x30) == 0x20)
if((mySWCHA & 0x30) == 0x20)
myRAM[address & 0x7FF] = value;
else
myImage[(myCurrentBank << 12) + address] = value;
@ -203,7 +203,7 @@ bool CartridgeCM::save(Serializer& out) const
{
out.putString(name());
out.putShort(myCurrentBank);
out.putByte(myRamState);
out.putByte(mySWCHA);
out.putByte(myColumn);
out.putByteArray(myRAM, 2048);
}
@ -225,7 +225,7 @@ bool CartridgeCM::load(Serializer& in)
return false;
myCurrentBank = in.getShort();
myRamState = in.getByte();
mySWCHA = in.getByte();
myColumn = in.getByte();
in.getByteArray(myRAM, 2048);
}

View File

@ -24,6 +24,9 @@ class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartCMWidget.hxx"
#endif
/**
Cartridge class used for SpectraVideo CompuMate bankswitched games.
@ -105,6 +108,8 @@ class System;
*/
class CartridgeCM : public Cartridge
{
friend class CartridgeCMWidget;
public:
/**
Create a new cartridge using the specified image
@ -191,6 +196,18 @@ class CartridgeCM : public Cartridge
*/
string name() const { return "CartridgeCM"; }
#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 CartridgeCMWidget(boss, font, x, y, w, h, *this);
}
#endif
public:
/**
Get the byte at the specified address.
@ -225,8 +242,8 @@ class CartridgeCM : public Cartridge
// The 2K of RAM
uInt8 myRAM[2048];
// RAM read/write state
uInt8 myRamState;
// Current copy of SWCHA (controls ROM/RAM accesses)
uInt8 mySWCHA;
// Column currently active
uInt8 myColumn;

View File

@ -62,8 +62,8 @@ class CompuMate
/**
Return the left and right CompuMate controllers
*/
Controller* leftController() { return (Controller*) myLeftController; }
Controller* rightController() { return (Controller*) myRightController; }
Controller* leftController() { return myLeftController; }
Controller* rightController() { return myRightController; }
private:
/**