Chapter 1 - Introduction This package of asynchronous communications tools for IBM (COM1 - COM4) and Digiboard (intelligent communications hardware, up to 32 ports) hardware, consists of library (.LIB) files for each memory model (SMALL, COMPACT, MEDIUM, LARGE), and for both IBM and Digiboard hardware. It also includes all of the source files, header files (with prototypes) and MAKE files needed to generate the various libraries. Batch files are included for calling make with appropriate flags for each supported compiler. With standard IBM asynchronous hardware, two ports can be opened simultaneous in any of the following combinations (limited because of only 2 interrupts allowed for asynchronous ports in DOS). ALLOWED NOT ALLOWED COM1 and COM2 COM1 and COM3 COM1 and COM4 COM2 and COM4 COM2 and COM3 COM3 and COM4 A working knowledge of 'C' and operation of your compiler is assumed. The "shareware" version is configured for the BORLANDC++ V3.0 compiler in . LIB format, and comes with the small memory model library only (ASYNCS.LIB). Header files with module prototypes for the library routines are included, as well as TEST.C for testing the modules on your system. No other source code is provided with the shareware version or support for Digiboard hardware. Also included are useful demonstration utilities as described in . Becoming a registered user will provide full source code to every module, support for other C compilers, 3 more utility programs, and a bound laser printed manual. There is also full support for Digiboard communications boards which will allow up to 32 ports on your PC. You will also be put on our registered users' list and receive upgrade notification whenever new, expanded versions become available. To register send a check for $45 to: Nordtech Research, Inc. P.O. Box 1011 1608 North Fourth Fairfield, Iowa 52556 Or by phone: (800) 274-7820 (515) 472-7820 Or by Compuserve Mail: 73200,2371 You may also register online with Compuserve. Or by FAX: (515) 472-3524 You can also pay with Visa or Mastercard. Provide your card number and expiration date. Please include the spelling of the name on the credit card. Always include your shipping address. To order by phone, call (800) 274-7820 (please use 800 number for ordering only) or (515) 472-7820. There is a registration/order form in the file README of the shareware version. Chapter 2 - Installation Registered users will receive 2 diskettes. The first diskette contains all files for standard IBM communications hardware (COM1 - COM4). The second diskette contains code for use with Digiboard hardware. If you are not going to use Digiboard hardware, file this diskette. If you are, follow the instructions below for both of your diskettes. First, place the diskette into the floppy drive and then copy all of the utility programs in the root directory of the diskette into the directory where you will place the library source code (for now). All of the utility and library source files, make files, batch files and the file README are archived into the file \SOURCE\SOURCE.ZIP (and \SOURCE\DSOURCE for Digiboard). If you desire to modify the library or want to look at these files, copy this file to the directory where you normally put your source code or to a new directory of your choice. Also copy the public domain utility PKUNZIP.COM (in the \SOURCE directory). Type PKUNZIP SOURCE (DSOURCE for Digiboard) to uncompress all of the source files, make files and batch files. Then follow the directions below for you specific compiler. The following sections assume that you have structured your subdirectories according to the directions for each of the compilers supported. 2.1 Shareware Version The shareware version contains only the BORLANDC small memory model library (ASYNCS.LIB), include files (*.h), and DATAMON.EXE (a nifty data line monitor program for debugging and testing RS-232 devices). All files are compressed together into ASYNC.ZIP. First copy ASYNC.ZIP to the subdirectory where your C source files are kept. Then type PKUNZIP ASYNC to uncompress the files. Copy ASYNCS.LIB to your \BORLANDC\LIB subdirectory. Copy *.H files to \BORLANDC\INCLUDE subdirectory. Print out READMEBC and this manual if desired. Follow instructions in to test your installation with a simple communications test program. 2.2 BorlandC Version Copy \BORLANDC\LIB\*.LIB to your \BORLANDC\LIB subdirectory. Copy \INCLUDE\*.H files to \BORLANDC\INCLUDE subdirectory. In your autoexec.bat file make sure you define the following environment variables to the proper directory. SET INCLUDE=C:\BORLANDC\INCLUDE\ SET LIB=C:\BORLANDC\LIB\ SET BIN=C:\BORLANDC\BIN\ Print out README for latest changes. Follow instructions in to test your installation with a simple communications test program. 2.3 ZORTECH Version Copy \ZORTECH\LIB\*.LIB files to your \ZORTECH\LIB subdirectory. Copy \INCLUDE\*.H files to \ZORTECH\INCLUDE subdirectory. In your autoexec.bat file make sure you define the following environment variables to the proper directory. SET INCLUDE=C:\ZORTECH\INCLUDE\ SET LIB=C:\ZORTECH\LIB\ Print out README for latest changes. Follow instructions in to test your installation with a simple communications test program. 2.4 QuickC Version Copy \MSC\LIB\*.LIB to your \QC\LIB subdirectory. Or to the \LIB directory if this is where you QuickC library files are kept. Copy \INCLUDE\*.H files to \QC\INCLUDE subdirectory. Or to the \INCLUDE directory if this is where your include files are kept. In your autoexec.bat file make sure you define the following environment variables to the proper directory. SET INCLUDE=C:\QC\INCLUDE\ SET LIB=C:\QC\LIB\ Print out README for latest changes. Follow instructions in to test your installation with a simple communications test program. 2.5 MSC Version Copy \C600\LIB\*.LIB to your \C600\LIB subdirectory. Or to the \LIB directory if this is where you MSC library files are kept. Copy \INCLUDE\*.H files to \C600\INCLUDE subdirectory. Or to the \INCLUDE directory if this is where your include files are kept. In your autoexec.bat file make sure you define the following environment variables to the proper directory. SET INCLUDE=C:\C600\INCLUDE\ SET LIB=C:\C600\LIB\ SET BIN=C:\C600\BIN\ Print out README for latest changes. Follow instructions in to test your installation with a simple communications test program. Chapter 3 - Demonstration Program The following code can be used to test this communications package. It is a simple terminal emulation program which reads characters from COM1 and displays them, and sends characters typed at the keyboard out COM1 (change statement in initialize() module if COM2-COM4 is desired). The baud rate as configured is set to 1200 but can be set to any legal value (as defined in ASYNC.H) by changing value in call to Async_Open in the module initialize(). The file TEST.C is included in all versions of the software and contains the code shown in section . Do not attempt to develop larger programs with the library until you can get TEST to work and you fully understand the program. It is quite simple and should be mastered within a few minute's time. Note that this file has included ASYNC.H. ASYNC.H should always be included in any program using these tools. The include file VID.H is included from ASYNC.H to allow generic support for direct video as explained in section . Other tools (file transfer, windows, etc) have other include files as defined in the introductory paragraphs to each of the individual sections discussing modules and files. Note the calls to Async_Init and Async_Open. These modules must always be called prior to any use of the other Async modules. 3.1 Compiler Independent Direct Video All of the supported compilers support direct access to the screen (much faster than using BIOS calls). To allow compiler independent calls to these routines the include file VID.H is supplied. The code you develop does not have to take advantage of these routines, but if you intend to modify the ASYNC library modules, it is recommended that you look at this include file to see how they work. As an example TEST.C below demonstrates their use. The first call to VID_open is needed for the Zortech version. All other compilers require no initialization, and therefore VID_open is a dummy macro in VID.H for BorlandC, QuickC and MSC and is redefined to disp_open for Zortech. VID_putc is for character output, VID_puts for string output and VID_printf for formatted output. VID_startstand sets all following characters to reverse video, VID_endstand sets the following characters to normal video. VID_clr_scr erases the entire screen. VID_move(x,y) moves the cursor to row x, column y (0,0 is upper left). Microsoft (MSC and QC) users should be aware that using direct video requires linking with the GRAPHICS.LIB library that came with your compiler. This makes programs grow quite large. 3.2 EXTERN symbol You will notice that the first statement in TEST.C is: #define EXTERN This symbol is used by ASYNC.H and other header files to determine if this is the main module where variables are not defined as "extern". ASYNC.H and the other header files first check to see if EXTERN is already defined and if not they create it as: #define EXTERN extern Only define EXTERN (#define EXTERN) in your main module to tell the compiler that it should place the global variables there. 3.3 BorlandC Command Line To compile TEST.C and link it with the async library small memory model library, type the following: tmf test S After successful compilation, type TEST and press . As you type characters they will be sent out COM1. Characters received at COM1 will be displayed on the screen. Press to quit back to DOS. 3.4 BorlandC Environment First create a project file called test.prj which has the following lines: test asyncs.lib Then enter the BorlandC environment (BC) and name the project file TEST. Set a compiler DEFINE to be _BORLANDC and then RUN. After successful compilation, the screen will blank and as you type characters they will be sent out COM1. Characters received at COM1 will be displayed on the screen. Press to quit back to the BORLANDC environment. 3.5 Zortech C To compile TEST.C and link it with the async library, type the following: zmf test After successful compilation, type TEST and press . As you type characters, they will be sent out COM1. Characters received at COM1 will be displayed on the screen. Press to quit back to DOS. 3.6 QuickC Command Line To compile TEST.C and link it with the async library, type the following: qmf test After successful compilation, type TEST and press . As you type characters, they will be sent out COM1. Characters received at COM1 will be displayed on the screen. Press to quit back to DOS. QMF.BAT will place an 'M' after the name of the file (i.e. TEST will become TESTM). This is because the make files for Microsofts MAKE program are quite a bit different than for Borlands MAKE. 3.7 MSC Command Line To compile TEST.C and link it with the async library, type the following: mmf test After successful compilation, type TEST and press . As you type characters, they will be sent out COM1. Characters received at COM1 will be displayed on the screen. Press to quit back to DOS. MMF.BAT will place an 'M' after the name of the file (i.e. TEST will become TESTM). This is because the make files for Microsofts MAKE program are quite a bit different than for Borlands MAKE. 3.8 TEST.C /* |-----------------------------------------------|*/ /* | |*/ /* | test -- test async library program |*/ /* | |*/ /* |-----------------------------------------------|*/ #define EXTERN #include #include #include #define COM1 0 #define COM2 1 #define COM3 2 #define COM4 3 #define SCAN 0 /* func. key scan code lead in */ #define QUIT 'D'/* F10 quit */ #define TRUE 1 char KbData, ModData; int port; main() { initialize(); VID_puts("\nPress F10 to quit...\n"); do { if (kbhit()) { /* get any char at kbd */ KbData = getch(); if (KbData == SCAN) { /* FUNCTION KEY */ KbData = getch(); switch (KbData) { case QUIT : CloseUp(); } } else Async_Send(port, KbData); } if (Async_Receive(port, &ModData)) { VID_putc(ModData); } } while (TRUE) /* main while loop */ } /* main */ CloseUp() { Async_Close(port); VID_close(); exit(0); } initialize() { VID_open(); port = COM1; Async_Init(); if (!Async_Open(port, 1200, 'E', 7, 1, 1000, 1000)) { VID_printf("Error opening COM%1s\n", port+1); VID_flush(); } } ProcessInputs() /* dummy routine for Delay module */ { } Chapter 4 - Files and Modules This chapter will describe each of the modules included with this communications library. 4.1 File A_INIT.C Modules (initialize, open, close) Before using any of the modules described in this section, include the file ASYNC.H. The 3 following modules need to be called whenever using these tools. The first procedure (Async_Init) initializes all buffer variables and is only called once before any other Async routine is called. The second procedure ( Async_Open) is called once for each communications port needed before it is ever used. The third routine (Async_Close) is called at the end of processing once for each open port. Routines: Async_Init Performs initialization. Async_Open Sets up COM port Async_Close Closes down COM port Async_Init --- Initialize Asynchronous Variables Purpose: Initializes variables, always call first and only call one time. Calling Sequence: Flag = Async_Init(); Calls: None (Except Digiboard version). Returns: TRUE is successful FALSE otherwise. (Always true except for DIGIBOARD version). int Async_Init(void) Async_Open --- Open communications port Purpose: This module initializes the communications hardware and sets up the interrupt vectors for the receive and send buffers. Calling Sequence: Flag = Async_Open(Port, BaudRate, Parity, WordSize, StopBits, RBuff, SBuff) Port which port (0, 1, 2, 3)(0=COM1 1=COM2 2=COM3 3= COM4) BaudRate Baud rate (110 to 57600) set to B115K for 115200 baud Parity "E" for even, "O" for odd, "N" for none WordSize Bits per character (5 through 8) StopBits How many stop bits (1 or 2) RBuff Size of receive buffer to allocate (number of WORDS, max 32K) SBuff Size of send buffer to allocate (number of CHARS, max 64K). Set to 0 to not use send interrupts. Flag returned TRUE if port opened successfully. Flag returned FALSE if any errors. Calls: intsetup (see asyncm.asm) Async_Open(int Port, unsigned BaudRate, char Parity, int WordSize, int StopBits, int RBuff, unsigned SBuff) Async_Close --- Close down communications interrupts Purpose: Resets interrupt system to what it was before port opened. Calling Sequence: Async_Close(port); port port to close. Calls: None void Async_Close(int Port) 4.2 File A_CHAR.C Modules (Send/Recv 1 char at a time) IMPORTANT: when compiling this module do not turn on the compiler stack overflow checking option. The interrupt service routine sets up its own stack that will cause run time errors if this switch is turned on. The modules in this section are used to send and receive data one character at a time. The module Async_Receive_With_Timeout returns -1 if a specified time elapses without a character coming in. The module Async_Putback puts a character back into the receive buffer such that it will be the next character read by Async_Receive or any module used to read characters from the buffer. Routines: Async_Receive Reads character from COM buffer Async_Putback Replace a character in COM buffer Async_Send Places char in send buffer Async_Receive_With_Timeout Receives char with timeout check Async_Send_Brk Sends break (attention) signal Async_Purge_Buffer Clears receive buffer Async_Isr Interrupt service routine Async_Receive --- Retrieve a character from buffer Purpose: Retrieve character (if any) from buffer Calling Sequence: Flag = Async_Receive(port, &c); port port to read character from c character (if any) retrieved from buffer Flag returned 1 if character retrieved from buffer. Flag returned 0 if no character retrieved. Flag returned with port status if character retrieved with parity, overrun or framing error Calls: None Async_Receive(int port, unsigned char *c) Async_Putback --- Return character to buffer Purpose: Replace character in buffer. If a character needs to be put back into buffer for a another module, etc. Calling Sequence: Async_Putback(port, c); port port to put character into c character to put back into buffer Calls: None Async_Putback(int port, unsigned char c) Async_Send --- Places a character in the send buffer Purpose: This module places a character in the send buffer. The character will be sent automatically at a later time by the interrupt service routine. Calling Sequence: Async_Send(port, c); port port to send character to c character to place in send buffer Calls: DeltaTime Remarks: If the send buffer is full this routine will wait .25 seconds for room to be made. If it is still full (probably something wrong) it will return ERR. void Async_Send(int port, unsigned char c) Async_putc --- Sends a character out the port without buffering Purpose: This module sends a character out the port. The character is sent immediately and not buffered. Calling Sequence: Async_putc(port, c); port port to send character to c character to send Calls: DeltaTime Remarks: If the send holding register is full this routine will wait .25 seconds for room to be made. If it is still full (probably something wrong) it will return ERR. void Async_putc(int port, unsigned char c) Async_Receive_With_TimeOut --- Retrieve a char from buffer with delay Purpose: Retrieve character as integer from buffer, or return TIMEOUT if specified delay period expires. Calling Sequence: Async_Receive_With_Timeout(port, delay, &C); port which commo port delay Timeout period in hundreths of a second C character (if any) retrieved from buffer. Set to TIMEOUT if Timeout occurs prior to character being received. Calls: Async_Receive int Async_Receive_With_Timeout(int Port, int Hunds, unsigned char *C) Async_Send_Brk --- Send break (attention) signal Calling Sequence: Async_Send_Brk(port); port which commo port Calls: None void Async_Send_Brk(int Port) Async_Purge_Buffer --- Purge communications input buffer Calling Sequence: Async_Purge_Buffer(port); port which commo port Calls: Async_Receive void Async_Purge_Buffer(int port) Async_Isr --- Interrupt Service Routine Purpose: When an interrupt has occurred for one of the communications ports, this routine is called by the routine to which the commo interrupts are vectored (intserv in asyncm.asm). Used for both send and receive interrupts as well as receive errors and BREAK processing. DO NOT CALL THIS ROUTINE. Calling Sequence: Async_Isr(port); interrupt Async_Isr(int port) 4.3 File A_STRNG.C Modules (Send strings) Routines: Async_Send_String Sends string over COM port Async_Send_String_With_Delays Sends string with timed delays Async_Send_String --- Send string over communications port Purpose: This module places a string of characters into the send buffer. Calling Sequence: Async_Send_String(port, s); port port to send chars to s string to send Calls: Async_Send void Async_Send_String(int port, unsigned char *s) Async_Send_Line --- Send line over communications port Purpose: This module places a string of characters into the send buffer followed by a NEWLINE. Calling Sequence: Async_Send_Line(port, s); port port to send chars to s string to send Calls: Async_Send void Async_Send_Line(int port, unsigned char *s) Async_Send_String_With_Delays --- Send string with timed delays Purpose: Sends string out over communications port with specified delays for each character and at the end of the string. Calling Sequence: Async_Send_String_With_Delays(port, s, char_Delay, EOS_Delay); port which commo port s String to send char_Delay Number of hundreth of second to delay per character EOS_Delay Number of hundreth of second to delay at end Calls: Async_Send Async_Send_String Delay Remarks: This routine is useful when writing routines to perform non-protocol uploads. Many computer systems require delays between receipt of characters for correct processing. The delay for end-of-string usually applies when the string represents an entire line of a file. If delays are not required, Async_Send_String is faster. This routine will call Async_Send_String if no character delay is to be done. void Async_Send_String_With_Delays(int port, unsigned char *s, int char_Delay, int EOS_Delay) 4.4 File A_HNDSHK.C Hardware Handshake Modules Routines: Async_DTR Set or clear Data Terminal Ready Async_RTS Set or clear Request To Send Async_DSR Check for modem DSR Async_CTS Check for modem CTS Async_DCD Checks for modem carrier detect Async_Carrier_Drop Checks for modem carrier drop Async_RI Check for modem RI Async_Percentage_Used Returns percentage Buffer used Async_SPercentage_Used Returns percentage SBuffer used Async_Buffer_Check Checks if character in COM buffer Async_DTR --- Set data terminal ready status Calling Sequence: Async_DTR(port, Ready_Status); port which commo port Ready_Status Set TRUE to set on, Set FALSE to set off. Calls: None void Async_DTR(int Port, char Ready_Status) Async_RTS --- Set Request To Send Calling Sequence: Async_RTS(port, Ready_Status ); port which commo port Ready_Status Set TRUE to set send on, Set FALSE to set off Calls: None void Async_RTS(int Port, char Ready_Status) Async_DSR --- Check for modem DSR Calling Sequence: Flag = Async_DSR(port); port which commo port Flag is set TRUE if "data set ready" detected, else FALSE. Calls: None int Async_DSR(int Port) Async_CTS --- Check for modem CTS Calling Sequence: Flag = Async_CTS(port); port which commo port Flag is set TRUE if "clear to send" detected, else FALSE. Calls: None int Async_CTS(int Port) Async_DCD --- Check for modem carrier detect Calling Sequence: Flag = Async_DCD(port); port which commo port Flag is set TRUE if "data carrier" detected, else FALSE. Calls: None int Async_DCD(int Port) Async_Carrier_Drop --- Check for modem carrier drop Calling Sequence: Flag = Async_Carrier_Drop(port); port which commo port Flag is set TRUE if carrier not detected, else FALSE. Calls: None int Async_Carrier_Drop(int Port) Async_RI --- Check for modem RI Calling Sequence: Flag = Async_RI(port); port which commo port Flag is set TRUE if "ring indication" detected, else FALSE. Calls: None int Async_RI(int Port) Async_Percentage_Used --- Report Percentage Buffer Filled Calling Sequence: Percentage = Async_Percentage_Used(port); port which commo port Percentage value range from 0 (empty) to 100 (full). Calls: None Remarks: This routine is helpful when incorporating handshake into a communications program. For example, assume that the host computer uses the XON/XOFF (DC1/DC3) protocol. Then the PC program should issue an XOFF to the host when the value returned by Async_Percentage_Used > 75 or so. When the utilization percentage drops below 25 or so, the PC program should transmit an XON. int Async_Percentage_Used(int port) Async_SPercentage_Used --- Report Percentage SBuffer Filled Calling Sequence: Percentage = Async_SPercentage_Used(port); port which commo port Percentage value range from 0 (empty) to 100 (full). Calls: None Remarks: This routine reports the status of the send buffer. int Async_SPercentage_Used(int port) Async_Buffer_Check --- Check if character in receive buffer Calling Sequence: Flag = Async_Buffer_Check(port); port port to check for waiting chars. Flag returned TRUE if character received in buffer. Flag returned FALSE if no character received. Calls: None Remarks: This routine only checks if a character has been received and thus can be read; it does NOT return the character. Use Async_Receive to read the character. int Async_Buffer_Check(int port) 4.5 File A_MODEM.C Modules (Hayes modem support) Routines: Async_Signon Sign on with Hayes modem (AT) Async_Signoff Hang up phone (place on hook) Async_Signon --- Dial phone using Hayes AT command sequence Calling Sequence: Async_Signon(port, phone); port port conneted to modem. phone string with phone number (T first char for Touch Tone) Calls: Async_Send_String, Async_Send, Delay void Async_Signon(int port, unsigned char *phone) Async_Signoff --- Hang up phone using Hayes AT command sequence Calling Sequence: Async_Signoff(port); port which commo port Calls: Async_Send_String, Delay void Async_Signoff(int port) 4.6 File A_TIMING.C Modules Modules in this file are used for real-time delays where various processes may still need to be performed while another process is being delayed (user needs to provide a ProcessInputs() routine, can be empty if not needed). Two other routines are provided for timing purposes. Before using any of the modules in this section include the file TIMING.H. Routines: Delay Wait for n hundredths of a second DeltaTime Determine elapsed time since specified time. GetSystemHundreths Read system hundreths of a second from counter. Delay -- Wait for n hundredths of a second Calling Sequence: Delay(n) n number of hundreths of a second to wait for Calls: ProcessInputs (provided by user or dummy if not needed) void Delay(int n) DeltaTime -- Determine how much time has elapsed since specified time. Calling Sequence: delta = DeltaTime(t1) t1 number of system hundreths to calculate elapsed time since. delta is set to number of hundreths elapsed since t1. Calls: GetSystemHundreths unsigned DeltaTime(unsigned long t1) GetSystemHundreths -- Read system hundreths of a second from counter. Calling Sequence: t = GetSystemHundreths() t Hundreths of a second counter from system. Calls: system (DOS or memory location) unsigned long GetSystemHundreths(void) 4.7 File FILEXFER.C Modules Before using any of the modules in this section include the file XFER.H. Routines: initxfer Initialize xfer variables upload upload a file with XOFF/XON protocol recvfile Receive a file in XMODEM protocol sendfile send a file in XMODEM protocol WaitFor Wait for specified string from port initxfer --- initialize file transfer variables Calling Sequence: initxfer(); Calls: none void initxfer(void) upload --- upload a file with XOFF/XON protocol Purpose: Sends a file with XOFF/XON protocol, no error check Calling Sequence: upload(port, file); port port to send file out of file name of file to send Calls: Async_Send, mcharinp, readchar, Async_Buffer_Check void upload(int port, char *file) sendfile --- send a file using XMODEM protocol Calling Sequence: flag = sendfile(port, file); port port to send file out of file name of file to send flag is set to ERROR if file is not found or transfer was not successful. flag is set to TRUE if file transfer was successful Calls: Async_Send, readchar int sendfile(int port, char *file) recvfile --- receive a file using XMODEM CHECKSUM protocol Calling Sequence: flag = recvfile(port, file); port port to send file out of file name of file to receive flag is set to ERROR if file can't be created or transfer was not successful. flag is set to TRUE if file transfer was successful Calls: Async_Send, readchar, creat, putc_scr int recvfile(int port, char *file) WaitFor --- Get data from a port until specified string is received. Calling Sequence: flag = WaitFor(port, string, startdelay, chardelay); port port to send file out of string string to wait for startdelay delay time to allow for first char to come chardelay delay time to allow for each additonal char flag is set to TIMEOUT if string is not received within time allowed. flag is set to TRUE if string is received. Calls: readchar int WaitFor(int port, unsigned char *string, int startdelay, int chardelay); 4.8 File WIND.C Modules Before using any of the modules in this section include the file WIND.H. See DATAMON.C for an example of the use of these modules. Routines: InitWindow Initialize window variables DefineWindow Define a new window in screen coordinates SelectWindow Change current window number for subsequent data StringToWindow Write a string to a specified window CharToWindow Write a character to a specified window CRLFToWindow Put cursor of specified window to next line start WindowNorm Set current window to normal WindowRV Set current window to reverse video WindowBlink Set current window to blink WindowUL Set current window to underline WindowHigh Set current window to high intensity WindowLow Set current window to low intensity scroll scroll current window up or down scroll_partial scroll current window, or insert/delete line ClearWindow clear current window to all blanks clear clear portion of current window inccur increment cursor location, scroll if necessary putcursor display the cursor in current position deccursor move cursor left and wrap up if flag set poscur position current window cursor proprt process a printing character to current window proctl process a control char to current window clr_scr clears the actual screen SwapOut copy screen to buffer area SwapIn copy saved page to screen buffer InitWindow --- Initialize window variables Calling Sequence: InitWindow(); Calls: None Remarks: See Datamon for example of usage void InitWindow(void) DefineWindow --- Define a new window in screen coordinates Calling Sequence: DefineWindow(num, xul, yul, xlr, ylr); num window number (set by caller) xul, yul x and y of upper left corner of window (screen) xlr, ylr x and y of lower right corner of window Calls: None Remarks: See Datamon for example of usage void DefineWindow(int num, int xul, int yul, int xlr, int ylr) SelectWindow --- Change current window number for subsequent data Calling Sequence: SelectWindow(n) n number of new window Calls: None Remarks: Sets WindowN global variable void SelectWindow(int n) StringToWindow --- Write a string to a specified window Calling Sequence: StringToWindow(Window, Str) Window number of window to write string to Str character string to write Calls: CharToWindow Remarks: Call with WindowN for current window void StringToWindow(int Window, char *Str) CharToWindow --- Write a character to a specified window Calling Sequence: CharToWindow(Window, c) Window number of window to write char to c char to write Calls: proprt, proctl Remarks: call with WindowN for current window. c can be a control character. void CharToWindow(int Window, char c) CRLFToWindow --- Put cursor of specified window to next line start Calling Sequence: CRLFToWindow(Window); Window number of window to move cursor of Calls: CharToWindow void CRLFToWindow(int Window) WindowNorm --- Set attribute of current window to Normal Calling Sequence: WindowNorm(); Calls: None void WindowNorm(void) WindowRV --- Set attribute of current window to Reverse Video Calling Sequence: WindowRV(); Calls: None void WindowRV(void) WindowBlink --- Set attribute of current window to Blink Calling Sequence: WindowBlink(); Calls: None void WindowBlink(void) WindowUL --- Set attribute of current window to Underline Calling Sequence: WindowUL(); Calls: None void WindowUL(void) WindowHigh --- Set attribute of current window to High Intensity Calling Sequence: WindowHigh(); Calls: None void WindowHigh(void) WindowLow --- Set attribute of current window to Low Intensity Calling Sequence: WindowLow(); Calls: None void WindowLow(void) scroll --- scroll current window up or down Calling Sequence: scroll(Direction); Direction set to UP or DOWN for direction of scroll Calls: scroll_partial Remarks: UP means top line of top of screen, blank bottom void scroll(int Direction) scroll_partial --- scroll current window, or insert/delete line Calling Sequence: scroll_partial(Direction, YTop) Direction set to UP or DOWN for direction of scroll YTop set to top line of window to scroll Calls: memmovew, memsetw, get_off_xy Remarks: This routine is used to scroll window, insert line (scroll DOWN at YTop set to insert point) and delete line (scroll UP at YTop set to delete line) void scroll_partial(int Direction, int YTop) ClearWindow --- clear current window to all blanks Calling Sequence: ClearWindow(); Calls: clear void ClearWindow(void) clear --- clear portion of current window Calling Sequence: clear(xmin, ymin, xmax, ymax) xmin, ymin coords of up/left corner of region to clear xmax, ymax coords of lower/right corner of region to clear Calls: memsetw Remarks: coords relative to current window void clear(int xmin, int ymin, int xmax, int ymax) inccur --- move cursor right, wrap, scroll if necessary Calling Sequence: inccur(); Calls: scroll, poscur Remarks: Current window. Called by proprt, etc. void inccur(void) putcursor --- display the cursor in current position Calling Sequence: putcursor(); Calls: poscur Remarks: Current window. Called by proprt, etc. void putcursor(void) deccursor --- move cursor left and wrap up if flag set Calling Sequence: deccursor(); Calls: poscur Remarks: does not scroll down if at top. Current window void deccursor(void) poscur --- position current window cursor. Calling Sequence: poscur(x, y); x, y location to move cursor to Calls: Remarks: x and y relative to window start void poscur(int x, int y) proprt --- process a printing character to current window Calling Sequence: proprt(c); c printable char (> BLANK) Calls: memsetw, inccur Remarks: use proctl for control characters (in current window) void proprt(char c) proctl --- process a control char to current window Calling Sequence: proctl(c); c a control character Calls: bdos, clear, poscur, scroll, deccursor, proprt, proctl (recursive) Remarks: many control chars are displayed void proctl(char c) SwapOut --- Copy screen to buffer area Calling Sequence: SwapOut(); Calls: peekw Remarks: Uses global variables initialized in InitWindow. Only one screen can be swapped out at a time. void SwapOut(void) SwapIn --- copy saved page to screen buffer Calling Sequence: SwapIn(); Calls: pokew void SwapIn(void) 4.9 File PRINTER.C Modules This file contains code for buffered printer support for LPT1 only at this point. Routines: InitPrinter Initialize printer, alloc memory StringToPrinter Write a string to printer CRLFToPrinter Send CR/LF sequence to printer CharToPrinter Write a char to printer (doesn't use buffer) PutPrinterBuffer Put a character into printer output buffer SendPrinterBuffer Send a character from printer buffer InitPrinter --- Initialize printer, alloc memory Calling Sequence: InitPrinter(); Calls: int86, VID_puts, CloseUp void InitPrinter(void) StringToPrinter --- Write a string to printer Calling Sequence: StringToPrinter(s); Calls: PutPrinterBuffer void StringToPrinter(unsigned char *s) CRLFToPrinter --- Write a CR and LF to printer Calling Sequence: CRLFToPrinter(); Calls: PutPrinterBuffer void CRLFToPrinter(void) CharToPrinter --- Write a char directly to printer Calling Sequence: CharToPrinter(c); Calls: int86 void CharToPrinter(unsigned char c) PutPrinterBuffer --- Put a char into printer buffer Calling Sequence: PutPrinterBuffer(c); Calls: none void PutPrinterBuffer(unsigned char c) SendPrinterBuffer --- Write a char to printer from buffer Calling Sequence: SendPrinterBuffer(); Calls: CharToPrinter void SendPrinterBuffer(void) 4.10 File ASYNCM.ASM Modules The modules in this file are written in assembly language for speed and portability across various "C" compilers. Users of this library will not need to call any of these routines. They are all called by Async_Open, described in . If you do modify or otherwise need to recompile them, MASM v5.1 or later must be used, or any version of TASM. See make files for command line compile options. Routines: intsetup Set interrupt vector offset with current CS intserv Low level commo interrupt service getvec Get current interrupt vector setvec Set interrupt vector (segment and offset) inton STI intoff CLI 4.11 File PEEKW.ASM Modules The modules in this file are written in assembly language for speed and portability across various "C" compilers. Users of this library will not need to call any of these routines. These routines augment standard library routines for accessing and writing to memory. Routines: peekw Move n words from SEG:OFF to DS:BUF pokew Move n words from DS:BUF to SEG:OFF movewords Move n words from SEG1:OFF1 to SEG2:OFF2 memsetw Set n words at SEG:OFF to c memmovew Move n words from SEG:OFF1 to SEG:OFF2 peekb Get 1 byte from SEG:OFF to AL pokeb Store 1 byte at SEG:OFF Chapter 5 - Library Maintenance Please see Chapter for instructions on decompressing the source, make and batch files discussed here. Each of the libraries (different memory models) can be created with a specific makefile. A batch file is included for each compiler (see following sections) which will set the flags necessary to invoke the correct compiler and route the completed library to the correct subdirectory. There is also a batch file for each compiler (MAKEALLT for BorlandC, MAKEALLZ for Zortech, MAKEALLQ for QuickC, MAKEALLM for MSC) which will recompile each of the memory model libraries. These batch files can be used only if you have DOS 3.3 or later (they use the CALL command within the batch file). If you do not use the standard directory layout specified with the compiler, you will need to edit the appropriate batch file. The following files are combined into the library and if modified you will need to recreate the library. If you do not have an assembler (WHAT?) you will need to extract the 2 object files ASYNCM.OBJ and PEEKW.OBJ from the appropriate library file (your compiler, the appropriate memory model .LIB file) prior to running the batch file to create the library. Otherwise the LIB command (or TLIB) will not be able to find the object file. Alternatively you could edit the makefile and take out the part of the statement which attempts to update these 2 modules in the library. A_INIT.C A_CHAR.C A_HNDSHK.C A_MODEM.C A_STRNG.C A_TIMING.C ASYNCM.ASM PEEKW.ASM For the Digiboard version, the following are combined into the library file: D_INIT.C D_CHAR.C D_HNDSHK.C D_MODEM.C D_STRNG.C D_TIMING.C DIGI.C PEEKW.ASM 5.1 BorlandC maintenance The batch file is called TMF.BAT. It utilizes the command line version of BorlandC. If you modify any of the files that are part of the standard library type TMF ASYNC ?. ? is replaced by S for the small memory model, C for compact (large data) model, M for medium (large code) model, and L for the Large model. Or use MAKEALLT as described above to recompile every memory model. There is also a batch file called BORLANDC.BAT which sets up the environment variables needed in the makefiles. You will undoubtedly need to edit this file because your environment (directories, disks, etc.) will be different than ours. 5.2 ZORTECH maintenance The batch file is called ZMF.BAT. If you modify any of the files that are part of the standard library type ZMF ASYNC?. ? is replaced by S for the small memory model, C for compact (large data) model, M for medium (large code) model, and L for the large (large code and data) model. Or use MAKEALLZ as described above to recompile every memory model. There is also a batch file called ZORTECH.BAT which sets up the environment variables needed in the makefiles. You will undoubtedly need to edit this file because your environment (directories, disks, etc.) will be different than mine. 5.3 QuickC maintenance The batch file is called QMF.BAT. If you modify any of the files that are part of the standard library type QMF ASYNC?. ? is replaced by S for the small memory model, C for compact (large data) model, M for medium (large code) model, and L for the large (large code and data) model. Or use MAKEALLQ as described above to recompile every memory model. There is also a batch file called QUICKC.BAT which sets up the environment variables needed in the makefiles. You will undoubtedly need to edit this file because your environment (directories, disks, etc.) will be different than mine. An additional file is needed for the Microsoft versions: a_printf.c. This file is used to implement a direct video printf routine. 5.4 MSC maintenance The batch file is called MMF.BAT. If you modify any of the files that are part of the standard library type MMF ASYNC S. ? is replaced by S for the small memory model, C for compact (large data) model, M for medium (large code) model, and L for the large (large code and data) model. Or use MAKEALLM as described above to recompile every memory model. An additional file is needed for the Microsoft versions: a_printf.c. This file is used to implement a direct video printf routine. There is also a batch file called MSC.BAT which sets up the environment variables needed in the makefiles. You will undoubtedly need to edit this file because your environment (directories, disks, etc.) will be different than mine. Chapter 6 - DIGIBOARD Software 6.1 DIGIBOARD Concepts The Digiboard intelligent communications hardware boards utilize different libraries than the standard IBM asynchronous hardware. These routines are found in the files D_*.C, DIGI.C with header files ASCYND.H and M232.H. Use of the routines should be identical to using the normal modules, however several special considerations need to be addressed. Upon start up, Async_Init will need to upload the file M232.FCM to each board installed in the system (up to 4 boards, 32 ports). Make sure that this file (M232.FCM) is in the same directory as your compiled program. The number of boards installed, total number of ports, and number of ports per board need to be set in the header file M232.H. The library files ASYNC?D.LIB on distribution diskette #2 were compiled for 1, 8 port board. If your system is different than this, you will need to recompile the library after setting these variables in M232.H. To recompile the library type: TMF ASYNC S -DDIGI (small memory model, Digiboard, BorlandC) ZMF ASYNCSD ( Zortech) QMF ASYNCSD ( QuickC) MMF ASYNC S DIGI=1 ( MSC) For other memory models, replace S with C, M or L. The utility DATAMOND is the same as DATAMON but configured for use with Digiboard hardware. The make file DATAMOND.M should be used instead of DATAMONS.M if you desire to modify the program. The header file DATAMON.H shows how the include file ASYNCD.H is used in place of the normal ASYNC.H if Digiboard hardware is present. The DEFINE variable DIGI is set automatically by DATAMOND.M as shown. Please use these examples when creating your own software for use with Digiboard hardware. 6.2 Digiboard Hardware Setup The Digiboard hardware can be setup at many different interrupts and port locations. Use of this software as configured requires the following setup. Board # I/O Port IRQ J2 J3 J4 J15 J16 J17 1 320 5(J11) 1-2 1-2 1-2 1-2 1-2 2-3 2 300 5(J11) 1-2 1-2 2-3 1-2 2-3 2-3 3 220 5(J11) 1-2 2-3 1-2 2-3 1-2 2-3 4 200 5(J11) 1-2 2-3 2-3 2-3 2-3 2-3 See the Digiboard COMi installation manual (page 7) for information on jumpering of the I/O port addresses. 6.3 DIGI.C User should not modify modules in this file. There are however several handshaking options which are set with routines in this file. See DATAMON.C for an example of setting up incoming hardware flow control. For further information contact us. 6.4 D_*.C These files contain all modules which are found in the files a_*.c as defined in . Many of the modules are implemented differently due to the special requirements of using the coprocessor on board the Digiboard. Their use remains the same as previously discussed. The one change is that you can not specify the size of the receive or send buffers (Async_Open). They are fixed at 1000 characters. When calling Async_Open you still need to have some value set as in the IBM versions for compatilbilty, again see DIGIBOARD.C. 6.5 D_BLOCK.C Async_Send_Block --- Send a block of data over communications port Purpose: This module retrieves a block of characters from the Digiboard receive buffer. Calling Sequence: num = Async_Get_Block(port, unsigned char *data, max); port port to get chars from data pointer to area to put block of chars max maximum number of chars to get num returned with number of characters (words) copied from Digiboard, 0 if no characters retrieved. Calls: None int Async_Get_Block(int port, unsigned char *data, max) Async_Send_Block --- Send a block of data over communications port Purpose: This module places a block of characters into the Digiboard send buffer. Useful when a Calling Sequence: numsent = Async_Send_Block(port, char *s, num); port port to send chars to s string to send num number of char in block to send numsent returned with number of characters (words) sent to Digiboard, 0 if buffer couldn't hold num. Calls: None int Async_Send_Block(int port, unsigned char *s, num) Chapter 7 - Included Utilities The following sections will describe complete programs developed using the modules describe in . Each of these programs is provided on disk in compiled form with all source code included. Each of these modules are useful tools for anyone who uses a personal computer. 7.1 DATAMON The Datamon program is a very powerful and useful tool when developing new software involving communications or anytime two communications devices are being connected. The makefile DATAMONS.M (S for small memory model) can be used to recreate the program if you desire to modify it. Use the appropriate batch file for your compiler to execute make (i.e. TMF DATAMON S for BorlandC users, see . Microsoft users type MMF DATAMON S or QMF DATAMON). Also see section for information about creating DATAMOND for use with Digiboard hardware. This utility can immediately show whether a "null" modem cable is needed and which control voltages are being provided by the other device. It can also be used to determine baud rates, parity, etc. The program shows the status of each hardware handshake line, allows easy changing of baud rate, port number, data bits, parity, stop bits. With one function key () it sends the "The quick brown fox... " message. It can capture received data and save the captured data to disk at exit. A very powerful feature is the Auto Baud Detect capability described later. It can, as its name implies, determine and set baud rate, parity and number of data bits to match that of incoming data on a line. There are no command line arguments and after starting the program the following screen is displayed. The upper window of the screen displays the current status of each of the handshake lines. The DCE STATUS lines are values provided by the device on the other end. The DTE STATUS values are controlled by pressing (RTS) and ( DTR). They are HIGH when first brought up. These control signals can only be used of course, if the appropriate pin is connected properly to the other device. This window also displays the status of the other pertinent communications parameters: baud rate, # of data bits, parity, # of stop bits, and which communications port. Baud rate is 1200 when first brought up and is changed by pressing . It will vary between 110 and 115200. If you see PARITY, FRAMING, BREAK or OVERRUN displayed those conditions are detected. These conditions, when displayed, are for the last character or bit sequence received. Framing and overrun usually means incorrect baud rate selection. Playing with baud rate (),number of data bits and parity in that order will allow you to determine appropriate settings for a more permanent program to attach to the port. Also see Auto Baud Detect discussion below. The middle window of the screen will display characters received over the communications port. The lower area of the screen displays the use of each of the function keys. These are described here. Pressing will start capturing received text into a 16K buffer. Pressing it again will discontinue capture. When you end the session () you will be asked for a filename to save the captured text to if desired, or RETURN if you don't want it. Pressing will send the message "The quick brown fox jumped over the lazy dog's back.". This message contains every alphabetic character controls parity. Values are EVEN, ODD and NONE. controls the number of data bits. Values are 5, 6, 7 and 8. is for number of stop bits (1 or 2). controls RTS. controls DTR. controls which PORT is being used. Pressing will look for another port and change to it if it is found. Values are COM1 through COM4. is used to send a BREAK sequence over the communications line. This signal (hold transmit line at SPACE) is used often to interrupt or otherwise signal other processes. turns on Auto Baud Detect. This is a powerful feature which actually can adjust baud rate, number of data bits, and parity to match that of an incoming signal. The word DETECT will appear in reverse video and any line error will change parity, data bits or baud rate in an attempt to adjust. Press again to turn this feature off. Manual adjustments are allowed when this process is taking place so you can help the system out. SUMMARY OF DATAMON KEY USAGE CAPTURE text to buffer for later saving to disk. Send "The quick brown fox ... " Change BAUD RATE Change PARITY Change DATA BITS Change STOP BITS Toggle RTS Toggle DTR Change PORT Send BREAK signal Toggles Auto Baud Detect QUIT (return to DOS) 7.2 SEND and RECV: quick file transfer The combination of SEND and RECV allows rapid transferring of files between two computers. Each of the two uses the XMODEM protocol to insure data integrity. The makefile SEND.M (RECV.M for RECV) can be used to recreate the program if you desire to modify it. Use the appropriate batch file for your compiler to execute make (i.e. TMF SEND S for BorlandC users, see ). Individual files can be specified or, optionally, a file can be specified which contains names of other files (one per line) which are to be transferred. This can also be done in conjunction with specifying individual file names. One very powerful use of these utility programs is to specify a file which contains names of other files transferred. To do this first send the file with these filenames and then use the file (by preceding its name on the command line with an @ symbol) to send the other files. For example, if the file FOO contained the names of three other files: FOO1 FOO2 and FOO3 (one filename per line, can include path information) then typing on the sending computer. SEND FOO @FOO And on the receiving computer: RECV FOO @FOO Would first transfer the file FOO and then transfer FOO1 FOO2 and FOO3 at 19200 baud over COM1 (baud, port can be changed as described below). Other command line options allow specifying baud rate, port, and number of stop bits. Data bits are always 8 and parity is none. This allows transferring binary (executable) files as well as text files. If no command line parameters are specified (or are specified incorrectly) the following is displayed: The same message is used for RECV (except of course recv instead of send). The default values are shown bracketed (i.e. COM1, 19200 baud, 1 stop bit). All parameters are optional except at least one filename or FILELIST must be specified. 7.3 MODEM: complete commo program The MODEM utility is a simple terminal program which can be used to access remote databases, etc. It has built in file transfer capabilities (like SEND and RECV) for exchanging files using XMODEM protocol. It also has a non-error correcting protocol which just sends files using the XOFF/XON protocol. It can also CAPTURE data (like DATAMON) and save the data at any time. Upon startup the following screen is displayed: Like TEST.C, characters typed at the keyboard are sent out of the communications port and characters received through the communications port are displayed on the screen. Chapter 8 - RS-232 Basics A Practical Guide to RS-232 Interfacing Thanks to: Lawrence E. Hughes The following information is intended to collect together in one place, and explain in relatively simple terms, enough of the details of the RS-232 standard to allow a technician to construct and/or debug interfaces between any two "RS-232 Compatible" devices. A more detailed coverage of the subject may be found in the book "Technical Aspects of Data Communication" by John E. McNamara (1977, Digital Press). This guide is necessary due to the casual way that vendors implement " RS-232" interfaces, sometimes omitting required signals, requiring optional ones, or worse, implementing signals incorrectly. Due to this, and a lack of readily available information about the real EIA standard, there is often considerable confusion involved in trying to interface two RS-232 devices. 8.1 BACKGROUND RS-232-C is the most recent version of the EIA (Electronics Industry Association) standard for low speed serial data communication. It defines a number of parameters concerning voltage levels, loading characteristics and timing relationships. The actual connectors which are almost universally used (DB-25P and DB-25S, sometimes called "EIA connectors") are recommended, but not mandatory. Typical practice requires mounting the female (DB-25S) connector on the chassis of communication equipment, and male (DB-25P) connectors on the cable connecting two such devices. There are two main classes of RS-232 devices, namely DTE (Data Terminal Equipment), such as terminals, and DCE (Data Communication Equipment), such as modems. Typically, one only interfaces a DTE to a DCE, as opposed to one DTE to another DTE, or one DCE to another DCE, although there are ways to do the later two by building non-standard cables. Rarely if ever are more than two devices involved in a given interface (multidrop is not supported). A serial port on a computer may be implemented as either DTE or DCE, depending on what type of device it is intended to support. RS-232 is intended for relatively short (50 feet or less), relatively low speed (19,200 bits per second or less) serial (as opposed to parallel) communications. Both asynchronous and synchronous serial encoding are supported. As "digital" signals (switched D.C. voltage, such as square waves) are used, as opposed to "analog" signals (continuously varying voltage, such as sine waves) a very wide bandwidth channel (such as direct wire) is required. A limited bandwidth channel (such as a phone circuit) would cause severe and unacceptable distortion and consequent loss of information. RS-232 will support simplex, half-duplex, or full-duplex type channels. In a simplex channel, data will only ever be travelling in one direction, e.g. from DCE to DTE. An example might be a "Receive Only" printer. In a half-duplex channel, data may travel in either direction, but at any given time data will only be travelling in one direction, and the line must be "turned around" before data can travel in the other direction. An example might be a Bell 201 style modem. In a full-duplex channel, data may travel in both directions simultaneously. An example might be a Bell 103 style modem. Certain of the RS-232 "handshaking" lines are used to resolve problems associated with these modes, such as which direction data may travel at any given instant. If one of the devices involved in an RS-232 interface is a real modem (especially a half-duplex modem), the "handshaking" lines must be supported, and the timing relationships between them are quite important. These lines are typically much easier to deal with if no modems are involved. In certain cases, these lines may be used to allow one device (which is receiving data at a higher rate than it is capable of processing indefinitely) to cause the other device to pause while the first one "catches up". This use of the handshaking lines was not really intended by the designers of the RS-232 standard, but it is a useful by-product of the way such interfaces are typically implemented. Much of the RS-232 standard is concerned with support of "modems". These are devices which can convert a serial digital data signal into an analog signal compatible with a narrow bandwidth (e.g. 3 kHz) channel such as a switched telephone circuit, and back into serial digital data on the other end. The first process is called "modulation", and the second process is called "demodulation", hence the term "MODEM". The actual process used (at data rates of up to 1200 bits per second) is FSK (Frequency Shift Keying), in which a constant frequency sine wave (called the "carrier") is shifted to a slightly higher or slightly lower frequency to represent a logic 0 or logic 1, respectively. In a half duplex modem, the entire available bandwidth is used for one direction. In a full duplex modem, the available bandwidth is divided into two sub-bands, hence there is both an "originate carrier" (e.g. for data from the terminal to the computer), and an "answer carrier" (e.g. for data from the computer to the terminal). The actual frequencies (in Hertz) used on the Bell 103A full duplex modem are: Bell 103A Modem Frequencies Signal State Originate Answer logic 0 SPACE 1180 1850 carrier 1080 1750 logic 1 MARK 980 1650 8.2 THE STANDARD CIRCUITS AND THEIR DEFINITIONS For the purposes of the RS-232 standard, a "circuit" is defined to be a continuous wire from one device to the other. There are 25 circuits in the full specification, less than half of which are at all likely to be found in a given interface. In the simplest case, a full-duplex interface may be implemented with as few as 3 circuits. There is a certain amount of confusion associated with the names of these circuits, partly because there are three different naming conventions (common name, EIA circuit name, and CCITT circuit name). The table below lists all three names, along with the circuit number (which is also the connector pin with which that circuit is normally associated on both ends). Note that the signal names are from the viewpoint of the DTE (e.g. Transmit Data is data being sent by the DTE, but received by the DCE). RS-232 Pinouts and Signal Descriptions PIN NAME EIA CCITT DTE DCE Description 1 CG AA 101 --- Chassis Ground 2 TD BA 103 --> Transmit Data 3 RD. BB 104 <-- Receive Data 4 RTS CA 105 --> Request To Send 5 CTS CB 106 <-- Clear To Send 6 DSR CC 107 <-- Data Set Ready 7 SG AB 102 --- Signal Ground 8 DCD CF 109 <-- Data Carrier Detect 9* <-- Pos. Test Voltage 10* <-- Neg. Test Voltage 11 (usually not used) 12+ SCDC SCF 122 <-- Sec. Data Car. Detect 13+ SCTS SCB 121 <-- Sec. Clear To Send 14+ STD SBA 118 --> Sec. Transmit Data 15# TC DB 114 <-- Transmit Clock 16+ SRD SBB 119 <-- Sec. Receive Data 17# RC DD 115 <- Receive Clock 18 (not usually used) 19+ SRTS SCA 120 --> Sec. Request To Send 20 DTR CD 1082 --> Data Terminal Ready 21* SQ CG 110 <-- Signal Quality 22 RI CE 125 <-- Ring Indicator 23* CH 111 --> Data Rate Selector CI 112 <-- Data Rate Selector 24* XTC DA 113 --> Ext. Transmit Clock 25* --> Busy In the above, the character following the pin number means: * rarely used + used only if secondary channel implemented # used only on synchronous interfaces also, the direction of the arrow indicates which end ( DTE or DCE) originates each signal, except for the ground lines (---). For example, circuit 2 (TD) is originated by the DTE, and received by the DCE. Certain of the above circuits (11, 14, 16, and 18) are used only by (or in a different way by) Bell 208A modems. A secondary channel is sometimes used to provide a very slow (5 to 10 bits per second) path for return information (such as ACK or NAK characters) on a primarily half duplex channel. If the modem used supports this feature, it is possible for the receiver to accept or reject a message without having to "turn the line around", a process that usually takes 100 to 200 milliseconds. On the above circuits, all voltages are with respect to the Signal Ground (SG) line. The following conventions are used: RS-232 Logic Voltage Levels Voltage Signal Logic Control +3 to +25 SPACE 0 On -3 to -25 MARK 1 Off Note that the voltage values are inverted from the logic values (e.g. the more positive logic value corresponds to the more negative voltage). Note also that a logic 0 corresponds to the signal name being "true" (e.g. if the DTR line is at logic 0, that is, in the +3 to +25 voltage range, then the Data Terminal IS Ready). 8.3 ELECTRICAL CHARACTERISTICS OF EACH CIRCUIT The following criteria apply to the electrical characteristics of each of the above lines: 1) The magnitude of an open circuit voltage shall not exceed 25V. 2) The driver shall be able to sustain a short to any other wire in the cable without damage to itself or to the other equipment, and the short circuit current shall not exceed 0.5 ampere. 3) Signals shall be considered in the MARK (logic 1) state when the voltage is more negative than -3V with respect to the Signal Ground. Signals shall be considered in the SPACE (logic 0) state when the voltage is more positive that 3V with respect to the Signal Ground. The range between -3V and 3V is defined as the transition region, within which the signal state is not defined. 4) The load impedance shall have a DC resistance of less than 7000 ohms when measured with an applied voltage of from 3V to 25V but more than 3000 ohms when measured with a voltage of less than 25V. 5) When the terminator load resistance meets the requirements of Rule 4 above, and the terminator open circuit voltage is 0V, the magnitude of the potential of that circuit with respect to Signal Ground will be in the 5V to 15V range. 6) The driver shall assert a voltage between -5V and -15V relative to the signal ground to represent a MARK signal condition. The driver shall assert a voltage between 5V and 15V relative to the Signal Ground to represent a SPACE signal condition. Note that this rule in conjunction with Rule 3 above allows for 2V of noise margin. Note also that in practice, -12V and 12V are typically used. 7) The driver shall change the output voltage at a rate not exceeding 30 volts per microsecond, but the time required for the signal to pass through the -3V to +3V transition region shall not exceed 1 millisecond, or 4 percent of a bit time, whichever is smaller. 8) The shunt capacitance of the terminator shall not exceed 2500 picofarads, including the capacitance of the cable. Note that when using standard cable with 40 to 50 picofarads per foot capacitance, this limits the cable length to no more than 50 feet. Lower capacitance cable allows longer runs. 9) The impedance of the driver circuit under power-off conditions shall be greater than 300 ohms. Note that two widely available integrated circuit chips (1488 and 1489) implement TTL to RS-232 drivers (4 per chip), and RS-232 receivers to TTL (also 4 per chip), in a manner consistent with all of the above rules. 8.4 DEFINITION OF THE MOST COMMON CIRCUITS 1 CG Chassis Ground This circuit (also called Frame Ground) is a mechanism to insure that the chassis of the two devices are at the same potential, to prevent electrical shock to the operator. Note that this circuit is not used as the reference for any of the other voltages. This circuit is optional. If it is used, care should be taken to not set up ground loops. 2 TD Transmit Data This circuit is the path whereby serial data is sent from the DTE to the DCE. This circuit must be present if data is to travel in that direction at any time. 3 RD. Receive Data This circuit is the path whereby serial data is sent from the DCE to the DTE. This circuit must be present if data is to travel in that direction at any time. 4 RTS Request To Send This circuit is the signal that indicates that the DTE wishes to send data to the DCE (note that no such line is available for the opposite direction, hence the DTE must always be ready to accept data). In normal operation, the RTS line will be OFF (logic 1 / MARK). Once the DTE has data to send, and has determined that the channel is not busy, it will set RTS to ON (logic 0 / SPACE), and await an ON condition on CTS from the DCE, at which time it may then begin sending. Once the DTE is through sending, it will reset RTS to OFF (logic 1 / MARK). On a full-duplex or simplex channel, this signal may be set to ON once at initialization and left in that state. Note that some DCEs must have an incoming RTS in order to transmit (although this is not strictly according to the standard). In this case, this signal must either be brought across from the DTE, or provided by a wraparound (e.g. from DSR) locally at the DCE end of the cable. 5 CTS Clear To Send This circuit is the signal that indicates that the DCE is ready to accept data from the DTE. In normal operation, the CTS line will be in the OFF state. When the DTE asserts RTS, the DCE will do whatever is necessary to allow data to be sent (e.g. a modem would raise carrier, and wait until it stabilized). At this time, the DCE would set CTS to the ON state, which would then allow the DTE to send data. When the RTS from the DTE returns to the OFF state, the DCE releases the channel (e.g. a modem would drop carrier), and then set CTS back to the OFF state. Note that a typical DTE must have an incoming CTS before it can transmit. This signal must either be brought over from the DCE, or provided by a wraparound (e.g. from DTR) locally at the DTE end of the cable. 6 DSR Data Set Ready This circuit is the signal that informs the DTE that the DCE is alive and well. It is normally set to the ON state by the DCE upon power-up and left there. Note that a typical DTE must have an incoming DSR in order to function normally. This line must either be brought over from the DCE, or provided by a wraparound (e.g. from DTR) locally at the DTE end of the cable. On the DCE end of the interface, this signal is almost always present, and may be wrapped back around (to DTR and/or RTS) to satisfy required signals whose normal function is not required. 7 SG Signal Ground This circuit is the ground to which all other voltages are relative. It must be present in any RS-232 interface. 8 DCD Data Carrier Detect This circuit is the signal whereby the DCE informs the DTE that it has an incoming carrier. It may be used by the DTE to determine if the channel is idle, so that the DTE can request it with RTS. Note that some DTEs must have an incoming DCD before they will operate. In this case, this signal must either be brought over from the DCE, or provided locally by a wraparound (e.g. from DTR) locally at the DTE end of the cable. 15 TC Transmit Clock This circuit provides the clock for the transmitter section of a synchronous DTE. It may or may not be running at the same rate as the receiver clock. This circuit must be present on synchronous interfaces. 17 RC Receiver Clock This circuit provides the clock for the receiver section of a synchronous DTE. It may of may not be running at the same rate as the transmitter clock. Note that both TC and RC are sourced by the DCE. This circuit must be present on synchronous interfaces. 20 DTR Data Terminal Ready This circuit provides the signal that informs the DCE that the DTE is alive and well. It is normally set to the ON state by the DTE at power-up and left there. Note that a typical DCE must have an incoming DTR before it will function normally. This signal must either be brought over from the DTE, or provided by a wraparound (e.g. from DSR) locally at the DCE end of the cable. On the DTE side of the interface, this signal is almost always present, and may be wrapped back around to other circuits (e.g. DSR, CTS and/or DCD) to satisfy required handshaking signals if their normal function is not required. Note that in an asynchronous channel, both ends provide their own internal timing, which (as long as they are within 5% of each other) is sufficient for them to agree when the bits occur within a single character. In this case, no timing information need be sent over the interface between the two devices. In a synchronous channel, however, both ends must agree when the bits occur over possibly thousands of characters. In this case, both devices must use the same clocks. Note that the transmitter and receiver may be running at different rates. Note also that BOTH clocks are provided by the DCE. When one has a synchronous terminal tied into a synchronous port on a computer via two synchronous modems, for example, and the terminal is transmitting, the terminal's modem supplies the Transmit Clock, which is brought directly out to the terminal at its end, and encodes the clock with the data, sends it to the computer's modem, which recovers the clock and brings it out as the Receive Clock to the computer. When the computer is transmitting, the same thing happens in the other direction. Hence, whichever modem is transmitting must supply the clock for that direction, but on each end, the DCE device supplies both clocks to the DTE device. All of the above applies to interfacing a DTE device to a DCE device. In order to interface two DTE devices, it is usually sufficient to provide a "flipped" cable, in which the pairs (TD, RD.), (RTS, CTS) and (DTR, DSR) have been flipped. Hence, the TD of one DTE is connected to the RD. of the other DTE, and vice versa. It may be necessary to wrap various of the handshaking lines back around from the DTR on each end in order to have both ends work. In a similar manner, two DCE devices can be interfaced to each other. An RS-232 "breakout box" is particularly useful in solving interfacing problems. This is a device which is inserted between the DTE and DCE. Firstly, it allows you to monitor the state of the various handshaking lines (light on = signal ON / logic 0), and watch the serial data flicker on TD and/or RD. Secondly, it allows you to break the connection on one or more of the lines (with dip-switches), and make any kind of cross-connections and/or wraparounds (with jumper wires). Using this, it is fairly easy to determine which lines are not functioning as required, and quickly build a prototype of a cable that will serve to interface the two devices. At this point, the breakout box can be removed and a real cable built that performs the same function. An example of this kind of device is the Datatran Datatracker available from Nordtech Research, Inc. With many breakout boxes, care has to be taken to connect the correct end of it to the DTE device, or the lights and switches do not correspond to the actual signals. But with this device the voltages of the two inputs are separated so, for example, if two DTE devices are hooked up to it the DTR light on both sides would show a Red light. Chapter 9 - Products/Services from Nordtech Research 9.1 Communications Hardware Nordtech Research, Inc. is a distributor of many communications hardware products. One of the most useful tools available when developing communications software is an RS-232 breakout box. This device allows monitoring of data and control (handshake) lines at the physical level, provides a means of rewiring from one line on one side to another on the other side. By connecting this device in line with a serial cable, it becomes a science rather then an art to establish communications between two devices. When connecting two computers together, the first question to ask is whether they are both DTE devices or if one has a DCE wired port (many serial boards for the IBM-PC for example allow setting up as either). This can be easily determined by connecting a breakout box to one of the devices (after the software is running) and observing which data line is being "marked" (i.e. negative voltage). If the transmit line (line 2) is being marked it is configured as a DTE; receive line (line 3) would indicate that the device is configured as DCE. If both devices are DTE (or both DCE) then a "null modem" cable will be needed. Unfortunately many different options need to be resolved. If you are developing the software for both devices, you will have control over the hardware and softwarehandshaking. Many times, however, you only have control over one end and won't have good specifications for the other end. A breakout box can determine what, if any, handshake is needed by the other end very quickly. Often you can wire a cable that feeds the DTR signal provided by the other computer back to his DSR and CTS lines, but this disallows you from stopping his transmission at the hardware level. This may be desirable, however, if you are using a software protocol (i.e. XOFF/XON, etc.). Please call for our latest pricing and availability on these and other useful testing devices, cabling, modems, etc. You can count on getting a better price from us than the list price usually charged by communications specialists. Nordtech Research, Inc. Current Pricing Manufacturer Model List Price Our Price Datatran Mini-Tracker $29.95 $24.95 Mini-Tracker Plus $49.95 $42.95 Datatracker $239.95 $195.95 Micropatch $29.95 $24.95 Gender Menders $19.95 $14.95 Universal Cable (4") $39.95 $34.95 Universal Cable (8") $44.95 $39.95 Standard Cable (4") $24.95 $19.95 Standard Cable (8") $29.95 $24.95 Digiboard Com 4 $479.00 $399.00 Com 8 $749.00 $625.00 Com 4i $985.00 $825.00 Com 8i $1195.00 $995.00 The mini-tracker and mini-Tracker Plus are simple LED devices which show the state of the various signals. The Mini-Tracker shows the 9 most used signals and the Plus version shows all 24 (line 1 not monitored). The Mini-Tracker uses Tri-State LEDs which glow red for negative voltage and green for positive. The Plus has separate LED's for positive and negative voltages which can be very helpful in identifying data on a line, especially at higher baud rates. The Datatracker is one of the most powerful Breakout Boxes on the market today for analyzing RS-232 communications problems. It not only has 2 LEDs for each line, but it separates the DTE side from the DCE side so if both devices are actually DTE, both DTR lights would be illuminated. The device also allows breaking each signal and patching it to another line. For example when you have determined that both pieces of hardware are DTE you could patch the DTR on one side (line 20) to DSR on the other side (line 6), and vice-versa. 2 would go to 3 (xmit to recv), 4 to 5 (CTS to RTS). This would give complete handshake between the two devices. All other lines would be left connected straight across (i.e. 1 and 7). The Datatracker also has provisions to automatically switch lines 2 and 3 (a common need). It also has optional add on devices to test an installed cable (i.e. one that has been run through the ceiling down the hall 100 feet (beyond the recommended limit for RS-232!). By attaching the Datatracker to one end of the cable and the optional cable tester to the other end, the Datatracker will show which lines are connected and how. Call for pricing on the cable tester. 9.2 Consulting Services Nordtech Research specializes in communications software development. Our services can be obtained for large and small software development projects and for phone questions. Phone questions can be billed to your Visa/MasterCard at the rate of $20 per 15 minutes (as of June 1988). Longer term projects can be done on a fixed price basis if suitable specifications for the project are available, or on an hourly rate of $60/hour (as of June 1988). Chapter 10 - Version History Version 3.0 This version adds support for the 16550 UART. This UART has built in FIFO buffers which greatly improve high speed communications reliability. Even though the chip is advertised to be completely compatbile with previous the 16450 UART and earlier chips, it would not work with previous versions of the toolbox. The Async_Open function now checks to see if this UART is present and sets it up to use the FIFO it is there. Other fixes have been made including a problem with some copies of Version 2.9 Borland Large Memory model library. There were no code fixes, just some corrupt files. Version 2.9: This version further improves upon the send interrupt handling, especially for the 8250 and 82C50 chips. Some 82C50 chips don't seem to ever generate an interrupt when the transmit buffer is empty. To handle this case call Async_Open with the transmit buffer size parameter set to 0 and all data is then sent without using interrupts. The data is also not buffered. See Async_putc. The sendfile function in filexfer (XMODEM Send) has been fixed to work when sending to PROCOMM. It takes a few seconds before data flow begins. PROCOMM first trys to use the CRC protocol then trys the CHECKSUM protocol which these tools use. The function SendLine is added to the Async_String module. The function SendBlock and GetBlock are added to the Digiboard versions. The function WaitFor is added to the filexfer module. All BorlandC libraries were compiled with BorlandC++ V2.0. No C++ capabilities are used. All Microsoft libraries were compiled with MSC 6.0. Version 2.8: This version further improves upon the interrupt handling, especially when 2 ports are being used simultaneously. The previous versions had a common stack area for all ports and this version creates a separate stack area for each port. It also allows higher priority interrupts to have priority over the commo port interrupts. Several new functions have been added (window attributes, a routine to check percentage use of the send buffer, etc.). All BorlandC libraries were recompiled with BorlandC C++ version 1.0. The Digiboard version has been overhauled and uses the latest board drivers from Digiboard Corporation. The previous version didn't handle hardware handshaking properly. See DATAMON.C : Open_Commo_Ports() for an example of setting up incoming hardware flow control (i.e. handshaking). Many batch and make files were modified to accommodate our new computer systems modified environment (i.e. directory structure). These include: TMF.BAT, MMF.BAT, ZMF.BAT, BORLANDC.BAT, MSC.BAT, ZOR.BAT and almost all make files (*.m). Version 2.7: This version fixed a bug in the interrupt handling which could cause the system to hang when characters are being sent and recieved simultaneously. It also added processing of receive errors and BREAK detection via interrupt handlers. It also fixes a potential problem for users who use the DI and SI registers (used with optimization turned on in 'C'). They were not being saved in the interrupt routine previously. Several routines were added to the windowing package for controlling character attributes. It also includes faster code for users of Digiboard products. FAR pointers are used instead of assembly routines to access data in the Digiboard memory. Version 2.6: This version fixed several bugs in the large code models. It also has several fixes to the filexfer.c module. Several improvements to the quality of the manual. Version 2.5: Fixed bugs in modem.c, added print capability for modem.c (ALT-P). Fixed various other minor bugs. Version 2.4: Added interrupt driven, buffered SEND modules. Requires changes to previously developed code (add size of send buffer in Async_Open). Fixed Microsoft C bug which caused stack overflow message (fix is in make file).