--- title: "Time Inquiry" id: 71492 type: "computer_media" slug: "time-inquiry" url: "http://localhost/computer_media/time-inquiry/" markdown_url: "http://localhost/computer_media/time-inquiry.md" published_at: "2026-09-09T09:07:21+00:00" modified_at: "2026-09-09T09:07:22+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/time-inquiry-2.png" excerpt: "Look up the current time in any world city by name, powered by a machine code search routine and an expandable packed database you can extend yourself." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "George Chambers" slug: "george-chambers" taxonomy: "indiv" url: "http://localhost/indiv/george-chambers/" genre: - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" media_type: "Program" programmers: - name: "George Chambers" slug: "george-chambers" taxonomy: "indiv" url: "http://localhost/indiv/george-chambers/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Time%20Inquiry%20(198x)(Chambers%2C%20George)(TS2068)(US)(Program).zip" tsrun_member: "Time Inquiry (198x)(Chambers, George)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/time-inquiry-2.png" - url: "http://localhost/wp-content/uploads/2026/09/time-inquiry.png" media_type_tags: "Home" --- # Time Inquiry Time Inquiry is a world time-zone lookup program that lets users find the corresponding local time for any city or country when given a known time at another location. It loads a companion machine code file (“time.C1”) into memory above address 32550 and uses a Z80 machine code routine (POKEd in from DATA statements at line 9030) to perform a binary search or sequential scan through a packed city/time-zone database stored in high RAM. City entries are encoded as a numeric time-zone code prefix concatenated with the city name and terminated by an asterisk (ASCII 42). The program supports adding new cities to the database via menu option 2 and can save both the BASIC program and the updated code/data file back to tape. Input validation routines check for alphabetic city names and numeric hour values in the range 0–24, rejecting fractional hours other than half-hours (converted to display as “.30”). *** ### Program Structure The program is organized around a central menu at line `350` with four options dispatched via `GO TO VAL x$*2000` (line 460), routing to: - `2000` – Time inquiry (main feature) - `4000` (via `4060`) – Add cities/countries to the database - `6020` – Information/help text - `8000`/`9900` – Save to tape Initialization (lines `10`–`80`) loads the machine code data file, POKEs the Z80 routine from DATA, sets up display attributes, and draws decorative border rectangles using `PLOT`/`DRAW`. The subroutine at `9000`–`9010` RESTOREs to line `9030` and POKEs 68 bytes of machine code into addresses `32552`–`32619`. ### Variable Conventions Several variables are pre-initialized at line `20` using idiomatic ZX Spectrum BASIC to avoid repeating numeric literals and to save memory: | Variable | Value | Meaning | | --- | --- | --- | | `oo` | 0 (`NOT PI`) | Zero / false | | `oa` | 1 (`PI/PI`) | One / true | | `ob` | 2 | Two (max consecutive spaces) | | `oj` | 10 | Column/row offset | | `ol` | 12 | Noon pivot value | | `w` | 350 | Menu line number | | `v` | 3000 | Screen-clear scroll subroutine line | | `l` | 32658 | Base address of city database in RAM | Using `NOT PI` for 0 and `PI/PI` for 1 is a well-known memory-saving idiom on this platform, avoiding storage of the numeric literal in the program line. ### Machine Code Usage Lines `9000`–`9034` POKE a 68-byte Z80 routine into RAM starting at address `32552`. The routine is invoked at line `2530` via `LET b= USR 32552`. Before the call, lines `2460`–`2500` set up a search string in RAM at `32513`, and patch the machine code at addresses `32604`–`32607` with the database pointer `p` (split into low and high bytes). After the call, lines `2540`–`2590` read the result address from `PEEK 32617`/`32618` and walk the found record to extract the numeric code (up to 5 characters, digits only) into `b$` and the city name into `d$`, stopping when a `*` terminator (ASCII 42) is found. The companion file “time.C1” is loaded at line `10` as a CODE block starting at `32656`, which stores the city database. The current end-of-database pointer `p` is reconstructed at line `15` from a two-byte little-endian value PEEKed from addresses `32656`/`32657`. ### Database Format Each city record in the CODE block is formatted as a numeric time-zone offset (e.g., `7`) immediately followed by the city name (e.g., `NEW YORK`), terminated by an asterisk (`*`, ASCII 42). The time-zone number represents the local hour when Greenwich Mean Time is 12:00 noon, functioning as an absolute UTC offset expressed on a 24-hour clock. New records are appended by the menu-option-2 path (lines `4060`–`4200`), with `p` maintained as a running pointer and persisted back into addresses `32656`/`32657`. ### Time Calculation The core arithmetic (lines `2170`–`2330`) computes the time difference as: 1. Extract origin city offset `a = VAL a$` and destination offset `b = VAL b$` from the database. 2. Compute displacement `t = b - a + f` where `f` is the user-entered known hour. 3. Wrap `t` into the 1–24 range, then classify as A.M., P.M., NOON, or MIDNIGHT using `ol` (12) as pivot. Line `2326` handles half-hour time zones: if `t - INT t <> 0`, it sets display suffix `r$` to `"0 "` and adds 0.3 to the integer part of `t` to produce a display like `7.30` instead of `7.5`. This is a practical workaround for displaying fractional hours since the platform’s `PRINT` would otherwise show `7.5`. ### Input Validation Two validation subroutines are used: - `100`–`180`: Validates a city/country name. Allows uppercase letters A–Z (ASCII 65–90), spaces, commas, and periods. Rejects strings with more than one consecutive space (`q` counts spaces; if `q=2`, branches to `320`). Invalid input triggers an error message at line `325`. - `240`–`310`: Validates a numeric hour. Allows digits and one decimal point; rejects values outside 0–24 or non-integer values (line `302`). The slash character (`/`, ASCII 47) is explicitly excluded despite being in the digit range check. ### Screen Management The subroutine at line `3000` scrolls the screen by printing 32 spaces (`e$`, dimensioned at line `80`) from row 21 up to row `oj` (10) in a `FOR` loop with `STEP -1`, effectively clearing lines without a full `CLS`. The variable `v=3000` is used throughout as `GO SUB v` for this purpose. ### Notable Anomalies - Line `2165` tests `IF LEN A$=0` (uppercase `A$`) but sets `A$="0"`; however, the origin city data was stored in lowercase `a$` at line `2020`. On this platform uppercase and lowercase variable names are distinct, so this guard may not function as intended if the origin city lookup populated `a$` rather than `A$`. - Line `2210` modifies `f` (subtracts 12) after it has already been used to compute `t`, which could affect the display label consistency in edge cases but does not alter the already-computed result. - Lines `3100`–`3140` appear to be a diagnostic/debugging utility left in the listing: they scan RAM from address 37380 onward and print raw memory contents. Line `3130` is commented out with `REM`. - Line `4000` is referenced by `GO TO 4000` at line `4140` but does not appear in the listing; the add-city entry point visible is `4060`. This is a non-existent line reference. - The `INKEY$` loop at line `2370`–`2380` has a subtle logic issue: line `2370` waits for a non-empty keypress, but line `2380` then re-reads `INKEY$`, which may already be empty by the time it executes, causing “N” to never be detected reliably. A stored variable for the keypress would be more robust. - Line `9910` does `GO TO ol`, i.e., `GO TO 12`, a non-existent line — standard technique to halt after saving. ## Source Code ``` 1 REM TIME INQUIRY 2 REM George Chambers 3 REM 14 Richome Court 4 REM Toronto,Ont. M1K 2Y1 10 CLEAR VAL "32550":LOAD "time.C1"CODE 15 LET p= PEEK VAL "32656"+ VAL "256"* PEEK VAL "32657" 20 LET oo= NOT PI:LET oa= PI/ PI:LET ob=2:LET oj= VAL "10":LET ol= VAL "12":LET w= VAL "350":LET v= VAL "3000":LET l= VAL "32658" 30 BORDER VAL "5":INK oo:PAPER VAL "5":CLS 40 GO SUB VAL "9000" 50 PRINT AT VAL "3",oj; PAPER VAL "6";"TIME INQUIRY"; PAPER VAL "5";,, TAB VAL "7"; PAPER VAL "6";"By George Chambers" 60 INK oa:PLOT oo, VAL "108":DRAW oo, VAL "62":DRAW VAL "255",oo:DRAW oo,-62:DRAW -255,oo 70 INK ob:PLOT VAL "8", VAL "114":DRAW oo, VAL "50":DRAW VAL "238",oo:DRAW oo,-50:DRAW -238,oo:INK oo 80 DIM e$(32) 90 GO TO w 100 LET q=oo 110 FOR n=oa TO LEN x$ 120 IF x$(n) <>" " THEN LET q=oo 130 IF x$(n)=" " THEN GO TO VAL "150" 135 IF x$(n)= CHR$ VAL "46" OR x$(n)= CHR$ VAL "44" THEN GO TO VAL "150" 140 IF x$(n)< CHR$ VAL "65" OR x$(n)> CHR$ VAL "90" THEN GO TO VAL "320" 150 IF x$(n)=" " THEN LET q=q+oa 160 IF q=ob THEN GO TO VAL "320" 170 NEXT n 180 RETURN 240 LET q=oo 250 FOR a=oa TO LEN x$ 260 IF x$(a)< CHR$ VAL "46" OR x$(a)> CHR$ VAL "57" OR x$= CHR$ VAL "47" THEN GO TO VAL "325" 270 IF x$(a)= CHR$ VAL "46" THEN LET q=q+oa 280 IF q=ob THEN GO TO VAL "325" 290 NEXT a 300 IF VAL x$> VAL "24" OR VAL x$ INT x THEN GO TO VAL "320" 310 RETURN 320 PRINT ,, TAB VAL "10";x$ 325 PRINT AT VAL "18",oa; FLASH oa;"YOU HAVE ENTERED INVALID DATA"; FLASH oo 330 PRINT ,,"Please press any key to restart" 340 IF INKEY$="" THEN GO TO VAL "340" 350 GO SUB v:PRINT AT oj,oo;"This program will provide theproper time displacement for anycountry or city in the world" 380 PRINT ''"1) Time Inquiry" 390 PRINT '"2) To Add Cities/Countries" 400 PRINT '"3) Information" 410 PRINT '"4) To save To Disk" 420 PRINT #1; INK oa;" PRESS A KEY:(1 TO 4)"; INK oo 430 LET x$= INKEY$ 440 IF x$<"1" OR x$>"4" THEN GO TO VAL "430" 460 GO TO VAL x$* VAL "2000" 2000 GO SUB v:PRINT AT oj,oo;"First enter the "; INK ob;"name of the city"; INK oo;"or country."; 2010 GO SUB VAL "2400" 2020 LET a$=b$ 2030 LET c$=d$ 2040 PRINT INK oa;"** ";c$;" **"; INK oo 2050 PRINT ,,"Now enter the "; INK oa;"known hour"; INK oo;" at ",; INK oa;c$; INK oo;" (as a figure","between 1 and 24)"; 2060 POKE VAL "23658", VAL "8":INPUT x$ 2070 IF x$="" THEN GO TO VAL "2060" 2080 PRINT INK ob;" ** ";x$;" **"; INK oo 2090 GO SUB VAL "240" 2100 LET f$=x$ 2120 LET h$="A.M." 2130 IF VAL f$>ol THEN LET h$="P.M." 2135 IF VAL f$=ol THEN LET h$="NOON" 2137 IF f$="24" THEN LET h$="MIDNIGHT" 2140 LET f= VAL f$ 2150 PRINT ,,"Next, Enter the "; INK oa;"name of the cityor country"; INK oo;" where you wish thecorresponding time check." 2160 GO SUB VAL "2400" 2165 IF LEN A$=0 THEN LET A$="0" 2170 LET a= VAL a$ 2180 LET b= VAL b$ 2190 LET t=b-a 2200 LET t=t+f 2210 IF f>ol THEN LET f=f-ol 2220 LET j$="A.M." 2230 IF t> VAL "24" THEN LET t=t- VAL "24" 2240 IF tol THEN LET j$="P.M.":LET t=t-ol 2280 IF t=ol AND j$="A.M." THEN LET j$="NOON" 2290 IF t=ol AND j$="P.M." THEN LET j$="MIDNIGHT" 2305 LET r$=".00 " 2307 GO SUB v 2310 PRINT AT oj,oo;"WHEN IT IS "; INK ob;f;".00 ";h$; INK oo;" AT" 2320 PRINT ' INK ob;c$; INK oo;" THE TIME AT" 2326 IF t- INT t <>oo THEN LET r$="0 ":LET t= INT t+.3 2330 PRINT ' INK ob;d$; INK oo;" WILL BE "; INK ob;t;r$;j$; INK oo 2340 PRINT ''"DO YOU WANT ANOTHER TIME CHECK?" 2350 PRINT ,, TAB oj;"ENTER Y/N" 2370 IF INKEY$="" THEN GO TO VAL "2370" 2380 IF INKEY$="N" THEN CLS :GO TO VAL "8010" 2390 GO TO w 2400 POKE VAL "23658", VAL "8":INPUT x$ 2410 IF x$="" THEN GO TO VAL "2400" 2420 GO SUB VAL "100" 2430 LET d$=x$ 2440 LET x$=x$+"\::" 2450 FOR x=oa TO LEN x$ 2460 POKE VAL "32513"+x, CODE x$(x) 2470 NEXT x 2480 POKE VAL "32606",p- VAL "256"* INT (p/256) 2490 POKE VAL "32607", INT (p/256) 2500 POKE VAL "32604", VAL "146":POKE VAL "32605", VAL "127" 2530 LET b= USR VAL "32552" 2540 LET x= PEEK VAL "32617"+ VAL "256"* PEEK VAL "32618" 2542 IF x=l THEN GO TO VAL "5000" 2543 LET b$="" 2545 LET d$="" 2550 FOR y=x TO x+ VAL "16" 2555 IF y-x>4 THEN GO TO VAL "2570" 2560 IF PEEK y> VAL "44" AND PEEK y< VAL "58" AND PEEK y <> VAL "45" AND PEEK y <> VAL "47" THEN LET b$=b$+ CHR$ PEEK y 2570 IF PEEK y> VAL "64" AND PEEK y< VAL "91" THEN LET d$=d$+ CHR$ PEEK y 2575 IF PEEK y= VAL "32" OR PEEK y= VAL "44" OR PEEK y= VAL "46" THEN LET d$=d$+ CHR$ PEEK y 2580 IF PEEK (y+oa)= VAL "42" THEN RETURN 2590 NEXT y 2690 RETURN 3000 FOR N=21 TO oj STEP -oa:PRINT AT N,oo;e$:NEXT N:RETURN 3100 REM \{17}\{4}To scan names list\{17}\{5} 3110 FOR n=37380 TO VAL "65000" 3120 PRINT n, CHR$ PEEK n 3130 REM IF PEEK (n)=42 THEN PRINT :PRINT (n+1);" "; 3140 NEXT n:STOP 4060 GO SUB v:PRINT AT oj,oo;" 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 VAL "14", VAL "8";e$' TAB oj; INK ob;x$; INK oo 4110 PRINT AT 18,oo;"Press N/L to log this listing or C to correct it" 4120 INPUT x$ 4130 GO SUB v 4140 IF x$="C" THEN GO TO VAL "4000" 4150 FOR x=oa TO LEN a$ 4160 POKE l+p, CODE a$(x) 4170 LET p=p+oa 4180 NEXT x 4190 POKE l+p, VAL "42" 4195 POKE VAL "32657", INT (p/ VAL "256"):POKE VAL "32656",p-(PEEK VAL "32657"* VAL "256") 4200 GO TO w 5020 GO SUB v:PRINT AT oj,oo;" 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 VAL "18",oo;"Press any key to return to Menu" 5070 IF INKEY$="" THEN GO TO VAL "5070" 5080 GO TO w 6020 CLS :PRINT AT oo,oo'"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 it's time zone."''" (Example) 7NEW YORK" 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 Time." 6300 PRINT INK oa'"Press any key to return to Menu"; INK oo 6310 IF INKEY$="" THEN GO TO VAL "6310" 6320 CLS :GO TO VAL "50" 8000 GO TO VAL "9900" 8010 GO SUB v:PRINT AT oj, VAL "8";" TEMPUS FUGITS " 8020 PRINT ,, TAB VAL "6";" MY,HOW TIME FLIES " 8030 PAUSE oo:STOP 9000 RESTORE VAL "9030" 9010 FOR n= VAL "32552" TO VAL "32619":READ a:POKE n,a:NEXT n:RETURN 9030 DATA 42,92,127,237,75,94,127,17,2,127,26,237,177,226,96 9031 DATA 127,19,26,254,143,202,71,127,237,161,202,56,127,195,47 9032 DATA 127,34,92,127,43,126,254,42,202,84,127,195,74,127,34 9033 DATA 105,127,237,67,94,127,201,44,142,228,3,33,146,127,1 9034 DATA 1,0,195,84,127,34,142,0,0 9890 STOP 9900 SAVE "time.B1" LINE 1:SAVE "time.C1"CODE VAL "32656",p 9910 GO TO ol ```