Word Wizard

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Ryan Gray
Date: 1983
Type: Program
Platform(s): TS 1000

Word Wizard is a multi-page text editor that stores up to five pages of 672 characters each in a two-dimensional string array, allowing the user to write, edit, save, and print documents. The editor features cursor movement, character insertion and deletion, a cut buffer for block operations, and a paste function, all driven by INKEY$ polling for keyboard input. Pages are displayed 32 characters wide across 21 lines, with the status bar on line 21 showing the current page number in inverse video. The program saves the entire file to tape using the filename entered at startup, and can send any page to a printer via LPRINT. An overflow buffer string E$ acts as a soft-wrap mechanism, carrying displaced characters from the end of one page when text is inserted.


Program Analysis

Program Structure

The program is organized into a startup/initialization block, a main menu, and a collection of subroutines and handler sections addressed by line number. The flow is:

  1. Lines 7–11: Variable initialization (C, A$, C$, E$, F$).
  2. Lines 19–28: Filename entry, reading exactly 10 keypresses with INKEY$ polling.
  3. Lines 29–38: Conditional SAVE (skipped when C=1 meaning a file-clear is in progress).
  4. Lines 39–74: Main menu display and option dispatch.
  5. Lines 100–590: Menu handlers — save (100), print (200), clear page (300), clear file (400), write page (500+).
  6. Lines 595–670: Main editing loop — character input, cursor positioning, key dispatch.
  7. Lines 1100–2580: Editing operations (insert, delete, cut, paste, page navigation, etc.).
  8. Lines 3000–3820: Backspace and page overflow.
  9. Lines 7000–8020: Home cursor and clear-buffer subroutines.
  10. Lines 9000–9260: Error/status message handlers and program end.

Data Storage

All text is held in A$(5,672) — a five-element array where each element is a fixed-length 672-character string, equivalent to 21 rows of 32 characters per page. Position within the current page is tracked by the integer variable POS (1–672).

Cursor Display Technique

The editor simulates a blinking cursor by alternating between printing the character at the current position normally and printing it in inverse video (character code + 128). The loop at lines 537–551 prints the inverse character, polls INKEY$, then restores the normal character and polls again, creating a flicker effect without any PAUSE.537 PRINT AT WL,WC;CHR$ (CODE A$(A,POS)+128)

Screen Position Calculation

Row and column are derived arithmetically from POS on every iteration. WL (line) is INT(POS/32) and WC (column) is POS - WL*32 - 1. A special boundary fix at line 535/8000 corrects the case where POS falls exactly on a 32-character boundary, forcing the cursor back to column 31 of the previous row.

Key Dispatch Table

After filtering printable characters (code ≥ 64), the editor checks a long series of IF statements at lines 568–590 for control characters. The mappings are:

CHR$ CodeAction / Target
112–115Cursor movement (up/down/left/right) → line 660
116Return to main menu → line 38
117Next page → line 1500
118NEWLINE remapped to space (line 565)
119Backspace/delete → line 3000
121End-of-line jump → line 631
192Special character input mode → line 1700
216Home (POS=1) → line 7000
217Clear character at cursor → line 1400
218Previous page → line 1600
219Unknown/extended → line 2000
220Insert line → line 1200 (handler at 1210)
221Clear E$ buffer → line 7020
222Cut block → line 1800
223Paste block → line 1900 (handler at 1910)
224Insert text string → line 1300
225Insert single space → line 1100
228Backspace with buffer restore → line 2200
229Remapped to £ (line 567)

Overflow Buffer (E$)

When characters are inserted, the rightmost character(s) pushed off the end of the current page’s 672-character string are prepended to the string variable E$. The subroutine at line 2500 distributes any accumulated E$ content to subsequent pages (pages A+1 through 4), displacing their own tail characters down the chain. This implements a rudimentary soft-flow between pages, though it is limited: E$ is capped at 200 characters (checked at line 1135) before an error is raised.

Cut and Paste

The cut operation (line 1800) prompts for a character count X, copies A$(A, POS-X TO POS-1) into the paste buffer F$, then removes those characters from the page string. Paste (line 1910) inserts F$ back at the current position. Note that this is a destructive cut (not a copy), and F$ is cleared after pasting.

