Full-screen word processor for the TS2068, published in 1984 by RHEESWARE. It supports up to five pages of text, stored in a 30,400-byte RAM buffer that spans addresses 33307–63686 — a precisely planned layout that leaves the machine code block (USR 63707, 1830 bytes) immediately adjacent above. Page store and retrieval are handled by machine code routines, and two custom fonts embedded within that same block are selectable at runtime alongside the standard ROM character set. The editor supports word wrap, INVERSE text, a graphics mode for entering block characters, tape save/load of the full document buffer, and COPY-based printing of single or all pages.
Program Structure
| Lines | Section |
|---|---|
| 5–6 | Initialization — CLEAR, load machine code from tape, set colors, cold-start clear all pages |
| 8–200 | Main editor input loop |
| 300–710 | Editing operations (ENTER, TAB, line clear, CAPS LOCK toggle) |
| 800–960 | Graphics mode — remaps keys to block graphic characters |
| 1000–1060 | STOP menu: Print / Clear / Tape / Set / Return |
| 2000–2100 | Startup subroutine: loads machine code, initializes arrays and character set data |
| 3000–3050 | Page-up navigation |
| 3200–3320 | Machine code store/retrieve page subroutines |
| 3400–3490 | Print routine (COPY / all pages / single page) |
| 4000–4240 | Tape save/load of document memory |
| 5000–5020 | Character set selection |
| 6000–6090 | Extended Sinclair keyword handling (STOP, NOT, STEP, TO, >=, <=) |
| 6100–6155 | Clear/new page operations |
| 6200–6310 | Next/previous page navigation |
| 7000 | Resume editing after page change |
| 8000 | DATA — block graphic character code tables |
| 8020 | DATA — character set ROM addresses (three sets) |
| 9000 | Error handler — reset and STOP |
| 9997/9999 | Development SAVE lines |
Key Technical Features
Machine code block. Line 2000 loads 1830 bytes of machine code (saved as "type"CODE 63707,1830). This block contains:
- Page store routine at USR 63807 — copies current screen content into the page buffer area
- Page retrieve routine at USR 63819 — restores a page from the buffer to the screen
- Special character renderers at USR 63707 and 63757 (called when the editor encounters
>=and<=tokens) - Two embedded custom fonts — pointed to by the character set data in the
s(3,2)array
Memory layout — elegantly planned. CLEAR 33305 sets RAMTOP just below the document storage area. Up to 5 pages are stored at 33307 + 6080*(page-1), filling addresses 33307–63686 (exactly 5 × 6080 = 30,400 bytes). The machine code block begins immediately after at 63707. There is no wasted space.
Multi-page document model. Up to 5 pages (pg variable, limited at line 6200). top tracks the highest page written. Page store/retrieve via machine code routines at every page navigation event.
Three selectable character sets. POKE 23606/23607 switches the ROM character pointer. From the DATA at line 8020 (values: 0, 60, 87, 248, 87, 251):
- Set 1: address 15360 — standard ROM font
- Set 2: address ~63575 — custom font embedded in machine code block
- Set 3: address ~64343 — second custom font, also in machine code block
Word wrap. Lines 53–59 detect when the cursor hits column 12 (triggering wrap-word assembly) and column 32 (end of line), then scan backward for the last space and reprint from that point on the next line.
Graphics mode. CHR$ 15 toggles a graphics flag (g). In graphics mode (lines 800–960), letter keys are remapped through the a() and b() arrays (populated from the 16-value DATA at line 8000: 140,129,139,130,141,131,142,132,138,133,143,134,137,135,136,128) to TS2068 block graphic characters. Some letter keys additionally produce compound keyword tokens (©, [, ], ON ERR, BEEP, \).
AY sound. Line 6 configures multiple AY chip registers via a long SOUND statement. Line 52 silences register 13 at column 6 — suggesting a click or tone keyed to certain cursor positions.
Content
Source Code
5 CLEAR 33305: GO SUB 2000: PAPER 7: INK 9: BORDER 4: CLS
6 SOUND 7,60;8,16;9,16;0,32;1,0;2,65;3,0;12,10;13,0: LET a$="ca": GO TO 6100
8 LET b=0: LET g=0: PRINT OVER 1;" ";CHR$ 8;
9 IF INKEY$<>"" THEN LET i$=INKEY$: GO TO 12
10 PAUSE 0: LET I$=INKEY$:
12 IF g THEN GO TO 800
15 IF i$<" " THEN GO TO 100
20 IF i$="_" THEN LET b=0: LET i$=CHR$ 21+CHR$ 1+"_": GO TO 40
35 IF i$>"©" THEN GO TO 6000
40 IF PEEK 23689=3 AND PEEK 23688=2 THEN GO TO 60
50 PRINT i$; OVER 1;" ";CHR$ 8;
52 IF PEEK 23688=6 THEN SOUND 13,0
53 IF PEEK 23688=12 THEN LET b=1: LET b$=""
54 IF NOT b THEN GO TO 10
55 LET b$=b$(2 TO )+i$: IF PEEK 23688<>32 THEN GO TO 10
56 LET b=0: IF b$(10)=" " THEN LET i$=CHR$ 8: GO TO 130
57 IF b$(9)="-" THEN GO TO 10
58 FOR a=10 TO 1 STEP -1: IF b$(a)=" " THEN PRINT AT 23-PEEK 23689,22+a;c$(a+1 TO );b$(a+1 TO ); OVER 1;" ";CHR$ 8;: GO TO 9
59 NEXT a: GO TO 9
60 PRINT i$;CHR$ 8; OVER 1;" ";CHR$ 8;
70 BEEP .5,-20: GO TO 10
100 IF I$=CHR$ 12 THEN PRINT " ";CHR$ 8;CHR$ 8;" ";CHR$ 8;: LET b$="x"+b$: GO TO 10
110 IF i$=CHR$ 11 THEN GO TO 3000
120 IF i$=CHR$ 13 THEN GO TO 300
130 IF i$=CHR$ 8 THEN PRINT OVER 1;" ";CHR$ 8;CHR$ 8;" ";CHR$ 8;: LET b$="x"+b$: GO TO 10
135 IF i$=CHR$ 7 THEN IF NOT (PEEK 23689=3 AND PEEK 23688<20) THEN PRINT OVER 1;," ";CHR$ 8;: LET b=0: GO TO 10
140 IF i$=CHR$ 9 THEN GO TO 400
150 IF i$=CHR$ 10 THEN GO TO 600
160 IF i$=CHR$ 6 THEN GO TO 700
170 IF I$=CHR$ 5 THEN INVERSE 1
180 IF i$=CHR$ 4 THEN INVERSE 0
190 IF i$=CHR$ 15 AND g=0 THEN LET g=1: POKE 23658,0
200 GO TO 10
300 LET b=0: IF PEEK 23689=3 THEN GO TO 6200
310 PRINT OVER 1;" ";: GO TO 40
400 IF PEEK 23689=3 AND PEEK 23688=2 THEN GO TO 70
410 LET b=0: PRINT OVER 1; INVERSE 0;" ";CHR$ 8;: GO TO 10
600 LET b=0: IF PEEK 23689=3 THEN GO TO 6200
610 PRINT OVER 1;" ";CHR$ 8;: GO TO 10
700 IF PEEK 23658=0 THEN POKE 23658,8: GO TO 10
710 POKE 23658,0: GO TO 10
800 LET b=0: IF i$=CHR$ 15 THEN LET g=0: GO TO 10
810 LET i=CODE i$: IF i>64 AND i<90 THEN LET i$=" ": GO TO 900
820 IF i>96 AND i<118 THEN LET i$=CHR$ (i+47): GO TO 40
830 IF i>3 AND i<12 THEN LET i$=CHR$ a(i-3): GO TO 40
840 IF i>48 AND i<57 THEN LET i$=CHR$ b(i-48): GO TO 40
850 IF i=32 THEN GO TO 40
860 IF i$=" STOP " THEN GO TO 1000
862 IF i=13 THEN GO TO 300
864 IF i=12 THEN GO TO 100
870 GO TO 10
900 IF i=80 THEN LET i$="©"
910 IF i=89 THEN LET i$="["
920 IF i=85 THEN LET i$="]"
930 IF i=70 THEN LET i$="ON ERR"
940 IF i=71 THEN LET i$="BEEP "
950 IF i=68 THEN LET i$="\"
960 GO TO 40
1000 INVERSE 0: POKE 23606,0: POKE 23607,60: LET i$=STR$ pg: INPUT PAPER 2; INK 7;VAL$ "i$";" Prnt/Clr/Tape/Set/Ret "; LINE a$
1010 IF a$(1)="p" OR a$(1)="P" THEN GO TO 3400
1020 IF a$(1)="c" OR a$(1)="C" THEN GO TO 6100
1030 IF a$="r " OR a$="R " THEN GO TO 5020
1040 IF a$="t " OR a$="T " THEN GO TO 4000
1055 IF a$="s " OR a$="S " THEN GO TO 5000
1060 GO TO 1000
1100 BEEP .5,-20
1110 LET i=pg: GO SUB 3305: ON ERR RESET : GO TO 5020
2000 CLS : PRINT AT 10,4;"LOADING PLEASE WAIT"'''"*** TYPE *** ©1984 by RHEESWARE": LOAD ""CODE
2010 LET top=1: DIM c$(10): DIM a(8): DIM b(8)
2020 RESTORE : FOR i=1 TO 8: READ a(i),b(i): NEXT i
2030 DIM b$(10)
2040 DIM a$(2)
2070 DIM s(3,2): FOR i=1 TO 3: READ s(i,1),s(i,2): NEXT i: LET set=1
2100 RETURN
3000 LET b=0: IF PEEK 23689=24 AND pg>1 THEN GO TO 3050
3010 PRINT OVER 1;" ";CHR$ 8;: FOR a=1 TO 16: PRINT CHR$ 8;CHR$ 8;: NEXT a: PRINT OVER 1;" ";CHR$ 8;: GO TO 10
3050 LET i=pg: GO SUB 3200: LET i=i-1: LET pg=i: GO SUB 3300: PRINT AT 21,0; OVER 1;" ";CHR$ 8;: GO TO 10
3200 REM store
3205 LET a=33307+6080*(i-1): IF i>top THEN LET top=i
3210 POKE 63809,INT (a/256): POKE 63808,a-256*PEEK 63809
3230 RANDOMIZE USR 63807: RETURN
3300 CLS : REM get
3305 LET a=33307+6080*(i-1)
3310 POKE 63824,INT (a/256): POKE 63823,a-256*PEEK 63824
3320 RANDOMIZE USR 63819: RETURN
3400 ON ERR GO TO 1100: LET i=pg: GO SUB 3200: LET i$=a$(2): IF i$=" " THEN COPY : GO TO 1110
3410 IF i$="a" OR a$="A" THEN FOR i=1 TO top: GO SUB 3305: COPY : NEXT i: GO TO 1110
3420 IF i$>"0" AND i$<"6" THEN LET i=VAL i$: GO SUB 3305: COPY : GO TO 1110
3490 GO TO 1110
4000 INPUT "Load/Save/Return "; LINE i$
4010 IF i$="r" OR i$="R" THEN GO TO 5020
4020 IF i$="l" OR i$="L" THEN GO TO 4100
4030 IF i$="s" OR i$="S" THEN GO TO 4200
4040 GO TO 4000
4100 INPUT "Enter file name- "; LINE i$: INPUT "Start tape and press ENTER"; LINE a$: ON ERR GO TO 4140
4110 LOAD i$CODE : LET top=PEEK 33306
4120 IF top<5 THEN FOR i=top+1 TO 5: CLS : GO SUB 3200: NEXT i: LET top=PEEK 33306
4130 LET i=1: LET pg=i: GO SUB 3300: GO TO 7000
4140 BEEP 2,-20: GO TO 4130
4200 INPUT "Enter File Name- "; LINE i$: IF i$="" THEN GO TO 4200
4210 ON ERR GO TO 4240: LET i=pg: GO SUB 3200: POKE 33306,top: SAVE i$CODE 33306,1+(6080*top)
4220 ON ERR RESET : GO TO 5020
4240 BEEP 2,-20: GO TO 4220
5000 INPUT "[on ";STR$ set;"] Character set? "; LINE i$: IF i$<"1" OR i$>"3" THEN GO TO 5000
5010 LET set=VAL i$
5020 ON ERR GO TO 9000: POKE 23606,s(set,1): POKE 23607,s(set,2): GO TO 10
6000 IF i$=" STOP " THEN GO TO 1000
6010 IF i$="NOT " THEN PRINT OVER 1;" ";AT 0,0;" ";CHR$ 8;
6020 IF i$=" STEP " THEN GO TO 6200
6030 IF i$=" TO " THEN GO TO 6300
6055 IF i$=">=" THEN RANDOMIZE USR 63707: GO TO 10
6060 IF i$="<=" THEN RANDOMIZE USR 63757
6090 GO TO 10
6100 REM cls
6110 IF a$(2)="a" OR a$(2)="A" THEN GO TO 6150
6115 IF a$(2)<>" " THEN GO TO 1000
6120 CLS : LET i=pg: LET pg=top: GO SUB 3200: IF i=pg AND i>1 THEN LET top=i-1
6130 LET pg=i: GO TO 7000
6150 FOR i=1 TO 5: CLS : GO SUB 3200: NEXT i: LET pg=1: LET top=pg: GO TO 7000
6200 IF pg=5 THEN GO TO 70
6205 LET b=0: LET i=pg: GO SUB 3200: LET i=i+1
6210 LET pg=i: CLS : GO SUB 3300: PRINT OVER 1;" ";CHR$ 8;: GO TO 10
6300 LET b=0: IF pg=1 THEN GO TO 70
6310 LET i=pg: GO SUB 3200: LET i=i-1: GO TO 6210
7000 ON ERR GO TO 9000: POKE 23606,s(set,1): POKE 23607,s(set,2): GO TO 8
8000 DATA 140,129,139,130,141,131,142,132,138,133,143,134,137,135,136,128
8020 DATA 0,60,87,248,87,251
9000 POKE 23606,0: POKE 23607,60: ON ERR RESET : STOP
9997 SAVE "type" LINE 0: SAVE "type"CODE 63707,1830
9999 SAVE "type" LINE 0: SAVE "type"CODE 63707,1830: VERIFY "": VERIFY ""CODE : VERIFY "": VERIFY ""CODE : GO TO 9999
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

