ProModem RS232 Interrupt Driven Serial Communication Library v1.5 Written By Adrian J. Michaud (C) Interactive Telecommunication Systems 1992-1993 Release Date: 01/20/93 Table Of Contents ----------------- Page Introduction 1 Features/Supported Compilers 2 Registration 3 Ording Form 4 SetupControlBlock() 5 OpenCom() 6 CloseCom() 7 SendCharacter() 8 CheckQueue() 9 GetCharacter() 10 ClearQueue() 11 GetCarrierDetect() 12 SetBaudRate() 13 SetDTR() 14 DropDTR() 15 SetDataFormat() 16 SendString() 17 SetFIFOMode() 18 SetFIFOTriggerLevel() 19 WaitForCharacter() 20 DisableIRQ() 21 EnableIRQ() 22 DisableCTSRTS() 23 EnableCTSRTS() 24 GetCTSRTSStatus() 25 TERMINAL.C - Example Terminal Program source file 26 BBS.C - Example Bulletin Board source file 27 If you are having trouble using ProModem 28 Page 1 - ProModem Users Manual Interactive Telecommunication Systems Introduction ------------ ProModem is a High Performance Interrupt Driven RS232 serial communication library that can be used for creating a Computerized Bulletin Board System, a Terminal program, a RS232 Networking Driver, or for RS232 Host to Host communications. ProModem supports the following UARTS: PC16550C, NS16550AF, PC16550CF, 16450, and the 8250. ProModem takes full advantage of a 16550 by enabling the 16 character FIFO to relieve the CPU of excessive software overhead. When using a 16550, internal FIFOs are activated allowing 16 bytes (plus 3 bits of error data per byte in the RCVR FIFO) to be stored in both receive and transmit modes. All the logic is on chip to minimize system overhead and maximize system efficiency. Page 2 - ProModem Users Manual Interactive Telecommunication Systems Features -------- ProModem contains the following features: o Interrupt driven INPUT directly VIA 8259 Peripheral Interrupt Controller. o Full 16550 FIFO support with selectable trigger levels. o Supports user definable Base Addresses using IRQ3 or IRQ4. o Automatic CTS/RTS Hardware Handshaking for Asynchronous Devices. o Baud rates up to 115k bits per second. o Handles unlimited Open Com Ports using IRQ3 and IRQ4. (overruns might occur with slow CPU's or High Baud Rates of course). o Supports both ISA (PC AT) and MCA (PS 2) machines o Small, (Large, and Huge memory models available to registered users). 'C' Compilers Supported ----------------------- Microsoft C - v5.1, v6.0, QuickC v2.5, and C/C++ v7.0 Borland TurboC - v1.0, v2.0, v3.0, v3.1 Page 3 - ProModem Users Manual Interactive Telecommunication Systems Registration ------------ ProModem is not a public domain program and is not free. ProModem is Copyright (C) 1993 by Interactive Telecommunication Systems. Non-registered users of this library are granted a limited one month license to ProModem to evaluate the libraries suitability for their requirements. Any usage of ProModem beyond evaluation time period requires registration of each copy of the library used. Use of non-registered copies of ProModem beyond the original evaluation period is prohibited. The Shareware version of ProModem has been built with a small model. When you register ProModem you will receive FULL printed documentation along with a LARGE and a HUGE library for all compilers supported. Source code to all memory models for all supported compilers is also part of the registration package. There are two ways to register. The first is by sending $25 to Interactive Telecommunication Systems along with a registration form. Non U.S. residents, please send checks drawn on U.S. funds. We will accept non U.S. currency, but you must include an additional $5 (US) to cover exchange handling. Also add $5 overseas shipping/handling. See the page 4 for the ordering form and ordering information. Page 4 - ProModem Users Manual Interactive Telecommunication Systems ProModem Ordering Form ---------------------- Please Remit To: Eutecnics C/O Adrian J. Michaud - ProModem! 30 Nagog Pk., Suite 105 Acton, Ma 01720 Qty. Description Each Total ____ ProModem Registration with 3.5" diskette $25.00 ________ Includes ALL memory models with Source Code and a printed Manual. MSC & TC. ____ ProModem Registration with 5.25" diskette $25.00 ________ Includes ALL memory models with Source Code and a printed Manual. MSC & TC. (U.S. orders add $2 shipping & handling) Shipping ________ (Foreign orders add $5 shipping) (Add $5 for Foreign Currency Exchange) Misc. Charges ________ (MA residents please add 7.25% sales tax) Tax ________ TOTAL $________ Name: _________________________________________________________________ Company: _________________________________________________________________ Address: _________________________________________________________________ _________________________________________________________________ _________________________________________________________________ Where did you obtain ProModem? ( ) Friend ( ) Shareware House ( ) Other ( ) BBS ( ) User Group __________ All checks or money orders must be drawn on U.S. Funds in U.S. Dollars. Sorry, no C.O.D. orders will be accepted. Make All Checks Payable to: Interactive Telecommunication Systems Page 5 - ProModem Users Manual Interactive Telecommunication Systems Function: int SetupControlBlock(AJMS *controlBlock, unsigned int baseAddress, int irq, unsigned int bufferSize); Description: Sets up a control block for a specific com port and IRQ number. This is the first function that is always used when preparing to communicate to a COM port. Each com port that will be opened requires a different control block. Return Value: SUCCESSFUL - Setup was successful. TOO_MANY_IRQS - Too many mounted com ports. Example Usage: #include "promodem.h" main() { AJMS controlBlock; /* This sets up a control block for COM1 (0x3f8), IRQ4, and a 4096 Byte receive Buffer. */ SetupControlBlock(&controlBlock , 0x3f8 , 4 , 4096);/*Init Control Block*/ OpenCom(&controlBlock); /*Open COM port */ } Page 6 - ProModem Users Manual Interactive Telecommunication Systems Function: int OpenCom(AJMS *controlBlock); Description: Opens a COM port for communication. This function allocates an IRQ buffer and sets up the UART for communication. DTR (Data Terminal Ready) is turned ON when port is opened. CTS (Clear To Send) and RTS (Request To Send) hardware handshaking is automaticly turned ON if detected when the com port is opened. Return Value: BUFFER_ALLOCATION_ERROR - Could not allocate IRQ buffer. COM_ALREADY_OPEN - Port is already open and ready. COM_PORT_NOT_READY - Unable to Talk To Serial Device. SUCCESSFUL - COM port successfully opened. Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up. */ OpenCom(&controlBlock); /* Open COM port */ } Page 7 - ProModem Users Manual Interactive Telecommunication Systems Function: int CloseCom(AJMS *controlBlock); Description: Closes a previously opened COM port. This de-allocates the IRQ buffer that was allocated by OpenCom() and restores the UART to its previous state before it was opened. Return Value: COM_PORT_NOT_OPEN - COM port was not previously Opened. SUCCESSFUL - COM port successfully closed and IRQ buffer has been de-allocated. Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ CloseCom(&controlBlock); /*Close COM port */ } Page 8 - ProModem Users Manual Interactive Telecommunication Systems Function: int SendCharacter(AJMS *controlBlock, unsigned char ch); Description: Sends a character to the COM port. Return Value: CARRIER - If there is a carrier. NO_CARRIER - If there isn't a carrier. Also see: SendString() Example Usage: #include "promodem.h" example() { unsigned char ch; /* Allocate ch on the stack */ extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ ch = (unsigned char)getch(); /* Get a character from the keyboard */ SendCharacter(&controlBlock, ch); /* Send character to COM port */ } Page 9 - ProModem Users Manual Interactive Telecommunication Systems Function: int CheckQueue(AJMS *controlBlock); Description: Checks the status of the IRQ receive buffer. Return Value: CHARACTERS_WAITING - If there are characters in queue. QUEUE_EMPTY - If queue is empty. Also see: GetCharacter(), ClearQueue(), WaitForCharacter() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ if (CheckQueue(&controlBlock) == CHARACTERS_WAITING) /* Check Queue */ printf("%c", GetCharacter(&controlBlock)); /* Print one byte from Queue */ } Page 10 - ProModem Users Manual Interactive Telecommunication Systems Function: int GetCharacter(AJMS *controlBlock); Description: Gets a single character from Receive IRQ Queue. Return Value: First Character that was placed in the receive Queue. The receive queue expands as more characters are received. GetCharacter() takes the first character from the queue and returns it as an (int) with the high byte masked. Also see: CheckQueue() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ if (CheckQueue(&controlBlock) == CHARACTERS_WAITING) /* Check Queue */ printf("%c", GetCharacter(&controlBlock)); /* Print one byte from Queue */ } Page 11 - ProModem Users Manual Interactive Telecommunication Systems Function: void ClearQueue(AJMS *controlBlock); Description: Clears the contents of the Receive IRQ Queue. This insures that there are no pending characters in the Receive IRQ Queue. Return Value: None. Also see: CheckQueue() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ ClearQueue(&controlBlock); /* Clears the Receive IRQ Queue */ } Page 12 - ProModem Users Manual Interactive Telecommunication Systems Function: int GetCarrierDetect(AJMS *controlBlock); Description: Checks the status of the DCD (Data Carrier Detect) line on the serial port. This is used to detect if a modem has a carrier or not. Return Value: CARRIER - If there is a carrier. NO_CARRIER - If there isn't a carrier. Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ if (GetCarrierDetect(&controlBlock) == NO_CARRIER) /* Check DCD */ printf("\nThere is no Carrier\n"); /* Display Loss of Carrier. */ } Page 13 - ProModem Users Manual Interactive Telecommunication Systems Function: void SetBaudRate(AJMS *controlBlock, unsigned long baudRate); Description: Sets up the baud rate for the serial port. Return Value: None. Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ SetBaudRate(&controlBlock, (unsigned long)38400); /* set to 38.4k Baud */ } Page 14 - ProModem Users Manual Interactive Telecommunication Systems Function: void SetDTR(AJMS *controlBlock); Description: Turns ON the DTR (Data Terminal Ready) line on the serial port. OpenCom() automaticly turns on DTR when a COM port is initially opened. DTR needs to be turned on to talk to a modem. Return Value: None. Also see: DropDTR() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ SetDTR(&controlBlock); /* Turns on DTR (Data Terminal Ready) */ } Page 15 - ProModem Users Manual Interactive Telecommunication Systems Function: void DropDTR(AJMS *controlBlock); Description: Turns OFF the DTR (Data Terminal Ready) line on the serial port. CloseCom() does NOT automatically turn OFF DTR. Some modems when set up correctly will drop carrier when DTR is toggled from ON->OFF->ON. Your modem manual will explain more about this and how to set up your modem to respond to DTR. Return Value: None. Also see: SetDTR() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ DropDTR(&controlBlock); /* Turns off DTR (Data Terminal Ready) */ } Page 16 - ProModem Users Manual Interactive Telecommunication Systems Function: void SetDataFormat(AJMS *controlBlock, int options); Description: Sets the Data format for a COM port. OpenCom() automatically sets the COM port to 8 Bits, 1 stop, no parity. To override this, use this function. Return Value: None. Example Usage: /* BITS_7 - Sets COM port for 7 bits */ /* BITS_6 - Sets COM port for 6 bits */ /* BITS_7 - Sets COM port for 7 bits */ /* BITS_8 - Sets COM port for 8 bits */ /* STOP_BITS_1 - Sets COM port for 1 stop bit */ /* STOP_BITS_2 - Sets COM port for 2 stop bits */ /* PARITY_ON - Sets COM port to use parity */ /* NO_PARITY - Sets COM port not to use a parity bit */ /* EVEN_PARITY - Sets COM port to use even parity */ /* ODD_PARITY - Sets COM port to use odd parity */ /* STICK_PARITY - Sets COM port to use stick parity */ /* SET_BREAK - Sets COM port to set break */ #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ /* Sets COM port for 8-N-1, simply Bitwise OR anything you want. */ SetDataFormat(&controlBlock, BIT_8 | NO_PARITY | STOP_BITS1); } Page 17 - ProModem Users Manual Interactive Telecommunication Systems Function: int SendString(AJMS *controlBlock, char *string); Description: Sends a NULL terminated string to the COM port. Return Value: CARRIER - If there was a carrier while sending string. NO_CARRIER - If there wasn't a carrier while sending string. Also see: SendCharacter() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ SendString(&controlBlock, "\nHello World!"); /* Send string to COM port */ } Page 18 - ProModem Users Manual Interactive Telecommunication Systems Function: SetFIFOMode(AJMS *controlBlock); Description: Turns on the FIFO buffer for a COM port. This will only work with a UART 16550. Return Value: FIFO_ENABLED - The FIFO has been enabled. NO_FIFO_PRESENT - No FIFO present (16550 Uarts ONLY) Also see: SetFIFOTriggerLevel() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ /* Try to enable the FIFO */ if (SetFIFOMode(&controlBlock)==FIFO_ENABLED) printf("\nFIFO has been enabled."); else printf("\nNo FIFO Present, not a 16550."); } Page 19 - ProModem Users Manual Interactive Telecommunication Systems Function: SetFIFOTriggerLevel(AJMS *controlBlock, unsigned char mode); Description: Sets the FIFO trigger level for the RCVR FIFO Interrupt. This only works with a UART 16550. Return Value: None. Also see: SetFIFOMode() Example Usage: /* FIFO_1_TRIGGER - IRQ will trigger with 1 byte in FIFO buffer */ /* FIFO_4_TRIGGER - IRQ will trigger with 4 bytes in FIFO buffer */ /* FIFO_8_TRIGGER - IRQ will trigger with 8 bytes in FIFO buffer */ /* FIFO_16_TRIGGER - IRQ will trigger with 16 bytes in FIFO buffer */ #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ /* Sets FIFO to trigger on 16 characters in RCVR buffer */ SetFIFOTriggerLevel(&controlBlock, FIFO_16_TRIGGER); } Page 20 - ProModem Users Manual Interactive Telecommunication Systems Function: int WaitForCharacter(AJMS *controlBlock, double seconds); Description: Waits for a character to be received in the IRQ receive queue for a specified number of seconds. Return Value: (int) - Character received (high byte masked) WAIT_TIME_OUT - Time out, no character received. Also see: GetCharacter() Example Usage: #include "promodem.h" example() { unsigned char ch; extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ /* wait 3.5 seconds for a character, or timeout */ ch = WaitForCharacter(&controlBlock, 3.50); if (ch==WAIT_TIME_OUT) printf("\nTimeout, no character received.\n"); else printf("\nHere is the character '%c'\n", ch); } Page 21 - ProModem Users Manual Interactive Telecommunication Systems Function: DisableIRQ(AJMS *controlBlock); Description: Turns OFF the IRQ vector and restores it to the original vector before the com port was opened. This should ALWAYS be done if you are doing any spawning that swaps your program to Disk or EMS. Return Value: None. Also see: EnableIRQ() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ DisableIRQ(&controlBlock); /* Restores IRQ vector to original */ } Page 22 - ProModem Users Manual Interactive Telecommunication Systems Function: EnableIRQ(AJMS *controlBlock); Description: Sets up the IRQ vector to point to ProModem's serial receive IRQ internal routine. This should only be used if DisableIRQ() was previously called. OpenCom() automatically sets up the IRQ vector when the com port is originally opened. Return Value: None. Also see: DisableIRQ() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ EnableIRQ(&controlBlock); /* Sets IRQ vector to point to ProModem's IRQ */ } Page 23 - ProModem Users Manual Interactive Telecommunication Systems Function: DisableCTSRTS(AJMS *controlBlock); Description: Turns OFF CTS/RTS Hardware handshaking. Return Value: None. Also see: EnableCTSRTS() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ DisableCTSRTS(&controlBlock); /* Disables CTS/RTS Hardware Handshaking */ } Page 24 - ProModem Users Manual Interactive Telecommunication Systems Function: EnableCTSRTS(AJMS *controlBlock); Description: Turns ON CTS/RTS Hardware handshaking. Return Value: None. Also see: DisableCTSRTS() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ EnableIRQ(&controlBlock); /* Enables CTS/RTS Hardware Handshaking */ } Page 25 - ProModem Users Manual Interactive Telecommunication Systems Function: GetCTSRTSStatus(AJMS *controlBlock); Description: Gets the status of the CTS/RTS state. Return Value: ENABLED - CTS/RTS hardware handshaking is enabled. DISABLED - CTS/RTS hardware handshaking is disabled. Also see: DisableCTSRTS(), DisableCTSRTS() Example Usage: #include "promodem.h" example() { extern AJMS controlBlock; /* Assumes a control block has previously */ /* been set up and the COM port is OPEN */ if (GetCTSRTSStatus(&controlBlock) == ENABLED) /* Check CTS/RTS */ printf("\nCTS/RTS is enabled!"); else printf("\nCTS/RTS is disabled!"); } Page 26 - ProModem Users Manual Interactive Telecommunication Systems TERMINAL.C - Example terminal program using ProModem. TERMINAL.C is a demo program written using the routines in the ProModem library to demonstrate the library functions. To build the program you need to have the PROMODEM.H file that came in the archive and the PROM_TC.LIB or PROM_MSC.LIB to link with. Once you have the correct LIBs and .H files in your INCLUDE and LIB directories, compile and link: nmake PROMODEM.MAK ;Microsoft QuickC cl terminal.c /link PROM_MSC.LIB ;Microsoft C tcc terminal.c PROM_TC.LIB ;Turbo C TERMINAL.C is yours to do what you want with. NOTE: With Microsoft compilers, you must <> the DEBUG flag if it is set. Page 27 - ProModem Users Manual Interactive Telecommunication Systems BBS.C - Example Bulletin Board System using ProModem. BBS.C is a demo BBS program written using the routines in the ProModem library to demonstrate the library functions. To build the program you need to have the PROMODEM.H file that came in the archive and the PROM_TC.LIB or PROM_MSC.LIB to link with. Once you have the correct LIBs and .H files in your INCLUDE and LIB directories, compile and link: nmake BBS.MAK ;Microsoft QuickC cl bbs.c /link PROM_MSC.LIB ;Microsoft C tcc bbs.c PROM_TC.LIB ;Turbo C BBS.C is yours to do what you want with. NOTE: With Microsoft compilers, you must <> the DEBUG flag if it is set. Page 28 - ProModem Users Manual Interactive Telecommunication Systems Having Problems with ProModem? ------------------------------ The original ProModem version 1.0 lacked CTS/RTS hardware handskaking. ProModem Version 1.5 now includes support for CTS (Clear To Send) and RTS (Request To Send) hardware handshaking. Version 1.5 is the latest version of ProModem as of 01/20/93. If you are having trouble getting ProModem to work, or have any questions about ProModem, please feel free to call my BBS (written using ProModem) at 617-581-1039 (2400 - 14,400 Baud) HST/V.32bis. Leave a message stating that you are a ProModem user and would like support. You will then be granted an account. I can be reached voice at 617-595-8912 after 8:00 PM EST.