home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / BASIC / QBSER20.ZIP / QBSERIAL.DOC < prev    next >
Encoding:
Text File  |  1990-10-31  |  25.8 KB  |  561 lines

  1.  
  2.  
  3.  
  4.  
  5.                                   QBserial version 2.0
  6.  
  7.                   Serial I/O Routines for use with QuickBASIC & BC6/7
  8.  
  9.           This library will provide you with serial I/O communications
  10.           routines for use in QuickBASIC 4.x (with or without PDQ), and the
  11.           Microsoft Basic Compiler 7.x Professional Development System. No
  12.           longer are you forced to use the poor communications support
  13.           provided by QB.  This program will allow you to control 8250 type
  14.           communications ports at speeds of up to 115200 baud. Communication
  15.           ports 1 - 4, and non-standard addresses are supported. You will no
  16.           longer have problems with the DTR signal. DTR is left in the same
  17.           state it was in when before you called this driver, or it can be
  18.           controlled by your program. The serial driver includes XON/XOFF and
  19.           CTS handshaking. Serial input is interrupt driven, using any IRQ
  20.           you specify (1 - 7), with incoming XOFF flow control (if enabled)
  21.           to prevent overrunning the input buffer. These are the same serial
  22.           I/O routines used in Sparkware's Qmail door, and the User Database
  23.           System Doors "Query Door" and "Upload Door".
  24.  
  25.           The driver is written in Microsoft's QuickC version 2.51. This
  26.           driver is useable with QuickBASIC version 4.x, and Basic Compiler
  27.           6.x & 7.x PDS. (With or without PDQ). BC 1.x, QuickBASIC 2.x, and
  28.           3.x are not supported by this driver. The reason is that versions
  29.           of QuickBASIC prior to 4.0 do not support the extensive multi-
  30.           language interface that QB4.x has (via the DECLARE statement and
  31.           Microsoft language extensions). Throughout this manual QB will be
  32.           used to refer to both QuickBASIC and the Basic Compilers (6.x & 7.x
  33.           PDS).
  34.  
  35.           Before the driver can be used, the following DECLARE statements
  36.           must be added to the beginning of your QB program:
  37.  
  38.           DECLARE SUB OpenComm CDECL ALIAS "_open_comm" (BYVAL Port%, BYVAL_
  39.                                IRQ%, BYVAL Wlen%, BYVAL Parity%, BYVAL Baud&,
  40.                                BYVAL HS%) 
  41.           DECLARE SUB CloseComm CDECL ALIAS "_close_comm" () 
  42.           DECLARE FUNCTION WriteChar% CDECL (BYVAL Ascii%) 
  43.           DECLARE FUNCTION ReadChar% CDECL () 
  44.           DECLARE SUB Transmit CDECL ALIAS "_transmit_string" (addr$) 
  45.           DECLARE FUNCTION DataWaiting% CDECL ALIAS "_data_waiting" () 
  46.           DECLARE SUB ClearInputBuffer CDECL ALIAS "_clear_input_buffer" () 
  47.           DECLARE SUB CarrierDetect CDECL ALIAS "_carrier_detect_flag"_
  48.                                     (BYVAL OnOff%) 
  49.           DECLARE FUNCTION CarrierLost% CDECL ALIAS "_carrier_state" ()
  50.           DECLARE SUB DTRcontrol CDECL ALIAS "_dtr" (BYVAL OnOff%)
  51.           DECLARE FUNCTION DriverCopyright% CDECL ()
  52.  
  53.           These declarations specify all the entry points into the serial
  54.           driver, They are in the include file QBSERIAL.DEC. DO NOT change
  55.           them or the driver may not function.
  56.  
  57.  
  58.         QBSERIAL User Manual - V 2.0                               Page 1
  59.  
  60.  
  61.  
  62.  
  63.           Refer to the included sample programs SIMPLE.BAS & PCBDOOR.BAS,
  64.           they use most of the calls described below.
  65.  
  66.  
  67.  
  68.                                   Port Initialization
  69.  
  70.           OpenComm Port%, IRQ%, Wordlen%, Parity%, Baudrate&, HS%
  71.  
  72.           Port%     This is an integer value. If the specified port is 1 to
  73.                     4, the driver opens that port. If you specify the port as
  74.                     ZERO (0) the driver enters "LOCAL" mode. This allows you
  75.                     to call the driver with data, but the driver won't send
  76.                     anything. This is useful when working with "doors". if
  77.                     you specify the port as any other value, QBserial will
  78.                     use that as the base address for the port. This allows
  79.                     you to work with non-standard I/O addresses. Note however
  80.                     that if you open a non-standard port, you must specify an
  81.                     IRQ value of 1 to 7
  82.  
  83.           IRQ%      Specifies which interrupt to use with this port. If the
  84.                     value of IRQ% is ZERO (0), then the default IRQ values
  85.                     are used (COM1 & COM3 use IRQ4, COM2 & COM4 use IRQ3).
  86.                     This is what most applications will use. Specify an IRQ
  87.                     value of 1 through 7 when you want to use an IRQ value
  88.                     other than the default. Such as when you want to use IRQ7
  89.                     with COM3. NOTE: Be careful when choosing an IRQ value
  90.                     other than the default. Most machines use the other IRQ
  91.                     inputs for other machine functions such as the Hard drive
  92.                     and system clock. QBserial DOES NOT chain the interrupt,
  93.                     it takes it over entirely. If you choose an IRQ that is
  94.                     used for something already, your machine will most
  95.                     certainly operate improperly.
  96.  
  97.           Wordlen%  an integer specifying the word length of the serial data.
  98.                     It has a value of 7 or 8.
  99.  
  100.           Parity%   an integer, 0 = NONE, 1 = ODD, 2 = EVEN.
  101.  
  102.           BaudRate& is a LONG INTEGER representing the desired baud rate.
  103.                     Valid numbers are 0, 300, 1200, 2400, 4800, 9600, 19200,
  104.                     38400, 57600, and 115200. The value you send is NOT
  105.                     checked and I assume you could generate crazy baud rates
  106.                     if desired. 115200 is the absolute maximum rate that can
  107.                     be generated. If you specify a baud rate of ZERO then the
  108.                     serial port is used AS-IS. The rate, word length, &
  109.                     parity are NOT changed. This is useful for door operation
  110.                     since the port is already initialized at the proper
  111.                     settings when you get control.
  112.  
  113.           HS%       an integer specifying the type of handshake you wish to
  114.                     use between the CPU and Modem (or destination device).
  115.  
  116.         QBSERIAL User Manual - V 2.0                               Page 2
  117.  
  118.  
  119.  
  120.  
  121.                     Valid numbers are: 0 = NO handshake, 1 = XON/XOFF, 2 =
  122.                     CTS, 3 = XON/XOFF and CTS.
  123.  
  124.  
  125.  
  126.                                      Serial Output
  127.  
  128.           To send a string of data out the serial port, you use the
  129.           "Transmit" call as follows:
  130.  
  131.                Temp$ = "Transmit this..."
  132.                Transmit Temp$
  133.  
  134.                     or
  135.  
  136.                Transmit "Send this also...."
  137.  
  138.           If you want to transmit single characters, you can use the
  139.           "WriteChar" function. Transmit calls WriteChar to send the actual
  140.           characters to the port. If you wish to use WriteChar, it has the
  141.           following format:
  142.  
  143.                Status% = WriteChar(Char%)
  144.  
  145.           Char% is the integer value of the character you want to send, it is
  146.           not a string. Status% is an integer returned by WriteChar, it is
  147.           NON-ZERO if the character was actually sent to the port, and ZERO
  148.           if the character was not sent. WriteChar will loop indefinitely on
  149.           CTS hold, XOFF hold, or Transmit Buffer Busy. These loops will exit
  150.           if carrier is lost in FULL or PARTIAL modes and return a ZERO
  151.           status%. WriteChar gives you more low level control of the sending
  152.           of characters, but you must send each character separately and
  153.           monitor its status.
  154.  
  155.           The Transmit function monitors the status of its calls to WriteChar
  156.           and triggers QuickBASIC's User Event trap (UEVENT) if a carrier
  157.           loss occurs in FULL mode. The UEVENT trap (FULL mode) is used by
  158.           default. You can disable the use of this event trap in the event
  159.           you already use the UEVENT trap for something else (PARTIAL mode).
  160.           Therefore, by default, carrier loss detection in your program is
  161.           done with the ON UEVENT GOSUB/UEVENT ON statements. The example
  162.           programs show the use of this method. By default UEVENT is also
  163.           used for catching carrier loss on keyboard input. this is described
  164.           below.
  165.  
  166.  
  167.  
  168.                                       Serial Input
  169.  
  170.           Serial input is managed with three functions: DataWaiting,
  171.           ReadChar, & ClearInputBuffer. DataWaiting is used to test the input
  172.           buffer to see if any characters need to be read from it. ReadChar
  173.  
  174.         QBSERIAL User Manual - V 2.0                               Page 3
  175.  
  176.  
  177.  
  178.  
  179.           is then called to get the characters. ClearInputBuffer flushes the
  180.           input buffer of any existing characters. Both example programs
  181.           contain a subroutine called "KeyboardInput" that demonstrates the
  182.           use of these calls. It also properly handles input from the local
  183.           and remote keyboards, and can be the routine you use in your
  184.           programs if you wish. Basically the procedure for reading the
  185.           remote keyboard (serial input) is as follows:
  186.  
  187.                IF DataWaiting THEN
  188.                     C$ = CHR$(ReadChar)
  189.                END IF
  190.  
  191.           The DataWaiting function also monitors the state of the carrier
  192.           detect signal and triggers, in FULL mode, the user event trap
  193.           (UEVENT) if carrier is lost. As you can see a singular trap routine
  194.           catches carrier loss on output as well as input. You will notice
  195.           that the "KeyboardInput" subroutine loops using DataWaiting, and as
  196.           such, carrier is constantly checked while waiting for input. If the
  197.           ReadChar function is called when no data is available (as indicated
  198.           by DataWaiting) a NULL character is returned.
  199.  
  200.           If XOFF/XON or BOTH is enabled, then the serial buffer will be
  201.           protected from overfills. When the buffer reaches 75% of capacity,
  202.           an XOFF will be sent on the serial output. When the buffer empties
  203.           out to 25% of capacity, an XON will be sent. The capacity of the
  204.           input buffer is 1024 bytes.
  205.  
  206.  
  207.  
  208.                                  Carrier Detect Control
  209.  
  210.           There are three modes of carrier detection: Full, Partial, & None.
  211.           Each has it own distinct use for a particular purpose. The driver
  212.           defaults to FULL carrier detection unless you change it. The
  213.           following call is used to change control modes:
  214.  
  215.                CarrierDetect 0 [or] 1 [or] 2
  216.  
  217.           Specifying a TWO (2) sets carrier detection to FULL. This is the
  218.           default mode. When a loss of carrier occurs while transmitting,
  219.           polling for input data, or sitting in a wait loop (XOFF/XON or
  220.           CTS), the driver will return to the calling program and trip the
  221.           UEVENT flag. Tripping the UEVENT flag causes Basic to go to the
  222.           User Event trap routine (providing ON UEVENT GOSUB/UEVENT ON has
  223.           been set up in the user program). You should use this mode only if
  224.           you want to use the UEVENT trap for carrier loss detection. You
  225.           cannot transmit data (with the Transmit function) in this mode if
  226.           there is no carrier. You can send characters in this mode with the
  227.           WriteChar function.
  228.  
  229.           Specifying a ONE (1) sets carrier detection to PARTIAL. This mode
  230.           is similar to FULL with the exception that the UEVENT flag is not
  231.  
  232.         QBSERIAL User Manual - V 2.0                               Page 4
  233.  
  234.  
  235.  
  236.  
  237.           tripped when carrier is lost. This mode should be used if UEVENT is
  238.           used for something else in your program, or you don't wish to
  239.           utilize UEVENT. This mode can also be used for talking to a modem
  240.           when there is no carrier signal present (such as dialing and
  241.           initialization commands). The Transmit and WriteChar routines will
  242.           always transmit data in this mode with or without carrier present.
  243.  
  244.           Specifying a ZERO (0) sets carrier detection to NONE. An example of
  245.           this mode would be where "plain Jane" serial I/O is required (such
  246.           as communicating with a "dumb" terminal). In this application there
  247.           are no modem handshake signals (3 wire EIA/RS-232). Carrier
  248.           detection must be disabled in this mode to prevent calls to Uevent
  249.           and disable the no carrier escape mechanisms built into the
  250.           XON/XOFF loops. Important: if you are using the XOFF/XON protocol
  251.           in this mode and receive an XOFF while transmitting, you will sit
  252.           forever waiting for an XON. This is a normal condition, with the
  253.           exception that there is no escape from this loop other than XON.
  254.  
  255.  
  256.                            Carrier Loss Detection by Polling
  257.  
  258.           As mentioned above, by default, the UEVENT trap is used to detect
  259.           when a loss of carrier occurs. There is also a function that allows
  260.           you to detect loss of carrier without using the UEVENT trap. While
  261.           I feel that using UEVENT is the simplest way to catch a carrier
  262.           loss in a program, it is possible that UEVENT might need to be used
  263.           by something else. This function is:
  264.  
  265.                X% = CarrierLost
  266.  
  267.           This function call allows to you to 'poll' for the state of
  268.           carrier. CarrierLost returns a NON-ZERO value when there is NO
  269.           carrier, and a ZERO when there IS carrier. CarrierLost is a real
  270.           time function, it returns the current carrier condition at the time
  271.           of the call. This allows you to code simple IF or DO loops to
  272.           detect loss:
  273.  
  274.                IF CarrierLost THEN
  275.                     ..process carrier loss
  276.                END IF
  277.  
  278.  
  279.  
  280.                                   Program Termination
  281.  
  282.           Since "OpenComm" seizes interrupt vectors, these vectors need to be
  283.           restored BEFORE your program ends. If you neglect to restore these
  284.           vectors, you are guaranteed a crash. The routine used to reset the
  285.           vectors is: CloseComm. Only use CloseComm if you specified a port
  286.           value of 1, 2, 3, 4, or a non-standard port address in the OpenComm
  287.           call. If you specified a port value of ZERO (Local mode) the
  288.           interrupt vectors are NOT grabbed, and do not need to be reset.
  289.  
  290.         QBSERIAL User Manual - V 2.0                               Page 5
  291.  
  292.  
  293.  
  294.  
  295.           CloseComm also resets any UART registers to their original value,
  296.           it also resets the programmable interrupt controller (8259 PIC) to
  297.           its original settings.
  298.  
  299.  
  300.  
  301.                                Data Terminal Ready (DTR)
  302.  
  303.           Everybody that has used QuickBASIC's OPEN COMn statement is very
  304.           familiar with the problems of the DTR signal. Apparently Microsoft
  305.           felt that DTR would never be needed after a program terminates.
  306.           Anybody who has ever tried to write a door, or chain from one
  307.           program to another has cursed this decision at some time during
  308.           their programs development. This driver handles the DTR with a
  309.           different view. When you close the comm channel the DTR signal is
  310.           left in the same state it was when you opened the comm channel. For
  311.           door applications, this is a must. 
  312.  
  313.           A function call is provided however that allows your program to
  314.           control the DTR signal:
  315.  
  316.           DTRcontrol 1 [or] 0           ' 0 = DTR OFF, 1 = DTR ON
  317.  
  318.           Additionally when you use DTRcontrol to change the state of the DTR
  319.           signal it also instructs the driver to leave it this way when the
  320.           CloseComm function is called. Remember that the driver leaves DTR
  321.           the way it found it when OpenComm was called. If you used some
  322.           other method to change DTR after OpenComm was called, it would
  323.           automatically return to that original state when you called
  324.           CloseComm. Therefor only DTRcontrol should be used if you wish to
  325.           change the state of DTR.
  326.  
  327.  
  328.                               Driver Version and Copyright
  329.  
  330.           A function is available to access the drivers version and copyright
  331.           string. This would be used if you wish to display in your final
  332.           product the version of QBserial that your are using, and/or my
  333.           copyright along with yours. In order to access the copyright
  334.           string, the following lines should be added to your Basic program:
  335.  
  336.                     X& = DriverCopyright
  337.                     WHILE (PEEK(X&))
  338.                          CP$ = CP$ + CHR$(PEEK(X&))
  339.                          X& = X& + 1
  340.                     WEND
  341.  
  342.           This places the version/copyright string into string variable CP$.
  343.           This string may now be handled in whatever method you choose.
  344.  
  345.  
  346.                                  Cresent's PDQ Library
  347.  
  348.         QBSERIAL User Manual - V 2.0                               Page 6
  349.  
  350.  
  351.  
  352.  
  353.  
  354.           An object module for use with PDQ is also included. PDQ does not
  355.           support UEVENT, so all references to UEVENT in the text should be
  356.           ignored. You will need to do carrier checking by polling with the
  357.           CarrierLost function. If you use FULL mode and carrier is lost it
  358.           will operate the same way as PARTIAL mode. The only exception to
  359.           this is the Transmit function, which when in FULL mode, will not
  360.           transmit data.
  361.  
  362.           NOTE:     An additional note for PDQ users. Since PDQ replaces the
  363.                     Microsoft run time libraries, the public variable
  364.                     ACRTUSED is not satisfied during the link stage. A dummy
  365.                     stub file, ACRTUSED.OBJ is included with QBserial to
  366.                     prevent this error from occurring. The next paragraph
  367.                     explains the proper linking sequence.
  368.  
  369.  
  370.                                         Linking
  371.  
  372.           Since object modules are provided for QB4.x, BC7, and PDQ, you will
  373.           need to select which one to use for your program. The additional
  374.           library (SERIAL.LIB) only contains routines from the C library that
  375.           are required by the driver. The file QBSER.OBJ should be used for
  376.           programs compiled with QuickBASIC, BC7SER.OBJ is to be used for
  377.           programs compiled with BC7 PDS, and QBSERPDQ.OBJ is for PDQ users.
  378.           Typical link command lines would look like this:
  379.  
  380.           Link yourprog qbser,,,serial;                (For QuickBASIC)
  381.  
  382.           Link yourprog bc7ser,,,serial;               (For BC7 PDS)
  383.  
  384.           Link yourprog qbserpdq acrtused,,,serial;    (For PDQ)
  385.  
  386.  
  387.  
  388.                                     Quick Libraries
  389.  
  390.           If you wish to develop programs from within the environment, you
  391.           will first need to create a Quick library using one of the object
  392.           modules (QBSER.OBJ, BC7SER.OBJ, QBSERPDQ.OBJ) and the SERIAL.LIB
  393.           file. To create a Quick lib for QuickBASIC 4.x, use the following
  394.           Link command:
  395.  
  396.                Link QBSER,,,SERIAL BQLB4x/q
  397.  
  398.           Where "BQLB4x" is one of the following: BQLB40.LIB, BQLB41.LIB, or
  399.           BQLB45.LIB. Use the one that came with your compiler. If you use
  400.           the wrong BQLB file you might get an "Invalid Format" error when
  401.           attempting to start QuickBASIC. QBSER.OBJ & SERIAL.LIB may also be
  402.           added to Quick Libraries containing other routines and OBJ's as
  403.           well.
  404.  
  405.  
  406.         QBSERIAL User Manual - V 2.0                               Page 7
  407.  
  408.  
  409.  
  410.  
  411.           To create a Quick Library for use within QBX (BC7's environment)
  412.           use the following link command (be sure to use Link v5.xx that came
  413.           with BC7):
  414.  
  415.                Link BC7SER,,,SERIAL QBXQLB/q;
  416.  
  417.           For PDQ, use the method for QB4.x, since you will be using the
  418.           built in run time routines built into the environment. You ONLY use
  419.           QBSERPDQ.OBJ when you link the EXEcutable file.
  420.  
  421.           Remember too, that you can also add BC7SER.OBJ & SERIAL.LIB to
  422.           Quicklibs containing other routines.
  423.  
  424.  
  425.  
  426.                                      Specifications
  427.  
  428.           The following port addresses and default interrupts are used:
  429.  
  430.                Comm      Base Address        IRQ (Default)
  431.  
  432.                 1          3F8 hex            4
  433.                 2          2F8 hex            3
  434.                 3          3E8 hex            4
  435.                 4          2E8 hex            3
  436.  
  437.           Please read the section explaining the OpenComm function for
  438.           information on how to use addresses or IRQ's other than the
  439.           defaults.
  440.  
  441.  
  442.                                         Support
  443.  
  444.           I'm reachable in the ILINK Basic conference, or the number below.
  445.           I'll help there if you have questions. No other support is
  446.           necessary. Bugs will be tended to if required, and good suggestions
  447.           tend to be implemented.
  448.  
  449.           This driver is copyrighted by me, but is being distributed as
  450.           shareware. You may copy and distribute it freely. In the spirit of
  451.           programmer to programmer I am not requesting any registration fee
  452.           for the use of these routines. All I ask is that you acknowledge in
  453.           your documentation that you are using them (Non-commercial use
  454.           only). If you want display my version/copyright notice in your
  455.           final product to give me a bit of free advertising, see the section
  456.           pertaining to this. If you feel that this driver is worth something
  457.           and you would like to send some sort of registration (say $20), I
  458.           won't refuse it! If you are using them in a PCBoard door, a copy of
  459.           the door for our system would be a nice gesture!
  460.  
  461.  
  462.  
  463.  
  464.         QBSERIAL User Manual - V 2.0                               Page 8
  465.  
  466.  
  467.  
  468.  
  469.           If you plan to use QBserial in a commercial product for resale, you
  470.           will need to license the driver first. please contact me for
  471.           details.
  472.  
  473.  
  474.                                       Source Code
  475.  
  476.           The source code for QBserial is available. The source is ONLY
  477.           available by signing a license agreement. The source may be used
  478.           for you own internal uses only. The source may not be distributed
  479.           by you to any other person, even if you make changes to it. Nor can
  480.           the resulting object code be sold or distributed. Modifications can
  481.           only be used in your end product, and without any type of royalty.
  482.           The license fee for the QBserial source code is $75.00. Please
  483.           contact me if you are interested.
  484.  
  485.                                       Jeff Sumberg
  486.                                 Sysop(2) - SailBoard BBS
  487.                                 Wayne, NJ, 201-831-8152
  488.  
  489.                                         [ or ]
  490.  
  491.                                         Box 212
  492.                                   Ringwood, NJ, 07456
  493.  
  494.  
  495.  
  496.                                     Acknowledgments
  497.  
  498.           Thanks go out to Mark "Sparky" Herring for using these routines in
  499.           his highly successful Qmail door (versions 3 & 4). Since his door
  500.           runs on so many systems of varied configuration, it has made
  501.           testing and proving out much easier.
  502.  
  503.           Thanks to Mark Wilson for some very good ideas.
  504.  
  505.  
  506.                                  Changes and Revisions
  507.  
  508.           06/09/89  1.0       Initial Release
  509.  
  510.           06/21/89  1.1       Added carrier detection control. Calling
  511.                               program can turn detection off and on as
  512.                               desired. Necessary if data sending/receiving
  513.                               required if carrier isn't present.
  514.  
  515.           09/01/89  1.2       Fixed a bug in Readchar where 'extended'
  516.                               characters (ASCII 128 to 255) were causing an
  517.                               Illegal Function Call in the CHR$() conversion
  518.                               (because they were being returned as negative
  519.                               numbers). Extended character may now be
  520.  
  521.  
  522.         QBSERIAL User Manual - V 2.0                               Page 9
  523.  
  524.  
  525.  
  526.  
  527.                               received properly. Added three new functions:
  528.                               CDtrap, CarrierLost, and DTRcontrol.
  529.  
  530.                     1.3
  531.                     1.4       Un-released interim versions.
  532.  
  533.           03/24/90  1.5       Added support for Basic Compiler 7.0 PDS and
  534.                               PDQ. Added sections to manual about Linking,
  535.                               Source code availability, and updated section
  536.                               on Quicklibs. Separate object files now
  537.                               supplied for QB, BC7, and PDQ.
  538.  
  539.           05/01/90  1.6       Oops! PDQ users found out fast that I forgot to
  540.                               compile the PDQ module with stack checking
  541.                               removed. I also forgot to include ACRTUSED.OBJ
  542.                               to satisfy linking requirements. Sorry 'bout
  543.                               that! Released only as beta to those that
  544.                               needed it.
  545.  
  546.           11/01/90  2.0       Added capability to specify non-standard port
  547.                               addresses and which IRQ to use when the port is
  548.                               opened. Removed CDtrap function. Created new
  549.                               carrier detection modes using the CarrierDetect
  550.                               function. (0 = NONE, 1 = PARTIAL, 2 = FULL).
  551.                               Also added DriverCopyright function to allow
  552.                               program access to the driver version.
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.         QBSERIAL User Manual - V 2.0                              Page 10
  581.