Added Mindlink controller emulation. Based on research, it seems that

only Bionic Breakthrough ever used this scheme, not Mind Maze and
Telepathy (as the properties database previously indicated).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2429 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-03-25 14:42:09 +00:00
parent 191e456770
commit db6e1c7c81
10 changed files with 79 additions and 89 deletions

View File

@ -18,6 +18,9 @@
actual keyboard, instead of having to remember the weird combinations
used on the original CompuMate keyboard.
* Added emulation for MindLink controller; the Bionic Breakthrough
ROM now works.
-Have fun!

View File

@ -10,7 +10,7 @@
<br><br>
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
<center><h4><b>Release 3.6</b></h4></center>
<center><h4><b>Release 3.7</b></h4></center>
<br><br>
<center><h2><b>User's Guide</b></h2></center>
@ -54,7 +54,7 @@
<br><br><br>
<center><b>February 1999 - March 2012</b></center>
<center><b>February 1999 - April 2012</b></center>
<center><b>The Stella Team</b></center>
<center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center>
@ -263,6 +263,7 @@
<li>Emulates Spectravideo CompuMate system using your computer's keyboard,
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
to the actual keys on your keyboard.</li>
<li>Emulates the Mindlink Controller using your computer's mouse</li>
<li>Support for real Atari 2600 controllers using the
<a href="http://www.stelladaptor.com">Stelladaptor</a> and
<a href="http://2600-daptor.com">2600-adaptor/2600-daptor II</a></li>
@ -1662,6 +1663,14 @@
<td> &#x2715;</td>
<td> &#x2715;</td>
</tr>
<tr>
<th> Mindlink</th>
<td> &#x2715;</td>
<td> &#x2715;</td>
<td> &#x2713;</td>
<td> &#x2713; (axis ignored)</td>
<td> &#x2715;</td>
</tr>
<tr>
<th> AtariVox</th>
<td> N/A</td>
@ -3180,6 +3189,7 @@ Ms Pac-Man (Stella extended codes):
<tr><td><a href="http://www.vectrex.biz/MemCard.htm">SaveKey</a></td><td>A 32K EEPROM for saving high scores, etc (the EEPROM portion of an AtariVox).</td></tr>
<tr><td>Genesis </td><td>Sega Genesis controller, which can be used similar to a BoosterGrip, giving an extra button.</td></tr>
<tr><td>CompuMate </td><td>Spectravideo CompuMate (if either left or right is set, CompuMate is used for both).</td></tr>
<tr><td>Mindlink </td><td>Mindlink controller.</td></tr>
</table></td>
</tr>

View File

@ -99,8 +99,10 @@ class CompuMate
public:
/**
Called after *all* digital pins have been written on Port A.
@param value The entire contents of the SWCHA register
*/
void controlWrite() { myHandler.update(); }
void controlWrite(uInt8) { myHandler.update(); }
/**
Update the entire digital and analog pin state according to the

View File

@ -160,8 +160,10 @@ class Controller : public Serializable
/**
Called after *all* digital pins have been written on Port A.
Most controllers don't do anything in this case.
@param value The entire contents of the SWCHA register
*/
virtual void controlWrite() { };
virtual void controlWrite(uInt8 value) { };
/**
Update the entire digital and analog pin state according to the

View File

@ -216,7 +216,7 @@ static const char* DefProps[DEF_PROPS_SIZE][21] = {
{ "0dfbdadf8f1bc718e7e1bb3ccd5fef3d", "", "", "Mr. Pac-Man (New start tune) (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e0808227ef41f6825c06f25082c2e56", "", "", "Candi (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e08cd2c5bcf11c6a7e5a009a7715b6a", "", "", "Boing! (PD) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "" },
{ "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e4b2b6e014a93ef8be896823da0d4ec", "", "", "Skiing (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e713d4e272ea7322c5b27d645f56dd0", "Home Vision - Gem International Corp.", "VCS83105", "Panda Chase (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "0e7e73421606873b544e858c59dc283e", "Digivision", "", "Super Soccer (Digivision)", "AKA RealSports Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
@ -829,7 +829,7 @@ static const char* DefProps[DEF_PROPS_SIZE][21] = {
{ "3d48b8b586a09bdbf49f1a016bf4d29a", "Video Game Cartridge - Ariola", "TP-606", "Hole Hunter (Video Game Cartridge)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3d6fc7a19be76d808aa233415cb583fc", "CCE", "C-833", "Target Practice (1983) (CCE)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "26", "214", "", "" },
{ "3d7749fb9c2f91a276dfe494495234c5", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "" },
{ "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3d8a2d6493123a53ade45e3e2c5cafa0", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3d934bb980e2e63e1ead3e7756928ccd", "Activision, Steve Cartwright - Ariola", "EAX-017, EAX-017-04I - 711 017-720", "MegaMania (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3d9c2fccf8b11630762ff00811c19277", "", "", "Challenge of.... Nexar, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },

View File

@ -272,24 +272,24 @@ void M6532::setPinState(bool swcha)
if(DDR bit is input) set output as 1
else if(DDR bit is output) set output as bit in ORA
*/
uInt8 a = myOutA | ~myDDRA;
Controller& port0 = myConsole.controller(Controller::Left);
port0.write(Controller::One, a & 0x10);
port0.write(Controller::Two, a & 0x20);
port0.write(Controller::Three, a & 0x40);
port0.write(Controller::Four, a & 0x80);
Controller& port1 = myConsole.controller(Controller::Right);
port1.write(Controller::One, a & 0x01);
port1.write(Controller::Two, a & 0x02);
port1.write(Controller::Three, a & 0x04);
port1.write(Controller::Four, a & 0x08);
uInt8 ioport = myOutA | ~myDDRA;
port0.write(Controller::One, ioport & 0x10);
port0.write(Controller::Two, ioport & 0x20);
port0.write(Controller::Three, ioport & 0x40);
port0.write(Controller::Four, ioport & 0x80);
port1.write(Controller::One, ioport & 0x01);
port1.write(Controller::Two, ioport & 0x02);
port1.write(Controller::Three, ioport & 0x04);
port1.write(Controller::Four, ioport & 0x08);
if(swcha)
{
port0.controlWrite();
port1.controlWrite();
port0.controlWrite(ioport);
port1.controlWrite(ioport);
}
}

