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