Classic Computer Magazine Archive COMPUTE! ISSUE 30 / NOVEMBER 1982 / PAGE 154

From VIC-20 To Mainframe

Ulrich Merten
Pittsburgh

Does your VIC need to communicate with a megamemory mainframe? Or use a modem for other specialized data transfers? This flexible program can handle a variety of communications needs for the VIC.

We recently wanted to use our VIC-20 to communicate with a mainframe computer running under IBM's VM/CMS interactive system. We wanted to access our files on the mainframe, to write into those files using the system editor, and to list BASIC programs developed on the VIC-20 to the larger system. The system has a 300 baud ASCII port which is accessible by telephone.

For this purpose we used a Bizcomp Versamodem and rewrote the software to fit our situation. In the process, we had to learn to convert a BASIC program listing into a cassette data file on the VIC-20. The methods we used should be of interest to other VIC-20 users with similar communications challenges.

The terminal program we wrote begins by opening a file directed to the VIC-20's RS-232 interface, specifying a "file name" which selects a communications speed of 300 baud. The program has two major segments which work alternately, one looking for input from the VIC keyboard, using the "GETB$" command at line 160, and the other looking for input from the mainframe, using the "GET#10, C$" command at line 560. The bulk of the program is concerned with converting the VIC characters to ASCII, and also with translating the ASCII code arriving from the mainframe into the corresponding VIC characters on the screen.

Because we were interested in working with text in the system editor, we set the VIC keyboard in the mode in which it types upper- and lowercase letters to the screen. At lines 305 and 330, the VIC codes for the lower- and uppercase alphabetic characters, respectively, are incremented to give the appropriate ASCII codes for the same letters. The remaining lines from 300 through 335 take care of a variety of problems, two of which deserve mention here.

Line 300 calls a subroutine which sends a quotation mark ahead of the ASCII code for "#", because we found that without this provision, the # symbol was not transmitted. This was the only case we encountered where the quotation mark was necessary, but there may be others. Line 301 sets the F1 key on the VIC for a purpose we'll discuss below. Obviously, additional lines could be written into the program at this point to accommodate other function keys. Line 400 causes our input to be printed on the screen so that we can see what we're doing, and line 500 sends it on to the RS-232 interface and the mainframe.

The codes coming back from the host are pure ASCII and have to be converted to what the VIC uses in this screen mode, and that's what lines 530-610 are all about. Lines 555 and 600 take care of upper- and lowercase alphabetic characters, respectively, and line 540 translates the signal sent out by the mainframe at the end of each line. The rest of the lines in the range 530-610 are for housekeeping.

The program increments most of the ASCII codes which do not represent alphanumeric characters by 160, causing them to print out as VIC graphic characters. This has the advantage that if and when the mainframe sends back one of these characters, you see it on the screen and can identify it. The feature can be eliminated as an unnecessary nuisance once you know what is being sent your way!

Buffer Relief

When we tried to "LIST" to the RS-232 interface using an early version of this program, we found that the buffer quickly overloaded and that our transfer attempts were unsuccessful. So we converted the program we wanted to list into a data file on our cassette, using the command series:

CLOSE1:OPEN1,1,1:CMD1:LIST

This proved a successful stratagem, except that when we used the "GET" command to read this file, we didn't get the last few program lines. We solved this problem by adding a few lines of "pound signs," CHR$(92), at the end of the program and sacrificing those.

Lines 190-225 of the terminal program exist to take care of these program listings. If the F1 key is depressed, the variable "z" is set equal to one, and the next time the program passes through line 150 it opens the cassette file at line 190, and starts reading the contents. Lines 215 and 220 tell the program what to do with some special VIC characters we had in the programs, which ASCII can't handle, and line 230 makes the program print out in uppercase at the mainframe. Line 210 watches out for those "pound signs" we added at the end of the listed program, and halts the proceedings when it sees the first one.

Our first attempts to run this version of the program were unsuccessful, because data kept going out at the end of each line, before the mainframe was ready for them. That's why we added the "IF" statement to line 510. The mainframe sends out a period when it's ready for a new line, and now the VIC waits for that period to come back before proceeding, after each time it sends out a carriage return.

We've found it possible to work effectively between the VIC-20 and the mainframe using this program, and are very pleased with the ease with which we can modify the "IF" statements to meet various demands such as printing substitute characters for those not available in ASCII.

100 OPEN 10, 2, 3, CHR$ (38) + CHR$ (160)
150 IF Z = 1 THEN 190
155 IF Z = 2 THEN 200
160 GETB$
165 IFB$ = ‘ ’ THEN 510
170 X = ASC (B$)
180 GOTO 300
190 CLOSE 1 : OPEN 1, 1, 0 : Z = 2 : GET # 1, B$ : GET # 1, B$
200 GET #1, B$
205 X = ASC (B$)
210 IF X = 92 THEN Z = 0 : CLOSE 1 : GOTO 510
215 IF X = 180 RX = 146 THEN 510
220 IF X = 147 THEN X = 99 : GOTO 400
225 IF X = 34 THEN X = 39 : GOTO 400
230 IF X > 64 AND X < 91 THEN 400
300 IF X = 35 THEN GOSUB 645 : GOTO 400
305 IF X > 64 AND X < 91 THEN X = X + 32 : GOTO 400
310 IF X > 127 AND X < 133 THEN X = 32 : GOTO 400
315 IF X = 133 THEN Z = 1 : GOTO 150
325 IF X > 133 AND X < 192 THEN X = 32 : GOTO 400
330 IF X > 192 AND X < 224 THEN X = X - 128 : GOTO 400
335 IF X > 224 THEN X = 32 : GOTO 400
400 PRINT B$;
500 PRINT # 10, CHR$ (X);
510 GET # 10, C$ : IF X = 13 AND Z > < 0 AND C$ > < ‘.’ THEN 510
520 IF C$ = ‘’ THEN 620
525 Y = ASC (C$)
530 IF Y = 13 THEN 620
540 IF Y < 32 THEN Y = Y + 160 : GOTO 615
555 IF Y > 64 AND Y < 91 THEN Y = Y + 128 : GOTO 615
560 IF Y = 96 THEN Y = 32 : GOTO 615
600 IF Y > 96 F AND Y < 123 THEN Y = Y - 32 : GOTO 615
605 IF Y > 122 AND Y < 127 THEN Y = Y - 64 : GOTO 615
610 IF Y = 127 THEN 630
615 C$ = CHR$ (Y)
620 PRINT C$;
630 IF ST = 0 THEN 150
640 PRINT ‘ERROR’
645 PRINT # 10, CHR$ (34);
646 RETURN
650 END