Merge from AppleWin-Tom @ 565-614 (Excluded HEAD=615, due to Tree Conflict errors)
Fix for SSC (big transfers): use queue instead of single byte buffer New switches: -log, -no-mb, -spkr-max, -spkr-inc Fix for Speaker underflow problem (max=200, inc=20) SSC: Support 112.5K Baud Dynamic 'Serial Port' drop-down menu Save "Serial Port Name" to Registry (instead of drop-down menu index as "Serial Port")
This commit is contained in:
parent
ec0afb8359
commit
a769bdf256
13 changed files with 561 additions and 272 deletions
|
@ -245,8 +245,8 @@ DISK_ICON ICON "DISK.ICO"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,16,1,0
|
||||
PRODUCTVERSION 1,16,1,0
|
||||
FILEVERSION 1,16,1,3
|
||||
PRODUCTVERSION 1,16,1,3
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -264,12 +264,12 @@ BEGIN
|
|||
VALUE "Comments", "http://applewin.berlios.de"
|
||||
VALUE "CompanyName", "AppleWin"
|
||||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||
VALUE "FileVersion", "1, 16, 1, 0"
|
||||
VALUE "FileVersion", "1, 16, 1, 3"
|
||||
VALUE "InternalName", "APPLEWIN"
|
||||
VALUE "LegalCopyright", " 1994-2009 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||
VALUE "ProductName", "Apple //e Emulator"
|
||||
VALUE "ProductVersion", "1, 16, 1, 0"
|
||||
VALUE "ProductVersion", "1, 16, 1, 3"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -71,6 +71,7 @@ DWORD g_dwCyclesThisFrame = 0;
|
|||
|
||||
FILE* g_fh = NULL;
|
||||
bool g_bDisableDirectSound = false;
|
||||
bool g_bDisableDirectSoundMockingboard = false;
|
||||
|
||||
CSuperSerialCard sg_SSC;
|
||||
CMouseInterface sg_Mouse;
|
||||
|
@ -464,16 +465,22 @@ void LoadConfiguration ()
|
|||
REGLOAD(TEXT("Joystick 1 Emulation"),&joytype[1]);
|
||||
REGLOAD(TEXT("Sound Emulation") ,&soundtype);
|
||||
|
||||
DWORD dwSerialPort;
|
||||
if (REGLOAD(TEXT("Serial Port"),&dwSerialPort))
|
||||
sg_SSC.SetSerialPort(dwSerialPort);
|
||||
char aySerialPortName[ CSuperSerialCard::SIZEOF_SERIALCHOICE_ITEM ];
|
||||
if (RegLoadString( TEXT("Configuration"),
|
||||
TEXT(REGVALUE_SERIAL_PORT_NAME),
|
||||
TRUE,
|
||||
aySerialPortName,
|
||||
sizeof(aySerialPortName) ) )
|
||||
{
|
||||
sg_SSC.SetSerialPortName(aySerialPortName);
|
||||
}
|
||||
|
||||
REGLOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
|
||||
REGLOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);
|
||||
REGLOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
|
||||
REGLOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);
|
||||
|
||||
Config_Load_Video();
|
||||
Config_Load_Video();
|
||||
|
||||
REGLOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled);
|
||||
REGLOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled);
|
||||
|
||||
SetCurrentCLK6502();
|
||||
|
||||
|
@ -760,8 +767,7 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
{
|
||||
g_bRegisterFileTypes = false;
|
||||
}
|
||||
else
|
||||
if(strcmp(lpCmdLine, "-d1") == 0)
|
||||
else if(strcmp(lpCmdLine, "-d1") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
|
@ -777,7 +783,7 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
{
|
||||
bSetFullScreen = true;
|
||||
}
|
||||
else if((strcmp(lpCmdLine, "-l") == 0) && (g_fh == NULL))
|
||||
else if(((strcmp(lpCmdLine, "-l") == 0) || (strcmp(lpCmdLine, "-log") == 0)) && (g_fh == NULL))
|
||||
{
|
||||
g_fh = fopen("AppleWin.log", "a+t"); // Open log file (append & text g_nAppMode)
|
||||
CHAR aDateStr[80], aTimeStr[80];
|
||||
|
@ -789,6 +795,10 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
{
|
||||
g_bDisableDirectSound = true;
|
||||
}
|
||||
else if(strcmp(lpCmdLine, "-no-mb") == 0)
|
||||
{
|
||||
g_bDisableDirectSoundMockingboard = true;
|
||||
}
|
||||
#ifdef RAMWORKS
|
||||
else if(strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..127]
|
||||
{
|
||||
|
@ -813,6 +823,20 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
{
|
||||
g_bDisplayPrintScreenFileName = true;
|
||||
}
|
||||
else if(strcmp(lpCmdLine, "-spkr-inc") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
const int nErrorInc = atoi(lpCmdLine);
|
||||
SoundCore_SetErrorInc( nErrorInc );
|
||||
}
|
||||
else if(strcmp(lpCmdLine, "-spkr-max") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
const int nErrorMax = atoi(lpCmdLine);
|
||||
SoundCore_SetErrorMax( nErrorMax );
|
||||
}
|
||||
else if(strcmp(lpCmdLine, "-use-real-printer") == 0) // Enable control in Advanced config to allow dumping to a real printer
|
||||
{
|
||||
g_bEnableDumpToRealPrinter = true;
|
||||
|
|
|
@ -40,7 +40,8 @@ extern int g_nCpuCyclesFeedback;
|
|||
extern DWORD g_dwCyclesThisFrame;
|
||||
|
||||
extern FILE* g_fh; // Filehandle for log file
|
||||
extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB support)
|
||||
extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB/Speaker support)
|
||||
extern bool g_bDisableDirectSoundMockingboard; // Cmd line switch: don't init MB support
|
||||
|
||||
// TODO: Make g_CurrentPeripherals[MAX_SLOTS] = { CT_Empty }
|
||||
extern UINT g_Slot4; // Mockingboard or Mouse in slot4
|
||||
|
|
|
@ -99,6 +99,7 @@ enum AppMode_e
|
|||
#define REGVALUE_VIDEO_MODE "Video Emulation"
|
||||
#define REGVALUE_VIDEO_HALF_SCAN_LINES "Half Scan Lines"
|
||||
#define REGVALUE_VIDEO_MONO_COLOR "Monochrome Color"
|
||||
#define REGVALUE_SERIAL_PORT_NAME "Serial Port Name"
|
||||
|
||||
// Preferences
|
||||
#define REG_PREFS "Preferences"
|
||||
|
|
|
@ -177,7 +177,7 @@ static BYTE g_nPhasorMode = 0; // 0=Mockingboard emulation, 1=Phasor native
|
|||
|
||||
static const unsigned short g_nMB_NumChannels = 2;
|
||||
|
||||
static const DWORD g_dwDSBufferSize = 16 * 1024 * sizeof(short) * g_nMB_NumChannels;
|
||||
static const DWORD g_dwDSBufferSize = MAX_SAMPLES * sizeof(short) * g_nMB_NumChannels;
|
||||
|
||||
static const SHORT nWaveDataMin = (SHORT)0x8000;
|
||||
static const SHORT nWaveDataMax = (SHORT)0x7FFF;
|
||||
|
@ -733,6 +733,8 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
|
|||
|
||||
static void MB_Update()
|
||||
{
|
||||
char szDbg[200];
|
||||
|
||||
if (!MockingboardVoice.bActive)
|
||||
return;
|
||||
|
||||
|
@ -816,13 +818,27 @@ static void MB_Update()
|
|||
{
|
||||
// |-----PxxxxxW-----|
|
||||
if((dwByteOffset > dwCurrentPlayCursor) && (dwByteOffset < dwCurrentWriteCursor))
|
||||
{
|
||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X xxx\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||
OutputDebugString(szDbg);
|
||||
if (g_fh) fprintf(g_fh, szDbg);
|
||||
|
||||
dwByteOffset = dwCurrentWriteCursor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// |xxW----------Pxxx|
|
||||
if((dwByteOffset > dwCurrentPlayCursor) || (dwByteOffset < dwCurrentWriteCursor))
|
||||
{
|
||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||
OutputDebugString(szDbg);
|
||||
if (g_fh) fprintf(g_fh, szDbg);
|
||||
|
||||
dwByteOffset = dwCurrentWriteCursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,10 +847,11 @@ static void MB_Update()
|
|||
nBytesRemaining += g_dwDSBufferSize;
|
||||
|
||||
// Calc correction factor so that play-buffer doesn't under/overflow
|
||||
const int nErrorInc = SoundCore_GetErrorInc();
|
||||
if(nBytesRemaining < g_dwDSBufferSize / 4)
|
||||
nNumSamplesError++; // < 0.25 of buffer remaining
|
||||
nNumSamplesError += nErrorInc; // < 0.25 of buffer remaining
|
||||
else if(nBytesRemaining > g_dwDSBufferSize / 2)
|
||||
nNumSamplesError--; // > 0.50 of buffer remaining
|
||||
nNumSamplesError -= nErrorInc; // > 0.50 of buffer remaining
|
||||
else
|
||||
nNumSamplesError = 0; // Acceptable amount of data in buffer
|
||||
|
||||
|
@ -1292,7 +1309,7 @@ static void MB_DSUninit()
|
|||
|
||||
void MB_Initialize()
|
||||
{
|
||||
if(g_bDisableDirectSound)
|
||||
if (g_bDisableDirectSound || g_bDisableDirectSoundMockingboard)
|
||||
{
|
||||
MockingboardVoice.bMute = true;
|
||||
g_SoundcardType = SC_NONE;
|
||||
|
@ -1312,7 +1329,6 @@ void MB_Initialize()
|
|||
|
||||
//
|
||||
|
||||
//DSInit();
|
||||
g_bMBAvailable = MB_DSInit();
|
||||
|
||||
MB_Reset();
|
||||
|
@ -1334,7 +1350,6 @@ void MB_Reinitialize()
|
|||
void MB_Destroy()
|
||||
{
|
||||
MB_DSUninit();
|
||||
//DSUninit();
|
||||
|
||||
for(int i=0; i<NUM_VOICES; i++)
|
||||
delete [] ppAYVoiceBuffer[i];
|
||||
|
|
|
@ -72,13 +72,6 @@ TCHAR* pszJoy1Choices[J1C_MAX] = { szJoyChoice0,
|
|||
int g_nJoy1ChoiceTranlationTbl[J1C_MAX];
|
||||
TCHAR joystick1choices[J1C_MAX*g_nMaxJoyChoiceLen];
|
||||
|
||||
TCHAR serialchoices[] = TEXT("None\0")
|
||||
TEXT("COM1\0")
|
||||
TEXT("COM2\0")
|
||||
TEXT("COM3\0")
|
||||
TEXT("COM4\0")
|
||||
TEXT("TCP\0");
|
||||
|
||||
TCHAR soundchoices[] = TEXT("Disabled\0")
|
||||
TEXT("PC Speaker (direct)\0")
|
||||
TEXT("PC Speaker (translated)\0")
|
||||
|
@ -345,7 +338,11 @@ static void ConfigDlg_OK(HWND window, UINT afterclose)
|
|||
else
|
||||
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE),NewApple2Type );
|
||||
|
||||
REGSAVE(TEXT("Serial Port") ,sg_SSC.GetSerialPort());
|
||||
RegSaveString( TEXT("Configuration"),
|
||||
TEXT(REGVALUE_SERIAL_PORT_NAME),
|
||||
TRUE,
|
||||
sg_SSC.GetSerialPortName() );
|
||||
|
||||
REGSAVE(TEXT("Custom Speed") ,IsDlgButtonChecked(window,IDC_CUSTOM_SPEED));
|
||||
REGSAVE(TEXT("Emulation Speed") ,g_dwSpeed);
|
||||
|
||||
|
@ -479,8 +476,10 @@ static BOOL CALLBACK ConfigDlgProc (HWND window,
|
|||
|
||||
FillComboBox(window,IDC_VIDEOTYPE,videochoices,g_eVideoType);
|
||||
CheckDlgButton(window, IDC_CHECK_HALF_SCAN_LINES, g_uHalfScanLines ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
FillComboBox(window,IDC_SERIALPORT,serialchoices,sg_SSC.GetSerialPort());
|
||||
|
||||
FillComboBox(window,IDC_SERIALPORT, sg_SSC.GetSerialPortChoices(), sg_SSC.GetSerialPort());
|
||||
EnableWindow(GetDlgItem(window, IDC_SERIALPORT), !sg_SSC.IsActive() ? TRUE : FALSE);
|
||||
|
||||
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETRANGE,1,MAKELONG(0,40));
|
||||
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETPAGESIZE,0,5);
|
||||
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETTICFREQ,10,0);
|
||||
|
|
|
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
|||
Copyright (C) 1994-1996, Michael O'Brien
|
||||
Copyright (C) 1999-2001, Oliver Schmidt
|
||||
Copyright (C) 2002-2005, Tom Charlesworth
|
||||
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
||||
Copyright (C) 2006-2009, Tom Charlesworth, Michael Pohoreski, Nick Westgate
|
||||
|
||||
AppleWin is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -43,7 +43,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "..\resource\resource.h"
|
||||
|
||||
//#define SUPPORT_MODEM
|
||||
#define TCP_SERIAL_OPTION 5
|
||||
#define TCP_SERIAL_PORT 1977
|
||||
|
||||
// Default: 19200-8-N-1
|
||||
|
@ -64,31 +63,50 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault =
|
|||
|
||||
//===========================================================================
|
||||
|
||||
CSuperSerialCard::CSuperSerialCard()
|
||||
CSuperSerialCard::CSuperSerialCard() :
|
||||
m_aySerialPortChoices(NULL),
|
||||
m_uTCPChoiceItemIdx(0)
|
||||
{
|
||||
m_dwSerialPort = 0;
|
||||
|
||||
GetDIPSW();
|
||||
|
||||
m_vRecvBytes = 0;
|
||||
memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName));
|
||||
m_dwSerialPortItem = 0;
|
||||
|
||||
m_hCommHandle = INVALID_HANDLE_VALUE;
|
||||
m_hCommListenSocket = INVALID_SOCKET;
|
||||
m_hCommAcceptSocket = INVALID_SOCKET;
|
||||
m_dwCommInactivity = 0;
|
||||
|
||||
m_bTxIrqEnabled = false;
|
||||
m_bRxIrqEnabled = false;
|
||||
|
||||
m_bWrittenTx = false;
|
||||
|
||||
m_vbCommIRQ = false;
|
||||
m_hCommThread = NULL;
|
||||
|
||||
for (UINT i=0; i<COMMEVT_MAX; i++)
|
||||
m_hCommEvent[i] = NULL;
|
||||
|
||||
memset(&m_o, 0, sizeof(m_o));
|
||||
|
||||
InternalReset();
|
||||
}
|
||||
|
||||
void CSuperSerialCard::InternalReset()
|
||||
{
|
||||
GetDIPSW();
|
||||
|
||||
m_bTxIrqEnabled = false;
|
||||
m_bRxIrqEnabled = false;
|
||||
|
||||
m_bWrittenTx = false;
|
||||
|
||||
m_vuRxCurrBuffer = 0;
|
||||
|
||||
m_vbTxIrqPending = false;
|
||||
m_vbRxIrqPending = false;
|
||||
|
||||
m_qComSerialBuffer[0].c.clear();
|
||||
m_qComSerialBuffer[1].c.clear();
|
||||
m_qTcpSerialBuffer.c.clear();
|
||||
}
|
||||
|
||||
CSuperSerialCard::~CSuperSerialCard()
|
||||
{
|
||||
delete [] m_aySerialPortChoices;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -195,91 +213,101 @@ BOOL CSuperSerialCard::CheckComm()
|
|||
m_dwCommInactivity = 0;
|
||||
|
||||
// check for COM or TCP socket handle, and setup if invalid
|
||||
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET))
|
||||
if (IsActive())
|
||||
return true;
|
||||
|
||||
if (m_dwSerialPortItem == m_uTCPChoiceItemIdx)
|
||||
{
|
||||
if (m_dwSerialPort == TCP_SERIAL_OPTION)
|
||||
// init Winsock 1.1 (for Win95, otherwise could use 2.2)
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(1, 1), &wsaData) == 0) // or (2, 2) for Winsock 2.2
|
||||
{
|
||||
// init Winsock 1.1 (for Win95, otherwise could use 2.2)
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(1, 1), &wsaData) == 0) // or (2, 2) for Winsock 2.2
|
||||
if (wsaData.wVersion != 0x0101) // or 0x0202 for Winsock 2.2
|
||||
{
|
||||
if (wsaData.wVersion != 0x0101) // or 0x0202 for Winsock 2.2
|
||||
{
|
||||
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;
|
||||
}
|
||||
WSACleanup();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
// initialized, so try to create a socket
|
||||
m_hCommListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (m_hCommListenSocket == INVALID_SOCKET)
|
||||
{
|
||||
UpdateCommState();
|
||||
COMMTIMEOUTS ct;
|
||||
ZeroMemory(&ct,sizeof(COMMTIMEOUTS));
|
||||
ct.ReadIntervalTimeout = MAXDWORD;
|
||||
SetCommTimeouts(m_hCommHandle,&ct);
|
||||
CommThInit();
|
||||
WSACleanup();
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
|
||||
// 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)
|
||||
{
|
||||
DWORD uError = GetLastError();
|
||||
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
|
||||
{
|
||||
_ASSERT(m_dwSerialPortItem);
|
||||
_ASSERT(m_dwSerialPortItem < m_vecSerialPortsItems.size()-1); // size()-1 is TCP item
|
||||
TCHAR portname[SIZEOF_SERIALCHOICE_ITEM];
|
||||
wsprintf(portname, TEXT("COM%u"), m_vecSerialPortsItems[m_dwSerialPortItem]);
|
||||
|
||||
return ((m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET));
|
||||
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)
|
||||
{
|
||||
//BOOL bRes = SetupComm(m_hCommHandle, 8192, 8192);
|
||||
//_ASSERT(bRes);
|
||||
|
||||
UpdateCommState();
|
||||
|
||||
// ReadIntervalTimeout=MAXDWORD; ReadTotalTimeoutConstant=ReadTotalTimeoutMultiplier=0:
|
||||
// Read operation is to return immediately with the bytes that have already been received,
|
||||
// even if no bytes have been received.
|
||||
COMMTIMEOUTS ct;
|
||||
ZeroMemory(&ct,sizeof(COMMTIMEOUTS));
|
||||
ct.ReadIntervalTimeout = MAXDWORD;
|
||||
SetCommTimeouts(m_hCommHandle,&ct);
|
||||
|
||||
CommThInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD uError = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
return IsActive();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -323,9 +351,9 @@ void CSuperSerialCard::CommTcpSerialClose()
|
|||
closesocket(m_hCommAcceptSocket);
|
||||
m_hCommAcceptSocket = INVALID_SOCKET;
|
||||
}
|
||||
while (!m_TcpSerialBuffer.empty())
|
||||
while (!m_qTcpSerialBuffer.empty())
|
||||
{
|
||||
m_TcpSerialBuffer.pop();
|
||||
m_qTcpSerialBuffer.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,19 +375,18 @@ void CSuperSerialCard::CommTcpSerialReceive()
|
|||
{
|
||||
if (m_hCommAcceptSocket != INVALID_SOCKET)
|
||||
{
|
||||
char data[0x80];
|
||||
int received = 0;
|
||||
while ((received = recv(m_hCommAcceptSocket, data, sizeof(data), 0)) > 0)
|
||||
char Data[0x80];
|
||||
int nReceived = 0;
|
||||
while ((nReceived = recv(m_hCommAcceptSocket, Data, sizeof(Data), 0)) > 0)
|
||||
{
|
||||
for (int i = 0; i < received; i++)
|
||||
for (int i = 0; i < nReceived; i++)
|
||||
{
|
||||
m_TcpSerialBuffer.push(data[i]);
|
||||
m_qTcpSerialBuffer.push(Data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bRxIrqEnabled && !m_TcpSerialBuffer.empty())
|
||||
if (m_bRxIrqEnabled && !m_qTcpSerialBuffer.empty())
|
||||
{
|
||||
m_vbCommIRQ = true;
|
||||
CpuIrqAssert(IS_SSC);
|
||||
}
|
||||
}
|
||||
|
@ -509,22 +536,22 @@ BYTE __stdcall CSuperSerialCard::CommControl(WORD, WORD, BYTE write, BYTE value,
|
|||
// a decent buffer in the device being accessed. The faster Apples
|
||||
// have no difficulty with this speed, however.
|
||||
|
||||
case 0x00: // fall through [16x external clock]
|
||||
case 0x00: m_uBaudRate = CBR_115200; break; // Internal clk: undoc'd 115.2K (or 16x external clock)
|
||||
case 0x01: // fall through [50 bps]
|
||||
case 0x02: // fall through [75 bps]
|
||||
case 0x03: // fall through [109.92 bps]
|
||||
case 0x04: // fall through [134.58 bps]
|
||||
case 0x05: m_uBaudRate = CBR_110; break; // [150 bps]
|
||||
case 0x06: m_uBaudRate = CBR_300; break;
|
||||
case 0x07: m_uBaudRate = CBR_600; break;
|
||||
case 0x08: m_uBaudRate = CBR_1200; break;
|
||||
case 0x05: m_uBaudRate = CBR_110; break; // [150 bps]
|
||||
case 0x06: m_uBaudRate = CBR_300; break;
|
||||
case 0x07: m_uBaudRate = CBR_600; break;
|
||||
case 0x08: m_uBaudRate = CBR_1200; break;
|
||||
case 0x09: // fall through [1800 bps]
|
||||
case 0x0A: m_uBaudRate = CBR_2400; break;
|
||||
case 0x0A: m_uBaudRate = CBR_2400; break;
|
||||
case 0x0B: // fall through [3600 bps]
|
||||
case 0x0C: m_uBaudRate = CBR_4800; break;
|
||||
case 0x0C: m_uBaudRate = CBR_4800; break;
|
||||
case 0x0D: // fall through [7200 bps]
|
||||
case 0x0E: m_uBaudRate = CBR_9600; break;
|
||||
case 0x0F: m_uBaudRate = CBR_19200; break;
|
||||
case 0x0E: m_uBaudRate = CBR_9600; break;
|
||||
case 0x0F: m_uBaudRate = CBR_19200; break;
|
||||
}
|
||||
|
||||
if (m_uControlByte & 0x10)
|
||||
|
@ -535,10 +562,10 @@ BYTE __stdcall CSuperSerialCard::CommControl(WORD, WORD, BYTE write, BYTE value,
|
|||
// UPDATE THE BYTE SIZE
|
||||
switch (m_uControlByte & 0x60)
|
||||
{
|
||||
case 0x00: m_uByteSize = 8; break;
|
||||
case 0x20: m_uByteSize = 7; break;
|
||||
case 0x40: m_uByteSize = 6; break;
|
||||
case 0x60: m_uByteSize = 5; break;
|
||||
case 0x00: m_uByteSize = 8; break;
|
||||
case 0x20: m_uByteSize = 7; break;
|
||||
case 0x40: m_uByteSize = 6; break;
|
||||
case 0x60: m_uByteSize = 5; break;
|
||||
}
|
||||
|
||||
// UPDATE THE NUMBER OF STOP BITS
|
||||
|
@ -564,6 +591,8 @@ BYTE __stdcall CSuperSerialCard::CommControl(WORD, WORD, BYTE write, BYTE value,
|
|||
|
||||
//===========================================================================
|
||||
|
||||
static UINT g_uDbgTotalSSCRx = 0;
|
||||
|
||||
BYTE __stdcall CSuperSerialCard::CommReceive(WORD, WORD, BYTE, BYTE, ULONG)
|
||||
{
|
||||
if (!CheckComm())
|
||||
|
@ -571,24 +600,40 @@ BYTE __stdcall CSuperSerialCard::CommReceive(WORD, WORD, BYTE, BYTE, ULONG)
|
|||
|
||||
BYTE result = 0;
|
||||
|
||||
if (!m_TcpSerialBuffer.empty())
|
||||
if (!m_qTcpSerialBuffer.empty())
|
||||
{
|
||||
result = m_TcpSerialBuffer.front();
|
||||
m_TcpSerialBuffer.pop();
|
||||
result = m_qTcpSerialBuffer.front();
|
||||
m_qTcpSerialBuffer.pop();
|
||||
}
|
||||
else if (m_vRecvBytes)
|
||||
else if (m_hCommHandle != INVALID_HANDLE_VALUE) // COM
|
||||
{
|
||||
// Don't need critical section in here as CommThread is waiting for ACK
|
||||
|
||||
result = m_RecvBuffer[0];
|
||||
--m_vRecvBytes;
|
||||
|
||||
if (m_vbCommIRQ && !m_vRecvBytes)
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
{
|
||||
// Read last byte, so get CommThread to call WaitCommEvent() again
|
||||
OutputDebugString("CommRecv: SetEvent - ACK\n");
|
||||
SetEvent(m_hCommEvent[COMMEVT_ACK]);
|
||||
const UINT uCOMIdx = m_vuRxCurrBuffer;
|
||||
const UINT uSSCIdx = uCOMIdx ^ 1;
|
||||
if (!m_qComSerialBuffer[uSSCIdx].empty())
|
||||
{
|
||||
result = m_qComSerialBuffer[uSSCIdx].front();
|
||||
m_qComSerialBuffer[uSSCIdx].pop();
|
||||
|
||||
UINT uNewSSCIdx = uSSCIdx;
|
||||
if ( m_qComSerialBuffer[uSSCIdx].empty() && // Current SSC buffer is empty
|
||||
!m_qComSerialBuffer[uCOMIdx].empty() ) // Current COM buffer has data
|
||||
{
|
||||
m_vuRxCurrBuffer = uSSCIdx; // Flip buffers
|
||||
uNewSSCIdx = uCOMIdx;
|
||||
}
|
||||
|
||||
if (m_bRxIrqEnabled && !m_qComSerialBuffer[uNewSSCIdx].empty())
|
||||
{
|
||||
CpuIrqAssert(IS_SSC);
|
||||
m_vbRxIrqPending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&m_CriticalSection);
|
||||
|
||||
g_uDbgTotalSSCRx++;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -668,11 +713,13 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
|
|||
// . IRQs disabled : always set it [Currently done]
|
||||
//
|
||||
|
||||
// So that /m_vRecvBytes/ doesn't change midway (from 0 to 1):
|
||||
// . bIRQ=false, but uStatus.ST_RX_FULL=1
|
||||
bool bComSerialBufferEmpty = true; // Assume true, so if using TCP then logic below works
|
||||
|
||||
if (m_hCommHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
const UINT uSSCIdx = m_vuRxCurrBuffer ^ 1;
|
||||
bComSerialBufferEmpty = m_qComSerialBuffer[uSSCIdx].empty();
|
||||
}
|
||||
|
||||
bool bIRQ = false;
|
||||
|
@ -680,17 +727,18 @@ BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
|
|||
{
|
||||
bIRQ = true;
|
||||
}
|
||||
if (m_bRxIrqEnabled && (m_vRecvBytes || !m_TcpSerialBuffer.empty()))
|
||||
if (m_bRxIrqEnabled)
|
||||
{
|
||||
bIRQ = true;
|
||||
bIRQ = m_vbRxIrqPending;
|
||||
m_vbRxIrqPending = false; // Ensure 2 reads of STATUS reg only return ST_IRQ for first read
|
||||
}
|
||||
|
||||
m_bWrittenTx = false; // Read status reg always clears IRQ
|
||||
m_bWrittenTx = false; // Read status reg always clears IRQ
|
||||
|
||||
//
|
||||
|
||||
BYTE uStatus = ST_TX_EMPTY
|
||||
| ((m_vRecvBytes || !m_TcpSerialBuffer.empty()) ? ST_RX_FULL : 0x00)
|
||||
| ((!bComSerialBufferEmpty || !m_qTcpSerialBuffer.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)
|
||||
|
@ -798,18 +846,7 @@ void CSuperSerialCard::CommReset()
|
|||
{
|
||||
CloseComm();
|
||||
|
||||
GetDIPSW();
|
||||
|
||||
m_vRecvBytes = 0;
|
||||
|
||||
//
|
||||
|
||||
m_bTxIrqEnabled = false;
|
||||
m_bRxIrqEnabled = false;
|
||||
|
||||
m_bWrittenTx = false;
|
||||
|
||||
m_vbCommIRQ = false;
|
||||
InternalReset();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -824,27 +861,31 @@ void CSuperSerialCard::CommDestroy()
|
|||
|
||||
//===========================================================================
|
||||
|
||||
void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport)
|
||||
// dwNewSerialPortItem is the drop-down list item
|
||||
void CSuperSerialCard::CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem)
|
||||
{
|
||||
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET))
|
||||
{
|
||||
m_dwSerialPort = newserialport;
|
||||
}
|
||||
if (m_dwSerialPortItem == dwNewSerialPortItem)
|
||||
return;
|
||||
|
||||
_ASSERT(!IsActive());
|
||||
if (IsActive())
|
||||
return;
|
||||
|
||||
m_dwSerialPortItem = dwNewSerialPortItem;
|
||||
|
||||
if (m_dwSerialPortItem == m_uTCPChoiceItemIdx)
|
||||
strcpy(m_ayCurrentSerialPortName, TEXT_SERIAL_TCP);
|
||||
else if (m_dwSerialPortItem != 0)
|
||||
sprintf(m_ayCurrentSerialPortName, TEXT_SERIAL_COM"%d", m_vecSerialPortsItems[m_dwSerialPortItem]);
|
||||
else
|
||||
{
|
||||
MessageBox(window,
|
||||
TEXT("You cannot change the serial port while it is ")
|
||||
TEXT("in use."),
|
||||
TEXT("Configuration"),
|
||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||
}
|
||||
m_ayCurrentSerialPortName[0] = 0; // "None"
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void CSuperSerialCard::CommUpdate(DWORD totalcycles)
|
||||
{
|
||||
if ((m_hCommHandle == INVALID_HANDLE_VALUE) && (m_hCommListenSocket == INVALID_SOCKET))
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
if ((m_dwCommInactivity += totalcycles) > 1000000)
|
||||
|
@ -871,25 +912,87 @@ void CSuperSerialCard::CommUpdate(DWORD totalcycles)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
// Had this error when sizeof(m_RecvBuffer)==1 was used
|
||||
// UPDATE: Fixed by using double-buffered queue
|
||||
//
|
||||
// ERROR_OPERATION_ABORTED: CE_RXOVER
|
||||
//
|
||||
// Config:
|
||||
// . DOS Box (laptop) -> ZLink (PC)
|
||||
// . Baud = 300/4800/9600/19200
|
||||
// . InQueue size = 0x1000
|
||||
// . AppleII speed = 1MHz/2MHz/Unthrottled
|
||||
// . TYPE AW-PascalCrash.txt >COM7
|
||||
// . NB. AW-PascalCrash.txt is 10020 bytes
|
||||
//
|
||||
// Error:
|
||||
// . Always get ERROR_OPERATION_ABORTED after reading 0x555 total bytes
|
||||
// . dwErrors = 1 (CE_RXOVER)
|
||||
// . COMSTAT::InQueue = 0x1000
|
||||
//
|
||||
|
||||
static UINT g_uDbgTotalCOMRx = 0;
|
||||
|
||||
void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask)
|
||||
{
|
||||
if (dwEvtMask & EV_RXCHAR)
|
||||
{
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
ReadFile(m_hCommHandle, m_RecvBuffer, 1, (DWORD*)&m_vRecvBytes, &m_o);
|
||||
LeaveCriticalSection(&m_CriticalSection);
|
||||
char Data[0x80];
|
||||
DWORD dwReceived = 0;
|
||||
bool bGotData = false;
|
||||
|
||||
if (m_bRxIrqEnabled && m_vRecvBytes)
|
||||
// Read COM buffer until empty
|
||||
// NB. Potentially dangerous, as Apple read rate might be too slow, so could run out of memory on PC!
|
||||
do
|
||||
{
|
||||
m_vbCommIRQ = true;
|
||||
CpuIrqAssert(IS_SSC);
|
||||
if (!ReadFile(m_hCommHandle, Data, sizeof(Data), &dwReceived, &m_o) || !dwReceived)
|
||||
break;
|
||||
|
||||
g_uDbgTotalCOMRx += dwReceived;
|
||||
|
||||
bGotData = true;
|
||||
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
{
|
||||
const UINT uCOMIdx = m_vuRxCurrBuffer;
|
||||
for (DWORD i = 0; i < dwReceived; i++)
|
||||
m_qComSerialBuffer[uCOMIdx].push(Data[i]);
|
||||
}
|
||||
LeaveCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
while(sizeof(Data) == dwReceived);
|
||||
|
||||
//
|
||||
|
||||
if (bGotData)
|
||||
{
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
{
|
||||
// NB. m_vuRxCurrBuffer may've changed since ReadFile() above -- can change in CommReceive()
|
||||
// - Maybe buffers have already been flipped
|
||||
|
||||
const UINT uCOMIdx = m_vuRxCurrBuffer;
|
||||
const UINT uSSCIdx = uCOMIdx ^ 1;
|
||||
if ( m_qComSerialBuffer[uSSCIdx].empty() && // Current SSC buffer is empty
|
||||
!m_qComSerialBuffer[uCOMIdx].empty() ) // Current COM buffer has data
|
||||
{
|
||||
m_vuRxCurrBuffer = uSSCIdx; // Flip buffers
|
||||
|
||||
if (m_bRxIrqEnabled)
|
||||
{
|
||||
CpuIrqAssert(IS_SSC);
|
||||
m_vbRxIrqPending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
}
|
||||
//else if (dwEvtMask & EV_TXEMPTY)
|
||||
//{
|
||||
// if (m_bTxIrqEnabled)
|
||||
// {
|
||||
// m_vbCommIRQ = true;
|
||||
// m_vbTxIrqPending = true;
|
||||
// CpuIrqAssert(IS_SSC);
|
||||
// }
|
||||
//}
|
||||
|
@ -908,19 +1011,9 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
|||
//
|
||||
|
||||
const UINT nNumEvents = 2;
|
||||
#if 1
|
||||
|
||||
HANDLE hCommEvent_Wait[nNumEvents] = {pSSC->m_hCommEvent[COMMEVT_WAIT], pSSC->m_hCommEvent[COMMEVT_TERM]};
|
||||
HANDLE hCommEvent_Ack[nNumEvents] = {pSSC->m_hCommEvent[COMMEVT_ACK], pSSC->m_hCommEvent[COMMEVT_TERM]};
|
||||
#else
|
||||
HANDLE hCommEvent_Wait[nNumEvents];
|
||||
HANDLE hCommEvent_Ack[nNumEvents];
|
||||
|
||||
hCommEvent_Wait[0] = m_hCommEvent[COMMEVT_WAIT];
|
||||
hCommEvent_Wait[1] = m_hCommEvent[COMMEVT_TERM];
|
||||
|
||||
hCommEvent_Ack[0] = m_hCommEvent[COMMEVT_ACK];
|
||||
hCommEvent_Ack[1] = m_hCommEvent[COMMEVT_TERM];
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -932,10 +1025,25 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
|||
if (!bRes)
|
||||
{
|
||||
DWORD dwRet = GetLastError();
|
||||
// Got this error once: ERROR_OPERATION_ABORTED
|
||||
_ASSERT(dwRet == ERROR_IO_PENDING);
|
||||
if (dwRet != ERROR_IO_PENDING)
|
||||
{
|
||||
// Probably: ERROR_OPERATION_ABORTED
|
||||
DWORD dwErrors;
|
||||
COMSTAT Stat;
|
||||
ClearCommError(pSSC->m_hCommHandle, &dwErrors, &Stat);
|
||||
if (dwErrors)
|
||||
{
|
||||
if (dwErrors & CE_RXOVER)
|
||||
sprintf(szDbg, "CommThread: Err=CE_RXOVER (0x%08X): InQueue=0x%08X\n", dwErrors, Stat.cbInQue);
|
||||
else
|
||||
sprintf(szDbg, "CommThread: Err=Other (0x%08X): InQueue=0x%08X, OutQueue=0x%08X\n", dwErrors, Stat.cbInQue, Stat.cbOutQue);
|
||||
OutputDebugString(szDbg);
|
||||
if (g_fh)
|
||||
fprintf(g_fh, szDbg);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Wait for comm event
|
||||
|
@ -943,7 +1051,7 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
|||
|
||||
while(1)
|
||||
{
|
||||
OutputDebugString("CommThread: Wait1\n");
|
||||
//OutputDebugString("CommThread: Wait1\n");
|
||||
dwWaitResult = WaitForMultipleObjects(
|
||||
nNumEvents, // number of handles in array
|
||||
hCommEvent_Wait, // array of event handles
|
||||
|
@ -959,7 +1067,7 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
|||
}
|
||||
|
||||
dwWaitResult -= WAIT_OBJECT_0; // Determine event # that signaled
|
||||
sprintf(szDbg, "CommThread: GotEvent1: %d\n", dwWaitResult); OutputDebugString(szDbg);
|
||||
//sprintf(szDbg, "CommThread: GotEvent1: %d\n", dwWaitResult); OutputDebugString(szDbg);
|
||||
|
||||
if (dwWaitResult == (nNumEvents-1))
|
||||
break; // Termination event
|
||||
|
@ -967,34 +1075,6 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
|||
|
||||
// Comm event
|
||||
pSSC->CheckCommEvent(dwEvtMask);
|
||||
|
||||
if (pSSC->m_vbCommIRQ)
|
||||
{
|
||||
//
|
||||
// Wait for ack
|
||||
//
|
||||
|
||||
while(1)
|
||||
{
|
||||
OutputDebugString("CommThread: Wait2\n");
|
||||
dwWaitResult = WaitForMultipleObjects(
|
||||
nNumEvents, // number of handles in array
|
||||
hCommEvent_Ack, // array of event handles
|
||||
FALSE, // wait until any one is signaled
|
||||
INFINITE);
|
||||
|
||||
if ((dwWaitResult >= WAIT_OBJECT_0) && (dwWaitResult <= WAIT_OBJECT_0+nNumEvents-1))
|
||||
break;
|
||||
}
|
||||
|
||||
dwWaitResult -= WAIT_OBJECT_0; // Determine event # that signaled
|
||||
sprintf(szDbg, "CommThread: GotEvent2: %d\n", dwWaitResult); OutputDebugString(szDbg);
|
||||
|
||||
if (dwWaitResult == (nNumEvents-1))
|
||||
break; // Termination event
|
||||
|
||||
pSSC->m_vbCommIRQ = false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1101,6 +1181,112 @@ void CSuperSerialCard::CommThUninit()
|
|||
|
||||
//===========================================================================
|
||||
|
||||
void CSuperSerialCard::ScanCOMPorts()
|
||||
{
|
||||
m_vecSerialPortsItems.clear();
|
||||
m_vecSerialPortsItems.push_back(SERIALPORTITEM_INVALID_COM_PORT); // "None"
|
||||
|
||||
for (UINT i=1; i<32; i++) // Arbitrary upper limit
|
||||
{
|
||||
TCHAR portname[SIZEOF_SERIALCHOICE_ITEM];
|
||||
wsprintf(portname, TEXT("COM%u"), i);
|
||||
|
||||
HANDLE 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 (hCommHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(hCommHandle);
|
||||
m_vecSerialPortsItems.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
m_vecSerialPortsItems.push_back(SERIALPORTITEM_INVALID_COM_PORT); // "TCP"
|
||||
m_uTCPChoiceItemIdx = m_vecSerialPortsItems.size()-1;
|
||||
}
|
||||
|
||||
char* CSuperSerialCard::GetSerialPortChoices()
|
||||
{
|
||||
if (IsActive())
|
||||
return m_aySerialPortChoices;
|
||||
|
||||
//
|
||||
|
||||
ScanCOMPorts(); // Do this every time in case news ones available (eg. for USB COM ports)
|
||||
delete [] m_aySerialPortChoices;
|
||||
m_aySerialPortChoices = new TCHAR [ GetNumSerialPortChoices() * SIZEOF_SERIALCHOICE_ITEM + 1 ]; // +1 for final NULL item
|
||||
|
||||
TCHAR* pNextSerialChoice = m_aySerialPortChoices;
|
||||
|
||||
//
|
||||
|
||||
pNextSerialChoice += wsprintf(pNextSerialChoice, TEXT("None"));
|
||||
pNextSerialChoice++; // Skip NULL char
|
||||
|
||||
for (UINT i=1; i<m_uTCPChoiceItemIdx; i++)
|
||||
{
|
||||
pNextSerialChoice += wsprintf(pNextSerialChoice, TEXT("COM%u"), m_vecSerialPortsItems[i]);
|
||||
pNextSerialChoice++; // Skip NULL char
|
||||
}
|
||||
|
||||
pNextSerialChoice += wsprintf(pNextSerialChoice, TEXT("TCP"));
|
||||
pNextSerialChoice++; // Skip NULL char
|
||||
|
||||
*pNextSerialChoice = 0;
|
||||
|
||||
//
|
||||
|
||||
return m_aySerialPortChoices;
|
||||
}
|
||||
|
||||
void CSuperSerialCard::SetSerialPortName(const char* pSerialPortName)
|
||||
{
|
||||
strncpy(m_ayCurrentSerialPortName, pSerialPortName, SIZEOF_SERIALCHOICE_ITEM);
|
||||
|
||||
if (m_vecSerialPortsItems.empty())
|
||||
ScanCOMPorts();
|
||||
|
||||
if (strncmp(TEXT_SERIAL_COM, pSerialPortName, sizeof(TEXT_SERIAL_COM)-1) == 0)
|
||||
{
|
||||
const char* p = &pSerialPortName[ sizeof(TEXT_SERIAL_COM)-1 ];
|
||||
const int nCOMPort = atoi(p);
|
||||
m_dwSerialPortItem = 0;
|
||||
for (UINT i=0; i<m_vecSerialPortsItems.size(); i++)
|
||||
{
|
||||
if (m_vecSerialPortsItems[i] == nCOMPort)
|
||||
{
|
||||
m_dwSerialPortItem = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//_ASSERT(m_dwSerialPortItem); // EG. Switched a USB COM port from COM7 to COM8 between AppleWin sessions
|
||||
|
||||
if (m_dwSerialPortItem >= GetNumSerialPortChoices())
|
||||
{
|
||||
_ASSERT(0);
|
||||
m_dwSerialPortItem = 0;
|
||||
}
|
||||
}
|
||||
else if (strncmp(TEXT_SERIAL_TCP, pSerialPortName, sizeof(TEXT_SERIAL_TCP)-1) == 0)
|
||||
{
|
||||
m_dwSerialPortItem = m_uTCPChoiceItemIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ayCurrentSerialPortName[0] = 0; // "None"
|
||||
m_dwSerialPortItem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD CSuperSerialCard::CommGetSnapshot(SS_IO_Comms* pSS)
|
||||
{
|
||||
pSS->baudrate = m_uBaudRate;
|
||||
|
@ -1109,8 +1295,8 @@ DWORD CSuperSerialCard::CommGetSnapshot(SS_IO_Comms* pSS)
|
|||
pSS->comminactivity = m_dwCommInactivity;
|
||||
pSS->controlbyte = m_uControlByte;
|
||||
pSS->parity = m_uParity;
|
||||
memcpy(pSS->recvbuffer, m_RecvBuffer, uRecvBufferSize);
|
||||
pSS->recvbytes = m_vRecvBytes;
|
||||
// memcpy(pSS->recvbuffer, m_RecvBuffer, uRecvBufferSize);
|
||||
pSS->recvbytes = 0;
|
||||
pSS->stopbits = m_uStopBits;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1123,8 +1309,8 @@ DWORD CSuperSerialCard::CommSetSnapshot(SS_IO_Comms* pSS)
|
|||
m_dwCommInactivity = pSS->comminactivity;
|
||||
m_uControlByte = pSS->controlbyte;
|
||||
m_uParity = pSS->parity;
|
||||
memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
||||
m_vRecvBytes = pSS->recvbytes;
|
||||
// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
||||
// m_vRecvBytes = pSS->recvbytes;
|
||||
m_uStopBits = pSS->stopbits;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,22 +20,28 @@ typedef struct
|
|||
bool bInterrupts;
|
||||
} SSC_DIPSW;
|
||||
|
||||
#define TEXT_SERIAL_COM TEXT("COM")
|
||||
#define TEXT_SERIAL_TCP TEXT("TCP")
|
||||
|
||||
class CSuperSerialCard
|
||||
{
|
||||
public:
|
||||
CSuperSerialCard();
|
||||
virtual ~CSuperSerialCard() {}
|
||||
virtual ~CSuperSerialCard();
|
||||
|
||||
void CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||
void CommReset();
|
||||
void CommDestroy();
|
||||
void CommSetSerialPort(HWND,DWORD);
|
||||
void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem);
|
||||
void CommUpdate(DWORD);
|
||||
DWORD CommGetSnapshot(SS_IO_Comms* pSS);
|
||||
DWORD CommSetSnapshot(SS_IO_Comms* pSS);
|
||||
|
||||
DWORD GetSerialPort() { return m_dwSerialPort; }
|
||||
void SetSerialPort(DWORD dwSerialPort) { m_dwSerialPort = dwSerialPort; }
|
||||
char* GetSerialPortChoices();
|
||||
DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item
|
||||
char* GetSerialPortName() { return m_ayCurrentSerialPortName; }
|
||||
void SetSerialPortName(const char* pSerialPortName);
|
||||
bool IsActive() { return (m_hCommHandle != INVALID_HANDLE_VALUE) || (m_hCommListenSocket != INVALID_SOCKET); }
|
||||
|
||||
void CommTcpSerialAccept();
|
||||
void CommTcpSerialReceive();
|
||||
|
@ -53,6 +59,7 @@ private:
|
|||
BYTE __stdcall CommStatus(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
BYTE __stdcall CommTransmit(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
|
||||
void InternalReset();
|
||||
void GetDIPSW();
|
||||
void SetDIPSWDefaults();
|
||||
BYTE GenerateControl();
|
||||
|
@ -64,11 +71,22 @@ private:
|
|||
static DWORD WINAPI CommThread(LPVOID lpParameter);
|
||||
bool CommThInit();
|
||||
void CommThUninit();
|
||||
UINT GetNumSerialPortChoices() { return m_vecSerialPortsItems.size(); }
|
||||
void ScanCOMPorts();
|
||||
|
||||
//
|
||||
|
||||
public:
|
||||
static const UINT SIZEOF_SERIALCHOICE_ITEM = 8*sizeof(char);
|
||||
|
||||
private:
|
||||
DWORD m_dwSerialPort;
|
||||
char m_ayCurrentSerialPortName[SIZEOF_SERIALCHOICE_ITEM];
|
||||
DWORD m_dwSerialPortItem;
|
||||
|
||||
static const UINT SERIALPORTITEM_INVALID_COM_PORT = 0;
|
||||
std::vector<UINT> m_vecSerialPortsItems; // Includes "None" & "TCP" items
|
||||
char* m_aySerialPortChoices;
|
||||
UINT m_uTCPChoiceItemIdx;
|
||||
|
||||
static SSC_DIPSW m_DIPSWDefault;
|
||||
SSC_DIPSW m_DIPSWCurrent;
|
||||
|
@ -95,20 +113,22 @@ private:
|
|||
//
|
||||
|
||||
CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/
|
||||
BYTE m_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used
|
||||
queue<BYTE> m_TcpSerialBuffer;
|
||||
volatile DWORD m_vRecvBytes;
|
||||
queue<BYTE> m_qComSerialBuffer[2];
|
||||
volatile UINT m_vuRxCurrBuffer; // Written to on COM recv. SSC reads from other one
|
||||
queue<BYTE> m_qTcpSerialBuffer;
|
||||
|
||||
//
|
||||
|
||||
bool m_bTxIrqEnabled;
|
||||
bool m_bRxIrqEnabled;
|
||||
|
||||
volatile bool m_vbTxIrqPending;
|
||||
volatile bool m_vbRxIrqPending;
|
||||
|
||||
bool m_bWrittenTx;
|
||||
|
||||
//
|
||||
|
||||
volatile bool m_vbCommIRQ;
|
||||
HANDLE m_hCommThread;
|
||||
|
||||
HANDLE m_hCommEvent[COMMEVT_MAX];
|
||||
|
|
|
@ -572,6 +572,33 @@ LONG NewVolume(DWORD dwVolume, DWORD dwVolumeMax)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
static int g_nErrorInc = 20; // Old: 1
|
||||
static int g_nErrorMax = 200; // Old: 50
|
||||
|
||||
int SoundCore_GetErrorInc()
|
||||
{
|
||||
return g_nErrorInc;
|
||||
}
|
||||
|
||||
void SoundCore_SetErrorInc(const int nErrorInc)
|
||||
{
|
||||
g_nErrorInc = nErrorInc < g_nErrorMax ? nErrorInc : g_nErrorMax;
|
||||
if(g_fh) fprintf(g_fh, "Speaker/MB Error Inc = %d\n", g_nErrorInc);
|
||||
}
|
||||
|
||||
int SoundCore_GetErrorMax()
|
||||
{
|
||||
return g_nErrorMax;
|
||||
}
|
||||
|
||||
void SoundCore_SetErrorMax(const int nErrorMax)
|
||||
{
|
||||
g_nErrorMax = nErrorMax < MAX_SAMPLES ? nErrorMax : MAX_SAMPLES;
|
||||
if(g_fh) fprintf(g_fh, "Speaker/MB Error Max = %d\n", g_nErrorMax);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static DWORD g_dwAdviseToken;
|
||||
static IReferenceClock *g_pRefClock = NULL;
|
||||
static HANDLE g_hSemaphore = NULL;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#define MAX_SAMPLES (16*1024)
|
||||
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
// Define max 1 of these:
|
||||
|
@ -35,6 +37,11 @@ void SoundCore_SetFade(eFADE FadeType);
|
|||
bool SoundCore_GetTimerState();
|
||||
void SoundCore_TweakVolumes();
|
||||
|
||||
int SoundCore_GetErrorInc();
|
||||
void SoundCore_SetErrorInc(const int nErrorInc);
|
||||
int SoundCore_GetErrorMax();
|
||||
void SoundCore_SetErrorMax(const int nErrorMax);
|
||||
|
||||
bool DSInit();
|
||||
void DSUninit();
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#define SOUND_WAVE 3
|
||||
|
||||
static const unsigned short g_nSPKR_NumChannels = 1;
|
||||
static const DWORD g_dwDSSpkrBufferSize = 16 * 1024 * sizeof(short) * g_nSPKR_NumChannels;
|
||||
static const DWORD g_dwDSSpkrBufferSize = MAX_SAMPLES * sizeof(short) * g_nSPKR_NumChannels;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
|
@ -207,7 +207,6 @@ static void InitRemainderBuffer()
|
|||
void SpkrDestroy ()
|
||||
{
|
||||
Spkr_DSUninit();
|
||||
//DSUninit();
|
||||
|
||||
//
|
||||
|
||||
|
@ -248,7 +247,6 @@ void SpkrInitialize ()
|
|||
}
|
||||
else
|
||||
{
|
||||
//DSInit();
|
||||
g_bSpkrAvailable = Spkr_DSInit();
|
||||
}
|
||||
|
||||
|
@ -802,7 +800,7 @@ static ULONG Spkr_SubmitWaveBuffer_FullSpeed(short* pSpeakerBuffer, ULONG nNumSa
|
|||
|
||||
static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
||||
{
|
||||
//char szDbg[200];
|
||||
char szDbg[200];
|
||||
nDbgSpkrCnt++;
|
||||
|
||||
if(!SpeakerVoice.bActive)
|
||||
|
@ -849,7 +847,11 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
|||
// |-----PxxxxxW-----|
|
||||
if((dwByteOffset > dwCurrentPlayCursor) && (dwByteOffset < dwCurrentWriteCursor))
|
||||
{
|
||||
//sprintf(szDbg, "[Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X xxx\n", dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples); OutputDebugString(szDbg);
|
||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||
sprintf(szDbg, "%010.3f: [Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X xxx\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||
OutputDebugString(szDbg);
|
||||
if (g_fh) fprintf(g_fh, szDbg);
|
||||
|
||||
dwByteOffset = dwCurrentWriteCursor;
|
||||
nNumSamplesError = 0;
|
||||
bBufferError = true;
|
||||
|
@ -860,7 +862,11 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
|||
// |xxW----------Pxxx|
|
||||
if((dwByteOffset > dwCurrentPlayCursor) || (dwByteOffset < dwCurrentWriteCursor))
|
||||
{
|
||||
//sprintf(szDbg, "[Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples); OutputDebugString(szDbg);
|
||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||
sprintf(szDbg, "%010.3f: [Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||
OutputDebugString(szDbg);
|
||||
if (g_fh) fprintf(g_fh, szDbg);
|
||||
|
||||
dwByteOffset = dwCurrentWriteCursor;
|
||||
nNumSamplesError = 0;
|
||||
bBufferError = true;
|
||||
|
@ -876,16 +882,17 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
|||
nBytesRemaining = g_dwDSSpkrBufferSize; // Case when complete buffer is to be played
|
||||
|
||||
// Calc correction factor so that play-buffer doesn't under/overflow
|
||||
const int nErrorInc = SoundCore_GetErrorInc();
|
||||
if(nBytesRemaining < g_dwDSSpkrBufferSize / 4)
|
||||
nNumSamplesError++; // < 1/4 of play-buffer remaining (need *more* data)
|
||||
nNumSamplesError += nErrorInc; // < 1/4 of play-buffer remaining (need *more* data)
|
||||
else if(nBytesRemaining > g_dwDSSpkrBufferSize / 2)
|
||||
nNumSamplesError--; // > 1/2 of play-buffer remaining (need *less* data)
|
||||
nNumSamplesError -= nErrorInc; // > 1/2 of play-buffer remaining (need *less* data)
|
||||
else
|
||||
nNumSamplesError = 0; // Acceptable amount of data in buffer
|
||||
|
||||
const int nMaxError = 50; // Cap feedback to +/-nMaxError units
|
||||
if(nNumSamplesError < -nMaxError) nNumSamplesError = -nMaxError;
|
||||
if(nNumSamplesError > nMaxError) nNumSamplesError = nMaxError;
|
||||
const int nErrorMax = SoundCore_GetErrorMax(); // Cap feedback to +/-nMaxError units
|
||||
if(nNumSamplesError < -nErrorMax) nNumSamplesError = -nErrorMax;
|
||||
if(nNumSamplesError > nErrorMax) nNumSamplesError = nErrorMax;
|
||||
g_nCpuCyclesFeedback = (int) ((double)nNumSamplesError * g_fClksPerSpkrSample);
|
||||
|
||||
//
|
||||
|
|
|
@ -10,6 +10,8 @@ void SpkrReset();
|
|||
BOOL SpkrSetEmulationType (HWND,DWORD);
|
||||
void SpkrUpdate (DWORD);
|
||||
void SpkrUpdate_Timer();
|
||||
void Spkr_SetErrorInc(const int nErrorInc);
|
||||
void Spkr_SetErrorMax(const int nErrorMax);
|
||||
DWORD SpkrGetVolume();
|
||||
void SpkrSetVolume(DWORD dwVolume, DWORD dwVolumeMax);
|
||||
void Spkr_Mute();
|
||||
|
|
|
@ -483,7 +483,7 @@ int tfe_activate_i(void)
|
|||
if (tfe==NULL)
|
||||
{
|
||||
#ifdef TFE_DEBUG_INIT
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate_i: Allocating tfe failed.");
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate_i: Allocating tfe failed.\n");
|
||||
#endif
|
||||
tfe_enabled = 0;
|
||||
return 0;
|
||||
|
@ -495,7 +495,7 @@ int tfe_activate_i(void)
|
|||
if (tfe_packetpage==NULL)
|
||||
{
|
||||
#ifdef TFE_DEBUG_INIT
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate: Allocating tfe_packetpage failed.");
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate: Allocating tfe_packetpage failed.\n");
|
||||
#endif
|
||||
lib_free(tfe);
|
||||
tfe=NULL;
|
||||
|
@ -504,8 +504,8 @@ int tfe_activate_i(void)
|
|||
}
|
||||
|
||||
#ifdef TFE_DEBUG_INIT
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate: Allocated memory successfully.");
|
||||
if(g_fh) fprintf(g_fh, "\ttfe at $%08X, tfe_packetpage at $%08X", tfe, tfe_packetpage );
|
||||
if(g_fh) fprintf(g_fh, "tfe_activate: Allocated memory successfully.\n");
|
||||
if(g_fh) fprintf(g_fh, "\ttfe at $%08X, tfe_packetpage at $%08X\n", tfe, tfe_packetpage );
|
||||
#endif
|
||||
|
||||
#ifdef DOS_TFE
|
||||
|
@ -862,7 +862,7 @@ void tfe_sideeffects_write_pp_on_txframe(WORD ppaddress)
|
|||
|| (txlen<MIN_TXLENGTH)
|
||||
) {
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Should send %u octets: Not allowed, thus ignoring!", txlen);
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Should send %u octets: Not allowed, thus ignoring!\n", txlen);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
@ -949,13 +949,13 @@ void tfe_sideeffects_write_pp(WORD ppaddress, int oddaddress)
|
|||
|
||||
case TFE_PP_ADDR_SE_RXEVENT:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Written read-only register TFE_PP_ADDR_SE_RXEVENT: IGNORED");
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Written read-only register TFE_PP_ADDR_SE_RXEVENT: IGNORED\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TFE_PP_ADDR_SE_BUSST:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Written read-only register TFE_PP_ADDR_SE_BUSST: IGNORED");
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Written read-only register TFE_PP_ADDR_SE_BUSST: IGNORED\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -966,7 +966,7 @@ void tfe_sideeffects_write_pp(WORD ppaddress, int oddaddress)
|
|||
#ifdef TFE_DEBUG_WARN
|
||||
/* check if we had a TXCMD, but not all octets were written */
|
||||
if (tfe_started_tx && !oddaddress) {
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Early abort of transmitted frame");
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Early abort of transmitted frame\n");
|
||||
}
|
||||
tfe_started_tx = 1;
|
||||
#endif
|
||||
|
@ -1051,13 +1051,13 @@ void tfe_sideeffects_read_pp(WORD ppaddress)
|
|||
|
||||
case TFE_PP_ADDR_TXCMD:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXCMD: IGNORED");
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXCMD: IGNORED\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TFE_PP_ADDR_TXLENGTH:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXLENGTH: IGNORED");
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXLENGTH: IGNORED\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -1146,7 +1146,7 @@ BYTE REGPARM1 tfe_read(WORD ioaddress)
|
|||
case TFE_ADDR_TXLENGTH:
|
||||
case TFE_ADDR_TXLENGTH+1:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Reading write-only TFE register $%02X!", ioaddress);
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Reading write-only TFE register $%02X!\n", ioaddress);
|
||||
#endif
|
||||
/* @SRT TODO: Verify with reality */
|
||||
retval = GET_TFE_8(ioaddress);
|
||||
|
@ -1157,7 +1157,7 @@ BYTE REGPARM1 tfe_read(WORD ioaddress)
|
|||
case TFE_ADDR_PP_DATA2:
|
||||
case TFE_ADDR_PP_DATA2+1:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Reading not supported TFE register $%02X!", ioaddress);
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Reading not supported TFE register $%02X!\n", ioaddress);
|
||||
#endif
|
||||
/* @SRT TODO */
|
||||
retval = GET_TFE_8(ioaddress);
|
||||
|
@ -1229,7 +1229,7 @@ void REGPARM2 tfe_store(WORD ioaddress, BYTE byte)
|
|||
case TFE_ADDR_INTSTQUEUE:
|
||||
case TFE_ADDR_INTSTQUEUE+1:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Writing read-only TFE register $%02X!", ioaddress);
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Writing read-only TFE register $%02X!\n", ioaddress);
|
||||
#endif
|
||||
/* @SRT TODO: Verify with reality */
|
||||
/* do nothing */
|
||||
|
@ -1240,7 +1240,7 @@ void REGPARM2 tfe_store(WORD ioaddress, BYTE byte)
|
|||
case TFE_ADDR_PP_DATA2:
|
||||
case TFE_ADDR_PP_DATA2+1:
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Writing not supported TFE register $%02X!", ioaddress);
|
||||
if(g_fh) fprintf(g_fh, "WARNING! Writing not supported TFE register $%02X!\n", ioaddress);
|
||||
#endif
|
||||
/* do nothing */
|
||||
return;
|
||||
|
@ -1296,7 +1296,7 @@ void REGPARM2 tfe_store(WORD ioaddress, BYTE byte)
|
|||
|
||||
#ifdef TFE_DEBUG_WARN
|
||||
if(g_fh) fprintf(g_fh,
|
||||
"WARNING! PacketPage register set to odd address $%04X (not allowed!)",
|
||||
"WARNING! PacketPage register set to odd address $%04X (not allowed!)\n",
|
||||
tfe_packetpage_ptr );
|
||||
#endif /* #ifdef TFE_DEBUG_WARN */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue