From DOS Binary to Playdate — Lemmings Preservation Port
The finished port in motion — native Playdate presentation built on preserved DOS data and a clean portable engine.
This document explains how a 1991 DOS game was studied and rebuilt as a highly faithful game for the Playdate handheld. It is written for readers who may be new to programming, reverse engineering, emulation, or game preservation.
The most important fact to understand is this:
“The Playdate game is not the original DOS program running inside an emulator, and it is not decompiled DOS code compiled for a new machine. It is a new, portable game engine written in C, guided by evidence from the original executable and driven by data converted from an owner-supplied copy of the DOS game.
That distinction explains both the technical approach and the quality of the result. The project preserved the parts that needed to remain exact—levels, masks, sprites, animation data, music commands, timing relationships, and many gameplay constants—while rewriting the platform-specific machinery for a modern one-bit handheld.
The finished port includes all 120 one-player levels in Fun, Tricky, Taxing, and Mayhem order; the complete skill set; mutable terrain; traps; progression and saved games; native Playdate menus and controls; exact 2× gameplay presentation; real-time AdLib synthesis; sound effects; and device-specific audio and storage optimizations.
1. The basic ideas
Before following the project, it helps to define a few terms.
Source code
Source code is the human-readable program written by a developer. C source might contain a line such as:
lemming->state = LP_STATE_FALL;
A compiler translates source code into machine code: numeric instructions that a processor can execute.
Machine code and executables
Machine code is designed for a particular processor. The DOS version of Lemmings contains 16-bit Intel x86 machine code. Playdate uses a very different ARM processor. The DOS instructions therefore cannot simply be copied into a Playdate application.
An executable is a file containing machine code plus information needed to load and run it. The DOS VGA program used here is an MZ executable, a common DOS executable format.
Assembly and disassembly
Assembly language is a readable notation for machine instructions. A disassembler turns machine-code bytes into assembly instructions. It can show that a value is loaded, compared, or written, but it usually cannot recover the original variable names, comments, file organization, or programmer intent.
Decompilation
A decompiler tries to turn machine instructions into higher-level pseudocode resembling C. This can make control flow easier to understand, but the result is an interpretation—not the original source code.
Compilation throws information away. A function once named UpdateFallingLemming may appear as FUN_1234. A meaningful structure may look like unrelated array offsets. Several original statements may become one instruction sequence, or one source operation may expand into many instructions.
This is why decompilation is the start of an investigation, not a button that restores a project.
Reverse engineering
Reverse engineering is the larger process of learning how a system works from its observable artifacts. It may use:
File-format inspection
Disassembly and decompilation
Controlled experiments in the original game
Comparisons between versions
Memory and register traces
Timing measurements
Tests of competing explanations
A port
A port adapts software to another platform. A faithful port preserves the important behavior and content while replacing assumptions that only made sense on the original machine.
Emulation
An emulator imitates another machine. For example, DOSBox emulates enough of a DOS-era PC to run the original executable. This project does not emulate a complete PC. It does, however, use a focused OPL2 emulator to recreate the AdLib sound chip. That is a small, deliberate form of component emulation inside an otherwise native port.
A clean implementation
The new engine was written as modern, portable C. The original executable was treated as private behavioral evidence rather than copied, translated, or linked into the port. Decompiled output stayed in a private workspace. Public code expresses independently written rules and interfaces.
This is sometimes described as a clean-room-style boundary. The important practical rule was simple: record facts about behavior and formats, then implement those facts cleanly in the new engine.
2. The project at a glance
The workflow has four main layers:
Owner-supplied DOS files<br>+--> checksums and preservation notes<br>+--> executable unpacking, disassembly, and private Ghidra analysis<br>| |<br>| +--> behavioral facts<br>+--> deterministic asset converter --> lemmings.lpd<br>New portable C engine + Playdate adapter ----------+--> Lemmings.pdx<br>ADLIB.DAT command image + DBOPL -------------------+--> real-time music
The...