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

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

unix.superglobalmegacorp.com

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