Tomorrow Lies In Ambush!

This file is part of and CATS Library Tape 3. Download the collection to get this file.
Developer(s): Emmett Jenkins
Date: 198x
Type: Program
Platform(s): TS 2068

This program is a line-based word processor that stores up to 600 lines of 32-character text in a string array T$(600,32). It provides a menu-driven interface with eight options covering text entry, printer output via LPRINT, tape SAVE/LOAD of the array, on-screen display, editing, and appending. Color setup at startup uses a small subroutine dispatch table (lines 9000–9005) that increments a pointer variable G by 2 each iteration to step through BORDER, PAPER, and INK label strings. The edit routine uses POKE 23692,255 to suppress the “scroll?” prompt during line display, and the search routine (line 8000) scans for a sentinel “END” string padded to 32 characters to determine how many lines have been entered.


Program Analysis

Program Structure

The program is divided into clearly delineated functional blocks separated by REM statements and large line-number gaps, a common BASIC organizational convention:

  1. Lines 1–7: Title screen, color setup initialization
  2. Lines 8–80: Color selection loop (BORDER, PAPER, INK)
  3. Lines 200–370: Main menu dispatcher
  4. Lines 705–750: On-screen display routine (Option 7)
  5. Lines 1000–1051: Text input routine (Options 1 and 8)
  6. Lines 2000–2120: Printer output routine (Option 2)
  7. Lines 3000–3040: Tape save routine (Option 3)
  8. Lines 4000–4040: Tape load routine (Option 4)
  9. Lines 5000–5240: Edit routine (Option 5)
  10. Lines 6000–6010: End/NEW routine (Option 6)
  11. Lines 8000–8040: Search/count subroutine
  12. Lines 9000–9005: Color-label dispatch table
  13. Lines 9100–9160: Input instructions subroutine

Data Storage

All text is held in T$(600,32), a two-dimensional string array declared at line 6 with 600 rows of exactly 32 characters each. The capacity advertised on the title screen (“578 LINES DEEP”) is slightly less than the 600 allocated, with the gap unexplained in the code. A sentinel row containing the word END padded to 32 characters is used to mark the logical end of entered text; the search subroutine at line 8000 scans for this sentinel and stores the found index in variable X, which is then used as the upper bound in print and edit loops.

Color Selection Dispatch Table

Lines 9000–9005 implement a rudimentary dispatch table for the color setup loop. Variable G is initialized to 9000 and incremented by 2 after each of the three color inputs (lines 40 and 20), so successive GO SUB G calls land on lines 9000, 9002, and 9004, each setting A$ to "BORDER", "PAPER", or "INK" respectively before returning. This is an unconventional but functional use of a computed GO SUB.

Key BASIC Idioms

  • Key-release/key-press pair: Lines 280–290 use the standard idiom of first waiting for INKEY$ to be empty, then waiting for it to be non-empty, ensuring a clean single keypress detection before the dispatch chain at lines 300–370.
  • Scroll suppression: Line 5050 uses POKE 23692,255 to reset the line count in system variable SCRCT, preventing the “scroll?” prompt from appearing while printing lines during the edit routine.
  • Tape array save/load: Lines 3030 and 4030 use SAVE S$ DATA T$() and LOAD S$ DATA T$() to persist and restore the entire text array directly by name.
  • PAUSE 0 for keypress wait: Used at lines 745 and 9150 to halt execution until any key is pressed.

Notable Bugs and Anomalies

LocationIssue
Lines 300–366After the key-release/key-press idiom at lines 280–290, the dispatch chain at lines 300–366 re-reads INKEY$ independently on each line. Because INKEY$ is instantaneous and the key may no longer be held, many dispatches may be silently skipped, and execution can fall through to GO TO 290 at line 370, requiring the user to press the key again.
Line 366Option 8 (Add Text) performs a CLS before checking INKEY$="8", which clears the screen unnecessarily on every pass through the dispatcher for any non-8 key that reaches that line.
Lines 1005–1050Variable C is initialized to 1 unconditionally in the input routine, so Option 8 (“ADD TEXT”) which jumps to line 1010 bypasses line 1005 and preserves C, but the title screen note “TO ADD TO TEXT; PRESS ‘8’ TWICE!” is needed because the menu dispatch at line 366 itself only reaches that GO TO 1010 after the user presses 8 a second time (due to the INKEY$ re-read problem above).
Lines 5070 and 5150Both lines use NEXT F inline within an IF statement. While syntactically valid in Spectrum BASIC, embedding loop control inside a conditional can cause confusing control flow, especially when combined with the GO TO 5125 targets at lines 5170–5180, which reference line 5125 — a non-existent line number that falls through to line 5130.
Line 9160Contains RETURN : GO TO 1010. The GO TO 1010 is unreachable because RETURN transfers control back to the caller, making the trailing statement dead code.
Line 1020The END sentinel comparison string includes trailing spaces padded to 32 characters (e.g., "END "), which is correct given the fixed-width string array, but the literal appears to contain 29 trailing spaces rather than 31, potentially causing a mismatch depending on how the editor stored them.

