Annotation of sbbs/sbbs2/rio/riolib.c, revision 1.1.1.1

1.1       root        1: /* RIOLIB.C */
                      2: 
                      3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
                      4: 
                      5: /* Remote communications Input/Output Library for OS/2 and Win32 */
                      6: 
                      7: #define RIOLIB_VER     100
                      8: 
                      9: #ifdef __OS2__
                     10:        #define INCL_DOSDEVICES
                     11:        #define INCL_DOSDEVIOCTL
                     12:        #define INCL_DOS
                     13:        #include <os2.h>
                     14: 
                     15: #else  // Win32
                     16: 
                     17:        #include <windows.h>
                     18: #endif
                     19: 
                     20: #include <time.h>
                     21: #include <stdio.h>
                     22: #include <fcntl.h>
                     23: #include <string.h>
                     24: #include <process.h>
                     25: #include "riolib.h"
                     26: #include "riodefs.h"
                     27: 
                     28: int rio_handle=-1;
                     29: 
                     30: int rio_abort=0,rio_aborted=0;
                     31: int inbufbot,inbuftop;
                     32: int outbufbot,outbuftop;
                     33: char inbuf[RIO_INCOM_BUFLEN];
                     34: char outbuf[RIO_OUTCOM_BUFLEN];
                     35: 
                     36: /****************************************************************************/
                     37: /* OS/2 Specific                                                                                                                       */
                     38: /****************************************************************************/
                     39: 
                     40: #ifdef __OS2__
                     41: 
                     42: HEV rio_sem;
                     43: 
                     44: typedef struct {       /* Packet for Get/Set Device Control Block Parms */
                     45: 
                     46:        ushort  wr_timeout;
                     47:        ushort  rd_timeout;
                     48:        uchar   flags1;
                     49:        uchar   flags2;
                     50:        uchar   flags3;
                     51:        uchar   err_char;
                     52:        uchar   brk_char;
                     53:        uchar   xon_char;
                     54:        uchar   xoff_char;
                     55: 
                     56:        } async_dcb_t;
                     57: 
                     58: typedef struct {       /* Parameter Packet for Extended Set Bit Rate */
                     59: 
                     60:        ulong rate;
                     61:        uchar frac;
                     62: 
                     63:        } setrate_t;
                     64: 
                     65: typedef struct {       /* Data Packet for Extended Query Bit Rate */
                     66: 
                     67:        ulong cur_rate;
                     68:        uchar cur_rate_frac;
                     69:        ulong min_rate;
                     70:        uchar min_rate_frac;
                     71:        ulong max_rate;
                     72:        uchar max_rate_frac;
                     73: 
                     74:        } getrate_t;
                     75: 
                     76: typedef struct {       /* Data Packet for Query Number of Chars Queue */
                     77: 
                     78:        ushort  cur,
                     79:                        max;
                     80: 
                     81:        } getqueue_t;
                     82: 
                     83: typedef struct {       /* Parameter Packet for Set Modem Control Signals */
                     84: 
                     85:        uchar   on;
                     86:        uchar   off;
                     87: 
                     88:        } setmdmctrl_t;
                     89: 
                     90: typedef struct {       /* Parameter Packet for Set Line Characteristics */
                     91: 
                     92:        uchar   data;
                     93:        uchar   parity;
                     94:        uchar   stop;
                     95: 
                     96:        } setline_t;
                     97: 
                     98: #else
                     99: 
                    100: /****************************************************************************/
                    101: /* Win32 Specific                                                                                                                      */
                    102: /****************************************************************************/
                    103: 
                    104: HANDLE rio_event;
                    105: 
                    106: #endif
                    107: 
                    108: /************************************************************************/
                    109: /* Opens COM port, ignoring IRQ argument                                                               */
                    110: /* Returns 0 on no error                                                                                               */
                    111: /************************************************************************/
                    112: int rioini(int com, int unused)
                    113: {
                    114:        char            str[64];
                    115: #ifdef __OS2__
                    116:        async_dcb_t async_dcb;
                    117: #else // Win32
                    118:        DCB             dcb;
                    119:        COMMTIMEOUTS timeouts;
                    120: #endif
                    121: 
                    122: #ifdef __WATOMC__
                    123:        char            *stack;
                    124: #endif
                    125: 
                    126: inbufbot=inbuftop=outbufbot=outbuftop=0;       /* clear our i/o buffers */
                    127: 
                    128: if(!com) { /* Close port */
                    129:        if(rio_handle>=0) {
                    130: #ifdef __OS2__
                    131:                close(rio_handle);
                    132:                rio_handle=-1;   /* signal outcom_thread() to end */
                    133:                DosPostEventSem(rio_sem);
                    134: #else // Win32
                    135:                CloseHandle((HANDLE)rio_handle);
                    136:                rio_handle=-1;
                    137:                SetEvent(rio_event);
                    138: #endif
                    139:                return(0); }
                    140:        return(-2); }
                    141: 
                    142: sprintf(str,"COM%u",com);
                    143: #ifdef __OS2__
                    144: if(rio_handle==-1) {   /* Not already opened */
                    145:        if((rio_handle=open(str,O_RDWR|O_BINARY,0))==-1)
                    146:                return(-1); }
                    147: #else // Win32
                    148: if(rio_handle==-1) {   /* Not already opened */
                    149:        if((rio_handle=(int)CreateFile(str
                    150:                ,GENERIC_READ|GENERIC_WRITE     /* Access */
                    151:                ,0                                                              /* Share mode */
                    152:                ,NULL                                                   /* Security attributes */
                    153:                ,OPEN_EXISTING                                  /* Create access */
                    154:                ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
                    155:                ,NULL                                                   /* Template */
                    156:                ))==(int)INVALID_HANDLE_VALUE)
                    157:                return(-1); }
                    158: #endif
                    159: 
                    160: #ifdef __OS2__
                    161: 
                    162: if(DosDevIOCtl(rio_handle
                    163:        ,IOCTL_ASYNC, 0x73      /* Query Device Control Block (DCB) Parms */
                    164:        ,NULL
                    165:        ,0
                    166:        ,NULL
                    167:        ,&async_dcb
                    168:        ,sizeof(async_dcb)
                    169:        ,NULL))
                    170:        return(-6);
                    171: 
                    172: async_dcb.flags2&=~(1<<1);     /* Disable Automatic Recv XON/XOFF flow ctrl */
                    173: /* Extended Hardware Buffering (16550 FIFO) */
                    174: if(async_dcb.flags3&((1<<4)|(1<<3))) {                 /* Supported */
                    175:        async_dcb.flags3&=~((1<<3)|(1<<6)|(1<<5));      /* Set to 1 char trgr lvl */
                    176:        async_dcb.flags3|=((1<<4)|(1<<7)); }            /* Set to 16 char tx buf */
                    177: async_dcb.flags3|=((1<<2)|(1<<1));                             /* No-Wait read timeout */
                    178: async_dcb.flags3&=~(1<<0);                                             /* Normal write timeout */
                    179: async_dcb.wr_timeout=499;                                              /* 5 seconds? */
                    180: DosDevIOCtl(rio_handle
                    181:        ,IOCTL_ASYNC, 0x53      /* Set Device Control Block (DCB) Parms */
                    182:        ,(void *)&async_dcb
                    183:        ,sizeof(async_dcb)
                    184:        ,NULL
                    185:        ,NULL
                    186:        ,0
                    187:        ,NULL);
                    188: 
                    189: if(DosCreateEventSem(NULL,&rio_sem,0,0))
                    190:        return(-5);
                    191: 
                    192: #else // Win32
                    193: 
                    194: if(GetCommState((HANDLE)rio_handle,&dcb)!=TRUE)
                    195:        return(-6);
                    196: 
                    197: dcb.fBinary=1;                 // No EOF check
                    198: dcb.fDtrControl=DTR_CONTROL_ENABLE;
                    199: dcb.fDsrSensitivity=FALSE;
                    200: dcb.fOutX=0;                   // No Xon/Xoff out
                    201: dcb.fInX=0;                    // No Xon/Xoff in
                    202: dcb.fErrorChar=FALSE;  // No character replacement
                    203: dcb.fNull=0;                   // No null stripping
                    204: dcb.fAbortOnError=0;   // Continue to communicate even if error detected
                    205: 
                    206: SetCommState((HANDLE)rio_handle,&dcb);
                    207: 
                    208: if(GetCommTimeouts((HANDLE)rio_handle,&timeouts)!=TRUE)
                    209:        return(-7);
                    210: 
                    211: timeouts.ReadIntervalTimeout=MAXDWORD;
                    212: timeouts.ReadTotalTimeoutMultiplier=0;
                    213: timeouts.ReadTotalTimeoutConstant=0;           // No-wait read timeout
                    214: timeouts.WriteTotalTimeoutMultiplier=0;
                    215: timeouts.WriteTotalTimeoutConstant=5000;       // 5 seconds
                    216: SetCommTimeouts((HANDLE)rio_handle,&timeouts);
                    217: 
                    218: SetupComm((HANDLE)rio_handle,4096,4096);       /* Init Rx and Tx buffer sizes */
                    219: 
                    220: if((rio_event=CreateEvent(NULL                 /* Security attributes */
                    221:        ,TRUE                                                           /* Manual reset */
                    222:        ,FALSE                                                          /* Non-signaled by default */
                    223:        ,NULL                                                           /* Event name */
                    224:        ))==NULL)
                    225:        return(-5);
                    226: 
                    227: #endif
                    228: 
                    229: #ifdef __WATCOMC__
                    230: stack=malloc(RIO_OUTCOM_STACK);
                    231: if(stack==NULL)
                    232:        return(-4);
                    233: if(_beginthread(outcom_thread,stack,RIO_OUTCOM_STKLEN,NULL)==-1)
                    234:        return(-3);
                    235: #else
                    236: if(_beginthread(outcom_thread,RIO_OUTCOM_STKLEN,NULL)==(ulong)-1)
                    237:        return(-3);
                    238: #endif
                    239: 
                    240: 
                    241: return(0);
                    242: }
                    243: 
                    244: /************************************************************************/
                    245: /* Raise or lower DTR                                                                                                  */
                    246: /* If onoff is 0, drop and exit, 1 raise and exit, >1 drop and wait    */
                    247: /* up to x seconds for DCD to drop, return 0 on success, 1 on failure  */
                    248: /************************************************************************/
                    249: int dtr(char onoff)
                    250: {
                    251: #ifdef __OS2__
                    252:        setmdmctrl_t setmdmctrl;
                    253:        ulong start;
                    254:        ushort w;
                    255:        uchar c;
                    256: 
                    257: if(onoff==1) {
                    258:        setmdmctrl.on=1;
                    259:        setmdmctrl.off=0xff; }
                    260: else {
                    261:        setmdmctrl.on=0;
                    262:        setmdmctrl.off=0xfe; }
                    263: 
                    264: DosDevIOCtl(rio_handle, IOCTL_ASYNC, 0x46      /* Set Modem Ctrl Signals */
                    265:        ,&setmdmctrl
                    266:        ,sizeof(setmdmctrl)
                    267:        ,NULL
                    268:        ,&w
                    269:        ,sizeof(short)
                    270:        ,NULL);
                    271: 
                    272: if(onoff<=1)
                    273:        return(0);
                    274: 
                    275: start=time(NULL);
                    276: while(time(NULL)-start<=onoff) {
                    277:        DosDevIOCtl(rio_handle
                    278:                ,IOCTL_ASYNC, 0x67                                      /* Get Modem Input Signals */
                    279:                ,NULL
                    280:                ,0
                    281:                ,NULL
                    282:                ,&c
                    283:                ,1
                    284:                ,NULL);
                    285:        if(!(c&DCD))    /* DCD is low */
                    286:                return(0);
                    287:        DosSleep(1); }
                    288: 
                    289: #else // Win32
                    290: 
                    291:        ulong l,start;
                    292: 
                    293: if(onoff==1)
                    294:        EscapeCommFunction((HANDLE)rio_handle,SETDTR);
                    295: else
                    296:        EscapeCommFunction((HANDLE)rio_handle,CLRDTR);
                    297: 
                    298: if(onoff<=1)
                    299:        return(0);
                    300: 
                    301: start=time(NULL);
                    302: while(time(NULL)-start<=onoff) {
                    303:        GetCommModemStatus((HANDLE)rio_handle,&l);
                    304:        if(!(l&MS_RLSD_ON)) // DCD is low
                    305:                return(0);
                    306:        Sleep(1000); }
                    307: 
                    308: #endif
                    309: 
                    310: return(1); /* Dropping DTR failed to lower DCD */
                    311: }
                    312: 
                    313: 
                    314: 
                    315: /************************************************************************/
                    316: /* Returns the current DTE rate of the currently open COM port                 */
                    317: /************************************************************************/
                    318: long rio_getbaud(void)
                    319: {
                    320: #ifdef __OS2__
                    321:        getrate_t getrate;
                    322: 
                    323: if(DosDevIOCtl(rio_handle, IOCTL_ASYNC, 0x63 /* Extended Query Bit Rate */
                    324:        ,NULL
                    325:        ,0
                    326:        ,NULL
                    327:        ,&getrate
                    328:        ,sizeof(getrate)
                    329:        ,NULL)==0)
                    330:        return(getrate.cur_rate);
                    331: 
                    332: #else // Win32
                    333: 
                    334:        DCB dcb;
                    335: 
                    336: if(GetCommState((HANDLE)rio_handle,&dcb)==TRUE) {
                    337:        switch(dcb.BaudRate) {
                    338:                case CBR_110:
                    339:                        return(110);
                    340:                case CBR_300:
                    341:                        return(300);
                    342:                case CBR_600:
                    343:                        return(600);
                    344:                case CBR_1200:
                    345:                        return(1200);
                    346:                case CBR_2400:
                    347:                        return(2400);
                    348:                case CBR_4800:
                    349:                        return(4800);
                    350:                case CBR_9600:
                    351:                        return(9600);
                    352:                case CBR_14400:
                    353:                        return(14400);
                    354:                case CBR_19200:
                    355:                        return(19200);
                    356:                case CBR_38400:
                    357:                        return(38400);
                    358:                case CBR_56000:
                    359:                        return(56000);
                    360:                case CBR_57600:
                    361:                        return(57600);
                    362:                case CBR_115200:
                    363:                        return(115200);
                    364:                case CBR_128000:
                    365:                        return(128000);
                    366:                case CBR_256000:
                    367:                        return(256000);
                    368:                default:
                    369:                        return(dcb.BaudRate); } }
                    370: 
                    371: #endif
                    372: 
                    373: return(-1); // Error
                    374: }
                    375: 
                    376: 
                    377: /************************************************************************/
                    378: /* Sets the current DTE rate                                                                                   */
                    379: /* Returns 0 on success                                                                                                */
                    380: /************************************************************************/
                    381: int setbaud(int rate)
                    382: {
                    383: #ifdef __OS2__
                    384:        setrate_t setrate;
                    385:        APIRET  ret;
                    386: 
                    387: setrate.rate=rate;
                    388: setrate.frac=0;
                    389: 
                    390: ret=DosDevIOCtl(rio_handle, IOCTL_ASYNC, 0x43  /* Extended Set Bit Rate */
                    391:        ,&setrate
                    392:        ,sizeof(setrate)
                    393:        ,NULL
                    394:        ,NULL
                    395:        ,0
                    396:        ,NULL);
                    397: 
                    398: if(ret)
                    399:        return(ret);
                    400: 
                    401: if(rio_getbaud()!=rate)        /* Make sure it actually changed rates */
                    402:        return(-1);
                    403: 
                    404: #else // Win32
                    405: 
                    406:        DCB dcb;
                    407: 
                    408: if(GetCommState((HANDLE)rio_handle,&dcb)!=TRUE)
                    409:        return(-1);
                    410: dcb.BaudRate=rate;
                    411: if(SetCommState((HANDLE)rio_handle,&dcb)!=TRUE)
                    412:        return(-1);
                    413: 
                    414: #endif
                    415: 
                    416: return(0);
                    417: }
                    418: 
                    419: /************************************************************************/
                    420: /* Return next incoming character from COM port, NOINP if none avail.  */
                    421: /* Uses a linear buffer.                                                                                               */
                    422: /************************************************************************/
                    423: int incom(void)
                    424: {
                    425:        char c;
                    426: 
                    427: if(inbufbot!=inbuftop) {
                    428:        c=inbuf[inbufbot];
                    429:        inbufbot++;
                    430:        if(inbufbot==inbuftop)
                    431:                inbufbot=inbuftop=0;
                    432:        if(rio_abort && c==3) {                 /* Ctrl-C */
                    433:                rio_aborted=1;
                    434:                rioctl(IOFO);
                    435:                return(NOINP); }
                    436:        return(c); }
                    437: 
                    438: inbufbot=0;
                    439: #ifdef __OS2__
                    440: inbuftop=read(rio_handle,inbuf,RIO_INCOM_BUFLEN);
                    441: #else // Win32
                    442: ReadFile((HANDLE)rio_handle,inbuf,RIO_INCOM_BUFLEN,(DWORD *)&inbuftop,NULL);
                    443: #endif
                    444: if(inbuftop<=0 || inbuftop>RIO_INCOM_BUFLEN) {
                    445:        inbuftop=0;
                    446:        return(NOINP); }
                    447: else
                    448:        return(inbuf[inbufbot++]);
                    449: }
                    450: 
                    451: /************************************************************************/
                    452: /* Return number of chars in our input buffer                                                  */
                    453: /************************************************************************/
                    454: int inbufcnt(void)
                    455: {
                    456: return(inbuftop-inbufbot);
                    457: }
                    458: 
                    459: /************************************************************************/
                    460: /* Place a character into outbound buffer, return TXBOF on buffer              */
                    461: /* overflow, 0 on success.                                                                                             */
                    462: /************************************************************************/
                    463: int outcom(int ch)
                    464: {
                    465:        int i=outbuftop+1;
                    466: 
                    467: if(i==RIO_OUTCOM_BUFLEN)
                    468:        i=0;
                    469: if(i==outbufbot)
                    470:        return(TXBOF);
                    471: outbuf[outbuftop++]=ch;
                    472: if(outbuftop==RIO_OUTCOM_BUFLEN)
                    473:        outbuftop=0;
                    474: #ifdef __OS2__
                    475: DosPostEventSem(rio_sem);       // Enable output
                    476: #else // Win32
                    477: SetEvent(rio_event);
                    478: #endif
                    479: return(0);
                    480: }
                    481: 
                    482: /************************************************************************/
                    483: /************************************************************************/
                    484: void outcom_thread(void *unused)
                    485: {
                    486:        int i,top;
                    487:        ulong l;
                    488: 
                    489: while(rio_handle>=0) {
                    490:        if(outbufbot==outbuftop) {
                    491: #ifdef __OS2__
                    492:                DosResetEventSem(rio_sem,&l);
                    493:                DosWaitEventSem(rio_sem,10000);  /* every 10 seconds */
                    494: #else // Win32
                    495:                ResetEvent(rio_event);
                    496:                WaitForSingleObject(rio_event,10000);
                    497: #endif
                    498:                continue; }
                    499:        top=outbuftop;
                    500:        if(top<outbufbot)
                    501:                i=RIO_OUTCOM_BUFLEN-outbufbot;
                    502:        else
                    503:                i=top-outbufbot;
                    504: #ifdef __OS2__
                    505:        i=write(rio_handle,outbuf+outbufbot,i);
                    506: #else // Win32
                    507:        WriteFile((HANDLE)rio_handle,outbuf+outbufbot,i,(DWORD *)&i,NULL);
                    508: #endif
                    509:        if(i>0 && i<=RIO_OUTCOM_BUFLEN-outbufbot)
                    510:                outbufbot+=i;
                    511:        if(outbufbot==RIO_OUTCOM_BUFLEN)
                    512:                outbufbot=0; }
                    513: _endthread();
                    514: }
                    515: 
                    516: /************************************************************************/
                    517: /* Return number of chars in our output buffer                                                 */
                    518: /************************************************************************/
                    519: int outbufcnt(void)
                    520: {
                    521: if(outbuftop>=outbufbot)
                    522:     return(outbuftop-outbufbot);
                    523: return(outbuftop+(RIO_OUTCOM_BUFLEN-outbufbot));
                    524: }
                    525: 
                    526: /************************************************************************/
                    527: /************************************************************************/
                    528: int rio_getstate(void)
                    529: {
                    530: #ifdef __OS2__
                    531:        uchar c;
                    532:        ushort state=0,w;
                    533:        getqueue_t getqueue;
                    534: 
                    535: if(rio_abort && !rio_aborted) {
                    536:        DosDevIOCtl(rio_handle
                    537:                ,IOCTL_ASYNC, 0x68 /* Query # of chars in rx queue */
                    538:                ,NULL
                    539:                ,0
                    540:                ,NULL
                    541:                ,&getqueue
                    542:                ,sizeof(getqueue)
                    543:                ,NULL);
                    544:        if(getqueue.cur && read(rio_handle,&c,1)==1) {
                    545:                if(c==3) { /* ctrl-c */
                    546:                        rio_aborted=1;
                    547:                        rioctl(IOFO); }
                    548:                else
                    549:                        if(inbuftop<RIO_INCOM_BUFLEN)  /* don't overflow input buffer */
                    550:                                inbuf[inbuftop++]=c; } }
                    551: 
                    552: if(rio_aborted)
                    553:     state|=ABORT;
                    554: 
                    555: #if 0  // just to see if things speed up
                    556: DosDevIOCtl(rio_handle
                    557:        ,IOCTL_ASYNC, 0x6D      /* Query COM Error */
                    558:        ,NULL
                    559:        ,0
                    560:        ,NULL
                    561:        ,&w
                    562:        ,sizeof(short)
                    563:        ,NULL);
                    564: state|=w&0xf;  /* FERR|PERR|OVRR|RXLOST */
                    565: #endif
                    566: 
                    567: DosDevIOCtl(rio_handle
                    568:        ,IOCTL_ASYNC, 0x67      /* Query Modem Input Signals */
                    569:        ,NULL
                    570:        ,0
                    571:        ,NULL
                    572:        ,&c
                    573:        ,sizeof(char)
                    574:        ,NULL);
                    575: state|=c&0xf0; /* DCD|RI|DSR|CTS */
                    576: 
                    577: #else // Win32
                    578: 
                    579:        uchar c;
                    580:        ushort state=0;
                    581:        int i;
                    582:        ulong l;
                    583:        COMSTAT comstat;
                    584: 
                    585: if(rio_abort && !rio_aborted) {
                    586:        ClearCommError((HANDLE)rio_handle,&l,&comstat);
                    587:        if(comstat.cbInQue) {
                    588:                ReadFile((HANDLE)rio_handle,&c,1,(DWORD *)&i,NULL);
                    589:                if(i==1) {
                    590:                        if(c==3) { /* Ctrl-C */
                    591:                                rio_aborted=1;
                    592:                                rioctl(IOFO); }
                    593:                        else
                    594:                                if(inbuftop<RIO_INCOM_BUFLEN)  /* don't overflow input buffer */
                    595:                                        inbuf[inbuftop++]=c; } } }
                    596: 
                    597: GetCommModemStatus((HANDLE)rio_handle,(DWORD *)&state);  /* DCD|RI|DSR|CTS */
                    598: if(rio_aborted)
                    599:     state|=ABORT;
                    600: 
                    601: #endif
                    602: 
                    603: return(state);
                    604: }
                    605: 
                    606: 
                    607: /************************************************************************/
                    608: /************************************************************************/
                    609: int rioctl(ushort action)
                    610: {
                    611: #ifdef __OS2__
                    612:        async_dcb_t     async_dcb;
                    613:        getqueue_t              getqueue;
                    614:        setline_t               setline;
                    615: #else // Win32
                    616:        COMMPROP                commprop;
                    617:        COMSTAT                 comstat;
                    618:        DCB                     dcb;
                    619:        ulong                   l;
                    620: #endif
                    621:        uchar c;
                    622:        ushort mode,w;
                    623:        clock_t start;
                    624: 
                    625: switch(action) {
                    626:        case GVERS:     /* Get version */
                    627:                return(RIOLIB_VER);
                    628:        case GUART:     /* Get UART I/O address, not available */
                    629:                return(0xffff);
                    630:        case GIRQN:     /* Get IRQ number, not available */
                    631:                return((int)rio_handle);
                    632:        case GBAUD:     /* Get current bit rate */
                    633:                return(rio_getbaud());
                    634:        case RXBC:              /* Get receive buffer count */
                    635: #ifndef __OS2__ // Win32
                    636:                ClearCommError((HANDLE)rio_handle,&l,&comstat);
                    637:                return(comstat.cbInQue+inbufcnt());
                    638: #endif
                    639:                /* Fall-through if OS/2 */
                    640:        case RXBS:              /* Get receive buffer size */
                    641: #ifdef __OS2__
                    642:                DosDevIOCtl(rio_handle
                    643:                        ,IOCTL_ASYNC, 0x68 /* Query # of chars in rx queue */
                    644:                        ,NULL
                    645:                        ,0
                    646:                        ,NULL
                    647:                        ,&getqueue
                    648:                        ,sizeof(getqueue)
                    649:                        ,NULL);
                    650:                if(action==RXBC)
                    651:                        return(getqueue.cur+inbufcnt());
                    652:                /* RXBS */
                    653:                return(getqueue.max+RIO_INCOM_BUFLEN);
                    654: #else
                    655:                GetCommProperties((HANDLE)rio_handle,&commprop);
                    656:                return(commprop.dwCurrentRxQueue+RIO_INCOM_BUFLEN);
                    657: #endif
                    658:        case TXBC:              /* Get transmit buffer count */
                    659: #ifndef __OS2__ // Win32
                    660:                ClearCommError((HANDLE)rio_handle,&l,&comstat);
                    661:                return(comstat.cbOutQue+outbufcnt());
                    662: #endif
                    663:                /* Fall-through if OS/2 */
                    664:        case TXBS:              /* Get transmit buffer size */
                    665:        case TXBF:              /* Get transmit buffer free space */
                    666: #ifdef __OS2__
                    667:                DosDevIOCtl(rio_handle
                    668:                        ,IOCTL_ASYNC, 0x69      /* Query # of chars in tx queue */
                    669:                        ,NULL
                    670:                        ,0
                    671:                        ,NULL
                    672:                        ,&getqueue
                    673:                        ,sizeof(getqueue)
                    674:                        ,NULL);
                    675:                if(action==TXBC)
                    676:                        return(getqueue.cur+outbufcnt());
                    677:                else if(action==TXBS)
                    678:                        return(getqueue.max+RIO_OUTCOM_BUFLEN);
                    679:                /* TXBF */
                    680:                return((getqueue.max-getqueue.cur)+(RIO_OUTCOM_BUFLEN-outbufcnt()));
                    681: #else
                    682:                GetCommProperties((HANDLE)rio_handle,&commprop);
                    683:                if(action==TXBS)
                    684:                        return(commprop.dwCurrentTxQueue+RIO_OUTCOM_BUFLEN);
                    685:                /* TXBF */
                    686:                ClearCommError((HANDLE)rio_handle,&l,&comstat);
                    687:                return((commprop.dwCurrentTxQueue-comstat.cbOutQue)
                    688:                        +(RIO_OUTCOM_BUFLEN-outbufcnt()));
                    689: #endif
                    690:        case IOSTATE:
                    691:                return(rio_getstate());
                    692:        case IOFI:              /* Flush input buffer */
                    693:        case IOFO:              /* Flush output buffer */
                    694:        case IOFB:              /* Flush both buffers */
                    695: #ifdef __OS2__
                    696:                c=0;
                    697:                if((action&IOFI)==IOFI) {
                    698:                        DosDevIOCtl(rio_handle
                    699:                                ,IOCTL_GENERAL, DEV_FLUSHINPUT
                    700:                                ,&c
                    701:                                ,sizeof(char)
                    702:                                ,NULL
                    703:                                ,&w
                    704:                                ,sizeof(short)
                    705:                                ,NULL);
                    706:                        inbufbot=inbuftop=0;
                    707:                        }          /* Clear our input buffer too */
                    708:                c=0;
                    709:                if((action&IOFO)==IOFO) {
                    710:                        DosDevIOCtl(rio_handle
                    711:                                ,IOCTL_GENERAL, DEV_FLUSHOUTPUT
                    712:                                ,&c
                    713:                                ,sizeof(char)
                    714:                                ,NULL
                    715:                                ,&w
                    716:                                ,sizeof(short)
                    717:                 ,NULL);
                    718:                        outbufbot=outbuftop=0;
                    719:                        }        /* Clear our output buffer too */
                    720: #else // Win32
                    721:                l=0;
                    722:                if((action&IOFI)==IOFI)
                    723:                        l|=(PURGE_RXABORT|PURGE_RXCLEAR);
                    724:                if((action&IOFO)==IOFO)
                    725:                        l|=(PURGE_TXABORT|PURGE_TXCLEAR);
                    726:                PurgeComm((HANDLE)rio_handle,l);
                    727: #endif
                    728:                return(rio_getstate());
                    729:        case LFN81:
                    730:        case LFE71:
                    731: #ifdef __OS2__
                    732:                setline.stop=0; /* 1 stop bit */
                    733:                if(action==LFN81) {
                    734:                        setline.data=8;
                    735:                        setline.parity=0; } /* No parity */
                    736:                else {
                    737:                        setline.data=7;
                    738:                        setline.parity=2; } /* Even parity */
                    739:                DosDevIOCtl(rio_handle
                    740:                        ,IOCTL_ASYNC, 0x42      /* Set Line Characteristics */
                    741:                        ,&setline
                    742:                        ,sizeof(setline)
                    743:                        ,NULL
                    744:                        ,NULL
                    745:                        ,0
                    746:                        ,NULL);
                    747: #else // Win32
                    748:                GetCommState((HANDLE)rio_handle,&dcb);
                    749:                if(action==LFN81) {
                    750:                        dcb.Parity=NOPARITY;
                    751:                        dcb.ByteSize=8;
                    752:                        dcb.StopBits=ONESTOPBIT; }
                    753:                else {
                    754:                        dcb.Parity=EVENPARITY;
                    755:                        dcb.ByteSize=7;
                    756:                        dcb.StopBits=ONESTOPBIT; }
                    757:                SetCommState((HANDLE)rio_handle,&dcb);
                    758: #endif
                    759:                return(0);
                    760:        case FIFOCTL:
                    761: #ifdef __OS2__
                    762:                DosDevIOCtl(rio_handle
                    763:                        ,IOCTL_ASYNC, 0x73      /* Query Device Control Block (DCB) Parms */
                    764:                        ,NULL
                    765:                        ,0
                    766:                        ,NULL
                    767:                        ,&async_dcb
                    768:                        ,sizeof(async_dcb)
                    769:                        ,NULL);
                    770: 
                    771:                /* Extended Hardware Buffering (16550 FIFO) */
                    772:                if(async_dcb.flags3&(1<<4)) {                                   /* Supported */
                    773:                        c=0xc0;
                    774:                        if(async_dcb.flags3&(1<<7))
                    775:                                c|=0x0c;
                    776:                        return(c); }
                    777: #else // Win32
                    778:                // Not supported under Win32?
                    779: #endif
                    780:                return(0);
                    781:        }
                    782: 
                    783: if((action&0xff)<=IOCM) {      /* Get/Set/Clear mode */
                    784:        mode=0;
                    785: 
                    786: #ifdef __OS2__
                    787:        DosDevIOCtl(rio_handle
                    788:                ,IOCTL_ASYNC, 0x73      /* Query Device Control Block (DCB) Parms */
                    789:                ,NULL
                    790:                ,0
                    791:                ,NULL
                    792:                ,&async_dcb
                    793:                ,sizeof(async_dcb)
                    794:                ,NULL);
                    795:        if(async_dcb.flags1&(1<<3)) /* Output CTS handshaking */
                    796:                mode|=CTSCK;
                    797:        if(async_dcb.flags2&(1<<0)) /* Automatic Xmit Control Flow Xon/Xoff */
                    798:                mode|=PAUSE;
                    799:        if(async_dcb.flags2&(1<<7)      /* RTS Input handshaking */
                    800:                && !(async_dcb.flags2&(1<<6)))
                    801:                mode|=RTSCK;
                    802:        if(rio_abort)
                    803:                mode|=ABORT;
                    804: 
                    805:        if(action==IOMODE)
                    806:                return(mode);
                    807: 
                    808:        if((action&0xff)==IOCM)         /* Clear mode */
                    809:                mode&=~(action&0xff00);
                    810:        else                                            /* Set mode */
                    811:                mode|=(action&0xff00);
                    812: 
                    813:        if(mode&CTSCK)
                    814:                async_dcb.flags1|=(1<<3);
                    815:        else
                    816:                async_dcb.flags1&=~(1<<3);
                    817:        if(mode&PAUSE) {
                    818:                async_dcb.flags2|=(1<<0);       /* xmit flow control */
                    819:                async_dcb.xon_char=17;          /* Ctrl-Q */
                    820:                async_dcb.xoff_char=19; }       /* Ctrl-S */
                    821:        else
                    822:                async_dcb.flags2&=~(1<<0);
                    823:        if(mode&RTSCK) {
                    824:                async_dcb.flags2|=(1<<7);
                    825:                async_dcb.flags2&=~(1<<6); }
                    826:        else
                    827:                async_dcb.flags2&=~((1<<7)|(1<<6));
                    828:        if(mode&ABORT)
                    829:                rio_abort=1;
                    830:        else
                    831:                rio_abort=0;
                    832: 
                    833:        DosDevIOCtl(rio_handle
                    834:                ,IOCTL_ASYNC, 0x53      /* Set Device Control Block (DCB) Parms */
                    835:                ,&async_dcb
                    836:                ,sizeof(async_dcb)
                    837:                ,NULL
                    838:                ,NULL
                    839:                ,0
                    840:                ,NULL);
                    841: 
                    842: #else // Win32
                    843: 
                    844:        GetCommState((HANDLE)rio_handle,&dcb);
                    845:        if(dcb.fOutxCtsFlow)
                    846:                mode|=CTSCK;
                    847:        if(dcb.fOutX)
                    848:                mode|=PAUSE;
                    849:        if(dcb.fRtsControl==RTS_CONTROL_HANDSHAKE)
                    850:                mode|=RTSCK;
                    851: 
                    852:        if(rio_abort)
                    853:                mode|=ABORT;
                    854: 
                    855:        if(action==IOMODE)
                    856:         return(mode);
                    857: 
                    858:        if((action&0xff)==IOCM)         /* Clear mode */
                    859:                mode&=~(action&0xff00);
                    860:        else                                            /* Set mode */
                    861:         mode|=(action&0xff00);
                    862: 
                    863:        if(mode&CTSCK)
                    864:                dcb.fOutxCtsFlow=1;
                    865:        else
                    866:                dcb.fOutxCtsFlow=0;
                    867:        if(mode&PAUSE) {
                    868:                dcb.fOutX=1;
                    869:                dcb.XonChar=17;         /* Ctrl-Q */
                    870:                dcb.XoffChar=19; }      /* Ctrl-S */
                    871:        else
                    872:                dcb.fOutX=0;
                    873:        if(mode&RTSCK)
                    874:                dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
                    875:        else
                    876:                dcb.fRtsControl=RTS_CONTROL_ENABLE;
                    877:        if(mode&ABORT)
                    878:                rio_abort=1;
                    879:        else
                    880:         rio_abort=0;
                    881: 
                    882:        SetCommState((HANDLE)rio_handle,&dcb);
                    883: 
                    884: #endif
                    885: 
                    886:        return(mode); }
                    887: 
                    888: if((action&0xff)==IOSS) {      /* Set state */
                    889: 
                    890:        if(action&ABORT)
                    891:                rio_aborted=1;
                    892: 
                    893: #ifdef __OS2__
                    894:        if(action&PAUSE)
                    895:                DosDevIOCtl(rio_handle
                    896:                        ,IOCTL_ASYNC, 0x47      /* Behave as if XOFF Received */
                    897:                        ,NULL
                    898:                        ,0
                    899:                        ,NULL
                    900:                        ,&w
                    901:                        ,sizeof(short)
                    902:             ,NULL);
                    903: #else // Win32
                    904:        if(action&PAUSE)
                    905:                EscapeCommFunction((HANDLE)rio_handle,SETXOFF);
                    906: #endif
                    907: 
                    908:        return(rio_getstate()); }
                    909: 
                    910: if((action&0xff)==IOCS) {      /* Clear state */
                    911: 
                    912:        if(action&ABORT)
                    913:                rio_aborted=0;
                    914: 
                    915: #ifdef __OS2__
                    916:        if(action&PAUSE)
                    917:                DosDevIOCtl(rio_handle
                    918:                        ,IOCTL_ASYNC, 0x48      /* Behave as if XON Received */
                    919:                        ,NULL
                    920:                        ,0
                    921:                        ,NULL
                    922:                        ,&w
                    923:                        ,sizeof(short)
                    924:             ,NULL);
                    925: #else // Win32
                    926:        if(action&PAUSE)
                    927:                EscapeCommFunction((HANDLE)rio_handle,SETXON);
                    928: #endif
                    929:     return(rio_getstate()); }
                    930: 
                    931: if((action&0xff)==TXSYNC) { /* Synchronize transmition */
                    932:     c=action>>8;            /* Number of seconds */
                    933:        w=110+(c*1000);                 /* Number of milliseconds */
                    934:        start=clock();
                    935:        while(clock()-start<w) {
                    936:                if(!outbufcnt()) {
                    937: #ifdef __OS2__
                    938:                        DosDevIOCtl(rio_handle
                    939:                                ,IOCTL_ASYNC, 0x69      /* Query # of chars in tx queue */
                    940:                                ,NULL
                    941:                                ,0
                    942:                                ,NULL
                    943:                                ,&getqueue
                    944:                                ,sizeof(getqueue)
                    945:                                ,NULL);
                    946:                        if(getqueue.cur==0)     /* Empty outbound queue */
                    947:                                return(0);
                    948: #else // Win32
                    949:                        ClearCommError((HANDLE)rio_handle,&l,&comstat);
                    950:                        if(comstat.cbOutQue==0) /* Empty outbound queue */
                    951:                                return(0);
                    952: #endif
                    953:                        }
                    954: #ifdef __OS2__
                    955:                DosSleep(1);
                    956: #else // Win32
                    957:                Sleep(1);
                    958: #endif
                    959:                }
                    960:        return(1); }
                    961: 
                    962: return(0);
                    963: }
                    964: 
                    965: /* End of file */

unix.superglobalmegacorp.com

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