Skip to content

Keep the best time and score

  • Sinclair ZX Spectrum
  • Assembly

A fast run and a high-scoring run need not be the same run. We will remember separate session records and make a successful finish worth more when it is faster.

best_time is a word outside the per-run state range. It begins at 65535, hexadecimal $FFFF, meaning no successful time yet. best_score is a byte that begins at zero. Retry clears the run’s state, not these records.

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.

score
—
finish_points
—
best_score
—
phase
—
elapsed
—
best_time
—

The inspector shows the stored sentinel as 65535 until a successful finish. The result screen now calls bonus_line and records to print the finish bonus, best time and best score, and records writes dashes into the best-time digits while the sentinel is stored. Those are two views of the same “not set” condition, not a 1310-second record to beat.

Award the finish bonus once

On success, convert elapsed to whole seconds and compute max(0,100-seconds). Add that many score units. Each unit is ten points, so a 41.84-second run receives 590 finish points. A 20.92-second run receives 800.

The subtraction clamps a negative result to zero. The bonus is calculated on the win path, once, before displaying the result. A failed run gets no finish bonus.

Compare words without an old carry

To consider a time record, load elapsed into HL and best_time into DE. Clear carry with or a, then use sbc hl,de. If the elapsed time is smaller, subtraction borrows and carry is set. Reload elapsed and store it as the new record. Otherwise keep the previous record.

A score record uses the opposite preference: larger is better. save_score compares the byte values and stores the run’s score unless it is lower. It is called for both outcomes, so a failed run can still establish a high score.

A failed run lasts only three seconds. Should it replace a successful twenty-second time?

Show the explanation

No. It did not complete the course. Only the won path considers best_time. The comparison is not enough by itself; the point at which it is called expresses what the record means.

Reset the right lifetime

Unit 11 gathered every run variable between state_start and state_end. new_game fills that range with zero, then restores the run’s initial ship position, hull and spawn countdown. The record bytes are deliberately placed outside the range. Moving them inside would make R forget them; moving elapsed outside it would make the next run inherit old time.

Test a loss and retry: run state should reset. After a successful finish, retry again and check that the records survive. Return to the title with Q and launch again: the title does not touch them either. Reassembling deliberately creates a new machine and loses them. These are RAM records for one session, not data saved to tape or disk.

The accepted course keeps score within a byte: even twenty boosted stars plus the largest possible bonus is at most 140 units. Adding more rewards later would require checking that bound again.

Sources

The maintained Meteor Storm source linked through this page supplies the game rules and data layout. Its experiments run original Z80 instructions on an emulated 48K PAL Spectrum; the game rules are design choices, not hardware properties.

Run it here

This unit's program, built for you.

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

Download meteor-storm.tap