Skip to content

From BASIC to machine code

How home-computer owners of the 1980s taught themselves to program the processor

Every home computer of the early 1980s started in BASIC, and for games BASIC was too slow. Owners crossed to machine code with PEEK, POKE and USR or SYS, hex loaders typed in from books, and a shelf of guides, from The ZX80 Companion (1980) and Sinclair User's 1982 tutorials to Usborne's Machine Code for Beginners and Rodnay Zaks's Programming the Z80. The programmers who made it described the crossing as hard, lonely and done mostly from books.

“This question crops up over and over again,” Your Computer told a reader in February 1986. David Browne of Bristol was “a competent Basic programmer” and wanted to program his Amstrad in machine code. How should he start? The magazine’s answer was the one a generation of home-computer owners had already worked out for themselves: get an assembler, buy a book, and “just dive in”.

Almost every home computer of the early 1980s switched on into BASIC, and most owners wrote their first programs in it. The ones who wanted to write fast arcade games soon found that BASIC could not keep up, and that the games in the shops were written in the processor’s own language, machine code. The crossing from one to the other had its own books, magazine columns and tools, and programmers who went on to write games described making it alone, from books, one crash at a time.

Why bother?

The period books gave two answers. Bruce Smith’s VIC 20 Machine Code (1984) put them in order:

Firstly speed. Machine code is executed very much faster than an interpreted high level language such as BASIC.

and then:

learning machine code allows you to understand just how your computer works, and lets you create special effects and routines not possible within the constraints imposed by the limited set of BASIC instructions.

Smith also explained where the time went. The BASIC interpreter is itself a machine-code program in ROM, and each BASIC statement is only a pointer to a routine in that ROM. “It is because each statement and command must first be identified and located within the ROM that a decrease in operational speed occurs.” John Hardman and Andrew Hewson made the same point with a Spectrum example in 40 Best Machine Code Routines for the ZX Spectrum (1982): a BASIC loop that copies the screen must decode every command afresh on every pass, so “the computer spends over 99% of the time preparing to perform the task rather than performing the task itself”. The machine-code version, they wrote, “executes more or less instantaneously”.

Mike Biddell, starting a machine-code series in Sinclair User in May 1982, gave three reasons: machine code was faster, it took less memory, which mattered on an unexpanded ZX81, and it let a programmer do things the manufacturer’s BASIC could not, such as scrolling the screen downwards when Sinclair BASIC only scrolled up. The software houses advertised the same thing. Orwin Software’s ZX81 cassettes, in a 1983 advertisement, promised that “7 of the 8 games are in machine code, because this is much faster than Basic”.

BASIC was not a dead end. CRASH noted in 1985 that “some classic games have been programmed entirely in BASIC”, naming Mined Out, Football Manager and Velnor’s Lair, and reviewed BASIC compilers that could make a program anywhere from 2 to 200 times faster. But “if you want to write a shoot-’em-up game, or a program with sophisticated graphics, you’ll almost certainly find BASIC too slow.”

The first step: POKE and USR

The crossing began inside BASIC. POKE put a number into a memory location and PEEK read one back, so a routine could be placed in memory one byte at a time from DATA statements. A call handed control to it. On the Sinclair machines that call was the function USR, which the Spectrum’s listings usually wrote as RANDOMIZE USR because a function has to sit inside a statement (see Sinclair BASIC); the Commodores used SYS, other machines CALL. Usborne’s Machine Code for Beginners (1983) told readers to check which one their manual used.

The ZX80 and ZX81 had no safe place set aside for machine code, so owners hid it in a REM statement at the start of the program. The ZX80 Companion (1980) printed a program by Pat Crabb that took a routine in hexadecimal and poked it into the REM. Biddell’s series in Sinclair User used the same trick on the ZX81, whose first REM began at address 16514: “The most suitable place for the code, it is generally agreed, is within a REM statement placed at line 1 of the program.” Because POKE takes decimal numbers, every byte had to be converted from the hexadecimal in the manual’s instruction table first.

Usborne’s book taught its first routine for the Z80 and the 6502 side by side: a program that adds 2 and 4 and stores the answer, typed in through a BASIC “hex loader” and run with the machine’s call command. Here it is on a 48K Spectrum, written as the Spectrum lists it:

BASIC
10 CLEAR 32767
20 FOR n=0 TO 7
30 READ b: POKE 32768+n,b
40 NEXT n
50 RANDOMIZE USR 32768
60 PRINT PEEK 32800
70 DATA 62,2,198,4,50,32,128,201

CLEAR 32767 moves the top of BASIC’s memory down so that the routine at 32768 is safe. The eight numbers in the DATA line are the Z80 routine:

Assembly
        org 32768
        ld a,2          ; put 2 in the accumulator
        add a,4         ; add 4 to it
        ld (32800),a    ; store the answer at 32800
        ret             ; back to BASIC

