Classic Computer Magazine Archive COMPUTE! ISSUE 41 / OCTOBER 1983 / PAGE 218

MACHINE LANGUAGE

Jim Butterfield, Associate Editor

Bagel Break, Part 3

We've looked at some of the planning that goes into organizing a machine language game of "Bagels." Let's put the final touches together, and discuss some less obvious aspects of the way the program fits with BASIC.

We chose to start the machine language at $033C, decimal 828. The main reason for this was to make it universal—the same space is available in PET, CBM, VIC and Commodore 64 computers. It is the memory address of the cassette tape buffer (on PET/CBM, the buffer for cassette 2).

But that space is not always free and clear. If we wished to save the program to cassette tape, we might need this buffer space. The SAVE command would begin by staging the program "header" block in this area; the program would be destroyed before it was written. If we should try any BASIC 4.0 disk commands, this area would also be invaded; a simple CATALOG command would wreck our program.

For safety's sake, we should pop our machine language program into place just before we use it. What better way than to build the program as a series of BASIC DATA statements, and POKE it into its working area?

That's exactly what we do in the program here. If we examine the numbers in the DATA statements, we'll be able to spot our original program. The first two numbers, for example, are 169 and 0. These decimal numbers would translate to $A900, and that's our first instruction, LDA #$00, or, "Load the A register with the actual value of hex 00." We could trace through all of the instructions of the original program in this fashion.

It Is BASIC

How did we get the DATA statement values in lines 100-180? We could do it by painstaking hand translation, but there are easier ways. After all, we have a computer to do the routine calculations for us. One way would be to put the hex program in place, and then write a loop using PEEK to print out the decimal values. For example,

FOR J = 828 TO 848 : PRINT PEEK(J) ; : NEXT J

would yield a series of decimal values. Using screen editing, we could insert the commas and prefix the values with a line number and the word DATA.

Thus, we have a program that's totally BASIC. When it runs, we manufacture a machine language program and then call it. But the program handles like BASIC, lists like BASIC, and may be loaded and saved like BASIC–because it is BASIC.

A few comments on the BASIC program itself. Line 290 causes the random number generator to be scrambled, or "randomized." When we use the value zero as an argument, i.e., RND(0), the random number seed is scrambled against the clock time so that all following numbers, called with RND(l), will be unpredictable.

Lines 300 to 320 generate four random numbers, each from 65 (the ASCII letter A) to 70 (letter F) inclusive. These values are POKEd into memory for the machine language program to use.

After the call to machine language, PEEK(577) will tell us whether or not the player got the solution. Location 577 ($0241), tells us about the "exact matches": four is a correct solution, of course. If the count is less than four, we must tell the player what the solution was by PEEKing the characters back out from addresses 580 to 583–that's where we put them.

We have looked at a simple game which uses BASIC and machine language working together. The emphasis this time was on working the problem through and commenting on the various tools that a programmer might bring to the task.

The program could well have been written entirely in BASIC. After all, Bagels doesn't need super-speed to run. But you may notice that for this sort of job, machine language brings a clean elegance to the program. The programmer often feels that machine language gives a more total control over the programming.

Bagels

90 REM BAGELS ML
100 DATA 169, 0, 141, 64, 2, 238, 64, 2, 173, 64, 2, 201, 10, 240, 5,
        32, 81, 3, 208, 241, 96
110 DATA 9, 48, 32, 210, 255, 169, 32, 32, 210, 25, 5, 162, 0, 142, 65,
        2, 142, 66, 2, 142, 67, 2
120 DATA 32, 228, 255, 201, 65, 144, 249, 201, 71, 176, 245, 32, 210, 255, 174, 67, 2
130 DATA 238, 67, 2, 157, 76, 2, 189, 68, 2, 157, 7, 2, 2, 224, 3, 208, 223, 189, 72, 2
140 DATA 221, 76.2, 208, 11, 238, 65, 2, 169, 0, 1, 57, 72, 2, 157,
        76, 2, 202, 16, 234, 160, 0
150 DATA 162, 0, 185, 72, 2, 240, 16, 221, 76, 2, 2, 08, 11, 238, 66,
        2, 169, 0, 153, 72, 2
160 DATA 157, 76, 2, 232, 224, 4, 144, 230, 200, 192, 4, 144, 223, 162, 0, 169, 32
170 DATA 32, 210, 255, 189, 65, 2, 9, 48, 32, 210, 255, 232, 224, 2, 144, 238
180 DATA 169, 13, 32, 210, 255, 173, 65, 2, 201, 4, 96
200 FOR J = 828 TO 990
210 READ X : T = T + X
220 POKE J, X
230 NEXT J : IF T <> 18169 THEN STOP
240 PRINT "BAGELS"
250 PRINT ".. GUESS MY SECRET CODE"
260 PRINT ".. I'LL TELL YOU HOW MANY"
270 PRINT ".. EXACT MATCHES AND OTHER"
280 PRINT ".. MATCHES YOU GET…"
290 X = RND(0)
300 FOR J = 0 TO 3
310 X = INT(RND(1) * 6) + 65
320 POKE 580 + J, X
330 NEXT J
340 SYS 828
350 IF PEEK(577) = 4 THEN PRINT "GOT IT!" : GOTO 400
360 PRINT "THE CODE WAS: ";
370 FOR J = 0 TO 3
380 PRINT CHR$(PEEK(580 + J));
390 NEXT J : PRINT
400 INPUT "WANT ANOTHER GAME" ; X$
410 IF X$ = "Y" OR X$ = "YES" GOTO 300