End-of-Line Jump

The jump-to-end-of-line shortcut at line 631 calculates the remaining columns on the current screen row as UU = (WL+1)*32 - POS and advances POS by UU+1, effectively moving the cursor to the start of the next line.

Bugs and Anomalies

  • Lines 660–665 handle cursor movement, but line 661 is reached by a fall-through from a GOTO 660 at line 569; however, the label dispatched to is 660, which does not exist in the listing — line 661 is the first line in that block. This is a harmless off-by-one in label naming, not in logic, since GO TO a missing line runs the next higher line.
  • Lines 1200 and 1700/1740/1750 are referenced (line 581 → 1200; line 571 → 1700) but their entry points at 1200 and 1700 are absent from the listing — execution falls through to lines 1210 and 1710 respectively, which is the intended behavior given the GO TO missing-line idiom.
  • Line 785 is unreachable dead code; the GOSUB 8000 there duplicates the boundary check already performed at line 535.
  • Lines 2010–2020 (GOSUB 2500 then GOTO 515) are reached from line 574 (CHR$ 219) but the intent of this key is unclear — it flushes the overflow buffer without any other action.
  • The “clear file” path at line 409 sets C=1 and jumps to line 8, which does not exist; execution falls to line 9 (the variable init block), effectively re-initializing without saving. This is the intended clear-file behavior.
  • Lines 9240–9260 (CLEAR, SAVE, RUN) appear to be a developer utility to save the program itself and are never reached by any normal execution path.

SLOW Mode Usage

SLOW is called at lines 38 and 536 to switch the display to the standard 50% CPU / display-generation sharing mode. This is used deliberately in the editor loop to keep the screen stable during cursor blinking, accepting the performance trade-off.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

Word Wizard

