Some more work on the EEPROM code. I still can't get it working; it seems

to never write anything to the EEPROM data array.  I'll have to speak to
Supercat about that one.

Rearranged controller stuff, and changed the API a little.  Basically, I
eliminated pointers to System in the controller classes, so they'll
always have a valid system object.

The savegame screen in MGD now appears, indicating that we're reading
from EEPROM SDA correctly.  Of course the score isn't being saved
properly yet.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1471 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-04-13 23:43:14 +00:00
parent 8083549240
commit b5a52b566c
19 changed files with 317 additions and 244 deletions

View File

@ -13,13 +13,14 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: AtariVox.cxx,v 1.13 2008-04-11 17:56:34 stephena Exp $
// $Id: AtariVox.cxx,v 1.14 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifdef SPEAKJET_EMULATION
#include "SpeakJet.hxx"
#endif
#include "MT24LC256.hxx"
#include "SerialPort.hxx"
#include "System.hxx"
#include "AtariVox.hxx"
@ -27,25 +28,29 @@
#define DEBUG_ATARIVOX 0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AtariVox::AtariVox(Jack jack, const Event& event, const SerialPort& port,
const string& device)
: Controller(jack, event, Controller::AtariVox),
AtariVox::AtariVox(Jack jack, const Event& event, const System& system,
const SerialPort& port, const string& portname,
const string& eepromfile)
: Controller(jack, event, system, Controller::AtariVox),
mySerialPort((SerialPort*)&port),
myEEPROM(NULL),
myPinState(0),
myShiftCount(0),
myShiftRegister(0),
myLastDataWriteCycle(0)
{
#ifndef SPEAKJET_EMULATION
if(mySerialPort->openPort(device))
myAboutString = " (using serial port \'" + device + "\')";
if(mySerialPort->openPort(portname))
myAboutString = " (using serial port \'" + portname + "\')";
else
myAboutString = " (invalid serial port \'" + device + "\')";
myAboutString = " (invalid serial port \'" + portname + "\')";
#else
mySpeakJet = new SpeakJet();
myAboutString = " (emulating SpeakJet device)";
#endif
myEEPROM = new MT24LC256(eepromfile, system);
myDigitalPinState[One] = myDigitalPinState[Two] =
myDigitalPinState[Three] = myDigitalPinState[Four] = true;
@ -60,6 +65,30 @@ AtariVox::~AtariVox()
#else
delete mySpeakJet;
#endif
delete myEEPROM;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AtariVox::read(DigitalPin pin)
{
// We need to override the Controller::read() method, since the timing
// of the actual read is important for the EEPROM (we can't just read
// 60 times per second in the ::update() method)
switch(pin)
{
// Pin 2: SpeakJet READY
case Two:
// For now, we just assume the device is always ready
return myDigitalPinState[Two] = true;
// Pin 3: EEPROM SDA
// input data from the 24LC256 EEPROM using the I2C protocol
case Three:
return myDigitalPinState[Three] = myEEPROM->readSDA();
default:
return Controller::read(pin);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,11 +106,6 @@ void AtariVox::write(DigitalPin pin, bool value)
clockDataIn(value);
break;
// Pin 2: SpeakJet READY
case Two:
// TODO - read READY signal from serial port
break;
// Pin 3: EEPROM SDA
// output data to the 24LC256 EEPROM using the I2C protocol
case Three:
@ -90,8 +114,9 @@ void AtariVox::write(DigitalPin pin, bool value)
cerr << "AtariVox: value "
<< value
<< " written to SDA line at cycle "
<< mySystem->cycles()
<< mySystem.cycles()
<< endl;
myEEPROM->writeSDA(value);
break;
// Pin 4: EEPROM SCL
@ -102,38 +127,32 @@ void AtariVox::write(DigitalPin pin, bool value)
cerr << "AtariVox: value "
<< value
<< " written to SCLK line at cycle "
<< mySystem->cycles()
<< mySystem.cycles()
<< endl;
myEEPROM->writeSCL(value);
break;
case Six:
// Not connected
default:
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariVox::update()
{
// Nothing to do, this seems to be an output-only device for now
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariVox::clockDataIn(bool value)
{
// bool oldValue = myPinState & 0x01;
myPinState = (myPinState & 0xfe) | (int)value;
uInt32 cycle = mySystem->cycles();
uInt32 cycle = mySystem.cycles();
if(DEBUG_ATARIVOX)
cerr << "AtariVox: value "
<< value
<< " written to DATA line at "
<< mySystem->cycles()
<< mySystem.cycles()
<< " (-"
<< myLastDataWriteCycle
<< "=="
<< (mySystem->cycles() - myLastDataWriteCycle)
<< (mySystem.cycles() - myLastDataWriteCycle)
<< ")"
<< endl;

View File

@ -13,16 +13,17 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: AtariVox.hxx,v 1.11 2008-04-11 17:56:34 stephena Exp $
// $Id: AtariVox.hxx,v 1.12 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef ATARIVOX_HXX
#define ATARIVOX_HXX
class SpeakJet;
class SerialPort;
class MT24LC256;
#include "Control.hxx"
#include "SerialPort.hxx"
/**
Richard Hutchinson's AtariVox "controller": A speech synthesizer and
@ -32,7 +33,7 @@ class SpeakJet;
driver code.
@author B. Watson
@version $Id: AtariVox.hxx,v 1.11 2008-04-11 17:56:34 stephena Exp $
@version $Id: AtariVox.hxx,v 1.12 2008-04-13 23:43:14 stephena Exp $
*/
class AtariVox : public Controller
{
@ -40,13 +41,16 @@ class AtariVox : public Controller
/**
Create a new AtariVox controller plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param port The serial port object
@param device Name of the port used for reading and writing
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
@param port The serial port object
@param portname Name of the port used for reading and writing
@param eepromfile The file containing the EEPROM data
*/
AtariVox(Jack jack, const Event& event, const SerialPort& port,
const string& device);
AtariVox(Jack jack, const Event& event, const System& system,
const SerialPort& port, const string& portname,
const string& eepromfile);
/**
Destructor
@ -54,6 +58,14 @@ class AtariVox : public Controller
virtual ~AtariVox();
public:
/**
Read the value of the specified digital pin for this controller.
@param pin The pin of the controller jack to read
@return The state of the pin
*/
virtual bool read(DigitalPin pin);
/**
Write the given value to the specified digital pin for this
controller. Writing is only allowed to the pins associated
@ -68,7 +80,7 @@ class AtariVox : public Controller
Update the entire digital and analog pin state according to the
events currently set.
*/
virtual void update();
virtual void update() { }
virtual string about() const;
@ -91,6 +103,9 @@ class AtariVox : public Controller
// bytes directly to it
SerialPort* mySerialPort;
// The EEPROM used in the AtariVox
MT24LC256* myEEPROM;
#ifdef SPEAKJET_EMULATION
// Instance of SpeakJet which will actually do the talking for us.
SpeakJet *mySpeakJet;

View File

@ -13,15 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Booster.cxx,v 1.12 2008-03-02 19:20:50 stephena Exp $
// $Id: Booster.cxx,v 1.13 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include "Event.hxx"
#include "Booster.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterGrip::BoosterGrip(Jack jack, const Event& event)
: Controller(jack, event, Controller::BoosterGrip)
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::BoosterGrip)
{
if(myJack == Left)
{

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: Booster.hxx,v 1.10 2008-03-02 19:20:50 stephena Exp $
// $Id: Booster.hxx,v 1.11 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef BOOSTERGRIP_HXX
@ -29,7 +29,7 @@
on it (a booster and a trigger).
@author Bradford W. Mott
@version $Id: Booster.hxx,v 1.10 2008-03-02 19:20:50 stephena Exp $
@version $Id: Booster.hxx,v 1.11 2008-04-13 23:43:14 stephena Exp $
*/
class BoosterGrip : public Controller
{
@ -37,10 +37,11 @@ class BoosterGrip : public Controller
/**
Create a new booster grip joystick plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
*/
BoosterGrip(Jack jack, const Event& event);
BoosterGrip(Jack jack, const Event& event, const System& system);
/**
Destructor

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: Console.cxx,v 1.136 2008-04-11 17:56:34 stephena Exp $
// $Id: Console.cxx,v 1.137 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include <cassert>
@ -81,93 +81,12 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
// Load user-defined palette for this ROM
loadUserPalette();
// Setup the controllers based on properties
const string& left = myProperties.get(Controller_Left);
const string& right = myProperties.get(Controller_Right);
// Swap the ports if necessary
int leftPort, rightPort;
if(myProperties.get(Console_SwapPorts) == "NO")
{
leftPort = 0; rightPort = 1;
}
else
{
leftPort = 1; rightPort = 0;
}
// Also check if we should swap the paddles plugged into a jack
bool swapPaddles = myProperties.get(Controller_SwapPaddles) == "YES";
Paddles::setMouseIsPaddle(-1); // Reset to defaults
// Construct left controller
if(left == "BOOSTER-GRIP")
{
myControllers[leftPort] = new BoosterGrip(Controller::Left, *myEvent);
}
else if(left == "DRIVING")
{
myControllers[leftPort] = new Driving(Controller::Left, *myEvent);
}
else if((left == "KEYBOARD") || (left == "KEYPAD"))
{
myControllers[leftPort] = new Keyboard(Controller::Left, *myEvent);
}
else if(left == "PADDLES")
{
myControllers[leftPort] = new Paddles(Controller::Left, *myEvent, swapPaddles);
}
else if(left == "TRACKBALL22")
{
myControllers[leftPort] = new TrackBall22(Controller::Left, *myEvent);
}
else
{
myControllers[leftPort] = new Joystick(Controller::Left, *myEvent);
}
// Construct right controller
if(right == "BOOSTER-GRIP")
{
myControllers[rightPort] = new BoosterGrip(Controller::Right, *myEvent);
}
else if(right == "DRIVING")
{
myControllers[rightPort] = new Driving(Controller::Right, *myEvent);
}
else if((right == "KEYBOARD") || (right == "KEYPAD"))
{
myControllers[rightPort] = new Keyboard(Controller::Right, *myEvent);
}
else if(right == "PADDLES")
{
myControllers[rightPort] = new Paddles(Controller::Right, *myEvent, swapPaddles);
}
else if(right == "TRACKBALL22")
{
myControllers[rightPort] = new TrackBall22(Controller::Right, *myEvent);
}
else if(right == "ATARIVOX")
{
myControllers[rightPort] = myAVox =
new AtariVox(Controller::Right, *myEvent, myOSystem->serialPort(),
myOSystem->settings().getString("avoxport"));
}
else
{
myControllers[rightPort] = new Joystick(Controller::Right, *myEvent);
}
// Create switches for the console
mySwitches = new Switches(*myEvent, myProperties);
// Now, we can construct the system and components
// Construct the system and components
mySystem = new System(13, 6);
// Inform the controllers about the system
myControllers[0]->setSystem(mySystem);
myControllers[1]->setSystem(mySystem);
M6502* m6502;
if(myOSystem->settings().getString("cpu") == "low")
m6502 = new M6502Low(1);
@ -191,6 +110,86 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
myCart = cart;
myRiot = m6532;
// Setup the controllers based on properties
const string& left = myProperties.get(Controller_Left);
const string& right = myProperties.get(Controller_Right);
// Swap the ports if necessary
int leftPort, rightPort;
if(myProperties.get(Console_SwapPorts) == "NO")
{
leftPort = 0; rightPort = 1;
}
else
{
leftPort = 1; rightPort = 0;
}
// Also check if we should swap the paddles plugged into a jack
bool swapPaddles = myProperties.get(Controller_SwapPaddles) == "YES";
Paddles::setMouseIsPaddle(-1); // Reset to defaults
// Construct left controller
if(left == "BOOSTER-GRIP")
{
myControllers[leftPort] = new BoosterGrip(Controller::Left, *myEvent, *mySystem);
}
else if(left == "DRIVING")
{
myControllers[leftPort] = new Driving(Controller::Left, *myEvent, *mySystem);
}
else if((left == "KEYBOARD") || (left == "KEYPAD"))
{
myControllers[leftPort] = new Keyboard(Controller::Left, *myEvent, *mySystem);
}
else if(left == "PADDLES")
{
myControllers[leftPort] = new Paddles(Controller::Left, *myEvent, *mySystem, swapPaddles);
}
else if(left == "TRACKBALL22")
{
myControllers[leftPort] = new TrackBall22(Controller::Left, *myEvent, *mySystem);
}
else
{
myControllers[leftPort] = new Joystick(Controller::Left, *myEvent, *mySystem);
}
// Construct right controller
if(right == "BOOSTER-GRIP")
{
myControllers[rightPort] = new BoosterGrip(Controller::Right, *myEvent, *mySystem);
}
else if(right == "DRIVING")
{
myControllers[rightPort] = new Driving(Controller::Right, *myEvent, *mySystem);
}
else if((right == "KEYBOARD") || (right == "KEYPAD"))
{
myControllers[rightPort] = new Keyboard(Controller::Right, *myEvent, *mySystem);
}
else if(right == "PADDLES")
{
myControllers[rightPort] = new Paddles(Controller::Right, *myEvent, *mySystem, swapPaddles);
}
else if(right == "TRACKBALL22")
{
myControllers[rightPort] = new TrackBall22(Controller::Right, *myEvent, *mySystem);
}
else if(right == "ATARIVOX")
{
string eepromfile = // fixme myOSystem->baseDir() + BSPF_PATH_SEPARATOR +
"atarivox_eeprom.dat";
myControllers[rightPort] = myAVox =
new AtariVox(Controller::Right, *myEvent, *mySystem, myOSystem->serialPort(),
myOSystem->settings().getString("avoxport"), eepromfile);
}
else
{
myControllers[rightPort] = new Joystick(Controller::Right, *myEvent, *mySystem);
}
// Query some info about this console
ostringstream buf;
buf << " Cart Name: " << myProperties.get(Cartridge_Name) << endl

View File

@ -13,17 +13,20 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Control.cxx,v 1.9 2008-04-11 17:56:34 stephena Exp $
// $Id: Control.cxx,v 1.10 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include <cassert>
#include "System.hxx"
#include "Control.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::Controller(Jack jack, const Event& event, Type type)
Controller::Controller(Jack jack, const Event& event, const System& system,
Type type)
: myJack(jack),
myEvent(event),
mySystem(system),
myType(type)
{
myDigitalPinState[One] =
@ -73,7 +76,7 @@ const Controller::Type Controller::type() const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Controller::read(DigitalPin pin) const
bool Controller::read(DigitalPin pin)
{
switch(pin)
{
@ -90,7 +93,7 @@ bool Controller::read(DigitalPin pin) const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 Controller::read(AnalogPin pin) const
Int32 Controller::read(AnalogPin pin)
{
switch(pin)
{
@ -173,6 +176,7 @@ const Int32 Controller::minimumResistance = 0x00000000;
Controller::Controller(const Controller& c)
: myJack(c.myJack),
myEvent(c.myEvent),
mySystem(c.mySystem),
myType(c.myType)
{
assert(false);

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.12 2008-04-11 17:56:34 stephena Exp $
// $Id: Control.hxx,v 1.13 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef CONTROLLER_HXX
@ -57,7 +57,7 @@ class System;
of the controller from the perspective of the controller's jack.
@author Bradford W. Mott
@version $Id: Control.hxx,v 1.12 2008-04-11 17:56:34 stephena Exp $
@version $Id: Control.hxx,v 1.13 2008-04-13 23:43:14 stephena Exp $
*/
class Controller : public Serializable
{
@ -83,11 +83,13 @@ class Controller : public Serializable
/**
Create a new controller plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param type The type for this controller
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param type The type for this controller
@param system The system using this controller
*/
Controller(Jack jack, const Event& event, Type type);
Controller(Jack jack, const Event& event, const System& system,
Type type);
/**
Destructor
@ -99,11 +101,6 @@ class Controller : public Serializable
*/
const Type type() const;
/**
Inform this controller about the current System.
*/
void setSystem(System* system) { mySystem = system; }
public:
/**
Enumeration of the digital pins of a controller port
@ -128,7 +125,7 @@ class Controller : public Serializable
@param pin The pin of the controller jack to read
@return The state of the pin
*/
bool read(DigitalPin pin) const;
virtual bool read(DigitalPin pin);
/**
Read the resistance at the specified analog pin for this controller.
@ -137,7 +134,7 @@ class Controller : public Serializable
@param pin The pin of the controller jack to read
@return The resistance at the specified pin
*/
Int32 read(AnalogPin pin) const;
virtual Int32 read(AnalogPin pin);
/**
Write the given value to the specified digital pin for this
@ -195,15 +192,15 @@ class Controller : public Serializable
/// Reference to the event object this controller uses
const Event& myEvent;
/// Pointer to the System object (used for timing purposes)
const System& mySystem;
/// Specifies which type of controller this is (defined by child classes)
const Type myType;
/// Specifies the name of this controller based on type
string myName;
/// Pointer to the System object (used for timing purposes)
System* mySystem;
/// The boolean value on each digital pin
bool myDigitalPinState[5];

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: Driving.cxx,v 1.16 2008-03-03 16:27:16 estolberg Exp $
// $Id: Driving.cxx,v 1.17 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include "Event.hxx"
@ -22,8 +22,8 @@
#include "Driving.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Driving::Driving(Jack jack, const Event& event)
: Controller(jack, event, Controller::Driving),
Driving::Driving(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Driving),
myCounter(0)
{
if(myJack == Left)

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: Driving.hxx,v 1.10 2008-03-03 16:27:16 estolberg Exp $
// $Id: Driving.hxx,v 1.11 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef DRIVING_HXX
@ -27,7 +27,7 @@
The standard Atari 2600 Indy 500 driving controller.
@author Bradford W. Mott
@version $Id: Driving.hxx,v 1.10 2008-03-03 16:27:16 estolberg Exp $
@version $Id: Driving.hxx,v 1.11 2008-04-13 23:43:14 stephena Exp $
*/
class Driving : public Controller
{
@ -36,10 +36,11 @@ class Driving : public Controller
Create a new Indy 500 driving controller plugged into
the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
*/
Driving(Jack jack, const Event& event);
Driving(Jack jack, const Event& event, const System& system);
/**
Destructor

View File

@ -13,15 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Joystick.cxx,v 1.11 2008-03-02 19:20:50 stephena Exp $
// $Id: Joystick.cxx,v 1.12 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include "Event.hxx"
#include "Joystick.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Joystick::Joystick(Jack jack, const Event& event)
: Controller(jack, event, Controller::Joystick)
Joystick::Joystick(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Joystick)
{
if(myJack == Left)
{

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: Joystick.hxx,v 1.9 2008-03-02 19:20:50 stephena Exp $
// $Id: Joystick.hxx,v 1.10 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef JOYSTICK_HXX
@ -27,7 +27,7 @@
The standard Atari 2600 joystick controller.
@author Bradford W. Mott
@version $Id: Joystick.hxx,v 1.9 2008-03-02 19:20:50 stephena Exp $
@version $Id: Joystick.hxx,v 1.10 2008-04-13 23:43:14 stephena Exp $
*/
class Joystick : public Controller
{
@ -35,10 +35,11 @@ class Joystick : public Controller
/**
Create a new joystick controller plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
*/
Joystick(Jack jack, const Event& event);
Joystick(Jack jack, const Event& event, const System& system);
/**
Destructor

View File

@ -13,15 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Keyboard.cxx,v 1.10 2008-02-06 13:45:21 stephena Exp $
// $Id: Keyboard.cxx,v 1.11 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include "Event.hxx"
#include "Keyboard.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Keyboard::Keyboard(Jack jack, const Event& event)
: Controller(jack, event, Controller::Keyboard),
Keyboard::Keyboard(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Keyboard),
myPinState(0)
{
if(myJack == Left)

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: Keyboard.hxx,v 1.8 2008-02-06 13:45:21 stephena Exp $
// $Id: Keyboard.hxx,v 1.9 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef KEYBOARD_HXX
@ -27,7 +27,7 @@
The standard Atari 2600 keyboard controller
@author Bradford W. Mott
@version $Id: Keyboard.hxx,v 1.8 2008-02-06 13:45:21 stephena Exp $
@version $Id: Keyboard.hxx,v 1.9 2008-04-13 23:43:14 stephena Exp $
*/
class Keyboard : public Controller
{
@ -35,10 +35,11 @@ class Keyboard : public Controller
/**
Create a new keyboard controller plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
*/
Keyboard(Jack jack, const Event& event);
Keyboard(Jack jack, const Event& event, const System& system);
/**
Destructor

View File

@ -13,15 +13,14 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: MT24LC256.cxx,v 1.1 2008-04-13 15:05:58 stephena Exp $
// $Id: MT24LC256.cxx,v 1.2 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include <cassert>
#include <cstdio>
#include <fstream>
#include "Control.hxx"
#include "System.hxx"
#include "MT24LC256.hxx"
/*
@ -33,9 +32,23 @@
4 - Chip waiting for acknowledgement
*/
#define LOG_EDGES 256
#define LOG_EVENTS 128
#define LOG_BUSY 4
#define LOG_UNCLEAN 2
#define LOG_ODDBALL 1
char jpee_msg[256];
#define JPEE_LOG0(vm,msg) jpee_logproc(msg)
#define JPEE_LOG1(vm,msg,arg1) sprintf(jpee_msg,(msg),(arg1)), jpee_logproc(jpee_msg)
#define JPEE_LOG2(vm,msg,arg1,arg2) sprintf(jpee_msg,(msg),(arg1),(arg2)), jpee_logproc(jpee_msg)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MT24LC256::MT24LC256(const string& filename, const Controller* controller)
: myController(controller),
MT24LC256::MT24LC256(const string& filename, const System& system)
: mySystem(system),
myCyclesWhenTimerSet(0),
myDataFile(filename)
{
// First initialize the I2C state
@ -79,27 +92,25 @@ bool MT24LC256::readSDA()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MT24LC256::writeSDA(bool state)
{
#if 0
//cerr << "writeSDA: " << state << endl;
if(state)
(!jpee_mdat && jpee_sdat && jpee_mclk && (jpee_data_stop(),1), jpee_mdat = 1)
else
#define jpee_data(x) ( (x) ? \
(!jpee_mdat && jpee_sdat && jpee_mclk && (jpee_data_stop(),1), jpee_mdat = 1) : \
(jpee_mdat && jpee_sdat && jpee_mclk && (jpee_data_start(),1), jpee_mdat = 0))
#endif
jpee_data(state);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MT24LC256::writeSCL(bool state)
{
#if 0
//cerr << "writeSCL: " << state << endl;
if(state)
jpee_mclk = 1;
else
#define jpee_clock(x) ( (x) ? \
(jpee_mclk = 1) : \
(jpee_mclk && (jpee_clock_fall(),1), jpee_mclk = 0))
#endif
jpee_clock(state);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -120,24 +131,25 @@ void MT24LC256::jpee_init()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MT24LC256::jpee_data_start()
{
//cerr << " ==> jpee_data_start()\n";
/* We have a start condition */
if (jpee_state == 1 && (jpee_nb != 1 || jpee_pptr != 3))
{
// JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON WRITE");
JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON WRITE");
jpee_ad_known = 0;
}
if (jpee_state == 3)
{
// JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON READ");
JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON READ");
}
if (!jpee_timercheck(0))
{
// JPEE_LOG0(LOG_EVENTS,"I2C_START");
JPEE_LOG0(LOG_EVENTS,"I2C_START");
jpee_state = 2;
}
else
{
// JPEE_LOG0(LOG_BUSY,"I2C_BUSY");
JPEE_LOG0(LOG_BUSY,"I2C_BUSY");
jpee_state = 0;
}
jpee_pptr = 0;
@ -148,30 +160,32 @@ void MT24LC256::jpee_data_start()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MT24LC256::jpee_data_stop()
{
//cerr << " ==> jpee_data_stop()\n";
int i;
if (jpee_state == 1 && jpee_nb != 1)
{
// JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON_WRITE");
JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON_WRITE");
jpee_ad_known = 0;
}
if (jpee_state == 3)
{
// JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON_READ");
JPEE_LOG0(LOG_UNCLEAN,"I2C_WARNING ABANDON_READ");
jpee_ad_known = 0;
}
/* We have a stop condition. */
if (jpee_state == 1 && jpee_nb == 1 && jpee_pptr > 3)
{
jpee_timercheck(1);
// JPEE_LOG2(LOG_EVENTS,"I2C_STOP(Write %d bytes at %04X)",jpee_pptr-3,jpee_address);
JPEE_LOG2(LOG_EVENTS,"I2C_STOP(Write %d bytes at %04X)",jpee_pptr-3,jpee_address);
if (((jpee_address + jpee_pptr-4) ^ jpee_address) & ~jpee_pagemask)
{
jpee_pptr = 4+jpee_pagemask-(jpee_address & jpee_pagemask);
// JPEE_LOG1(LOG_ODDBALL,"I2C_WARNING PAGECROSSING!(Truncate to %d bytes)",jpee_pptr-3);
JPEE_LOG1(LOG_ODDBALL,"I2C_WARNING PAGECROSSING!(Truncate to %d bytes)",jpee_pptr-3);
}
for (i=3; i<jpee_pptr; i++)
{
cerr << " => writing\n";
myData[(jpee_address++) & jpee_sizemask] = jpee_packet[i];
if (!(jpee_address & jpee_pagemask))
break; /* Writes can't cross page boundary! */
@ -179,13 +193,15 @@ void MT24LC256::jpee_data_stop()
jpee_ad_known = 0;
}
else
;// JPEE_LOG0(LOG_EVENTS,"I2C_STOP");
JPEE_LOG0(LOG_EVENTS,"I2C_STOP");
jpee_state = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MT24LC256::jpee_clock_fall()
{
//cerr << " ==> jpee_clock_fall()\n";
switch(jpee_state)
{
case 1:
@ -199,28 +215,28 @@ void MT24LC256::jpee_clock_fall()
if (jpee_smallmode && ((jpee_nb & 0xF0) == 0xA0))
{
jpee_packet[1] = (jpee_nb >> 1) & 7;
// if (jpee_packet[1] != (jpee_address >> 8) && (jpee_packet[0] & 1))
// JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING ADDRESS MSB CHANGED");
if (jpee_packet[1] != (jpee_address >> 8) && (jpee_packet[0] & 1))
JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING ADDRESS MSB CHANGED");
jpee_nb &= 0x1A1;
}
if (jpee_nb == 0x1A0)
{
// JPEE_LOG1(LOG_EVENTS,"I2C_SENT(%02X--start write)",jpee_packet[0]);
JPEE_LOG1(LOG_EVENTS,"I2C_SENT(%02X--start write)",jpee_packet[0]);
jpee_state = 2;
jpee_sdat = 0;
}
else if (jpee_nb == 0x1A1)
{
jpee_state = 4;
// JPEE_LOG2(LOG_EVENTS,"I2C_SENT(%02X--start read @%04X)",
// jpee_packet[0],jpee_address);
// if (!jpee_ad_known)
// JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING ADDRESS IS UNKNOWN");
JPEE_LOG2(LOG_EVENTS,"I2C_SENT(%02X--start read @%04X)",
jpee_packet[0],jpee_address);
if (!jpee_ad_known)
JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING ADDRESS IS UNKNOWN");
jpee_sdat = 0;
}
else
{
// JPEE_LOG1(LOG_ODDBALL,"I2C_WARNING ODDBALL FIRST BYTE!(%02X)",jpee_nb & 0xFF);
JPEE_LOG1(LOG_ODDBALL,"I2C_WARNING ODDBALL FIRST BYTE!(%02X)",jpee_nb & 0xFF);
jpee_state = 0;
}
}
@ -245,14 +261,14 @@ void MT24LC256::jpee_clock_fall()
}
else if (jpee_pptr < 70)
{
// JPEE_LOG1(LOG_EVENTS,"I2C_SENT(%02X)",jpee_nb & 0xFF);
JPEE_LOG1(LOG_EVENTS,"I2C_SENT(%02X)",jpee_nb & 0xFF);
jpee_packet[jpee_pptr++] = (unsigned char)jpee_nb;
jpee_address = (jpee_packet[1] << 8) | jpee_packet[2];
if (jpee_pptr > 2)
jpee_ad_known = 1;
}
// else
// JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING OUTPUT_OVERFLOW!");
else
JPEE_LOG0(LOG_ODDBALL,"I2C_WARNING OUTPUT_OVERFLOW!");
}
jpee_sdat = 1;
jpee_nb = 1;
@ -262,13 +278,13 @@ void MT24LC256::jpee_clock_fall()
case 4:
if (jpee_mdat && jpee_sdat)
{
// JPEE_LOG0(LOG_EVENTS,"I2C_READ_NAK");
JPEE_LOG0(LOG_EVENTS,"I2C_READ_NAK");
jpee_state=0;
break;
}
jpee_state=3;
jpee_nb = (myData[jpee_address & jpee_sizemask] << 1) | 1; /* Fall through */
// JPEE_LOG2(LOG_EVENTS,"I2C_READ(%04X=%02X)",jpee_address,jpee_nb/2);
JPEE_LOG2(LOG_EVENTS,"I2C_READ(%04X=%02X)",jpee_address,jpee_nb/2);
case 3:
jpee_sdat = !!(jpee_nb & 256);
@ -285,30 +301,43 @@ void MT24LC256::jpee_clock_fall()
/* Do nothing */
break;
}
// JPEE_LOG2(LOG_EDGES,"I2C_CLOCK (dat=%d/%d)",jpee_mdat,jpee_sdat);
JPEE_LOG2(LOG_EDGES,"I2C_CLOCK (dat=%d/%d)",jpee_mdat,jpee_sdat);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int MT24LC256::jpee_timercheck(int mode)
bool MT24LC256::jpee_timercheck(int mode)
{
// TODO - implement a timer emulating the delay in accessing the EEPROM
// For now, we assume it's always ready
/*
The application should define a function jpee_timercheck() which is used to
evaluate how long the EEPROM is busy. When invoked with an argument of 1,
the system should start a timer (probably about 5 milliseconds); when invoked
with an argument of 0, it should return zero if the timer has expired or
non-zero if it is still running.
Evaluate how long the EEPROM is busy. When invoked with an argument of 1,
start a timer (probably about 5 milliseconds); when invoked with an
argument of 0, return zero if the timer has expired or non-zero if it is
still running.
*/
if(mode) // set timer
{
myCyclesWhenTimerSet = mySystem.cycles();
return true;
}
else // read timer
{
uInt32 elapsed = mySystem.cycles() - myCyclesWhenTimerSet;
cerr << " --> elapsed: " << elapsed << endl;
return elapsed < (uInt32)(5000.0 / 838.0);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int MT24LC256::jpee_logproc(char const *st)
{
cerr << st << endl;
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MT24LC256::MT24LC256(const MT24LC256& c)
: myController(c.myController),
: mySystem(c.mySystem),
myCyclesWhenTimerSet(c.myCyclesWhenTimerSet),
myDataFile(c.myDataFile)
{
assert(false);

View File

@ -13,13 +13,14 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: MT24LC256.hxx,v 1.1 2008-04-13 15:05:58 stephena Exp $
// $Id: MT24LC256.hxx,v 1.2 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef MT24LC256_HXX
#define MT24LC256_HXX
class Controller;
class System;
#include "bspf.hxx"
@ -29,7 +30,7 @@ class Controller;
(aka Supercat) for the bulk of this code.
@author Stephen Anthony & J. Payson
@version $Id: MT24LC256.hxx,v 1.1 2008-04-13 15:05:58 stephena Exp $
@version $Id: MT24LC256.hxx,v 1.2 2008-04-13 23:43:14 stephena Exp $
*/
class MT24LC256
{
@ -37,10 +38,10 @@ class MT24LC256
/**
Create a new 24LC256 with its data stored in the given file
@param filename Data file representing the EEPROM data
@param controller The controller attached to this device
@param filename Data file containing the EEPROM data
@param system The system using the controller of this device
*/
MT24LC256(const string& filename, const Controller* controller);
MT24LC256(const string& filename, const System& system);
/**
Destructor
@ -61,16 +62,19 @@ class MT24LC256
void jpee_data_start();
void jpee_data_stop();
void jpee_clock_fall();
// int jpee_logproc(char const *st);
int jpee_timercheck(int mode);
int jpee_logproc(char const *st);
bool jpee_timercheck(int mode);
private:
// The controller attached to this device
const Controller* myController;
// The system of the parent controller
const System& mySystem;
// The EEPROM data
uInt8 myData[32768];
// Indicates when the timer was set
uInt32 myCyclesWhenTimerSet;
// The file containing the EEPROM data
string myDataFile;

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: Paddles.cxx,v 1.14 2008-03-22 17:35:02 stephena Exp $
// $Id: Paddles.cxx,v 1.15 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#define TRIGMAX 240
@ -23,8 +23,8 @@
#include "Paddles.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Paddles::Paddles(Jack jack, const Event& event, bool swap)
: Controller(jack, event, Controller::Paddles)
Paddles::Paddles(Jack jack, const Event& event, const System& system, bool swap)
: Controller(jack, event, system, Controller::Paddles)
{
// Swap the paddle events, from paddle 0 <=> 1 and paddle 2 <=> 3
// Also consider whether this is the left or right port

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: Paddles.hxx,v 1.13 2008-03-22 17:35:02 stephena Exp $
// $Id: Paddles.hxx,v 1.14 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef PADDLES_HXX
@ -27,7 +27,7 @@
The standard Atari 2600 pair of paddle controllers.
@author Bradford W. Mott
@version $Id: Paddles.hxx,v 1.13 2008-03-22 17:35:02 stephena Exp $
@version $Id: Paddles.hxx,v 1.14 2008-04-13 23:43:14 stephena Exp $
*/
class Paddles : public Controller
{
@ -35,11 +35,12 @@ class Paddles : public Controller
/**
Create a new pair of paddle controllers plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param swap Whether to swap the paddles plugged into this jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
@param swap Whether to swap the paddles plugged into this jack
*/
Paddles(Jack jack, const Event& event, bool swap);
Paddles(Jack jack, const Event& event, const System& system, bool swap);
/**
Destructor

View File

@ -13,15 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TrackBall22.cxx,v 1.4 2008-03-08 23:34:23 stephena Exp $
// $Id: TrackBall22.cxx,v 1.5 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#include "Event.hxx"
#include "TrackBall22.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TrackBall22::TrackBall22(Jack jack, const Event& event)
: Controller(jack, event, Controller::TrackBall22),
TrackBall22::TrackBall22(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::TrackBall22),
myHCounter(0),
myVCounter(0)
{

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: TrackBall22.hxx,v 1.2 2008-02-06 13:45:22 stephena Exp $
// $Id: TrackBall22.hxx,v 1.3 2008-04-13 23:43:14 stephena Exp $
//============================================================================
#ifndef TRACKBALL22_HXX
@ -27,7 +27,7 @@
The standard Atari 2600 CX-22 Trakball controller.
@author Stephen Anthony
@version $Id: TrackBall22.hxx,v 1.2 2008-02-06 13:45:22 stephena Exp $
@version $Id: TrackBall22.hxx,v 1.3 2008-04-13 23:43:14 stephena Exp $
*/
class TrackBall22 : public Controller
{
@ -35,10 +35,11 @@ class TrackBall22 : public Controller
/**
Create a new CX-22 TrackBall controller plugged into the specified jack
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
*/
TrackBall22(Jack jack, const Event& event);
TrackBall22(Jack jack, const Event& event, const System& system);
/**
Destructor