Skip to content

Instantly share code, notes, and snippets.

@vitorio
Created January 9, 2025 02:19
Show Gist options
  • Save vitorio/4e5d8de0db5c56b6816b95817c207b09 to your computer and use it in GitHub Desktop.
Save vitorio/4e5d8de0db5c56b6816b95817c207b09 to your computer and use it in GitHub Desktop.
Still Life with Emulator (Vitorio's Version)

In 2013, I created the cross-compilation infrastructure to thin a large C/C++ codebase and translate vertical slices to JavaScript for presentation on the web.

The project was called JSMESS. It divvied up the monolithic MESS and MAME emulators, each a large C/C++ codebase for emulating hundreds of hardware platforms in a single binary, into just enough code to run individual vintage computers and arcade games, and it was one of the earliest large-scale uses of Emscripten, the LLVM WebAssembly toolchain.

The narrative version of this gist is online here, as an archived Twitter thread:

The project started in October 2011, with the goal of making vintage software as easy to experience on the web as a YouTube video. Paul Ford wrote a nice, lay-accessible introduction for the United Airlines in-flight magazine in May 2013, shortly before I joined and all of this transpired:

In early August 2013, I spent around 40 hours figuring out how to cross-compile just enough files to get the Canon Cat (Jef Raskin's post-Macintosh project) emulation working. This worklog was my entire process for figuring that out, and then replicated twice more for two different systems. This document began to allow for new systems to be brought online (by hand) in hours instead of days or weeks.

A repeatable process is an automatable process, though, and a colleague pointed out that I was basically manually performing the functions of a linker. So, first, I documented the process to automate the discovery steps, followed by writing a shell script to do it:

Next, actual automation, starting with documenting how to more robustly extract all the dependencies each system might rely on and resolving all their mangled function names; then, a new shell script to use those intermediate files to build a makefile almost entirely on its own, and the documentation for it:

This was the result of another 60 hours of work. You'll notice a caveat at the end of the tool's output in the documentation:

You may need to edit ../mess/src/mess/atari400.mak to add 'CPUS +=' lines, or to set up layout files.

There was still a bit of manual labor to be done for some systems, but this didn't stop the Internet Archive from throwing a party and unveiling thousands of vintage software programs as being newly available on the web. I continued working with the project to support arcade machines into the following year. This included better integration with the upstream MESS and MAME projects: they had master lists of CPUs and other devices that they weren't being very diligent about keeping up-to-date, and relying on these files made it more likely they would be kept in sync, eliminating any final manual steps.

I also drove a lot of the testing for audio improvements, resulting in a clear path for another developer to understand and resolve many of our audio issues. Being able to "bag and tag" releases, more readily add JavaScript-side callbacks from running emulations, and reliably document issues for reproduction drove a lot of improvements in the upstream Emscripten project. The success of JSMESS overall led the parent MESS and MAME projects to support JavaScript cross-compilation in-house, deprecating all of this code two years later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment