Added ability to change controller port pins from the POV of the

controller to the RIOT debugger tab.  For now, it's very joystick-
centric, and will remain that way for the next release.  Also, the
states are inverted, in that selecting 'up' for port 0 actually
turns the checkbox *on*.  This is more intuitive from the POV of the
user, but in actual fact behind the scenes the bit is set to 0!

This is all I'm including wrt the controller ports for the next
release.  The dumped INPTx registers will have to wait.

Still TODO is add the console switches to the RIOT tab.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1507 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-05-15 15:07:29 +00:00
parent 865fc88e7c
commit ff48c93a02
8 changed files with 210 additions and 74 deletions

View File

@ -22,7 +22,7 @@ Stephen Anthony at stephena@users.sourceforge.net.
* Improve debugger support for cartridges with dedicated RAM, and add
source-level debugging
* Add support for uncommon controllers (KidVid, Lightgun, Amiga/ST mouse)
* Add support for uncommon controllers (KidVid, Lightgun, etc)
* Either Support DASM as frontend or integrate a 6507 Assembler

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RiotDebug.cxx,v 1.4 2008-05-13 15:13:17 stephena Exp $
// $Id: RiotDebug.cxx,v 1.5 2008-05-15 15:07:29 stephena Exp $
//============================================================================
#include <sstream>
@ -51,6 +51,20 @@ const DebuggerState& RiotDebug::getState()
myState.TIMINT = timint();
myState.TIMCLKS = timClocks();
// Controller port pins
Controller& port0 = mySystem.m6532().myConsole.controller(Controller::Left);
myState.P0_PIN1 = port0.myDigitalPinState[Controller::One];
myState.P0_PIN2 = port0.myDigitalPinState[Controller::Two];
myState.P0_PIN3 = port0.myDigitalPinState[Controller::Three];
myState.P0_PIN4 = port0.myDigitalPinState[Controller::Four];
myState.P0_PIN6 = port0.myDigitalPinState[Controller::Six];
Controller& port1 = mySystem.m6532().myConsole.controller(Controller::Right);
myState.P1_PIN1 = port1.myDigitalPinState[Controller::One];
myState.P1_PIN2 = port1.myDigitalPinState[Controller::Two];
myState.P1_PIN3 = port1.myDigitalPinState[Controller::Three];
myState.P1_PIN4 = port1.myDigitalPinState[Controller::Four];
myState.P1_PIN6 = port1.myDigitalPinState[Controller::Six];
return myState;
}
@ -75,6 +89,20 @@ void RiotDebug::saveOldState()
myOldState.INTIM = intim();
myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks();
// Controller port pins
Controller& port0 = mySystem.m6532().myConsole.controller(Controller::Left);
myOldState.P0_PIN1 = port0.myDigitalPinState[Controller::One];
myOldState.P0_PIN2 = port0.myDigitalPinState[Controller::Two];
myOldState.P0_PIN3 = port0.myDigitalPinState[Controller::Three];
myOldState.P0_PIN4 = port0.myDigitalPinState[Controller::Four];
myOldState.P0_PIN6 = port0.myDigitalPinState[Controller::Six];
Controller& port1 = mySystem.m6532().myConsole.controller(Controller::Right);
myOldState.P1_PIN1 = port1.myDigitalPinState[Controller::One];
myOldState.P1_PIN2 = port1.myDigitalPinState[Controller::Two];
myOldState.P1_PIN3 = port1.myDigitalPinState[Controller::Three];
myOldState.P1_PIN4 = port1.myDigitalPinState[Controller::Four];
myOldState.P1_PIN6 = port1.myDigitalPinState[Controller::Six];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -159,6 +187,28 @@ Int32 RiotDebug::timClocks()
return mySystem.m6532().timerClocks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RiotDebug::setP0Pins(bool Pin1, bool Pin2, bool Pin3, bool Pin4, bool Pin6)
{
Controller& port0 = mySystem.m6532().myConsole.controller(Controller::Left);
port0.myDigitalPinState[Controller::One] = Pin1;
port0.myDigitalPinState[Controller::Two] = Pin2;
port0.myDigitalPinState[Controller::Three] = Pin3;
port0.myDigitalPinState[Controller::Four] = Pin4;
port0.myDigitalPinState[Controller::Six] = Pin6;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RiotDebug::setP1Pins(bool Pin1, bool Pin2, bool Pin3, bool Pin4, bool Pin6)
{
Controller& port1 = mySystem.m6532().myConsole.controller(Controller::Right);
port1.myDigitalPinState[Controller::One] = Pin1;
port1.myDigitalPinState[Controller::Two] = Pin2;
port1.myDigitalPinState[Controller::Three] = Pin3;
port1.myDigitalPinState[Controller::Four] = Pin4;
port1.myDigitalPinState[Controller::Six] = Pin6;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::dirP0String()
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RiotDebug.hxx,v 1.2 2008-05-13 15:13:17 stephena Exp $
// $Id: RiotDebug.hxx,v 1.3 2008-05-15 15:07:29 stephena Exp $
//============================================================================
#ifndef RIOT_DEBUG_HXX
@ -36,6 +36,9 @@ class RiotState : public DebuggerState
uInt8 TIM1T, TIM8T, TIM64T, TIM1024T, INTIM, TIMINT;
Int32 TIMCLKS;
bool P0_PIN1, P0_PIN2, P0_PIN3, P0_PIN4, P0_PIN6;
bool P1_PIN1, P1_PIN2, P1_PIN3, P1_PIN4, P1_PIN6;
};
class RiotDebug : public DebuggerSystem
@ -63,6 +66,14 @@ class RiotDebug : public DebuggerSystem
uInt8 timint();
Int32 timClocks();
/* Controller pins, from the POV of 'outside' the system
(ie, state is determined by what the controller sends to the RIOT)
Setting a pin to false is the same as if the external controller
pulled the pin low
*/
void setP0Pins(bool Pin1, bool Pin2, bool Pin3, bool Pin4, bool Pin6);
void setP1Pins(bool Pin1, bool Pin2, bool Pin3, bool Pin4, bool Pin6);
/* Port A description */
string dirP0String();
string dirP1String();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RiotWidget.cxx,v 1.3 2008-05-14 18:04:57 stephena Exp $
// $Id: RiotWidget.cxx,v 1.4 2008-05-15 15:07:29 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -41,6 +41,43 @@
xpos += bits->getWidth() + 5; \
bits->setList(off, on);
#define CREATE_PORT_PINS(label, pins, pinsID) \
t = new StaticTextWidget(boss, font, xpos, ypos+2, 14*fontWidth, \
fontHeight, label, kTextAlignLeft); \
xpos += t->getWidth()/2 - 5; ypos += t->getHeight() + 5; \
pins[0] = new CheckboxWidget(boss, font, xpos, ypos, "", \
kCheckActionCmd); \
pins[0]->setID(pinsID); \
pins[0]->setTarget(this); \
addFocusWidget(pins[0]); \
ypos += pins[0]->getHeight() * 2 + 10; \
pins[1] = new CheckboxWidget(boss, font, xpos, ypos, "", \
kCheckActionCmd); \
pins[1]->setID(pinsID); \
pins[1]->setTarget(this); \
addFocusWidget(pins[1]); \
xpos -= pins[0]->getWidth() + 5; \
ypos -= pins[0]->getHeight() + 5; \
pins[2] = new CheckboxWidget(boss, font, xpos, ypos, "", \
kCheckActionCmd); \
pins[2]->setID(pinsID); \
pins[2]->setTarget(this); \
addFocusWidget(pins[2]); \
xpos += (pins[0]->getWidth() + 5) * 2; \
pins[3] = new CheckboxWidget(boss, font, xpos, ypos, "", \
kCheckActionCmd); \
pins[3]->setID(pinsID); \
pins[3]->setTarget(this); \
addFocusWidget(pins[3]); \
xpos -= (pins[0]->getWidth() + 5) * 2; \
ypos = 20 + (pins[0]->getHeight() + 10) * 3; \
pins[4] = new CheckboxWidget(boss, font, xpos, ypos, "Fire", \
kCheckActionCmd); \
pins[4]->setID(pinsID); \
pins[4]->setTarget(this); \
addFocusWidget(pins[4]); \
col += t->getWidth() + 20;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h)
@ -52,7 +89,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight();
int xpos = 10, ypos = 25, lwidth = 9 * fontWidth;
int xpos = 10, ypos = 25, lwidth = 9 * fontWidth, col = 0;
StaticTextWidget* t;
// Set the strings to be used in the various bit registers
@ -66,6 +103,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
// SWCHA bits in 'poke' mode
CREATE_IO_REGS("SWCHA(W):", mySWCHAWriteBits, kSWCHABitsID);
col = xpos + 20; // remember this for adding widgets to the second column
// SWACNT bits
xpos = 10; ypos += lineHeight + 5;
@ -109,7 +147,11 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
myTimRead->setEditable(false);
addFocusWidget(myTimRead);
// Controller port pins (for now, only the latched pins)
xpos = col; ypos = 10;
CREATE_PORT_PINS("P0 Controller:", myP0Pins, kP0PinsID);
xpos = col; ypos = 10;
CREATE_PORT_PINS("P1 Controller:", myP1Pins, kP1PinsID);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -171,13 +213,25 @@ void RiotWidget::loadConfig()
changed.push_back(state.TIMCLKS != oldstate.TIMCLKS);
myTimRead->setList(alist, vlist, changed);
// Update port pins
// We invert the booleans, since in the UI it makes more sense that
// if, for example, the 'up' checkbox is set, it means 'go up'
myP0Pins[0]->setState(!state.P0_PIN1);
myP0Pins[1]->setState(!state.P0_PIN2);
myP0Pins[2]->setState(!state.P0_PIN3);
myP0Pins[3]->setState(!state.P0_PIN4);
myP0Pins[4]->setState(!state.P0_PIN6);
myP1Pins[0]->setState(!state.P1_PIN1);
myP1Pins[1]->setState(!state.P1_PIN2);
myP1Pins[2]->setState(!state.P1_PIN3);
myP1Pins[3]->setState(!state.P1_PIN4);
myP1Pins[4]->setState(!state.P1_PIN6);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
int addr = -1, value = -1;
int value = -1;
RiotDebug& riot = instance()->debugger().riotDebug();
switch(cmd)
@ -186,25 +240,22 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
switch(id)
{
case kTimWriteID:
{
addr = myTimWrite->getSelectedAddr();
value = myTimWrite->getSelectedValue();
switch(addr)
switch(myTimWrite->getSelectedAddr())
{
case kTim1TID:
riot.tim1T(value);
riot.tim1T(myTimWrite->getSelectedValue());
break;
case kTim8TID:
riot.tim8T(value);
riot.tim8T(myTimWrite->getSelectedValue());
break;
case kTim64TID:
riot.tim64T(value);
riot.tim64T(myTimWrite->getSelectedValue());
break;
case kTim1024TID:
riot.tim1024T(value);
riot.tim1024T(myTimWrite->getSelectedValue());
break;
}
}
break;
}
break;
@ -221,5 +272,21 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
break;
}
break;
case kCheckActionCmd:
switch(id)
{
case kP0PinsID:
riot.setP0Pins(!myP0Pins[0]->getState(), !myP0Pins[1]->getState(),
!myP0Pins[2]->getState(), !myP0Pins[3]->getState(),
!myP0Pins[4]->getState());
break;
case kP1PinsID:
riot.setP1Pins(!myP1Pins[0]->getState(), !myP1Pins[1]->getState(),
!myP1Pins[2]->getState(), !myP1Pins[3]->getState(),
!myP1Pins[4]->getState());
break;
}
break;
}
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RiotWidget.hxx,v 1.3 2008-05-14 18:04:58 stephena Exp $
// $Id: RiotWidget.hxx,v 1.4 2008-05-15 15:07:29 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -52,10 +52,12 @@ class RiotWidget : public Widget, public CommandSender
DataGridWidget* myTimWrite;
DataGridWidget* myTimRead;
CheckboxWidget* myP0Dir, *myP1Dir;
CheckboxWidget* myP0Pins[5], *myP1Pins[5];
CheckboxWidget* myP0Diff, *myP1Diff;
CheckboxWidget* myTVType;
CheckboxWidget* mySwitches;
CheckboxWidget* mySelect;
CheckboxWidget* myReset;
StaticTextWidget* myP0DirText, *myP1DirText;
StaticTextWidget* myP0DiffText, *myP1DiffText;
@ -65,8 +67,9 @@ class RiotWidget : public Widget, public CommandSender
// ID's for the various widgets
// We need ID's, since there are more than one of several types of widgets
enum {
kTim1TID = 0, kTim8TID = 1, kTim64TID = 2, kTim1024TID = 3,
kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kTimWriteID
kTim1TID, kTim8TID, kTim64TID, kTim1024TID,
kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kTimWriteID,
kP0PinsID, kP1PinsID
};
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TiaWidget.cxx,v 1.12 2008-05-04 17:16:39 stephena Exp $
// $Id: TiaWidget.cxx,v 1.13 2008-05-15 15:07:29 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -32,54 +32,6 @@
#include "TiaWidget.hxx"
// ID's for the various widgets
// We need ID's, since there are more than one of several types of widgets
enum {
kP0_PFID, kP0_BLID, kP0_M1ID, kP0_M0ID, kP0_P1ID,
kP1_PFID, kP1_BLID, kP1_M1ID, kP1_M0ID,
kM0_PFID, kM0_BLID, kM0_M1ID,
kM1_PFID, kM1_BLID,
kBL_PFID, // Make these first, since we want them to start from 0
kRamID,
kColorRegsID,
kGRP0ID, kGRP1ID,
kPosP0ID, kPosP1ID,
kPosM0ID, kPosM1ID, kPosBLID,
kHMP0ID, kHMP1ID,
kHMM0ID, kHMM1ID, kHMBLID,
kRefP0ID, kRefP1ID,
kDelP0ID, kDelP1ID, kDelBLID,
kNusizP0ID, kNusizP1ID,
kNusizM0ID, kNusizM1ID, kSizeBLID,
kEnaM0ID, kEnaM1ID, kEnaBLID,
kResMP0ID, kResMP1ID,
kPF0ID, kPF1ID, kPF2ID,
kRefPFID, kScorePFID, kPriorityPFID
};
// Strobe button commands
enum {
kWsyncCmd = 'Swsy',
kRsyncCmd = 'Srsy',
kResP0Cmd = 'Srp0',
kResP1Cmd = 'Srp1',
kResM0Cmd = 'Srm0',
kResM1Cmd = 'Srm1',
kResBLCmd = 'Srbl',
kHmoveCmd = 'Shmv',
kHmclrCmd = 'Shmc',
kCxclrCmd = 'Scxl'
};
// Color registers
enum {
kCOLUP0Addr,
kCOLUP1Addr,
kCOLUPFAddr,
kCOLUBKAddr
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TiaWidget.hxx,v 1.6 2008-02-06 13:45:20 stephena Exp $
// $Id: TiaWidget.hxx,v 1.7 2008-05-15 15:07:29 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -105,6 +105,54 @@ class TiaWidget : public Widget, public CommandSender
CheckboxWidget* myRefPF;
CheckboxWidget* myScorePF;
CheckboxWidget* myPriorityPF;
// ID's for the various widgets
// We need ID's, since there are more than one of several types of widgets
enum {
kP0_PFID, kP0_BLID, kP0_M1ID, kP0_M0ID, kP0_P1ID,
kP1_PFID, kP1_BLID, kP1_M1ID, kP1_M0ID,
kM0_PFID, kM0_BLID, kM0_M1ID,
kM1_PFID, kM1_BLID,
kBL_PFID, // Make these first, since we want them to start from 0
kRamID,
kColorRegsID,
kGRP0ID, kGRP1ID,
kPosP0ID, kPosP1ID,
kPosM0ID, kPosM1ID, kPosBLID,
kHMP0ID, kHMP1ID,
kHMM0ID, kHMM1ID, kHMBLID,
kRefP0ID, kRefP1ID,
kDelP0ID, kDelP1ID, kDelBLID,
kNusizP0ID, kNusizP1ID,
kNusizM0ID, kNusizM1ID, kSizeBLID,
kEnaM0ID, kEnaM1ID, kEnaBLID,
kResMP0ID, kResMP1ID,
kPF0ID, kPF1ID, kPF2ID,
kRefPFID, kScorePFID, kPriorityPFID
};
// Strobe button commands
enum {
kWsyncCmd = 'Swsy',
kRsyncCmd = 'Srsy',
kResP0Cmd = 'Srp0',
kResP1Cmd = 'Srp1',
kResM0Cmd = 'Srm0',
kResM1Cmd = 'Srm1',
kResBLCmd = 'Srbl',
kHmoveCmd = 'Shmv',
kHmclrCmd = 'Shmc',
kCxclrCmd = 'Scxl'
};
// Color registers
enum {
kCOLUP0Addr,
kCOLUP1Addr,
kCOLUPFAddr,
kCOLUBKAddr
};
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Control.hxx,v 1.15 2008-05-12 22:40:23 stephena Exp $
// $Id: Control.hxx,v 1.16 2008-05-15 15:07:29 stephena Exp $
//============================================================================
#ifndef CONTROLLER_HXX
@ -57,10 +57,15 @@ class System;
of the controller from the perspective of the controller's jack.
@author Bradford W. Mott
@version $Id: Control.hxx,v 1.15 2008-05-12 22:40:23 stephena Exp $
@version $Id: Control.hxx,v 1.16 2008-05-15 15:07:29 stephena Exp $
*/
class Controller : public Serializable
{
/**
Riot debug class needs special access to the underlying controller state
*/
friend class RiotDebug;
public:
/**
Enumeration of the controller jacks