home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / croutes.zip / IBMTTY.C < prev    next >
Text File  |  1984-06-25  |  16KB  |  646 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. /*********************************************************************/
  316. /* Output a horizontal tab to screen while checking communications   */
  317. /* port for transmission.  Returns a -1 if an error occured.         */
  318. /*                                                                   */
  319. int dotab()
  320. {
  321.     static int iret,irow,icol;
  322.  
  323.     /* check comm port for receiption of data */
  324.     if ((iret = readcomm()) == (-1)) {
  325.         return(-1);
  326.     }
  327.  
  328.     /* find cursor position */
  329.     iret = biospos();
  330.     icol = iret & 255;    /* column returned in low order bits */
  331.     irow = iret >> 8;    /* row returned in high order bits */
  332.  
  333.     /* check comm port for receiption of data */
  334.     if ((iret = readcomm()) == (-1)) {
  335.         return(-1);
  336.     }
  337.  
  338.     /* calculate tab position */
  339.     icol++;
  340.     while ((icol % 8) != 0) {
  341.         icol++;
  342.     }
  343.  
  344.     /* set cursor to that position */
  345.     biosset(irow,icol);
  346.  
  347.     return(0);
  348. }
  349.  
  350. /*********************************************************************/
  351. /* write characters to communications port for transmission.  Return */
  352. /* a -1 if error, 0 if no characters written, or character written.  */
  353. /*                                                                   */
  354. int wrtcomm()
  355. {
  356.     static char c,pushback;
  357.     static int iret,lstat;
  358.  
  359.     /* write characters to communications port for transmission */
  360.     lstat=inp(lsr);
  361.     if (((lstat&32) != 0) && (!gotxoff)) {
  362.  
  363.         /* write characters received from keyboard */
  364.         if ((iret=getbuf(&com)) != (-1)) {
  365.             c = iret&127;
  366.             outp(thr,c);
  367.             if (lecho) putbuf(&crt,c);
  368.             return(c);
  369.  
  370.         /* write characters from file */
  371.         } else if (outchan) {
  372.             if (pushback != NULL) {
  373.                 outp(thr,pushback);
  374.                 pushback = NULL;
  375.                 if (lecho) putbuf(&crt,pushback);
  376.                 return(pushback);
  377.             }
  378.  
  379.             if ((iret=getbuf(&mem)) == (-1)) {
  380.                 outp(thr,CONZ);
  381.                 fclose(outchan);
  382.                 outchan = FALSE;
  383.                 mem.wbuf = mem.rbuf = mem.fbuf;
  384.                 return(0);
  385.             }
  386.  
  387.             c = iret&127;
  388.             if (c == '\n') {
  389.                 outp(thr,'\r');
  390.                 if (lecho) {
  391.                     putbuf(&crt,'\r');
  392.                     putbuf(&crt,'\n');
  393.                 } else {
  394.                     dowait();
  395.                 }
  396.             } else {
  397.                 outp(thr,c);
  398.                 if (lecho) putbuf(&crt,c);
  399.             }
  400.             return(c);
  401.         }
  402.     }
  403.  
  404.     return(0);
  405. }
  406.  
  407. /*********************************************************************/
  408. /* Function to wait until the receiption of a line feed after the    */
  409. /* transmission of a carriage return.                                */
  410. /*                                                                   */
  411. int dowait()
  412. {
  413.     int iret;
  414.  
  415.     /* loop */
  416.     while ((iret=readcomm()) != '\n') {
  417.         if (iret == -1) break;
  418.     }
  419.  
  420.     return(0);
  421. }
  422.  
  423. /*********************************************************************/
  424. /* Check the keyboard for receipt of a character and buffer it.      */
  425. /* Returns a -1 if error occured, 0 if no character at keyboard, or  */
  426. /* character typed.                                                  */
  427. /*                                                                   */
  428. /* kbhit() is a special IBM-PC microsoft "C" function.               */
  429. /*                                                                   */
  430. int readkey()
  431. {
  432.     static char c;
  433.  
  434.     /* check for keyboard entry */
  435.     if (kbhit()) {
  436.         c = readc();
  437.  
  438.         /* display menu if ESCAPE entered */
  439.         if (c == ESC) {
  440.             doesc();
  441.             return(c);
  442.         }
  443.  
  444.         /* character mapping */
  445.         if (c == '\b') {
  446.             c = DEL;
  447.         } else if (c == '\n') {
  448.             c = '\r';
  449.         }
  450.  
  451.         /* store character in keyboard buffer */
  452.         if (putbuf(&com,c) == (-1)) {
  453.             writes("\007");        /* buffer full */
  454.             return(-1);
  455.         }
  456.         return(c);
  457.     }
  458.  
  459.     return(0);
  460. }
  461.  
  462. /*********************************************************************/
  463. /* Write a character into a buffer.  Returns a -1 if overflow.       */
  464. /*                                                                   */
  465. int putbuf(p,c)
  466. struct buf *p;
  467. char c;
  468. {
  469.     *p->wbuf = c;
  470.  
  471.     /* increment (possible wrap-around) pointer */
  472.     if (++p->wbuf > p->lbuf) p->wbuf = p->fbuf;
  473.  
  474.     /* if overflow, indicate */
  475.     if (p->wbuf == p->rbuf) {
  476.         if (--p->wbuf < p->fbuf) p->wbuf = p->lbuf;
  477.         return(-1);
  478.     }
  479.  
  480.     return(0);
  481. }
  482.  
  483. /*********************************************************************/
  484. /* Read a character from a buffer.  Returns a -1 if buffer is empty. */
  485. /*                                                                   */
  486. int getbuf(p)
  487. struct buf *p;
  488. {
  489.     static int c;
  490.  
  491.     /* empty */
  492.     if (p->rbuf == p->wbuf) return(-1);
  493.  
  494.     /* get char, increment (possible wrap-around) pointer */
  495.     c = *p->rbuf;
  496.     if (++p->rbuf > p->lbuf) p->rbuf = p->fbuf;
  497.  
  498.     return(c);
  499. }
  500.  
  501. /*********************************************************************/
  502. /* Function to do special features.                                  */
  503. /*                                                                   */
  504. int doesc()
  505. {
  506.     char ans[3],memsiz[6];
  507.     char c;
  508.     int iret,ians;
  509.  
  510.     /* output special information */
  511.     loop:
  512.     escreen(2);        /* erase screen */
  513.  
  514.     writes("\r\n memory buffer is : ");
  515.     sprintf(memsiz,"%u",(mem.wbuf-mem.fbuf));
  516.     writes(memsiz);
  517.     writes("/");
  518.     sprintf(memsiz,"%u",(mem.lbuf-mem.fbuf));
  519.     writes(memsiz);
  520.  
  521.     writes("\r\n receive file is  : ");
  522.     writes((inchan)?infil:"<OFF>");
  523.  
  524.     writes("\r\n transmit file is : ");
  525.     writes((outchan)?outfil:"<OFF>");
  526.  
  527.     writes("\r\n local echo is    : ");
  528.     writes((lecho)?"<ON>":"<OFF>");
  529.  
  530.     /* output menu and accept choice */
  531.     if ((ians=chosit("comm",ans,sizeof(ans))) == (-1)) {
  532.         writes("\r\n\007*** error displaying menu ***");
  533.         ians = 4;
  534.     }
  535.  
  536.     /* execute command */
  537.     switch (ians) {
  538.  
  539.         case 5:
  540.             if (inchan) {
  541.                 wrtbuf();
  542.                 fclose(inchan);
  543.             }
  544.             if (outchan) fclose(outchan);
  545.             outp(mcr,0);    /* drop DTR and RTS */
  546.             writes("\r\n");
  547.             exit();
  548.             break;
  549.  
  550.         case 4:
  551.             cursor(25,1);
  552.             writes("\r\n*** you are now back as a terminal ***\r\n");
  553.             return(0);
  554.             break;
  555.  
  556.         case 3:
  557.             lecho = !lecho;
  558.             break;
  559.  
  560.         case 2:
  561.             if (outchan) {
  562.                 fclose(outchan);
  563.                 outchan = FALSE;
  564.                 mem.wbuf = mem.rbuf = mem.fbuf;
  565.             } else {
  566.                 if (inchan) {
  567.                     wrtbuf();
  568.                     fclose(inchan);
  569.                     inchan = FALSE;
  570.                 }
  571.                 sendfile:
  572.                 writes("\r\n\nFilename? ");
  573.                 reads(outfil,sizeof(outfil));
  574.                 if (outfil[0] == NULL) goto done;
  575.  
  576.                 if ((outchan=fopen(&outfil[0],"r")) == NULL) {
  577.                     writes("\007  *** can't open file ***");
  578.                     goto sendfile;
  579.                 }
  580.  
  581.                 readbuf();
  582.             }
  583.             break;
  584.  
  585.         case 1:
  586.             if (inchan) {
  587.                 wrtbuf();
  588.                 fclose(inchan);
  589.                 inchan = FALSE;
  590.             } else {
  591.                 if (outchan) {
  592.                     fclose(outchan);
  593.                     outchan = FALSE;
  594.                     mem.wbuf = mem.rbuf = mem.fbuf;
  595.                 }
  596.                 savefile:
  597.                 writes("\r\n\nFilename? ");
  598.                 reads(infil,sizeof(infil));
  599.                 if (infil[0] == NULL) goto done;
  600.  
  601.                 if ((inchan=fopen(&infil[0],"w")) == NULL) {
  602.                     writes("\007  *** can't open file ***");
  603.                     goto savefile;
  604.                 }
  605.             }
  606.             break;
  607.  
  608.     }
  609.     done:
  610.     goto loop;
  611. }
  612.  
  613. /*********************************************************************/
  614. /* Function to write the data receiption buffer to output file.      */
  615. /*                                                                   */
  616. int wrtbuf()
  617. {
  618.     for (mem.rbuf=mem.fbuf;mem.rbuf<mem.wbuf;mem.rbuf++) {
  619.         fputc(*mem.rbuf,inchan);
  620.     }
  621.  
  622.     mem.wbuf = mem.rbuf = mem.fbuf;
  623.     return(0);
  624. }
  625.  
  626. /*********************************************************************/
  627. /* Function to read a file into the file transmission buffer.        */
  628. /* Returns a 0 if successful, or a -1 if buffer overflow.            */
  629. /*                                                                   */
  630. int readbuf()
  631. {
  632.     static char c;
  633.     static int iret;
  634.  
  635.     /* loop until end-of-file is found */
  636.     while ((iret=getc(outchan)) != EOF) {
  637.         c = iret&127;
  638.         if ((putbuf(&mem,c)) == (-1)) {
  639.             writes("\r\n\007*** file transmission buffer overflow ***");
  640.             return(-1);
  641.         }
  642.     }
  643.  
  644.     return(0);
  645. }
  646.