TIME CHECK is a world time zone conversion program that calculates the corresponding local time in one city or country given a known time in another. It maintains a database of city/country names paired with numerical UTC offset codes, stored as machine code data beginning at address 32552 and searched via a USR call. The program saves and loads this city database as a separate CODE block (“time C”) alongside the BASIC program itself, allowing the data to persist across sessions and grow as users add entries via the menu. Input validation routines check for alphabetic city names and numeric hour values, and the time arithmetic handles AM/PM labeling, noon, and midnight edge cases using 24-hour clock arithmetic.
Program Structure
The program is organized around a main menu at line 350 and uses two key pointer variables: V=200 (pointing to the header display subroutine at line 200) and W=350 (pointing to the menu entry point). GO SUB V and GO TO W are used throughout as indirect calls, a compact BASIC idiom that avoids hardcoded line numbers in repeated jumps. Menu selection at line 460 uses GO TO VAL X$*2000 to dispatch directly to line 2000, 4000, 6000, or 8000 for the four menu options.
- Lines 100–180: Alphabetic name validation subroutine
- Lines 200–230: Screen header display subroutine
- Lines 240–310: Numeric hour validation subroutine
- Lines 320–340: Invalid input error handler
- Lines 350–460: Main menu
- Lines 2000–2395: Time inquiry (menu item 1)
- Lines 2400–2690: City/country database lookup subroutine
- Lines 4000–4190: Add city/country to database (menu item 2)
- Lines 5000–5080: “Not found” handler
- Lines 6000–6320: Information screen (menu item 3)
- Lines 8000/9000: Save to tape (menu item 4)
- Lines 9900–9999: Load stub and exit
Machine Code Database Engine
The city/country database is stored as raw bytes beginning at address 32552 in RAM. Each record consists of a numeric code prefix (the city’s time as a 24-hour value when GMT is 12:00) followed by the city name and terminated by a byte value of 23. A new entry is prepended with an asterisk ("*") as a record separator at line 4090. The variable P tracks the current write offset into the data area.
Lookup is performed by a machine code routine called via USR 32552 at line 2530. Before calling it, the program POKEs the search string (appended with a █ block character as a terminator) into the data area starting at address 32513, and sets up a subroutine address via POKEs at 32604–32607. The result address of the matched record is returned in PEEK 32617 + 256 * PEEK 32618. If the returned address equals 32658 (the start of the actual data), the search failed and the program branches to line 5000.
After a successful match, lines 2543–2590 walk through memory from the match address, extracting numeric characters (ASCII 45–57, excluding 45 and 47) into B$ and uppercase alphabetic characters plus spaces, commas, and periods into D$, stopping when a byte value of 42 (*) is encountered.
Time Arithmetic
The offset code stored for each city represents the local hour when GMT is 12:00. The time difference between two cities is computed at lines 2170–2200:
A = VAL A$— source city’s GMT-relative codeB = VAL B$— destination city’s GMT-relative codeT = B - A + F— destination time = displacement + known hour
Lines 2230–2290 then normalize T into the 1–12 range and assign AM/PM, NOON, or MIDNIGHT labels. A fractional-hour check at lines 2326–2327 handles half-hour time zones: if T - INT T <> 0, the display suffix is changed from ".OO " to "0 " and T is adjusted by adding 0.3 to the integer part, which converts a decimal 0.5 into a display value of x.3 — an approximate but visible indicator of a half-hour offset rather than a true formatted output.
Save/Load Mechanism
Menu item 4 triggers line 9000, which performs two SAVE operations: first the BASIC program itself with LINE 9900 as the auto-start line, then the machine code and data block as a CODE file named "time C" covering 106+P bytes from address 32552. The load stub at line 9900 prints a message and then executes LOAD "time C" CODE followed by GO TO 350, reassembling the full program state from tape.
Input Validation
Two validation subroutines are used. The alphabetic validator (lines 100–180) scans X$ character by character, rejecting input that contains non-alphabetic characters (outside A–Z, CHR$ 65–90) other than spaces, periods, or commas, and also rejects strings with more than one consecutive space (double-space check via counter Q). The numeric validator (lines 240–310) checks that all characters are in the range CHR$ 46–57 (digits and period), counts decimal points (max one), and then validates that the numeric value is between 0 and 24 and is a whole integer (X <> INT X test at line 302).
There is a minor bug at line 260: the condition X$= CHR$ 47 compares the entire string X$ to the slash character rather than the individual character X$(A), so the slash exclusion never triggers correctly.
Notable Idioms and Anomalies
- The
GO TO VAL X$*2000dispatch at line 460 is an efficient computed-GOTO technique. GO SUB VwithV=200andGO TO WwithW=350provide single-point redirection for the header and menu, useful during development or modification.- Line 2395 (
GO TO W) is unreachable, placed afterGO TO 9996at line 2390. - Line 2310 contains a commented-out
PRINTstatement preserved as a REM, alongside its replacement at line 2311, indicating iterative development. - The exit screen at lines 9996–9999 prints “TEMPUS FUGITS” — a humorous if slightly incorrect Latin phrase (the correct form is “tempus fugit”) — before halting.
- Lines 2370–2380 use two consecutive
INKEY$checks without a pause between them, which on fast hardware can cause the “Y” keypress from 2370 to also satisfy 2380, making it difficult to decline another check. A PAUSE 0 between them would be more robust.
Content
Source Code
1 REM
9 REM
10 REM >TIME CHECK<
11 REM ████████████
15 REM
20 REM AN ORIGINAL PROGRAM
30 REM
40 REM WRITTEN FOR THE ZX81
50 REM
53 REM AND MODIFIED FOR THE
54 REM
55 REM TIMEX 2068
57 REM
58 REM
60 REM BY G.F. CHAMBERS
70 REM ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
80 REM (C)1984
85 REM
90 GO TO 350
100 LET Q=0
110 FOR N=1 TO LEN X$
120 IF X$(N) <>" " THEN LET Q=0
130 IF X$(N)=" " THEN GO TO 150
135 IF X$(N)= CHR$ 46 OR X$(N)= CHR$ 44 THEN GO TO 150
140 IF X$(N)< CHR$ 65 OR X$(N)> CHR$ 90 THEN GO TO 320
150 IF X$(N)=" " THEN LET Q=Q+1
160 IF Q=2 THEN GO TO 320
170 NEXT N
180 RETURN
200 CLS
210 PRINT TAB 10;"TIME CHECK"
220 PRINT TAB 10;"▀▀▀▀▀▀▀▀▀▀"
230 RETURN
240 LET Q=0
250 FOR A=1 TO LEN X$
260 IF X$(A)< CHR$ 46 OR X$(A)> CHR$ 57 OR X$= CHR$ 47 THEN GO TO 325
270 IF X$(A)= CHR$ 46 THEN LET Q=Q+1
280 IF Q=2 THEN GO TO 325
290 NEXT A
300 IF VAL X$>24 OR VAL X$<0 THEN GO TO 325
301 LET X= VAL X$
302 IF X <> INT X THEN GO TO 320
310 RETURN
320 PRINT ,, TAB 10;X$
325 PRINT AT 18,0;"YOU HAVE ENTERED INVALID DATA"
330 PRINT ,,"PLEASE PRESS ANY KEY TO RESTART"
340 IF INKEY$="" THEN GO TO 340
350 LET V=200
351 LET W=350
355 GO SUB V
360 PRINT ,,,, TAB 1;"MENU"
370 PRINT TAB 1;"===="
380 PRINT ,,"1) TIME INQUIRY"
390 PRINT ,,"2) TO ADD CITIES/COUNTRIES"
400 PRINT ,,"3) INFORMATION"
410 PRINT ,,"4) TO SAVE TO TAPE"
420 PRINT ,,,," PRESS A KEY:(1 TO 4)"
430 LET X$= INKEY$
440 IF X$<"1" OR X$>"4" THEN GO TO 430
460 GO TO VAL X$*2000
2000 GO SUB V
2005 PRINT ,,"THIS PROGRAM WILL PROVIDE THECORRECT TIME DISPLACEMENT FORANY COUNTRY OR CITY AROUND THEWORLD"
2010 PRINT ,,"FIRST ENTER THE NAME OF THE CITYOR COUNTRY.";
2020 GO SUB 2400
2030 LET A$=B$
2040 LET C$=D$
2050 PRINT "** ";C$;" **"
2060 PRINT ,,"NOW ENTER THE KNOWN HOUR AT ",C$;" (AS A FIGURE","BETWEEN 1 AND 24)";
2070 INPUT X$
2075 IF X$="" THEN GO TO 2070
2080 PRINT " ** ";X$;" **"
2090 GO SUB 240
2100 LET F$=X$
2120 LET H$="A.M."
2130 IF VAL F$>12 THEN LET H$="P.M."
2135 IF VAL F$=12 THEN LET H$="NOON"
2137 IF F$="24" THEN LET H$="MIDNIGHT"
2140 LET F= VAL F$
2150 PRINT ,,"NEXT, ENTER THE NAME OF THE CITYOR COUNTRY WHERE YOU WISH THECORRESPONDING TIME CHECK"
2160 GO SUB 2400
2170 LET A= VAL A$
2180 LET B= VAL B$
2190 LET T=B-A
2200 LET T=T+F
2210 IF F>12 THEN LET F=F-12
2220 LET J$="A.M."
2230 IF T>24 THEN LET T=T-24
2240 IF T<0 THEN LET J$="P.M."
2250 IF T<0 THEN LET T=T+12
2260 IF T>12 THEN LET J$="P.M."
2270 IF T>12 THEN LET T=T-12
2280 IF T=12 AND J$="A.M." THEN LET J$="NOON"
2290 IF T=12 AND J$="P.M." THEN LET J$="MIDNIGHT"
2300 GO SUB V
2305 LET R$=".OO "
2310 REM PRINT AT 10,0;"WHEN THE TIME AT ",C$
2311 PRINT AT 10,0;"WHEN IT IS ";F;".OO ";H$;" AT"
2320 REM PRINT "IS ";F;".OO ";H$;", THE TIME AT"
2321 PRINT C$;" THE TIME AT"
2326 IF T- INT T <>0 THEN LET R$="0 "
2327 IF T- INT T <>0 THEN LET T= INT T+.3
2330 PRINT D$;" WILL BE ";T;R$;J$
2340 PRINT ,,"DO YOU WANT ANOTHER TIME CHECK?"
2350 PRINT ,, TAB 10;"ENTER Y/N"
2360 PRINT TAB 10;"▀▀▀▀▀▀▀▀▀"
2370 IF INKEY$="" THEN GO TO 2370
2380 IF INKEY$="Y" THEN GO TO 350
2390 GO TO 9996
2395 GO TO W
2400 INPUT X$
2410 IF X$="" THEN GO TO 2400
2415 GO SUB 100
2420 LET D$=X$
2430 LET X$=X$+"█"
2440 FOR X=1 TO LEN X$
2450 POKE 32513+X, CODE X$(X)
2460 NEXT X
2470 POKE 32606,P-256* INT (P/256)
2480 POKE 32607, INT (P/256)
2490 POKE 32604,146
2500 POKE 32605,127
2530 LET B= USR 32552
2540 LET X= PEEK 32617+256* PEEK 32618
2542 IF X=32658 THEN GO TO 5000
2543 LET B$=""
2545 LET D$=""
2550 FOR Y=X TO X+P
2555 IF Y-X>4 THEN GO TO 2570
2560 IF PEEK Y>44 AND PEEK Y<58 AND PEEK Y <>45 AND PEEK Y <>47 THEN LET B$=B$+ CHR$ PEEK Y
2570 IF PEEK Y>64 AND PEEK Y<91 THEN LET D$=D$+ CHR$ PEEK Y
2575 IF PEEK Y=32 OR PEEK Y=44 OR PEEK Y=46 THEN LET D$=D$+ CHR$ PEEK Y
2580 IF PEEK (Y+1)=42 THEN RETURN
2590 NEXT Y
2690 RETURN
4000 CLS
4050 GO SUB V
4060 PRINT AT 8,0;"ENTER THE CODE NUMBER AND NAME",,," OF THE CITY OR COUNTRY"
4070 PRINT ,," (SEE INSTRUCTIONS)"
4080 INPUT X$
4090 LET A$="*"+X$
4100 PRINT AT 14,8;"** ";X$;" **"
4110 PRINT AT 16,0;"PRESS N/L TO LOG THIS LISTING OR C TO CORRECT IT"
4120 INPUT X$
4130 CLS
4140 IF X$="C" THEN GO TO 4000
4150 FOR X=1 TO LEN A$
4160 POKE 32658+P, CODE A$(X)
4170 LET P=P+1
4180 NEXT X
4190 POKE 32658+P,23
4200 GO TO W
5000 CLS
5010 GO SUB V
5020 PRINT ,," THE NAME YOU REQUESTED",,," ";D$;" "
5025 PRINT ,," IS NOT IN OUR RECORDS"
5030 PRINT ,,"PLEASE SELECT ANOTHER NAME."
5040 PRINT ,," IF YOU WISH, IT IS POSSIBLE TOENTER ADDITIONAL LOCATIONS INTOTHIS PROGRAM VIA MENU ITEM NO.2. CHECK THE INSTRUCTIONS."
5060 PRINT AT 18,0;"PRESS ANY KEY TO RETURN TO MENU"
5070 IF INKEY$="" THEN GO TO 5070
5080 GO TO W
6000 CLS
6010 GO SUB V
6020 PRINT ,,"IF THE REQUESTED LOCALITY IS NOTSTORED, YOU WILL BE ADVISED"
6030 PRINT ,,"YOU MAY ADD LOCALITIES TO THEDATA BASE, IF YOU WISH"
6040 PRINT ,,"AN ENTRY CONSISTS OF THE NAME OFTHE CITY, PLUS A NUMERICAL CODEPREFIX DENOTING ITS TIME ZONE"
6050 PRINT ,,"THE CODE PREFIX MUST CORRESPONDTO THE TIME (AS A 24-HOUR CLOCK)IN THAT LOCALITY,WHEN THE GREEN-WICH MEAN TIME IS 12 NOON"
6060 PRINT ,,"NOTE: THIS PROGRAM DOES NOT COPEWITH DAYLIGHT SAVING TIMES"
6300 PRINT ,,"PRESS ANY KEY TO RETURN TO MENU"
6310 IF INKEY$="" THEN GO TO 6310
6320 GO TO W
8000 GO TO 9000
9000 SAVE "TIME" LINE 9900:BEEP .2,15:SAVE "time C"CODE 32552,106+P
9900 PRINT AT 10,4;"""TIME"" DATA NOW LOADING"," LEAVE RECORDER RUNNING":LOAD "time C"CODE :GO TO 350
9996 CLS
9997 PRINT AT 10,8;" TEMPUS FUGITS "
9998 PRINT ,, TAB 6;" MY,HOW TIME FLIES "
9999 STOP
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
