Skip to navigation

BBC Micro Elite

About this project

This project is based on the original source files for Elite on the BBC Micro Model B, which can be found on Ian Bell's personal website. The game code in this repository is totally unchanged from the original source, apart from being reformatted to be easier to read. I've left all the original label names intact, as this site is all about digital archaeology and appreciating the authors' original handiwork.

Here's a bit more on how this project came to be.

Ian Bell's original sources
---------------------------

When I first saw that the sources to Elite had been released on Ian Bell's website, I couldn't believe it. I'd always wanted to understand how this astonishing technical feat had been achieved, ever since I'd sat wide-mouthed as a 14-year-old when I first launched from the space station and saw the planet Lave hanging in space, right in front of my eyes. Which, of course, was shortly before dying for the first time, but that didn't matter. It was love at first sight.

So I excitedly opened one of the source files at random... and was greeted by page after page of this kind of thing:

  9300.LL145 \CLIP
  9305LDA#0:STASWAP
  9310LDAXX15+5:.LL147 LDX#Y*2-1:ORAXX12+1:BNELL107:CPXXX12
  9315BCCLL107:LDX#0:.LL107 STXXX13:LDAXX15+1:ORAXX15+3:BNELL83
  9320LDA#Y*2-1:CMPXX15+2:BCCLL83
  9325LDAXX13:BNELL108:.LL146 LDAXX15+2
  9330STAXX15+1:LDAXX15+4:STAXX15+2:LDAXX12:STAXX15+3:CLC:RTS
  9335.LL109 SEC:RTS:.LL108 LSRXX13:.LL83
  9340LDAXX13:BPLLL115
  9345LDAXX15+1:ANDXX15+5:BMILL109:LDAXX15+3:ANDXX12+1:BMILL109
  9350LDXXX15+1:DEX:TXA:LDXXX15+5:DEX:STXXX12+2:ORAXX12+2
  9355BPLLL109:LDAXX15+2:CMP#Y*2:LDAXX15+3:SBC#0:STAXX12+2
  9360LDAXX12:CMP#Y*2:LDAXX12+1:SBC#0:ORAXX12+2:BPLLL109
  9365.LL115 TYA:PHA:LDAXX15+4:SEC:SBCXX15:STAXX12+2:LDAXX15+5
  9370SBCXX15+1:STAXX12+3:LDAXX12:SEC:SBCXX15+2:STAXX12+4
  9375LDAXX12+1:SBCXX15+3:STAXX12+5:EORXX12+3:STAS

I suppose I should have expected it, but the original source files are incredibly terse. Because the game was compiled on a BBC Micro, the source code had to be squashed into a number of extremely cramped BASIC files, with all the spaces removed and almost no comments to speak of. The source files are not particularly human-friendly; they aren't supposed to be.

Not only that, but parts of the game started life on an Acorn Atom, where labels in assembly language are restricted to two letters plus digits, so the source is full of memorable names like XX16, QQ17 and LL9. I mean, look at this bit:

  8501.LL42 \DO nodeX-Ycoords
  8506\TrnspMat:LDYXX16+2:LDXXX16+3:LDAXX16+6:STAXX16+2:
  LDAXX16+7:STAXX16+3:STYXX16+6:STXXX16+7
  8508LDYXX16+4:LDXXX16+5:LDAXX16+12:STAXX16+4:LDAXX16+13
  8509STAXX16+5:STYXX16+12:STXXX16+13
  8510LDYXX16+10:LDXXX16+11:LDAXX16+14:STAXX16+10:LDAXX16+15
  8511STAXX16+11:STYXX16+14:STXXX16+15

