Skip to navigation

BBC Micro Elite

The Elite memory map

A map of memory usage, details of unused memory locations, and notes on BBC Micro and Acorn Atom label names

References: ZP, XX3, T%, QQ18, K%, WP, S%, XX21, SHIP4
The cassette version of Elite uses almost every nook and cranny of the BBC
Micro Model B, which isn't surprising when you consider just how much the
authors managed to squeeze into this 32K micro. Sure, the disc version of the
game has more features, but that's because the main game code is split into
two different programs, one that's loaded when you're docked and another
that's loaded for spaceflight. The cassette version that's documented here
doesn't have the luxury of fast loading - quite the opposite, in fact - so it
has to cram the whole game into memory, all at once. It's an absolute marvel
of efficiency.

When the cassette version of Elite is loaded, this is how the memory map of
the BBC Micro Model B looks.

    +-----------------------------------+   &FFFF
    |                                   |
    | Machine Operating System (MOS)    |
    |                                   |
    +-----------------------------------+   &C000
    |                                   |
    | Paged ROMs                        |
    |                                   |
    +-----------------------------------+   &8000
    |                                   |
    | Python blueprint (PYTHON.bin)     |
    |                                   |
    +-----------------------------------+   &7F00 = SHIP4
    |                                   |
    | Memory for the split-screen mode  |
    |                                   |
    +-----------------------------------+   &6000
    |                                   |
    | Ship blueprints (SHIPS.bin)       |
    |                                   |
    +-----------------------------------+   &563A = XX21
    |                                   |
    | Main game code (ELTcode.bin)      |
    |                                   |
    +-----------------------------------+   &0F40 = S%
    |                                   |
    | &0F34-&0F40 unused                |
    |                                   |
    +-----------------------------------+   &0F34
    |                                   |
    | WP workspace                      |
    |                                   |
    +-----------------------------------+   &0D40 = WP
    |                                   |
    | Ship line heap descends from WP   |
    |                                   |
    +-----------------------------------+   SLSP
    |                                   |
    .                                   .
    .                                   .
    .                                   .
    .                                   .
    .                                   .
    |                                   |
    +-----------------------------------+   INF
    |                                   |
    | Ship data blocks ascend from K%   |
    |                                   |
    +-----------------------------------+   &0900 = K%
    |                                   |
    | Page 8 MOS sound/printer space    |
    |                                   |
    +-----------------------------------+   &0800
    |                                   |
    | Recursive tokens (WORDS9.bin)     |
    |                                   |
    +-----------------------------------+   &0400 = QQ18
    |                                   |
    | Page 3 MOS tape system workspace  |
    |                                   |
    +-----------------------------------+   &0372
    |                                   |
    | T% workspace                      |
    |                                   |
    +-----------------------------------+   &0300 = T%
    |                                   |
    | Page 2 MOS workspace              |
    |                                   |
    +-----------------------------------+   &0200
    |                                   |
    | 6502 stack descends from &01FF    |
    |                                   |
    +-----------------------------------+
    |                                   |
    .                                   .
    .                                   .
    .                                   .
    .                                   .
    .                                   .
    |                                   |
    +-----------------------------------+
    |                                   |
    | Heap space ascends from XX3       |
    |                                   |
    +-----------------------------------+   &0100 = XX3
    |                                   |
    | Zero page workspace               |
    |                                   |
    +-----------------------------------+   &0000 = ZP

This memory map shows the full 64K of addressable memory that's supported by
the BBC's 6502 processor, but only the bottom 32K is writable RAM, and hence
usable by Elite. The top 16K is mapped to the MOS (Machine operating system)
ROM, and the next 16K is mapped to the currently selected paged ROM, which
might be anything from BBC Basic to the VIEW word processor.

This 32K of RAM includes both screen memory and the various operating system
workspaces, which can leave a pretty small amount for programs (especially in
high resolution screen modes). Let's take a look at how the authors managed to
shoehorn their game into such a small amount of memory.

