Annotation of hatari/src/rs232.c, revision 1.1.1.12

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.12! 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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.