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

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: */
        !            16: char RS232_rcsid[] = "Hatari $Id: rs232.c,v 1.12 2004/07/26 11:39:28 thothy Exp $";
        !            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
        !            49: # if defined(__sun) && defined(__SVR4)
        !            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:        }
        !           347: #endif HAVE_TERMIOS_H
        !           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: 
        !           398:        if (baudtype == -1)
        !           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.