Talk Clock

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Clock

Talking alarm clock program that sets the system clock using the TS 2068’s frame counter registers (addresses 23672–23674) and triggers a humorous speech routine at 6:00 AM. The program converts a user-entered hour and minute into a frame count stored across three memory locations, then continuously reads those registers back to display the current time in HH:MM:SS format on screen. A companion machine code file (“talkclockC”) is loaded at address 59200 and initialized via RANDOMIZE USR 59206, which handles the speech synthesis output. The alarm routine at line 9930 uses POKE 59360 with values 192, 128, 64, and 0 to control speech parameters, printing words to streams #1 and #4 that are vocalized by the machine code driver.


Program Structure

The program is organized into three logical sections: initialization and time-entry (lines 1–90), the main clock loop (lines 100–190), and the alarm subroutine (lines 9920–9940), with a final SAVE line at 9998. A companion machine code block is loaded separately and provides the speech synthesis engine.

Machine Code Interface

The file "talkclockC" is loaded at address 59200 and entry point 59206 is called via RANDOMIZE USR 59206 at line 4. This machine code routine is the speech driver. The alarm subroutine communicates with it by poking values 192, 128, 64, and 0 into address 59360 between PRINT statements to streams #1 and #4. These poked values appear to be control codes that select speech parameters (pitch, voice, or phoneme bank) for each word or phrase that follows. The SAVE line at 9998 preserves 6000 bytes of machine code starting at 59200.

Clock Register Encoding

The TS 2068 maintains a frame counter in a three-byte little-endian value across system variables at addresses 23672, 23673, and 23674. The program converts the user-supplied hour and minute into a total frame count (at 60 frames per second) and distributes it across these three bytes:

  1. Compute total frames: a = (h*3600 + m*60) * 60
  2. High byte: b = INT(a/65536), POKEd to 23674
  3. Middle byte: a = INT(c/256), POKEd to 23673
  4. Low byte: remainder, POKEd to 23672

The main loop at line 100 reads these three bytes back continuously and reconstructs the elapsed time in seconds, from which hours, minutes, and seconds are derived.

Time Display

A fixed-length string t$ of 8 characters is dimensioned at line 20 with colons pre-placed at positions 3 and 6, forming the HH:MM:SS template. Lines 150–170 fill in the numeric fields using STR$ and pad single-digit values with a leading zero. The result is printed at a fixed screen position with PRINT AT 11,12.

Alarm Logic

A flag variable zt is initialized to 0 at line 7. At line 115, when the hour reaches 6, the alarm subroutine at 9930 is called and zt is set to 1. Line 113 skips the alarm check once it has fired, preventing repeated triggering. The alarm message is deliberately comic, with misspellings (“yor”, “owr”, “buttoxs”, “patooty”, “u”) that appear intentional for comedic effect.

Notable Techniques and Idioms

  • The 24-hour rollover is handled in line 140: IF h=24 THEN LET h=0, consistent with the REM at line 9 which documents a 24-hour mode variant.
  • CLEAR 58999 at line 2 protects the machine code area above 59000 from BASIC memory use.
  • The use of PRINT #1 and PRINT #4 directs output to different streams, likely routed by the machine code driver to the speech synthesizer rather than (or in addition to) the screen.
  • The main loop (lines 100–190) has no PAUSE or delay, relying entirely on the frame counter registers for timekeeping rather than BASIC timing loops.

Bugs and Anomalies

  • At line 150, the slice t$(TO 2) assigns a two-character field, but a two-digit hour string fits cleanly. However, if STR$ h produces only one character, the assignment leaves a stale character at position 2 before the correction on the same line overwrites both positions correctly.
  • The REM at line 9 documents a 12-hour variant (reset h to 1 when h=13) but this branch is not implemented in the active code; only the 24-hour variant at line 140 is used.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 REM CLOCK
    2 CLEAR 58999
    3 LOAD "talkclockC"CODE 
    4 RANDOMIZE USR 59206
    5 REM ** Main Program **
    7 LET zt=0
    9 REM FOR 12 HOUR TIME...140 IF h=13 THEN LET h=1; FOR 24 HOUR TIME...140 LET s=b-m*60:IF h=24 THEN LET h=0
   10 BORDER 6:PAPER 6:INK 0:CLS 
   20 DIM t$(8):LET t$(3)=":":LET t$(6)=":"
   30 INPUT "Hour ? ";h
   40 INPUT "Minute ? ";m
   50 LET a=(h*3600+m*60)*60
   60 LET b= INT (a/65536):POKE 23674,b
   70 LET c=a-b*65536
   80 LET a= INT (c/256):POKE 23673,a
   90 LET b=c-a*256:POKE 23672,b
  100 LET t= INT ((65536* PEEK 23674+256* PEEK 23673+ PEEK 23672)/60)
  110 LET h= INT (t/3600)
  113 IF zt=1 THEN GO TO 120
  115 IF h=6 THEN GO SUB 9930:LET zt=1
  120 LET b=t-h*3600
  130 LET m= INT (b/60)
  140 LET s=b-m*60:IF h=24 THEN LET h=0
  150 LET t$( TO 2)= STR$ h:IF LEN STR$ h=1 THEN LET t$( TO 2)="0"+ STR$ h
  160 LET t$(4 TO 5)= STR$ m:IF LEN STR$ m=1 THEN LET t$(4 TO 5)="0"+ STR$ m
  170 LET t$(7 TO )= STR$ s:IF LEN STR$ s=1 THEN LET t$(7 TO )="0"+ STR$ s
  180 PRINT AT 11,12;t$
  190 GO TO 100
 9920 STOP 
 9930 PRINT #1;"It is time to":POKE 59360,192:PRINT #1;" wake  up":POKE 59360,128:PRINT #1;" you knuckle heads.":POKE 59360,64:PRINT #4;"  Rise and shine.   It's":POKE 59360,0:PRINT #4;" going to be a":POKE 59360,192:PRINT #4;" Golden":POKE 59360,128:PRINT #4;" Grahm":POKE 59360,64:PRINT #4;" day.":POKE 59360,0:PRINT #4;"  If you do not wake up this":POKE 59360,128:PRINT #4;" very ":POKE 59360,0:PRINT #4;"instant, I will be forced to kick yor rear" 
 9935 POKE 59360,192:PRINT #4;" butt   owr   patooty   buttoxs or ":POKE 59360,64:PRINT #4;"whatever u call it."
 9940 RETURN 
 9998 SAVE "TalkClock" LINE 0:SAVE "talkclockC"CODE 59200,6000

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

People

No people associated with this content.

Scroll to Top