The program prints 6. On a Commodore 64 the same idea uses the free memory at 49152 and SYS:

BASIC
10 FOR N=0 TO 8
20 READ B:POKE 49152+N,B
30 NEXT N
40 SYS 49152
50 PRINT PEEK(49200)
60 DATA 24,169,2,105,4,141,48,192,96

and the 6502 routine behind it:

Assembly
        * = 49152
        clc             ; clear the carry flag
        lda #2          ; put 2 in the accumulator
        adc #4          ; add 4 (and the carry, now 0)
        sta 49200       ; store the answer at 49200
        rts             ; back to BASIC

The 6502 has no add without carry, so the routine clears the carry flag first; Usborne’s book leaves that step out of its first example and explains the carry flag a few pages later. Nothing about either program is fast. The point is the path: BASIC puts the bytes in memory, hands control to the processor, and gets control back when the routine returns.

Acorn’s machines made the step shorter. Elbug, a magazine for Acorn Electron owners, explained in November 1984 that “on some machines this is a separate utility, but on the Electron the assembler is built into Basic”: in any BBC BASIC program, a [ switched to assembly language and a ] switched back. The same article explained why the mnemonics existed at all: hexadecimal was less tedious than binary, but “any program written this way will be completely unreadable to all but the most fanatic of programmers. To make life easier for everyone, all 6502 machine code instructions can be represented by three letter mnemonic codes.”

Books and columns

The guides started early. The ZX80 Companion, first printed in May 1980, did not set out to teach Z80 machine code, but its section on it began: “Once the user has mastered BASIC there are still many areas of the system which may be explored”. For the processor itself it sent readers to Rodnay Zaks’s Programming the Z80, published by Sybex, which became the book everyone recommended and few found easy. Hardman and Hewson called it “the standard reference” but warned that “the beginner might find it rather formidable because it runs to more than 600 pages”. Your Computer, in its 1986 answer, thought it “far too general” for a novice and recommended a book written for the reader’s own machine.

Books for particular machines followed:

  • Ian Logan took apart the ZX80, ZX81 and Spectrum ROMs for Melbourne House, from Understanding Your ZX81 ROM (1981) to The Complete Spectrum ROM Disassembly with Frank O’Hara (1983).
  • Toni Baker’s Mastering Machine Code on Your ZX81 was on sale by July 1982 at £7.50; a Your Computer columnist had heard “good reports” of it.
  • John Hardman and Andrew Hewson, 40 Best Machine Code Routines for the ZX Spectrum (Hewson Consultants, 1982): three chapters on the Z80 and the Spectrum’s memory, then routines for scrolling, searching, renumbering and more, to use from BASIC “with or without adaption”.
  • Lisa Watts and Mike Wharton, Machine Code for Beginners (Usborne, 1983): illustrated, for the Z80 and 6502 machines side by side, with instruction tables for both.
  • James Walsh and Paul Holmes, Spectrum Machine Code Made Easy, in two volumes, one for beginners by Walsh and an advanced one by Holmes, each first sold at £5.95; Your Computer was still offering the pair to its readers in 1987.
  • Richard Mansfield, Machine Language for Beginners (COMPUTE! Books, 1983), for Commodore, Atari and Apple owners, with a chapter of machine-language equivalents of BASIC commands and the Supermon monitor listed in full.
  • Bruce Smith, VIC 20 Machine Code (Shiva, 1984), which printed every program as DATA statements, as machine code and as assembly language, so readers could enter it whichever way they could.

The magazines taught it too. Biddell’s three-part series in Sinclair User ran from May to July 1982 and promised to end with “a machine code-based game”. From 1982 until 1988 the same magazine ran Andrew Hewson’s Helpline, a monthly page in which the head of Hewson Consultants answered readers’ technical questions, many of them about machine code. In America COMPUTE! printed long machine-language programs as numbers, and in 1984 gave readers MLX, a checksum program for typing them in without mistakes (see type-in listings).

Monitors and assemblers

Typing hex into a loader worked for a few bytes. For anything longer, readers bought tools. In July 1982 Sinclair User compared a shelf of ZX81 monitors and disassemblers, programs that showed memory and turned bytes back into instructions. In June 1983 it reviewed Crystal Computing’s Zeus assembler for the 48K Spectrum, £8.95, which let a programmer write assembly language in numbered lines, like BASIC, and listed any errors with their line numbers; Crystal sold a monitor and disassembler at the same price. By December 1984 Sinclair User credited HiSoft of Bedfordshire, whose machine-code development system Devpac had come out more than a year before, with giving the Spectrum “a higher credibility factor than Sinclair Research could ever manage by itself”. Your Computer’s 1986 answer named Devpac as its own choice on the Amstrad.