View File

@ -23,12 +23,14 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MindLink::MindLink(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::MindLink),
myIOPort(0xff),
myMindlinkPos(0x2800),
myMindlinkPos1(0x2800),
myMindlinkPos2(0x1000),
myMindlinkShift(1)
{
myDigitalPinState[One] = true;
myDigitalPinState[Two] = true;
myDigitalPinState[Three] = true;
myDigitalPinState[Four] = true;
// Analog pins are never used by the MindLink
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
}
@ -41,61 +43,35 @@ MindLink::~MindLink()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MindLink::update()
{
myIOPort |= 0xf0;
if(0)//MPdirection & 0x01)
myMindlinkPos = myMindlinkPos2 + 0x1800;
else
myMindlinkPos = myMindlinkPos1;
myDigitalPinState[One] =
myDigitalPinState[Two] =
myDigitalPinState[Three] =
myDigitalPinState[Four] = true;
myMindlinkPos = (myMindlinkPos & 0x3fffffff) +
(myEvent.get(Event::MouseAxisXValue) << 3);
if(myMindlinkPos < 0x2800)
myMindlinkPos = 0x2800;
if(myMindlinkPos >= 0x3800)
myMindlinkPos = 0x3800;
if(0)//MPdirection & 0x01)
{
myMindlinkPos2 = myMindlinkPos - 0x1800;
myMindlinkPos = myMindlinkPos2;
}
else
myMindlinkPos1 = myMindlinkPos;
myMindlinkShift = 1;
nextMindlinkBit();
if(myEvent.get(Event::MouseButtonLeftValue) ||
myEvent.get(Event::MouseButtonRightValue))
myMindlinkPos |= 0x4000; /* this bit starts a game */
//cerr << HEX4 << (int)myMindlinkPos << " : " << HEX2 << (int)myIOPort << endl;
// Convert IOPort values back to booleans
myDigitalPinState[One] = myIOPort & 0x10;
myDigitalPinState[Two] = myIOPort & 0x20;
myDigitalPinState[Three] = myIOPort & 0x40;
myDigitalPinState[Four] = myIOPort & 0x80;
myMindlinkPos |= 0x4000; // this bit starts a game
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MindLink::nextMindlinkBit()
{
if(myIOPort & 0x10)
if(myDigitalPinState[One])
{
myIOPort &= 0x3f;
myDigitalPinState[Three] = false;
myDigitalPinState[Four] = false;
if(myMindlinkPos & myMindlinkShift)
myIOPort |= 0x80;
myDigitalPinState[Four] = true;
myMindlinkShift <<= 1;
myDigitalPinState[One] = myIOPort & 0x10;
myDigitalPinState[Two] = myIOPort & 0x20;
myDigitalPinState[Three] = myIOPort & 0x40;
myDigitalPinState[Four] = myIOPort & 0x80;
cerr << dec << (int)myMindlinkShift << " : " << HEX2 << (int)myIOPort << endl;
}
}

View File

@ -59,9 +59,21 @@ class MindLink : public Controller
public:
/**
Called after *all* digital pins have been written on Port A.
Write the given value to the specified digital pin for this
controller. Writing is only allowed to the pins associated
with the PIA. Therefore you cannot write to pin six.
@param pin The pin of the controller jack to write to
@param value The value to write to the pin
*/
void controlWrite() { nextMindlinkBit(); }
void write(DigitalPin pin, bool value) { myDigitalPinState[pin] = value; }
/**
Called after *all* digital pins have been written on Port A.
@param value The entire contents of the SWCHA register
*/
void controlWrite(uInt8) { nextMindlinkBit(); }
/**
Update the entire digital and analog pin state according to the
@ -73,21 +85,10 @@ class MindLink : public Controller
void nextMindlinkBit();
private:
uInt8 myMask1, myMask2, myMask3;
// Internal state of the port pins
uInt8 myIOPort;
// Position value in Mindlink controller
// Gets transferred bitwise (16 bits)
int myMindlinkPos;
// Position for player 1 (0x2800-0x3800)
int myMindlinkPos1;
// Position for player 2 (0x1000-0x2000)
int myMindlinkPos2;
// Which bit to transfer next
int myMindlinkShift;
};

View File

@ -402,6 +402,14 @@
"Controller.MouseAxis" "01"
""
"Cartridge.MD5" "c246e05b52f68ab2e9aee40f278cd158"
"Cartridge.Manufacturer" "Thomas Jentzsch"
"Cartridge.Name" "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)"
"Cartridge.Note" "NTSC Conversion"
"Cartridge.Rarity" "Homebrew"
"Display.Height" "230"
""
"Cartridge.MD5" "7b5207e68ee85b16998bea861987c690"
"Cartridge.Manufacturer" "Atari, Carol Shaw"
"Cartridge.ModelNo" "CX26163P"
@ -413,14 +421,6 @@
"Cartridge.Name" "Fu Kung! (V0.16) (2003) (AD)"
""
"Cartridge.MD5" "c246e05b52f68ab2e9aee40f278cd158"
"Cartridge.Manufacturer" "Thomas Jentzsch"
"Cartridge.Name" "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)"
"Cartridge.Note" "NTSC Conversion"
"Cartridge.Rarity" "Homebrew"
"Display.Height" "230"
""
"Cartridge.MD5" "cba56e939252b05df7b7de87307d12ca"
"Cartridge.Name" "Playfield Text Demo (2001) (Roger Williams)"
""
@ -760,6 +760,11 @@
"Cartridge.Rarity" "Prototype"
""
"Cartridge.MD5" "bdf1996e2dd64baf8eff5511811ca6ca"
"Cartridge.Manufacturer" "Tron"
"Cartridge.Name" "H.E.R.O. (Tron)"
""
"Cartridge.MD5" "81414174f1816d5c1e583af427ac89fc"
"Cartridge.Manufacturer" "Thomas Jentzsch"
"Cartridge.Name" "Treasure Below (Thomas Jentzsch)"
@ -777,11 +782,6 @@
"Cartridge.Note" "AKA International Soccer"
""
"Cartridge.MD5" "bdf1996e2dd64baf8eff5511811ca6ca"
"Cartridge.Manufacturer" "Tron"
"Cartridge.Name" "H.E.R.O. (Tron)"
""
"Cartridge.MD5" "521f4dd1eb84a09b2b19959a41839aad"
"Cartridge.Manufacturer" "Bit Corporation"
"Cartridge.ModelNo" "PG206"
@ -9233,9 +9233,7 @@
"Cartridge.MD5" "0e224ea74310da4e7e2103400eb1b4bf"
"Cartridge.Manufacturer" "Atari, Peter C. Niday, Howard Scott Warshaw"
"Cartridge.Name" "Mind Maze (10-10-1984) (Atari) (Prototype)"
"Cartridge.Note" "Uses the Mindlink Controller"
"Cartridge.Rarity" "Prototype"
"Controller.Left" "MINDLINK"
""
"Cartridge.MD5" "eb503cc64c3560cd78b7051188b7ba56"
@ -14298,9 +14296,7 @@
"Cartridge.MD5" "3d7aad37c55692814211c8b590a0334c"
"Cartridge.Manufacturer" "Atari, Dan Oliver"
"Cartridge.Name" "Telepathy (1983) (Atari) (Prototype)"
"Cartridge.Note" "Uses the Mindlink Controller"
"Cartridge.Rarity" "Prototype"
"Controller.Left" "MINDLINK"
""
"Cartridge.MD5" "f777444fc21a5925e066b68b1d350575"

View File

@ -242,7 +242,7 @@ GameInfoDialog::GameInfoDialog(
ctrls.push_back("Sega Genesis", "GENESIS" );
ctrls.push_back("CompuMate", "COMPUMATE" );
// ctrls.push_back("KidVid", "KIDVID" );
// ctrls.push_back("MindLink", "MINDLINK" );
ctrls.push_back("MindLink", "MINDLINK" );
myP0Controller = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, ctrls, "", 0, 0);
wid.push_back(myP0Controller);