diff --git a/stella/src/debugger/EquateList.cxx b/stella/src/debugger/EquateList.cxx index 2ba77ee2e..9bdb0b961 100644 --- a/stella/src/debugger/EquateList.cxx +++ b/stella/src/debugger/EquateList.cxx @@ -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: EquateList.cxx,v 1.31 2008-05-04 17:16:39 stephena Exp $ +// $Id: EquateList.cxx,v 1.32 2008-05-06 16:39:10 stephena Exp $ //============================================================================ #include @@ -71,9 +71,9 @@ void EquateList::addEquate(const string& label, int address) else if((address & 0x1000) == 0x1000) flags = EQF_RW; else -{ cerr << "label = " << label << ", address = " << hex << address << " discarded\n"; +//{ cerr << "label = " << label << ", address = " << hex << address << " discarded\n"; return; // don't know what else to do for now -} +//} removeEquate(label); diff --git a/stella/src/emucore/AtariVox.cxx b/stella/src/emucore/AtariVox.cxx index 49d1f74eb..6a3bf3fee 100644 --- a/stella/src/emucore/AtariVox.cxx +++ b/stella/src/emucore/AtariVox.cxx @@ -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: AtariVox.cxx,v 1.18 2008-04-29 20:06:14 stephena Exp $ +// $Id: AtariVox.cxx,v 1.19 2008-05-06 16:39:10 stephena Exp $ //============================================================================ #ifdef SPEAKJET_EMULATION @@ -102,6 +102,7 @@ void AtariVox::write(DigitalPin pin, bool value) // Pin 1: SpeakJet DATA // output serial data to the speakjet case One: + myDigitalPinState[One] = value; clockDataIn(value); break; @@ -114,6 +115,7 @@ void AtariVox::write(DigitalPin pin, bool value) << " written to SDA line at cycle " << mySystem.cycles() << endl; + myDigitalPinState[Three] = value; myEEPROM->writeSDA(value); break; @@ -126,6 +128,7 @@ void AtariVox::write(DigitalPin pin, bool value) << " written to SCLK line at cycle " << mySystem.cycles() << endl; + myDigitalPinState[Four] = value; myEEPROM->writeSCL(value); break; @@ -137,10 +140,6 @@ void AtariVox::write(DigitalPin pin, bool value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AtariVox::clockDataIn(bool value) { - // Data is normally inverted when sending to the SpeakJet; - // we need to reverse that -// value = !value; - uInt32 cycle = mySystem.cycles(); if(DEBUG_ATARIVOX) cerr << "AtariVox: value " diff --git a/stella/src/emucore/M6532.cxx b/stella/src/emucore/M6532.cxx index 491ca46d6..c0f0b5535 100644 --- a/stella/src/emucore/M6532.cxx +++ b/stella/src/emucore/M6532.cxx @@ -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: M6532.cxx,v 1.23 2008-04-28 21:31:40 stephena Exp $ +// $Id: M6532.cxx,v 1.24 2008-05-06 16:39:11 stephena Exp $ //============================================================================ #include @@ -137,9 +137,11 @@ uInt8 M6532::peek(uInt16 addr) if(port1.read(Controller::Three)) value |= 0x04; if(port1.read(Controller::Four)) value |= 0x08; - // Return the input bits set by the controller *and* the - // output bits set by the last write to SWCHA - return (value & ~myDDRA) | (myOutA & myDDRA); + // Each pin is high (1) by default and will only go low (0) if either + // (a) External device drives the pin low + // (b) Corresponding bit in SWACNT = 1 and SWCHA = 0 + // Thanks to A. Herbert for this info + return (myOutA | ~myDDRA) & value; } case 0x01: // Port A Data Direction Register @@ -235,59 +237,20 @@ void M6532::poke(uInt16 addr, uInt8 value) case 0: // Port A I/O Register (Joystick) { myOutA = value; - 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); + setOutputState(); break; } case 1: // Port A Data Direction Register { myDDRA = value; - - /* - Undocumented feature used by the AtariVox and SaveKey. - When the DDR is changed, the ORA (output register A) cached - from a previous write to SWCHA is 'applied' to the controller pins. - - When a bit in the DDR is set as input, +5V is placed on its output - pin. When it's set as output, either +5V or 0V (depending on the - contents of SWCHA) will be placed on the output pin. - The standard macros for the AtariVox use this fact to send data - to the port. This is represented by the following algorithm: - - 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); + setOutputState(); break; } default: // Port B I/O & DDR Registers (Console switches) break; // hardwired as read-only - } + } } } @@ -303,6 +266,34 @@ void M6532::setTimerRegister(uInt8 value, uInt8 interval) myCyclesWhenTimerSet = mySystem->cycles(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void M6532::setOutputState() +{ + /* + When a bit in the DDR is set as input, +5V is placed on its output + pin. When it's set as output, either +5V or 0V (depending on the + contents of SWCHA) will be placed on the output pin. + The standard macros for the AtariVox use this fact to send data + to the port. This is represented by the following algorithm: + + 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); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool M6532::save(Serializer& out) const { diff --git a/stella/src/emucore/M6532.hxx b/stella/src/emucore/M6532.hxx index fa1598991..4cec8186c 100644 --- a/stella/src/emucore/M6532.hxx +++ b/stella/src/emucore/M6532.hxx @@ -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: M6532.hxx,v 1.12 2008-04-23 16:51:11 stephena Exp $ +// $Id: M6532.hxx,v 1.13 2008-05-06 16:39:11 stephena Exp $ //============================================================================ #ifndef M6532_HXX @@ -32,7 +32,7 @@ class Deserializer; RIOT @author Bradford W. Mott - @version $Id: M6532.hxx,v 1.12 2008-04-23 16:51:11 stephena Exp $ + @version $Id: M6532.hxx,v 1.13 2008-05-06 16:39:11 stephena Exp $ */ class M6532 : public Device { @@ -131,6 +131,7 @@ class M6532 : public Device { return myTimer - (mySystem->cycles() - myCyclesWhenTimerSet); } void setTimerRegister(uInt8 data, uInt8 interval); + void setOutputState(); private: // Reference to the console diff --git a/stella/src/emucore/MT24LC256.cxx b/stella/src/emucore/MT24LC256.cxx index 9a4ab9884..b3c74f68b 100644 --- a/stella/src/emucore/MT24LC256.cxx +++ b/stella/src/emucore/MT24LC256.cxx @@ -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: MT24LC256.cxx,v 1.7 2008-04-29 20:06:14 stephena Exp $ +// $Id: MT24LC256.cxx,v 1.8 2008-05-06 16:39:11 stephena Exp $ //============================================================================ #include @@ -48,7 +48,11 @@ char jpee_msg[256]; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MT24LC256::MT24LC256(const string& filename, const System& system) : mySystem(system), + mySDA(false), + mySCL(false), myCyclesWhenTimerSet(0), + myCyclesWhenSDASet(0), + myCyclesWhenSCLSet(0), myDataFile(filename) { // First initialize the I2C state @@ -93,25 +97,42 @@ bool MT24LC256::readSDA() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::writeSDA(bool state) { -//cerr << "writeSDA: " << state << endl; + mySDA = state; + myCyclesWhenSDASet = mySystem.cycles(); -#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)) - - jpee_data(state); + update(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::writeSCL(bool state) { -//cerr << "writeSCL: " << state << endl; + mySCL = state; + myCyclesWhenSCLSet = mySystem.cycles(); + update(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MT24LC256::update() +{ #define jpee_clock(x) ( (x) ? \ (jpee_mclk = 1) : \ (jpee_mclk && (jpee_clock_fall(),1), jpee_mclk = 0)) - jpee_clock(state); +#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)) + + // These pins have to be updated at the same time + // However, the there's no guarantee that the writeSDA() and writeSDL() + // methods will be called at the same time or in the correct order, so + // we only do the write when they have the same 'timestamp' + if(myCyclesWhenSDASet == myCyclesWhenSCLSet) + { +cerr << endl << "--> SCL = " << mySCL << ", SDA = " << mySDA << " @ " << myCyclesWhenSDASet << endl; + jpee_clock(mySCL); + jpee_data(mySDA); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -127,12 +148,14 @@ void MT24LC256::jpee_init() for(int i = 0; i < 256; i++) for(int j = 0; j < 128; j++) myData[i + j*256] = (i+1)*(j+1); + +// jpee_timercheck(1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::jpee_data_start() { -//cerr << " ==> jpee_data_start()\n"; +cerr << " ==> jpee_data_start()\n"; /* We have a start condition */ if (jpee_state == 1 && (jpee_nb != 1 || jpee_pptr != 3)) { @@ -161,7 +184,7 @@ void MT24LC256::jpee_data_start() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::jpee_data_stop() { -//cerr << " ==> jpee_data_stop()\n"; +cerr << " ==> jpee_data_stop()\n"; int i; if (jpee_state == 1 && jpee_nb != 1) @@ -186,7 +209,7 @@ void MT24LC256::jpee_data_stop() } for (i=3; i writing\n"; +cerr << " => writing\n"; myData[(jpee_address++) & jpee_sizemask] = jpee_packet[i]; if (!(jpee_address & jpee_pagemask)) break; /* Writes can't cross page boundary! */ @@ -202,7 +225,7 @@ void MT24LC256::jpee_data_stop() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::jpee_clock_fall() { -//cerr << " ==> jpee_clock_fall()\n"; +cerr << " ==> jpee_clock_fall()\n"; switch(jpee_state) { case 1: @@ -318,12 +341,19 @@ bool MT24LC256::jpee_timercheck(int mode) if(mode) // set timer { myCyclesWhenTimerSet = mySystem.cycles(); +cerr << " --> timer set: " << myCyclesWhenTimerSet << endl; + return true; } else // read timer { uInt32 elapsed = mySystem.cycles() - myCyclesWhenTimerSet; -//cerr << " --> elapsed: " << elapsed << endl; + +if(elapsed < (uInt32)(5000000.0 / 838.0)) +cerr << " --> timer still running: " << elapsed << endl; +else +cerr << " --> timer expired: " << elapsed << endl; + return elapsed < (uInt32)(5000000.0 / 838.0); } } @@ -331,7 +361,7 @@ bool MT24LC256::jpee_timercheck(int mode) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int MT24LC256::jpee_logproc(char const *st) { -// cerr << " " << st << endl; + cerr << " " << st << endl; return 0; } diff --git a/stella/src/emucore/MT24LC256.hxx b/stella/src/emucore/MT24LC256.hxx index 43c190fdc..cf1efe80b 100644 --- a/stella/src/emucore/MT24LC256.hxx +++ b/stella/src/emucore/MT24LC256.hxx @@ -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: MT24LC256.hxx,v 1.2 2008-04-13 23:43:14 stephena Exp $ +// $Id: MT24LC256.hxx,v 1.3 2008-05-06 16:39:12 stephena Exp $ //============================================================================ #ifndef MT24LC256_HXX @@ -30,7 +30,7 @@ class System; (aka Supercat) for the bulk of this code. @author Stephen Anthony & J. Payson - @version $Id: MT24LC256.hxx,v 1.2 2008-04-13 23:43:14 stephena Exp $ + @version $Id: MT24LC256.hxx,v 1.3 2008-05-06 16:39:12 stephena Exp $ */ class MT24LC256 { @@ -65,6 +65,8 @@ class MT24LC256 int jpee_logproc(char const *st); bool jpee_timercheck(int mode); + void update(); + private: // The system of the parent controller const System& mySystem; @@ -72,9 +74,15 @@ class MT24LC256 // The EEPROM data uInt8 myData[32768]; + // Cached state of the SDA and SCL pins on the last write + bool mySDA, mySCL; + // Indicates when the timer was set uInt32 myCyclesWhenTimerSet; + // Indicates when the SDA and SCL pins were set/written + uInt32 myCyclesWhenSDASet, myCyclesWhenSCLSet; + // The file containing the EEPROM data string myDataFile; diff --git a/stella/src/emucore/SaveKey.cxx b/stella/src/emucore/SaveKey.cxx index 42fc8bacb..99595ef99 100644 --- a/stella/src/emucore/SaveKey.cxx +++ b/stella/src/emucore/SaveKey.cxx @@ -13,15 +13,13 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: SaveKey.cxx,v 1.1 2008-04-29 15:49:34 stephena Exp $ +// $Id: SaveKey.cxx,v 1.2 2008-05-06 16:39:12 stephena Exp $ //============================================================================ #include "MT24LC256.hxx" #include "System.hxx" #include "SaveKey.hxx" -#define DEBUG_SAVEKEY 0 - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SaveKey::SaveKey(Jack jack, const Event& event, const System& system, const string& eepromfile) @@ -67,24 +65,14 @@ void SaveKey::write(DigitalPin pin, bool value) // Pin 3: EEPROM SDA // output data to the 24LC256 EEPROM using the I2C protocol case Three: - if(DEBUG_SAVEKEY) - cerr << "SaveKey: value " - << value - << " written to SDA line at cycle " - << mySystem.cycles() - << endl; + myDigitalPinState[Three] = value; myEEPROM->writeSDA(value); break; // Pin 4: EEPROM SCL // output clock data to the 24LC256 EEPROM using the I2C protocol case Four: - if(DEBUG_SAVEKEY) - cerr << "SaveKey: value " - << value - << " written to SCLK line at cycle " - << mySystem.cycles() - << endl; + myDigitalPinState[Four] = value; myEEPROM->writeSCL(value); break;