Multi-Base Clock

Big Numbers

One number, counting up, shown in four bases at once — decimal, dozenal (base 12), hexadecimal and sexagesimal (base 60, like clock minutes and seconds) — plus a 64-bit odometer. Turning a number into digits of a given base needs the quotient and the remainder at each step, which the standard library's div() hands back together as a little struct. Runs on its own; 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 same instant ticks in four bases at once.

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

What it is

To write a number in another base you repeatedly divide by the base and keep the remainders — those are the digits. The standard library gives you both at once:

div_t d = div(n, base);   // quotient AND remainder, in ONE call
digit = d.rem;            // ...returned together as a two-field struct
n     = d.quot;           // repeat to peel off the next digit

div() returns a div_t — a struct holding the quotient and the remainder — by value. Returning a struct from a function is a distinct calling-convention path, and underneath it drives the compiler's divide-with-remainder. The four read-outs all show the same instant. It stays bit-exact across every codegen mode.

Compiler stress-test

ItemWhat it exercises
div_t by valueThe standard library div() returns a small struct — quotient and remainder together — by value. Returning an aggregate from a function is its own calling-convention path, separate from returning a single number, and this is the first demo to exercise it.
divide + remainderConverting a number to another base needs both the quotient and the remainder at each step. div() computes them once; underneath, that is the compiler's divide-with-remainder routine, reading the remainder back from a scratch slot on the stack.
lldiv for 64-bitThe odometer at the bottom is a 64-bit number, split with lldiv() — the long-long version, which returns a bigger struct and drives the 64-bit divide-with-remainder.
width disciplinediv() operates on int, which is 16-bit on the 65816 but 32-bit on the host — so the four-base counter is kept under 32768 to stay identical on both. lldiv()'s long long is 64-bit everywhere, so the odometer is always safe.

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 CRC 0x371A — a fold of base conversions in four bases plus a 64-bit odometer, each cross-checked by reconstructing the value) live in this tab. No far pointers — the same source passes every way: host == default == +mos-a16 == +mos-xy16 == bsnes-jg, -verify clean.