Skip to content

// FROM THE METAL //

Programming explained through the machine.

What does a loop cost? When does a smaller program run more slowly? These essays use vintage machines to examine how programs work and why familiar advice sometimes helps — and sometimes does not. Each explanation connects a concrete example to the choices we make when programming today.

Performance · 6502

Why "unroll your loops" is real advice

Twenty-year-old advice, finally visible. On a 6502 the loop is just instructions that run every time round — and unrolling deletes them.

Read →

ARITHMETIC · 6502

When 255 + 1 = 0

255 + 1 = 0 with a carry, $80 is both 128 and −128, and abs(MIN) comes back negative — two's complement, shown whole in three 6502 instructions.

Read →

ARITHMETIC · Z80

Why everything is a power of two

The Z80 can't multiply, so it has to show you why a power-of-two capacity makes modulo free and 1,024 is engineering, not superstition.

Read →

ARCHITECTURE · 68000

"Stack overflow" is a real place

On the 68000 the stack is just A7 walking down through RAM — watch the pointer move and stack frames, recursion's cost and 'stack overflow' all turn literal.

Read →

GRAPHICS · NES (6502)

Racing the beam

The NES paints to a moving beam, not a buffer — so everything happens in vblank. Every frame budget and VSync toggle you know starts here.

Read →

TABLES · 68000

The fastest function is the one you already ran

Maths is dear, memory is cheap — so the demoscene computed sine once into a table and read it forever. Every cache and memoised function is the same trade.

Read →

HARDWARE · Z80

The register is the bitfield

On the Spectrum one byte to port $FE runs three pieces of hardware at once — so you set and clear bits with OR and AND. Every packed-flags enum is this.

Read →

ARITHMETIC · NES (6502)

Mario moves in fractions of a pixel

No floats on the NES, so position is a whole pixel plus a fraction — and a carry turns a pile of subpixels into the famous glide, the way money lives in whole cents.

Read →

MEMORY · 68000

Why your structs have holes in them

On the 68000 a misaligned word read traps — so the compiler pads your structs to keep every field on an even address. Padding is hardware law, not fussiness.

Read →

MEMORY · 6502 vs 68000

Why the bytes come out backwards

The 6502 stores low byte first, the 68000 high byte first — set them side by side and byte-swaps, hex dumps and htons() stop being mysteries.

Read →

MEMORY · 6502

A pointer is just an address you stored somewhere

The asterisks and arrows fall away on a 6502 — a pointer is just an address you stored somewhere, set with two stores and followed with one load.

Read →

// 3 more in the series — a new one every week //