Subroutine at Line 8999

Line 8999 contains GO TO 9998, which references a non-existent line and sits between the search subroutine (ending at line 8040) and the color-label table (starting at 9000). This acts as a fall-through guard to prevent execution from accidentally entering the color-label subroutines, a known technique for protecting lookup tables from unintended execution.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

Tomorrow Lies In Ambush!

Source Code

    1 REM EMMETT JENKINS 04/15/84
    2 PRINT AT 1,5; FLASH 1;"TOMORROW LIES IN AMBUSH!"; FLASH 0;AT 4,5;"WORD PROCESSOR",AT 6,5;"CREATED FOR:",AT 8,5; FLASH 1;"L.I.S.T!": FLASH 0
    3 FLASH 1: PRINT AT 12,5;"BY EMMETT JENKINS": FLASH 0: PRINT AT 15,5;"PRESS ANY KEY TO START!",AT 18,5;"32 CHARACTERS",AT 20,5;"578 LINES DEEP"
    4 PAUSE 4000
    5 LET X=0: LET B=0: LET G=9000: DIM A (3)
    6 DIM T$(600,32)
    7 CLS 
    8 FOR L=0 TO 32
    9 BRIGHT 1
   10 FOR F=1 TO 3
   13 CLS 
   20 GO SUB G
   30 PRINT AT 10,3;"INPUT:",A$;AT 12,7;"COLOR"
   40 LET G=G+2
   50 INPUT A(F)
   55 CLS 
   60 NEXT F
   70 BORDER A(1): PAPER A(2): INK A(3) 
   80 CLS 
  150 CLS 
  200 REM OPTIONS
  205 CLS : PRINT AT 1,5; FLASH 1;"PRESS NUMBER OF OPTION": FLASH 0
  210 PRINT AT 5,0;"OPTION 1";TAB 10;"ENTER TEXT"     
  215 PRINT 
  220 PRINT "OPTION 2";TAB 10;"PRINTOUT TEXT"
  225 PRINT 
  230 PRINT "OPTION 3";TAB 10;"SAVE TEXT"
  235 PRINT 
  240 PRINT "OPTION 4";TAB 10;"LOAD TEXT"
  245 PRINT 
  250 PRINT "OPTION 5";TAB 10;"EDIT TEXT"
  255 PRINT 
  270 PRINT "OPTION 6";TAB 10;"END"
  275 PRINT AT 17,0;"OPTION 7";TAB 10;"PRINT TEXT ON SCREEN"
  276 PRINT AT 19,0;"OPTION 8";TAB 10;"ADD TEXT"
  277 PRINT AT 21,0; FLASH 1;"TO ADD TO TEXT; PRESS '8' TWICE!"
  280 IF INKEY$<>"" THEN GO TO 280
  290 IF INKEY$="" THEN GO TO 290
  300 IF INKEY$="1" THEN GO TO 1000
  310 IF INKEY$="2" THEN GO TO 2000
  330 IF INKEY$="3" THEN GO TO 3000
  340 IF INKEY$="4" THEN GO TO 4000
  350 IF INKEY$="5" THEN GO TO 5000
  360 IF INKEY$="6" THEN GO TO 6000
  365 IF INKEY$="7" THEN GO TO 700
  366 CLS : IF INKEY$="8" THEN GO TO 1010
  370 GO TO 290
  705 CLS 
  710 GO SUB 8000
  720 FOR F=1 TO X
  730 PRINT T$(F)
  740 NEXT F
  745 PRINT AT 21,3; FLASH 1;"PRESS ANY KEY TO CONTINUE"; FLASH 0: PAUSE 0
  750 GO TO 200
 1000 REM INPUT ROUTINE
 1001 CLS 
 1002 GO SUB 9100
 1005 LET C=1
 1008 IF T$(C)=CHR$ 32 THEN BEEP .03,6
 1009 IF C=578 THEN PRINT AT 10,0; FLASH 1;"THAT WAS YOUR LAST LINE"; FLASH 0; FLASH 1;AT 13,0;"PRESS ANY KEY TO CONTINUE"; FLASH 0: PAUSE 500: GO TO 1051
 1010 INPUT T$(C):
 1020 IF T$(C)="END                             " OR T$(C)="end                             " THEN GO TO 205:                 
 1030 PRINT T$(C):
 1040 LET C=C+1
 1050 GO TO 1009
 1051 PRINT AT 15,3; FLASH 1;"NOW TYPE END"; FLASH 0: GO TO 1010
 2000 REM OUTPUT ROUTINE
 2050 GO SUB 8000
 2100 FOR F=1 TO X
 2110 LPRINT T$(F)
 2115 NEXT F
 2120 GO TO 200
 3000 REM SAVE ROUTINE
 3010 CLS : PRINT AT 10,0; FLASH 1;"INPUT NAME OF TEXT"; FLASH 0
 3020 INPUT S$
 3030 SAVE S$ DATA T$()
 3040 GO TO 200
 4000 REM LOAD TEXT ROUTINE
 4010 CLS : PRINT AT 10,0; FLASH 1;"INPUT NAME OF TEXT"; FLASH 0
 4020 INPUT S$
 4025 PRINT FLASH 1;"START TAPE"; FLASH 0
 4030 LOAD S$ DATA T$()
 4035 PRINT AT 16,10; FLASH 1;"STOP TAPE"; FLASH 0: PAUSE 500
 4040 GO TO 200
 5000 REM EDIT ROUTINE
 5001 CLS 
 5010 GO SUB 8000
 5020 PRINT FLASH 1;"TO EDIT LAST LINE PRESS '0'"; FLASH 0
 5025 PRINT 
 5030 FOR F=1 TO X
 5040 IF T$(F)="END                             " OR T$(F)="end                             " THEN GO TO 205
 5050 PRINT T$(F): POKE 23692,255
 5060 PAUSE 300
 5070 IF LEN INKEY$=0 THEN NEXT F: PRINT LEN INKEY$: GO TO 205
 5080 CLS : PRINT FLASH 1;"PRESS APPROPRIATE KEY"; FLASH 0
 5090 PRINT : PRINT "1 TO CONTINUE"
 5100 PRINT : PRINT "2 TO EDIT THIS LINE"
 5110 PRINT : PRINT "3 UP ONE LINE"
 5120 PRINT : PRINT "4 DOWN ONE LINE"
 5130 IF INKEY$<>"" THEN GO TO 5130
 5140 IF INKEY$="" THEN GO TO 5140
 5150 IF INKEY$="1" THEN CLS : NEXT F
 5160 IF INKEY$="2" THEN GO TO 5200
 5170 IF INKEY$="3" THEN LET F=F-1: GO TO 5125
 5180 IF INKEY$="4" THEN LET F=F+1: GO TO 5125
 5190 GO TO 5130
 5200 CLS : PRINT AT 5,0; FLASH 1;"RE-WRITE THIS LINE CORRECTLY!"; FLASH 0
 5210 PRINT AT 16,0;T$(F)
 5220 INPUT T$(F)
 5225 CLS : PRINT FLASH 1;"TO EDIT LAST LINE PRESS '0'"; FLASH 0: PRINT : PRINT T$(F)
 5230 NEXT F
 5240 GO TO 200
 6000 REM END ROUTINE
 6010 NEW 
 8000 REM SEARCH ROUTINE
 8010 FOR N=1 TO 600
 8020 IF T$(N)="END                             " OR T$(N)="end                             " THEN LET X=N: RETURN 
 8030 NEXT N
 8040 RETURN 
 8999 GO TO 9998
 9000 LET A$="BORDER"
 9001 RETURN 
 9002 LET A$="PAPER"
 9003 RETURN 
 9004 LET A$="INK"
 9005 RETURN 
 9100 PRINT AT 0,5;"THIS WORD PROCESSOR",AT 2,3;"WORKS JUST LIKE A TYPEWRITER",AT 4,5;"AT THE END OF EACH LINE",AT 6,5;"YOU PRESS THE ENTER KEY",AT 8,0;"YOU MAY ONLY ENTER 32 CHARACTERS",AT 12,2; INVERSE 1;"TO END TEXT INPUT,TYPE 'END'"; INVERSE 0
 9110 PRINT : PRINT : PRINT : PRINT 
 9130 PRINT AT 17,3; FLASH 1;"PRESS ANY KEY TO CONTINUE!": FLASH 0
 9140 PRINT 
 9150 PAUSE 0
 9155 CLS 
 9160 RETURN : GO TO 1010

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

Scroll to Top