if (select (1, &fd, NULL, NULL, &tv)) {
serialconn = accept (serialsocket, (struct sockaddr*)socketaddr, &sa_len);
if (serialconn != INVALID_SOCKET)
- write_log (_T("SERIRAL_TCP: connection accepted\n"));
+ write_log (_T("SERIAL_TCP: connection accepted\n"));
}
}
return serialconn != INVALID_SOCKET;
static void outser (void)
{
DWORD actual;
- if (WaitForSingleObject (writeevent, 0) == WAIT_OBJECT_0 && datainoutput > 0) {
+ if (datainoutput > 0 && WaitForSingleObject (writeevent, 0) == WAIT_OBJECT_0 ) {
memcpy (outputbufferout, outputbuffer, datainoutput);
WriteFile (hCom, outputbufferout, datainoutput, &actual, &writeol);
datainoutput = 0;
}
}
-int checkserwrite (void)
+int checkserwrite (int spaceneeded)
{
if (hCom == INVALID_HANDLE_VALUE || !currprefs.use_serial)
return 1;
return 1;
} else {
outser ();
- if (datainoutput >= sizeof (outputbuffer) - 1)
+ if (datainoutput + spaceneeded >= sizeof (outputbuffer))
return 0;
}
return 1;
int err = recv (serialconn, buf, 1, 0);
if (err == 1) {
*buffer = buf[0];
+ //write_log(_T(" %02X "), buf[0]);
return 1;
} else {
tcp_disconnect ();
const static GUID GUID_DEVINTERFACE_PARALLEL = {0x97F76EF0,0xF883,0x11D0,
{0xAF,0x1F,0x00,0x00,0xF8,0x00,0x84,0x5C}};
+static const GUID serportsguids[] =
+{
+ GUID_DEVINTERFACE_COMPORT,
+ // GUID_DEVINTERFACE_MODEM
+ { 0x2C7089AA, 0x2E0E, 0x11D1, { 0xB1, 0x14, 0x00, 0xC0, 0x4F, 0xC2, 0xAA, 0xE4} }
+};
+static const GUID parportsguids[] =
+{
+ GUID_DEVINTERFACE_PARALLEL
+};
+
static int enumports_2 (struct serparportinfo **pi, int cnt, bool parport)
{
// Create a device information set that will be the container for
// the device interfaces.
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
- BOOL bOk = TRUE;
SP_DEVICE_INTERFACE_DATA ifcData;
DWORD dwDetDataSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA) + 256 * sizeof (TCHAR);
- DWORD ii;
+ const GUID *guids = parport ? parportsguids : serportsguids;
+ int guidcnt = parport ? sizeof(parportsguids)/sizeof(parportsguids[0]) : sizeof(serportsguids)/sizeof(serportsguids[0]);
- hDevInfo = SetupDiGetClassDevs (parport ? &GUID_DEVINTERFACE_PARALLEL : &GUID_DEVINTERFACE_COMPORT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
- if(hDevInfo == INVALID_HANDLE_VALUE)
- return 0;
- // Enumerate the serial ports
- pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)xmalloc (uae_u8, dwDetDataSize);
- // This is required, according to the documentation. Yes,
- // it's weird.
- ifcData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
- pDetData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
- for (ii = 0; bOk; ii++) {
- bOk = SetupDiEnumDeviceInterfaces (hDevInfo, NULL, parport ? &GUID_DEVINTERFACE_PARALLEL : &GUID_DEVINTERFACE_COMPORT, ii, &ifcData);
- if (bOk) {
- // Got a device. Get the details.
- SP_DEVINFO_DATA devdata = { sizeof (SP_DEVINFO_DATA)};
- bOk = SetupDiGetDeviceInterfaceDetail (hDevInfo,
- &ifcData, pDetData, dwDetDataSize, NULL, &devdata);
+ for (int guididx = 0; guididx < guidcnt; guididx++) {
+ hDevInfo = SetupDiGetClassDevs (&guids[guididx], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if(hDevInfo == INVALID_HANDLE_VALUE)
+ continue;
+ // Enumerate the serial ports
+ pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)xmalloc (uae_u8, dwDetDataSize);
+ // This is required, according to the documentation. Yes,
+ // it's weird.
+ ifcData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
+ pDetData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
+ BOOL bOk = TRUE;
+ for (int ii = 0; bOk; ii++) {
+ bOk = SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &guids[guididx], ii, &ifcData);
if (bOk) {
- // Got a path to the device. Try to get some more info.
- TCHAR fname[256];
- TCHAR desc[256];
- BOOL bSuccess = SetupDiGetDeviceRegistryProperty (
- hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
- (PBYTE)fname, sizeof (fname), NULL);
- bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty (
- hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
- (PBYTE)desc, sizeof (desc), NULL);
- if (bSuccess && cnt < MAX_SERPAR_PORTS) {
- TCHAR *p;
- pi[cnt] = xcalloc (struct serparportinfo, 1);
- pi[cnt]->dev = my_strdup (pDetData->DevicePath);
- pi[cnt]->name = my_strdup (fname);
- p = _tcsstr (fname, parport ? _T("(LPT") : _T("(COM"));
- if (p && (p[5] == ')' || p[6] == ')')) {
- pi[cnt]->cfgname = xmalloc (TCHAR, 100);
- if (isdigit(p[5]))
- _stprintf (pi[cnt]->cfgname, parport ? _T("LPT%c%c") : _T("COM%c%c"), p[4], p[5]);
- else
- _stprintf (pi[cnt]->cfgname, parport ? _T("LPT%c") : _T("COM%c"), p[4]);
- } else {
- pi[cnt]->cfgname = my_strdup (pDetData->DevicePath);
+ // Got a device. Get the details.
+ SP_DEVINFO_DATA devdata = { sizeof (SP_DEVINFO_DATA)};
+ bOk = SetupDiGetDeviceInterfaceDetail (hDevInfo,
+ &ifcData, pDetData, dwDetDataSize, NULL, &devdata);
+ if (bOk) {
+ // Got a path to the device. Try to get some more info.
+ TCHAR fname[256];
+ TCHAR desc[256];
+ BOOL bSuccess = SetupDiGetDeviceRegistryProperty (
+ hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
+ (PBYTE)fname, sizeof (fname), NULL);
+ bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty (
+ hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
+ (PBYTE)desc, sizeof (desc), NULL);
+ if (bSuccess && cnt < MAX_SERPAR_PORTS) {
+ TCHAR *p;
+ pi[cnt] = xcalloc (struct serparportinfo, 1);
+ pi[cnt]->dev = my_strdup (pDetData->DevicePath);
+ pi[cnt]->name = my_strdup (fname);
+ p = _tcsstr (fname, parport ? _T("(LPT") : _T("(COM"));
+ if (p && (p[5] == ')' || p[6] == ')')) {
+ pi[cnt]->cfgname = xmalloc (TCHAR, 100);
+ if (isdigit(p[5]))
+ _stprintf (pi[cnt]->cfgname, parport ? _T("LPT%c%c") : _T("COM%c%c"), p[4], p[5]);
+ else
+ _stprintf (pi[cnt]->cfgname, parport ? _T("LPT%c") : _T("COM%c"), p[4]);
+ } else {
+ pi[cnt]->cfgname = my_strdup (pDetData->DevicePath);
+ }
+ write_log (_T("%s: '%s' = '%s' = '%s'\n"), parport ? _T("PARPORT") : _T("SERPORT"), pi[cnt]->name, pi[cnt]->cfgname, pi[cnt]->dev);
+ cnt++;
}
- write_log (_T("%s: '%s' = '%s' = '%s'\n"), parport ? _T("PARPORT") : _T("SERPORT"), pi[cnt]->name, pi[cnt]->cfgname, pi[cnt]->dev);
- cnt++;
+ } else {
+ write_log (_T("SetupDiGetDeviceInterfaceDetail failed, err=%d"), GetLastError ());
+ break;
}
} else {
- write_log (_T("SetupDiGetDeviceInterfaceDetail failed, err=%d"), GetLastError ());
- goto end;
- }
- } else {
- DWORD err = GetLastError ();
- if (err != ERROR_NO_MORE_ITEMS) {
- write_log (_T("SetupDiEnumDeviceInterfaces failed, err=%d"), err);
- goto end;
+ DWORD err = GetLastError ();
+ if (err != ERROR_NO_MORE_ITEMS) {
+ write_log (_T("SetupDiEnumDeviceInterfaces failed, err=%d"), err);
+ break;
+ }
}
}
+ xfree(pDetData);
+ if (hDevInfo != INVALID_HANDLE_VALUE)
+ SetupDiDestroyDeviceInfoList (hDevInfo);
}
-end:
- xfree(pDetData);
- if (hDevInfo != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList (hDevInfo);
return cnt;
}
#define SERIALDEBUG 0 /* 0, 1, 2 3 */
#define SERIALHSDEBUG 0
#define MODEMTEST 0 /* 0 or 1 */
+#define SERIAL_HSYNC_BEFORE_OVERFLOW 200
static int data_in_serdat; /* new data written to SERDAT */
static int data_in_serdatr; /* new data received */
static int lastbitcycle_active_hsyncs;
static bool gotlogwrite;
static unsigned int lastbitcycle;
+static int serial_recv_previous, serial_send_previous;
+static int serdatr_last_got;
int serdev;
int seriallog = 0, log_sercon = 0;
int serial_enet;
baud = 115200;
serial_period_hsyncs = 1;
}
+ serial_recv_previous = -1;
+ serial_send_previous = -1;
#ifdef SERIAL_PORT
setbaud (baud);
#endif
return '.';
}
+static bool canreceive(void)
+{
+ if (!data_in_serdatr)
+ return true;
+ if (currprefs.serial_direct)
+ return false;
+ return serdatr_last_got >= SERIAL_HSYNC_BEFORE_OVERFLOW || currprefs.cpu_cycle_exact;
+}
+
static void checkreceive_enet (void)
{
#ifdef SERIAL_ENET
uae_u16 recdata;
+ if (!canreceive())
+ return;
if (!enet_readseravail ())
return;
if (!enet_readser (&recdata))
else
serdatr |= 0x100;
data_in_serdatr = 1;
+ serdatr_last_got = 0;
serial_check_irq ();
#if SERIALDEBUG > 2
write_log (_T("SERIAL: received %02X (%c)\n"), serdatr & 0xff, dochar (serdatr));
static int ninebitdata;
int recdata;
- if (!readseravail())
+ if (!canreceive())
return;
if (ninebit) {
+ if (!readseravail())
+ return;
for (;;) {
if (!readser (&recdata))
return;
}
}
} else {
- if (!readser (&recdata))
+ if (!readseravail())
return;
+ if (!readser(&recdata))
+ return;
+ if (currprefs.serial_crlf) {
+ if (recdata == 0 || (serial_recv_previous == 13 && recdata == 10)) {
+ //write_log(_T(" [%02X] "), (uae_u8)recdata);
+ serial_recv_previous = -1;
+ return;
+ }
+ }
+ //write_log(_T(" %02X "), (uae_u8)recdata);
+ serial_recv_previous = recdata;
serdatr = recdata;
serdatr |= 0x100;
}
+
data_in_serdatr = 1;
+ serdatr_last_got = 0;
serial_check_irq ();
#if SERIALDEBUG > 2
write_log (_T("SERIAL: received %02X (%c)\n"), serdatr & 0xff, dochar (serdatr));
static void checksend(void)
{
- bool sent = true;
-
if (data_in_sershift != 1)
return;
}
#endif
#ifdef SERIAL_PORT
- if (checkserwrite()) {
- if (ninebit)
- writeser(((serdatshift >> 8) & 1) | 0xa8);
+ if (ninebit) {
+ if (!checkserwrite(2))
+ return;
+ writeser(((serdatshift >> 8) & 1) | 0xa8);
writeser(serdatshift_masked);
} else {
- // buffer full, try again later
- sent = false;
+ if (currprefs.serial_crlf) {
+ if (serdatshift_masked == 10 && serial_send_previous != 13) {
+ if (!checkserwrite(2))
+ return;
+ writeser(13);
+ }
+ }
+ if (!checkserwrite(1))
+ return;
+ writeser(serdatshift_masked);
+ serial_send_previous = serdatshift_masked;
}
#endif
- if (sent) {
- data_in_sershift = 2;
- }
+ data_in_sershift = 2;
#if SERIALDEBUG > 2
- write_log(_T("SERIAL: send %04X (%c)\n"), serdatshift, dochar(serdatshift));
+ write_log(_T("SERIAL: send %04X (%c)\n"), serdatshift, dochar(serdatshift));
#endif
}
serial_check_irq();
checksend();
-
if (seriallog) {
gotlogwrite = true;
write_log(_T("%c"), dochar(serdatshift_masked));
serial_check_irq();
}
}
+ serdatr_last_got++;
if (serial_period_hsyncs == 0)
return;
serial_period_hsync_counter++;