Source Code

   1 REM :::::::::::::::
   2 REM ::WORD WIZARD::
   3 REM ::    BY     ::
   4 REM :: RYAN GRAY ::
   5 REM ::  3/3/83   ::
   6 REM :::::::::::::::
   7 LET C=0
   8 DIM A$(5,672)
   9 LET C$=""
  10 LET E$=""
  11 LET F$=""
  19 CLS 
  20 PRINT AT 10,0;" ENTER FILE NAME. ----------"
  21 FOR A=1 TO 10
  22 LET B$=INKEY$
  23 IF B$="" THEN GOTO 22
  24 IF B$=CHR$ 118 THEN LET B$=" "
  25 PRINT AT 10,A+17;B$
  26 LET C$=C$+B$
  27 NEXT A
  28 LET D$=C$
  29 IF C=1 THEN GOTO 38
  30 PRINT ,,,," SAVING:";C$
  31 PAUSE 200
  32 SAVE C$
  38 SLOW 
  39 LET C=0
  40 CLS 
  41 PRINT "CURRENT FILE:";D$
  42 PRINT ,,"    WORD WIZARD BY RYAN GRAY    "
  43 PRINT "\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.."
  44 PRINT ,,"   MENU:"
  45 PRINT ,,"     1:SAVE FILE"
  46 PRINT ,,"     2:SEND PAGE TO PRINTER"
  47 PRINT ,,"     3:CLEAR PAGE"
  48 PRINT ,,"     4:CLEAR FILE"
  49 PRINT ,,"     5:WRITE PAGE"
  51 PRINT AT 21,0;"OPTION?    "
  52 PRINT AT 21,6;"?"
  53 LET B$=INKEY$
  54 IF B$<>"" THEN GOTO 60
  55 PRINT AT 21,6;"%?"
  56 GOTO 52
  60 IF B$<"1" OR B$>"6" THEN GOTO 55
  70 IF B$="1" THEN GOTO 100
  71 IF B$="2" THEN GOTO 200
  72 IF B$="3" THEN GOTO 300
  73 IF B$="4" THEN GOTO 400
  74 IF B$="5" THEN GOTO 500
 100 CLS 
 110 GOTO 9
 200 PRINT AT 21,0;"WHICH PAGE?"
 210 INPUT A
 211 IF A<1 OR A>5 THEN GOTO 9000
 212 LPRINT "PAGE:";A
 213 LPRINT 
 220 LPRINT A$(A)
 230 GOTO 51
 300 PRINT AT 21,0;"WHICH PAGE?"
 310 INPUT A
 311 IF A<1 OR A>5 THEN GOTO 9000
 312 LET A$(A)=""
 317 GOTO 51
 400 PRINT AT 21,0;"CONFIRM.Y/N"
 401 IF INKEY$="" THEN GOTO 401
 402 IF INKEY$="Y" THEN GOTO 409
 403 GOTO 51
 409 LET C=1
 410 GOTO 8
 500 PRINT AT 21,0;"WHICH PAGE?"
 505 INPUT A
 510 IF A<1 OR A>5 THEN GOTO 9000
 511 CLS 
 512 LET POS=1
 513 LET B$=CHR$ (CODE (STR$ A)+128)
 514 PRINT AT 21,0;"% %W%O%R%D% %W%I%Z%A%R%D% % % % % % % % % % % % % %P%A%G%E%:";B$;"% "
 515 PRINT AT 0,0;A$(A)
 520 LET WL=INT (POS/32)
 530 LET WC=POS-WL*32-1
 535 IF POS/32=INT (POS/32) THEN GOSUB 8000
 536 SLOW 
 537 PRINT AT WL,WC;CHR$ (CODE A$(A,POS)+128)
 538 LET X$=INKEY$
 539 IF X$<>"" THEN GOTO 560
 540 PRINT AT WL,WC;A$(A,POS)
 550 LET X$=INKEY$
 551 IF X$="" THEN GOTO 537
 560 REM 
 565 IF X$=CHR$ 118 THEN LET X$=" "
 567 IF X$=CHR$ 229 THEN LET X$="£"
 568 IF CODE X$<64 THEN GOTO 595
 569 IF CODE X$>111 AND CODE X$<116 THEN GOTO 660
 570 IF X$=CHR$ 116 THEN GOTO 38
 571 IF X$=CHR$ 192 THEN GOTO 1700
 572 IF X$=CHR$ 217 THEN GOTO 1400
 573 IF X$=CHR$ 224 THEN GOTO 1300
 574 IF X$=CHR$ 219 THEN GOTO 2000
 575 IF X$=CHR$ 117 THEN GOTO 1500
 576 IF X$=CHR$ 221 THEN GOTO 7020
 577 IF X$=CHR$ 216 THEN GOTO 7000
 578 IF X$=CHR$ 225 THEN GOTO 1100
 579 IF X$=CHR$ 228 THEN GOTO 2200
 580 IF X$=CHR$ 121 THEN GOTO 631
 581 IF X$=CHR$ 220 THEN GOTO 1200
 586 IF X$=CHR$ 119 THEN GOTO 3000
 588 IF X$=CHR$ 218 THEN GOTO 1600
 589 IF X$=CHR$ 222 THEN GOTO 1800
 590 IF X$=CHR$ 223 THEN GOTO 1900
 595 LET A$(A,POS)=X$
 600 PRINT AT WL,WC;A$(A,POS)
 610 LET POS=POS+1
 620 IF POS>672 OR POS<1 THEN GOTO 3800
 630 GOTO 520
 631 LET UU=(WL+1)*32-POS
 632 LET POS=POS+UU+1
 633 PRINT AT WL,WC;A$(A,POS-UU-1)
 634 GOTO 620
 661 PRINT AT WL,WC;A$(A,POS)
 665 LET POS=POS+(X$=CHR$ 115)-(X$=CHR$ 114)+32*(X$=CHR$ 113)-32*(X$=CHR$ 112)
 670 GOTO 620
 785 IF POS/32=INT (POS/32) THEN GOSUB 8000
