Cray-1
An authored, in-browser emulator of the Cray-1, the 1976 Cray Research vector supercomputer that made "supercomputer" mean "vector machine". A compact JavaScript core models the programmer-visible state — the A, S and V register sets, the B and T register files, VL, VM and 64-bit-word memory — and a working subset of the scalar and vector instruction set, rendering the whole register and vector display to a canvas.
It plugs into the shared debugger through a new cray1 CPU decoder that disassembles the 16-bit g/h/i/j/k parcel format in octal CAL notation, with single-instruction step, execution breakpoints on the P parcel counter, and write watchpoints on memory words. It boots running a hand-authored vector add and dot product so the vector registers visibly fill.
Runs on: Web browser
Cray-1 Online Emulator
Play Cray-1 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Vector add & dot product | Cray-1 | Cray-1 | open | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
The Cray-1 here is authored from scratch in one file, cray1.js. It is a plain global — CRAY1.create(canvas) returns a machine object whose whole state is ordinary JavaScript (registers are arrays, memory is a DataView), so the debugger reaches straight into it with no wasm heap or hidden loop.
Boot. Create the machine on a <canvas>; it loads its default vector demo automatically. Then run your own loop built on cray.step() (execute exactly one parcel-instruction):
var cray = CRAY1.create(canvas);
(function loop(){
var r = cray.step(); // 'ok' | 'stop'
cray.render();
if (r !== 'stop') requestAnimationFrame(loop);
})();
The machine is plain fields. Everything the debugger needs is live on the object:
| Member | Kind | What it does |
|---|---|---|
cray.step() | method | Execute exactly one instruction (one or two parcels); returns 'ok' or 'stop'. The single-step primitive. |
cray.a · cray.s · cray.v | fields | The eight A (24-bit), eight S (64-bit) and eight V (64-element) registers, read and written live. |
cray.vl · cray.vm · cray.p | fields | Vector length, vector mask and the P (parcel) program counter. |
cray.parcel(a) | method | The 16-bit instruction parcel at parcel-address a — the cray1 decoder reads through it (the hex view's byte reader would truncate a parcel). |
cray.peek(a) · cray.poke(a,b) | methods | Side-effect-free byte read / write of the 64-bit-word data memory — used by the debugger's memory views. |
cray.onWrite(word) | hook | Called on every word write; the boot uses it to implement watchpoints. |
Debugger integration
The plug-in cray-1-debug.js calls EmuKit.defineMachine with everything the shared debugger needs, and the boot shim owns the run loop so the debugger can drive it.
- New CPU decoder.
debugger/src/cpus/cray1.jsregisters thecray1decoder. It splits each 16-bit parcel into the Crayg/h/i/j/kfields, recognises the instruction groups (special & branch, A-register, S-register, scalar memory, and the full vector block), and renders them in octal CAL notation (V2 V0+FV1,Si Vj,Ak,,A0,Ak Vj). Two-parcel forms returnlength 2; anything unrecognised falls back to.parcel <octal>. - Instruction step.
transport.stepInsn(n)callscray.step()— one parcel-instruction, advancing P by one or two parcels. - Execution breakpoints are a host-side
Setof parcel addresses; the loop checks the P register before each step and pauses on a hit. The disasm view's gutter toggles them. - Write watchpoints. The core calls
onWrite(word)on every 64-bit word write; the boot checks aSetof watched word addresses and pauses on a hit — no change to the core arithmetic. - Registers. A0-A7, S0-S7, a V0-V7 vector summary, VL, VM, P and B00/T00 are all read live and (except the vector summary) written back through
set(); memory is exposed as two chips — the program parcels (disassembled) and the byte-addressable data memory (hex + bit views).
Architecture
The Cray-1, delivered in 1976, was the fastest computer in the world and the machine that made "supercomputer" mean "vector processor". Serial 1 went to Los Alamos; an 80 MHz clock, freon cooling and the iconic C-shape (short wires = less delay) gave it up to 160 MFLOPS.
The programmer sees a rich register set feeding pipelined functional units (add, multiply, reciprocal, logical, shift), with results chained unit-to-unit:
- A0-A7 — eight 24-bit address registers (addressing, loop counts, shift amounts), backed by 64 B registers.
- S0-S7 — eight 64-bit scalar registers (integer and floating), backed by 64 T registers.
- V0-V7 — eight vector registers of 64 elements × 64 bits. A single instruction streams up to VL (1-64) elements through a functional unit, one per clock; the VM vector mask gates per-element operations.
Instructions are one or two 16-bit parcels. The first parcel is five fields: g (4 bits) and h (3) form the 7-bit op code; i names the result register; j and k the operands. Two-parcel forms carry a 16-bit m field for 22-bit constants and 24-bit branch addresses. The op-code map is octal: 03x address arithmetic, 04x-07x scalar, 10x-13x memory, 14x-17x vector. This model uses IEEE-754 doubles for the 64-bit words (a pragmatic stand-in for genuine Cray floating format); the register sets, parcel format, vector semantics and the pipeline picture are faithful. The default program is an open, hand-authored vector add and dot product.