home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / DEVELOP.ZIP / OS2PORTS.DOC < prev    next >
Text File  |  1994-11-03  |  6KB  |  139 lines

  1. PCBoard accesses OS/2 comm ports directly, even though PCBoard is a DOS
  2. application.  Many developers do not realize that a DOS application has access
  3. to the SAME function calls (file open, read, write, close as well as Device
  4. IOCtrl funcions) that OS/2 provides to native OS/2 applications.  PCBoard takes
  5. advantage of this fact to allow it to directly access comm ports that otherwise
  6. would appear to be available only to OS/2 applications.
  7.  
  8. Accessing OS/2 comm ports requires that you:
  9.  
  10. 1) Use the standard DOS operating system function calls normally associated
  11.    with files to open the comm port by name (e.g.  you would open "COM2", as if
  12.    it were a file, to access the comm port).  You then keep track of the same
  13.    file handle information to read from and write to the comm port using the
  14.    standard DOS read file and write file function calls.  And finally, you use
  15.    the same file handle and standard DOS close file function call to close it.
  16.  
  17. 2) To set port speed, check for carrier detect, turn DTR on or off, etc, you
  18.    use the standard DOS IOCTL calls.  The only trick here is ... IOCTL usage
  19.    requires that you know what parameters to send it.  And that information is
  20.    provided by IBM in their OS/2 documentation.  And *that* is the only reason
  21.    why developers are largely unaware that the same functionality is available
  22.    from DOS.
  23.  
  24. As a quick example to send something to an OS/2 comm port, consider the
  25. following C source code:
  26.  
  27.     port = open("COM2",O_RDWR);
  28.     write(port,"HELLO OS/2 WORLD!\r\n",19);
  29.     close(port);
  30.  
  31. Or consider this example which takes everything that comes in from the comm
  32. port and immediately sends it back out again:
  33.  
  34.     while (1) {
  35.       BytesRead = read(port,Buf,sizeof(Buf));
  36.       if (BytesRead > 0)
  37.         write(port,Buf,BytesRead);
  38.     }
  39.  
  40. As you can see, OS/2's usage of the file system makes receiving and sending
  41. bytes a fairly trivial matter.  What's left is how to "control" the comm port
  42. and that is where the IOCtrl function calls come in.
  43.  
  44. Here is an example of how you can control OS/2 comm ports:
  45.  
  46.     mov  ax, 0x440C      ;Ah=0x44 IOCTL,  Al=0x0C  Handle based call
  47.     mov  bx, [Handle]    ;load BX with the comm port handle
  48.  
  49.     mov  ch, 1           ;Category 1 functions are for ASYNCH
  50.     mov  cl, [Func]      ;Load CL with the async function to be used
  51.  
  52.     les  di, CmdPacket   ;point to a cmd packet (or NULL if no command packet)
  53.     mov  si, es          ;SI:DI = pointer to command packet
  54.  
  55.     push ds
  56.     lds  dx, DataPacket  ;DS:DX = pointer to data packet (or NULL if no data)
  57.     int  0x21
  58.     pop  ds
  59.  
  60.     jc   goback          ;AX has the error code to return, return it now
  61.     xor  ax              ;clear AX register before returning
  62.     goback:
  63.     ret
  64.  
  65. The entire sequence up above can be wrapped into a function call which you can
  66. then call from anywhere within your C source code.  For example, you might
  67. wrap a prototype such as the following around it:
  68.  
  69. int DevIOCtl(int Handle, int Func, void far *DataPacket, void far *CmdPacket);
  70.  
  71. With the above prototype, you could then set the port speed for a comm port
  72. by using the following code:
  73.  
  74.    long BitRate = 38400L;
  75.    DevIOCtl(Port,0x41,NULL,&BitRate);
  76.  
  77. Or to turn the DTR signal off, you might use the following code:
  78.  
  79.    int  Mask = 0xFF01;       /* FF = don't turn any off, 01 = turn DTR on */
  80.    long RetVal;              /* return value */
  81.    DevIOCtl(Port,0x46,&RetVal,&Mask);
  82.  
  83. ------------------------------------------------------------------------------
  84.  
  85. The above examples are meant merely to give you an idea as to HOW you can
  86. accomplish the task of accessing OS/2 comm ports from with a DOS program.
  87.  
  88. This information is NOT meant to be a complete tutorial or reference on
  89. accessing OS/2 comm ports.
  90.  
  91. It is recommended that you obtain, from IBM, the OS/2 API Reference Guide to
  92. obtain information on the IOCtrl function calls.  A commonly found document,
  93. called GUIREF20.INF, which is viewable using OS/2's "VIEW" command, can be used
  94. to obtain this information.
  95.  
  96. ------------------------------------------------------------------------------
  97.  
  98. Tips:
  99.  
  100. Beyond the technical details of "how" to program OS/2 comm ports from a DOS
  101. application, there remains the issue of how to "optimize" your program to get
  102. the best performance possible.
  103.  
  104. A few key ideas to keep in mind are:
  105.  
  106. - You can send data as fast as you want by writing data to the comm port
  107.   handle.  OS/2 will take care of making sure that the data is fed to the
  108.   comm port as fast as it can be accepted.
  109.  
  110. - Obtaining data from the comm port will "block" your application if there is
  111.   nothing in the comm port to be read in.  This can be highly desirable in
  112.   that it means your application gets *no* attention from OS/2 (no CPU cycles
  113.   are wasted) unless you have data in the port to be read in.
  114.  
  115.   HOWEVER, if your program needs to be able to monitor local keystrokes while
  116.   waiting for comm port data, or if your program has some other work to do,
  117.   you will have to AVOID using this capability due to the fact that your DOS
  118.   application cannot have multiple threads of execution and you don't want the
  119.   entire application to be blocked.
  120.  
  121.   Instead, what you might consider doing is setting the Read Timeout value
  122.   (IOCtrl function 53h) to a low enough value that control can be given back
  123.   to you quickly if there are no bytes waiting in the input buffer.
  124.  
  125. - Another thing to consider is that these function calls (read/write/ioctl) are
  126.   "expensive" function calls in terms of CPU time.  In other words, if you
  127.   spend a lot of time calling these functions you may send the CPU usage right
  128.   through the roof.
  129.  
  130.   For example, if you need to recognize when carrier is lost, you won't want to
  131.   set up a tight look that continually calls IOCtrl to find out if carrier is
  132.   lost because the CPU will be busy doing almost nothing but that function.
  133.   Instead, what you might want to do is create some kind of "interval" at which
  134.   you will make that function call (perhaps once a second, or whatever you
  135.   deem appropriate).
  136.  
  137. With these kinds of ideas in mind, you can "tune" your application to make the
  138. best use of the OS/2 API's possible.
  139.