home *** CD-ROM | disk | FTP | other *** search
- #ifndef OS_2
- #pragma message("This Module For OS/2")
- #else
- #include <stdio.h>
- #ifdef IBM_C
- #include <stdarg.h>
- #else
- #include <varargs.h>
- #endif
- #include <ctype.h>
- #include <conio.h>
- #include <string.h>
- #include <stdlib.h>
- #define INCL_DOS
- #define INCL_DOSDEVICES
- #define INCL_DOSDEVIOCTL
- #define INCL_DOSSEMAPHORES
- #define INCL_NOPM
- #include <os2.h>
- #include "bink.h"
- #include "com.h"
- #include "async.h"
-
- /*--------------------------------------------------------*
- * This file contains the operating system specific *
- * serial communications routines for OS/2. *
- * *
- * (C) Copyright Peter Fitzsimmons Sun 04-16-1989 *
- * *
- * Add-ins for BinkleyTerm on Sat 05-06-1989 *
- *--------------------------------------------------------*/
-
- /* This one has excellent send or receive, even with 8088 */
- /* but the xmit rate is a bit low in Janus w/o SetPrty. */
-
-
- /* #define DEBUG */
- /* #define MultiWrt */
-
-
- void status_line (char *,...);
- static void zap_zbuf(void);
-
- /* Private data */
- /* static HFILE hfComHandle = -1; */ /* handle from DosOpen() */
- HFILE hfComHandle = -1; /* handle from DosOpen() */
-
- /* transmitter stuff */
- #define TSIZE 8192
- static unsigned char tBuf[TSIZE];
- static int tpos = 0;
- static unsigned char zTxBuf[TSIZE];
- static int zpos = 0;
- static int tBufsize = 0;
- static unsigned int TQSize = 0;
- /* static HSEM WriteSem = 0; */
- ULONG WriteSem = 0;
-
- /* receiver stuff */
- #define RSIZE 8192
- static unsigned char rbuf[RSIZE];
- static int rpos = 0;
- static int rbufsize = 0;
- static USHORT Rbytes = 0;
- static word RQBbytes = 0;
- static word RQBbyte2 = 0;
-
- #ifdef DEBUG
-
- #define debug_msg(m,c) status_line("!" m, c)
- #define IOCtl(func, data, parm) _ioctl(#func, func, (void far *) data, (void far *) parm)
-
- static int _ioctl(char *funcname, int func, void far * data, void far * parm)
- {
- int i;
-
- if (i = DosDevIOCtl((PVOID) data, (PVOID) parm, func, IOCTL_ASYNC, (HFILE) hfComHandle)) {
- printf("ioctl(%s) err(0x%04x)\n", funcname, i);
- status_line("!ioctl(%s) err(0x%04x)", funcname, i);
- }
- return (i);
- }
-
- #else
- #define debug_msg(m,c)
- #define IOCtl(func, data, parm) DosDevIOCtl((PVOID) data, (PVOID) parm, func, IOCTL_ASYNC, (HFILE) hfComHandle)
- #endif
-
- static int com_getDCB(struct _DCBINFO far * dcb);
- static int com_setDCB(struct _DCBINFO far * dcb);
- static void com_kick(void);
-
-
- /* com_init() : Intialize communications port. Baud rate is preserved.
- * int port : Hardware port (0 based) to init
- * -OR- char *unc : Full UNC \\networkId\modemId to init.
- *
- * if unc==NULL, port is used. if unc != NULL, unc is used
- */
- int com_init(int port, char far *unc)
- {
- char str[30];
- char *s;
- USHORT ActionTaken; /* action: returned by OS/2 */
- USHORT stat;
- DCBINFO sDCB;
- RXQUEUE q;
-
- cputs("\033[1;33mOS/2 FOSSIL emulator for BinkleyTerm, Peter Fitzsimmons (1:250/628)\033[0m\r\n");
- sprintf(str, "COM%d", port + 1);
- if (!unc)
- unc = str;
- #ifdef DEBUG
- stat = DosOpen((PSZ) unc,(PHFILE) &hfComHandle,(PUSHORT) &ActionTaken, 0L, 0, 0x0001, 0x4012, 0L);
- #else
- stat = DosOpen((PSZ) unc,(PHFILE) &hfComHandle,(PUSHORT) &ActionTaken, 0L, 0, 0x0001, 0x6012, 0L);
- #endif
- if (stat) {
- hfComHandle = -1;
- printf("com_init() : DosOpen() error 0x%04x on '%s'\n", stat, unc);
- return (FALSE);
- }
- (void) DosSemClear((HSEM) &WriteSem);
- if (!IOCtl(ASYNC_GETINQUECOUNT, (PVOID) &q, (PVOID) 0L)) {
- s = getenv("RBUF");
- if (s)
- rbufsize = min( RSIZE, atoi(s));
- else
- rbufsize = RSIZE;
- RQBbytes = min( RSIZE, rbufsize);
- RQBbyte2 = RQBbytes/2;
- #ifdef DEBUG
- printf("com_init() : ASYNC Input Buffer size is %d'\n", q.cbQueue);
- #endif
- }
- if (!IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L)) {
- s = getenv("TBUF");
- if (s)
- tBufsize = min( TSIZE, atoi(s));
- else
- tBufsize = TSIZE;
- TQSize = min(TSIZE, q.cbQueue);
- #ifdef DEBUG
- printf("com_init() : ASYNC Output Buffer size is %d'\n", q.cbQueue);
- #endif
- }
- com_XON_disable();
-
- com_getDCB((struct _DCBINFO far *) &sDCB);
-
- /* turn off IDSR, ODSR */
- /* sDCB.bFlags1 &= ~(MODE_DSR_HANDSHAKE | MODE_DSR_SENSITIVITY); */
-
- /* raise DTR, CTS output flow control */
- /* sDCB.bFlags1 |= (MODE_DTR_CONTROL | MODE_CTS_HANDSHAKE); */
-
- /* turn off XON/XOFF flow control, error replacement off, null
- * stripping off, break replacement off */
- sDCB.bFlags2 &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE |
- MODE_ERROR_CHAR | MODE_NULL_STRIPPING |
- MODE_BREAK_CHAR);
-
- /* RTS enable */
- /* sDCB.bFlags2 |= MODE_RTS_CONTROL; */
-
- sDCB.bFlags3 |= (MODE_NO_WRITE_TIMEOUT | MODE_NOWAIT_READ_TIMEOUT);
-
- sDCB.usReadTimeout = 1000;
- sDCB.usWriteTimeout = 1000;
- com_setDCB((struct _DCBINFO far *) &sDCB);
-
- return (!stat);
- }
-
- void com_DTR_on(void)
- {
- DCBINFO sDCB;
-
- com_getDCB((struct _DCBINFO far *) &sDCB);
- sDCB.bFlags1 |= MODE_DTR_CONTROL; /* raise DTR */
- com_setDCB((struct _DCBINFO far *) &sDCB);
- }
-
- void com_DTR_off(void)
- {
- DCBINFO sDCB;
-
- com_getDCB((struct _DCBINFO far *) &sDCB);
- sDCB.bFlags1 &= ~MODE_DTR_CONTROL; /* lower DTR */
- com_setDCB((struct _DCBINFO far *) &sDCB);
- }
-
- /* close communications channel. Baud rate is preserved. */
- int com_fini(void)
- {
- int stat;
-
- if (!(hfComHandle == -1)) {
- com_wait();
- while ((DosSemWait((HSEM) &WriteSem, 1L)) && (com_online()))
- ;
- com_clear_in();
- com_clear_out();
- if (stat = DosClose(hfComHandle)) {
- hfComHandle = -1;
- debug_msg("DosClose() error 0x%04x", stat);
- return (FALSE);
- }
- hfComHandle = -1;
- }
- return(TRUE);
- }
-
- long com_cur_baud(void)
- {
- USHORT rate = 0;
-
- IOCtl(ASYNC_GETBAUDRATE, (PVOID) &rate, (PVOID) 0L);
- return ((long) rate);
- }
-
- /* com_set_baud() :
- *
- * rate = 110..19200
- * parity = N, E, O, M, S (none,even, odd, mark, space)
- * databits = 5..8
- * stopbits = 1..2
- *
- */
- int com_set_baud(unsigned rate, char parity, int databits, int stopbits)
- {
- int stat;
- struct _LINECONTROL {
- BYTE bDataBits;
- BYTE bParity;
- BYTE bStopBits;
- BYTE fbTransBreak;
- } lc;
-
- stat = IOCtl(ASYNC_SETBAUDRATE, (PVOID) 0L, (PVOID) &rate);
- if (stat) {
- return (FALSE);
- }
- lc.bDataBits = (BYTE) databits;
- switch (stopbits) {
- case 1:
- lc.bStopBits = 0;
- break;
- case 2:
- lc.bStopBits = 2;
- break;
- default:
- if (databits == 5)
- lc.bStopBits = 1;
- }
- lc.fbTransBreak = 0;
- switch (toupper(parity)) {
- case 'N':
- lc.bParity = 0;
- break;
- case 'O':
- lc.bParity = 1;
- break;
- case 'E':
- lc.bParity = 2;
- break;
- case 'M':
- lc.bParity = 3;
- break;
- case 'S':
- lc.bParity = 4;
- break;
- default:
- debug_msg("Bad parity '%c'", parity);
- return (FALSE);
- }
- stat = IOCtl(ASYNC_SETLINECTRL, (PVOID) 0L, (PVOID) &lc);
- if (stat) {
- return (FALSE);
- }
- return (TRUE);
- }
-
- static int com_getDCB(struct _DCBINFO far * dcb)
- {
- int stat;
-
- stat = IOCtl(ASYNC_GETDCBINFO, (PVOID) dcb, (PVOID) 0L);
- return (!stat);
- }
-
- static int com_setDCB(struct _DCBINFO far * dcb)
- {
- int stat;
-
- stat = IOCtl(ASYNC_SETDCBINFO, (PVOID) 0L, (PVOID) dcb);
- return (!stat);
- }
-
- void com_XON_disable(void)
- {
- DCBINFO sDCB;
-
- if (com_getDCB((struct _DCBINFO far *) &sDCB)) {
- /* disable auto Xmit and recv flow control */
- sDCB.bFlags2 &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
- com_setDCB((struct _DCBINFO far *) &sDCB);
- }
- }
-
- void com_XON_enable(void)
- {
- DCBINFO sDCB;
-
- if (com_getDCB((struct _DCBINFO far *) &sDCB)) {
- /* enable auto Xmit and recv flow control */
- sDCB.bFlags2 |= (MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
- com_setDCB((struct _DCBINFO far *) &sDCB);
- }
- }
-
- /* nuke receive buffer */
- void com_clear_in(void)
- {
- int stat;
- char FlushParm = 0; /* param to flush IOCTL function */
-
- Rbytes = rpos = 0;
- stat = DosDevIOCtl((PVOID) 0L, (PVOID) &FlushParm, DEV_FLUSHINPUT, IOCTL_GENERAL, hfComHandle);
- if (stat) {
- debug_msg("DEV_FLUSHINPUT err 0x%04x", stat);
- }
- }
-
- /* com_getbuf() : return negative value if error */
- int com_getbuf(void)
- {
- int stat = 0;
- RXQUEUE q;
- USHORT Rbytet;
-
- if (rpos == Rbytes) /* If buffer empty, */
- rpos = Rbytes = 0; /* reset pointers */
-
- Rbytet = Rbytes; /* Save old count */
- Rbytes = 0; /* Clear new count */
-
- if (!(IOCtl(ASYNC_GETINQUECOUNT, (PVOID) &q, (PVOID) 0L))) {
- if (q.cbChars > 0)
- stat = DosRead(hfComHandle, rbuf+Rbytet, (USHORT) min(RQBbytes-Rbytet,q.cbChars), &Rbytes);
- else
- return (-1);
- } else
- return (-1);
-
- if (stat && !Rbytes && (!(stat==ERROR_MORE_DATA))) {
- debug_msg("DosRead() error 0x%04x", stat);
- return (-1);
- }
-
- Rbytes += Rbytet;
- return (TRUE);
- }
-
- /* com_getchar() : return negative value if error */
- int com_getchar(void)
- {
- if (rpos != Rbytes)
- return ((int) rbuf[rpos++]);
-
- if (com_getbuf() == TRUE)
- return ((int) rbuf[rpos++]);
- return (-1);
- }
-
- /*non destructive read ahead; no wait */
- int com_peek(void)
- {
- int c;
-
- if (!com_char_avail())
- c = -1;
- else {
- c = com_getchar();
- if (c != -1)
- rpos--;
- }
- return (c);
- }
-
- /* if RXQueue over half full, return TRUE */
- bool com_in_check(void)
- {
- RXQUEUE q;
-
- if (IOCtl(ASYNC_GETINQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return (FALSE);
- return ((bool)((q.cbChars > RQBbyte2) ? TRUE : FALSE));
- }
-
- /* return number of chars in input buffer */
- int com_char_avail(void)
- {
- RXQUEUE q;
-
- if (rpos < Rbytes)
- return (Rbytes-rpos);
-
- return ((!(IOCtl(ASYNC_GETINQUECOUNT, (PVOID) (PVOID) &q, 0L))) ? q.cbChars : FALSE );
- }
-
- /* return non 0 value if carrier detected */
- bool com_online(void)
- {
- BYTE msr;
-
- if (hfComHandle == -1)
- return(FALSE);
- if (IOCtl(ASYNC_GETMODEMINPUT, (PVOID) &msr, (PVOID) 0L))
- return (FALSE);
- return (msr & DCD_ON);
- }
-
- /* com_break() : start break if on==TRUE, stop break if on==FALSE */
- void com_break(int on)
- {
- int cmd;
- USHORT comerr;
-
- cmd = (on) ? ASYNC_SETBREAKON : ASYNC_SETBREAKOFF;
- IOCtl(cmd, (PVOID) &comerr, (PVOID) 0L);
- }
-
- /* com_out_empty() : return TRUE if output buffer is empty */
- bool com_out_empty(void)
- {
- RXQUEUE q;
-
- if (IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return (TRUE);
-
- if (!com_online())
- return (TRUE);
-
- if (com_in_check())
- (void) com_getbuf();
-
- /* if (DosSemWait((HSEM) &WriteSem, 1L))
- return (FALSE); */
-
- if (IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return (TRUE);
-
- return ((bool) (q.cbChars < q.cbQueue));
- }
-
- /* com_out_full() : return TRUE if output buffer is full */
- bool com_out_full(void)
- {
- RXQUEUE q;
-
- if (com_in_check())
- (void) com_getbuf();
- if (!com_online())
- return (FALSE);
-
- /* if (DosSemWait((HSEM) &WriteSem, 1L))
- return (TRUE); */
-
- if (IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return (TRUE);
-
- return ((bool) !(q.cbChars < q.cbQueue));
- }
-
- /* nuke transmit buffer */
- void com_clear_out(void)
- {
- char FlushParm = 0; /* param to flush IOCTL function */
- int stat;
-
- /* do {
- if (!com_online())
- break;
- if (com_in_check())
- (void) com_getbuf();
- } while(DosSemWait((HSEM) &WriteSem, 1L)); */
-
- stat = IOCtl(ASYNC_STARTTRANSMIT, (PVOID) 0L, (PVOID) 0L);
- if (stat) {
- debug_msg("ASYNC_STARTTRANSMIT err 0x%04x", stat);
- }
-
- zap_zbuf();
-
- stat = DosDevIOCtl((PVOID) 0L, (PVOID) &FlushParm, DEV_FLUSHOUTPUT, IOCTL_GENERAL, hfComHandle);
- if (stat) {
- debug_msg("DEV_FLUSHOUTPUT err 0x%04x", stat);
- }
- DosSemClear((HSEM) &WriteSem);
- }
-
- /* com_putc_now() : disregard any buffering and send a byte now damnit! */
- /* this function should be called only during emergencies...like when
- * trying to cancel a file transfer
- */
- /* Since the equivalent is a Com_ call, which in DOS is unsigned... */
- unsigned com_putc_now(byte c)
- {
- return (!IOCtl(ASYNC_TRANSMITIMM, (PVOID) 0L, (PVOID) &c));
- }
-
- /* com_putc() : output to com port */
- /* This function is very slow..where possile, write to com port in blocks
- * using com_write() instead...especially above 2400 bps
- */
- void com_putc(byte c)
- {
- static USHORT bytes;
- int stat;
- RXQUEUE q;
-
- if (IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return;
-
- do {
- if (com_in_check())
- (void) com_getbuf();
- } while(DosSemWait((HSEM) &WriteSem, 1L));
-
- do {
- if (IOCtl(ASYNC_GETOUTQUECOUNT, (PVOID) &q, (PVOID) 0L))
- return;
- if (com_in_check())
- (void) com_getbuf();
- if (q.cbChars >= q.cbQueue)
- DosSleep (1L);
- } while (q.cbChars >= q.cbQueue);
-
- /*
- * DosWriteAsync() didn't work here.
- */
- if (stat = DosWrite(hfComHandle, &c, 1, &bytes))
- debug_msg("DosWrite() err 0x%04x", stat);
- }
-
- /* com_write() : buffered block write */
- void com_write(char *buf, unsigned int num, int carcheck)
- {
- static USHORT err, bytes;
- #ifdef MultiWrt
- unsigned int tnum = 0;
- #endif
-
- do {
- if ((carcheck) && !com_online())
- return;
- if (com_in_check())
- (void) com_getbuf();
- } while(DosSemWait((HSEM) &WriteSem, 1L));
-
- (void) DosSemRequest((HSEM) &WriteSem, 0L);
-
- #ifdef MultiWrt
- while (tnum+TQSize > num+TQSize) {
- memcpy (tBuf, &buf[tnum], TQSize);
- DosWriteAsync(hfComHandle, (PULONG) &WriteSem, &err, tBuf, TQSize, &bytes);
- tnum += TQSize;
- do {
- if ((carcheck) && !com_online())
- return;
- if (com_in_check())
- (void) com_getbuf();
- } while(DosSemWait((HSEM) &WriteSem, 1L));
-
- (void) DosSemRequest((HSEM) &WriteSem, 0L);
- }
-
- memcpy (tBuf, &buf[tnum], num-tnum);
- DosWriteAsync(hfComHandle, (PULONG) &WriteSem, &err, tBuf, num-tnum, &bytes);
- #else
-
- memcpy (tBuf, buf, num);
- DosWriteAsync(hfComHandle, (PULONG) &WriteSem, &err, tBuf, num, &bytes);
- #endif
- }
-
- /* wait for output buffer to empty */
- void com_wait(void)
- {
- while ((!com_out_empty()) && com_online())
- DosSleep (1L);
- }
-
- extern unsigned int baud;
- extern unsigned int comm_bits;
- extern unsigned int parity;
- extern unsigned int stop_bits;
- extern struct baud_str btypes[];
-
- void MDM_ENABLE(unsigned rate)
- {
- char _parity;
- int databits;
- int stopbits;
-
- com_clear_out();
- com_clear_in();
- databits = 7 + (comm_bits == BITS_8);
- stopbits = 1 + (stop_bits == STOP_2);
- switch (parity) {
- case NO_PARITY:
- _parity = 'N';
- break;
- case ODD_PARITY:
- _parity = 'O';
- break;
- case EVEN_PARITY:
- _parity = 'E';
- break;
- }
- com_set_baud(rate, _parity, databits, stopbits);
- }
-
- void MDM_DISABLE(void)
- {
- if (hfComHandle == -1)
- return;
- com_clear_out();
- com_clear_in();
- com_fini();
- }
-
- /* zsend.c uses BUFFER_BYTE and UNBUFFER_BYTES...good idea. */
- void BUFFER_BYTE(unsigned char ch)
- {
- if (zpos == tBufsize)
- UNBUFFER_BYTES();
- zTxBuf[zpos++] = ch;
- }
-
- void UNBUFFER_BYTES(void)
- {
- if (com_online() && zpos)
- (zpos == 1)?(com_putc(zTxBuf[0])):(com_write(zTxBuf,zpos,1));
- zpos = 0;
- }
-
- static void zap_zbuf(void)
- {
- zpos = 0;
- }
-
- unsigned Cominit(int port)
- {
- if (hfComHandle != -1)
- com_fini();
- if (port == 0xff || com_init(port, NULL))
- return (0x1954);
- else
- return (0);
- }
- #endif /* OS_2 */