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