From 52e7d61c7efaff92f8ba27b67cbec4978974dcf3 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 22 Apr 2018 14:37:59 +0100 Subject: [PATCH] SSC: . 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. --- source/Applewin.cpp | 16 +-------- source/SerialComms.cpp | 80 ++++++++++++++++-------------------------- source/SerialComms.h | 9 ++--- 3 files changed, 34 insertions(+), 71 deletions(-) diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 37909826..7505d533 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -1210,24 +1210,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) { 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); } - 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 { LogFileOutput("Unsupported arg: %s\n", lpCmdLine); diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 0964ba9a..7cde6fca 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -68,9 +68,7 @@ CSuperSerialCard::CSuperSerialCard() : m_aySerialPortChoices(NULL), m_uTCPChoiceItemIdx(0), m_uSlot(0), - m_bCfgSupportDCD(false), - m_bCfgSupportDSR(false), - m_bCfgSupportDTR(false) + m_bCfgSupportDCD(false) { memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName)); m_dwSerialPortItem = 0; @@ -119,6 +117,7 @@ void CSuperSerialCard::InternalReset() m_uDTR = DTR_CONTROL_DISABLE; m_uRTS = RTS_CONTROL_DISABLE; + m_dwModemStatus = m_kDefaultModemStatus; } CSuperSerialCard::~CSuperSerialCard() @@ -524,11 +523,8 @@ void CSuperSerialCard::UpdateCommandReg(BYTE command) m_bRxIrqEnabled = false; } - if (m_bCfgSupportDTR) // 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; - } + // Data Terminal Ready (DTR) setting (0=set DTR high (indicates 'not ready')) (GH#386) + m_uDTR = (m_uCommandByte & CMD_DTR) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE; } BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value, ULONG) @@ -754,29 +750,21 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG) if (!CheckComm()) return ST_DSR | ST_DCD | ST_TX_EMPTY; - static DWORD modemStatus = 0; - if (m_bCfgSupportDCD || m_bCfgSupportDSR) + DWORD modemStatus = m_kDefaultModemStatus; + if (m_hCommHandle != INVALID_HANDLE_VALUE) { - if (m_hCommHandle != INVALID_HANDLE_VALUE) + modemStatus = m_dwModemStatus; // Take a copy of this volatile variable + if (!m_bCfgSupportDCD) // Default: DSR state is mirrored to DCD (GH#553) { - // Call GetCommModemStatus() outside of the critical section. For Win7-64: takes 1-2msecs! - static DWORD dwLastTimeGettingModemStatus = 0; - 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! - GetCommModemStatus(m_hCommHandle, &modemStatus); // Returns 0x30 = MS_DSR_ON|MS_CTS_ON - dwLastTimeGettingModemStatus = dwCurrTime; - } - } - else if (m_hCommListenSocket != INVALID_SOCKET) - { - if (m_hCommAcceptSocket != INVALID_SOCKET) - modemStatus = MS_RLSD_ON | MS_DSR_ON | MS_CTS_ON; - else - modemStatus = 0; + modemStatus &= ~MS_RLSD_ON; + if (modemStatus & MS_DSR_ON) + modemStatus |= MS_RLSD_ON; } } + else if (m_hCommListenSocket != INVALID_SOCKET && m_hCommAcceptSocket != INVALID_SOCKET) + { + modemStatus = MS_RLSD_ON | MS_DSR_ON | MS_CTS_ON; + } // @@ -803,17 +791,8 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG) // - BYTE DSR = 0; - BYTE DCD = 0; - - 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; - } + BYTE DSR = (modemStatus & MS_DSR_ON) ? 0x00 : ST_DSR; // DSR is active low (see SY6551 datasheet) (GH#386) + BYTE DCD = (modemStatus & MS_RLSD_ON) ? 0x00 : ST_DCD; // DCD is active low (see SY6551 datasheet) (GH#386) // @@ -825,7 +804,7 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG) BYTE uStatus = IRQ | DSR - | DCD // Need 0x00 (ie. DCD is active) to allow ZLink to start up + | DCD | TX_EMPTY | 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 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) - { - DWORD modemStatus = 0; - if (GetCommModemStatus(m_hCommHandle, &modemStatus)) - CTS = (modemStatus & MS_CTS_ON) ? 0 : 1; // CTS is true when 0 - } + CTS = (m_dwModemStatus & MS_CTS_ON) ? 0 : 1; // CTS active low (see SY6551 datasheet) else if (m_hCommListenSocket != INVALID_SOCKET) - { CTS = (m_hCommAcceptSocket != INVALID_SOCKET) ? 0 : 1; - } // SSC-54: sw = SW2_1<<7 | // b7 : SW2-1 @@ -1070,10 +1043,18 @@ void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask) LeaveCriticalSection(&m_CriticalSection); } } - else if (dwEvtMask & EV_TXEMPTY) + + if (dwEvtMask & EV_TXEMPTY) { 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(&m_dwModemStatus)); + } } DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter) @@ -1081,8 +1062,7 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter) CSuperSerialCard* pSSC = (CSuperSerialCard*) lpParameter; char szDbg[100]; - BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_TXEMPTY | EV_RXCHAR); -// BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_RXCHAR); // Just RX + BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_RLSD | EV_DSR | EV_CTS | EV_TXEMPTY | EV_RXCHAR); if (!bRes) { sprintf(szDbg, "SSC: CommThread(): SetCommMask() failed\n"); diff --git a/source/SerialComms.h b/source/SerialComms.h index cfc393ca..89231dfa 100644 --- a/source/SerialComms.h +++ b/source/SerialComms.h @@ -43,8 +43,6 @@ public: void SetSerialPortName(const char* pSerialPortName); bool IsActive() { return (m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET); } 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 CommTcpSerialReceive(); @@ -139,12 +137,11 @@ private: BYTE* m_pExpansionRom; UINT m_uSlot; - // Modem bool m_bCfgSupportDCD; - bool m_bCfgSupportDSR; - bool m_bCfgSupportDTR; 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; };