SearchA-ZC › Curta

Curta

1948 Open source · CC0-1.0 Authored core · open Online

An authored, in-browser model of the Curta Type I, the hand-cranked mechanical pocket calculator designed by Curt Herzstark and first produced in 1948 — a masterpiece of miniature gearing nicknamed "the math grenade". The Curta has no CPU; it is a precision gear machine, and this is a faithful model of the mechanism itself: the eight setting sliders (the number you dial in), the crank (one turn adds the setting into the answer), the liftable, rotatable carriage, and the two counter rings — the 11-digit results counter and the 6-digit turns counter — driven by a single stepped drum with complementary-nine teeth for subtraction.

It plugs into the shared debugger through a new curta decoder that reads the machine's operation tape — one hand action per step (dial a slider, crank to add or subtract, shift the carriage, clear a ring) — with single-operation step, execution breakpoints on the tape, and write watchpoints on the results-counter digits. It boots at rest, all rings zero, with a demo tape loaded that computes 7 × 6 = 42.

Visit the official site ↗

Runs on: Web browser

Curta Online Emulator

Play Curta using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Multiply 7 × 6 = 42CurtaCurtaopenOpen ⛶
Multiply 12 × 34 = 408 (carriage shift)CurtaCurtaopenOpen ⛶
Subtract 100 − 37 = 63 (nine's complement)CurtaCurtaopenOpen ⛶

Machines emulated

Notes

Embedding

The Curta here is authored from scratch in one small file, curta.js. It is a plain global — Curta.create(canvas) returns a machine object whose whole mechanical state (setting sliders, results and turns counters, carriage) is ordinary JavaScript, so the debugger reaches straight into it with no wasm heap and no hidden loop.

Boot. Create the machine on a <canvas>, load an operation tape (a list of hand actions), and it sits at rest, all rings zero. Then either run your own loop over curta.step() (advance the tape by one action) or drive it live with curta.perform(op) from the keypad:

var curta = Curta.create(canvas);
var OP = Curta.OP;
curta.load([                          // 7 × 6 = 42
  {op:OP.SET, pos:0, d:7},              // dial the units slider to 7
  {op:OP.ADD},{op:OP.ADD},{op:OP.ADD},   // turn the crank ...
  {op:OP.ADD},{op:OP.ADD},{op:OP.ADD}    // ... six times
]);
(function turn(){
  var r = curta.step();             // 'ok' | 'end' — one hand action
  curta.render();
  if (r !== 'end') requestAnimationFrame(turn);
})();

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

MemberKindWhat it does
curta.step()methodAdvance the operation tape by exactly one action; returns 'ok' or 'end'. The single-step primitive.
curta.perform(op)methodRecord a live hand action onto the tape and execute it at once — the keypad path.
curta.setting · curta.result · curta.turnsfieldsThe three digit rings (setting register, results counter, turns counter), each an array of digits, units first.
curta.carriage · curta.liftedfieldsThe carriage decimal-shift position and the lift flag (lifted = the crank subtracts).
curta.peek(a) · curta.poke(a,v)methodsSide-effect-free read / write of the ring memory (setting · results · turns digits) — used by the debugger.
curta.onWrite(addr,v)hookCalled on every ring-digit write; the boot uses it to implement watchpoints on the results counter.

Because the whole mechanism is ordinary JavaScript, breakpoints are a host-side Set of operation indices checked before each step(), and watchpoints are checked inside onWrite — no changes to the core.

Debugger integration

The plug-in (curta-debug.js) describes the machine to the shared debugger, and a new decoder (debugger/src/cpus/curta.js) makes the operation tape readable. The Curta is mechanical — no CPU, no bytes, no opcodes — so this is an unusual but faithful mapping:

  • The operation tape is the program. The "disassembly" view decodes one hand action per address: SET p=d (dial a slider), CRANK + / CRANK − (a crank turn adding or subtracting), CARRIAGE << / >> (shift a decimal place), LIFT / DROP (raise / lower the carriage), CLEAR and CLR SET. Anything unrecognised decodes to .op.
  • Registers are the machine's programmer-visible state: the SETTING register, the RESULT and TURNS counters, the CARRIAGE position, the LIFT flag and the OP tape index — all read live and written back each refresh.
  • Single step is one curta.step() — the tape advances by one action. Breakpoints are host-side checks on the operation index (click an operation in the disassembly gutter); watchpoints fire inside onWrite when a watched results-counter digit is written by a crank turn.
  • Like cpus/analytical.js, the decoder cannot express a structured action through the byte-masked reader the view provides, so it reads the real op off the live core (window.EMU_BOOT.curta.tape) and falls back to a one-byte kind code only when the core is absent.

Architecture

The Curta is a hand-cranked mechanical pocket calculator, designed by Curt Herzstark — much of it while he was imprisoned in the Buchenwald concentration camp — and first produced in 1948. It is a masterpiece of miniature precision engineering, so densely packed with gears that it became a collector's legend, nicknamed "the math grenade" for its shape and its heft.

All of its work is done by turning a crank, feeding a single stepped drum (a Leibniz stepped cylinder). The parts modelled here (Type I):

  • The setting register — eight sliders down the body, each dialled 0-9. This is the number you enter; one crank turn runs it once through the drum.
  • The crank — one turn adds the setting number into the results counter, with carries rippling up the digits automatically.
  • The carriage — the movable top ring carrying the two counters. Rotating it shifts which decimal place the setting is added at (so you multiply and divide by powers of ten); lifting it engages the drum's nine's-complement teeth so the very same crank turn now subtracts — Herzstark's elegant one-drum trick for both directions.
  • The results counter (11 digits) shows the running total; the turns counter (6 digits) counts the crank turns at each carriage position, giving the multiplier or the quotient.
  • The clearing ring sweeps the results and turns counters back to zero.

How subtraction works. The drum carries, for each setting digit, teeth for the digit and teeth for its nine's complement. With the carriage lifted, a turn adds the nine's complement plus one — the ten's complement — so the counter runs backward with proper borrows, all in gears, no separate mechanism. Multiplication is repeated addition with carriage shifts; division is repeated subtraction. The default tape multiplies 7 × 6 = 42 by cranking a setting of 7 six times.