home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / modem / commsupp.arc / COMMTERM.C < prev   
Text File  |  1988-07-21  |  12KB  |  469 lines

  1. /*
  2.   commterm.c - a stupid communications program demonstrating the use of
  3.                commsupp.c and commasm.a
  4.  
  5.   Tom Poindexter, March 1984
  6.  
  7. */
  8.  
  9. /* #include "commsupp.h" (included inline here) */
  10. /* commsupp.h    - commsupp declares and defines */
  11.  
  12. /*
  13.   init_com   - initialize comm port, interrupts, baud, data, parity, stop, buf
  14.   uninit_com - disable interrupts, flushes buffer
  15.   send_brk   - send break signal
  16.   set_xoff   - enable XON, XOFF protocol
  17.   recd_xoff  - return true if XOFF received, reset recd_xoff flag
  18.   sent_xoff  - return true if XOFF sent, reset sent_xoff flag
  19.   inp_cnt    - returns the number of unread bytes in receive buffer
  20.   inp_char   - return one byte from buffer
  21.   inp_strn   - transfer n bytes from buffer to string
  22.   outp_char  - send one byte
  23.   outp_strn  - send n bytes of a string, up to end of string
  24.   com_stat   - return line status (high byte) and modem status (low byte)
  25.   on_com     - specify a routine to execute when a character is received
  26. */
  27.  
  28. /* declare entry points to commsupp routines */
  29.  
  30. int  init_com();   /* init_com(port,baud,parity,data,stop,buff_len); */
  31. int  uninit_com(); /* uninit_com(port,lv_open);  */
  32. int  send_brk();   /* send_brk(port);            */
  33. int  set_xoff();   /* set_xoff(port,xoff_state); */
  34. int  recd_xoff();  /* recd_xoff(port);           */
  35. int  sent_xoff();  /* sent_xoff(port);           */
  36. int  inp_cnt();    /* inp_cnt(port);             */
  37. int  inp_char();   /* inp_char(port);            */
  38. int  inp_strn();   /* inp_strn(port,&str,cnt);   */
  39. int  outp_char();  /* outp_char(port,c);         */
  40. int  outp_strn();  /* outp_strn(port,&str,cnt);  */
  41. int  com_stat();   /* com_stat(port);            */
  42. int  on_com();     /* on_com(port,routine);      */
  43.  
  44. /* define for values returned by routines */
  45. #define ERROR     -1
  46. #define TRUE      1
  47. #define FALSE     0
  48.  
  49. /* defines for parity (init_com) */
  50. #define PARITY_NONE  0
  51. #define PARITY_ODD   1
  52. #define PARITY_EVEN  2
  53. #define PARITY_MARK  3
  54. #define PARITY_SPACE 4
  55.  
  56. /* defines for comm errors - mask using com_stat value */
  57. #define OVER_RUN    0x0200
  58. #define PARITY_ERR  0x0400
  59. #define FRAME_ERR   0x0800
  60. #define BREAK_IND   0x1000
  61.  
  62. /* defines for modem conditions - mask using com_stat value */
  63. #define CLEAR_SEND  0x0010
  64. #define DATASET_RDY 0x0020
  65. #define RING_IND    0x0040
  66. #define CARRIER     0x0080
  67.  
  68. /* end of commsupp.h */
  69.  
  70.  
  71. #define ALT_H  0x2300  /* help  */
  72. #define ALT_B  0x3000  /* break */
  73. #define ALT_X  0x2d00  /* exit  */
  74. #define ALT_E  0x1200  /* echo  */
  75. #define ALT_S  0x1f00  /* pause */
  76. #define ALT_Q  0x1000  /* resume*/
  77. #define PGUP   0x4900  /* upload */
  78. #define PGDN   0x5100  /* download */
  79. #define NUL    0
  80. #define BS     8
  81. #define LF     10
  82. #define CR     13
  83. #define XON    17
  84. #define XOFF   19
  85. #define DELAY  5000
  86.  
  87. int max;
  88. unsigned total,min_sp;
  89.  
  90. #include "stdio.h"
  91.  
  92. main ()
  93.  
  94. {
  95.   int port,baud,parity,data,stop,buff_len;
  96.   int c,e,x,i,n,x_state,counter;
  97.   int bytecount();
  98.   FILE f;
  99.   char strn[128];
  100.  
  101.  
  102.   puts("\n\n\ncommterm\n");
  103.  
  104.   puts("\nComm port (1 or 2)? ");
  105.   gets(strn);
  106.   port = atoi(strn);
  107.  
  108.   puts("\nBaud rate? ");
  109.   gets(strn);
  110.   baud = atoi(strn);
  111.  
  112.   puts("\nParity (0=none, 1=odd, 2=even, 3=mark, 4=space)? ");
  113.   gets(strn);
  114.   parity = atoi(strn);
  115.  
  116.   puts("\nData length (5 - 8)? ");
  117.   gets(strn);
  118.   data = atoi(strn);
  119.  
  120.   puts("\nStop bits (1 or 2)? ");
  121.   gets(strn);
  122.   stop = atoi(strn);
  123.  
  124.   puts("\nBuffer length? ");
  125.   gets(strn);
  126.   buff_len = atoi(strn);
  127.  
  128.   puts("\nXON/XOFF enabled (y or n)? ");
  129.   gets(strn);
  130.   x_state = (tolower(strn[0]) == 'y') ? TRUE : FALSE;
  131.  
  132.   if (init_com(port,baud,parity,data,stop,buff_len) == ERROR)
  133.    {
  134.     putchar(7);
  135.     puts("\n\nSorry, you screwed up somewhere along the line.\n\n");
  136.     exit();
  137.    }
  138.   else
  139.    {
  140.     set_xoff(port,x_state);
  141.     on_com(port,bytecount);
  142.    }
  143.  
  144.   puts("\nEnter modem initialization string: ");
  145.   gets(strn);
  146.   outp_strn(port,strn,128);
  147.   outp_char(port,CR);
  148.  
  149.   puts("\n\nPress ALT-H for help on special keys.\n\n");
  150.   total = max = c = e = n = 0;
  151.   min_sp = 0xffff;
  152.  
  153.   while (c != ALT_X)
  154.    {
  155.  
  156.     termin(port,1);
  157.  
  158.     if (com_stat(port) & BREAK_IND)
  159.       puts("\n\n**B R E A K**\n\n");
  160.  
  161.     c = key_in();
  162.     if (c > 0)
  163.      {
  164.       switch (c)
  165.        {
  166.         case ALT_H:
  167.          puts("\n\ncommterm help\n\n");
  168.          puts("press.........to\n");
  169.          puts("Alt-E.........echo key strokes\n");
  170.          puts("Alt-B.........send break signal\n");
  171.          puts("Alt-H.........help on keys\n");
  172.          puts("Alt-X.........exit program\n");
  173.          puts("Alt-S.........pause (XOFF)\n");
  174.          puts("Alt-Q.........resume (XON)\n");
  175.          puts("PgUp..........upload a file\n");
  176.          puts("PgDn..........download to a file\n");
  177.          puts("\n\ncontinue...\n\n");
  178.          break;
  179.  
  180.         case ALT_B:
  181.          send_brk(port);
  182.          break;
  183.  
  184.         case ALT_E:
  185.          e = !e;
  186.          break;
  187.  
  188.         case PGUP:
  189.          puts("\n\nUpload what file? ");
  190.          gets(strn);
  191.          f=fopen(strn,"r");
  192.          if (f == FALSE)
  193.           {
  194.            puts("\nERROR - file ");
  195.            puts(strn);
  196.            puts(" not found.....\n");
  197.           }
  198.          else
  199.           {
  200.            puts("\nUploading ");
  201.            puts(strn);
  202.            puts(", press PgUp key to abort.....\n\n");
  203.            while (fgets(strn,128,f) != FALSE && key_in() != PGUP)
  204.             {
  205.              termin(port,0);
  206.              for (i = 0; i < 128 && strn[i] != '\0'; i++)
  207.                {
  208.                 if (x_state && recd_xoff(port) == TRUE)
  209.                  {
  210.                   puts("\nXOFF received.  Waiting for XON or press any key to continue.\n");
  211.                   while (inp_char(port) != XON && csts() == FALSE)
  212.                     ;
  213.                  }
  214.                 outp_char(port,strn[i]);
  215.                 termin(port,0);
  216.                }
  217.               outp_char(port,CR);
  218.             }
  219.            fclose(f);
  220.            puts("\nUpload complete.\n\n");
  221.           }
  222.          break;
  223.  
  224.         case PGDN:
  225.          puts("\n\nDownload to what file? ");
  226.          gets(strn);
  227.          if ((f=fopen(strn,"r")) == FALSE)
  228.           {
  229.            if (strlen(strn) > 0)
  230.             {
  231.              puts("\nCreating ");
  232.              puts(strn);
  233.              puts("\n\n");
  234.              f = creat(strn);
  235.             }
  236.            else
  237.              f = 0;
  238.           }
  239.          else
  240.           {
  241.            fclose(f);
  242.            puts("\nFile ");
  243.            puts(strn);
  244.            puts(" exists, press 'e' to erase file or 'a' to add to it: ");
  245.            i = getchar();
  246.            if (tolower(i) == 'e')
  247.              f = creat(strn);
  248.            else
  249.              f = fopen(strn,"a");
  250.           }
  251.          puts("\n\nDownloading, press PgDn again to close file.\n\n");
  252.          counter = DELAY;
  253.          while (((c=key_in()) != PGDN) && (f != 0))
  254.           {
  255.            if (c != 0)
  256.              conout(c,e,port);
  257.            if (inp_cnt(port) > max) max = inp_cnt(port);
  258.            i = inp_cnt(port);
  259.            i = (i <= 127) ? i : 127;
  260.            inp_strn(port,strn,i);
  261.            strn[i] = '\0';
  262.            fputs(strn,f);
  263.            for (n = 0; strn[n] != '\0'; n++)
  264.              switch (strn[n])
  265.               {
  266.                case BS:
  267.                 putchar('\b');
  268.                 break;
  269.                case CR:
  270.                 putchar(CR);
  271.                 putchar(LF);
  272.                 break;
  273.                case LF:
  274.                 break;
  275.                case NUL:
  276.                 break;
  277.                default:
  278.                 putchar(strn[n]);
  279.               }
  280.            if (x_state && sent_xoff(port) == TRUE)
  281.             {
  282.              puts("\nXOFF sent. No test delay till buffer empties to 25%.\n");
  283.              outp_char(port,XOFF);
  284.              counter = 0;
  285.             }
  286.            if (x_state && counter == 0)
  287.             {
  288.              if (inp_cnt(port) < (buff_len * 1/4))
  289.                {
  290.                 puts("\nXON sent\n");
  291.                 outp_char(port,XON);
  292.                 counter = DELAY;
  293.                }
  294.             }
  295.            else
  296.              if (x_state)
  297.                /* dummy loop to test the XON/XOFF flow control */
  298.                for(i=0; i<counter; i++)
  299.                  ;
  300.           }
  301.          fclose(f);
  302.          puts("\nDownload complete.\n\n");
  303.  
  304.          break;
  305.  
  306.         default:
  307.          conout(c,e,port);
  308.          break;
  309.         }
  310.       }
  311.    }
  312.  
  313.   puts("\n\nExiting..\n");
  314.   puts("\nLeave port initialized (y or n)? ");
  315.   gets(strn);
  316.   x = (tolower(strn[0]) == 'y') ? TRUE : FALSE;
  317.  
  318.   uninit_com(port,x);
  319.  
  320.   printf("\nThe buffer high water mark reached %d of a buffer length of %d",
  321.          max,buff_len);
  322.  
  323.   printf("\nThe total number of characters received was %u",
  324.          total);
  325.  
  326.   printf("\nThe smallest stack space available was %u",
  327.          min_sp);
  328.  
  329. }  /* end of commterm.c */
  330.  
  331. bytecount () /* on comm routine */
  332. {
  333.  int m;
  334.  
  335.  m = _showsp();
  336.  if (m < min_sp)
  337.    min_sp = m;
  338.  total++;
  339. }
  340.  
  341. conout(c,e,port) /* send a character over the serial port, optionally echo */
  342. int c,e,port;
  343. {
  344.   switch (c)
  345.    {
  346.     case ALT_S:
  347.      /* DOS sometimes eats ^S as a pause (ala Ctrl-NumLock) */
  348.      outp_char(port,XOFF);
  349.      break;
  350.  
  351.     case ALT_Q:
  352.      outp_char(port,XON);
  353.      break;
  354.  
  355.     case CR:
  356.      if (e)
  357.       {
  358.        putchar(CR);
  359.        putchar(LF);
  360.       }
  361.      outp_char(port,CR);
  362.      break;
  363.  
  364.     case BS:
  365.      if (e)
  366.        putchar ('\b');
  367.      outp_char(port,BS);
  368.      break;
  369.  
  370.     default:
  371.      if (c < 128)
  372.       {
  373.        if (e)
  374.         putchar(c);
  375.        outp_char(port,c);
  376.       }
  377.      break;
  378.     }
  379. }
  380.  
  381.  
  382.  
  383. termin(port,x)  /* get characters from the serial port and print it */
  384. int port,x;
  385. {
  386.   int c;
  387.  
  388.     if (x)
  389.       if (recd_xoff(port))
  390.         puts("<<XOFF>>");
  391.  
  392.     if (inp_cnt(port) > max) max = inp_cnt(port);
  393.     while (inp_cnt(port))
  394.      {
  395.       c = inp_char(port);
  396.       switch (c)
  397.        {
  398.         case NUL:
  399.          break;
  400.  
  401.         case CR:
  402.          putchar(CR);
  403.          putchar(LF);
  404.          break;
  405.  
  406.         case LF:
  407.          break;
  408.  
  409.         case BS:
  410.          putchar('\b');
  411.          break;
  412.  
  413.         default:
  414.          putchar(c);
  415.          break;
  416.        }
  417.      }
  418.  
  419. }  /* end of termin */
  420.  
  421. /* ********************************************************************** */
  422.  
  423. /* key_in.c
  424.  
  425.       direct read of keyboard, including special keys.
  426.  
  427.       written to replace scr_in() in pcio.a because scr_in()
  428.       filters most special keys, and returns char.
  429.       key_in, returns an int value.  see tech reference manual
  430.       or basic manual for values of different key combinations.
  431.  
  432.       key_in() returns: 0 = no key pressed
  433.                         other = key and/or special key code
  434.  
  435.                         when value < 128 : normal ASCII
  436.                         when value >=128 : special key
  437.  
  438.  
  439.     calls: sysint
  440.  
  441. */
  442.  
  443. #define KEYBOARD 0x16
  444. #define GET_KEY  0x0000
  445. #define KEY_STAT 0x0100
  446. #define ZERO     0x0040
  447. /* ZERO is a mask for the 8088 flag register zero bit */
  448.  
  449. key_in ()
  450.  
  451. {
  452.  struct {int ax,bx,cx,dx,si,di,ds,es;} r;
  453.  
  454.  r.ax = r.bx = r.cx = r.dx = r.si = r.di = r.ds = r.es = 0;
  455.  
  456.  r.ax = KEY_STAT;
  457.  
  458.  if ( !(sysint (KEYBOARD, &r, &r) & ZERO))
  459.   {
  460.    r.ax = GET_KEY;
  461.    sysint (KEYBOARD, &r, &r);
  462.    return ( (r.ax & 0x00ff) ? (r.ax & 0x00ff) : (r.ax) );
  463.   }
  464.  else
  465.   return (0);
  466.  
  467. } /* end of key_in.c */
  468.  
  469.