Memory usage
------------
Here's a full breakdown of memory usage in bytes, once the cassette version of
Elite is loaded and running:

                                                               Used     Unused

  Machine operating system (MOS) ROM                         16,384          -
  Paged ROMs                                                 16,384          -
  MOS general workspace in page 2                               256          -
  MOS sound and printer workspace in page 8                     256          -
  MOS tape filing system workspace in page 3                    142          -
  MOS zero page locations, &B0-&D0 and &E2-&FF inclusive         63          -
                                                             ------     ------
                              Total MOS and ROM memory       33,485          -


  Memory for the split-screen mode (31 rows of 256 bytes)     7,936          -
  6502 stack and XX3 heap space (at opposite ends of page 1)    256          -
                                                             ------     ------
                              Total shared memory             8,192          -


  Main game code                                             18,136         34
  Ship blueprints (11 different designs, all except Python)   2,502          -
  K% workspace (ship data blocks and line heaps)              1,088          -
  Game text (recursive token table)                           1,023          1
  WP workspace (ship slots, variables)                          499         13
  Python ship blueprint and SVN, VEC variables                  245         11
  Zero page workspace (INWK workspace, variables)               192          1
  T% workspace (current commander data, stardust data)          108          6
                                                             ------     ------
                              Total game code memory         23,793         66


                              Total memory                   65,536

As you can see - and contrary to popular legend - Elite does not use every
single last byte of the BBC Micro's usable memory. There are actually quite a
few unused bytes in the cassette version, as noted in the "Unused" column
above; 66 of them, to be precise. Here are the details, in the order in which
they appear above:

  * In the main game code:

    * There are six unused bytes in the last saved commander data at NA%. Two
      of them are between LASER and CRGO, just after the four laser powers;
      they were originally used for up and down lasers, but those views were
      dropped and the space never reclaimed. There are four more unused bytes
      between the escape pod at ESCP and the cargo bay capacity at CRGO, which
      might have been for additional equipment that didn't get implemented...
      who knows?

    * There's an unused and unlabelled duplicate of the multiplication routine
      MULTU sandwiched between FMLTU and MLTU2 that takes up 24 bytes

    * The MUT3 routine is never called and would be identical to MUT2 even if
      it were, so that's another four bytes that aren't used

  * In the recursive token table at QQ18:

    * There is one unused byte at &07FF, right at the end of the table

  * In the WP workspace:

    * The one-byte variable XX24 is never used

    * There are 12 bytes at the end of the WP workspace, from &0F34 to &0F40,
      which aren't used

  * In the Python workspace:

    * There are 11 unused bytes between the end of the Python ship blueprint
      and the SVN and VEC variables, right at the top of user memory

  * In the zero page workspace:

    * The one-byte variable XX14 is never used

  * In the T% workspace:

    * There are six unused bytes in the current commander data block at T%,
      which correspond with the unused bytes in the last saved commander data
      block at NA% (see above)

On top of this, there are quite a few instructions in the main game code that
have no effect and could have been culled without impact; I've identified 20
of them, but there are no doubt more of them to find (search the comments for
"no effect" to find the ones I've spotted).

But this is splitting hairs, as Elite swells the BBC Micro to near bursting
point while being both incredibly clever and incredibly efficient, and for
that, very serious respect is due to the authors.

Shared locations
----------------
Some locations have two names in the source code. This is partly because some
of the code was developed on an Acorn Atom, which restricts the names you can
use for labels to two letters followed by one or more numbers. Presumably when
this code was merged with the code that was developed on a BBC Micro, where
label naming is more flexible, it was easier just to share label names than
refactor the Atom code.

The following label names point to the same locations in memory, and are
therefore interchangeable:

  LOIN        = LL30
  INWK        = XX1
  INWK(34 33) = XX19(1 0)
  X1          = XX15
  Y1          = XX15+1
  X2          = XX15+2
  Y2          = XX15+3
  K5          = XX18         = QQ17
  K3          = XX2
  LSO         = LSX
  CABTMP      = MANY

The last one is slightly different, in that the first byte of the MANY table
is unused, so CABTMP simply makes the most of the otherwise unused location.