--- uae/src/od-win32/parser.c 2018/04/24 16:40:31 1.1 +++ uae/src/od-win32/parser.c 2018/04/24 17:17:37 1.1.1.4 @@ -1,290 +1,467 @@ -/* - * UAE - The Un*x Amiga Emulator - * - * Not a parser, but parallel and serial emulation for Win32 - * - * Copyright 1997 Mathias Ortmann - */ - -#ifdef __GNUC__ -#define __int64 long long -#include "machdep/winstuff.h" -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include "config.h" -#include "sysconfig.h" -#include "sysdeps.h" - -#include "options.h" -#include "gensound.h" -#include "sounddep/sound.h" -#include "events.h" -#include "uae.h" -#include "include/memory.h" -#include "custom.h" -#include "osdep/win32gui.h" -#include "osdep/win32.h" - -#define PRTBUFSIZE 1024 -UINT prttimer; -char prtbuf[PRTBUFSIZE]; -int prtbufbytes; -HANDLE hPrt = INVALID_HANDLE_VALUE; -extern HWND hAmigaWnd; - -void flushprtbuf (void) -{ - DWORD written; - - if (hPrt == INVALID_HANDLE_VALUE) - hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); - if (hPrt == INVALID_HANDLE_VALUE) - hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - - if (hPrt != INVALID_HANDLE_VALUE) - WriteFile (hPrt, prtbuf, prtbufbytes, &written, 0); - - prtbufbytes = 0; -} - -void finishjob (void) -{ - flushprtbuf (); - if (hPrt != INVALID_HANDLE_VALUE) { - CloseHandle (hPrt); - hPrt = INVALID_HANDLE_VALUE; - } - KillTimer (hAmigaWnd, prttimer); - prttimer = 0; -} - -void putprinter (char val) -{ - PostMessage (hAmigaWnd, WM_USER + 0x200, val, 0); -} - -void DoSomeWeirdPrintingStuff (WPARAM wParam) -{ - if (prttimer) - KillTimer (hAmigaWnd, prttimer); - if (prtbufbytes < PRTBUFSIZE) { - prtbuf[prtbufbytes++] = wParam; - prttimer = SetTimer (hAmigaWnd, 1, 2000, NULL); - } else { - flushprtbuf (); - *prtbuf = wParam; - prtbufbytes = 1; - prttimer = 0; - } -} - -static HANDLE hCom = INVALID_HANDLE_VALUE; -static HANDLE writeevent; -static DCB dcb; - -char inbuf[1024], outbuf[1024]; -int inptr, inlast, outlast; - -int openser (char *sername) -{ - char buf[32]; - COMMTIMEOUTS CommTimeOuts; - - sprintf (buf, "\\.\\\\%s", sername); - - if (!(writeevent = CreateEvent (NULL, TRUE, FALSE, NULL))) { - write_log ("Failed to create serial event!\n"); - return 0; - } - if ((hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, - NULL)) != INVALID_HANDLE_VALUE) { - SetCommMask (hCom, EV_RXFLAG); - SetupComm (hCom, 4096, 4096); - PurgeComm (hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); - CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; - CommTimeOuts.ReadTotalTimeoutMultiplier = 0; - CommTimeOuts.ReadTotalTimeoutConstant = 0; - CommTimeOuts.WriteTotalTimeoutMultiplier = 0; - CommTimeOuts.WriteTotalTimeoutConstant = 0; - SetCommTimeouts (hCom, &CommTimeOuts); - - GetCommState (hCom, &dcb); - - dcb.BaudRate = 9600; - dcb.ByteSize = 8; - dcb.Parity = 0; - dcb.StopBits = NOPARITY; - - dcb.fOutxCtsFlow = TRUE; - dcb.fOutxDsrFlow = FALSE; - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fTXContinueOnXoff = FALSE; - dcb.fOutX = FALSE; - dcb.fInX = FALSE; - dcb.fNull = FALSE; - dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - dcb.fAbortOnError = FALSE; - - if (SetCommState (hCom, &dcb)) { - MyOutputDebugString ("Using %s\n", sername); - return 1; - } - CloseHandle (hCom); - hCom = INVALID_HANDLE_VALUE; - } - return 0; -} - -void closeser (void) -{ - if (hCom != INVALID_HANDLE_VALUE) { - CloseHandle (hCom); - hCom = INVALID_HANDLE_VALUE; - } -} - -void doserout (void) -{ - DWORD dwErrorFlags; - unsigned long actual; - OVERLAPPED ol = - {0}; - - if (hCom != INVALID_HANDLE_VALUE) { - if (outlast) { - ResetEvent (ol.hEvent = writeevent); - - actual = 0; - if (!WriteFile (hCom, outbuf, outlast, &actual, &ol)) { - while (outlast -= actual) { - if ((dwErrorFlags = GetLastError ()) == ERROR_IO_INCOMPLETE || dwErrorFlags == ERROR_IO_PENDING) { - actual = 0; - GetOverlappedResult (hCom, &ol, &actual, FALSE); - - if ((dwErrorFlags = GetLastError ()) != ERROR_IO_INCOMPLETE && dwErrorFlags != ERROR_IO_PENDING) { - MyOutputDebugString ("writeser: error %d, lost %d chars!\n", GetLastError (), outlast - actual); - outlast = 0; - break; - } - if (WaitForSingleObject (writeevent, 1000) == WAIT_TIMEOUT) { - MyOutputDebugString ("writeser: timeout, lost %d chars!\n", outlast - actual); - outlast = 0; - break; - } - } else { - if (dwErrorFlags) { - MyOutputDebugString ("writeser: error %d while writing, lost %d chars!\n", dwErrorFlags, outlast - actual); - ClearCommError (hCom, &dwErrorFlags, NULL); - } - outlast = 0; - break; - } - } - } - } - } else { - outlast = 0; - inptr = inlast = 0; - } -} - -void writeser (char c) -{ - outbuf[outlast++] = c; - if (outlast == sizeof outbuf) - doserout (); -} - -int readser (char *buffer) -{ - COMSTAT ComStat; - DWORD dwErrorFlags; - DWORD result; - unsigned long actual; - OVERLAPPED ol = - {0}; - - if (inptr < inlast) { - *buffer = inbuf[inptr++]; - return 1; - } - if (hCom != INVALID_HANDLE_VALUE) { - inptr = inlast = 0; - - /* only try to read number of bytes in queue */ - ClearCommError (hCom, &dwErrorFlags, &ComStat); - if (ComStat.cbInQue) { - if (!ReadFile (hCom, inbuf, min (ComStat.cbInQue, sizeof inbuf), &inlast, &ol)) { - if (GetLastError () == ERROR_IO_PENDING) { - write_log ("readser: INTERNAL ERROR - intermittent loss of serial data!\n"); - for (;;) { - actual = 0; - result = GetOverlappedResult (hCom, &ol, &actual, TRUE); - inlast += actual; - - if (result) - break; - - if (GetLastError () != ERROR_IO_INCOMPLETE) { - ClearCommError (hCom, &dwErrorFlags, &ComStat); - break; - } - } - } else - ClearCommError (hCom, &dwErrorFlags, &ComStat); - } - } - if (inptr < inlast) { - *buffer = inbuf[inptr++]; - return 1; - } - } - return 0; -} - -void getserstat (int *status) -{ - DWORD stat; - - *status = 0; - - if (hCom != INVALID_HANDLE_VALUE) { - GetCommModemStatus (hCom, &stat); -#if 0 - /* ouch */ - if (stat & MS_RLSD_ON) - *status |= TIOCM_CAR; - if (stat & MS_DSR_ON) - *status |= TIOCM_DSR; -#endif - } -} - -int setbaud (long baud) -{ - if (hCom != INVALID_HANDLE_VALUE) { - if (GetCommState (hCom, &dcb)) { - dcb.BaudRate = baud; - if (!SetCommState (hCom, &dcb)) - MyOutputDebugString ("Error setting baud rate %d!\n", baud); - } else - write_log ("setbaud: internal error!\n"); - } - return 0; -} - +/* + * UAE - The Un*x Amiga Emulator + * + * Not a parser, but parallel and serial emulation for Win32 + * + * Copyright 1997 Mathias Ortmann + * Copyright 1998-1999 Brian King - added MIDI output support + */ + +#include "sysconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysdeps.h" +#include "options.h" +#include "gensound.h" +#include "events.h" +#include "uae.h" +#include "memory.h" +#include "custom.h" +#include "osdep/win32gui.h" +#include "osdep/parser.h" +#include "osdep/midi.h" + +UINT prttimer; +char prtbuf[PRTBUFSIZE]; +int prtbufbytes,wantwrite; +HANDLE hPrt = INVALID_HANDLE_VALUE; +DWORD dwJob; +extern HWND hAmigaWnd; + OVERLAPPED ol = { 0 }; + +void flushprtbuf (void) +{ + DWORD written = 0; + + if (hPrt != INVALID_HANDLE_VALUE) + { + if( WritePrinter( hPrt, prtbuf, prtbufbytes, &written ) ) + { + if( written != prtbufbytes ) + write_log( "PRINTER: Only wrote %d of %d bytes!\n", written, prtbufbytes ); + } + else + { + write_log( "PRINTER: Couldn't write data!\n" ); + } + } + else + { + write_log( "PRINTER: Not open!\n" ); + } + prtbufbytes = 0; +} + +void finishjob (void) +{ + flushprtbuf (); +} + +void DoSomeWeirdPrintingStuff( char val ) +{ + if (prttimer) + KillTimer (hAmigaWnd, prttimer); + if (prtbufbytes < PRTBUFSIZE) { + prtbuf[prtbufbytes++] = val; + prttimer = SetTimer (hAmigaWnd, 1, 2000, NULL); + } else { + flushprtbuf (); + *prtbuf = val; + prtbufbytes = 1; + prttimer = 0; + } +} + +FILE *openprinter( void ) +{ + FILE *result = NULL; + DOC_INFO_1 DocInfo; + + if( ( hPrt == INVALID_HANDLE_VALUE ) && *currprefs.prtname ) + { + if( OpenPrinter(currprefs.prtname, &hPrt, NULL ) ) + { + // Fill in the structure with info about this "document." + DocInfo.pDocName = "My Document"; + DocInfo.pOutputFile = NULL; + DocInfo.pDatatype = "RAW"; + // Inform the spooler the document is beginning. + if( (dwJob = StartDocPrinter( hPrt, 1, (LPSTR)&DocInfo )) == 0 ) + { + ClosePrinter( hPrt ); + hPrt = INVALID_HANDLE_VALUE; + } + else if( StartPagePrinter( hPrt ) ) + { + result = 1; + } + } + else + { + hPrt = INVALID_HANDLE_VALUE; // Stupid bug in Win32, where OpenPrinter fails, but hPrt ends up being zero + } + } + if( hPrt != INVALID_HANDLE_VALUE ) + { + write_log( "PRINTER: Opening printer \"%s\" with handle 0x%x.\n", currprefs.prtname, hPrt ); + } + else if( *currprefs.prtname ) + { + write_log( "PRINTER: ERROR - Couldn't open printer \"%s\" for output.\n", currprefs.prtname ); + } + + return result; +} + +void closeprinter( void ) +{ + if( hPrt != INVALID_HANDLE_VALUE ) + { + EndPagePrinter( hPrt ); + EndDocPrinter( hPrt ); + ClosePrinter( hPrt ); + hPrt = INVALID_HANDLE_VALUE; + write_log( "PRINTER: Closing printer.\n" ); + } + KillTimer( hAmigaWnd, prttimer ); + prttimer = 0; +} + +void putprinter (char val) +{ + DoSomeWeirdPrintingStuff( val ); +} + +static HANDLE hCom = INVALID_HANDLE_VALUE; +static HANDLE writeevent = NULL; +static DCB dcb; + +char inbuf[1024], outbuf[1024]; +int inptr, inlast, outlast; + +int openser (char *sername) +{ + char buf[32]; + COMMTIMEOUTS CommTimeOuts; + + sprintf (buf, "\\.\\\\%s", sername); + + if (!(writeevent = CreateEvent (NULL, TRUE, FALSE, NULL))) { + write_log ("SERIAL: Failed to create event!\n"); + return 0; + } + if ((hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL)) != INVALID_HANDLE_VALUE) { + SetCommMask (hCom, EV_RXFLAG); + SetupComm (hCom, 65536,128); + PurgeComm (hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; + CommTimeOuts.ReadTotalTimeoutMultiplier = 0; + CommTimeOuts.ReadTotalTimeoutConstant = 0; + CommTimeOuts.WriteTotalTimeoutMultiplier = 0; + CommTimeOuts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts (hCom, &CommTimeOuts); + + GetCommState (hCom, &dcb); + + dcb.BaudRate = 9600; + //dcb.ByteSize = 8; + //dcb.Parity = 0; + //dcb.StopBits = NOPARITY; + + //dcb.fOutxCtsFlow = TRUE; + //dcb.fOutxDsrFlow = FALSE; + //dcb.fDtrControl = DTR_CONTROL_ENABLE; + //dcb.fTXContinueOnXoff = FALSE; + //dcb.fOutX = FALSE; + //dcb.fInX = FALSE; + //dcb.fNull = FALSE; + //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + //dcb.fAbortOnError = FALSE; + + if (SetCommState (hCom, &dcb)) { + write_log ("SERIAL: Using %s\n", sername); + return 1; + } + CloseHandle (hCom); + hCom = INVALID_HANDLE_VALUE; + } + return 0; +} + +void closeser (void) +{ + if (hCom != INVALID_HANDLE_VALUE) + { + CloseHandle (hCom); + hCom = INVALID_HANDLE_VALUE; + } + if( writeevent ) + CloseHandle( writeevent ); +} + +void doserout( void ) +{ + DWORD dwErrorFlags; + unsigned long actual; + + if (hCom != INVALID_HANDLE_VALUE) + { + if (outlast) + { + ResetEvent (ol.hEvent = writeevent); + actual = 0; + + if (!WriteFile (hCom, outbuf, outlast, &actual, &ol)) + { + //GetOverlappedResult (hCom, &ol, &actual, FALSE); + + /* while (outlast -= actual) + { + if ((dwErrorFlags = GetLastError ()) == ERROR_IO_INCOMPLETE || dwErrorFlags == ERROR_IO_PENDING) + { + actual = 0; + GetOverlappedResult (hCom, &ol, &actual, FALSE); + + if ((dwErrorFlags = GetLastError ()) != ERROR_IO_INCOMPLETE && dwErrorFlags != ERROR_IO_PENDING) + { + write_log ("writeser: error %d, lost %d chars!\n", GetLastError (), outlast - actual); + outlast = 0; + break; + } + if (WaitForSingleObject (writeevent, 100) == WAIT_TIMEOUT) + { + write_log ("writeser: timeout, lost %d chars!\n", outlast - actual); + outlast = 0; + break; + } + } + else + { + if (dwErrorFlags) + { + write_log ("writeser: error %d while writing, lost %d chars!\n", dwErrorFlags, outlast - actual); + ClearCommError (hCom, &dwErrorFlags, NULL); + } + + outlast = 0; + break; + } + + } + */ + outlast=0; + } + } + } + else + { + outlast = 0; + inptr = inlast = 0; + } +} + +void writeser (char c) +{ + COMSTAT ComStat; + DWORD dwErrorFlags; + extern uae_u16 serdat; + { + outbuf[ outlast++ ] = c; +//serial + if (outlast == 100/*sizeof outbuf*/) + { + doserout(); + wantwrite=2000; + return; + } + } + serdat|=0x2000; /* Set TBE in the SERDATR ... */ + intreq|=1; /* ... and in INTREQ register */ + INTREQ( 0x8000 | 0x01 ); +} +int state,oldstatelw,oldstaterw; + +void hsyncstuff( void ) //only generate Interrupts when +//writebuffer is complete flushed +//check state of lwin rwin + +{ + static int keycheck=0; + extern uae_u16 serdat; + extern int serdev; + + keycheck++; + if(keycheck==1000) + { + state=GetAsyncKeyState(VK_LWIN); + + if (state!=oldstatelw){my_kbd_handler(VK_LWIN,0,state); + oldstatelw=state; + } + state=GetAsyncKeyState(VK_RWIN); + + if (state!=oldstaterw){my_kbd_handler(VK_RWIN,0,state); + oldstaterw=state; + } + keycheck=0; + } + + if (!serdev) /* || (serdat&0x4000)) */ + return; + + if(wantwrite) + { + int actual=0; + if(wantwrite==1) + { + serdat|=0x2000; + intreq|=0x1; + INTREQ(0x8000 | (0x01)); + wantwrite=0; + } + wantwrite--; + GetOverlappedResult (hCom, &ol, &actual, FALSE); + if (actual==100) + { serdat|=0x2000; + intreq|=0x1; + INTREQ(0x8000 | (0x01)); + wantwrite=0; + } + } +} + +int readser (char *buffer) +{ + COMSTAT ComStat; + DWORD dwErrorFlags; + DWORD result; + unsigned long actual; + + + { + + + // + //if(intreq&&1); + //else + /*if (WaitForSingleObject (writeevent,0) != WAIT_TIMEOUT) + { + serdat|=0x2000; + intreq|=0x1; + INTREQ(0x8000 | (0x01)); + ResetEvent (ol.hEvent = writeevent); + + } + else {INTREQ(0x1); + serdat &=0xdfff; + }*/ + if (inptr < inlast) + { + *buffer = inbuf[inptr++]; + return 1; + } + if (hCom != INVALID_HANDLE_VALUE) + { + inptr = inlast = 0; + + /* only try to read number of bytes in queue */ + ClearCommError (hCom, &dwErrorFlags, &ComStat); + if (ComStat.cbInQue) + { + + if (!ReadFile (hCom, inbuf, min (ComStat.cbInQue, sizeof inbuf), &inlast, &ol)) + { + if (GetLastError () == ERROR_IO_PENDING) + { + write_log ("readser: INTERNAL ERROR - intermittent loss of serial data!\n"); + for (;;) + { + actual = 0; + result = GetOverlappedResult (hCom, &ol, &actual, TRUE); + inlast += actual; + + if (result) + break; + + if (GetLastError () != ERROR_IO_INCOMPLETE) + { + ClearCommError (hCom, &dwErrorFlags, &ComStat); + break; + } + } + } + else + { + ClearCommError (hCom, &dwErrorFlags, &ComStat); + } + } + } + if (inptr < inlast) + { + *buffer = inbuf[inptr++]; + return 1; + } + } + } + return 0; +} + +void getserstat (int *status) +{ + DWORD stat; + + *status = 0; + if (hCom != INVALID_HANDLE_VALUE) { + //GetCommModemStatus (hCom, &stat); +/* @@@ This "ouch" section was #ifdef 0 before - BDK */ +#if 0 +#define TIOCM_CAR 1 +#define TIOCM_DSR 2 + /* ouch */ + if (stat & MS_CTS_ON) + *status |= TIOCM_CAR; + if (stat & MS_RLSD_ON) + *status |= TIOCM_CAR; + if (stat & MS_DSR_ON) + *status |= TIOCM_DSR; +#endif + } +} + +int setbaud (long baud) +{ + write_log( "Baud-rate is %d\n", baud ); + { + if (hCom != INVALID_HANDLE_VALUE) + { + if (GetCommState (hCom, &dcb)) + { + dcb.BaudRate = baud; + if (!SetCommState (hCom, &dcb)) + write_log ("SERIAL: Error setting baud rate %d!\n", baud); + } + else + { + write_log ("SERIAL: setbaud internal error!\n"); + } + } + } + return 0; +} +