- Added TCP serial option on port 1977 (hard-coded - see TODOs) implemented as asynchronous Winsock 1.1 (Win95 ok?) sockets via WndProc() messages
- Fixed Winres.h dependency
This commit is contained in:
parent
06d9ea6327
commit
8db9ad6e9d
7 changed files with 248 additions and 38 deletions
|
@ -82,7 +82,7 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="htmlhelp.lib comctl32.lib ddraw.lib winmm.lib dsound.lib dxguid.lib version.lib strmiids.lib dinput8.lib user32.lib gdi32.lib Advapi32.lib shell32.lib Comdlg32.lib ole32.lib"
|
AdditionalDependencies="htmlhelp.lib comctl32.lib ddraw.lib winmm.lib dsound.lib dxguid.lib version.lib strmiids.lib dinput8.lib user32.lib gdi32.lib Advapi32.lib shell32.lib Comdlg32.lib ole32.lib wsock32.lib"
|
||||||
OutputFile=".\Release/Applewin.exe"
|
OutputFile=".\Release/Applewin.exe"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="true"
|
SuppressStartupBanner="true"
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="htmlhelp.lib comctl32.lib ddraw.lib winmm.lib dsound.lib dxguid.lib version.lib strmiids.lib dinput8.lib user32.lib gdi32.lib Advapi32.lib shell32.lib Comdlg32.lib ole32.lib"
|
AdditionalDependencies="htmlhelp.lib comctl32.lib ddraw.lib winmm.lib dsound.lib dxguid.lib version.lib strmiids.lib dinput8.lib user32.lib gdi32.lib Advapi32.lib shell32.lib Comdlg32.lib ole32.lib wsock32.lib"
|
||||||
OutputFile=".\Debug/Applewin.exe"
|
OutputFile=".\Debug/Applewin.exe"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="true"
|
SuppressStartupBanner="true"
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
//
|
//
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
//
|
//
|
||||||
#include "winres.h"
|
#include "winresrc.h"
|
||||||
|
#define IDC_STATIC (-1)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
|
@ -109,7 +109,7 @@ enum AppMode_e
|
||||||
#define WM_USER_LOADSTATE WM_USER+4
|
#define WM_USER_LOADSTATE WM_USER+4
|
||||||
#define VK_SNAPSHOT_560 WM_USER+5
|
#define VK_SNAPSHOT_560 WM_USER+5
|
||||||
#define VK_SNAPSHOT_280 WM_USER+6
|
#define VK_SNAPSHOT_280 WM_USER+6
|
||||||
|
#define WM_USER_TCP_SERIAL WM_USER+7
|
||||||
|
|
||||||
enum eSOUNDCARDTYPE {SC_UNINIT=0, SC_NONE, SC_MOCKINGBOARD, SC_PHASOR}; // Apple soundcard type
|
enum eSOUNDCARDTYPE {SC_UNINIT=0, SC_NONE, SC_MOCKINGBOARD, SC_PHASOR}; // Apple soundcard type
|
||||||
|
|
||||||
|
|
|
@ -1199,6 +1199,49 @@ LRESULT CALLBACK FrameWndProc (
|
||||||
case WM_USER_LOADSTATE: // Load state
|
case WM_USER_LOADSTATE: // Load state
|
||||||
Snapshot_LoadState();
|
Snapshot_LoadState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_USER_TCP_SERIAL: // TCP serial events
|
||||||
|
WORD error = WSAGETSELECTERROR(lparam);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
LogOutput("TCP Serial Winsock error 0x%X (%d)\r", error, error);
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case WSAENETRESET:
|
||||||
|
case WSAECONNABORTED:
|
||||||
|
case WSAECONNRESET:
|
||||||
|
case WSAENOTCONN:
|
||||||
|
case WSAETIMEDOUT:
|
||||||
|
sg_SSC.CommTcpSerialClose();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sg_SSC.CommTcpSerialCleanup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WORD wSelectEvent = WSAGETSELECTEVENT(lparam);
|
||||||
|
switch(wSelectEvent)
|
||||||
|
{
|
||||||
|
case FD_ACCEPT:
|
||||||
|
sg_SSC.CommTcpSerialAccept();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FD_CLOSE:
|
||||||
|
sg_SSC.CommTcpSerialClose();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FD_READ:
|
||||||
|
sg_SSC.CommTcpSerialReceive();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FD_WRITE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return DefWindowProc(window,message,wparam,lparam);
|
return DefWindowProc(window,message,wparam,lparam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ TCHAR serialchoices[] = TEXT("None\0")
|
||||||
TEXT("COM1\0")
|
TEXT("COM1\0")
|
||||||
TEXT("COM2\0")
|
TEXT("COM2\0")
|
||||||
TEXT("COM3\0")
|
TEXT("COM3\0")
|
||||||
TEXT("COM4\0");
|
TEXT("COM4\0")
|
||||||
|
TEXT("TCP\0");
|
||||||
|
|
||||||
TCHAR soundchoices[] = TEXT("Disabled\0")
|
TCHAR soundchoices[] = TEXT("Disabled\0")
|
||||||
TEXT("PC Speaker (direct)\0")
|
TEXT("PC Speaker (direct)\0")
|
||||||
|
|
|
@ -43,6 +43,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
//#define SUPPORT_MODEM
|
//#define SUPPORT_MODEM
|
||||||
|
#define TCP_SERIAL_OPTION 5
|
||||||
|
#define TCP_SERIAL_PORT 1977
|
||||||
|
|
||||||
// Default: 19200-8-N-1
|
// Default: 19200-8-N-1
|
||||||
// Maybe a better default is: 9600-7-N-1 (for HyperTrm)
|
// Maybe a better default is: 9600-7-N-1 (for HyperTrm)
|
||||||
|
@ -71,6 +73,8 @@ CSuperSerialCard::CSuperSerialCard()
|
||||||
m_vRecvBytes = 0;
|
m_vRecvBytes = 0;
|
||||||
|
|
||||||
m_hCommHandle = INVALID_HANDLE_VALUE;
|
m_hCommHandle = INVALID_HANDLE_VALUE;
|
||||||
|
m_hCommListenSocket = INVALID_SOCKET;
|
||||||
|
m_hCommAcceptSocket = INVALID_SOCKET;
|
||||||
m_dwCommInactivity = 0;
|
m_dwCommInactivity = 0;
|
||||||
|
|
||||||
m_bTxIrqEnabled = false;
|
m_bTxIrqEnabled = false;
|
||||||
|
@ -92,6 +96,7 @@ CSuperSerialCard::CSuperSerialCard()
|
||||||
// TODO: Serial Comms - UI Property Sheet Page:
|
// TODO: Serial Comms - UI Property Sheet Page:
|
||||||
// . Ability to config the 2x DIPSWs - only takes affect after next Apple2 reset
|
// . Ability to config the 2x DIPSWs - only takes affect after next Apple2 reset
|
||||||
// . 'Default' button that resets DIPSWs to DIPSWDefaults
|
// . 'Default' button that resets DIPSWs to DIPSWDefaults
|
||||||
|
// . Need to respect IRQ disable dipswitch (cannot be overridden by software)
|
||||||
|
|
||||||
void CSuperSerialCard::GetDIPSW()
|
void CSuperSerialCard::GetDIPSW()
|
||||||
{
|
{
|
||||||
|
@ -189,41 +194,100 @@ BOOL CSuperSerialCard::CheckComm()
|
||||||
{
|
{
|
||||||
m_dwCommInactivity = 0;
|
m_dwCommInactivity = 0;
|
||||||
|
|
||||||
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && m_dwSerialPort)
|
// check for COM or TCP socket handle, and setup if invalid
|
||||||
|
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET))
|
||||||
{
|
{
|
||||||
TCHAR portname[8];
|
if (m_dwSerialPort == TCP_SERIAL_OPTION)
|
||||||
wsprintf(portname, TEXT("COM%u"), m_dwSerialPort);
|
|
||||||
|
|
||||||
m_hCommHandle = CreateFile(portname,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
0, // exclusive access
|
|
||||||
(LPSECURITY_ATTRIBUTES)NULL, // default security attributes
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_OVERLAPPED, // required for WaitCommEvent()
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
UpdateCommState();
|
// init Winsock 1.1 (for Win95, otherwise could use 2.2)
|
||||||
COMMTIMEOUTS ct;
|
WSADATA wsaData;
|
||||||
ZeroMemory(&ct,sizeof(COMMTIMEOUTS));
|
if (WSAStartup(MAKEWORD(1, 1), &wsaData) == 0) // or (2, 2) for Winsock 2.2
|
||||||
ct.ReadIntervalTimeout = MAXDWORD;
|
{
|
||||||
SetCommTimeouts(m_hCommHandle,&ct);
|
if (wsaData.wVersion != 0x0101) // or 0x0202 for Winsock 2.2
|
||||||
CommThInit();
|
{
|
||||||
|
WSACleanup();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialized, so try to create a socket
|
||||||
|
m_hCommListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (m_hCommListenSocket == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// have socket so attempt to bind it
|
||||||
|
SOCKADDR_IN saAddress;
|
||||||
|
saAddress.sin_family = AF_INET;
|
||||||
|
saAddress.sin_port = htons(TCP_SERIAL_PORT); // TODO: get from registry / GUI
|
||||||
|
saAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
if (bind(m_hCommListenSocket, (LPSOCKADDR)&saAddress, sizeof(saAddress)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
m_hCommListenSocket = INVALID_SOCKET;
|
||||||
|
WSACleanup();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bound, so listen
|
||||||
|
if (listen(m_hCommListenSocket, 1) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
m_hCommListenSocket = INVALID_SOCKET;
|
||||||
|
WSACleanup();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now send async events to our app's message handler
|
||||||
|
if (WSAAsyncSelect(
|
||||||
|
/* SOCKET s */ m_hCommListenSocket,
|
||||||
|
/* HWND hWnd */ g_hFrameWindow,
|
||||||
|
/* unsigned int wMsg */ WM_USER_TCP_SERIAL,
|
||||||
|
/* long lEvent */ (FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE)) != 0)
|
||||||
|
{
|
||||||
|
m_hCommListenSocket = INVALID_SOCKET;
|
||||||
|
WSACleanup();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD uError = GetLastError();
|
TCHAR portname[8];
|
||||||
|
wsprintf(portname, TEXT("COM%u"), m_dwSerialPort);
|
||||||
|
|
||||||
|
m_hCommHandle = CreateFile(portname,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
0, // exclusive access
|
||||||
|
(LPSECURITY_ATTRIBUTES)NULL, // default security attributes
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OVERLAPPED, // required for WaitCommEvent()
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
UpdateCommState();
|
||||||
|
COMMTIMEOUTS ct;
|
||||||
|
ZeroMemory(&ct,sizeof(COMMTIMEOUTS));
|
||||||
|
ct.ReadIntervalTimeout = MAXDWORD;
|
||||||
|
SetCommTimeouts(m_hCommHandle,&ct);
|
||||||
|
CommThInit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD uError = GetLastError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (m_hCommHandle != INVALID_HANDLE_VALUE);
|
return ((m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void CSuperSerialCard::CloseComm()
|
void CSuperSerialCard::CloseComm()
|
||||||
{
|
{
|
||||||
|
CommTcpSerialCleanup(); // Shut down Winsock
|
||||||
|
|
||||||
CommThUninit(); // Kill CommThread before closing COM handle
|
CommThUninit(); // Kill CommThread before closing COM handle
|
||||||
|
|
||||||
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
||||||
|
@ -235,6 +299,74 @@ void CSuperSerialCard::CloseComm()
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
void CSuperSerialCard::CommTcpSerialCleanup()
|
||||||
|
{
|
||||||
|
if (m_hCommListenSocket != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
WSAAsyncSelect(m_hCommListenSocket, g_hFrameWindow, 0, 0); // Stop event messages
|
||||||
|
closesocket(m_hCommListenSocket);
|
||||||
|
m_hCommListenSocket = INVALID_SOCKET;
|
||||||
|
|
||||||
|
CommTcpSerialClose();
|
||||||
|
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void CSuperSerialCard::CommTcpSerialClose()
|
||||||
|
{
|
||||||
|
if (m_hCommAcceptSocket != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
shutdown(m_hCommAcceptSocket, 2 /* SD_BOTH */); // In case the client is waiting for data
|
||||||
|
closesocket(m_hCommAcceptSocket);
|
||||||
|
m_hCommAcceptSocket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
while (!m_TcpSerialBuffer.empty())
|
||||||
|
{
|
||||||
|
m_TcpSerialBuffer.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void CSuperSerialCard::CommTcpSerialAccept()
|
||||||
|
{
|
||||||
|
// Valid listener socket and invalid accept socket?
|
||||||
|
if ((m_hCommListenSocket != INVALID_SOCKET) && (m_hCommAcceptSocket == INVALID_SOCKET))
|
||||||
|
{
|
||||||
|
// Y: accept the connection
|
||||||
|
m_hCommAcceptSocket = accept(m_hCommListenSocket, NULL, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void CSuperSerialCard::CommTcpSerialReceive()
|
||||||
|
{
|
||||||
|
if (m_hCommAcceptSocket != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
char data[0x80];
|
||||||
|
int received = 0;
|
||||||
|
while ((received = recv(m_hCommAcceptSocket, data, sizeof(data), 0)) > 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)
|
BYTE __stdcall CSuperSerialCard::SSC_IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
|
UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
|
||||||
|
@ -342,7 +474,7 @@ BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value,
|
||||||
break;
|
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);
|
m_bRxIrqEnabled = ((m_uCommandByte & 0x02) == 0);
|
||||||
|
|
||||||
if (m_uCommandByte & 0x01) // Data Terminal Ready (DTR) setting [0=set DTR high (indicates 'not ready')]
|
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;
|
return 0;
|
||||||
|
|
||||||
BYTE result = 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
|
// 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())
|
if (!CheckComm())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DWORD uBytesWritten;
|
if (m_hCommAcceptSocket != INVALID_SOCKET)
|
||||||
WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o);
|
{
|
||||||
|
BYTE data = value;
|
||||||
m_bWrittenTx = true; // Transmit done
|
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:
|
// TO DO:
|
||||||
// 1) Use CommThread determine when transmit is complete
|
// 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):
|
// So that /m_vRecvBytes/ doesn't change midway (from 0 to 1):
|
||||||
// . bIRQ=false, but uStatus.ST_RX_FULL=1
|
// . bIRQ=false, but uStatus.ST_RX_FULL=1
|
||||||
EnterCriticalSection(&m_CriticalSection);
|
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&m_CriticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
bool bIRQ = false;
|
bool bIRQ = false;
|
||||||
if (m_bTxIrqEnabled && m_bWrittenTx)
|
if (m_bTxIrqEnabled && m_bWrittenTx)
|
||||||
{
|
{
|
||||||
bIRQ = true;
|
bIRQ = true;
|
||||||
}
|
}
|
||||||
if (m_bRxIrqEnabled && m_vRecvBytes)
|
if (m_bRxIrqEnabled && (m_vRecvBytes || !m_TcpSerialBuffer.empty()))
|
||||||
{
|
{
|
||||||
bIRQ = true;
|
bIRQ = true;
|
||||||
}
|
}
|
||||||
|
@ -537,14 +690,17 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
//
|
//
|
||||||
|
|
||||||
BYTE uStatus = ST_TX_EMPTY
|
BYTE uStatus = ST_TX_EMPTY
|
||||||
| (m_vRecvBytes ? ST_RX_FULL : 0x00)
|
| ((m_vRecvBytes || !m_TcpSerialBuffer.empty()) ? ST_RX_FULL : 0x00)
|
||||||
#ifdef SUPPORT_MODEM
|
#ifdef SUPPORT_MODEM
|
||||||
| ((modemstatus & MS_RLSD_ON) ? 0x00 : ST_DCD) // Need 0x00 to allow ZLink to start up
|
| ((modemstatus & MS_RLSD_ON) ? 0x00 : ST_DCD) // Need 0x00 to allow ZLink to start up
|
||||||
| ((modemstatus & MS_DSR_ON) ? 0x00 : ST_DSR)
|
| ((modemstatus & MS_DSR_ON) ? 0x00 : ST_DSR)
|
||||||
#endif
|
#endif
|
||||||
| (bIRQ ? ST_IRQ : 0x00);
|
| (bIRQ ? ST_IRQ : 0x00);
|
||||||
|
|
||||||
LeaveCriticalSection(&m_CriticalSection);
|
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(&m_CriticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
CpuIrqDeassert(IS_SSC);
|
CpuIrqDeassert(IS_SSC);
|
||||||
|
|
||||||
|
@ -670,7 +826,7 @@ void CSuperSerialCard::CommDestroy()
|
||||||
|
|
||||||
void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport)
|
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;
|
m_dwSerialPort = newserialport;
|
||||||
}
|
}
|
||||||
|
@ -688,7 +844,7 @@ void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport)
|
||||||
|
|
||||||
void CSuperSerialCard::CommUpdate(DWORD totalcycles)
|
void CSuperSerialCard::CommUpdate(DWORD totalcycles)
|
||||||
{
|
{
|
||||||
if (m_hCommHandle == INVALID_HANDLE_VALUE)
|
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((m_dwCommInactivity += totalcycles) > 1000000)
|
if ((m_dwCommInactivity += totalcycles) > 1000000)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
extern class CSuperSerialCard sg_SSC;
|
extern class CSuperSerialCard sg_SSC;
|
||||||
|
|
||||||
|
@ -36,6 +37,11 @@ public:
|
||||||
DWORD GetSerialPort() { return m_dwSerialPort; }
|
DWORD GetSerialPort() { return m_dwSerialPort; }
|
||||||
void SetSerialPort(DWORD dwSerialPort) { m_dwSerialPort = 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_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);
|
static BYTE __stdcall SSC_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
||||||
|
|
||||||
|
@ -82,12 +88,15 @@ private:
|
||||||
//
|
//
|
||||||
|
|
||||||
HANDLE m_hCommHandle;
|
HANDLE m_hCommHandle;
|
||||||
|
SOCKET m_hCommListenSocket;
|
||||||
|
SOCKET m_hCommAcceptSocket;
|
||||||
DWORD m_dwCommInactivity;
|
DWORD m_dwCommInactivity;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/
|
CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/
|
||||||
BYTE m_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used
|
BYTE m_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used
|
||||||
|
queue<BYTE> m_TcpSerialBuffer;
|
||||||
volatile DWORD m_vRecvBytes;
|
volatile DWORD m_vRecvBytes;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Reference in a new issue