In the programmers’ words

Programmers interviewed by Sinclair User in the 1980s described learning this way.

  • Matthew Smith, who wrote Manic Miner, started on a Tandy. “I learned Level One Basic on it, which was no use for anything at all. I started learning machine code. It was tough. There were virtually no books at all, except a really heavy one by Rodney Zaks,” he told Sinclair User in 1984.
  • John Gibson of Imagine, 36 when Sinclair User met him in May 1984, had taught himself on a ZX81 bought in 1980. “I could not afford a 16K RAM pack in those days and with only 1K to play with, there was no choice but to learn machine code.”
  • Stephen Curtis learnt some BASIC on a Commodore PET at college in 1980, then bought a ZX81. “Bit by bit I learnt machine code, mostly from books. I bought three at once and read each one at least three times. These days I just use Rodney Zaks’ reference book on the Z80.” He thought it the best way to learn: “you have to go through the business of solving the problems yourself and do it all by trial and error.” The first program he wrote, once he had moved up to a Spectrum, was a version of Breakout.

CRASH remembered what that trial and error cost on a tape-based machine. “Learning machine code was a traumatic process: before disks and microdrives … every programming mistake meant a crash.” After each mistake it took “several minutes to re-load your assembler, debugger and program source from tape in preparation for another crack at the problem.” Some of the people who took those cracks went on to write the games described in bedroom coder.

Sources

  • Your Computer, February 1986, “Response Frame”: David Browne’s question on Amstrad machine code and Jim Taylor’s answer (Devpac; Zaks “far too general”; Ian Sinclair’s Introducing Amstrad CPC464 Machine Code; the Firmware Manual).
  • Bruce Smith, VIC 20 Machine Code (Shiva Publishing, 1984), chapter 1, “Machine Code or Assembly Language”, pp. 3–4 (“Why machine code?”; programs in DATA, machine code and assembler forms).
  • John Hardman and Andrew Hewson, 40 Best Machine Code Routines for the ZX Spectrum (Hewson Consultants, 1982), pp. 4–5 (the screen-copy loop, “over 99%”, “How to Learn Machine Code” and Zaks’s book) and back cover.
  • Mike Biddell, machine code series, Sinclair User issue 2, May 1982, p. 48 (his reasons; the Nascom-1 and the Mostek manual; the REM at 16514); issue 3, June 1982; issue 4, July 1982, p. 62 (final part).
  • Sinclair Programs issue 12, October 1983, and issue 15, January 1984: Orwin Software advertisement.
  • CRASH issue 19, August 1985, pp. 86–87: “Basic Compilers for the Spectrum” (games written in BASIC; 2 to 200 times faster; learning machine code from tape).
  • Steven Vickers, Sinclair ZX Spectrum BASIC Programming (Sinclair Research, 1982), appendix C, USR (“Calls the machine code subroutine whose starting address is x”).
  • Lisa Watts and Mike Wharton, Machine Code for Beginners (Usborne, 1983): “About this book”; hex loader and “Running the machine code program”, pp. 24–25; carry flag, p. 29.
  • Mike Williams, “Introducing Machine Code”, Elbug vol. 2 no. 1, November 1984, pp. 24–25.
  • Bob Maunder, Terry Trotter and Ian Logan, The ZX80 Companion, 2nd edition (Linsac, 1980; first printed May 1980), section 3.7, “Machine Code”, pp. 43–49.
  • Your Computer, July 1982: reader’s advice column (Toni Baker’s Mastering Machine Code on Your ZX81, £7.50; Programming the Z-80 “for further reading”).
  • Richard Mansfield, Machine Language for Beginners (COMPUTE! Books, 1983): contents (chapter 9, “ML Equivalents of BASIC Commands”; Supermon).
  • Sinclair User issue 4, July 1982: ZX81 monitors and disassemblers compared; Helpline, Andrew Hewson. Issue 71, February 1988: Helpline, Andrew Hewson.
  • Your Computer, March 1987 and April 1987: book offers (Spectrum Machine Code Made Easy, volumes one and two, their authors and prices).
  • COMPUTE! issue 46, March 1984: Charles Brannon, “MLX: Machine Language Entry Program for Commodore 64”.
  • Sinclair User issue 15, June 1983, p. 28: “Useful tool from Zeus” (Crystal Computing).
  • Sinclair User issue 33, December 1984, p. 13: HiSoft, Devpac and the Pascal compiler.
  • Chris Bourne, “Hit Squad”, Sinclair User issue 33, December 1984, pp. 88–89: Matthew Smith interview.
  • Nicole Segre, “Hit Squad”, Sinclair User issue 26, May 1984, pp. 40–41: John Gibson.
  • Sinclair User issue 63, June 1987: profile of Stephen Curtis.

See also

Checked. Verified against primary sources and signed off by a person.