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

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

unix.superglobalmegacorp.com

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