mirror of https://github.com/stella-emu/stella.git
Add support for 2600-daptor II when flashed as an AVox-USB converter.
Basically, for this device we use software flow control rather than hardware CTS signal.
This commit is contained in:
parent
0ef60c517b
commit
c00fda482d
|
@ -34,8 +34,8 @@
|
|||
one ZIP file, and distribute just that file.
|
||||
|
||||
* Extended AtariVox support to handle flow control, so that long phrases
|
||||
are no longer corrupted/cut off. Note that some USB-serial adaptors
|
||||
don't support this mode, so there may still be issues with those.
|
||||
are no longer corrupted/cut off. This includes properly supporting the
|
||||
2600-daptor II, which is flashable to an AVox-USB converter.
|
||||
|
||||
* Added option to select the audio device.
|
||||
|
||||
|
|
|
@ -56,10 +56,27 @@ bool AtariVox::read(DigitalPin pin)
|
|||
switch(pin)
|
||||
{
|
||||
// Pin 2: SpeakJet READY
|
||||
// CTS (Clear To Send) is sent directly to pin 2
|
||||
// We also deal with the case where devices send CTS inverted
|
||||
// READY signal is sent directly to pin 2
|
||||
case DigitalPin::Two:
|
||||
return setPin(pin, mySerialPort->isCTS() ^ myCTSFlip);
|
||||
{
|
||||
// Some USB-serial adaptors support only CTS, others support only
|
||||
// software flow control
|
||||
// So we check the state of both then AND the results, on the
|
||||
// assumption that if a mode isn't supported, then it reads as TRUE
|
||||
// and doesn't change the boolean result
|
||||
// Thus the logic is:
|
||||
// READY_SIGNAL = READY_STATE_CTS && READY_STATE_FLOW
|
||||
// Note that we also have to take inverted CTS into account
|
||||
|
||||
// When using software flow control, only update on a state change
|
||||
uInt8 flowCtrl = 0;
|
||||
if(mySerialPort->readByte(flowCtrl))
|
||||
myReadyStateSoftFlow = flowCtrl == 0x11; // XON
|
||||
|
||||
// Now combine the results of CTS and'ed with flow control
|
||||
return setPin(pin,
|
||||
(mySerialPort->isCTS() ^ myCTSFlip) && myReadyStateSoftFlow);
|
||||
}
|
||||
|
||||
default:
|
||||
return SaveKey::read(pin);
|
||||
|
|
|
@ -32,7 +32,7 @@ class FilesystemNode;
|
|||
This code owes a great debt to Alex Herbert's AtariVox documentation and
|
||||
driver code.
|
||||
|
||||
@author B. Watson
|
||||
@author B. Watson, Stephen Anthony
|
||||
*/
|
||||
class AtariVox : public SaveKey
|
||||
{
|
||||
|
@ -91,7 +91,9 @@ class AtariVox : public SaveKey
|
|||
*/
|
||||
void reset() override;
|
||||
|
||||
string about(bool swappedPorts) const override { return Controller::about(swappedPorts) + myAboutString; }
|
||||
string about(bool swappedPorts) const override {
|
||||
return Controller::about(swappedPorts) + myAboutString;
|
||||
}
|
||||
|
||||
private:
|
||||
void clockDataIn(bool value);
|
||||
|
@ -117,9 +119,11 @@ class AtariVox : public SaveKey
|
|||
// "close enough".
|
||||
uInt64 myLastDataWriteCycle{0};
|
||||
|
||||
// Some USB-Serial adaptors either don't support CTS, or send the signal
|
||||
// as inverted; we detect that when opening the port, and flip the signal
|
||||
// when necessary
|
||||
// When using software flow control, assume the device starts in READY mode
|
||||
bool myReadyStateSoftFlow{true};
|
||||
|
||||
// Some USB-Serial adaptors send the CTS signal inverted; we detect
|
||||
// that when opening the port, and flip the signal when necessary
|
||||
bool myCTSFlip{false};
|
||||
|
||||
// Holds information concerning serial port usage
|
||||
|
|
|
@ -43,7 +43,6 @@ class SerialPort
|
|||
|
||||
/**
|
||||
Read a byte from the serial port.
|
||||
NOTE: This is for potential future use; no class currently uses this.
|
||||
|
||||
@param data Destination for the byte read from the port
|
||||
@return True if a byte was read, else false
|
||||
|
|
|
@ -63,14 +63,21 @@ bool SerialPortMACOS::openPort(const string& device)
|
|||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortMACOS::readByte(uInt8& data)
|
||||
{
|
||||
if(myHandle)
|
||||
return read(myHandle, &data, 1) == 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortMACOS::writeByte(uInt8 data)
|
||||
{
|
||||
if(myHandle)
|
||||
{
|
||||
// cerr << "SerialPortMACOS::writeByte " << int(data) << endl;
|
||||
return write(myHandle, &data, 1) == 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ class SerialPortMACOS : public SerialPort
|
|||
*/
|
||||
bool openPort(const string& device) override;
|
||||
|
||||
/**
|
||||
Read a byte from the serial port.
|
||||
|
||||
@param data Destination for the byte read from the port
|
||||
@return True if a byte was read, else false
|
||||
*/
|
||||
bool readByte(uInt8& data) override;
|
||||
|
||||
/**
|
||||
Write a byte to the serial port.
|
||||
|
||||
|
|
|
@ -49,7 +49,9 @@ bool SerialPortUNIX::openPort(const string& device)
|
|||
if(myHandle <= 0)
|
||||
return false;
|
||||
|
||||
// Open the device in nonblocking mode
|
||||
// Clear buffers, then open the device in nonblocking mode
|
||||
tcflush(myHandle, TCOFLUSH);
|
||||
tcflush(myHandle, TCIFLUSH);
|
||||
fcntl(myHandle, F_SETFL, FNDELAY);
|
||||
|
||||
struct termios termios;
|
||||
|
@ -64,14 +66,21 @@ bool SerialPortUNIX::openPort(const string& device)
|
|||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortUNIX::readByte(uInt8& data)
|
||||
{
|
||||
if(myHandle)
|
||||
return read(myHandle, &data, 1) == 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortUNIX::writeByte(uInt8 data)
|
||||
{
|
||||
if(myHandle)
|
||||
{
|
||||
// cerr << "SerialPortUNIX::writeByte " << int(data) << endl;
|
||||
return write(myHandle, &data, 1) == 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ class SerialPortUNIX : public SerialPort
|
|||
*/
|
||||
bool openPort(const string& device) override;
|
||||
|
||||
/**
|
||||
Read a byte from the serial port.
|
||||
|
||||
@param data Destination for the byte read from the port
|
||||
@return True if a byte was read, else false
|
||||
*/
|
||||
bool readByte(uInt8& data) override;
|
||||
|
||||
/**
|
||||
Write a byte to the serial port.
|
||||
|
||||
|
|
|
@ -62,6 +62,14 @@ bool SerialPortWINDOWS::openPort(const string& device)
|
|||
dcb.Parity = NOPARITY;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
SetCommState(myHandle, &dcb);
|
||||
|
||||
COMMTIMEOUTS commtimeouts;
|
||||
commtimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commtimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commtimeouts.ReadTotalTimeoutConstant = 1;
|
||||
commtimeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
commtimeouts.WriteTotalTimeoutConstant = 0;
|
||||
SetCommTimeouts(myHandle, &commtimeouts);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
@ -69,13 +77,26 @@ bool SerialPortWINDOWS::openPort(const string& device)
|
|||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortWINDOWS::readByte(uInt8& data)
|
||||
{
|
||||
if(myHandle)
|
||||
{
|
||||
DWORD read;
|
||||
ReadFile(myHandle, &data, 1, &read, NULL);
|
||||
return read == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SerialPortWINDOWS::writeByte(uInt8 data)
|
||||
{
|
||||
if(myHandle)
|
||||
{
|
||||
DWORD written;
|
||||
return WriteFile(myHandle, &data, 1, &written, 0) == TRUE;
|
||||
WriteFile(myHandle, &data, 1, &written, NULL);
|
||||
return written == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,14 @@ class SerialPortWINDOWS : public SerialPort
|
|||
*/
|
||||
bool openPort(const string& device) override;
|
||||
|
||||
/**
|
||||
Read a byte from the serial port.
|
||||
|
||||
@param data Destination for the byte read from the port
|
||||
@return True if a byte was read, else false
|
||||
*/
|
||||
bool readByte(uInt8& data) override;
|
||||
|
||||
/**
|
||||
Write a byte to the serial port.
|
||||
|
||||
|
|
Loading…
Reference in New Issue