Loading And Linking Commodore Programs
The Commodore 128
Jim Butterfield, Associate Editor
This month's installment concludes the series by discussing load/link techniques on Commodore's newest eight-bit computer, the 128. As you'll see, the 128's powerful BASIC has simple, built-in commands to perform jobs that require programming tricks on earlier Commodore computers.
There are three major ways to connect programs together. Chaining allows several programs to perform a job, each program continuing the work that a previous program has done. Load linking enables one program to call another, with the new program starting fresh on a new task. Overlaying allows a main program to call in supplementary material, such as machine language subroutines, data tables, or additional screens. All these techniques are easy on the Commodore 128 in 128 mode. For 64 mode, of course, you can use the techniques explained in previous articles in this series.
A program that is chained is broken into separate modules, and each part runs separately. The programs may proceed in a specific order; for example, an input program may be followed by a sorting program and then an output program. Or a menu program may call in other programs that you request.
The 128's DLOAD command makes disk chaining extraordinarily easy. If a program executes the statement DLOAD"THISPROG", the computer loads and runs the program named THISPROG. Variables from the earlier program are preserved, so the new program can continue where the old one left off.
The chaining pitfalls of earlier Commodore machines don't apply to the 128. Because the 128 stores the BASIC program text in a different bank of RAM from the working values (variables, strings, and arrays), there is no danger that DLOAD will interfere with variables. The new program simply replaces the old one.
By the way, the 128 has no static strings; all strings, whether static or dynamic, are safely stored in bank 1.
Let's revise the rules for well-chained programs on the 128:
- It doesn't matter whether the first program is bigger or smaller than subsequent programs.
- Strings, variables, and arrays are passed from program to program.
- If you use DEF FN definitions, redefine them in each program module.
- Arrays should be DIMensioned only once, preferably in the first program.
A Short Example
Let's write the first of a small series of Commodore 128 programs which chain together. We'll call our first program START, and it assumes that you want to record grades for eight students.
110 PRINT "SIMPLE GRADEBOOK DEMO" 120 DIM N$(15),M(15) 130 N=8 140 FOR J=1 To N 150 PRINT "STUDENT";J; 160 INPUT "NAME";N$(J) 170 INPUT "SCORE";M(J) 180 NEXT J 190 DLOAD "MENU"
When the program runs to this point, we have data on eight students. Save the program using the filename START.
Now let's enter the menu program. Type NEW and enter this:
100 PRINT 110 PRINT "DO YOU WANT TO-- 120 PRINT "1. CALCULATE AVERAGE SCORE" 130 PRINT "2. CALCULATE HIGH/LOW SCORES" 140 PRINT "3. QUIT" 150 PRINT 160 INPUT "YOUR CHOICE (1-3)";C 170 ON C GOTO 300,310,320 180 GOTO 160 300 DLOAD "C.AVG" 310 DLOAD "C.HIL" 320 END
Note that line 300 won't run into line 310, nor 310 into 320. The moment the program executes DLOAD, the new program loads and begins running. After checking this program closely, save it on disk with the filename MENU. (The name is important; don't substitute any other filename.)
Now type NEW and enter this program:
100 PRINT 110 A=0 120 FOR J=1 TO N 130 A=A+M(J) 140 NEXT J 150 PRINT "AVERAGE SCORE FOR";N;"STUDENTS =";A/N 160 PRINT 170 DLOAD "MENU"
Check this closely and save it as C.AVG. Again, the filename is important. Now type NEW and enter this program:
100 PRINT 110 H=M(1):L=M(1) 120 FOR J=1 TO N 130 IF H
M(J) THEN L=M(J) 150 NEXT J 160 PRINT "HIGH SCORE WAS";H; "BY:" 170 FOR J=1 TO N 180 IF H=M(J) THEN PRINT N$(J) 190 NEXT J 200 PRINT "LOW SCORE WAS";L; "BY:" 210 FOR J=1 TO N 220 IF L=M(J) THEN PRINT N$(J) 230 NEXT J 240 PRINT 250 DLOAD "MENU"
Again, check your typing closely and save it as C.HIL to complete the set.
Now you can experiment with chaining on the 128 by loading the first program (filename START). Note that this program is smaller than both MENU and C.HIL. On earlier Commodore computers, that would be a problem. But it doesn't matter on the 128.
Chaining links one program to the next while keeping the first program's working values intact. That's useful when you're continuing a calculation. But sometimes you'd rather throw away these values, allowing the newly loaded program to start fresh. The RUN command does exactly that. No fuss or bother--just specify the appropriate program name and you're in business, the old variables disappear, the pointers are reset, and the new program starts running.
To illustrate, let's write two very simple programs and use a menu program to select which one to use. Type NEW, then enter this simple square root program:
100 PRINT "TABLE OF SQUARE ROOTS" 110 FOR J=1 TO 20 120 PRINT J, SQR(J) 130 NEXT J
You can try running the program if you want. Save it with the filename SQUARE.
Now type NEW again and enter this simple cube root program:
100 PRINT "TABLE OF CUBE ROOTS" 110 X=1/3 120 FOR I=1 TO 20 130 PRINT I, I^X 140 NEXT I
Again, you might like to try running the program. Save it with the filename CUBE. Type NEW again and enter this simple 128 loading program:
100 DATA SQUARE,CUBE 110 READ A$(1),A$(2) 120 PRINT "WHICH ROOTS DO YOU WANT--" 130 FOR J=1 TO 2 140 PRINT J;A$(J) 150 NEXT J 160 INPUT "WHICH (1 OR 2)";N 170 IF N<1 OR N>2 GOTO 120 180 RUN (A$(N))
Note the syntax of the RUN command. If you don't specify a drive number, the computer assumes you want drive 0. If you want to run a program on a disk in drive 1, you would add ,D1 to the end of the filename. And if you want to use a variable for the filename (as shown above), it must be enclosed in parentheses.
When you run the menu program, it loads and runs SQUARE or CUBE as selected. When the new program runs, all the old variables are scrapped. The second program starts fresh.
This technique brings in extra material to accompany a BASIC program. It might be a machine language routine, a screen, sprite shapes, or data tables. Whereas chaining and load linking move from one BASIC program to another, overlaying lets the same BASIC program continue with new data in memory.
On the Commodore 128, BASIC 7.0's BLOAD command can bring in the material with no problems. It loads the file, and the BASIC program continues with the next statement. It's quite straightforward, especially compared to the gyrations required on earlier Commodore machines.
However, you must take care not to BLOAD information into the same area of memory occupied by the BASIC program itself (a crash usually results). BLOAD lets you specify a load address, but it's usually convenient to BLOAD a file into the same memory area from which it was saved.
Here's a quick example. First, let's set up a short machine language routine that prints a string of characters. Type NEW and enter this program:
100 DATA 0,26 110 DATA 162,65 120 DATA 138 130 DATA 32,210,255 140 DATA 232 150 DATA 201,90 160 DATA 144,247 170 DATA 169,13 180 DATA 76,210,255 190 A=18 200 FOR J=1 TO A 210 READ X 220 T=T+X 230 NEXT J 240 IF T<>2525 THEN STOP 250 RESTORE 260 DOPEN#8, "ML,P",W 270 FOR J=1 TO A 280 READ X 290 PRINT#8,CHR$(X); 300 NEXT J 310 CLOSE 8
Be sure that line 290 ends with a semicolon. Then run the program. If it stops at line 240, there's a typing error in one of the DATA statements. Otherwise, it creates a one-block machine language routine on disk called ML. As we'll see in a moment, this routine prints the alphabet on the screen when called into memory.
Here's our main program, which loads the ML module we just created:
100 BANK 15 110 BLOAD "ML" 120 PRINT "HERE IS THE ALPHABET---" 130 SYS 6656 140 PRINT "HERE IT IS AGAIN..." 150 SYS 6656 160 PRINT "THAT'S ALL."
BLOAD just brings the ML routine into memory and makes it available to the BASIC program. Simple and effective.
Overlays are popular with machine language programmers on the 128 partly because they are so easy to do and partly because of the mobility of BASIC programs. Depending on recent graphics activities, a BASIC program might start at address 7169 (the usual place) or at 16385 (if a graphics area has been allocated). Rather than puzzle over how to fit a machine language routine into memory with these uncertain locations, many programmers use an overlay. That way they know where the routine loads, even if they're not sure where the BASIC program might be.
Compared to the complexity of earlier Commodore computers, these techniques are a snap on the Commodore 128 in 128 mode. Just remember: DLOAD for chaining, RUN for load linking, and BLOAD for overlaying.
Copyright 1986, Jim Butterfield