|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Not a parser, but parallel and serial emulation for Win32 ! 5: * ! 6: * Copyright 1997 Mathias Ortmann ! 7: */ ! 8: ! 9: #ifdef __GNUC__ ! 10: #define __int64 long long ! 11: #include "machdep/winstuff.h" ! 12: #else ! 13: #include <windows.h> ! 14: #include <ddraw.h> ! 15: #include <stdlib.h> ! 16: #include <stdarg.h> ! 17: #include <commctrl.h> ! 18: #include <commdlg.h> ! 19: #include <stdio.h> ! 20: #include <fcntl.h> ! 21: #include <sys/stat.h> ! 22: #include <io.h> ! 23: #endif ! 24: ! 25: #include "config.h" ! 26: #include "sysconfig.h" ! 27: #include "sysdeps.h" ! 28: ! 29: #include "options.h" ! 30: #include "gensound.h" ! 31: #include "sounddep/sound.h" ! 32: #include "events.h" ! 33: #include "uae.h" ! 34: #include "include/memory.h" ! 35: #include "custom.h" ! 36: #include "osdep/win32gui.h" ! 37: #include "osdep/win32.h" ! 38: ! 39: #define PRTBUFSIZE 1024 ! 40: UINT prttimer; ! 41: char prtbuf[PRTBUFSIZE]; ! 42: int prtbufbytes; ! 43: HANDLE hPrt = INVALID_HANDLE_VALUE; ! 44: extern HWND hAmigaWnd; ! 45: ! 46: void flushprtbuf (void) ! 47: { ! 48: DWORD written; ! 49: ! 50: if (hPrt == INVALID_HANDLE_VALUE) ! 51: hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); ! 52: if (hPrt == INVALID_HANDLE_VALUE) ! 53: hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); ! 54: ! 55: if (hPrt != INVALID_HANDLE_VALUE) ! 56: WriteFile (hPrt, prtbuf, prtbufbytes, &written, 0); ! 57: ! 58: prtbufbytes = 0; ! 59: } ! 60: ! 61: void finishjob (void) ! 62: { ! 63: flushprtbuf (); ! 64: if (hPrt != INVALID_HANDLE_VALUE) { ! 65: CloseHandle (hPrt); ! 66: hPrt = INVALID_HANDLE_VALUE; ! 67: } ! 68: KillTimer (hAmigaWnd, prttimer); ! 69: prttimer = 0; ! 70: } ! 71: ! 72: void putprinter (char val) ! 73: { ! 74: PostMessage (hAmigaWnd, WM_USER + 0x200, val, 0); ! 75: } ! 76: ! 77: void DoSomeWeirdPrintingStuff (WPARAM wParam) ! 78: { ! 79: if (prttimer) ! 80: KillTimer (hAmigaWnd, prttimer); ! 81: if (prtbufbytes < PRTBUFSIZE) { ! 82: prtbuf[prtbufbytes++] = wParam; ! 83: prttimer = SetTimer (hAmigaWnd, 1, 2000, NULL); ! 84: } else { ! 85: flushprtbuf (); ! 86: *prtbuf = wParam; ! 87: prtbufbytes = 1; ! 88: prttimer = 0; ! 89: } ! 90: } ! 91: ! 92: static HANDLE hCom = INVALID_HANDLE_VALUE; ! 93: static HANDLE writeevent; ! 94: static DCB dcb; ! 95: ! 96: char inbuf[1024], outbuf[1024]; ! 97: int inptr, inlast, outlast; ! 98: ! 99: int openser (char *sername) ! 100: { ! 101: char buf[32]; ! 102: COMMTIMEOUTS CommTimeOuts; ! 103: ! 104: sprintf (buf, "\\.\\\\%s", sername); ! 105: ! 106: if (!(writeevent = CreateEvent (NULL, TRUE, FALSE, NULL))) { ! 107: write_log ("Failed to create serial event!\n"); ! 108: return 0; ! 109: } ! 110: if ((hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE, ! 111: 0, ! 112: NULL, ! 113: OPEN_EXISTING, ! 114: FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, ! 115: NULL)) != INVALID_HANDLE_VALUE) { ! 116: SetCommMask (hCom, EV_RXFLAG); ! 117: SetupComm (hCom, 4096, 4096); ! 118: PurgeComm (hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); ! 119: CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; ! 120: CommTimeOuts.ReadTotalTimeoutMultiplier = 0; ! 121: CommTimeOuts.ReadTotalTimeoutConstant = 0; ! 122: CommTimeOuts.WriteTotalTimeoutMultiplier = 0; ! 123: CommTimeOuts.WriteTotalTimeoutConstant = 0; ! 124: SetCommTimeouts (hCom, &CommTimeOuts); ! 125: ! 126: GetCommState (hCom, &dcb); ! 127: ! 128: dcb.BaudRate = 9600; ! 129: dcb.ByteSize = 8; ! 130: dcb.Parity = 0; ! 131: dcb.StopBits = NOPARITY; ! 132: ! 133: dcb.fOutxCtsFlow = TRUE; ! 134: dcb.fOutxDsrFlow = FALSE; ! 135: dcb.fDtrControl = DTR_CONTROL_ENABLE; ! 136: dcb.fTXContinueOnXoff = FALSE; ! 137: dcb.fOutX = FALSE; ! 138: dcb.fInX = FALSE; ! 139: dcb.fNull = FALSE; ! 140: dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; ! 141: dcb.fAbortOnError = FALSE; ! 142: ! 143: if (SetCommState (hCom, &dcb)) { ! 144: MyOutputDebugString ("Using %s\n", sername); ! 145: return 1; ! 146: } ! 147: CloseHandle (hCom); ! 148: hCom = INVALID_HANDLE_VALUE; ! 149: } ! 150: return 0; ! 151: } ! 152: ! 153: void closeser (void) ! 154: { ! 155: if (hCom != INVALID_HANDLE_VALUE) { ! 156: CloseHandle (hCom); ! 157: hCom = INVALID_HANDLE_VALUE; ! 158: } ! 159: } ! 160: ! 161: void doserout (void) ! 162: { ! 163: DWORD dwErrorFlags; ! 164: unsigned long actual; ! 165: OVERLAPPED ol = ! 166: {0}; ! 167: ! 168: if (hCom != INVALID_HANDLE_VALUE) { ! 169: if (outlast) { ! 170: ResetEvent (ol.hEvent = writeevent); ! 171: ! 172: actual = 0; ! 173: if (!WriteFile (hCom, outbuf, outlast, &actual, &ol)) { ! 174: while (outlast -= actual) { ! 175: if ((dwErrorFlags = GetLastError ()) == ERROR_IO_INCOMPLETE || dwErrorFlags == ERROR_IO_PENDING) { ! 176: actual = 0; ! 177: GetOverlappedResult (hCom, &ol, &actual, FALSE); ! 178: ! 179: if ((dwErrorFlags = GetLastError ()) != ERROR_IO_INCOMPLETE && dwErrorFlags != ERROR_IO_PENDING) { ! 180: MyOutputDebugString ("writeser: error %d, lost %d chars!\n", GetLastError (), outlast - actual); ! 181: outlast = 0; ! 182: break; ! 183: } ! 184: if (WaitForSingleObject (writeevent, 1000) == WAIT_TIMEOUT) { ! 185: MyOutputDebugString ("writeser: timeout, lost %d chars!\n", outlast - actual); ! 186: outlast = 0; ! 187: break; ! 188: } ! 189: } else { ! 190: if (dwErrorFlags) { ! 191: MyOutputDebugString ("writeser: error %d while writing, lost %d chars!\n", dwErrorFlags, outlast - actual); ! 192: ClearCommError (hCom, &dwErrorFlags, NULL); ! 193: } ! 194: outlast = 0; ! 195: break; ! 196: } ! 197: } ! 198: } ! 199: } ! 200: } else { ! 201: outlast = 0; ! 202: inptr = inlast = 0; ! 203: } ! 204: } ! 205: ! 206: void writeser (char c) ! 207: { ! 208: outbuf[outlast++] = c; ! 209: if (outlast == sizeof outbuf) ! 210: doserout (); ! 211: } ! 212: ! 213: int readser (char *buffer) ! 214: { ! 215: COMSTAT ComStat; ! 216: DWORD dwErrorFlags; ! 217: DWORD result; ! 218: unsigned long actual; ! 219: OVERLAPPED ol = ! 220: {0}; ! 221: ! 222: if (inptr < inlast) { ! 223: *buffer = inbuf[inptr++]; ! 224: return 1; ! 225: } ! 226: if (hCom != INVALID_HANDLE_VALUE) { ! 227: inptr = inlast = 0; ! 228: ! 229: /* only try to read number of bytes in queue */ ! 230: ClearCommError (hCom, &dwErrorFlags, &ComStat); ! 231: if (ComStat.cbInQue) { ! 232: if (!ReadFile (hCom, inbuf, min (ComStat.cbInQue, sizeof inbuf), &inlast, &ol)) { ! 233: if (GetLastError () == ERROR_IO_PENDING) { ! 234: write_log ("readser: INTERNAL ERROR - intermittent loss of serial data!\n"); ! 235: for (;;) { ! 236: actual = 0; ! 237: result = GetOverlappedResult (hCom, &ol, &actual, TRUE); ! 238: inlast += actual; ! 239: ! 240: if (result) ! 241: break; ! 242: ! 243: if (GetLastError () != ERROR_IO_INCOMPLETE) { ! 244: ClearCommError (hCom, &dwErrorFlags, &ComStat); ! 245: break; ! 246: } ! 247: } ! 248: } else ! 249: ClearCommError (hCom, &dwErrorFlags, &ComStat); ! 250: } ! 251: } ! 252: if (inptr < inlast) { ! 253: *buffer = inbuf[inptr++]; ! 254: return 1; ! 255: } ! 256: } ! 257: return 0; ! 258: } ! 259: ! 260: void getserstat (int *status) ! 261: { ! 262: DWORD stat; ! 263: ! 264: *status = 0; ! 265: ! 266: if (hCom != INVALID_HANDLE_VALUE) { ! 267: GetCommModemStatus (hCom, &stat); ! 268: #if 0 ! 269: /* ouch */ ! 270: if (stat & MS_RLSD_ON) ! 271: *status |= TIOCM_CAR; ! 272: if (stat & MS_DSR_ON) ! 273: *status |= TIOCM_DSR; ! 274: #endif ! 275: } ! 276: } ! 277: ! 278: int setbaud (long baud) ! 279: { ! 280: if (hCom != INVALID_HANDLE_VALUE) { ! 281: if (GetCommState (hCom, &dcb)) { ! 282: dcb.BaudRate = baud; ! 283: if (!SetCommState (hCom, &dcb)) ! 284: MyOutputDebugString ("Error setting baud rate %d!\n", baud); ! 285: } else ! 286: write_log ("setbaud: internal error!\n"); ! 287: } ! 288: return 0; ! 289: } ! 290:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.