Signed Odometer

Big Numbers

A vast signed odometer ticking through zero on a Super Nintendo — a chip with no hardware divide at all. Each value is split into decimal digits by the classic v%10 / v/=10 loop, which on a negative number exercises the sign-corrected 64-bit divide+modulo the compiler provides as a runtime call. Runs automatically; no joypad needed. Written in C and compiled with the llvm-mos-based 65816 toolchain (+mos-a16, 16-bit accumulator mode).

loading core…

Self-running demo — the odometer tape ticks upward through zero.

Click the screen to focus, then watch. Tab away and it pauses.

What it is

To print a number in decimal you peel off digits from the right: the last digit is the value mod 10, then you divide by 10 and repeat. For a 64-bit signed value on a CPU with no divide instruction, each of those steps is a call into the compiler's math runtime, and the sign has to be handled carefully:

for (i = 0; i < 18; i++) {
    d = v % 10;      // signed modulo — negative when v < 0
    digit[i] = |d|;
    v = v / 10;      // signed divide — truncates toward zero
}
// clang merges the two into ONE call: __divmoddi4

The odometer sweeps from deeply negative up through zero, so the digit-peeling runs on both signs. It stays bit-exact across every codegen mode — the value shown on the tape is identical to the host reference, three ways over.

Compiler stress-test

ItemWhat it exercises
signed 64-bitA 64-bit signed integer split into decimal digits. On the 65816 there is no hardware divide at all — 64-bit signed division is a compiler-runtime call, and the sign has to be corrected around the unsigned core.
__divmoddi4Because the loop uses both v/10 and v%10 on the same value, clang merges them into the single combined signed call __divmoddi4 — quotient and remainder in one shot. Distinct from an unsigned 64-bit divide (__udivdi3); the differential confirms no unsigned form appears.
through zeroThe odometer starts deeply negative and steps up past zero into positive territory. That sweep exercises the sign-correction in both directions: C truncates division toward zero and gives a non-positive remainder for a negative operand, so the digit extraction of negatives is a distinct path from positives.
bit-exactEvery value on the scrolling tape is computed the same way on the host reference and on all three codegen modes. The gate folds the digits of 60 swept values; host == default == +mos-a16 == +mos-xy16 == bsnes-jg, byte for byte.

Written in C with the llvm-mos 65816 toolchain and verified against bsnes-jg (and MAME where the SPC700 IPL is present). Hit Verify fidelity to reproduce the build gate's WRAM assert (gate hash 0xD2A2 — a fold of the digits of 60 swept signed values) live in this tab. No far pointers — the same source passes every way: host == default == +mos-a16 == +mos-xy16 == bsnes-jg, -verify clean.