Reverse Engineering
The Great Escape
BY DAVID THOMAS

Never Heard of It

  • Prison break game for the 48K ZX Spectrum

  • Created in my home town of Liverpool by Denton Designs

  • Released in 1986 by Ocean

  • One of the best-regarded Spectrum games

  • Later ported to the PC, Amstrad CPC & Commodore C64

  • Sequel: Where Time Stood Still

Specify Sinclair Spectrum Specifications

  • 8-bit Z80A CPU at 3.5MHz

  • 16K of ROM

  • 16- or 48K of RAM

  • Single fixed screen resolution of 256x192 with up to 15 colours

  • Built-in beeper for music and sound effects

  • Cassette tape storage

    • ≈ 1400 baud, taking around five minutes to load a game

As with most systems of this generation, games with any sort of performance expectations had to be written in Z80 assembly language.

SHOW THEM THE GAME DAVE

DAVE SHOW THEM THE GAME

SHOW THEM DAVE THE GAME

Rippity Doo-Dah: Pull the Game Apart

How do we get started?

  • Dump game memory out

    • Use .SNA format: Header + Straight dump of RAM

  • Use graphics ripper to locate any graphics

    • Sprites: pairs of bitmaps & masks

    • Font glyphs: usually 8x8 bitmaps

  • Use hex dump to find non-graphic data

    • ASCII strings

    • Lookup tables (tables of flipped bytes etc.)

  • Rule of thumb when looking at game memory:

    • Patterns are probably data, noise is probably code

Commence Disassemblifications

Start disassembling the game

  • IDA Pro

    • An interactive disassembler

    • Handles Z80 assembly language (among many)

    • Analyses the binary to find funcs

    • Call graphs

    • Magic decompilation to C

    • Eye wateringly expensive (work had a copy)

  • In practice it kept crashing

    • No undo (!)

    • Wrote a script to automate the marking up

START REVERSING

  • Ideally: Pick a func and pull it apart, then repeat

  • Look for hardware access (keyboard, joystick, sound)

  • Follow those funcs upwards to find the main game loop

  • Expect:

    • "Get player input"

    • "Move hero"

    • "Move enemies"

    • "Play a sound"

    • "Wipe last frame"

    • "Draw new frame"

    • "Wait"

Fog O' War

Which locations are genuine instructions?

  • Run RZX recording of complete play-through of the game with profiling enabled through FUSE

  • The profile spat out must be real instrs

  • Capture this profile in IDA Pro as comments

SkoolKit

  • Richard Dymond had pulled apart Speccy classics

    • Skool Daze, Back To Skool & Contact Sam Cruise

  • ...and built a toolkit called SkoolKit to help out

  • From a single '.skool' file SkoolKit can output

    • assembly listings

    • game snapshots

    • entire cross-referenced HTML disassemblies

  • Written in Python and scriptable:

    • Generate images of game assets, e.g.

      • Dumps of the game map and the rooms

      • Even animations from within the game

    • Game-specific macros

SkoolKit WORKFLOW

REVERSING FUNCTIONS

  • Discoveries about one function usually impact elsewhere
    • Expect to move around the disassembly a lot
  • Function boundaries can be unclear in hand crafted code:
    • Multiple entry points
    • Fallthrough (no RET...)
    • Funcs buried in other funcs
  • Even late in the process I was changing my mind about what constituted a complete function

Semantic Hoisting (Explaining Stuff)

  • Point of the project is to explain the game's workings

    • Binary > Raw asm > Commented asm > What?

    • My approach: Write C-style pseudocode of game logic

  • Register de-allocation

    • Initially our vars are just regs

    • Analyse vars' lifetimes

    • Create new vars from regs to explain the intent

  • Return types

    • Must survey all callers of a func and decide if values left in regs really are used

  • Good old self modifying code

    • Replace with vars in a (pretend) state structure

A Portable TGE Emerges

  • With suitable pummeling my C-style pseudocode eventually becomes compilable

  • Marshalled it into C files in a macOS Xcode project and added a virtual ZX Spectrum: screen, keyboard, etc.

    • The resultant code becomes The Great Escape in C

  • Work carries on in parallel with the disassembly project

    • The C version forces questions to be answered!

    • Feed back those discoveries in to the disassembly

  • C version has since been ported to macOS, Windows, SDL and recently RISC OS

  • Eventually delete all of the C-style pseudocode and rewrite the whole disassembly in plain ish English

IT BE DEMO TIME

IT BE DEMO TIME

IT BE DEMO TIME

IT BE DEMO TIME

IT BE DEMO TIME

#DEMOTIME

Game DISCOVERIES

  • Wah 😭

    • You can't get up on the battlements

    • The secret doors don't go anywhere

    • There are no secret rooms

    • The radio has no use

  • A cast of 27:

    • Our hero and six active prisoners

      • vs.

    • Fifteen guards, four dogs and the commandant

  • There's nothing really higher up on the map (it's blank)

  • BUT

    • You can escape through the main gate!

TECH DISCOVERIES

  • The game screen is double buffered for scrolling

    • Can cause lumpy performance due to byte rolls

  • The exterior map encoding is pretty cunning

    • Map defn > 32x32 Supertiles > 8x8 Tiles

    • Fits in <10K

  • Movable objects are 'people' too

    • Have you never bribed a boiler?

  • A max of eight characters on-screen simultaneously

    • From a cast of 27

  • Various bugs spotted just by reading the code

    •  Sprite glitches too

  • Entire game never uses the Z80's IX register

U Wot U Wot Star Dot

  • So... how about a Beeb port?

  • C64 version is already in 6502

Thanks For Listening To My Crazed Rantings

The Great Escape game entry on World of Spectrum:
http://www.worldofspectrum.org/infoseekid.cgi?id=0002125

Write-up on my site:
http://www.davespace.co.uk/the.great.escape/

Reverse engineering project on github:
https://github.com/dpt/The-Great-Escape

The cross-referenced disassembly output from above: http://dpt.github.io/The-Great-Escape/

Rebuild in C project on github:
https://github.com/dpt/The-Great-Escape-in-C

Stardot thread where RISC OS beta builds are pooed: https://stardot.org.uk/forums/viewtopic.php?f=53&t=18826

The Great Escape (for Stardot talk)

By David Thomas

The Great Escape (for Stardot talk)

Reverse engineering the classic isometric 1986 ZX Spectrum game "The Great Escape".

  • 781
Loading comments...

More from David Thomas