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

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

unix.superglobalmegacorp.com

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