More work on the CompuMate scheme. The logic for the Controllers is

now complete; I just need to define how to pass actual keyboard keys
through the Event system.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2413 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-03-14 22:24:54 +00:00
parent 47f151b87c
commit 82a4bc13b1
5 changed files with 117 additions and 27 deletions

View File

@ -108,6 +108,8 @@ class System;
*/ */
class CartridgeCM : public Cartridge class CartridgeCM : public Cartridge
{ {
friend class CompuMate;
public: public:
/** /**
Create a new cartridge using the specified image Create a new cartridge using the specified image

View File

@ -22,12 +22,15 @@
#include "CompuMate.hxx" #include "CompuMate.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CompuMate::CompuMate(const Event& event, const System& system) CompuMate::CompuMate(CartridgeCM& cart, const Event& event,
: mySystem(system), const System& system)
: myCart(cart),
myEvent(event),
mySystem(system),
myLeftController(0), myLeftController(0),
myRightController(0), myRightController(0),
myCycleAtLastUpdate(0), myCycleAtLastUpdate(0),
myIOPort(0xff) myColumn(0)
{ {
myLeftController = new CMControl(*this, Controller::Left, event, system); myLeftController = new CMControl(*this, Controller::Left, event, system);
myRightController = new CMControl(*this, Controller::Right, event, system); myRightController = new CMControl(*this, Controller::Right, event, system);
@ -46,5 +49,95 @@ void CompuMate::update()
} }
myCycleAtLastUpdate = cycle; myCycleAtLastUpdate = cycle;
// TODO - handle SWCHA changes // Handle SWCHA changes - the following comes almost directly from z26
Controller& lp = *myLeftController;
Controller& rp = *myRightController;
uInt8 IOPortA = (lp.read() << 4) | rp.read();
lp.myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
lp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
lp.myDigitalPinState[Controller::Six] = true;
rp.myAnalogPinValue[Controller::Nine] = Controller::minimumResistance;
rp.myAnalogPinValue[Controller::Five] = Controller::maximumResistance;
rp.myDigitalPinState[Controller::Six] = true;
uInt8& column = myCart.myColumn;
if(IOPortA & 0x20) column = 0;
if(IOPortA & 0x40) column = (column + 1) % 10;
IOPortA = IOPortA | (0x0c & 0x7f);
#if 0
switch(column)
{
case 0:
if (KeyTable[Key7]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyU]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyJ]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyM]) IOPortA = IOPortA & 0xf7;
break;
case 1:
if (KeyTable[Key6]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyY]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyH]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyN]) IOPortA = IOPortA & 0xf7;
break;
case 2:
if (KeyTable[Key8]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyI]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyK]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyComma]) IOPortA = IOPortA & 0xf7;
break;
case 3:
if (KeyTable[Key2]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyW]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyS]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyX]) IOPortA = IOPortA & 0xf7;
break;
case 4:
if (KeyTable[Key3]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyE]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyD]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyC]) IOPortA = IOPortA & 0xf7;
break;
case 5:
if (KeyTable[Key0]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyP]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyColon]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeySlash]) IOPortA = IOPortA & 0xf7;
break;
case 6:
if (KeyTable[Key9]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyO]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyL]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyDot]) IOPortA = IOPortA & 0xf7;
break;
case 7:
if (KeyTable[Key5]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyT]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyG]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyB]) IOPortA = IOPortA & 0xf7;
break;
case 8:
if (KeyTable[Key1]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyQ]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyA]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyZ]) IOPortA = IOPortA & 0xf7;
break;
case 9:
if (KeyTable[Key4]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyR]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyF]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyV]) IOPortA = IOPortA & 0xf7;
break;
default:
break;
}
#endif
// Convert back to digital pins
rp.myDigitalPinState[Controller::One] = IOPortA & 0x01;
rp.myDigitalPinState[Controller::Two] = IOPortA & 0x02;
rp.myDigitalPinState[Controller::Three] = IOPortA & 0x04;
rp.myDigitalPinState[Controller::Four] = IOPortA & 0x08;
} }

View File

@ -21,6 +21,7 @@
#define COMPUMATE_HXX #define COMPUMATE_HXX
#include "bspf.hxx" #include "bspf.hxx"
#include "CartCM.hxx"
#include "Control.hxx" #include "Control.hxx"
#include "Event.hxx" #include "Event.hxx"
@ -32,8 +33,8 @@
unique for the 2600 in that it requires close co-operation between the unique for the 2600 in that it requires close co-operation between the
cartridge and the left and right controllers. cartridge and the left and right controllers.
This class acts as a 'parent' for both the left and right CMControl's, This class acts as a 'parent' for cartridge and both the left and right
taking care of their creation and communication between them. CMControl's, taking care of their creation and communication between them.
@author Stephen Anthony @author Stephen Anthony
@version $Id$ @version $Id$
@ -46,10 +47,11 @@ class CompuMate
Note that this class creates CMControl controllers for both ports, Note that this class creates CMControl controllers for both ports,
but does not take responsibility for their deletion. but does not take responsibility for their deletion.
@param cart The CompuMate cartridge
@param event The event object to use for events @param event The event object to use for events
@param system The system using this controller @param system The system using this controller
*/ */
CompuMate(const Event& event, const System& system); CompuMate(CartridgeCM& cart, const Event& event, const System& system);
/** /**
Destructor Destructor
@ -57,12 +59,6 @@ class CompuMate
*/ */
virtual ~CompuMate() { } virtual ~CompuMate() { }
public:
/**
Called by the controller(s) when all pins have been written
*/
void update();
/** /**
Return the left and right CompuMate controllers Return the left and right CompuMate controllers
*/ */
@ -70,6 +66,12 @@ class CompuMate
Controller* rightController() { return (Controller*) myRightController; } Controller* rightController() { return (Controller*) myRightController; }
private: private:
/**
Called by the controller(s) when all pins have been written
This method keeps track of consecutive calls, and only updates once
*/
void update();
// The actual CompuMate controller // The actual CompuMate controller
// More information about these scheme can be found in CartCM.hxx // More information about these scheme can be found in CartCM.hxx
class CMControl : public Controller class CMControl : public Controller
@ -122,7 +124,9 @@ class CompuMate
}; };
private: private:
// System object // Cart, Event and System objects
CartridgeCM& myCart;
const Event& myEvent;
const System& mySystem; const System& mySystem;
// Left and right controllers // Left and right controllers
@ -132,8 +136,8 @@ class CompuMate
// Multiple calls at the same cycle should be ignored // Multiple calls at the same cycle should be ignored
uInt32 myCycleAtLastUpdate; uInt32 myCycleAtLastUpdate;
// Internal state of the port pins // Column currently active
uInt8 myIOPort; uInt8 myColumn;
}; };
#endif #endif

View File

@ -617,7 +617,7 @@ void Console::setControllers(const string& rommd5)
if(left == "COMPUMATE" || right == "COMPUMATE") if(left == "COMPUMATE" || right == "COMPUMATE")
{ {
delete myCMHandler; delete myCMHandler;
myCMHandler = new CompuMate(myEvent, *mySystem); myCMHandler = new CompuMate(*((CartridgeCM*)myCart), myEvent, *mySystem);
myControllers[0] = myCMHandler->leftController(); myControllers[0] = myCMHandler->leftController();
myControllers[1] = myCMHandler->rightController(); myControllers[1] = myCMHandler->rightController();
return; return;

View File

@ -64,16 +64,7 @@ Keyboard::~Keyboard()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Keyboard::write(DigitalPin pin, bool value) void Keyboard::write(DigitalPin pin, bool value)
{ {
switch(pin) myDigitalPinState[pin] = value;
{
case One:
case Two:
case Three:
case Four:
myDigitalPinState[pin] = value;
default:
break;
}
// Set defaults // Set defaults
myDigitalPinState[Six] = true; myDigitalPinState[Six] = true;