Skip to content

Show seconds and hundredths

  • Sinclair ZX Spectrum
  • Assembly

A frame count is good for measuring a run. Seconds and hundredths are easier to compare at the finish. We will convert the counter for display without changing the counter itself.

This lesson’s program adds that conversion and its display to unit 18’s program. The code that measures elapsed is unchanged; what is new is seconds, format_time, the time buffers and a time line in the HUD.

On our 48K PAL target, fifty frames make one second. Divide elapsed by 50: the quotient is whole seconds and the remainder is leftover frames. Multiplying the remainder by two gives hundredths, because one frame is two hundredths of a second.

Source · view and edit
ZX Spectrum
Companion file: assets.inc

The include line reads this editable data when you assemble. Keep it beside your source for a local build.

Edit the source, then assemble.

Edits are saved in this browser. Keep a downloaded copy of work you want to keep.

Focus the Spectrum screen to use the keyboard, or hold these buttons. Assemble again for a fresh machine.

Run the program to inspect it. Editing source does not change the running machine.

time_seconds
—
time_fraction
—
elapsed
—

The live display updates when the game updates. It does not claim finer timing resolution than a frame: the hundredths advance in multiples of two, and ordinary two-frame updates often change them by four.

Division by repeated subtraction

seconds takes elapsed in HL and sets DE to 50. It subtracts 50 repeatedly, counting successful subtractions in B. or a clears carry before sbc hl,de, so a carry left by earlier work cannot subtract an extra one.

When a subtraction borrows, the routine has gone one subtraction too far. It adds 50 back, leaving the remainder in HL, and returns the quotient in A. In this game’s short runs the quotient fits in a byte and the remainder fits in L.

meteor-storm.asm, excerpt
seconds:
 ld b,0
 ld de,50
seconds_loop:
 or a
 sbc hl,de
 jr c,seconds_done
 inc b
 jr seconds_loop
seconds_done:
 add hl,de
 ld a,b
 ret

; HL frames, DE output MM.SS-style seconds/hundredths buffer (SS.CC).

For 2092 frames, forty-one successful subtractions leave 42. That means 41 seconds plus 84 hundredths: 41.84 seconds.

Reuse decimal conversion carefully

format_time saves the quotient and doubled remainder, then uses decimal3 to fill the digit buffers. Its output pointer refers to a five-character SS.CC area with one writable padding byte before it. The three-digit seconds conversion begins in that padding position; the fraction conversion temporarily uses the dot position, which is restored afterwards.

This is a compact buffer arrangement with a specific contract. The source reserves time_pad before time_digits. If you call this routine with an arbitrary five-byte buffer, it writes one byte before that buffer. Name the required padding instead of hoping unused memory happens to be available.

hud now calls format_time on every update. After a clear, when hud_drawn is zero, it prints the whole line from time_text: the string "TIME " has no terminator, so text runs on through time_pad and time_digits to the zero after them. Later updates redraw only the five digits, starting at column 7. The complete time line includes the padding position, so it can show a leading zero. The significant short-course time is still seconds and hundredths. This formatter is intended for runs below 100 seconds; hours and long sessions need a different format.

A run takes 1046 frames. Is the display 20.46 seconds?

Show the explanation

No. 1046 divided by 50 is 20 remainder 46. Forty-six frames are 92 hundredths, giving 20.92 seconds. The remainder counts frames until we convert its units.

Try changing the fraction’s add a,a to nop. The timer in RAM still measures the same frames, but the displayed fraction is wrong. Revert after observing the mismatch. Display conversion can lie about correct state; that is why we inspect both.

Sources

Zilog, Z80 CPU User Manual, UM008011-0816, instruction descriptions for the operations shown in this lesson. The running experiment supplies the program-specific observations.

Run it here

This unit's program, built for you.

Program
meteor-storm.tap
Machine
ZX Spectrum 48K (PAL)

Download meteor-storm.tap