Word Wizard

This file is part of and 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

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
 1100 LET E$=A$(A,672)+E$
 1120 LET A$(A)=A$(A,1 TO POS-1)+" "+A$(A,POS TO 672)
 1130 LET POS=POS+1
 1135 IF LEN E$>200 THEN GOTO 9090
 1140 GOTO 515
 1210 LET E$=A$(A,672-32 TO 672)+E$
 1220 LET A$(A)=A$(A,1 TO POS-1)+"                                "+A$(A,POS TO 672)
 1240 GOTO 515
 1300 PRINT AT 21,13;"ENTER TEXT"
 1320 INPUT X$
 1330 LET X=LEN X$
 1340 LET E$=A$(A,672-X TO 672)+E$
 1350 LET A$(A)=A$(A,1 TO POS-1)+X$+A$(A,POS TO 672)
 1360 IF LEN E$>200 THEN GOTO 9200
 1365 PRINT AT 21,13;"% % % % % % % % % % "
 1370 GOTO 515
 1400 LET A$(A,POS)=" "
 1410 PRINT AT WL,WC;A$(A,POS)
 1420 GOTO 520
 1500 GOSUB 2500
 1510 IF A=5 THEN LET A=0
 1520 LET A=A+1
 1530 GOTO 511
 1600 GOSUB 2500
 1610 IF A=1 THEN LET A=6
 1620 LET A=A-1
 1630 GOTO 511
 1710 PAUSE 100
 1720 IF INKEY$="" THEN GOTO 1720
 1740 LET A$(A,POS)=INKEY$
 1750 GOTO 536
 1800 PRINT AT 21,13;"AMOUNT?"
 1810 INPUT X
 1820 LET F$=A$(A,POS-X TO POS-1)
 1830 LET A$(A)=A$(A,1 TO POS-X-1)+A$(A,POS TO 672)
 1840 PRINT AT 21,13;"% % % % % % % "
 1850 GOTO 515
 1910 LET A$(A)=A$(A,1 TO POS-1)+F$+A$(A,POS TO 672)
 1920 LET F$=""
 1930 GOTO 515
 2010 GOSUB 2500
 2020 GOTO 515
 2200 IF E$="" THEN LET A$(A)=A$(A,1 TO POS-2)+A$(A,POS TO 672)
 2210 IF E$<>"" THEN LET A$(A)=A$(A,1 TO POS-2)+A$(A,POS TO 672)+E$(1)
 2220 IF E$<>"" THEN LET E$=E$(2 TO )
 2230 LET POS=POS-1
 2240 GOTO 515
 2500 IF E$="" THEN RETURN 
 2510 LET X=LEN E$
 2520 FOR B=A+1 TO 4
 2530 LET G$=A$(B,672-X TO 672)
 2540 LET A$(B)=E$+A$(B,1 TO 672-X-1)
 2550 LET E$=G$
 2560 NEXT B
 2570 LET E$=""
 2580 RETURN 
 3000 LET POS=POS-1
 3005 LET A$(A,POS)=" "
 3006 PRINT AT WL,WC;A$(A,POS+1)
 3010 GOTO 520
 3800 LET A=A+1
 3810 IF A>5 THEN GOTO 9100
 3820 GOTO 511
 7000 PRINT AT WL,WC;A$(A,POS)
 7005 LET POS=1
 7010 GOTO 520
 7020 LET E$=""
 7030 GOTO 520
 8000 LET WC=31
 8010 LET WL=WL-1
 8020 RETURN 
 9000 PRINT AT 21,0;"%E%R%R%O%R:NO SUCH PAGE"
 9010 FOR B=0 TO 30
 9020 NEXT B
 9030 PRINT AT 21,0;"                                "
 9040 GOTO 51
 9070 PRINT AT 21,13;"END OF PAGE"
 9071 FOR B=0 TO 30
 9072 NEXT B
 9073 GOTO 38
 9090 PRINT AT 21,13;"BUFFER FULL"
 9091 FOR B=0 TO 30
 9092 NEXT B
 9093 GOTO 38
 9100 PRINT AT 21,13;"ALL FILES USED"
 9110 FOR B=0 TO 30
 9120 NEXT B
 9130 GOTO 38
 9200 PRINT AT 21,13;"TOO MUCH% % "
 9210 FOR B=0 TO 30
 9220 NEXT B
 9230 GOTO 38
 9240 CLEAR 
 9250 SAVE "1008%7"
 9260 RUN 

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

Scroll to Top