How To Write ZX Spectrum Games – Chapter 18
Making Games Load and Run Automatically
Note: This article was originally written by Jonathan Cauldwell and is reproduced here with permission.
While this is simple enough to achieve for an experienced Sinclair BASIC programmer, it is an area often overlooked. In particular, programmers migrating to the Spectrum from other machines will not be familiar with the way this is done.
In order to run a machine code routine, we have to start it from BASIC. This means writing a small BASIC loader program, which clears the space for the machine code, loads that code, and then runs it. The simplest sort of loader would be along these lines:
10 CLEAR 24575: LOAD ""CODE: RANDOMIZE USR 24576
The first command, CLEAR, sets RAMTOP below the area occupied by the machine code, so BASIC doesn’t overwrite it. It also clears the screen and moves the stack out of the way. The number that follows should usually be one byte below the first byte of your game. LOAD “”CODE loads the next code file on the tape, and RANDOMIZE USR effectively calls the machine code routine at the address specified, in this case 24576. This should be the entry point for your game. On a Spectrum, The ROM sits in the first 16K, and this is followed by various other things such as screen RAM, system variables and BASIC. A safe place for your code is above this area, all the way up to the top of RAM at address 65535. With just a short BASIC loader a start address of 24576, or even 24000 will give you plenty of room for your game.
This loader program is then saved to tape using a command like this:
SAVE "name" LINE 10
LINE 10 indicates that on loading, the BASIC program is to auto-run from line 10.
After the BASIC loader comes the code file. You can save a code file like this:
SAVE "name" CODE 24576,40960
CODE tells the Spectrum to save a code file, as opposed to BASIC. The first number after this is the start address of the block of code, and the last number is its length.
That is simple enough, but what if we want to add a loading screen? Well, that is straightforward enough. We can load a screen using
LOAD ""SCREEN$
What this will do is load a block of code up to 6912 bytes long, to the start of the screen display at address 16384. Putting the screen file there is a bit trickier, because we cannot simply save out the screen as a file as the bottom two lines would be overwritten with the Start tape, then press any key message. So we load our picture into a point in RAM – say, 32768 – then use
SAVE "name" CODE 32768,6912
6912 is the size of the Spectrum’s display RAM. When we reload the block from tape using LOAD “”SCREEN$, we are specifying that we want to force the code file to be loaded into screen memory. Under these circumstances it doesn’t matter where the code file was located when it was saved.
Now we have another problem: wouldn’t the Bytes: name message that is printed up on loading the code block overwrite part of the screen? Well, yes it would. We can overcome this by poking the output stream.
POKE 23739,111
Will do the trick for us. So our BASIC loader now looks like this:
10 CLEAR 24575: LOAD ""SCREEN$: POKE 23739,111: LOAD ""CODE: RANDOMIZE USR 24576
Thank you so much for posting these chapters. They have been incredibly helpful in getting my Spectrum game going. I live the U.S. where Speccy books are nonexistent, making these posts doubly helpful.
Glad to be of service!