All those XXXs are enough to make your eyes boggle, but at least this excerpt has some comments, so do they help? "TrnspMat" - is that "transponder materials"? Or "transport maths"? I guess it's something to do with "DO nodeX-Ycoords", which clearly involves nodes and coordinates, but it's not exactly readable. (I now know that this is part of the LL42 routine that transposes the rotation matrix, but knowing that doesn't make it any easier to follow; it possibly makes it even scarier.)

This terseness is not remotely surprising given the space constraints of compiling code on a 32K micro, but I was still flummoxed. The fact that any kind of source code had been released at all was a kind of Holy Grail experience for me, but it ended up generating more questions than answers.

So I put it to one side and figured I'd probably never understand how this game worked.

Paul Brink's annotated disc disassembly
---------------------------------------

The next breakthrough was when I stumbled across the commentary by Paul Brink, whose annotated disassembly of the disc version of BBC Elite appeared on Ian Bell's site in 2014, covering both the docked code and the flight code. This was a big improvement over the original source files, and like many others, I eagerly grabbed them and settled down with a cup of tea for some interesting reading.

Unfortunately, I still couldn't really work out what was going on; it was like stumbling across a trail of breadcrumbs in the forest, but after heavy monsoonal rain. Every now and then something would seem to make some vague kind of sense, but then I'd come across this kind of thing:

  \XX16 got INWK 9..21..26 up at LL15  . The ROTMAT has 18 bytes, for 3x3 matrix
  \XX16_lsb[   0  2  4     highest XX16 done below is 5, then X taken up by 6,
  \            6  8 10                                        Y taken up by 2.
  \       12 14 16=0 ?]

This refers to the same code as above, and is one of the more verbose explanations in the commentary. It's definitely a step up from "DO nodeX-Ycoords" and "TrnspMat", but what are XX16 and INWK? And ROTMAT - that's a rotation matrix, right? OK, so there are matrices in there somewhere, which is no surprise given the 3D nature of the game. But it's still really hard to work out what's going on, and the code that this comment explains doesn't really make things any clearer than before:

      .LL42  \ ->  &4B04 \ DO nodeX-Ycoords their comment  \  TrnspMat 
  A4 0B                  LDY &0B     \ XX16+2          \ Transpose Matrix
  A6 0C                  LDX &0C     \ XX16+3
  A5 0F                  LDA &0F     \ XX16+6
  85 0B                  STA &0B     \ XX16+2
  A5 10                  LDA &10     \ XX16+7

We're still left with XX16+2 and its friends, so this is essentially the source code, laid out differently, with cryptic hints scattered throughout, hints that seem to be aimed at someone who already understands the basics... which I certainly didn't as I sat there, just as confused as ever.

By this time my tea had gone cold, so once again I put my dreams on hold and forgot about trying to unlock the secrets of Elite.

Kieran Connell's elite-beebasm
------------------------------

In 2020, lockdown boredom led me to stumble across a 2018 post on the Stardot forums by Kieran Connell of the Bitshifters Collective. These guys do some incredibly clever things with BBC computers, and that's exactly what Kieran had done - he'd created elite-beebasm, a port of the original BBC Elite source code from the super-terse BASIC files into the BeebAsm assembler.

Not only had he managed to drag the source code into some kind of human-compatible shape, but he'd also managed to pull apart the encryption process that hides Elite's code from prying eyes. He'd then created an equivalent system in Python, enabling modern computers to build an exact replica of the released version of Elite from the original source. This meant I could not only build a local version of Elite, but I could tweak the code to help work out what it did, which I figured would be a really useful way of working out how Elite weaves its magic.

That said, the source code still looked worryingly familiar:

  .LL42
  \DO nodeX-Ycoords
  \TrnspMat
    LDY XX16+2
    LDX XX16+3
    LDA XX16+6
    STA XX16+2
    LDA XX16+7
    STA XX16+3
    STY XX16+6
    STX XX16+7

But at least I now had a buildable codebase I could work with, and that was real progress.

At last, a fully documented version
-----------------------------------

Kieran's version gave me the leg-up that I needed to crack the problem. I started by copying Paul Brink's comments into Kieran's version, hoping that this would give me some clues to analysing the code, and some small, early glimmers of understanding gave me enough confidence to start poking my way through the bits of the game that had always fascinated me.

I started with the text token system, then worked out the split-screen mode, and then moved on to the universe generation... and by then I was completely hooked. Every little step forward, I felt like I was unpicking a bit more of the story of two young developers creating a modern-day masterpiece; if you squint carefully, you can almost sense where the whole starts to become greater than the sum of the parts. Elite is the coding equivalent of A Day in the Life, a mash-up between the Acorn world's very own Lennon and McCartney, with results that are just as seminal in their field. They say you should never meet your heroes, but grokking their source code... well, that's another matter altogether.

This site and its accompanying repository are the results. The aim is that anyone with a basic knowledge of 6502 assembly language and simple trigonometry will be able to read through the source code and not only understand what's going on, but will also be able appreciate the beauty and elegance of this exceptional piece of 1980s programming.

For comparison, this is what the LL145 code block above now looks like, and this is the fully annotated LL42 rotation matrix code. I think it's a bit easier to understand now.

It has been a privilege to unravel the intricacies of Elite. I hope you enjoy the ride.

Next steps for this project
---------------------------

This project is a work in progress. Here are my current plans:

  • The commentary needs tidying up and clarifying in places - as it stands, this whole thing is basically a first draft that needs a fair amount of editing. There are one or two areas where the code is documented in terms of explaining what the code does, but I'm still trying to get my head around exactly how it works, so those areas still need addressing.
  • I'm going to write more deep dive articles, as well as expanding the ones that are there. There is so much more to say about this masterpiece, from explaining the program flow to analysing how much of the code is devoted to each type of functionality.
  • I'm also hoping to analyse the disc and 6502 Second Processor versions, so I can document the code that differs from the cassette version. That's a longer-term goal, though - first, I need to get the cassette version polished up, but for now there's a GitHub repository containing a buildable version of 6502 Second Processor Elite that you can play with.

Watch this space!