\n1100 LET E$=A$(A,672)+E$
\n1120 LET A$(A)=A$(A,1 TO POS-1)+" "+A$(A,POS TO 672)
\n1130 LET POS=POS+1
\n1135 IF LEN E$>200 THEN GOTO 9090
\n1140 GOTO 515
\n1210 LET E$=A$(A,672-32 TO 672)+E$
\n1220 LET A$(A)=A$(A,1 TO POS-1)+"                                "+A$(A,POS TO 672)
\n1240 GOTO 515
\n1300 PRINT AT 21,13;"ENTER TEXT"
\n1320 INPUT X$
\n1330 LET X=LEN X$
\n1340 LET E$=A$(A,672-X TO 672)+E$
\n1350 LET A$(A)=A$(A,1 TO POS-1)+X$+A$(A,POS TO 672)
\n1360 IF LEN E$>200 THEN GOTO 9200
\n1365 PRINT AT 21,13;"% % % % % % % % % % "
\n1370 GOTO 515
\n1400 LET A$(A,POS)=" "
\n1410 PRINT AT WL,WC;A$(A,POS)
\n1420 GOTO 520
\n1500 GOSUB 2500
\n1510 IF A=5 THEN LET A=0
\n1520 LET A=A+1
\n1530 GOTO 511
\n1600 GOSUB 2500
\n1610 IF A=1 THEN LET A=6
\n1620 LET A=A-1
\n1630 GOTO 511
\n1710 PAUSE 100
\n1720 IF INKEY$="" THEN GOTO 1720
\n1740 LET A$(A,POS)=INKEY$
\n1750 GOTO 536
\n1800 PRINT AT 21,13;"AMOUNT?"
\n1810 INPUT X
\n1820 LET F$=A$(A,POS-X TO POS-1)
\n1830 LET A$(A)=A$(A,1 TO POS-X-1)+A$(A,POS TO 672)
\n1840 PRINT AT 21,13;"% % % % % % % "
\n1850 GOTO 515
\n1910 LET A$(A)=A$(A,1 TO POS-1)+F$+A$(A,POS TO 672)
\n1920 LET F$=""
\n1930 GOTO 515
\n2010 GOSUB 2500
\n2020 GOTO 515
\n2200 IF E$="" THEN LET A$(A)=A$(A,1 TO POS-2)+A$(A,POS TO 672)
\n2210 IF E$<>"" THEN LET A$(A)=A$(A,1 TO POS-2)+A$(A,POS TO 672)+E$(1)
\n2220 IF E$<>"" THEN LET E$=E$(2 TO )
\n2230 LET POS=POS-1
\n2240 GOTO 515
\n2500 IF E$="" THEN RETURN 
\n2510 LET X=LEN E$
\n2520 FOR B=A+1 TO 4
\n2530 LET G$=A$(B,672-X TO 672)
\n2540 LET A$(B)=E$+A$(B,1 TO 672-X-1)
\n2550 LET E$=G$
\n2560 NEXT B
\n2570 LET E$=""
\n2580 RETURN 
\n3000 LET POS=POS-1
\n3005 LET A$(A,POS)=" "
\n3006 PRINT AT WL,WC;A$(A,POS+1)
\n3010 GOTO 520
\n3800 LET A=A+1
\n3810 IF A>5 THEN GOTO 9100
\n3820 GOTO 511
\n7000 PRINT AT WL,WC;A$(A,POS)
\n7005 LET POS=1
\n7010 GOTO 520
\n7020 LET E$=""
\n7030 GOTO 520
\n8000 LET WC=31
\n8010 LET WL=WL-1
\n8020 RETURN 
\n9000 PRINT AT 21,0;"%E%R%R%O%R:NO SUCH PAGE"
\n9010 FOR B=0 TO 30
\n9020 NEXT B
\n9030 PRINT AT 21,0;"                                "
\n9040 GOTO 51
\n9070 PRINT AT 21,13;"END OF PAGE"
\n9071 FOR B=0 TO 30
\n9072 NEXT B
\n9073 GOTO 38
\n9090 PRINT AT 21,13;"BUFFER FULL"
\n9091 FOR B=0 TO 30
\n9092 NEXT B
\n9093 GOTO 38
\n9100 PRINT AT 21,13;"ALL FILES USED"
\n9110 FOR B=0 TO 30
\n9120 NEXT B
\n9130 GOTO 38
\n9200 PRINT AT 21,13;"TOO MUCH% % "
\n9210 FOR B=0 TO 30
\n9220 NEXT B
\n9230 GOTO 38
\n9240 CLEAR 
\n9250 SAVE "1008%7"
\n9260 RUN 

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

Scroll to Top