BASIC Code

TRS-80 GameOfLife.BAS

Click the emulator window to play.

Conway's Game of Life is a life simulation with four rules:

  1. Any live cell with fewer than two live neighbours dies, as if by underpopulation.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

It's a common programming project, and the version here was adapted from a code listing in the August 1980 issue of 80 Micro by Claud M. Grace and Terry L. Kepner. It'll run automatically after it starts; the initial generation is always the same but when you press 'C' to start a new one it should be different.

This is a TRS-80 Model III BASIC program presented in Peter Phillip's Javascript emulator. It uses a hybrid approach, with some machine language to make the program run much faster - without the machine language, each generation takes over two minutes instead of a fraction of a second.

The Listing

``` 10 DEFINT Z 20 CLS 30 PRINT "CONWAY'S GAME OF LIFE" 40 PRINT "BASED ON CLAUD GRACE AND TERRY KEPNER'S LISTING" 50 PRINT "REFACTORED BY MICHAEL COORLIM" 55 PRINT ```

As mentioned, this is in TRS-80's Model III BASIC which is a different beast than what we've been seeing. DEFINT defines Z as an integer, and CLS clears the screen.

60 PRINT "PRESS SPACE TO BEGIN, PRESS C TO CHANGE PATTERN"
70 PRINT:PRINT:PRINT
80 POKE 16526,0:POKE 16527,112:POKE 16535,255:GOSUB 350:CLEAR 100

Oh man, Pokes.POKE is a way to directly alter hardware memory (emulated hardware memory here) with a specific value. It's different in every language, because different microcomputers had different memory registers. This is why I need to use emulators for some listings because it isn't something that the Basic Anywhere Machine can easily handle.

The POKES here set us up to use machine language.

90 INPUT "DELAY BETWEEN GENERATIONS IN SECONDS"; SP

One of my few changes. This was originally given in cycles of the For-Next loop, advising that 250 was one second. I simply ask for a value in seconds, and multiply it by 250 later.

100 Z=1
110 CLS
120 PRINT @0, STRING$(64," ");
130 FOR X=1 TO 60
140 J=RND(30)+17:K=RND(8)+4
150 PRINT @(K+64+J),"*";
160 NEXT X
170 Q=USR(0)
190 GEN=GEN+Z:PRINT@0,"GENERATION   ";GEN;
200 FOR X=1 TO SP*250: NEXT X
210 K$=INKEY$:IF K$="" THEN 170
220 IF K$="C" THEN GEN=0:GOTO 90:ELSE GEN=0:CLS:GOTO 130

This sets up the initial generation. It'll always be the same on a first run because of the way RND pseudo-random numbers work, but future runs (after pressing C) should have more variation.

225 REM ## MACHINE LANGUAGE SCREEN UPDATE ##
230 DATA 221,33,0,116,33,0,60,229,253,225,22,0,62,42
240 DATA 253,190,1,204,78,112,253,190,255,204,78,112,253,190,191,204,78,112
250 DATA 253,190,192,204,78,112,253,190,193,204,78,112,253,190,63,204,78,112
260 DATA 253,190,64,204,78,112,253,190,65,204,78,112,205,80,112
270 DATA 35,62,64,188,194,7,112,205,129,112,195,142,112,20,201
280 DATA 190,194,108,112,122,254,2,202,128,112,254,3,202,128,112
290 DATA 221,117,0,221,35,221,116,0,221,35,195,128,112,122,254,3,194,128,112
300 DATA 221,117,0,221,35,221,116,0,221,203,0,254,221,35,201
310 DATA 221,54,0,0,221,35,221,54,0,0,221,35,201,221,33,0,116
320 DATA 221,110,0,221,35,221,102,0,221,35,124,254,0,200
330 DATA 254,128,242,170,112,54,32,195,146,112,203,188,54,42,195,146,112,300

This is the machine language instructions, and they must be transcribed from the magazine listing exactly for the program to work. It is many many times faster than BASIC, however.

What do these lines do? I have no idea. I don't know Assembly.

350 ADDR=28672
360 READ CODE
370 IF CODE>255 THEN RETURN
380 POKE ADDR,CODE
390 ADDR=ADDR+1:GOTO 360

This is the subroutine that reads the machine language instructions from our data statements - each is a POKE.

#80 Micro #Model III BASIC