Skip to content

A reverse-engineering of Speedball 2 for the Sega Megadrive

Notifications You must be signed in to change notification settings

simon-frankau/speedball2-re

Repository files navigation

Reverse engineering of Speedball 2 for Sega Megadrive (Genesis)

This repo is a reverse engineering of Speedball 2, using Ghidra to reverse the assembly. Graphics, sound, etc. are extracted by with some tools I wrote in Rust.

It's an absolute classic of a game, and I'd always kinda wondered how it was put together, how the AI works, etc. So, why not find out?

I chose the Megadrive version not only because that's the version that I played, but because the image would be a direct ROM mapping, and the hardware involved looked relatively tractable. It gave me a great excuse to learn how the Megadrive hardware worked (and I'd love to give a great shout-out to the excellent "GenesisSoftwareManual.pdf" that the internet provided me with). I also didn't need to worry about any fancy disk image loading, which took away an initial hurdle.

In many ways, the ideal version would have been the Amiga version, with a nicer playing pitch, the famous "Ice cream!" sample, and generally more sensible audio. There's a bunch of code in the Megadrive sound subsystem that only makes sense in terms of a port from another platform. In other areas, there's dead code that looks like it was never removed from a porting effort. On the other hand, this is all evidence that as a 68K Speedball 2, it shares a lot of heritage with the Amiga version, so perhaps not all is lost.

This is not a perfect reversing - I wanted to get something out, after all this messing around, so here it is, with a first pass on all the (reachable) code, but not everything completely worked out.

My approach was to attack the code from a few angles - the ROM entry point, the obvious graphics resources, code that referenced hardware and/or those resources, etc. It was fun watching Ghidra trying to work out what was code and what wasn't. There aren't a huge number of function pointers, but it took quite a while to identify all the code nonetheless.

To simplify, my approach roughly proceeded in stages:

  • Work through all the accesses to the GDP that I could find, as well as other hardware accesses, interrupt handlers, etc. By understanding all the places where the code touches the outside world, you can get a handle on what it's trying to achieve. This also helped me get a start on the practical side of GDP programming.
  • Understand the title sequence, and associated splash screens/backdrops. Relatively straightforward code to ramp up on, but it includes an interesting little decompression algorithm.
  • Pull apart the sound subsystem, which includes both the sequencer and sample-player (with a short excursion into the Z80 sound coprocessor!).
  • Menus and training screens - non-game code uses its own sprite display system, so this involved reversing that, and from there the training screens and so on revealed the structures for player stats etc.
  • The core match loop. This included a second set of sprite-display routines, and the code to run the match and update the various game entities, leaving until last...
  • The player routines. I started with the user-controlled player routines; how pressing buttons on the keypad makes your selected player behave. From there I incrementally worked my way through the game's AI, which includes distinct logic for the active player and the rest of the team, and special code for the goalies.

And that, I think pulls apart the whole game. It was a fascinating journey for me, I don't know if anyone else will enjoy reading it!

The notes I made along the way are in NOTES.md. They're a bit out of date right now. Indeed, there are lots of loose ends, documented in TODOs.md. Maybe I'll tidy them up when I've recovered a bit from the first pass!

The tools I built along the way are documented in tools/README.md.

About

A reverse-engineering of Speedball 2 for the Sega Megadrive

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published