home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / advos2 / ch12 / dumbterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-12  |  7.5 KB  |  196 lines

  1. /*
  2.     DUMBTERM.C
  3.  
  4.     A simple multithreaded OS/2 terminal program that exchanges
  5.     characters between the console and the serial port.
  6.  
  7.     Communication parameters for COM1 are set at 2400 baud,
  8.     8 data bits, no parity, and 1 stop bit.
  9.  
  10.     Compile with:  C> cl /F 2000 dumbterm.c
  11.  
  12.     Usage is:  C> dumbterm
  13.  
  14.     Press Alt-X to terminate the program.
  15.  
  16.     Copyright (C) 1988 Ray Duncan
  17. */
  18.  
  19. #include <stdio.h>
  20.  
  21. #define WAIT   0                        /* parameters for KbdCharIn */
  22. #define NOWAIT 1
  23.  
  24. #define EXITKEY  0x2d                   /* Exit key = Alt-X */
  25.  
  26. #define STKSIZE 2048                    /* stack size for threads */
  27.  
  28. #define COMPORT "COM1"                  /* COM port configuration */
  29. #define BAUD    2400                    /* 110, 150 ... 19200 */
  30. #define PARITY    0            /* 0 = N, 1 = O, 2 = E, 3 = M, 4 = S */
  31. #define DATABIT 8                       /* 5-8 allowed */
  32. #define STOPBIT 0            /* 0 = 1, 1 = 1.5, 2 = 2 */
  33.  
  34. #define API unsigned extern far pascal    /* OS/2 API prototypes */
  35.  
  36. API DosClose(unsigned); 
  37. API DosCreateThread(void (far *)(), unsigned far *, void far *);
  38. API DosDevIOCtl(void far *, void far *, unsigned, unsigned, unsigned);
  39. API DosExit(unsigned, unsigned);
  40. API DosOpen(char far *, unsigned far *, unsigned far *, unsigned long,
  41.             unsigned, unsigned, unsigned, unsigned long);           
  42. API DosRead(unsigned, void far *, int, unsigned far *);
  43. API DosSemClear(unsigned long far *);
  44. API DosSemSet(unsigned long far *);
  45. API DosSemWait(unsigned long far *, unsigned long);
  46. API DosSuspendThread(unsigned);
  47. API DosWrite(unsigned, void far *, int, unsigned far *);
  48. API KbdCharIn(void far *, unsigned, unsigned);
  49. API KbdGetStatus(void far *, unsigned);
  50. API KbdSetStatus(void far *, unsigned);
  51. API VioWrtTTY(char far *, int, unsigned);
  52.  
  53. void far comin(void);                   /* local function prototypes */
  54. void far comout(void);
  55. void errexit(char *);
  56.  
  57. struct _F41Info {                       /* DosDevIOCTl info structure */
  58.     int BaudRate;                       /* 110, 150 ... 19200 */
  59.     } F41Info;
  60.  
  61. struct _F42Info {                       /* DosDevIOCtl info structure */
  62.     char DataBits;                      /* character length 5-8 bits */
  63.     char Parity;            /* 0=N, 1=O, 2=E, 3=Mark, 4=Space */
  64.     char StopBits;                      /* 0=1, 1=1.5, 2=2 stop bits */
  65.     } F42Info;
  66.  
  67. struct _KbdInfo {                       /* KbdCharIn info structure */
  68.     char CharCode;                      /* ASCII character code */
  69.     char ScanCode;                      /* keyboard scan code */
  70.     char Status;                        /* misc. status flags */
  71.     char Reserved1;                     /* reserved byte */
  72.     unsigned ShiftState;                /* keyboard shift state */
  73.     long TimeStamp;                     /* character timestamp */
  74.     } KbdInfo;
  75.  
  76. struct _KbdStatus {                     /* KbdGetStatus info structure */
  77.     int Length;                         /* length of structure */
  78.     unsigned Mask;                      /* keyboard state flags */
  79.     char TurnAround[2];                 /* logical end-of-line */
  80.     unsigned Interim;                   /* interim character flags */
  81.     unsigned ShiftState;                /* keyboard shift state */
  82.     } KbdStatus;
  83.  
  84. unsigned chandle;                       /* handle for COM port */
  85. unsigned long exitsem;                  /* Alt-X exit semaphore */
  86.  
  87. main()
  88. {
  89.     unsigned action;                    /* result of DosOpen */
  90.     unsigned openflag = 0x01;           /* fail if device not found */
  91.     unsigned openmode = 0x12;           /* read/write, deny all */
  92.     unsigned cominID;                   /* COM input thread ID */
  93.     unsigned comoutID;                  /* COM output thread ID */
  94.     char cominstk[STKSIZE];             /* COM input thread stack */
  95.     char comoutstk[STKSIZE];            /* COM output thread stack */
  96.  
  97.                                         /* open COM port */
  98.     if(DosOpen(COMPORT, &chandle, &action, 0L, 0, openflag, openmode, 0L))
  99.         errexit("\nCan't open COM device.\n");
  100.  
  101.     F41Info.BaudRate = BAUD;            /* configure COM port */
  102.     F42Info.DataBits = DATABIT;         /* using DosDevIOCtl */
  103.     F42Info.Parity = PARITY;            /* Category 1 functions */
  104.     F42Info.StopBits = STOPBIT;    
  105.     if(DosDevIOCtl(NULL, &F41Info, 0x41, 1, chandle))
  106.         errexit("\nCan't set baud rate.\n");
  107.     if(DosDevIOCtl(NULL, &F42Info, 0x42, 1, chandle))
  108.         errexit("\nCan't configure COM port.\n");
  109.  
  110.     KbdStatus.Length = 10;              /* force keyboard */
  111.     KbdGetStatus(&KbdStatus, 0);        /* into binary mode */
  112.     KbdStatus.Mask &= 0xfff0;           /* with echo off */
  113.     KbdStatus.Mask |= 0x06;
  114.     KbdSetStatus(&KbdStatus, 0);    
  115.  
  116.     exitsem = 0L;                       /* initialize and */
  117.     DosSemSet(&exitsem);                /* set exit semaphore */
  118.  
  119.                                         /* create COM input thread */
  120.     if(DosCreateThread(comin, &cominID, cominstk+STKSIZE))
  121.         errexit("\nCan't create COM input thread.\n");
  122.  
  123.                                         /* create COM output thread */
  124.     if(DosCreateThread(comout, &comoutID, comoutstk+STKSIZE))
  125.         errexit("\nCan't create COM output thread.\n");
  126.  
  127.     puts("\nCommunicating...");         /* sign-on message */
  128.     
  129.     DosSemWait(&exitsem, -1L);          /* wait for exit signal */
  130.  
  131.     DosSuspendThread(cominID);          /* freeze COM input and */
  132.     DosSuspendThread(comoutID);         /* output threads */
  133.  
  134.     puts("\nTerminating...");           /* sign-off message */
  135.  
  136.     DosExit(1, 0);                      /* terminate all threads */
  137.                                         /* return code = 0 */
  138. }
  139.  
  140. /*
  141.     The 'comin' thread reads characters one at a time from the
  142.     COM port and sends them to the display.
  143. */
  144. void far comin(void)
  145. {
  146.     unsigned rlen;                      /* scratch variable */  
  147.     char inchar;                        /* character input buffer */
  148.  
  149.     while(1)                            
  150.     {                    /* read character from COM */
  151.         DosRead(chandle, &inchar, 1, &rlen);
  152.     VioWrtTTY(&inchar, 1, 0);    /* send character to display */
  153.     }
  154. }
  155.  
  156. /*
  157.     The 'comout' thread reads characters one at a time from the
  158.     keyboard and sends them to the COM port.  If the exit key is
  159.     detected, the main thread is signaled to clean up and exit.
  160. */
  161. void far comout(void)
  162. {
  163.     unsigned wlen;                      /* scratch variable */  
  164.  
  165.     while(1)
  166.     {
  167.         KbdCharIn(&KbdInfo, WAIT, 0);   /* read keyboard */
  168.     wlen = 1;            /* assume 1-byte character */
  169.         
  170.                                         /* extended character? */
  171.         if((KbdInfo.CharCode == 0) || (KbdInfo.CharCode == 0xe0))
  172.         {
  173.             wlen = 2;                   /* yes, set length = 2 */
  174.             
  175.             if(KbdInfo.ScanCode == EXITKEY)
  176.             {                           /* if exit key detected */
  177.                 DosSemClear(&exitsem);  /* signal thread 1 to exit */      
  178.                 wlen = 0;               /* and discard character */
  179.             }
  180.         }                               
  181.                                         /* write COM port */
  182.         DosWrite(chandle, &KbdInfo.CharCode, wlen, &wlen); 
  183.     }
  184. }
  185.  
  186. /*
  187.     Common error exit routine; displays error message
  188.     and terminates process.
  189. */
  190. void errexit(char *msg)
  191. {
  192.     VioWrtTTY(msg, strlen(msg), 0);     /* display error message */
  193.     DosExit(1, 1);                      /* terminate, exit code = 1 */
  194. }                                       
  195. 
  196.