Skip to navigation

Elite on the BBC Micro

Building Elite from the source

If you would like to build a fully working version of Elite from the source code on this site, then you can find out how to do that in the accompanying GitHub repositories (there's one for the BBC Micro cassette version, one for the BBC Micro disc version, another for the 6502 Second Processor version, another for the BBC Master version, and a final one for the Electron version). The repositories replicate the original build process as closely as possible, so let's take a look at how the source files are structured and how the build process works.

To keep things simple, let's concentrate on the build process for the BBC Micro cassette version. The BBC Micro disc, 6502 Second Processor and BBC Master versions have more files and produces more binaries, but the basic pipeline is essentially the same, while the Electron version has an identical build process to the cassette version.

The original file structure
---------------------------

The original Elite source code is split across a number of separate BBC BASIC files, each of which assembles and saves a binary file (the game itself isn't written in BASIC - the source code just uses BBC BASIC's built-in assembler to produce the game). These small binary files are then concatenated into the final game binaries by the "Big Code File" source, and the results are copied to a disc image that you can load into an emulator, or into a real BBC Micro or Acorn Electron using a device like a Gotek.

The annotated sources on this site have been organised in a couple of different ways, one of which follows this original structure (see the "Elite source code by file" section in the site menu). Let's take a look at the various files involved in building Elite from the source.

(I am indebted to Kieran Connell for the following, who designed this build pipeline and wrote the original Python programs as part of his epic elite-beebasm project. Without his original project, none of this would have ever happened...)

The Elite build pipeline
------------------------

The following files together form a build process that creates a fully playable version of Elite from the source code. This is how the source code breaks down:

  • elite-loader.asm contains the source for the game loader (see the annotated source here: Loader)
  • elite-source.asm contains the main source code for Elite (see the annotated source here: Workspaces, Text tokens, Elite A, Elite B, Elite C, Elite D, Elite E, Elite F, Elite G and Ship blueprints)
  • elite-bcfs.asm concatenates the individual binaries into one big code file (see the annotated source here: Big Code File)
  • elite-checksum.py computes checksums and applies the copy protection
  • elite-disc.asm creates the final disc image
  • crc32.py verifies the build

All these files are also available in the BBC Micro cassette version repository.

(For comparison, the 6502 Second Processor version has two separate loader files, the main parasite code is made up of Elite A through Elite J, and there's an additional I/O processor source that runs on the BBC Micro side of the Tube. The disc version, meanwhile, has three loaders, two main code files and 16 ship blueprint files, and the BBC Master version has one loader and just two main files, one for the main game code and another for data.)

The build process uses a five-stage pipeline. This pipeline is based on the original build process from the source disc, but it uses the BeebAsm assembler and Python instead of BBC BASIC.

The end product is an SSD disc image file that can be loaded by a BBC Micro with DFS, or an emulator like JSBeeb or BeebEm. The code produced is identical to the released version of the game.

Each stage of the build pipeline uses one of the source files from the sources folder, so let's look at what's involved.

1. Compile the main game with elite-source.asm
----------------------------------------------

BeebAsm loads elite-source.asm and creates the following files:

  • output/ELTA.bin
  • output/ELTB.bin
  • output/ELTC.bin
  • output/ELTD.bin
  • output/ELTE.bin
  • output/ELTF.bin
  • output/ELTG.bin
  • output/PYTHON.bin
  • output/SHIPS.bin
  • output/WORDS9.bin

elite-source.asm contains the main source code for Elite. It is based on the original BASIC source files, converted to BeebAsm assembler syntax. In the original build, this is what happens:

  • ELITEA produces the ELTA binary
  • ELITEB produces the ELTB binary
  • ELITEC produces the ELTC binary
  • ELITED produces the ELTD binary
  • ELITEE produces the ELTE binary
  • ELITEF produces the ELTF binary
  • ELITEG produces the ELTG binary
  • DIALSHP contains the PYTHON binary
  • SHPPRTE produces the SHIPS binary
  • GENTOK produces the WORDS9 binary

So the BeebAsm process mirrors the original compilation steps pretty closely.

2. Concatenate the game code and compile the header with elite-bcfs.asm
-----------------------------------------------------------------------

BeebAsm then loads elite-bcfs.asm, which reads the following files:

  • output/ELTA.bin
  • output/ELTB.bin
  • output/ELTC.bin
  • output/ELTD.bin
  • output/ELTE.bin
  • output/ELTF.bin
  • output/ELTG.bin
  • output/SHIPS.bin

and creates the following:

  • output/ELTcode.unprot.bin
  • output/ELThead.bin

elite-bcfs.asm is the BeebAsm version of the BASIC source file S.BCFS, which is responsible for creating the "Big Code File" - i.e. concatenating the ELTA to ELTG binaries plus the SHIPS data into a single executable called ELTcode.

There is also a simple checksum test added to the start of the ELTcode file, but at this stage the compiled code is not encrypted, which is why it has unprot in the name. The original BASIC files contain encryption code that can't be replicated in BeebAsm, so we do this using Python in step 4 below.

3. Compile the loader with elite-loader.asm
-------------------------------------------

Next, BeebAsm loads elite-loader.asm, which reads the following files:

  • binaries/P.DIALS.bin
  • binaries/P.ELITE.bin
  • binaries/P.A-SOFT.bin
  • binaries/P.(C)ASFT.bin
  • output/WORDS9.bin
  • output/PYTHON.bin

and creates the following:

  • output/ELITE.unprot.bin

This is the BeebAsm version of the BASIC source file ELITES, which creates the executable Elite loader ELITE. This is responsible for displaying the title screen and planet, loading the dashboard image, setting up interrupt routines, configuring a number of operating system settings, relocating code to lower memory (below PAGE), and finally loading and running the main game.

The loader incorporates four image binaries from the images folder that, together with the code to draw the Saturn backdrop, make up the loading screen. It also incorporates the WORDS9 and PYTHON data files that contains the game's text and the Python ship blueprint.

There are also a number of checksum and protection routines that EOR the code and data with other parts of memory in an attempt to obfuscate and protect the game from tampering. This can't be done in BeebAsm, so we do this using Python in the next step.

4. Calculate checksums and add encryption with elite-checksum.py
----------------------------------------------------------------

Next, the pipeline runs the Python script elite-checksum.py, which reads the following files:

  • output/ELTA.bin
  • output/ELTB.bin
  • output/ELTC.bin
  • output/ELTD.bin
  • output/ELTE.bin
  • output/ELTF.bin
  • output/ELTG.bin
  • output/ELThead.bin
  • output/SHIPS.bin
  • output/ELITE.unprot.bin

and creates the following:

  • output/ELTcode.bin
  • output/ELITE.bin

There are a number of checksum and simple EOR encryption routines that form part of the Elite build process. These were trivial to interleave with the assembly process in the original BASIC source files, but they've been converted into Python so they can run on modern machines (as not too many modern computers support BBC BASIC out of the box). Kieran Connell is the genius behind all this Python magic, so many thanks to him for cracking the code.

The script has two parts. The first part generates an encrypted version of the ELTcode binary, based on the code in the original S.BCFS BASIC source program:

  • Concatenate all the compiled binaries
  • Compute the checksum for the commander data
  • Poke the checksum value into the binary
  • Compute the checksum for all the game code except the header
  • Poke the checksum value into the binary
  • Encrypt all the game code except the header using a cycling EOR value (0-255)
  • Compute the final checksum for the game code
  • Output the encrypted ELTcode binary

The second part implements the checksum and encryption functions from the ELITES BASIC source program to generate an encrypted ELITE binary:

  • Reverse the bytes for a block of code that is placed on the stack
  • Compute the checksum for MAINSUM
  • Poke the checksum value into the binary
  • Compute the checksum for CHECKbyt
  • Poke the checksum value into the binary
  • Encrypt a block of code by EOR'ing with the code to be placed on the stack
  • Encrypt the code destined for lower RAM by EOR'ing with the loader boot code
  • Encrypt binary data (dashboard etc.) by EOR'ing with the loader boot code
  • Output the encrypted ELITE binary

At the end of all this we have two encrypted binaries, one for the loader and another for the main game.

5. Assemble a bootable disc image with elite-disc.asm
-----------------------------------------------------

Finally, BeebAsm loads elite-disc.asm, which reads the following files:

  • binaries/$.!BOOT.bin
  • binaries/$.ELITE.bin
  • output/ELITE.bin
  • output/ELTcode.bin

and creates the following:

  • elite-cassette.ssd

This script builds the final disc image, to match the released version of the game (albeit on a disc rather than a cassette). It is passed as an argument to BeebAsm by the Makefile when it creates the disc image.

The names of the files in the released version of Elite are slightly different to those produced by the build process from the source disc, because the released disc also contains Acornsoft's iconic mode 7 loading screen in a BASIC program called ELITE. As a result, the ELITE binary that the build process generates for the Elite loader gets renamed to ELTdata for the released version. The final disc therefore contains the following files:

  • !BOOT - a boot file that is *EXECuted on a Shift-Break and simply CHAINs the ELITE program
  • ELITE - displays the mode 7 Acornsoft loading screen for Elite, and then *RUNs the Elite loader in ELTdata
  • ELTdata - the Elite loader with its Saturn loading screen, renamed from the original ELITE file that's produced by the build process
  • ELTcode - the main game code

Note that by default, the build process produces a version of the cassette game that can be loaded from disc, so the above names are designed to fit into the seven-character limit of DFS. You can build a genuine cassette version by setting the DISC configuration variable to FALSE, in which case the filenames should be ELITEdata and ELITEcode.

The disc image is called elite-cassette.ssd, and you can load it into an emulator, or into a real BBC Micro using a device like a Gotek.

Doing the above on a modern computer
------------------------------------

For more details on how to run this process on a modern computer, and for all the source and build files you need to run this on your PC, Mac or Linux box, see the accompanying GitHub repositories:

In each case the source code on GitHub is identical to the code on this site (in fact, this website is generated from the GitHub repositories, so they are guaranteed to be identical).