|
|
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.