home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / PROGRAM / PCL4C30.ZIP / TERM.C < prev    next >
Text File  |  1992-01-20  |  8KB  |  302 lines

  1. /*
  2. **                    ---  term.c ---
  3. **
  4. **  EXAMPLE CODE: Terminal emulator. Can transfer files using
  5. **  XMODEM and YMODEM protocols.
  6. **
  7. **  Link with TERM_IO, MODEM_IO, CRC, DOS, XYMODEM, and XYPACKET.
  8. **  See TERM makefiles.
  9. **
  10. **  This example program (not the PCL4C library) is donated to
  11. **  the Public Domain by MarshallSoft Computing, Inc. It is
  12. **  provided as an example of the use of the PCL4C.
  13. **
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <fcntl.h>
  18. #include <sys\types.h>
  19. #include <sys\stat.h>
  20.  
  21. #define FALSE 0
  22. #define TRUE !FALSE
  23. #define ONESECOND 18
  24. #define NORMAL 0x07
  25. #define INVERSE 0x70
  26. #define MESSAGE_POS 48
  27.  
  28. /* Set HAYES to 1 if using a HAYES modem, else set HAYES to 0 */
  29. #define HAYES 0
  30.  
  31. #include "pcl4c.h"
  32. #include "ascii.h"
  33.  
  34. /*** Global variables ***/
  35.  
  36. int Port;               /* current COM port [0..3] */
  37. char Filename[15];      /* file name buffer */
  38. char Buffer[1024];      /* block buffer */
  39. char  RxBuf[2048];
  40. char *BaudRate[10] =  {"300","600","1200","2400","4800","9600",
  41.                        "19200","38400","57600","115200"};
  42. int BaudCode;         /* baud rate code ( index into BaudRate[] ) */
  43. int CRCflag   = TRUE;
  44. int OneKflag  = FALSE;
  45. int BatchFlag = FALSE;
  46. char Protocol = 'X';
  47.  
  48. /*** main program ***/
  49.  
  50. main(argc,argv)
  51. int argc;
  52. char *argv[];
  53. {int DataFlag = FALSE;
  54.  char c;
  55.  int i, k;
  56.  int n, rc;
  57.  int Delta;         /* delta port status */
  58.  int Status;        /* port status */
  59.  char temp[81];
  60.  /* right number of parameters ? */
  61.  if(argc!=3)
  62.      {printf("Usage: 'TERM port baud' -- example 'TERM 1 9600'\n");
  63.       exit(1);
  64.      }
  65.  /* get port number from command line */
  66.  Port = atoi(argv[1]) - 1;
  67.  if((Port<0) || (Port>3))
  68.      {printf("Port must be 1 to 4\n");
  69.       exit(1);
  70.      }
  71.  /* get baud rate from command line */
  72.  BaudCode = BaudMatch(argv[2]);
  73.  if(BaudCode<0)
  74.      {printf("Cannot recognize baud rate = %s\n",argv[2]);
  75.       exit(1);
  76.      }
  77.  /* setup receive buffer */
  78.  rc = SioRxBuf(Port,RxBuf,Size2048);
  79.  if(rc<0)
  80.      {SioError(rc);
  81.       exit(1);
  82.      }
  83.  /* set parms & reset (initialize) COM port */
  84.  SioParms(Port,NoParity,OneStopBit,WordLength8);
  85.  MyStart(Port,BaudCode);
  86.  /* init CRCR table */
  87.  InitCRC();
  88.  /* set DTR and RTS */
  89.  SioDTR(Port,'S');
  90.  SioRTS(Port,'S');
  91.  /* initialize screen */
  92.  Scroll(0,0,24,79,0,NORMAL);
  93.  /* display status message */
  94.  sprintf(temp," COM%d %s %c 'ESC for menu' ",1+Port,BaudRate[BaudCode],Protocol);
  95.  for(i=0;i<strlen(temp);i++)
  96.      {/* write character */
  97.       Position(24,MESSAGE_POS+i);
  98.       AttrWrite(temp[i],INVERSE);
  99.      }
  100.  /* home cursor & clear CCL receive buffer */
  101.  Position(0,0);
  102.  SioRxFlush(Port);
  103.  
  104. #if HAYES
  105.  /* wait for Modem to say its ready */
  106.  printf("Waiting for Modem DSR.");
  107.  while( !SioDSR(Port) )
  108.      {
  109.       if(SioKeyPress()||SioBrkKey()) MyExit(0,"Aborted by user");
  110.       putchar('.');
  111.       SioDelay(18);
  112.      }
  113.  putchar('\n');
  114.  /* initialize (Hayes compatible) modem */
  115.  SendTo(Port,"!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!");
  116.  if(!WaitFor(Port,"OK")) MyExit(0,"Expecting OK");
  117.  printf("\nMODEM READY\n");
  118. #endif
  119.  
  120.  /* enter terminal loop */
  121.  SioRxFlush(Port);
  122.  while(1)
  123.      {/* Control-BREAK ? */
  124.       if(SioBrkKey()) MyExit(0,"User pressed Ctrl-BREAK");
  125.       /* was key pressed ? */
  126.       if(SioKeyPress())
  127.           {/* read key press */
  128.            i = SioKeyRead();
  129.            if((char)i==ESC)
  130.                {/* process user's request */
  131.                 ProcessESC();
  132.                 continue;
  133.                }
  134.            else PutChar(Port,i);
  135.           }
  136.       /* was break detected ? */
  137.       if( SioBrkSig(Port,'D') ) DisplayLine("BREAK detected ",NULL,0);
  138.       /* any incoming over serial port ? */
  139.       i = GetChar(Port,0);
  140.       if(i>-1)
  141.           {/* good character */
  142.            if(DataFlag&(i<0x20))
  143.                {MyCrtWrite('^');
  144.                 MyCrtWrite('@'+i);
  145.                }
  146.            else MyCrtWrite(i&0x007f);
  147.           }
  148.       /* any change in DCD or DSR ? */
  149.       Delta = SioModem(Port,DeltaDCD|DeltaDSR);
  150.       if(Delta)
  151.           {/* display new status */
  152.            Status = SioModem(Port,DCD|DSR);
  153.            if(!Delta&DeltaDCD) MyExit(0,"Dropped DSD");
  154.            if(!Delta&DeltaDSR) MyExit(0,"Dropped DSR");
  155.           }
  156.      } /* end -- key pressed */
  157. }
  158.  
  159. /*** write to screen except for bottom line ***/
  160.  
  161. int MyCrtWrite(ch)
  162. char ch;
  163. {/* write character */
  164.  SioCrtWrite(ch);
  165.  /* scroll all but bottom line */
  166.  if(GetRow()==24)
  167.     {Scroll(0,0,23,79,1,NORMAL);
  168.      Position(23,0);
  169.     }
  170. }
  171.  
  172. /*** make multiple attempts to reset port ***/
  173.  
  174. int MyStart(Port,BaudCode)
  175. int Port;
  176. int BaudCode;
  177. {int i, rc;
  178.  /* try up to 3 times to reset COM port */
  179.  for(i=0;i<3;i++)
  180.      {printf("Resetting COM%d at %s baud\n",Port+1,BaudRate[BaudCode]);
  181.       if( (rc = SioReset(Port,BaudCode))==0) return;
  182.       if(rc<0) MyExit(rc,"Error resetting port");
  183.       SioDone(Port);
  184.       /* display errors */
  185.       if(rc&OverrunError) puts("Overrun Error");
  186.       if(rc&ParityError)  puts("Parity Error");
  187.       if(rc&FramingError) puts("Framing Error");
  188.       if(rc&BreakDetect)  puts("Break Detect");
  189.      }
  190.  exit(1);
  191. }
  192.  
  193. /*** find baud rate string in table ***/
  194.  
  195. int BaudMatch(ptr)
  196. char *ptr;
  197. {int i;
  198.  /* find baud rate in table */
  199.  for(i=0;i<10;i++) if(strcmp(BaudRate[i],ptr)==0) return(i);
  200.  return(-1);
  201. }
  202.  
  203. /*** user pressed Escape */
  204.  
  205. int ProcessESC()
  206. {int i;
  207.  int rc;
  208.  int c1, c2;
  209.  char Answer[2]; /* array for 1 char answer */
  210.  int row, col;
  211.  /* user pressed <ESC> */
  212.  Answer[0] = '?';
  213.  Answer[1] = '\0';
  214.  DisplayLine("Q)uit P)rotocol S)end R)eceive: ",Answer,1);
  215.  if(strlen(Answer)) switch(toupper(Answer[0]))
  216.      {
  217.       case 'P':
  218.           DisplayLine("X)MODEM Y)MODEM: ",Answer,1);
  219.           if(strlen(Answer)) switch( toupper(Answer[0]) )
  220.                {
  221.                 case 'X':
  222.                     Protocol = 'X';
  223.                     ShowProtocol();
  224.                     OneKflag = FALSE;
  225.                     BatchFlag = FALSE;
  226.                     CRCflag = TRUE;
  227.                     DisplayLine("Protocol = XMODEM",NULL,1);
  228.                     break;
  229.                 case 'Y':
  230.                     Protocol = 'Y';
  231.                     ShowProtocol();
  232.                     OneKflag = TRUE;
  233.                     BatchFlag = TRUE;
  234.                     CRCflag = TRUE;
  235.                     DisplayLine("Protocol = YMODEM",NULL,1);
  236.                     break;
  237.                 default:
  238.                     DisplayLine("Must answer X or Y",NULL,1);
  239.                     break;
  240.                }
  241.           break;
  242.       case 'Q':
  243.           MyExit(0,"User pressed ESC");
  244.           break;
  245.       case 'R':
  246.           /* XMODEM / YMODEM receive */
  247.           if(BatchFlag)
  248.                {do
  249.                     {/* receive files till get empty filename */
  250.                      RxyModem(Port,Filename,Buffer,CRCflag,BatchFlag);
  251.                      if(SioKeyPress()) break;
  252.                     } while(Filename[0]!='\0');
  253.                }
  254.           else /* not Batch */
  255.                {DisplayLine("Enter filename:",Filename,15);
  256.                 if(strlen(Filename)==0) break;
  257.                 RxyModem(Port,Filename,Buffer,CRCflag,BatchFlag);
  258.                }
  259.           break;
  260.       case 'S':
  261.           DisplayLine("Enter filename:",Filename,15);
  262.           if(strlen(Filename)==0) break;
  263.           /* XMODEM / YMODEM send */
  264.           TxyModem(Port,Filename,Buffer,OneKflag,BatchFlag);
  265.           if(BatchFlag)
  266.                {/* send empty filename */
  267.                 Filename[0] = '\0';
  268.                 SioDelay(5);
  269.                 TxyModem(Port,Filename,Buffer,OneKflag,BatchFlag);
  270.                }
  271.           break;
  272.      default:
  273.           DisplayLine("Must answer Q, P, S, or R",NULL,0);
  274.           break;
  275.     } /* end switch */
  276. }
  277.  
  278. /*** show protocol choosen ***/
  279. int ShowProtocol()
  280. {int Row;
  281.  int Col;
  282.  Row = GetRow();
  283.  Col = GetCol();
  284.  Position(24,MESSAGE_POS+strlen(BaudRate[BaudCode])+7);
  285.  AttrWrite(Protocol,INVERSE);
  286.  Position(Row,Col);
  287. }
  288.  
  289. /*** exit program ***/
  290.  
  291. int MyExit(code,msg)
  292. int code;
  293. char *msg;
  294. {int rc;
  295.  if(code<0) SioError(code);
  296.  /* Assert UART break & sign off */
  297.  SioBrkSig(Port,'A');
  298.  printf("\nTERMINATING: %s\n",msg);
  299.  SioDelay(ONESECOND);
  300.  SioDone(Port);
  301.  exit(0);
  302. }