SearchA-ZA › Analytical Engine

Analytical Engine

1837 Open source · Public domain Authored core · open Online

The Analytical Engine, designed by Charles Babbage from 1837, was the first design for a general-purpose, programmable computer — a steam-powered machine of brass and steel, a century before electronics. This is a faithful authored model of it in pure JavaScript. It has the three parts Babbage designed: the Mill (the arithmetic unit, with two ingress axes, an egress axis and the run-up lever that lets it branch), the Store (a rank of columns each holding one signed 50-digit decimal number), and the card streams (woven Operation and Variable punched cards that are the program). It boots running a demo card program and prints the result. The whole engine is drawn to the screen, and every part is exposed to the debugger so you can single-step the card reader one card at a time.

John Walker's fourmilab Analytical Engine resource ↗

Visit the official site ↗

Runs on: Web browser

Analytical Engine Online Emulator

Play Analytical Engine using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Factorial (6!)Analytical EngineAnalytical EngineopenOpen ⛶
Triangular sum (1..N)Analytical EngineAnalytical EngineopenOpen ⛶
Powers of two (2^N)Analytical EngineAnalytical EngineopenOpen ⛶

Notes

Embedding

The Analytical Engine here is authored from scratch in one small file, analytical.js. It is a plain global — AnalyticalEngine.create(canvas) returns a machine object whose whole state (Mill, Store and card chain) is ordinary JavaScript, so the debugger reaches straight into it with no wasm heap and no hidden loop.

Boot. Create the engine on a <canvas>, load a program (a chain of cards plus the initial Store), then run your own loop built on ae.step() (turn the engine by exactly one card):

var ae = AnalyticalEngine.create(canvas);
ae.load({ store:{0:6, 1:1, 2:1}, cards:[
  {k:K.OP, op:'multiply'}, {k:K.LOAD, col:1}, {k:K.LOAD, col:0}, {k:K.STORE, col:1},
  /* ... decrement the counter, test the run-up lever, loop ... */
]});
(function turn(){
  var r = ae.step();               // 'ok' | 'halt' — one card
  ae.render();
  if (r !== 'halt') requestAnimationFrame(turn);
})();

The engine is plain fields. Everything the debugger needs is live on the object:

MemberKindWhat it does
ae.step()methodTurn the engine by exactly one card; returns 'ok' or 'halt'. The single-step primitive.
ae.ingress · ae.egressfieldsThe Mill's two ingress axes and its egress axis (signed BigInt, mod 1050).
ae.runUpfieldThe run-up lever: set when an addition overflows fifty digits or a subtraction runs below zero — the one conditional-branch flag.
ae.cardIndexfieldThe card reader's position in the chain (the program counter).
ae.peekColumn(c) · ae.pokeColumn(c,v)methodsSide-effect-free read / write of a Store column — used by the debugger.
ae.onWrite(col,v)hookCalled on every Store write; the boot uses it to implement watchpoints.

Because the Mill, Store and card reader are ordinary JavaScript, breakpoints are a host-side Set of card indices checked before each step(), and watchpoints are checked inside onWrite — no changes to the core.

Debugger integration

The plug-in (analytical-engine-debug.js) describes the engine to the shared debugger, and a new CPU decoder (debugger/src/cpus/analytical.js) makes the card chain readable. The Analytical Engine has no bytes and no opcodes, so this is an unusual but faithful mapping:

  • The card chain is the program. The "disassembly" view decodes one card per address instead of one byte: Operation cards (+ − × ÷), Variable cards (L07 supply, Z07 supply-and-zero, S05 store) and combinatorial cards (CF?3 / CB?3 run the chain forward/back if the run-up lever is set). Anything unrecognised decodes to .card.
  • Registers are the Mill: the two INGR ingress axes, the EGRESS axis, the CARD reader index, and the RUN-UP lever and HALT flags — read live and written back each refresh. (The register inputs show the low 32 bits; the canvas shows the full fifty digits.)
  • Single step is one ae.step() — the card reader advances by one card. Breakpoints are host-side checks on the card index (click a card in the disassembly gutter); watchpoints fire inside onWrite when a watched Store column is written.
  • Like cpus/mix.js, the decoder cannot express a structured card through the byte-masked reader the view provides, so it reads the real card off the live core (window.EMU_BOOT.ae.cards) and falls back to a one-byte kind code only when the core is absent.

Architecture

Charles Babbage designed the Analytical Engine from 1837: a steam-powered, general-purpose mechanical computer, programmed with Jacquard punched cards. It was never built in his lifetime, but its design already had the parts of a modern computer:

  • The Mill — the arithmetic unit ("processor"). Numbers are brought in on two ingress axes, an operation (add, subtract, multiply, divide) is performed, and the result is left on the egress axis. A run-up lever runs up when a result overflows fifty digits or a subtraction goes below zero; testing it is how the engine branches.
  • The Store — the memory: a rank of columns of geared wheels, each column holding one signed 50-digit decimal number (a "Variable", V0, V1, …). Babbage planned around a thousand columns.
  • The Cards — the program, on two woven streams: Operation cards choose the mill's operation, Variable cards name which Store column to read into the mill or write the result back to. Combinatorial cards back up or run forward the card chain — the conditional loop.
  • The printing apparatus — results were to be set in type and printed automatically, or drawn as curves.

In 1843 Ada Lovelace, translating Menabrea's account of the engine, appended her own Notes — including Note G, a card program to compute the Bernoulli numbers. It is regarded as the first published computer algorithm. The demos here are small loops in the same style: a counter in the Store, the mill folding a running result, and a combinatorial card testing the run-up lever to close the loop.