Sinclair ZX Basic
It might be basic, both in name and nature, but this programming language is capable of plenty, as Mike Bedford reveals.
It might be basic, both in name and nature, but this venerable programming language is capable of anything that today’s languages can do, as Mike Bedford reveals.
Nearly 40 years ago an astonishing new computer appeared on the scene. What was so noteworthy about it was its price of £99.95, making in the first computer to sell in the UK for less than £100. That computer was the Sinclair ZX80. Today, £100 might not sound too remarkable when we consider that the Raspberry Pi 4 costs £34, and when we also bear in mind that prices in 1980 were the equivalent of four times that amount today because of inflation – but in that era it was truly ground-breaking.
Computers such as the Commodore PET and the Apple II cost £775 and £1,200 respectively, and even these were cheap compared to the lowest-priced computers from just a few years earlier: minicomputers like the DEC PDP/8 which would have set you back ten times as much. Public reaction was profound. At long last, would-be computer enthusiasts could get their hands on some hardware, and no fewer than 100,000 of them did just that.
It might not have mattered to those early computer users, but it’ll come as no surprise to learn that the ZX80’S specification was somewhat modest in comparison to other personal computers of the early ’80s, let alone a modern-day computer. The processor was an 8-bit Zilog Z80 clocked at 3.25MHZ, it had 1KB of RAM – yes, really, just 0.000001GB – and it had 4KB of EPROM non-volatile memory – the 1980s equivalent of flash memory – that contained the system software.
Perhaps one of the most astonishing omissions, though, was an operating system. The bottom line is that there really was no operating system, and instead it powered up into an environment that allowed you to enter and run your own BASIC code. This provided an opportunity to learn to code, but there was more. The home computer software industry was in its infancy so, generally speaking, many users would enter code that had been published as BASIC source code in magazines
(madness!–ed) and books – that brings us full circle with this guide to the BASIC programming language.
If your informative years were well after this era of the first affordable home computers, you can view this as a hands-on history lesson. Once you’ve learned to code in BASIC, we don’t expect you to abandon Python or C++ any time soon, but we trust you’ll find it fascinating to learn how an earlier generation of enthusiasts learned to program, and how a relatively unsophisticated language can, nevertheless, achieve impressive results.
A BASIC introduction
BASIC stands for Beginners’ All-purpose Symbolic Instruction Code, and it was developed in 1964 specifically as a vehicle to teach programming. Unlike many languages, which have stayed true to their roots, BASIC has spawned many variants over the years, many of which seem to share little more than the name with the original. The ZX80 used a variant of BASIC that had some extensions, but not nearly as many as the versions that have appeared more recently. Our aim here, therefore, is to show you how to use a fairly basic BASIC which isn’t too different from that used by the Sinclair BASIC on the ZX80.
To categorise these early BASICS, we’d have to say that they’re not object-orientated and they’re not blockstructured. That latter phrase isn’t commonly used today, because pretty much all modern languages are block-structured, but it means that groups of statements can be used instead of single statements
in, for example, IF THEN ... ELSE ... ENDIF constructs. The only block structure that was supported in the original BASIC was the FOR ... NEXT construct.
While BASIC might have been rather simplistic, though, many of the common implementations embodied a concept that was undoubtedly forwardlooking. The phrase probably wouldn’t have been used at the time, but common BASIC implementations were often IDES (Integrated Development Environments). So instead of entering the code in a text editor, and then compiling it before running it, code was written at the command line and, once complete, would be executed simply by typing RUN. With most implementations also being interpreters, the code would be run immediately, each line being converted to an executable form, on the fly, as it was run.
BASIC hands-on
The version of BASIC that we’re going to use here – selected to give you much of the look and feel of BASIC programming of old – is called Bywater BASIC, but it’s referred to as bwbasic in repositories. So, install it on your system and then type bwbasic in a terminal window. If you were expecting a fancy user interface to appear, you haven’t got into a 1980s mindset yet, so either cast your mind back 40 years or, if this is a revelation to you, just be prepared to accept something new… er, old. Above all, though, remember that back in the ’80s, this was exciting stuff – never before had ordinary people had computing power at their disposal.
On running Bywater BASIC, you’ll notice that a threeline introduction appears in the terminal window – from which you’ll see that even this post-zx80 implementation of BASIC is no spring chicken – and this is followed by the prompt BWBASIC: , which you’ll be seeing a lot more of.
The standard BASIC user interface tended to be different from that of most IDES or text editors, in that you can’t move up and down your program using arrow keys to make changes. Actually, Bywater BASIC does include a ‘proper’ editor, but we’re going to ignore that and guide you through the more common interface of the 1970s and early 1980s, to give you that authentic retro experience.
To enter a program, you type lines of code at the prompt, making sure you add a line number at the start of each line. Your program will be ordered according to the line numbers – which are also the targets for GOTO and GOSUB statements – and to edit your code, you just enter a new line which will replace the previous line with that number. Alternatively, if you just type a number by itself, any line with that number will be deleted. You might expect us to start out with a ‘Hello World’ program, but this wasn’t really an ’80s thing, so let’s start with something just a bit more complicated to give you a feel for the user interface.
We’re going to write a program to print out the words of the song Ten Green Bottles, which was a common example to teach the concept of loops. So, type the following commands at the BWBASIC: prompt: 10 FOR N = 10 to 1 STEP -1
20 PRINT N; “green bottles hanging on the wall, “30 PRINT N; “green bottles hanging on the wall, “40 PRINT “and if one green bottle should accidentally fall, “ 50 PRINT “there’d be “; N-1; “green bottles hanging on the wall. “
60 PRINT
70 NEXT N
200 END
If you’ve typed in the instructions one after another, exactly as shown, this eight-line program will be seen on the lines immediately above the prompt. In general, though, especially if you’ve edited your program, it’s useful to be able to see a listing. To do this, just type LIST , noting that anything you type without a line number, such as the LIST command, is executed immediately. Once you’re happy that the listing is correct, type RUN and, all being well, you should see all ten verses appear on screen.
Admittedly the first two lines of each verse have a space at the start, which results from BASIC’S formatting of numbers in print statements (there’s a space at the beginning of positive numbers, where a minus sign would appear in its place for negative ones), but it’s not bad for a first attempt. However, we could do better, by putting the proper words for numbers instead of digits.
To do this, we’re going to use an alphanumeric array to hold the words for each of the numbers from 0 to 10. Normal variables don’t need to be declared in BASIC because they’re all floating-point unless they have a dollar sign at the end, in which case they’re alphabetic – but arrays do need to be declared. To declare an array, enter the following:
2 DIM A$(10)
Now we need to initialise the array with the words for the numbers, and to do this, we’ll use a DATA
statement that we’ll put near the end of the program. So enter the following:
100 DATA “no”, “one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”, “ten”
Next, we need a loop to read these values into the array, so enter the following commands:
4 FOR N = 0 to 10
6 READ A$(N)
8 NEXT N
Finally, we need to alter the lines 20, 30 and 50 by retyping them, so that each occurrence of N is replaced by A$(N) , and the occurrence of N-1 is replaced by A$(N-1) . Once you’ve done that, LIST the program to check it through and, if you’re confident it’s OK, RUN it. The critical will note that the plural word “bottles” is used when there’s only one – we’ll leave you to fix that if you feel so inspired.
Even so, this simple program reveals a major problem with the use of line numbers to enter BASIC programs. We used numbers mostly in steps of 10, to start, to allow some space for adding extra instructions should such a need arise. We then made use of that to add some more instructions before line 10. However, there’s not a lot of room left to add any more, and this is a major problem.
One solution, of course, is to use a GOTO statement to jump off to some new code with high line numbers, and to jump back afterwards, but this doesn’t lead to programs that are particularly easy to read and amend at a later stage. A rather more sensible solution is to make use of the fact that most implementations of BASIC, including Bywater BASIC but not Sinclair BASIC, allow multiple statements to be put on the same line, separated by colons.
Some BASIC implementations had a RENUMBER command that overcame this problem, but Bywater
BASIC doesn’t, so be aware of this and, if necessary, use lines spaces by more than 10 in some parts of the program. Alternatively, for an interesting programming exercise, you could try writing a program to renumber another program stored in a file, outputting the result to another file.
Keeping it BASIC
Bywater BASIC has several extensions compared to the original BASIC and compared to Sinclair BASIC. For that authentic experience, however, there are some things which, although supported by Bywater BASIC, you should avoid. Sinclair BASIC allows long alphabetic variable names of the sort you’ll be used to in just about any other mainstream programming language, but alphanumeric variables and arrays can have just singleletter names (plus the dollar sign for alphanumerics). Even this was an improvement on the original BASIC, though, which permitted variable names to be either just a single letter or a single letter followed by a single numeric digit. Needless to say, programs are much harder to understand if a variable that really ought to be called left_margin has to be called M0 .
Next, Bywater BASIC has a WHILE command. Early BASICS didn’t, and this first attempt at supporting structured programming only started to appear in the years after the ZX80. The final important extension you should know about is the option of ELSE in Bywater
BASIC’S IF statement, something that wasn’t available in early BASICS, including Sinclair BASIC. An IF
statement only be of the form IF
Before creating a new program, you might want to save the Green Bottles program using the SAVE
command, with a filename after it surrounded by double quotes: SAVE “greenbot” . To subsequently load it, just use the LOAD command. With that program saved, you can now use the NEW command to clear the current program from memory in preparation for entering a new one. However, we did notice that the NEW command doesn’t clear everything properly, so if your new program tries to
declare an array with a different size to the old one, you’ll get an error message. It might be safer, therefore, to exit BASIC using the QUIT command and restart it.
Most of this should make sense, so long as you’ve got a grasp of programming fundamentals, so just enter the following program and try it out.
10 P$ = “negative” : REM positive or negative flag
20 E$ = “odd” : REM even or odd flag
30 INPUT “Please enter an integer” N
40 IF N = 0 THEN PRINT “That number is zero.” : GOTO 100
50 IF N <> INT(N) THEN PRINT “Not an integer...” : GOTO 30
60 IF N > 0 THEN P$ = “positive”
70 IF N/2 = INT(N/2) THEN E$ = “even”
80 PRINT “That is a “; P$; ““; E$; “number.”
100 END
Although this program is simple, it does introduce a few new concepts, perhaps most importantly the INPUT and IF statements. Here we’re using the version of the INPUT statement that includes a user prompt, but the simplest form excludes that prompt text, and prompts the user with just a question mark. We’re also starting to see how the lack of structured programming constructs forces the use of GOTO statements, in this case as part of an IF statement.
With BASIC dialects that don’t allow the use of colons to make multiple statements on the same line conditional, for example Sinclair BASIC, it’s sometimes inevitable that the code will become even more convoluted. Last, but by no means least, we’ve introduced the REM statement, short for “remark”, more commonly known as a comment.
A universal language
We’ve seen a couple of sample programs, both of them simple in the extreme – but then we have been using BASIC, which is first and foremost a simple programming language. Don’t be fooled, though; BASIC is a Turing Complete language, which means that if you can solve a problem in Python, or whatever your favourite language is, you can solve it in BASIC. If you’re on that trip down memory lane, you might well have fond memories of what you were able to do using BASIC with a bit of perseverance and a lot of ingenuity and patience. If your computer experience doesn’t go back that far, we trust you won’t be too dismissive of what some of us used to learn to program in our formative years. Either way, we really hope that you’re up for the challenge of putting BASIC to work on some rather more ambitious projects. Wherever you go from here with Bywater BASIC, though, you’ll need the language reference manual at http://web.cs.mun. ca/~ed/cs2602/basic1.html.
The result might not compare too favourably to modern implementations in terms of speed, or the sophistication of the graphics, but how about coding the Game of Life in Bywater BASIC? Many programmers of old cut their teeth on this, as some still do today. If you’re not familiar with it, let’s just say it’s not really a game but a mathematical curiosity, and the technically-minded often find it fascinating and surprisingly addictive. Needless to say, a quick online search will tell you all you need to know.
Try the online one at https://bitstorm.org/ gameoflife to get a better idea of what’s it’s supposed to do, and to check your code against. Modern versions of the Game of Life use bitmapped graphics and a huge grid, often expandable. However, we suggest starting off with a small grid, no more than 50 x 50, displaying the grid textually using a space for a dead cell and an asterisk for a live one, and prompt the user to proceed from one generation to the next. Oh, and since this will run forever, we ought to let you in on the secret that, in common with many other dialects of BASIC, you can terminate any running program in Bywater BASIC using the Ctrl+c shortcut.
With the Game of Life under your belt, the sky’s the limit – so how about trying your hand at coding a game? A real game that is. You won’t manage animated graphics in Bywater BASIC, but that won’t make it any less of a voyage of discovery, in a 1980s sort of way. No doubt you’ll have lots of other ideas, but a common ’80s programming exercise was the game of Noughts and Crosses. Implementing it as a two-player game would be easy. Who said BASIC was basic?