# Appendix F
Communications

This appendix describes the GW-BASIC statements necessary to support RS-232 asynchronous communications with other computers and peripheral devices.

## F.1 Opening Communications Files

The OPEN COM statement allocates a buffer for input and output in the same manner as the OPEN statement opens disk files.

## F.2 Communications I/O

Since the communications port is opened as a file, all I/O statements valid for disk files are valid for COM.

COM sequential input statements are the same as those for disk files:

    INPUT#
    LINE INPUT#
    INPUT$

COM sequential output statements are the same as those for diskette:

    PRINT#
    PRINT# USING

See the GW-BASIC User's Reference for more information on these statements.

## F.3 The COM I/O Functions

The most difficult aspect of asynchronous communications is processing characters as quickly as they are received. At rates above 2400 baud (bps), it is necessary to suspend character transmission from the host long enough for the receiver to catch up. This can be done by sending XOFF (CTRL-S) to the host to temporarily suspend transmission, and XON (CTRL-Q) to resume, if the application supports it.

GW-BASIC provides three functions which help to determine when an overrun condition is imminent:

LOC(x) | Returns the number of characters in the input queue waiting to be read. The input queue can hold more than 255 characters (determined by the /c: switch). If there are more than 255 characters in the queue, LOC(x) returns 255. Since a string is limited to 255 characters, this practical limit alleviates the need for the programmer to test for string size before reading data into it.
LOF(x) | Returns the amount of free space in the input queue; that is
    /c:(size)-number of characters in the input queue
LOF may be used to detect when the input queue is reaching storage capacity.
EOF(x) | True (-1), indicates that the input queue is empty. False (0) is returned if any characters are waiting to be read.

## F.4 Possible Errors:

A "Communications buffer overflow" error occurs if a read is attempted after the input queue is full (that is, LOC(x) returns 0).

A "Device I/O" error occurs if any of the following line conditions are detected on receive: overrun error (OE), framing error (FE), or break interrupt (BI). The error is reset by subsequent inputs, but the character causing the error is lost.

A "Device fault" error occurs if data set ready (DSR) is lost during I/O.

A "Parity error" occurs if the PE (parity enable) option was used in the OPEN COM statement and incorrect parity was received.

## F.5 The INPUT$ Function

The INPUT$ function is preferred over the INPUT and LINE INPUT statements for reading COM files, because all ASCII characters may be significant in communications. INPUT is least desirable because input stops when a comma or an enter is seen. LINE INPUT terminates when an enter is seen.

INPUT$ allows all characters read to be assigned to a string.

