← Back
dparnell

dparnell/newton-re

Reverse Engineering the Newton 2x00 ROM

View on GitHub ↗
Stars
3
Forks
0
Watchers
3
Open issues
0
Contributors
1
Language
C++
License
—
Default branch
main
Created Oct 1, 2026Updated Oct 1, 2026

Star growth

Today—
This week—
This month—

Star history will appear here once this repo has been tracked for a couple of days.

README

Newton MessagePad 2x00 ROM reverse engineering

Reverse engineering of the Apple Newton MessagePad 2x00 ROM, with the long-term goal of a retargetable, maintainable re-implementation of Newton OS. Two debug ROMs are in the repository and the tooling works with either; the reconstruction in src/ is of the US English one, MP2x00 US (2.1, build 717006). The other, MP2100 D (D-2.1, build 747129), is the newer operating system but a German one, with no English locale and German strings built into the applications in its ROM extension, so it is kept as a second opinion rather than as the subject.

Where it has got to

The reconstructed Newton OS boots and runs without a ROM image. By default newton boots from data built from the committed, editable romsrc/ tree - the ROM's NewtonScript world as decompiled source, its bitmaps, sounds, fonts, dictionaries and tables as ordinary files - and the reconstructed C++ in src/. The ROM images in DebugRom/ are only needed to check the reconstruction against the original (--rom) and to run the analysis tools.

Build it and run it:

cmake -G Ninja -S src -B build/host -DCMAKE_TOOLCHAIN_FILE=%CD%/src/cmake/zig-toolchain.cmake
cmake --build build/host
build\host\host\newton --store my.store

On Linux use the system compiler instead (cmake -G Ninja -S src -B build/host -DCMAKE_CXX_COMPILER=clang++; newton wants the X11 and ALSA development headers). The build makes build/host/romsrc-objects.bin from romsrc/ with Python and the reconstruction's own NewtonScript compiler; no ROM image is read.

newton opens a window on the Newton's screen - the mouse is the pen, the keyboard the keyboard - and the machine starts as a new MessagePad does: the Setup assistant, then the Notepad. Useful options:

Option What it does
--store FILE keep the internal store (flash) in a file, so notes, settings and installed packages survive; a new one is a 64 MB sparse image
--display WxH a screen of any size, e.g. 1024x768; a wider window starts in landscape
--package FILE.pkg install a package (or drop one onto the window)
--card FILE a PC Card (memory or ATA) from a host image
--ipp-printer URI print to a network printer by IPP (printers can also be found and added from the Newton itself)
--rom IMAGE boot the original ROM image instead, for comparison

Handwriting is read by both of the ROM's recognisers, ink is kept, the built-in applications work, packages install (third-party native ARM code runs on a built-in ARM interpreter), and the Newton beams, docks with a desktop over TCP port 3679, faxes, prints (PostScript and HP PCL, by IPP) and reaches the Internet through the host's own network. What each part does and what is still NOT YET is in docs/ - docs/newt/README.md for the boot, and docs/next-steps.md for what is left.

Run the tests with ctest --test-dir build/host (about 400 of them; a build without the ROM image simply skips the few that compare against it).

Contents

Path What it is
DebugRom/ Debug ROM images (... image, AIF format with symbol table) and ROM extensions (... high) for the MP2100 D (2001) and MP2x00 US (1997) - not needed to boot; used to check the reconstruction against the original and by the analysis tools
headers/ C/C++ headers from the Newton Driver Developer Kit (DDK): kernel (OS600), Frames object model, CommAPI, PCMCIA, QD, UtilityClasses, … — the primary source of struct/class layouts for reconstruction (classic Mac CR line endings)
documentation/ Newton Programmer's Guide / Reference, NewtonScript language and bytecode specs
tools/newton-rom/ Our tooling: ROM extraction, demangling, Ghidra import — see its README
src/ The reconstruction itself, organised by functional area and buildable on a host — see src/README.md
romsrc/ The ROM's NewtonScript world and resources as editable source, built into what newton boots — see romsrc/README.md
fixtures/packages/ Third-party Newton packages the tests install and use
docs/ Reverse-engineering notes per subsystem, starting with the kernel (docs/os600); generated tables are marked as such
docs/curiosities.md The findings worth telling somebody about: clever tricks, shipped bugs, and the compiler idioms that are easy to misread
docs/next-steps.md Where the last piece of work left off and what is obviously next, with the groundwork already read out of the ROM
tools/mpdumper/ Alexey Danilchenko's 2004 symbol dumper (libiberty demangler) and its pre-generated symbol listings for the US ROM; used as the reference oracle for our demangler

Reproducing the Ghidra project

Requirements: Python 3.9+, Ghidra 11.3+ (we use 12.1.3) and a JDK 21 for it.

python -m venv build\venv
build\venv\Scripts\pip install -r tools\newton-rom\requirements.txt
build\venv\Scripts\pip install --no-index --find-links "<ghidra>\Ghidra\Features\PyGhidra\pypkg\dist" pyghidra
build\venv\Scripts\python tools\newton-rom\pipeline.py "DebugRom\MP2x00 US" -o build\MP2x00US --ghidra <ghidra> --name MP2x00US

Result: build/ghidra/MP2x00US.gpr, a Ghidra project of the ROM as the CPU sees it, with ~35,000 functions named and placed in ~1,050 C++ class namespaces, 16,000+ prototypes (1,500 of them complete with return types and parameter names from the DDK headers), the DDK's ~250 structs/classes and 60 enums as Ghidra data types, class sizes and vtables recovered from the constructors (and checked against the headers), and the patchable jump table resolved to thunks. Details, the memory layout, and the analysis behind it are in tools/newton-rom/README.md.

Run the tests with python tools/newton-rom/tests/test_demangle.py, python tools/newton-rom/tests/test_rom.py and (with libclang installed) python tools/newton-rom/tests/test_headers.py.

Project rules

  • Every tool used in the process lives in this repository under tools/, is documented (purpose, inputs, outputs, exact invocation) and is runnable from a clean checkout so that others can reproduce each step.
  • Findings about the ROM (layout, tables, conventions) are recorded in the tool READMEs and, where possible, asserted by tests against the images.