home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 153_01 / ibmtty.c < prev    next >
Text File  |  1985-03-11  |  16KB  |  649 lines

  1. /*                          *** ibmtty.c ***                         */
  2. /*                                                                   */
  3. /* IBM-PC microsoft "C" under PC-DOS                                 */
  4. /*                                                                   */
  5. /* Terminal emulation program with file upload and download capabili-*/
  6. /* ties.  Optimized to communicate with a DEC VAX 11/780.            */
  7. /*                                                                   */
  8. /* Written by L. Cuthbertson, April 1984.                            */
  9. /*                                                                   */
  10. /*********************************************************************/
  11. /*                                                                   */
  12.  
  13. #include <stdio.h>
  14.  
  15. #define TRUE 1
  16. #define FALSE 0
  17. #define XON '\021'
  18. #define XOFF '\023'
  19. #define ESC '\033'
  20. #define CONZ '\032'
  21. #define DEL '\177'
  22.  
  23. #define LCR 0x3FB    /* 8250 line control register */
  24. #define DLL 0x3F8    /* 8250 least significant divisor latch */
  25. #define DLM 0x3F9    /* 8250 most significant divisor latch */
  26. #define LSR 0x3FD    /* 8250 line status register */
  27. #define IIR 0x3FA    /* 8250 interrupt identification register */
  28. #define IER 0x3F9    /* 8250 interrupt enable register */
  29. #define MCR 0x3FC    /* 8250 modem control register */
  30. #define MSR 0x3FE    /* 8250 modem status register */
  31. #define RBR 0x3F8    /* 8250 receiver buffer register */
  32. #define THR 0x3F8    /* 8250 transmitter holding register */
  33.  
  34. char *lcr=(char*)LCR, *dll=(char*)DLL, *dlm=(char*)DLM;
  35. char *lsr=(char*)LSR, *iir=(char*)IIR, *ier=(char*)IER;
  36. char *mcr=(char*)MCR, *msr=(char*)MSR, *rbr=(char*)RBR;
  37. char *thr=(char*)THR;
  38.  
  39. struct buf {
  40.     char *fbuf;
  41.     char *wbuf,*rbuf;
  42.     char *lbuf;
  43. };
  44.  
  45. struct buf mem;            /* file receiption/transmission buff */
  46.  
  47. char combuf[64];        /* transmission buffer */
  48. struct buf com;
  49.  
  50. char crtbuf[512];        /* receiption buffer */
  51. struct buf crt;
  52.  
  53. char outfil[13];        /* transmit file name */
  54. FILE *outchan;
  55.  
  56. char infil[13];            /* receive file name */
  57. FILE *inchan;
  58.  
  59. char lecho = FALSE;
  60. char gotxoff = FALSE;
  61. char sendxoff = FALSE;
  62. char sentxoff = FALSE;
  63.  
  64. /*********************************************************************/
  65. /*                                                                   */
  66. main(argc,argv)
  67. int argc;
  68. char *argv[];
  69. {
  70.     char *malloc();
  71.     int iret,port;
  72.     unsigned u;
  73.  
  74.     /* initialize file receiption/transmission */
  75.     inchan = FALSE;
  76.     outchan = FALSE;
  77.  
  78.     /* set up buffer structures */
  79.     com.fbuf = com.wbuf = com.rbuf = &combuf[0];
  80.     com.lbuf = &combuf[0] + sizeof(combuf) - 1;
  81.     crt.fbuf = crt.wbuf = crt.rbuf = &crtbuf[0];
  82.     crt.lbuf = &crtbuf[0] + sizeof(crtbuf) - 1;
  83.  
  84.     /* allocate as much memory as possible to file buffer */
  85.     for (u=65023;;u -= 512) {
  86.         if (u < (512+(5*_BUFSIZ))) {
  87.             writes("\r\n\007*** not enough memory available ***");
  88.             exit();
  89.         }
  90.         mem.fbuf = malloc(u);
  91.         if (mem.fbuf != 0) {
  92.             free(mem.fbuf);
  93.             u -= 5*_BUFSIZ;
  94.             mem.fbuf = malloc(u);
  95.             break;
  96.         }
  97.     }
  98.  
  99.     mem.wbuf = mem.rbuf = mem.fbuf;
  100.     mem.lbuf = mem.fbuf + u - 1;
  101.  
  102.     /* determine communications port to use */
  103.     if (argc > 1) {
  104.         sscanf(argv[1],"%d",&port);
  105.         port--;
  106.         if ((port < 0) || (port > 1)) {
  107.             writes("\r\n\007*** invalid communications port - enter 1 or 2 ***");
  108.             exit();
  109.         }
  110.     } else {
  111.         port = 0;
  112.     }
  113.  
  114.     /* adjust port addresses if neccessary */
  115.     if (port == 1) {
  116.         lcr -= 0x100;
  117.         dll -= 0x100;
  118.         dlm -= 0x100;
  119.         lsr -= 0x100;
  120.         iir -= 0x100;
  121.         ier -= 0x100;
  122.         mcr -= 0x100;
  123.         msr -= 0x100;
  124.         rbr -= 0x100;
  125.         thr -= 0x100;
  126.     }
  127.  
  128.     /* initialize 8250  - use DOS "MODE" command */
  129.     outp(mcr,3);        /* send DTR and RTS */
  130.     pause(1.);
  131.  
  132.     /* check for carrier */
  133.     if ((inp(msr)&48) != 48) {
  134.         writes("\r\n\007*** carrier not detected - please check your connections ***");
  135.         exit();
  136.     }
  137.  
  138.     /* courtesy message */
  139.     cursor(25,1);
  140.     writes("\r\n*** you are now connected ***\r\n");
  141.  
  142.     /* polling loop */
  143.     for (;;) {
  144.  
  145.         /* check communications port for reception of data */
  146.         if ((readcomm()) != 0)
  147.             ;
  148.  
  149.         /* check if screen output needed */
  150.         if ((wrtscr()) != 0)
  151.             ;
  152.  
  153.         /* check communications port for receiption of data */
  154.         if ((readcomm()) != 0)
  155.             ;
  156.  
  157.         /* write characters to comm port for transmission */
  158.         if ((wrtcomm()) != 0)
  159.             ;
  160.  
  161.         /* check communications port for receiption of data */
  162.         if ((readcomm()) != 0)
  163.             ;
  164.  
  165.         /* check for screen output */
  166.         if ((wrtscr()) != 0)
  167.             ;
  168.  
  169.         /* check communications port for receiption of data */
  170.         if ((readcomm()) != 0)
  171.             ;
  172.  
  173.         /* check for keyboard entry */
  174.         if ((readkey()) != 0)
  175.             ;
  176.  
  177.     }
  178. }
  179.  
  180. /*********************************************************************/
  181. /* Check the comm port for receiption of data and puts recieved data */
  182. /* into buffers.  Returns a -1 if error detected, 0 if no data, or   */
  183. /* the character received.                                           */
  184. /*                                                                   */
  185. int readcomm()
  186. {
  187.     static char oldc = NULL;
  188.     static char c;
  189.     static int iret;
  190.  
  191.     /* check comm port for data receiption */
  192.     iret = inp(lsr);
  193.     if ((iret&1) != 0) {
  194.  
  195.         /* ignore data overrun errors */
  196.         /* expect to loose padd characters at high baud rate */
  197.         if ((iret&2) != 0) {
  198.             ;
  199.  
  200.         /* framing or parity error */
  201.         } else if ((iret&12) != 0) {
  202.             writes("\007*** data reception error ***");
  203.             return(-1);
  204.  
  205.         /* break currenly being sent */
  206.         } else if ((iret&16) != 0) {
  207.             return(0);    /* break detect */
  208.         }
  209.  
  210.         /* read character */
  211.         c = inp(rbr)&127;
  212.  
  213.         /* process character */
  214.         if (c == XOFF) {
  215.             gotxoff = TRUE;
  216.         } else if (c == XON) {
  217.             gotxoff = FALSE;
  218.         } else if (c != NULL) {
  219.  
  220.             /* prevent CR CR LF line endings */
  221.             if ((c != '\r') || (oldc != '\r')) {
  222.  
  223.                 /* store character in receiption buffer */
  224.                 if ((putbuf(&crt,c)) == (-1)) {
  225.                     writes("\007*** screen buffer overflow ***");
  226.                     return(-1);
  227.                 }
  228.  
  229.                 /* store character if file receiption buffer */
  230.                 if (inchan) {
  231.                     if ((putbuf(&mem,c)) == (-1)) {
  232.                         writes("\007*** file receiption buffer overflow ***");
  233.                         inchan = FALSE;
  234.                         return(-1);
  235.                     }
  236.                 }
  237.             }
  238.             oldc = c;
  239.         }
  240.         return(c);
  241.     }
  242.  
  243.     /* no character found */
  244.     return(0);
  245. }
  246.  
  247. /*********************************************************************/
  248. /* write characters from the screen buffer to the screen.  Returns a */
  249. /* -1 if error occured, 0 if no characters in buffer, or character   */
  250. /* written.                                                          */
  251. /*                                                                   */
  252. int wrtscr()
  253. {
  254.     static char c;
  255.     static int i,iret;
  256.  
  257.     /* get character from screen buffer */
  258.     if ((iret = getbuf(&crt)) != (-1)) {
  259.         c = iret&127;    /* strip parity */
  260.  
  261.         /* if line feed then scroll screen */
  262.         if (c == '\n') {
  263.             if ((iret = doscr()) == (-1)) {
  264.                 return(-1);
  265.             }
  266.  
  267.         /* handle tabs seperatly */
  268.         } else if (c == '\t') {
  269.             if ((iret = dotab()) == (-1)) {
  270.                 return(-1);
  271.             }
  272.  
  273.         /* output other characters */
  274.         } else {
  275.             biostty(c);
  276.         }
  277.         return(c);
  278.     }
  279.  
  280.     /* no character in buffer */
  281.     return(0);
  282. }
  283.  
  284. /*********************************************************************/
  285. /* scroll the screen up one line at a time while checking the comm   */
  286. /* port for data receiption.  Returns a -1 if an error occured.      */
  287. /*                                                                   */
  288. int doscr()
  289. {
  290.     static char fillchar;
  291.     static int trow,tlcol,brow,brcol;
  292.     static int iret;
  293.  
  294.     /* initialize */
  295.     fillchar = 0x20;    /* fill opened line with blanks */
  296.     tlcol = 0;        /* top left column of window */
  297.     brcol = 79;        /* bottom right column of window */
  298.  
  299.     /* begin check and scroll loop */
  300.     for(trow=0;trow<24;trow++) {
  301.  
  302.         /* check comm port for data receiption */
  303.         if ((iret = readcomm()) == (-1)) {
  304.             return(-1);
  305.         }
  306.  
  307.         /* scroll 1 line up */
  308.         brow = trow + 1;
  309.         biosup(1,trow,tlcol,brow,brcol,fillchar);
  310.     }
  311.  
  312.     return(0);
  313. }
  314.  
  315. /*********************************************