|
|
1.1 root 1: /*
1.1.1.4 root 2: Hatari - rs232.c
1.1 root 3:
1.1.1.4 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
1.1 root 6:
1.1.1.4 root 7: RS-232 Communications
1.1.1.3 root 8:
1.1.1.4 root 9: This is similar to the printing functions, we open a direct file
10: (e.g. /dev/ttyS0) and send bytes over it.
11: Using such method mimicks the ST exactly, and even allows us to connect
12: to an actual ST! To wait for incoming data, we create a thread which copies
13: the bytes into an input buffer. This method fits in with the internet code
14: which also reads data into a buffer.
15: */
1.1.1.11! root 16: const char RS232_rcsid[] = "Hatari $Id: rs232.c,v 1.33 2008/06/16 19:22:37 thothy Exp $";
1.1.1.4 root 17:
1.1.1.9 root 18: #include <config.h>
1.1.1.4 root 19:
20: #if HAVE_TERMIOS_H
21: # include <termios.h>
22: # include <unistd.h>
23: #endif
24:
25: #include <SDL.h>
26: #include <SDL_thread.h>
27: #include <errno.h>
1.1.1.3 root 28:
1.1 root 29: #include "main.h"
1.1.1.4 root 30: #include "configuration.h"
1.1.1.10 root 31: #include "ioMem.h"
1.1.1.8 root 32: #include "m68000.h"
1.1.1.4 root 33: #include "mfp.h"
1.1 root 34: #include "rs232.h"
1.1.1.2 root 35:
1.1 root 36:
1.1.1.4 root 37: #define RS232_DEBUG 0
38:
39: #if RS232_DEBUG
40: #define Dprintf(a) printf a
41: #else
42: #define Dprintf(a)
43: #endif
44:
45:
1.1.1.11! root 46: bool bConnectedRS232 = FALSE; /* Connection to RS232? */
1.1.1.8 root 47: static FILE *hComIn = NULL; /* Handle to file for reading */
48: static FILE *hComOut = NULL; /* Handle to file for writing */
1.1.1.4 root 49:
1.1.1.8 root 50: static unsigned char InputBuffer_RS232[MAX_RS232INPUT_BUFFER];
51: static int InputBuffer_Head=0, InputBuffer_Tail=0;
1.1.1.4 root 52:
1.1.1.8 root 53:
54: #if HAVE_TERMIOS_H
55:
56: #if !HAVE_CFMAKERAW
1.1.1.4 root 57: static inline void cfmakeraw(struct termios *termios_p)
58: {
59: termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
60: termios_p->c_oflag &= ~OPOST;
61: termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
62: termios_p->c_cflag &= ~(CSIZE|PARENB);
63: termios_p->c_cflag |= CS8;
64: }
65: #endif
66:
1.1.1.9 root 67:
68: #if defined(__AMIGAOS4__)
69:
70: // dummy functions. REMOVE THEM LATER
71:
72: int tcgetattr(int file_descriptor,struct termios *tios_p)
73: {
74: return -1;
75: }
76:
77: int tcsetattr(int file_descriptor,int action,struct termios *tios_p)
78: {
79: return -1;
80: }
81:
82: int cfsetospeed(struct termios *tios, speed_t ospeed)
83: {
84:
85: tios->c_ospeed = ospeed;
86:
87: return 0;
88: }
89:
90:
91: int cfsetispeed(struct termios *tios,speed_t ispeed)
92: {
93: tios->c_ispeed = ispeed;
94:
95: return 0;
96: }
97:
98: #endif /* __AMIGAOS4__ */
99:
100:
1.1.1.4 root 101: /*-----------------------------------------------------------------------*/
1.1.1.9 root 102: /**
103: * Set serial line parameters to "raw" mode.
104: */
1.1.1.11! root 105: static bool RS232_SetRawMode(FILE *fhndl)
1.1 root 106: {
1.1.1.8 root 107: struct termios termmode;
108: int fd;
1.1 root 109:
1.1.1.8 root 110: memset (&termmode, 0, sizeof(termmode)); /* Init with zeroes */
111: fd = fileno(fhndl); /* Get file descriptor */
1.1.1.4 root 112:
1.1.1.8 root 113: if (isatty(fd))
1.1.1.4 root 114: {
1.1.1.8 root 115: if (tcgetattr(fd, &termmode) != 0)
116: return FALSE;
117:
118: /* Set "raw" mode: */
119: termmode.c_cc[VMIN] = 1;
120: termmode.c_cc[VTIME] = 0;
121: cfmakeraw(&termmode);
122: if (tcsetattr(fd, TCSADRAIN, &termmode) != 0)
123: return FALSE;
1.1.1.4 root 124: }
125:
1.1.1.8 root 126: return TRUE;
127: }
1.1.1.4 root 128:
129: /*-----------------------------------------------------------------------*/
1.1.1.9 root 130: /**
131: * Set hardware configuration of RS-232:
132: * - Bits per character
133: * - Parity
134: * - Start/stop bits
135: */
1.1.1.11! root 136: static bool RS232_SetBitsConfig(int fd, int nCharSize, int nStopBits, bool bUseParity, bool bEvenParity)
1.1.1.4 root 137: {
138: struct termios termmode;
139:
140: memset (&termmode, 0, sizeof(termmode)); /* Init with zeroes */
141:
142: if (isatty(fd))
143: {
144: if (tcgetattr(fd, &termmode) != 0)
1.1.1.8 root 145: {
146: Dprintf(("RS232_SetBitsConfig: tcgetattr failed.\n"));
1.1.1.4 root 147: return FALSE;
1.1.1.8 root 148: }
1.1.1.4 root 149:
1.1.1.8 root 150: /* Set the character size: */
151: termmode.c_cflag &= ~CSIZE;
152: switch (nCharSize)
153: {
154: case 8: termmode.c_cflag |= CS8; break;
155: case 7: termmode.c_cflag |= CS7; break;
156: case 6: termmode.c_cflag |= CS6; break;
157: case 5: termmode.c_cflag |= CS5; break;
158: }
159:
160: /* Set stop bits: */
161: if (nStopBits >= 2)
162: termmode.c_oflag |= CSTOPB;
163: else
164: termmode.c_oflag &= ~CSTOPB;
165:
166: /* Parity bit: */
167: if (bUseParity)
168: termmode.c_cflag |= PARENB;
169: else
170: termmode.c_cflag &= ~PARENB;
171:
172: if (bEvenParity)
173: termmode.c_cflag &= ~PARODD;
174: else
175: termmode.c_cflag |= PARODD;
176:
177: /* Now store the configuration: */
1.1.1.4 root 178: if (tcsetattr(fd, TCSADRAIN, &termmode) != 0)
1.1.1.8 root 179: {
180: Dprintf(("RS232_SetBitsConfig: tcsetattr failed.\n"));
1.1.1.4 root 181: return FALSE;
1.1.1.8 root 182: }
1.1.1.4 root 183: }
184:
185: return TRUE;
1.1 root 186: }
1.1.1.8 root 187:
1.1.1.4 root 188: #endif /* HAVE_TERMIOS_H */
1.1 root 189:
1.1.1.4 root 190:
191: /*-----------------------------------------------------------------------*/
1.1.1.9 root 192: /**
193: * Open file on COM port.
194: */
1.1.1.11! root 195: static bool RS232_OpenCOMPort(void)
1.1 root 196: {
1.1.1.4 root 197: bConnectedRS232 = FALSE;
1.1.1.3 root 198:
1.1.1.4 root 199: /* Create our COM file for output */
1.1.1.9 root 200: hComOut = fopen(ConfigureParams.RS232.szOutFileName, "wb");
1.1.1.4 root 201: if (hComOut == NULL)
202: {
203: Dprintf(("RS232: Failed to open output file %s\n",
204: ConfigureParams.RS232.szOutFileName));
205: return FALSE;
206: }
207: setvbuf(hComOut, NULL, _IONBF, 0);
208:
209: /* Create our COM file for input */
1.1.1.9 root 210: hComIn = fopen(ConfigureParams.RS232.szInFileName, "rb");
1.1.1.4 root 211: if (hComIn == NULL)
212: {
213: Dprintf(("RS232: Failed to open input file %s\n",
214: ConfigureParams.RS232.szInFileName));
215: fclose(hComOut); hComOut = NULL;
216: return FALSE;
217: }
218: setvbuf(hComIn, NULL, _IONBF, 0);
219:
220: #if HAVE_TERMIOS_H
221: /* First set the output parameters to "raw" mode */
222: if (!RS232_SetRawMode(hComOut))
223: {
224: fprintf(stderr, "Can't set raw mode for %s\n",
225: ConfigureParams.RS232.szOutFileName);
226: }
227:
228: /* Now set the input parameters to "raw" mode */
229: if (!RS232_SetRawMode(hComIn))
230: {
231: fprintf(stderr, "Can't set raw mode for %s\n",
232: ConfigureParams.RS232.szInFileName);
233: }
234: #endif
1.1 root 235:
1.1.1.4 root 236: /* Set all OK */
237: bConnectedRS232 = TRUE;
1.1 root 238:
1.1.1.4 root 239: Dprintf(("Successfully opened RS232 files.\n"));
1.1 root 240:
1.1.1.4 root 241: return TRUE;
1.1 root 242: }
243:
1.1.1.4 root 244:
245: /*-----------------------------------------------------------------------*/
1.1.1.9 root 246: /**
247: * Close file on COM port
248: */
1.1.1.8 root 249: static void RS232_CloseCOMPort(void)
1.1 root 250: {
1.1.1.4 root 251: /* Do have file open? */
252: if (bConnectedRS232)
253: {
254: bConnectedRS232 = FALSE;
255:
256: /* Close */
257: fclose(hComIn);
258: hComIn = NULL;
1.1 root 259:
1.1.1.4 root 260: fclose(hComOut);
261: hComOut = NULL;
262:
263: Dprintf(("Closed RS232 files.\n"));
264: }
1.1 root 265: }
266:
1.1.1.4 root 267:
1.1.1.8 root 268: /* thread stuff */
269: static SDL_sem* pSemFreeBuf; /* Semaphore to sync free space in InputBuffer_RS232 */
270: static SDL_Thread *RS232Thread = NULL; /* Thread handle for reading incoming data */
271:
272:
1.1.1.4 root 273: /*-----------------------------------------------------------------------*/
1.1.1.9 root 274: /**
275: * Add incoming bytes from other machine into our input buffer
276: */
1.1.1.8 root 277: static void RS232_AddBytesToInputBuffer(unsigned char *pBytes, int nBytes)
1.1.1.4 root 278: {
1.1.1.8 root 279: int i;
1.1 root 280:
1.1.1.8 root 281: /* Copy bytes into input buffer */
282: for (i=0; i<nBytes; i++)
283: {
284: SDL_SemWait(pSemFreeBuf); /* Wait for free space in buffer */
285: InputBuffer_RS232[InputBuffer_Tail] = *pBytes++;
286: InputBuffer_Tail = (InputBuffer_Tail+1) % MAX_RS232INPUT_BUFFER;
287: }
288: }
1.1.1.4 root 289:
1.1.1.8 root 290:
291: /*-----------------------------------------------------------------------*/
1.1.1.9 root 292: /**
293: * Thread to read incoming RS-232 data, and pass to emulator input buffer
294: */
1.1.1.8 root 295: static int RS232_ThreadFunc(void *pData)
296: {
297: int iInChar;
298: unsigned char cInChar;
299:
300: /* Check for any RS-232 incoming data */
301: while (TRUE)
1.1.1.4 root 302: {
1.1.1.8 root 303: if (hComIn)
1.1.1.4 root 304: {
1.1.1.8 root 305: /* Read the bytes in, if we have any */
306: iInChar = fgetc(hComIn);
307: if (iInChar != EOF)
308: {
309: /* Copy into our internal queue */
310: cInChar = iInChar;
311: RS232_AddBytesToInputBuffer(&cInChar, 1);
312: /* FIXME: Use semaphores to lock MFP variables? */
313: MFP_InputOnChannel(MFP_RCVBUFFULL_BIT, MFP_IERA, &MFP_IPRA);
314: Dprintf(("RS232: Read character $%x\n", iInChar));
315: }
316: else
317: {
318: /*Dprintf(("RS232: Reached end of input file!\n"));*/
319: clearerr(hComIn);
320: SDL_Delay(20);
321: }
1.1.1.4 root 322:
1.1.1.8 root 323: /* Sleep for a while */
324: SDL_Delay(2);
325: }
326: else
1.1.1.4 root 327: {
1.1.1.8 root 328: /* No RS-232 connection, sleep for 20ms */
329: SDL_Delay(20);
1.1.1.4 root 330: }
1.1.1.8 root 331: }
1.1.1.4 root 332:
1.1.1.8 root 333: return(TRUE);
334: }
1.1.1.4 root 335:
336:
1.1.1.8 root 337: /*-----------------------------------------------------------------------*/
1.1.1.9 root 338: /**
339: * Initialize RS-232, start thread to wait for incoming data
340: * (we will open a connection when first bytes are sent).
341: */
1.1.1.8 root 342: void RS232_Init(void)
343: {
344: if (ConfigureParams.RS232.bEnableRS232)
345: {
346: /* Create semaphore */
347: if (pSemFreeBuf == NULL)
348: pSemFreeBuf = SDL_CreateSemaphore(MAX_RS232INPUT_BUFFER);
349: if (pSemFreeBuf == NULL)
350: {
351: fprintf(stderr, "RS232_Init: Can't create semaphore!\n");
352: return;
353: }
1.1.1.4 root 354:
1.1.1.8 root 355: if (!bConnectedRS232)
356: RS232_OpenCOMPort();
357:
358: /* Create thread to wait for incoming bytes over RS-232 */
359: if (!RS232Thread)
1.1.1.4 root 360: {
1.1.1.8 root 361: RS232Thread = SDL_CreateThread(RS232_ThreadFunc, NULL);
362: Dprintf(("RS232 thread has been created.\n"));
1.1.1.4 root 363: }
364: }
1.1.1.8 root 365: }
1.1.1.4 root 366:
1.1.1.8 root 367:
368: /*-----------------------------------------------------------------------*/
1.1.1.9 root 369: /**
370: * Close RS-232 connection and stop checking for incoming data.
371: */
1.1.1.8 root 372: void RS232_UnInit(void)
373: {
374: /* Close, kill thread and free resource */
375: if (RS232Thread)
376: {
377: /* Instead of killing the thread directly, we should probably better
378: inform it via IPC so that it can terminate gracefully... */
379: Dprintf(("Killing RS232 thread...\n"));
380: SDL_KillThread(RS232Thread);
381: RS232Thread = NULL;
382: }
383: RS232_CloseCOMPort();
1.1.1.9 root 384:
1.1.1.8 root 385: if (pSemFreeBuf)
386: {
387: SDL_DestroySemaphore(pSemFreeBuf);
388: pSemFreeBuf = NULL;
389: }
1.1.1.4 root 390: }
1.1 root 391:
1.1.1.4 root 392:
393: /*-----------------------------------------------------------------------*/
1.1.1.9 root 394: /**
395: * Set hardware configuration of RS-232 according to the USART control register.
396: *
397: * ucr: USART Control Register
398: * Bit 0: unused
399: * Bit 1: 0-Odd Parity, 1-Even Parity
400: * Bit 2: 0-No Parity, 1-Parity
401: * Bits 3,4: Start/Stop bits
402: * 0 0 : 0-Start, 0-Stop Synchronous
403: * 0 1 : 0-Start, 1-Stop Asynchronous
404: * 1 0 : 1-Start, 1.5-Stop Asynchronous
405: * 1 1 : 1-Start, 2-Stop Asynchronous
406: * Bits 5,6: 'WordLength'
407: * 0 0 : 8 Bits
408: * 0 1 : 7 Bits
409: * 1 0 : 6 Bits
410: * 1 1 : 5 Bits
411: * Bit 7: Frequency from TC and RC
412: */
1.1.1.4 root 413: void RS232_HandleUCR(short int ucr)
414: {
415: #if HAVE_TERMIOS_H
416: int nCharSize; /* Bits per character: 5, 6, 7 or 8 */
417: int nStopBits; /* Stop bits: 0=0 bits, 1=1 bit, 2=1.5 bits, 3=2 bits */
418:
419: nCharSize = 8 - ((ucr >> 5) & 3);
420: nStopBits = (ucr >> 3) & 3;
421:
422: Dprintf(("RS232_HandleUCR(%i) : character size=%i , stop bits=%i\n",
423: ucr, nCharSize, nStopBits));
424:
425: if (hComOut != NULL)
426: {
427: if (!RS232_SetBitsConfig(fileno(hComOut), nCharSize, nStopBits, ucr&4, ucr&2))
428: fprintf(stderr, "Failed to set bits configuration for hComOut!\n");
429: }
430:
431: if (hComIn != NULL)
432: {
433: if (!RS232_SetBitsConfig(fileno(hComIn), nCharSize, nStopBits, ucr&4, ucr&2))
434: fprintf(stderr, "Failed to set bits configuration for hComIn!\n");
435: }
1.1.1.5 root 436: #endif /* HAVE_TERMIOS_H */
1.1.1.4 root 437: }
438:
439:
440: /*-----------------------------------------------------------------------*/
1.1.1.9 root 441: /**
442: * Set baud rate configuration of RS-232.
443: */
1.1.1.11! root 444: bool RS232_SetBaudRate(int nBaud)
1.1.1.4 root 445: {
446: #if HAVE_TERMIOS_H
447: int i;
448: int fd;
449: speed_t baudtype;
450: struct termios termmode;
1.1.1.8 root 451: static const int baudtable[][2] =
1.1.1.4 root 452: {
453: { 50, B50 },
454: { 75, B75 },
455: { 110, B110 },
456: { 134, B134 },
457: { 150, B150 },
458: { 200, B200 },
459: { 300, B300 },
460: { 600, B600 },
461: { 1200, B1200 },
462: { 1800, B1800 },
463: { 2400, B2400 },
464: { 4800, B4800 },
465: { 9600, B9600 },
466: { 19200, B19200 },
467: { 38400, B38400 },
468: { 57600, B57600 },
469: { 115200, B115200 },
1.1.1.8 root 470: #ifdef B230400 /* B230400 is not defined on all systems */
1.1.1.4 root 471: { 230400, B230400 },
1.1.1.8 root 472: #endif
1.1.1.4 root 473: { -1, -1 }
474: };
475:
476: Dprintf(("RS232_SetBaudRate(%i)\n", nBaud));
477:
478: /* Convert baud number to baud termios constant: */
479: baudtype = -1;
480: for (i = 0; baudtable[i][0] != -1; i++)
481: {
482: if (baudtable[i][0] == nBaud)
483: {
484: baudtype = baudtable[i][1];
485: break;
486: }
487: }
488:
1.1.1.5 root 489: if (baudtype == (speed_t)-1)
1.1.1.4 root 490: {
491: Dprintf(("RS232_SetBaudRate: Unsupported baud rate %i.\n", nBaud));
492: return FALSE;
493: }
494:
495: /* Set ouput speed: */
496: if (hComOut != NULL)
497: {
498: memset (&termmode, 0, sizeof(termmode)); /* Init with zeroes */
499: fd = fileno(hComOut);
500: if (isatty(fd))
501: {
502: if (tcgetattr(fd, &termmode) != 0)
503: return FALSE;
504:
505: cfsetospeed(&termmode, baudtype);
506:
507: if (tcsetattr(fd, TCSADRAIN, &termmode) != 0)
508: return FALSE;
509: }
510: }
511:
512: /* Set input speed: */
513: if (hComIn != NULL)
514: {
515: memset (&termmode, 0, sizeof(termmode)); /* Init with zeroes */
516: fd = fileno(hComIn);
517: if (isatty(fd))
518: {
519: if (tcgetattr(fd, &termmode) != 0)
520: return FALSE;
521:
522: cfsetispeed(&termmode, baudtype);
523:
524: if (tcsetattr(fd, TCSADRAIN, &termmode) != 0)
525: return FALSE;
526: }
527: }
528: #endif /* HAVE_TERMIOS_H */
529:
530: return TRUE;
531: }
532:
533:
534: /*-----------------------------------------------------------------------*/
1.1.1.9 root 535: /**
536: * Set baud rate configuration of RS-232 according to the Timer-D hardware
537: * registers.
538: */
1.1.1.4 root 539: void RS232_SetBaudRateFromTimerD(void)
1.1 root 540: {
1.1.1.4 root 541: int nTimerD_CR, nTimerD_DR, nBaudRate;
542:
1.1.1.10 root 543: nTimerD_CR = IoMem[0xfffa1d] & 0x07;
544: nTimerD_DR = IoMem[0xfffa25];
1.1.1.4 root 545:
546: if (!nTimerD_CR)
547: return;
548:
549: /* Calculate baud rate: (MFP/Timer-D is supplied with 2.4576 MHz) */
550: nBaudRate = 2457600 / nTimerD_DR / 2;
1.1.1.11! root 551:
! 552: /*if (IoMem[0xfffa29] & 0x80)*/ /* We only support the by-16 prescaler */
! 553: nBaudRate /= 16;
! 554:
1.1.1.4 root 555: switch (nTimerD_CR)
556: {
557: case 1: nBaudRate /= 4; break;
558: case 2: nBaudRate /= 10; break;
559: case 3: nBaudRate /= 16; break;
560: case 4: nBaudRate /= 50; break;
561: case 5: nBaudRate /= 64; break;
562: case 6: nBaudRate /= 100; break;
563: case 7: nBaudRate /= 200; break;
564: }
565:
566: /* Adjust some ugly baud rates from TOS to more reasonable values: */
567: switch (nBaudRate)
568: {
569: case 80: nBaudRate = 75; break;
570: case 109: nBaudRate = 110; break;
571: case 120: nBaudRate = 110; break;
572: case 1745: nBaudRate = 1800; break;
573: case 1920: nBaudRate = 1800; break;
574: }
1.1 root 575:
1.1.1.4 root 576: RS232_SetBaudRate(nBaudRate);
577: }
578:
579:
580: /*-----------------------------------------------------------------------*/
1.1.1.9 root 581: /**
582: * Set flow control configuration of RS-232.
583: */
1.1.1.4 root 584: void RS232_SetFlowControl(int ctrl)
585: {
586: Dprintf(("RS232_SetFlowControl(%i)\n", ctrl));
587:
588: /* Not yet written */
1.1 root 589: }
590:
1.1.1.4 root 591:
592: /*----------------------------------------------------------------------- */
1.1.1.9 root 593: /**
594: * Pass bytes from emulator to RS-232
595: */
1.1.1.11! root 596: bool RS232_TransferBytesTo(unsigned char *pBytes, int nBytes)
1.1 root 597: {
1.1.1.4 root 598: /* Do need to open a connection to RS232? */
599: if (!bConnectedRS232)
600: {
601: /* Do have RS-232 enabled? */
602: if (ConfigureParams.RS232.bEnableRS232)
603: bConnectedRS232 = RS232_OpenCOMPort();
604: }
605:
606: /* Have we connected to the RS232? */
607: if (bConnectedRS232)
608: {
609: /* Send bytes directly to the COM file */
610: if (fwrite(pBytes, 1, nBytes, hComOut))
611: {
612: Dprintf(("RS232: Sent %i bytes ($%x ...)\n", nBytes, *pBytes));
613: MFP_InputOnChannel(MFP_TRNBUFEMPTY_BIT, MFP_IERA, &MFP_IPRA);
614:
615: return(TRUE); /* OK */
616: }
617: }
618:
619: return(FALSE); /* Failed */
620: }
621:
622:
623: /*-----------------------------------------------------------------------*/
1.1.1.9 root 624: /**
625: * Read characters from our internal input buffer (bytes from other machine)
626: */
1.1.1.11! root 627: bool RS232_ReadBytes(unsigned char *pBytes, int nBytes)
1.1.1.4 root 628: {
629: int i;
630:
631: /* Connected? */
632: if (bConnectedRS232 && InputBuffer_Head != InputBuffer_Tail)
633: {
634: /* Read bytes out of input buffer */
635: for (i=0; i<nBytes; i++)
636: {
637: *pBytes++ = InputBuffer_RS232[InputBuffer_Head];
638: InputBuffer_Head = (InputBuffer_Head+1) % MAX_RS232INPUT_BUFFER;
639: SDL_SemPost(pSemFreeBuf); /* Signal free space */
640: }
641: return(TRUE);
642: }
643:
644: return(FALSE);
645: }
646:
647:
648: /*-----------------------------------------------------------------------*/
1.1.1.9 root 649: /**
650: * Return TRUE if bytes waiting!
651: */
1.1.1.11! root 652: bool RS232_GetStatus(void)
1.1.1.4 root 653: {
654: /* Connected? */
655: if (bConnectedRS232)
656: {
657: /* Do we have bytes in the input buffer? */
658: if (InputBuffer_Head != InputBuffer_Tail)
659: return(TRUE);
660: }
1.1 root 661:
1.1.1.4 root 662: /* No, none */
663: return(FALSE);
664: }
1.1 root 665:
666:
1.1.1.4 root 667: /*-----------------------------------------------------------------------*/
1.1.1.9 root 668: /**
669: * Read from the Syncronous Character Register.
670: */
1.1.1.4 root 671: void RS232_SCR_ReadByte(void)
1.1 root 672: {
1.1.1.8 root 673: M68000_WaitState(4);
674:
675: /* nothing */
1.1.1.4 root 676: }
677:
678: /*-----------------------------------------------------------------------*/
1.1.1.9 root 679: /**
680: * Write to the Syncronous Character Register.
681: */
1.1.1.4 root 682: void RS232_SCR_WriteByte(void)
683: {
1.1.1.8 root 684: M68000_WaitState(4);
685:
1.1.1.10 root 686: /*Dprintf(("RS232: Write to SCR: $%x\n", (int)IoMem[0xfffa27]));*/
1.1.1.4 root 687: }
1.1 root 688:
1.1.1.4 root 689:
690: /*-----------------------------------------------------------------------*/
1.1.1.9 root 691: /**
692: * Read from the USART Control Register.
693: */
1.1.1.4 root 694: void RS232_UCR_ReadByte(void)
695: {
1.1.1.8 root 696: M68000_WaitState(4);
697:
1.1.1.10 root 698: Dprintf(("RS232: Read from UCR: $%x\n", (int)IoMem[0xfffa29]));
1.1.1.4 root 699: }
1.1 root 700:
1.1.1.4 root 701: /*-----------------------------------------------------------------------*/
1.1.1.9 root 702: /**
703: * Write to the USART Control Register.
704: */
1.1.1.4 root 705: void RS232_UCR_WriteByte(void)
706: {
1.1.1.8 root 707: M68000_WaitState(4);
708:
1.1.1.10 root 709: Dprintf(("RS232: Write to UCR: $%x\n", (int)IoMem[0xfffa29]));
1.1.1.4 root 710:
711: if (bConnectedRS232)
1.1.1.10 root 712: RS232_HandleUCR(IoMem[0xfffa29]);
1.1 root 713: }
714:
1.1.1.4 root 715:
716: /*-----------------------------------------------------------------------*/
1.1.1.9 root 717: /**
718: * Read from the Receiver Status Register.
719: */
1.1.1.4 root 720: void RS232_RSR_ReadByte(void)
1.1 root 721: {
1.1.1.8 root 722: M68000_WaitState(4);
723:
1.1.1.4 root 724: if (RS232_GetStatus())
1.1.1.10 root 725: IoMem[0xfffa2b] |= 0x80; /* Buffer full */
1.1.1.4 root 726: else
1.1.1.10 root 727: IoMem[0xfffa2b] &= ~0x80; /* Buffer not full */
1.1.1.4 root 728:
1.1.1.10 root 729: Dprintf(("RS232: Read from RSR: $%x\n", (int)IoMem[0xfffa2b]));
1.1.1.4 root 730: }
731:
732: /*-----------------------------------------------------------------------*/
1.1.1.9 root 733: /**
734: * Write to the Receiver Status Register.
735: */
1.1.1.4 root 736: void RS232_RSR_WriteByte(void)
737: {
1.1.1.8 root 738: M68000_WaitState(4);
739:
1.1.1.10 root 740: Dprintf(("RS232: Write to RSR: $%x\n", (int)IoMem[0xfffa2b]));
1.1 root 741: }
742:
1.1.1.4 root 743:
744: /*-----------------------------------------------------------------------*/
1.1.1.9 root 745: /**
746: * Read from the Transmitter Status Register.
747: */
1.1.1.4 root 748: void RS232_TSR_ReadByte(void)
1.1 root 749: {
1.1.1.8 root 750: M68000_WaitState(4);
751:
1.1.1.4 root 752: if (ConfigureParams.RS232.bEnableRS232)
1.1.1.10 root 753: IoMem[0xfffa2d] |= 0x80; /* Buffer empty */
1.1.1.4 root 754: else
1.1.1.10 root 755: IoMem[0xfffa2d] &= ~0x80; /* Buffer not empty */
1.1 root 756:
1.1.1.10 root 757: Dprintf(("RS232: Read from TSR: $%x\n", (int)IoMem[0xfffa2d]));
1.1 root 758: }
759:
1.1.1.4 root 760: /*-----------------------------------------------------------------------*/
1.1.1.9 root 761: /**
762: * Write to the Transmitter Status Register.
763: */
1.1.1.4 root 764: void RS232_TSR_WriteByte(void)
765: {
1.1.1.8 root 766: M68000_WaitState(4);
767:
1.1.1.10 root 768: Dprintf(("RS232: Write to TSR: $%x\n", (int)IoMem[0xfffa2d]));
1.1.1.4 root 769: }
770:
771:
772: /*-----------------------------------------------------------------------*/
1.1.1.9 root 773: /**
774: * Read from the USART Data Register.
775: */
1.1.1.4 root 776: void RS232_UDR_ReadByte(void)
1.1 root 777: {
1.1.1.9 root 778: unsigned char InByte = 0;
1.1 root 779:
1.1.1.8 root 780: M68000_WaitState(4);
781:
1.1.1.4 root 782: RS232_ReadBytes(&InByte, 1);
1.1.1.10 root 783: IoMem[0xfffa2f] = InByte;
784: Dprintf(("RS232: Read from UDR: $%x\n", (int)IoMem[0xfffa2f]));
1.1.1.4 root 785:
786: if (RS232_GetStatus()) /* More data waiting? */
787: {
788: /* Yes, generate another interrupt. */
789: MFP_InputOnChannel(MFP_RCVBUFFULL_BIT, MFP_IERA, &MFP_IPRA);
790: }
1.1 root 791: }
1.1.1.4 root 792:
793: /*-----------------------------------------------------------------------*/
1.1.1.9 root 794: /**
795: * Write to the USART Data Register.
796: */
1.1.1.4 root 797: void RS232_UDR_WriteByte(void)
798: {
799: unsigned char OutByte;
800:
1.1.1.8 root 801: M68000_WaitState(4);
802:
1.1.1.10 root 803: OutByte = IoMem[0xfffa2f];
1.1.1.4 root 804: RS232_TransferBytesTo(&OutByte, 1);
1.1.1.10 root 805: Dprintf(("RS232: Write to UDR: $%x\n", (int)IoMem[0xfffa2f]));
1.1.1.4 root 806: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.