home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- QBserial version 2.10
-
- Serial I/O Routines for use with QuickBASIC & BC6/7
-
- This library will provide you with serial I/O communications
- routines for use in QuickBASIC 4.x (with or without PDQ), and the
- Microsoft Basic Compiler 7.x Professional Development System. No
- longer are you forced to use the poor communications support
- provided by QB. This program will allow you to control 8250
- (includes 16450) type communications ports at speeds of up to
- 115200 baud. Communication ports 1 - 4, and non-standard addresses
- are supported. You will no longer have problems with the DTR
- signal. DTR is left in the same state it was in when before you
- called this driver, or it can be controlled by your program. The
- serial driver includes XON/XOFF and CTS/RTS handshaking. Serial
- input is interrupt driven, using any IRQ you specify (1 - 7), with
- incoming XOFF flow control (if enabled), or RTS flow control (if
- enabled) to prevent overrunning the input buffer. These are the
- same serial I/O routines used in Sparkware's Qmail door, and the
- User Database System Doors "Query Door" and "Upload Door".
-
- The driver was written with Microsoft's C, and compiled with
- version 6.0a of that compiler. This driver is useable with
- QuickBASIC version 4.x, and Basic Compiler 6.x & 7.x PDS. (With or
- without PDQ). BC 1.x, QuickBASIC 2.x, and 3.x are not supported by
- this driver. The reason is that versions of QuickBASIC prior to 4.0
- do not support the extensive multi-language interface that QB4.x
- has (via the DECLARE statement and Microsoft language extensions).
- Throughout this manual QB will be used to refer to both QuickBASIC
- and the Basic Compilers (6.x & 7.x PDS).
-
- Before the driver can be used, the following DECLARE statements
- must be added to the beginning of your QB program:
-
- DECLARE SUB OpenComm CDECL ALIAS "_open_comm" (BYVAL Port%, BYVAL_
- IRQ%, BYVAL Wlen%, BYVAL Parity%, BYVAL Baud&,
- BYVAL HS%)
- DECLARE SUB CloseComm CDECL ALIAS "_close_comm" ()
- DECLARE FUNCTION WriteChar% CDECL (BYVAL Ascii%)
- DECLARE FUNCTION ReadChar% CDECL ()
- DECLARE SUB Transmit CDECL ALIAS "_transmit_string" (addr$)
- DECLARE FUNCTION DataWaiting% CDECL ALIAS "_data_waiting" ()
- DECLARE SUB ClearInputBuffer CDECL ALIAS "_clear_input_buffer" ()
- DECLARE SUB CarrierDetect CDECL ALIAS "_carrier_detect_flag"_
- (BYVAL OnOff%)
- DECLARE FUNCTION CarrierLost% CDECL ALIAS "_carrier_state" ()
- DECLARE SUB DTRcontrol CDECL ALIAS "_dtr" (BYVAL OnOff%)
- DECLARE SUB RTScontrol CDECL ALIAS "_rts" (BYVAL OnOff%)
- DECLARE FUNCTION DriverCopyright% CDECL ()
-
-
-
- QBSERIAL User Manual - V 2.10 Page 1
-
-
- These declarations specify all the entry points into the serial
- driver, They are in the include file QBSERIAL.DEC. DO NOT change
- them or the driver may not function.
-
- Refer to the included sample programs SIMPLE.BAS & PCBDOOR.BAS,
- they use most of the calls described below.
-
-
-
- Port Initialization
-
- OpenComm Port%, IRQ%, Wordlen%, Parity%, Baudrate&, HS%
-
- Port% This is an integer value. If the specified port is 1 to
- 4, the driver opens that port. If you specify the port as
- ZERO (0) the driver enters "LOCAL" mode. This allows you
- to call the driver with data, but the driver won't send
- anything. This is useful when working with "doors". if
- you specify the port as any other value, QBserial will
- use that as the base address for the port. This allows
- you to work with non-standard I/O addresses. Note however
- that if you open a non-standard port, you must specify an
- IRQ value of 1 to 7
-
- IRQ% Specifies which interrupt to use with this port. If the
- value of IRQ% is ZERO (0), then the default IRQ values
- are used (COM1 & COM3 use IRQ4, COM2 & COM4 use IRQ3).
- This is what most applications will use. Specify an IRQ
- value of 1 through 7 when you want to use an IRQ value
- other than the default. Such as when you want to use IRQ7
- with COM3. NOTE: Be careful when choosing an IRQ value
- other than the default. Most machines use the other IRQ
- inputs for other machine functions such as the Hard drive
- and system clock. QBserial DOES NOT chain the interrupt,
- it takes it over entirely. If you choose an IRQ that is
- used for something already, your machine will most
- certainly operate improperly.
-
- Wordlen% an integer specifying the word length of the serial data.
- It has a value of 7 or 8.
-
- Parity% an integer, 0 = NONE, 1 = ODD, 2 = EVEN.
-
- BaudRate& is a LONG INTEGER representing the desired baud rate.
- Valid numbers are 0, 300, 1200, 2400, 4800, 9600, 19200,
- 38400, 57600, and 115200. The value you send is NOT
- checked and I assume you could generate crazy baud rates
- if desired. 115200 is the absolute maximum rate that can
- be generated. If you specify a baud rate of ZERO then the
- serial port is used AS-IS. The rate, word length, &
- parity are NOT changed. This is useful for door operation
-
-
- QBSERIAL User Manual - V 2.10 Page 2
-
-
- since the port is already initialized at the proper
- settings when you get control.
-
- HS% an integer specifying the type of handshake you wish to
- use between the CPU and Modem (or destination device).
- Valid numbers are: 0 = NO handshake, 1 = XON/XOFF, 2 =
- CTS/RTS, 3 = XON/XOFF and CTS/RTS.
-
-
- Serial Output
-
- To send a string of data out the serial port, you use the
- "Transmit" call as follows:
-
- Temp$ = "Transmit this..."
- Transmit Temp$
-
- or
-
- Transmit "Send this also...."
-
- If you want to transmit single characters, you can use the
- "WriteChar" function. Transmit calls WriteChar to send the actual
- characters to the port. If you wish to use WriteChar, it has the
- following format:
-
- Status% = WriteChar(Char%)
-
- Char% is the integer value of the character you want to send, it is
- not a string. Status% is an integer returned by WriteChar, it is
- NON-ZERO if the character was actually sent to the port, and ZERO
- if the character was not sent. WriteChar will loop indefinitely on
- CTS hold, XOFF hold, or Transmit Buffer Busy. These loops will exit
- if carrier is lost in FULL or PARTIAL modes and return a ZERO
- status%. WriteChar gives you more low level control of the sending
- of characters, but you must send each character separately and
- monitor its status.
-
- The Transmit function monitors the status of its calls to WriteChar
- and triggers QuickBASIC's User Event trap (UEVENT) if a carrier
- loss occurs in FULL mode. The UEVENT trap (FULL mode) is used by
- default. You can disable the use of this event trap in the event
- you already use the UEVENT trap for something else (PARTIAL mode).
- Therefore, by default, carrier loss detection in your program is
- done with the ON UEVENT GOSUB/UEVENT ON statements. The example
- programs show the use of this method. By default UEVENT is also
- used for catching carrier loss on keyboard input. this is described
- below.
-
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 3
-
-
- Serial Input
-
- Serial input is managed with three functions: DataWaiting,
- ReadChar, & ClearInputBuffer. DataWaiting is used to test the input
- buffer to see if any characters need to be read from it. ReadChar
- is then called to get the characters. ClearInputBuffer flushes the
- input buffer of any existing characters. Both example programs
- contain a subroutine called "KeyboardInput" that demonstrates the
- use of these calls. It also properly handles input from the local
- and remote keyboards, and can be the routine you use in your
- programs if you wish. Basically the procedure for reading the
- remote keyboard (serial input) is as follows:
-
- IF DataWaiting THEN
- C$ = CHR$(ReadChar)
- END IF
-
- The DataWaiting function also monitors the state of the carrier
- detect signal and triggers, in FULL mode, the user event trap
- (UEVENT) if carrier is lost. As you can see a singular trap routine
- catches carrier loss on output as well as input. You will notice
- that the "KeyboardInput" subroutine loops using DataWaiting, and as
- such, carrier is constantly checked while waiting for input. If the
- ReadChar function is called when no data is available (as indicated
- by DataWaiting) a NULL character is returned.
-
- If XOFF/XON, CTS/RTS, or BOTH is enabled, then the serial buffer
- will be protected from overfills. When the buffer reaches 75% of
- capacity, an XOFF will be sent on the serial output or RTS will be
- dropped. When the buffer empties out to 25% of capacity, an XON
- will be sent or RTS raised. The capacity of the input buffer is
- 2048 bytes.
-
-
- Carrier Detect Control
-
- There are three modes of carrier detection: Full, Partial, & None.
- Each has it own distinct use for a particular purpose. The driver
- defaults to FULL carrier detection unless you change it. The
- following call is used to change control modes:
-
- CarrierDetect 0 [or] 1 [or] 2
-
- Specifying a TWO (2) sets carrier detection to FULL. This is the
- default mode. When a loss of carrier occurs while transmitting,
- polling for input data, or sitting in a wait loop (XOFF/XON or
- CTS), the driver will return to the calling program and trip the
- UEVENT flag. Tripping the UEVENT flag causes Basic to go to the
- User Event trap routine (providing ON UEVENT GOSUB/UEVENT ON has
- been set up in the user program). You should use this mode only if
- you want to use the UEVENT trap for carrier loss detection. You
- cannot transmit data (with the Transmit function) in this mode if
-
- QBSERIAL User Manual - V 2.10 Page 4
-
-
- there is no carrier. You can send characters in this mode with the
- WriteChar function.
-
- Specifying a ONE (1) sets carrier detection to PARTIAL. This mode
- is similar to FULL with the exception that the UEVENT flag is not
- tripped when carrier is lost. This mode should be used if UEVENT is
- used for something else in your program, or you don't wish to
- utilize UEVENT.
-
- Specifying a ZERO (0) sets carrier detection to NONE. An example of
- this mode would be where "plain Jane" serial I/O is required (such
- as communicating with a "dumb" terminal). In this application there
- are no modem handshake signals (3 wire EIA/RS-232). This mode can
- also be used for talking to a modem when there is no carrier signal
- present (such as dialing and initialization commands). The Transmit
- and WriteChar routines will always transmit data in this mode with
- or without carrier present. Carrier detection must be disabled in
- this mode to prevent calls to Uevent and disable the no carrier
- escape mechanisms built into the XON/XOFF loops. Important: if you
- are using the XOFF/XON protocol in this mode and receive an XOFF
- while transmitting, you will sit forever waiting for an XON. This
- is a normal condition, with the exception that there is no escape
- from this loop other than XON.
-
- Please note that there was an error in documentation in the
- previous version (2.0). With CarrierDetect set to 1 (partial) data
- WOULD NOT be sent if no carrier was present (I had said it would be
- sent). You MUST use mode 0 if you wish to converse with a modem
- that is not currently on-line (has no carrier). Once carrier is
- detected, you would then switch to either mode 1 or 2.
-
- Carrier Loss Detection by Polling
-
- As mentioned above, by default, the UEVENT trap is used to detect
- when a loss of carrier occurs. There is also a function that allows
- you to detect loss of carrier without using the UEVENT trap. While
- I feel that using UEVENT is the simplest way to catch a carrier
- loss in a program, it is possible that UEVENT might need to be used
- by something else. This function is:
-
- X% = CarrierLost
-
- This function call allows to you to 'poll' for the state of
- carrier. CarrierLost returns a NON-ZERO value when there is NO
- carrier, and a ZERO when there IS carrier. CarrierLost is a real
- time function, it returns the current carrier condition at the time
- of the call. This allows you to code simple IF or DO loops to
- detect loss:
-
- IF CarrierLost THEN
- ..process carrier loss
- END IF
-
- QBSERIAL User Manual - V 2.10 Page 5
-
-
-
-
- Program Termination
-
- Since "OpenComm" seizes an interrupt vector, this vector needs to
- be restored BEFORE your program ends. If you neglect to restore
- this vector, you could be risking a crash. The routine used to
- reset the vector is: CloseComm. Only use CloseComm if you specified
- a port value of 1, 2, 3, 4, or a non-standard port address in the
- OpenComm call. If you specified a port value of ZERO (Local mode)
- the interrupt vector is NOT grabbed, and does not need to be reset.
- CloseComm also resets any UART registers to their original value.
-
-
-
- Data Terminal Ready (DTR)
-
- Everybody that has used QuickBASIC's OPEN COMn statement is very
- familiar with the problems of the DTR signal. Apparently Microsoft
- felt that DTR would never be needed after a program terminates.
- Anybody who has ever tried to write a door, or chain from one
- program to another has cursed this decision at some time during
- their programs development. This driver handles the DTR with a
- different view. When you close the comm channel the DTR signal is
- left in the same state it was when you opened the comm channel. For
- door applications, this is a must.
-
- A function call is provided however that allows your program to
- control the DTR signal:
-
- DTRcontrol 1 [or] 0 ' 0 = DTR OFF, 1 = DTR ON
-
- Additionally when you use DTRcontrol to change the state of the DTR
- signal it also instructs the driver to leave it this way when the
- CloseComm function is called. Remember that the driver leaves DTR
- the way it found it when OpenComm was called. If you used some
- other method to change DTR after OpenComm was called, it would
- automatically return to that original state when you called
- CloseComm. Therefor only DTRcontrol should be used if you wish to
- change the state of DTR.
-
- Request To Send (RTS)
-
- Request To Send (RTS) is a hardware flow control signal used to
- tell the remote device to STOP sending data to us. Normally RTS is
- set "on" and data will always flow (or the signal is ignored at the
- remote end). With some communications programs RTS is used to
- temporarily stop a modem from sending data while I/O is done to a
- slow disk. This is especially true with high speed communications
- where there is very little time between interrupts. This function
- is independent of the automatic RTS flow control selected by
- handshake 2 or 3 which tells the remote device to stop sending when
-
- QBSERIAL User Manual - V 2.10 Page 6
-
-
- the input buffer is almost full. This function allows you to
- manually control the state of RTS so you could, for instance, go
- off and write the data somewhere without fear of loosing data.
-
- RTScontrol 1 [or] 0 ' 0 = RTS OFF, 1 = RTS ON
-
- When you use RTScontrol to change the state of the RTS signal it
- also instructs the driver to leave it this way when the CloseComm
- function is called. The driver leaves RTS the way it found it when
- OpenComm was called. If you used some other method to change RTS
- after OpenComm was called, it will automatically return to that
- original state when you call CloseComm. Therefor only RTScontrol
- should be used if you wish to change the state of RTS. This is
- similar in the way DTRcontrol works.
-
- Driver Version and Copyright
-
- A function is available to access the drivers version and copyright
- string. This would be used if you wish to display in your final
- product the version of QBserial that your are using, and/or my
- copyright along with yours. In order to access the copyright
- string, the following lines should be added to your Basic program:
-
- X& = DriverCopyright
- WHILE (PEEK(X&))
- CP$ = CP$ + CHR$(PEEK(X&))
- X& = X& + 1
- WEND
-
- This places the version/copyright string into string variable CP$.
- This string may now be handled in whatever method you choose.
-
-
- Cresent's PDQ Library
-
- An object module for use with PDQ is also included. PDQ does not
- support UEVENT, so all references to UEVENT in the text should be
- ignored. You will need to do carrier checking by polling with the
- CarrierLost function. If you use FULL mode and carrier is lost it
- will operate the same way as PARTIAL mode. The only exception to
- this is the Transmit function, which when in FULL mode, will not
- transmit data.
-
- NOTE: An additional note for PDQ users. Since PDQ replaces the
- Microsoft run time libraries, the public variable
- ACRTUSED is not satisfied during the link stage. A dummy
- stub file, ACRTUSED.OBJ is included with QBserial to
- prevent this error from occurring. The next paragraph
- explains the proper linking sequence.
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 7
-
-
- Linking
-
- Since object modules are provided for QB4.x, BC7, and PDQ, you will
- need to select which one to use for your program. The file
- QBSER.OBJ should be used for programs compiled with QuickBASIC,
- BC7SER.OBJ is to be used for programs compiled with BC7 PDS, and
- QBSERPDQ.OBJ is for PDQ users. Typical link command lines would
- look like this: (Please note that your command lines will probably
- be different if you use additional libraries to generate your code)
-
- Link yourprog qbser; (For QuickBASIC)
-
- Link yourprog bc7ser; (For BC7 PDS)
-
- Link yourprog qbserpdq acrtused; (For PDQ)
-
-
-
- Quick Libraries
-
- If you wish to develop programs from within the environment, you
- will first need to create a Quick library using one of the object
- modules QBSER.OBJ, BC7SER.OBJ, or QBSERPDQ.OBJ. To create a Quick
- lib for QuickBASIC 4.x, use the following Link command:
-
- Link QBSER,,,BQLB4x/q
-
- Where "BQLB4x" is one of the following: BQLB40.LIB, BQLB41.LIB, or
- BQLB45.LIB. Use the one that came with your compiler. If you use
- the wrong BQLB file you might get an "Invalid Format" error when
- attempting to start QuickBASIC. QBSER.OBJ may also be added to
- Quick Libraries containing other routines and OBJ's as well.
-
- To create a Quick Library for use within QBX (BC7's environment)
- use the following link command (be sure to use Link v5.xx that came
- with BC7):
-
- Link BC7SER,,,QBXQLB/q;
-
- For PDQ, use the method for QB4.x, since you will be using the
- built in run time routines built into the environment. You ONLY use
- QBSERPDQ.OBJ when you link the EXEcutable file.
-
- Remember too, that you can also add BC7SER.OBJ to Quicklibs
- containing other routines.
-
-
-
-
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 8
-
-
- Specifications
-
- The following port addresses and default interrupts are used:
-
- Comm Base Address IRQ (Default)
-
- 1 3F8 hex 4
- 2 2F8 hex 3
- 3 3E8 hex 4
- 4 2E8 hex 3
-
- Please read the section explaining the OpenComm function for
- information on how to use addresses or IRQ's other than the
- defaults.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 9
-
-
- Registration and Support
-
- QBserial is distributed as shareware. You may copy and distribute
- it freely.
-
- QBserial is not free software, and requires registration. There are
- two classes of registration which are dependant upon use:
- Commercial and Non-Commercial.
-
- Registration of QBserial is $25 for non-commercial use. Non-
- commercial uses are: Personal use, or use in another shareware
- product such as doors and utilities where you allows others to try
- the product first before buying and request a nominal registration
- fee. Source code is available as an option for an additional $50.
-
- Registration of QBserial for commercial use is $75. Commercial uses
- are: Inclusion of QBserial into ANY product that is to be sold for
- profit, or any use of this program in a business environment. Any
- program that must be paid for in advance before the product is
- delivered, or use in a corporate environment fits this category.
- Commercial registration includes the source code for QBserial in C
- (Microsoft C), if desired.
-
- Please register your copy!
-
- Software and Shareware distribution houses may charge a nominal
- distribution and copying fee not to exceed $5.00. They may not sell
- this program outright or ask you for the registration fee directly,
- they must inform you that registration is required by the author.
-
- If you have access to a BBS that is an ILINK mail network member,
- you can reach me in the Basic conference. If you do not have ILINK
- access anywhere nearby, then you can always contact me on the
- SailBoard BBS at the number listed below. I would prefer if you
- contact me directly on the SailBoard however, as ILINK isn't as
- reliable as Id like, and I have missed messages. I'll do the best I
- can to help if you have questions. Bugs will be tended to if
- required, and good suggestions tend to be implemented.
-
-
- Source Code
-
- The source code for QBserial is available. The source is available
- by signing at the appropriate place on the registration form. The
- source may be used for you own internal uses only. The source may
- not be distributed by you to any other person, even if you make
- changes to it. Nor can the resulting object code be sold or
-
-
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 10
-
-
- distributed. Modifications can only be used in your end product,
- and without any type of royalty. The source is available only after
- you register QBserial. The license fee for the QBserial source code
- is $50.00 for Non-Commercial users. Commercial users receive the
- source as part of their registration fee if they desire it.
-
- Jeff Sumberg
- Sysop(2) - SailBoard BBS
- Wayne, NJ, 201-831-8152
-
- [ or ]
-
- Box 212
- Ringwood, NJ, 07456
-
-
-
- Acknowledgments
-
- Thanks go out to Mark "Sparky" Herring for using these routines in
- his highly successful Qmail door (versions 3 & 4).
-
- Thanks to Mark Wilson for some very good ideas in version 2.0.
- Thanks to Michael Conley for finding a real time sensitive
- interrupt problem.
- Thanks to Jeffrey Morley (author of ZipLab) for testing.
-
-
- Changes and Revisions
-
- 06/09/89 1.0 Initial Release
-
- 06/21/89 1.1 Added carrier detection control. Calling
- program can turn detection off and on as
- desired. Necessary if data sending/receiving
- required if carrier isn't present.
-
- 09/01/89 1.2 Fixed a bug in Readchar where 'extended'
- characters (ASCII 128 to 255) were causing an
- Illegal Function Call in the CHR$() conversion
- (because they were being returned as negative
- numbers). Extended character may now be
- received properly. Added three new functions:
- CDtrap, CarrierLost, and DTRcontrol.
-
-
- 03/24/90 1.5 Added support for Basic Compiler 7.0 PDS and
- PDQ. Added sections to manual about Linking,
- Source code availability, and updated section
- on Quicklibs. Separate object files now
- supplied for QB, BC7, and PDQ.
-
-
- QBSERIAL User Manual - V 2.10 Page 11
-
-
- 05/01/90 1.6 Oops! PDQ users found out fast that I forgot to
- compile the PDQ module with stack checking
- removed. I also forgot to include ACRTUSED.OBJ
- to satisfy linking requirements. Sorry 'bout
- that! Released only as beta to those that
- needed it.
-
- 11/01/90 2.0 Added capability to specify non-standard port
- addresses and which IRQ to use when the port is
- opened. Removed CDtrap function. Created new
- carrier detection modes using the CarrierDetect
- function. (0 = NONE, 1 = PARTIAL, 2 = FULL).
- Also added DriverCopyright function to allow
- program access to the driver version.
-
- 02/08/92 2.10 Added RTS flow control support. RTS will be
- used to control data coming in to QBserial when
- the handshake is set to 2 (CTS/RTS). Removed
- necessity for SERIAL.LIB library file by adding
- inline assembler that performed the routines
- that were previously included in that library.
- QBserial is now compiled with Microsoft C 6.0
- which will give smaller, faster, and more
- efficient code than QuickC could generate. This
- is especially true in the interrupt area. Added
- new function RTScontrol, to allow program to
- control RTS line directly. Increased size of
- input buffer from 1024 to 2048 bytes. Changed
- method in which interrupt controller mask bits
- were set & cleared. Corrected error found in
- documentation describing the function of
- CarrierDetect.
-
-
- Future Plans
-
- I hope in the not to near future to be able to add support for
- extended interrupts (IRQs 8-15). There have been several requests
- for this already.
-
- I also hope to be able to add support for the 16550A buffered UART.
- This would make high speed communications much more reliable.
-
- I would also like to do a version of QBserial that can use two comm
- ports simultaneously.
-
-
-
-
-
-
-
-
- QBSERIAL User Manual - V 2.10 Page 12