INPUT$ returns x characters from the y file. The following statements then are most efficient for reading a COM file:

    10 WHILE NOT EOF(1)
    20 A$=INPUT$(LOC(1),#1)
    30 ...
    40 ... Process data returned in A$ ...
    50 ...
    60 WEND

This sequence of statements translates: As long as something is in the input queue, return the number of characters in the queue and store them in A$. If there are more than 255 characters, only 255 are returned at a time to prevent string overflow. If this is the case, EOF(1) is false, and input continues until the input queue is empty.

### GET and PUT Statements for COM Files

#### Purpose:

To allow fixed-length I/O for COM.

#### Syntax:

    GET filenumber, nbytes PUT filenumber, nbytes

#### Comments:

filenumber is an integer expression returning a valid file number.

nbytes is an integer expression returning the number of bytes to be transferred into or out of the file buffer. nbytes cannot exceed the value set by the /s: switch when GW-BASIC was invoked.

Because of the low performance associated with telephone line communications, it is recommended that GET and PUT not be used in such applications.

#### Example:

The following TTY sample program is an exercise in communications I/O. It is designed to enable your computer to be used as a conventional terminal. Besides full-duplex communications with a host, the TTY program allows data to be downloaded to a file. Conversely, a file may be uploaded (transmitted) to another machine.

In addition to demonstrating the elements of asynchronous communications, this program is useful for transferring GW-BASIC programs and data to and from a computer.

Note

This program is set up to communicate with a DECŪ System-20 especially in the use of XON and XOFF. It may require modification to communicate with other types of hardware.

## F.6 The TTY Sample Program

    10 SCREEN 0,0:WIDTH 80
    15 KEY OFF:CLS:CLOSE
    20 DEFINT A-Z
    25 LOCATE 25,1
    30 PRINT STRING$(60," ")
    40 FALSE=0:TRUE=NOT FALSE
    50 MENU=5 'Value of MENU Key (^E)
    60 XOFF$=CHR$(19):XON$=CHR$(17)
    100 LOCATE 25,1:PRINT "Async TTY Program";
    110 LOCATE 1,1:LINE INPUT "Speed?";"SPEED$
    120 COMFIL$="COM1:,+SPEED$+",E,7"
    130 OPEN COMFIL$ AS #1
    140 OPEN "SCRN:"FOR OUTPUT AS #3
    200 PAUSE=FALSE
    210 A$=INKEY$:IF A$=""THEN 230
    220 IF ASC(A$)=MENU THEN 300 ELSE PRINT #1,A$;
    230 IF EOF(1) THEN 210
    240 IF LOC(1)>128 THEN PAUSE=TRUE:PRINT #1,XOFF$;
    250 A$=INPUT$(LOC(1),#1)
    260 PRINT #3,A$;:IF LOC(1)>0 THEN 240
    270 IF PAUSE THEN PAUSE=FALSE:PRINT #1,XON$;
    280 GOTO 210
    300 LOCATE 1,1:PRINT STRING$(30,32):LOCATE 1,1
    310 LINE INPUT "FILE?";DSKFIL$
    400 LOCATE 1,1:PRINT STRING$(30,32):LOCATE 1,1
    410 LINE INPUT"(T)ransmit or (R)eceive?";TXRX$
    420 IF TXRX$="T" THEN OPEN DSKFIL$ FOR INPUT AS #2:GOTO 1000
    430 OPEN DSKFIL$ FOR OUTPUT AS #2
    440 PRINT #1,CHR$(13);
    500 IF EOF(1) THEN GOSUB 600
    510 IF LOC(1)>128 THEN PAUSE=TRUE:PRINT #1,XOFF$;
    520 A$=INPUT$(LOC(1),#1)
    530 PRINT #2,A$;:IF LOC(1)>0 THEN 510
    540 IF PAUSE THEN PAUSE=FALSE:PRINT #1,XON$;
    550 GOTO 500
    600 FOR I=1 TO 5000
    610 IF NOT EOF(1) THEN I=9999
    620 NEXT I
    630 IF I>9999 THEN RETURN
    640 CLOSE #2;CLS:LOCATE 25,10:PRINT "* Download complete *";
    650 RETURN 200
    1000 WHILE NOT EOF(2)
    1010 A$=INPUT$(1,#2)
    1020 PRINT #1,A$;
    1030 WEND
    1040 PRINT #1,CHR$(28);^Z to make close file.
    1050 CLOSE #2:CLS:LOCATE 25,10:PRINT "** Upload complete **";
    1060 GOTO 200
    9999 CLOSE:KEY ON

## F.7 Notes on the TTY Sample Program

Note

Asynchronous implies character I/O as opposed to line or block I/O. Therefore, all prints (either to the COM file or screen) are terminated with a semicolon (;). This retards the return line feed normally issued at the end of the PRINT statement.

Line Number | Comments
10 | Sets the SCREEN to black and white alpha mode and sets the width to 80.
15 | Turns off the soft key display, clears the screen, and makes sure that all files are closed.
20 | Defines all numeric variables as integer, primarily for the benefit of the subroutine at 600-620. Any program looking for speed optimization should use integer counters in loops where possible.
40 | Defines Boolean true and false.
50 | Defines the ASCII (ASC) value of the MENU key.
60 | Defines the ASCII XON and XOFF characters.
100-130 | Prints program ID and asks for baud rate (speed). Opens communications to file number 1, even parity, 7 data bits.
200-280 | This section performs full-duplex I/O between the video screen and the device connected to the RS-232 connector as follows:

1. Read a character from the keyboard into A$. INKEY$ returns a null string if no character is waiting.
2. If a keyboard character is available, waiting, then:

- If the character is the MENU key, the operator is ready to down-load a file. Get filename.
- If the character (A$) is not the MENU key send it by writing to the communications file (PRINT #1...).

3. If no character is waiting, check to see if any characters are being received.
4. At 230, see if any characters are waiting in COM buffer. If not, go back and check the keyboard.
5. At 240, if more than 128 characters are waiting, set PAUSE flag to indicate that input is being suspended. Send XOFF to host, stopping further transmission.
6. At 250-260, read and display contents of COM buffer on screen until empty. Continue to monitor size of COM buffer (in 240). Suspend transmission if reception falls behind.
7. Resume host transmission by sending XON only if suspended by previous XOFF.
8. Repeat process until the MENU key is pressed.

300-320 | Get disk filename to be down-loaded to. Open the file as number 2.
400-420 | Asks if file named is to be transmitted (uploaded) or received (down-loaded).
430 | Receive routine. Sends a RETURN to the host to begin the down-load. This program assumes that the last command sent to the host was to begin such a transfer and was missing only the terminating return. If a DEC® system is the host, such a command might be
    COPY TTY:=MANUAL.MEM (MENU Key)
if the MENU key was struck instead of RETURN.
500 | When no more characters are being received, (LOC(x) returns 0), then performs a timeout routine.
510 | If more than 128 characters are waiting, signal a pause and send XOFF to the host.
520-530 | Read all characters in COM queue (LOC(x)) and write them to diskette (PRINT #2...) until reception is caught up to transmission.
540-550 | If a pause is issued, restart host by sending XON and clearing the pause flag. Continue the process until no characters are received for a predetermined time.
600-650 | Time-out subroutine. The FOR loop count was determined by experimentation. If no character is received from the host for 17-20 seconds, transmission is assumed complete. If any character is received during this time (line 610), then set n well above the FOR loop range to exit loop and return to caller. If host transmission is complete, close the disk file and resume regular activities.
1000-1060 | Transmit routine. Until end of disk file, read one character into A$ with INPUT$ statement. Send character to COM device in 1020. Send a ^Z at end of file in 1040 in case receiving device needs one to close its file. Lines 1050 and 1060 close disk file, print completion message, and go back to conversation mode in line 200.
9999 | Presently not executed. As an exercise, add some lines to the routine 400-420 to exit the program via line 9999. This line closes the COM file left open and restores the function key display.