diff --git a/AppleWin/ApplewinExpress9.00.vcproj b/AppleWin/ApplewinExpress9.00.vcproj index 1af2436c..edb5109b 100644 --- a/AppleWin/ApplewinExpress9.00.vcproj +++ b/AppleWin/ApplewinExpress9.00.vcproj @@ -82,7 +82,7 @@ /> 0) + { + for (int i = 0; i < received; i++) + { + m_TcpSerialBuffer.push(data[i]); + } + } + + if (m_bRxIrqEnabled && !m_TcpSerialBuffer.empty()) + { + m_vbCommIRQ = true; + CpuIrqAssert(IS_SSC); + } + } +} + +//=========================================================================== + BYTE __stdcall CSuperSerialCard::SSC_IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft) { UINT uSlot = ((uAddr & 0xff) >> 4) - 8; @@ -342,7 +474,7 @@ BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value, break; } - // interrupt request disable [0=enable receiver interrupts] + // interrupt request disable [0=enable receiver interrupts] - NOTE: SSC docs get this wrong! m_bRxIrqEnabled = ((m_uCommandByte & 0x02) == 0); if (m_uCommandByte & 0x01) // Data Terminal Ready (DTR) setting [0=set DTR high (indicates 'not ready')] @@ -438,7 +570,13 @@ BYTE __stdcall CSuperSerialCard::CommReceive(WORD, WORD, BYTE, BYTE, ULONG) return 0; BYTE result = 0; - if (m_vRecvBytes) + + if (!m_TcpSerialBuffer.empty()) + { + result = m_TcpSerialBuffer.front(); + m_TcpSerialBuffer.pop(); + } + else if (m_vRecvBytes) { // Don't need critical section in here as CommThread is waiting for ACK @@ -463,10 +601,22 @@ BYTE __stdcall CSuperSerialCard::CommTransmit(WORD, WORD, BYTE, BYTE value, ULON if (!CheckComm()) return 0; - DWORD uBytesWritten; - WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o); - - m_bWrittenTx = true; // Transmit done + if (m_hCommAcceptSocket != INVALID_SOCKET) + { + BYTE data = value; + if (m_uByteSize < 8) + { + data &= ~(1 << m_uByteSize); + } + send(m_hCommAcceptSocket, (const char*)&data, 1, 0); + m_bWrittenTx = true; // Transmit done + } + else if (m_hCommHandle != INVALID_HANDLE_VALUE) + { + DWORD uBytesWritten; + WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o); + m_bWrittenTx = true; // Transmit done + } // TO DO: // 1) Use CommThread determine when transmit is complete @@ -520,14 +670,17 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG) // So that /m_vRecvBytes/ doesn't change midway (from 0 to 1): // . bIRQ=false, but uStatus.ST_RX_FULL=1 - EnterCriticalSection(&m_CriticalSection); + if (m_hCommHandle != INVALID_HANDLE_VALUE) + { + EnterCriticalSection(&m_CriticalSection); + } bool bIRQ = false; if (m_bTxIrqEnabled && m_bWrittenTx) { bIRQ = true; } - if (m_bRxIrqEnabled && m_vRecvBytes) + if (m_bRxIrqEnabled && (m_vRecvBytes || !m_TcpSerialBuffer.empty())) { bIRQ = true; } @@ -537,14 +690,17 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG) // BYTE uStatus = ST_TX_EMPTY - | (m_vRecvBytes ? ST_RX_FULL : 0x00) + | ((m_vRecvBytes || !m_TcpSerialBuffer.empty()) ? ST_RX_FULL : 0x00) #ifdef SUPPORT_MODEM | ((modemstatus & MS_RLSD_ON) ? 0x00 : ST_DCD) // Need 0x00 to allow ZLink to start up | ((modemstatus & MS_DSR_ON) ? 0x00 : ST_DSR) #endif | (bIRQ ? ST_IRQ : 0x00); - LeaveCriticalSection(&m_CriticalSection); + if (m_hCommHandle != INVALID_HANDLE_VALUE) + { + LeaveCriticalSection(&m_CriticalSection); + } CpuIrqDeassert(IS_SSC); @@ -670,7 +826,7 @@ void CSuperSerialCard::CommDestroy() void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport) { - if (m_hCommHandle == INVALID_HANDLE_VALUE) + if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET)) { m_dwSerialPort = newserialport; } @@ -688,7 +844,7 @@ void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport) void CSuperSerialCard::CommUpdate(DWORD totalcycles) { - if (m_hCommHandle == INVALID_HANDLE_VALUE) + if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET)) return; if ((m_dwCommInactivity += totalcycles) > 1000000) diff --git a/AppleWin/source/SerialComms.h b/AppleWin/source/SerialComms.h index 9b6df460..9fc8e848 100644 --- a/AppleWin/source/SerialComms.h +++ b/AppleWin/source/SerialComms.h @@ -1,4 +1,5 @@ #pragma once +#include extern class CSuperSerialCard sg_SSC; @@ -36,6 +37,11 @@ public: DWORD GetSerialPort() { return m_dwSerialPort; } void SetSerialPort(DWORD dwSerialPort) { m_dwSerialPort = dwSerialPort; } + void CommTcpSerialAccept(); + void CommTcpSerialReceive(); + void CommTcpSerialClose(); + void CommTcpSerialCleanup(); + static BYTE __stdcall SSC_IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft); static BYTE __stdcall SSC_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft); @@ -82,12 +88,15 @@ private: // HANDLE m_hCommHandle; + SOCKET m_hCommListenSocket; + SOCKET m_hCommAcceptSocket; DWORD m_dwCommInactivity; // CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/ BYTE m_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used + queue m_TcpSerialBuffer; volatile DWORD m_vRecvBytes; //