. DCD state is now a mirror of DSR unless -dcd switch is used. (Fixes #553)
. Removed -dsr,-dtr switches, so -modem is now an alias for -dcd.  (Also for #553)
. Wait for events (RLSD,DSR,CTS) in CommThread and call GetCommModemStatus() in CommThread.
This commit is contained in:
tomcw 2018-04-22 14:37:59 +01:00
parent 279fdf523b
commit 52e7d61c7e
3 changed files with 34 additions and 71 deletions

View File

@ -1210,24 +1210,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{ {
g_bMultiMon = true; g_bMultiMon = true;
} }
else if (strcmp(lpCmdLine, "-dcd") == 0) // GH#386 else if ((strcmp(lpCmdLine, "-dcd") == 0) || (strcmp(lpCmdLine, "-modem") == 0)) // GH#386
{ {
sg_SSC.SupportDCD(true); sg_SSC.SupportDCD(true);
} }
else if (strcmp(lpCmdLine, "-dsr") == 0) // GH#386
{
sg_SSC.SupportDSR(true);
}
else if (strcmp(lpCmdLine, "-dtr") == 0) // GH#386
{
sg_SSC.SupportDTR(true);
}
else if (strcmp(lpCmdLine, "-modem") == 0) // GH#386
{
sg_SSC.SupportDCD(true);
sg_SSC.SupportDSR(true);
sg_SSC.SupportDTR(true);
}
else // unsupported else // unsupported
{ {
LogFileOutput("Unsupported arg: %s\n", lpCmdLine); LogFileOutput("Unsupported arg: %s\n", lpCmdLine);

View File

@ -68,9 +68,7 @@ CSuperSerialCard::CSuperSerialCard() :
m_aySerialPortChoices(NULL), m_aySerialPortChoices(NULL),
m_uTCPChoiceItemIdx(0), m_uTCPChoiceItemIdx(0),
m_uSlot(0), m_uSlot(0),
m_bCfgSupportDCD(false), m_bCfgSupportDCD(false)
m_bCfgSupportDSR(false),
m_bCfgSupportDTR(false)
{ {
memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName)); memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName));
m_dwSerialPortItem = 0; m_dwSerialPortItem = 0;
@ -119,6 +117,7 @@ void CSuperSerialCard::InternalReset()
m_uDTR = DTR_CONTROL_DISABLE; m_uDTR = DTR_CONTROL_DISABLE;
m_uRTS = RTS_CONTROL_DISABLE; m_uRTS = RTS_CONTROL_DISABLE;
m_dwModemStatus = m_kDefaultModemStatus;
} }
CSuperSerialCard::~CSuperSerialCard() CSuperSerialCard::~CSuperSerialCard()
@ -524,11 +523,8 @@ void CSuperSerialCard::UpdateCommandReg(BYTE command)
m_bRxIrqEnabled = false; m_bRxIrqEnabled = false;
} }
if (m_bCfgSupportDTR) // GH#386 // Data Terminal Ready (DTR) setting (0=set DTR high (indicates 'not ready')) (GH#386)
{
// Data Terminal Ready (DTR) setting (0=set DTR high (indicates 'not ready'))
m_uDTR = (m_uCommandByte & CMD_DTR) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE; m_uDTR = (m_uCommandByte & CMD_DTR) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
}
} }
BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value, ULONG) BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value, ULONG)
@ -754,28 +750,20 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
if (!CheckComm()) if (!CheckComm())
return ST_DSR | ST_DCD | ST_TX_EMPTY; return ST_DSR | ST_DCD | ST_TX_EMPTY;
static DWORD modemStatus = 0; DWORD modemStatus = m_kDefaultModemStatus;
if (m_bCfgSupportDCD || m_bCfgSupportDSR)
{
if (m_hCommHandle != INVALID_HANDLE_VALUE) if (m_hCommHandle != INVALID_HANDLE_VALUE)
{ {
// Call GetCommModemStatus() outside of the critical section. For Win7-64: takes 1-2msecs! modemStatus = m_dwModemStatus; // Take a copy of this volatile variable
static DWORD dwLastTimeGettingModemStatus = 0; if (!m_bCfgSupportDCD) // Default: DSR state is mirrored to DCD (GH#553)
DWORD dwCurrTime = GetTickCount();
if (dwCurrTime - dwLastTimeGettingModemStatus > 8) // Limit reading status to twice a 16.6ms video frame (arbitrary throttle limit)
{ {
// Only permit periodic reading, otherwise a tight 6502 polling loop can kill emulator performance! modemStatus &= ~MS_RLSD_ON;
GetCommModemStatus(m_hCommHandle, &modemStatus); // Returns 0x30 = MS_DSR_ON|MS_CTS_ON if (modemStatus & MS_DSR_ON)
dwLastTimeGettingModemStatus = dwCurrTime; modemStatus |= MS_RLSD_ON;
} }
} }
else if (m_hCommListenSocket != INVALID_SOCKET) else if (m_hCommListenSocket != INVALID_SOCKET && m_hCommAcceptSocket != INVALID_SOCKET)
{ {
if (m_hCommAcceptSocket != INVALID_SOCKET)
modemStatus = MS_RLSD_ON | MS_DSR_ON | MS_CTS_ON; modemStatus = MS_RLSD_ON | MS_DSR_ON | MS_CTS_ON;
else
modemStatus = 0;
}
} }
// //
@ -803,17 +791,8 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
// //
BYTE DSR = 0; BYTE DSR = (modemStatus & MS_DSR_ON) ? 0x00 : ST_DSR; // DSR is active low (see SY6551 datasheet) (GH#386)
BYTE DCD = 0; BYTE DCD = (modemStatus & MS_RLSD_ON) ? 0x00 : ST_DCD; // DCD is active low (see SY6551 datasheet) (GH#386)
if ((m_hCommHandle != INVALID_HANDLE_VALUE) && (m_bCfgSupportDCD || m_bCfgSupportDSR)) // GH#386
{
if (m_bCfgSupportDSR)
DSR = (modemStatus & MS_DSR_ON) ? 0x00 : ST_DSR;
if (m_bCfgSupportDCD)
DCD = (modemStatus & MS_RLSD_ON) ? 0x00 : ST_DCD;
}
// //
@ -825,7 +804,7 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
BYTE uStatus = BYTE uStatus =
IRQ IRQ
| DSR | DSR
| DCD // Need 0x00 (ie. DCD is active) to allow ZLink to start up | DCD
| TX_EMPTY | TX_EMPTY
| RX_FULL; | RX_FULL;
@ -882,17 +861,11 @@ BYTE __stdcall CSuperSerialCard::CommDipSw(WORD, WORD addr, BYTE, BYTE, ULONG)
BYTE SW2_5 = m_DIPSWCurrent.bLinefeed ? 0 : 1; // SW2-5 (LF: yes-ON(0); no-OFF(1)) BYTE SW2_5 = m_DIPSWCurrent.bLinefeed ? 0 : 1; // SW2-5 (LF: yes-ON(0); no-OFF(1))
BYTE CTS = 0; // GH#311 BYTE CTS = 1; // Default to CTS being false. (Support CTS in DIPSW: GH#311)
if (CheckComm() && m_hCommHandle != INVALID_HANDLE_VALUE) if (CheckComm() && m_hCommHandle != INVALID_HANDLE_VALUE)
{ CTS = (m_dwModemStatus & MS_CTS_ON) ? 0 : 1; // CTS active low (see SY6551 datasheet)
DWORD modemStatus = 0;
if (GetCommModemStatus(m_hCommHandle, &modemStatus))
CTS = (modemStatus & MS_CTS_ON) ? 0 : 1; // CTS is true when 0
}
else if (m_hCommListenSocket != INVALID_SOCKET) else if (m_hCommListenSocket != INVALID_SOCKET)
{
CTS = (m_hCommAcceptSocket != INVALID_SOCKET) ? 0 : 1; CTS = (m_hCommAcceptSocket != INVALID_SOCKET) ? 0 : 1;
}
// SSC-54: // SSC-54:
sw = SW2_1<<7 | // b7 : SW2-1 sw = SW2_1<<7 | // b7 : SW2-1
@ -1070,10 +1043,18 @@ void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask)
LeaveCriticalSection(&m_CriticalSection); LeaveCriticalSection(&m_CriticalSection);
} }
} }
else if (dwEvtMask & EV_TXEMPTY)
if (dwEvtMask & EV_TXEMPTY)
{ {
TransmitDone(); TransmitDone();
} }
if (dwEvtMask & (EV_RLSD|EV_DSR|EV_CTS))
{
// For Win7-64: takes 1-2msecs!
// Don't read from main emulation thread, otherwise a tight 6502 polling loop can kill emulator performance!
GetCommModemStatus(m_hCommHandle, const_cast<DWORD*>(&m_dwModemStatus));
}
} }
DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter) DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
@ -1081,8 +1062,7 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
CSuperSerialCard* pSSC = (CSuperSerialCard*) lpParameter; CSuperSerialCard* pSSC = (CSuperSerialCard*) lpParameter;
char szDbg[100]; char szDbg[100];
BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_TXEMPTY | EV_RXCHAR); BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_RLSD | EV_DSR | EV_CTS | EV_TXEMPTY | EV_RXCHAR);
// BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_RXCHAR); // Just RX
if (!bRes) if (!bRes)
{ {
sprintf(szDbg, "SSC: CommThread(): SetCommMask() failed\n"); sprintf(szDbg, "SSC: CommThread(): SetCommMask() failed\n");

View File

@ -43,8 +43,6 @@ public:
void SetSerialPortName(const char* pSerialPortName); void SetSerialPortName(const char* pSerialPortName);
bool IsActive() { return (m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET); } bool IsActive() { return (m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET); }
void SupportDCD(bool bEnable) { m_bCfgSupportDCD = bEnable; } // Status void SupportDCD(bool bEnable) { m_bCfgSupportDCD = bEnable; } // Status
void SupportDSR(bool bEnable) { m_bCfgSupportDSR = bEnable; } // Status
void SupportDTR(bool bEnable) { m_bCfgSupportDTR = bEnable; } // Control
void CommTcpSerialAccept(); void CommTcpSerialAccept();
void CommTcpSerialReceive(); void CommTcpSerialReceive();
@ -139,12 +137,11 @@ private:
BYTE* m_pExpansionRom; BYTE* m_pExpansionRom;
UINT m_uSlot; UINT m_uSlot;
// Modem
bool m_bCfgSupportDCD; bool m_bCfgSupportDCD;
bool m_bCfgSupportDSR;
bool m_bCfgSupportDTR;
UINT m_uDTR; UINT m_uDTR;
// Modem (end)
static const DWORD m_kDefaultModemStatus = 0; // MS_RLSD_OFF(=DCD_OFF), MS_DSR_OFF, MS_CTS_OFF
volatile DWORD m_dwModemStatus; // Updated by CommThread when any of RLSD|DSR|CTS changes / Read by main thread - CommStatus()& CommDipSw()
UINT m_uRTS; UINT m_uRTS;
}; };