--- title: "WORD 5+" id: 71296 type: "computer_media" slug: "word-5" url: "http://localhost/computer_media/word-5/" markdown_url: "http://localhost/computer_media/word-5.md" published_at: "2026-09-02T07:08:33+00:00" modified_at: "2026-09-02T07:08:34+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/word-2.png" excerpt: "A ten-page text editor with cursor movement, character and line insertion/deletion, tape save/load, and multi-copy printer output — all in BASIC." 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: "James DuPuy" slug: "james-dupuy" taxonomy: "indiv" url: "http://localhost/indiv/james-dupuy/" genre: - name: "Word Processor" slug: "word-processor" taxonomy: "genre" url: "http://localhost/type/word-processor/" media_type: "Program" programmers: - name: "James DuPuy" slug: "james-dupuy" taxonomy: "indiv" url: "http://localhost/indiv/james-dupuy/" download_url: "https://archive.org/download/timex-sinclair-software-archive/WORD%205%2B%20(198x)(Dupuy%2C%20James)(TS2068)(US)(Program).zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/word-2.png" - url: "http://localhost/wp-content/uploads/2026/09/word.png" media_type_tags: "Word Processor" --- # WORD 5+ WORD 5+ is a full-featured text editor that stores up to 10 pages of text in a three-dimensional string array `a$(11,22,32)`, giving 22 lines of 32 characters per page. The program supports cursor movement via control codes (codes 8–12), character insertion and deletion at the character and line level, uppercase lock via a toggle flag, and printing with multi-copy and page-range support through LPRINT. Files are saved and loaded as DATA arrays to tape, and a machine code block (“PRCODE”) loaded at address 64256 is used alongside specific POKE values to support printer interfacing. ON ERR is used both for tape-error recovery and as a guard against out-of-bounds array access at the cursor position. *** ### Program Structure The program is organized into clearly labeled subroutine blocks, each preceded by a REM comment. The main editing loop runs from lines 100–200, with a function dispatcher at lines 500–1000 that handles control-code keypresses. Separate subroutines cover printing (2000–2240), page navigation (3000–3200), tape save (4000–4020), tape load (5000–6000), space/line insert and delete (7000–9610), erase (8000–8200), and the instruction screen (9800–9920). ### Data Storage All text is held in the three-dimensional string array `a$(11,22,32)`. The first dimension (1–10) represents pages; dimension 11 is used as a scratch buffer in the line-insert and line-delete routines. The second dimension is the row (1–22, corresponding to screen rows 0–21), and the third is the column (1–32, corresponding to display columns 0–31). The variable `c` is the current page, `a` is the current row (0-based), and `b` is the current column (0-based), with `+1` offsets applied when indexing the array. ### Machine Code Block Line 9970 sets up a 1111-byte machine code block at address 64256 with `CLEAR 64255` and a series of POKEs, then loads it from tape as “PRCODE”. The POKEs to addresses 26703–26704 and 64256–64259 suggest printer driver configuration, likely patching the system’s printer output vector or configuring a specific hardware interface. This block is saved separately at line 9960 alongside the BASIC program. ### Key Detection and Control Codes The editing loop at line 100 reads `INKEY$` and dispatches based on character code. Printable characters (codes 14–122) are written to the array and displayed. Control codes handled in the subroutine at line 500 include: - Code 8 — cursor left - Code 9 — cursor right - Code 10 — cursor down - Code 11 — cursor up - Code 12 — backspace-delete (also handles wrap to previous line) - Code 13 — carriage return / new line - Code 7 — go to specific line and column via INPUT Keys outside the printable range (codes <14 or >123) are routed to the function dispatcher at line 500 via `GO SUB 500` at line 140. ### Spectrum Keyword Tokens as Commands Several extended-mode keypresses produce multi-character keyword tokens rather than single characters. The program exploits this by comparing `z$` to these token strings to trigger editing functions: | Token / z$ value | Function | Subroutine | | --- | --- | --- | | `"STOP "` | Print to paper | 2000 | | `" THEN "` | Go to next page | inline / 3030 | | `"<="` | Page navigation input | 3000 | | `"NOT "` | Save to tape | 4000 | | `" TO "` | Load from tape | 5000 | | `" STEP "` | Delete one space | 7000 | | `"AT "` | Insert one space | 7500 | | `">="` | Erase page or line | 8000 | | `" OR "` | Delete one line | 9000 | | `" AND "` | Insert one line | 9500 | | `"<>"` | Show instructions | 9800 | ### Caps Lock Toggle The underscore character (`_`, line 125) toggles a caps-lock mode. The flag variables `t` and `t1` control this: when active, `t` is set to 32, which is subtracted from the character code at line 160 (`CHR$ ((CODE z$)-t)`), converting lowercase letters (codes 97–122) to uppercase (codes 65–90). The flag `t1` tracks whether the shift is active, and line 150 resets `t` to 0 if a non-lowercase key is pressed while the lock is on, preventing erroneous shifts on control characters. ### Space and Line Insert/Delete The space-delete routine (7000–7100) copies the current row into `t$`, shifts characters from position `b+1` leftward by one, and restores the character that was displaced. The space-insert routine (7500–7600) shifts characters rightward from the cursor, dropping the last character off the end of the 32-character line. Line insert (9500–9610) and line delete (9000–9100) use page 11 of `a$()` as a temporary buffer to shift rows within the current page up or down. ### Printing The print section (2000–2240) offers single-page printing with a configurable copy count, or multi-page printing with a selectable first and last page. Page order can be reversed: if the first page number is greater than the last, the step is set to `-1` at line 2100, allowing pages to be printed in reverse sequence using `FOR p=f TO l STEP s`. Between copies, the program pauses and prompts the user to confirm readiness. ### Error Handling `ON ERR GO TO 100` at line 100 catches any runtime error in the main loop (such as an out-of-bounds array index when the cursor reaches the edge) and silently returns to the top of the loop. The tape load routine uses `ON ERR GO TO 6000` at line 5005 to catch load errors and prompt the user to rewind and retry. After the tape error handler at line 6000, `ON ERR RESET` clears the error trap. The instruction display at line 9800 also opens with `ON ERR RESET` for safety. ### Anomalies and Notes - Line 170’s page-overflow handler uses a nested `IF` with an `INPUT` that directly controls `c`, which is unusual structure for the era but functional. - Line 507 handles the case where the page limit of 10 is reached on a newline by jumping to an `INPUT` for a new page number rather than silently wrapping. - The scratch buffer in dimension 11 of `a$()` means the array is dimensioned to 11 pages but only 10 are user-accessible; this is intentional design. - Line 8040 manually sets each line to a 32-space string literal for page erase rather than using a loop or `DIM`-style reset, which is straightforward but verbose. - Line 9960 uses `SAVE "WORD 5+" LINE 9970` to auto-start at line 9970, which performs initialization POKEs and loads the machine code before the main program begins at line 2. ## Source Code ``` 1 REM Program "WORD" 2 CLS :BORDER 6 9 REM Initialize 10 POKE 23609,15 20 DIM a$(11,22,32) 25 DIM t$(32) 26 LET u$="" 27 LET t=0:LET t1=0 30 LET a=0:LET b=0:LET c=1 50 PRINT AT 10,8; FLASH 1;" Program:""word"" "; AT 11,8; "James G.Dupuy ":CIRCLE 124,86,85:PAUSE 200:CLS 60 GO SUB 9800 99 REM Key detect and print 100 ON ERR GO TO 100:PRINT AT a,b; FLASH 1;a$(c,a+1,b+1) 110 LET z$= INKEY$ 115 IF z$ <>"" THEN BEEP .005,40 120 IF z$="" THEN GO TO 100 125 IF z$="_" THEN GO TO 1010 130 IF z$ <>"" AND b >=30 THEN BEEP .02,20 140 IF CODE z$>123 OR CODE z$<14 THEN GO SUB 500 150 IF t1=1 AND CODE z$<97 THEN LET t=0 160 IF CODE z$>13 AND CODE z$<123 THEN LET a$(c,a+1,b+1)= CHR$ ((CODE z$)-t):PRINT AT a,b;a$(c,a+1,b+1):LET b=b+1 162 IF t1=1 THEN LET t=32 165 IF INKEY$ <>"" THEN PAUSE 10 170 IF b>31 THEN LET b=0:LET a=a+1:IF a>21 THEN INPUT FLASH 1;"Enter-next page,x-correct:";u$:IF u$="" THEN LET c=c+1:GO SUB 3030 175 IF u$="x" THEN LET a=21:LET b=31:LET u$="":LET a$(c,22,32)=" ":GO TO 165 180 IF u$ <>"" THEN GO TO 1100 200 GO TO 100 499 REM Function selector 500 PRINT AT a,b;a$(c,a+1,b+1) 505 IF CODE z$=13 THEN LET a=a+1:LET b=0:IF a>21 AND c<10 THEN LET c=c+1:CLS :GO SUB 3030 507 IF a>21 AND c >=10 THEN INPUT FLASH 1;"OUT OF PAGES!(Enter pages 1-10):";c:GO SUB 3030 510 IF CODE z$=8 THEN LET b=b-1:IF b<0 THEN LET b=0 520 IF CODE z$=9 THEN LET b=b+1:IF b>31 THEN LET b=31 530 IF CODE z$=10 THEN LET a=a+1:IF a>21 THEN LET a=21 540 IF CODE z$=11 THEN LET a=a-1:IF a<0 THEN LET a=0 550 IF CODE z$=12 THEN LET b=b-1:IF b >=0 THEN LET a$(c,a+1,b+1)="" 551 IF b<0 AND a>0 THEN LET b=31:LET a=a-1:LET a$(c,a+1,b+1)=" " 552 IF b<0 THEN LET b=0 560 IF z$="STOP " THEN GO TO 2000 570 IF z$=" THEN " THEN LET c=c+1:GO SUB 3030 580 IF z$="<=" THEN GO SUB 3000 590 IF z$="NOT " THEN GO SUB 4000 600 IF z$=" TO " THEN GO SUB 5000 620 IF z$=" STEP " THEN GO SUB 7000 640 IF z$="AT " THEN GO SUB 7500 700 IF z$=">=" THEN GO SUB 8000 720 IF z$=" OR " THEN GO SUB 9000 740 IF z$=" AND " THEN GO SUB 9500 780 IF z$="<>" THEN GO SUB 9800 800 IF CODE z$=7 THEN INPUT "Enter LINE# & Column#:";a;"-";b:IF a>21 OR a<0 OR b>31 OR b<0 THEN GO TO 800 1000 RETURN 1010 IF t=32 THEN LET t=0:LET t1=0:GO TO 1030 1020 IF t=0 THEN LET t=32:LET t1=1 1030 BEEP .3,50:GO TO 100 1100 INPUT "Enter-next page,x-correct:";u$:IF u$="x" THEN LET a=21:LET b=31:LET u$="":LET a$(c,22,32)=" ":GO TO 165 1120 IF u$="" THEN LET c=c+1:GO SUB 3030:GO TO 100 1200 GO TO 1100 1997 REM Paper printout 1998 REM 1999 REM 1 page,multiple copies 2000 INPUT "Print this page only?(Y/N):";y$:IF y$="n" OR y$="no" THEN GO TO 2100 2007 INPUT "If more than 1 copy Enter #:";m$:IF m$="" THEN LET m=1:GO TO 2010 2008 LET m= VAL m$ 2010 FOR o=1 TO m 2019 FOR n=1 TO a+1 2020 LPRINT a$(c,n) 2040 NEXT n 2044 IF o=m THEN GO TO 2050 2045 LPRINT ''':INPUT "Press ENTER for next Print";r$ 2050 NEXT o 2060 IF m>1 THEN LPRINT ''' 2070 GO TO 3000 2090 REM 2 pages or more of print 2100 INPUT "FIRST page to be printed:";f:INPUT "Last page to be printed:";l:IF f>l THEN LET s=-1:GO TO 2110 2105 LET s=1 2150 FOR p=f TO l STEP s 2170 FOR n=1 TO 22 2190 LPRINT a$(p,n) 2200 NEXT n 2220 NEXT p 2240 LPRINT ''' 2999 REM New page to screen 3000 CLS 3020 INPUT "Enter Page (1-10);:";c 3030 LET a=0:LET b=0 3035 IF c<1 OR c>10 THEN GO TO 3020 3040 CLS :PRINT AT 0,5;"You are now at page:";c:PAUSE 60:CLS 3050 FOR n=1 TO 22 3100 PRINT AT n-1,0;a$(c,n) 3150 NEXT n 3200 RETURN 3999 REM Save to tape 4000 INPUT "Enter File Name:";n$:IF LEN n$>10 THEN GO TO 4000 4010 SAVE n$ DATA a$() 4020 RETURN 4999 REM Load another 10 pages 5000 CLS :INPUT "Enter file to be loaded.(NAME):";f$:IF LEN f$>10 THEN GO TO 5000 5005 ON ERR GO TO 6000 5010 CLS :LOAD f$ DATA a$() 5050 CLS :PRINT AT 10,10; FLASH 1;"STOP TAPE ":PAUSE 100 5100 GO TO 3000 5999 REM Error trap 6000 CLS :PRINT "Tape loading error. Rewind tape and try again.":ON ERR RESET :PAUSE 100:GO TO 5000 7000 REM Delete one space 7010 LET t$=a$(c,a+1) 7020 LET a$(c,a+1,32)=" " 7025 PRINT AT a,31;" " 7027 LET g$=t$(b+1) 7030 FOR n=b+1 TO 31 7040 LET a$(c,a+1,n)=t$(n+1) 7060 NEXT n 7062 LET a$(c,a+1,b+1)=g$ 7064 PRINT AT a,0;a$(c,a+1) 7100 RETURN 7500 REM Insert one space 7510 LET t$=a$(c,a+1) 7525 LET a$(c,a+1,b+1)=" " 7530 FOR n=b+1 TO 31 7540 LET a$(c,a+1,n+1)=t$(n) 7560 NEXT n 7570 PRINT AT a,0;a$(c,a+1) 7600 RETURN 7990 STOP 7999 REM Erase routine 8000 INPUT "P-Page/L-Line,else resume";s$:IF s$="p" THEN GO TO 8020 8005 IF s$="l" THEN GO TO 8100 8010 RETURN 8015 REM Erase page 8020 CLS 8030 FOR n=1 TO 22 8040 LET a$(c,n)=" " 8050 NEXT n 8060 GO TO 3030 8090 REM Erase line 8100 INPUT "Cursor at the correct line?";s$:IF s$="n" THEN CLS :PRINT AT 20,0,"Move cursor to correct line,"'"then goto erase again.":PAUSE 100:GO TO 3035 8150 LET a$(c,a+1)=" " 8200 GO TO 3035 9000 REM Delete one line 9005 FOR n=1 TO 22 9010 LET a$(11,n)=a$(c,n) 9015 NEXT n 9020 LET a$(c,22)=" " 9030 FOR n=a+1 TO 21 9040 LET a$(c,n)=a$(11,n+1) 9050 NEXT n 9070 FOR n=1 TO 22 9080 PRINT AT n-1,0;a$(c,n) 9090 NEXT n 9100 RETURN 9500 REM Insert one line 9505 FOR n=1 TO 22 9510 LET a$(11,n)=a$(c,n) 9515 NEXT n 9530 FOR n=a+1 TO 21 9540 LET a$(c,n+1)=a$(11,n) 9550 NEXT n 9560 LET a$(c,a+1)=" " 9570 FOR n=1 TO 22 9580 PRINT AT n-1,0;a$(c,n) 9590 NEXT n 9610 RETURN 9799 REM Print instructions 9800 ON ERR RESET :CLS :PRINT "The following keys&symble-shift will do the following:" 9810 PRINT "A--- to get print out on paper. S--- to save pages." 9820 PRINT "D--- to delete a single space. I--- to insert a single space. U--- to delete a single line. Y--- to insert a single line." 9830 PRINT "Q--- to see a new page . E--- to erase a page or line. G--- to go to next page. F--- to load a new set of pages." 9835 PRINT "_--- to activate CAP lock." 9840 PRINT '"Caps-shift & the arrow keys willmove the cursor that way." 9850 PRINT '"Caps-shift & Delete will back- space & erase asit goes." 9860 PRINT '"Symbol-shift & ""W"" to get these instructions again." 9900 INPUT "Press C-for copy,Enter-cont";x$ 9910 IF x$="c" THEN COPY 9920 GO TO 3035 9950 STOP 9960 SAVE "WORD 5+" LINE 9970:SAVE "PRCODE"CODE 64256,1111:STOP 9970 CLEAR 64255:POKE 26703,4:POKE 26704,251:POKE 64256,1:POKE 64258,0:POKE 64257,0:POKE 64259,79:LOAD "PRCODE"CODE 64256,1111 ```