From: Toni Wilen Date: Sat, 2 May 2015 16:18:32 +0000 (+0300) Subject: Serial port update, telnet cr/lf translation. X-Git-Tag: 3100~43 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=2e09d3961b07fe30caa126abbf3cc4ed46a7cef2;p=francis%2Fwinuae.git Serial port update, telnet cr/lf translation. --- diff --git a/od-win32/parser.cpp b/od-win32/parser.cpp index 8e87bcfe..3fcf3f4a 100644 --- a/od-win32/parser.cpp +++ b/od-win32/parser.cpp @@ -860,7 +860,7 @@ static bool tcp_is_connected (void) 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; @@ -1092,7 +1092,7 @@ void closeser (void) 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; @@ -1125,7 +1125,7 @@ void writeser (int c) } } -int checkserwrite (void) +int checkserwrite (int spaceneeded) { if (hCom == INVALID_HANDLE_VALUE || !currprefs.use_serial) return 1; @@ -1133,7 +1133,7 @@ int checkserwrite (void) return 1; } else { outser (); - if (datainoutput >= sizeof (outputbuffer) - 1) + if (datainoutput + spaceneeded >= sizeof (outputbuffer)) return 0; } return 1; @@ -1191,6 +1191,7 @@ int readser (int *buffer) int err = recv (serialconn, buf, 1, 0); if (err == 1) { *buffer = buf[0]; + //write_log(_T(" %02X "), buf[0]); return 1; } else { tcp_disconnect (); @@ -1386,77 +1387,90 @@ void hsyncstuff (void) 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; } diff --git a/od-win32/serial_win32.cpp b/od-win32/serial_win32.cpp index c5fce8aa..b7e90a79 100644 --- a/od-win32/serial_win32.cpp +++ b/od-win32/serial_win32.cpp @@ -155,6 +155,7 @@ bool shmem_serial_create(void) #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 */ @@ -168,6 +169,8 @@ static int ninebit; 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; @@ -233,6 +236,8 @@ void SERPER (uae_u16 w) baud = 115200; serial_period_hsyncs = 1; } + serial_recv_previous = -1; + serial_send_previous = -1; #ifdef SERIAL_PORT setbaud (baud); #endif @@ -248,11 +253,22 @@ static TCHAR dochar (int v) 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)) @@ -263,6 +279,7 @@ static void checkreceive_enet (void) 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)); @@ -276,10 +293,12 @@ static void checkreceive_serial (void) static int ninebitdata; int recdata; - if (!readseravail()) + if (!canreceive()) return; if (ninebit) { + if (!readseravail()) + return; for (;;) { if (!readser (&recdata)) return; @@ -300,12 +319,25 @@ static void checkreceive_serial (void) } } } 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)); @@ -318,8 +350,6 @@ static void serdatcopy(void); static void checksend(void) { - bool sent = true; - if (data_in_sershift != 1) return; @@ -331,20 +361,28 @@ static void checksend(void) } #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 } @@ -379,7 +417,6 @@ static void serdatcopy(void) serial_check_irq(); checksend(); - if (seriallog) { gotlogwrite = true; write_log(_T("%c"), dochar(serdatshift_masked)); @@ -445,6 +482,7 @@ void serial_hsynchandler (void) serial_check_irq(); } } + serdatr_last_got++; if (serial_period_hsyncs == 0) return; serial_period_hsync_counter++;