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

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.9 ! root       16: const char RS232_rcsid[] = "Hatari $Id: rs232.c,v 1.30 2008/01/02 20:01:54 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.8   root       31: #include "m68000.h"
1.1.1.4   root       32: #include "mfp.h"
                     33: #include "stMemory.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.8   root       46: BOOL bConnectedRS232 = FALSE;      /* Connection to RS232? */
                     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.8   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.8   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.8   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.4   root      444: BOOL RS232_SetBaudRate(int nBaud)
                    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: 
                    543:        nTimerD_CR = STRam[0xfffa1d] & 0x07;
                    544:        nTimerD_DR = STRam[0xfffa25];
                    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;
                    551:        if (STRam[0xfffa29] & 0x80)
                    552:        {
                    553:                nBaudRate /= 16;
                    554:        }
                    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       root      596: BOOL RS232_TransferBytesTo(unsigned char *pBytes, int nBytes)
                    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.4   root      627: BOOL RS232_ReadBytes(unsigned char *pBytes, int nBytes)
                    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.4   root      652: BOOL RS232_GetStatus(void)
                    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.4   root      686:        /*Dprintf(("RS232: Write to SCR: $%x\n", (int)STRam[0xfffa27]));*/
                    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.4   root      698:        Dprintf(("RS232: Read from UCR: $%x\n", (int)STRam[0xfffa29]));
                    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.4   root      709:        Dprintf(("RS232: Write to UCR: $%x\n", (int)STRam[0xfffa29]));
                    710: 
                    711:        if (bConnectedRS232)
                    712:                RS232_HandleUCR(STRam[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())
                    725:                STRam[0xfffa2b] |= 0x80;        /* Buffer full */
                    726:        else
                    727:                STRam[0xfffa2b] &= ~0x80;       /* Buffer not full */
                    728: 
                    729:        Dprintf(("RS232: Read from RSR: $%x\n", (int)STRam[0xfffa2b]));
                    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.4   root      740:        Dprintf(("RS232: Write to RSR: $%x\n", (int)STRam[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)
                    753:                STRam[0xfffa2d] |= 0x80;        /* Buffer empty */
                    754:        else
                    755:                STRam[0xfffa2d] &= ~0x80;       /* Buffer not empty */
1.1       root      756: 
1.1.1.4   root      757:        Dprintf(("RS232: Read from TSR: $%x\n", (int)STRam[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.4   root      768:        Dprintf(("RS232: Write to TSR: $%x\n", (int)STRam[0xfffa2d]));
                    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);
                    783:        STRam[0xfffa2f] = InByte;
                    784:        Dprintf(("RS232: Read from UDR: $%x\n", (int)STRam[0xfffa2f]));
                    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.4   root      803:        OutByte = STRam[0xfffa2f];
                    804:        RS232_TransferBytesTo(&OutByte, 1);
                    805:        Dprintf(("RS232: Write to UDR: $%x\n", (int)STRam[0xfffa2f]));
                    806: }

unix.superglobalmegacorp.com

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