Digital Clock

This file is part of Timex Sinclair Public Domain Library Tape 1003 . Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Home

This program implements a digital clock display for the ZX81/TS1000, accepting a starting time from the user in a compact numeric format (e.g., 352 for 3:52, 1107 for 11:07) along with an AM/PM indicator. The clock ticks by looping through a PAUSE delay of approximately P=3572 units, which approximates a one-minute interval on this hardware, then increments the minutes counter each loop. Lines 110–130 implement real-time keyboard adjustments: pressing F slows the clock, D speeds it up, and J jumps back two minutes, compensating for timing drift. AM/PM switching is handled at the 12:01 boundary by comparing and toggling the M$ string. The POKE 16437,255 at line 220 resets the system’s frame counter to prevent the display from blanking during the clock’s main loop.


Program Analysis

Program Structure

The program is divided into two phases: an initialisation phase (lines 10–80) that collects the starting time and AM/PM indicator, and a main clock loop (lines 100–230) that increments minutes, handles rollovers, and refreshes the display. Line 90 jumps directly into the display/pause portion at line 200, bypassing the minute-increment on the very first iteration so the entered time is shown immediately.

  1. Lines 10–80: User input and variable setup. T is split into hours H and minutes M by integer division.
  2. Line 80: CLS clears the screen before entering the loop.
  3. Lines 100–190: Minute increment, keyboard adjustment, rollover logic, and AM/PM toggle.
  4. Lines 200–230: Display, pause, watchdog POKE, and loop-back.

Time Input Parsing

The user enters the time as a plain integer (e.g., 352 for 3:52 or 1107 for 11:07). Line 50 extracts the hours with INT(T/100) and line 60 recovers minutes as M = T - H*100. This avoids any string-parsing overhead and is a common ZX81 space-saving idiom.

Timing Mechanism

The clock “ticks” once per minute. The delay is implemented with PAUSE P at line 210, where P is initialised to 3572 at line 70. On a standard ZX81/TS1000 running at 3.25 MHz, each PAUSE unit corresponds to one 50 Hz frame (approximately 20 ms), so 3572 frames ≈ 71.4 seconds. The intended period is 60 seconds, suggesting the value may need tuning or was empirically chosen to account for the overhead of the BASIC interpreter executing the loop body.

Keyboard Adjustment Controls

Lines 110–130 poll INKEY$ during each loop iteration (after the PAUSE has already elapsed) to allow manual correction of drift:

KeyEffect
FDecreases P by 1 (speeds up ticking — shorter pause)
DIncreases P by 1 (slows down ticking — longer pause)
JSubtracts 2 from M (steps time back 2 minutes)

Because INKEY$ is read after the PAUSE, only one keypress is registered per minute cycle. The J key subtracts 2 (not 1) because line 100 has already added 1 before line 130 is reached, so a net correction of −1 minute results.

Rollover and AM/PM Logic

Minute rollover is handled in two consecutive IF statements at lines 140 and 150: line 140 increments H when M reaches 60, then line 150 resets M to 0. Hour rollover at line 160 wraps H from 13 back to 1, implementing a 12-hour clock.

AM/PM toggling (lines 170–190) uses an intermediate variable C$ to capture the current value of M$ before any change. The toggle fires when H=12 and M=1 (one minute past noon/midnight). Using M=1 rather than M=0 is an artefact of the increment happening at line 100 before the check: when the clock ticks from 11:59 to 12:00, M becomes 60 → reset to 0 and H becomes 12, but the AM/PM check sees M=0 that cycle; the following cycle gives M=1 which triggers the toggle. This means the AM/PM indicator flips one minute late.

Display and Watchdog POKE

Line 200 uses PRINT AT 21,18 to position the clock output at the bottom-right of the screen, formatting it as H.M M$ with trailing spaces to overwrite any residual characters. Line 220 executes POKE 16437,255, which writes to the ZX81 system variable FRAMES (the lower byte of the two-byte frame counter at 16436–16437). This prevents the BASIC interpreter’s display-blank watchdog from blanking the screen during long PAUSE calls — a standard ZX81 technique.

Bugs and Anomalies

  • No lower bound on M from J key: Pressing J can drive M below 0 (to −1), because there is no guard against a negative minute value. Subsequent IF M=60 checks will never fire, and the display will show a negative minutes value until the user presses J again or a natural rollover occurs.
  • AM/PM toggle one minute late: As described above, the switch happens at H=12, M=1 rather than H=12, M=0.
  • PAUSE value not calibrated for 60 seconds: P=3572 produces roughly 71 seconds at 50 Hz, so the clock will run slow without manual F-key correction.
  • Lines 240–250 are unreachable: The GOTO 100 at line 230 creates an infinite loop; SAVE and RUN at lines 240–250 are never executed during normal program flow.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10122 – 10175.

Related Products

Related Articles

Related Content

Image Gallery

Digital Clock

Source Code

   1 REM "DIGITAL CLOCK"
  10 PRINT "AM OR PM"
  20 INPUT M$
  30 PRINT " INPUT TIME IN FORM 352 OR 1107"
  40 INPUT T
  50 LET H=INT  (T/100)
  60 LET M=T-H*100
  70 LET P=3572
  80 CLS 
  90 GOTO 200
 100 LET M=M+1
 110 IF INKEY$="F" THEN LET P=P-1
 120 IF INKEY$="D" THEN LET P=P+1
 130 IF INKEY$="J" THEN LET M=M-2
 140 IF M=60 THEN LET H=H+1
 150 IF M=60 THEN LET M=0
 160 IF H=13 THEN LET H=1
 170 LET C$=M$
 180 IF H=12 AND M=1 AND C$="AM" THEN LET M$="PM"
 190 IF H=12 AND M=1 AND C$="PM" THEN LET M$="AM"
 200 PRINT AT 21,18;H;".";M;" ";M$;"  "
 210 PAUSE P
 220 POKE 16437,255
 230 GOTO 100
 240 SAVE "1016%6"
 250 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top