This program implements a simple full-screen text editor, using a blinking cursor rendered by rapidly printing and erasing a block-graphic character (▖) at the current position. The cursor position is tracked by variables X (row, 0–21) and Y (column, 0–31), matching the Spectrum’s 22-row × 32-column display. Key mappings handle character entry, backspace (r/code 114), forward movement (s/code 115), line-down (v/code 118), cursor up (q/code 113), home (code 23), end (code 19), clear screen (y/code 121), and a SAVE routine triggered by code 225. Typed characters are written directly to the screen with PRINT AT, and the cursor advances automatically, wrapping from column 31 to the next row.
Program Structure
The program is divided into clearly demarcated functional blocks:
- Initialisation (lines 10–20): Sets cursor position
X(row) andY(column) to 0. - Main loop (lines 100–1130): Reads
INKEY$, flashes the cursor, dispatches on key code, or prints the character and advances the cursor. - Key dispatch (lines 1010–1090): A chain of
IF CODE A$=n THEN GOTOtests routing to handlers. - Command handlers (lines 1200–2020): Separate subroutine-like blocks for each function, all returning via
GOTO 100.
Cursor Rendering
The blinking cursor is produced in the tight loop at lines 105–110. Line 105 prints the block graphic ▖ (lower-left quadrant, char 130) at position (X,Y), line 106 immediately overwrites it with a space, and line 110 loops back if no key has been pressed. Because the Spectrum’s display refresh is fast relative to BASIC execution, this creates a visible flicker that serves as a cursor indicator.
Key Mappings
| Code | Key | Action | Handler |
|---|---|---|---|
| 114 | r | Backspace / move left | 1200 |
| 115 | s | Move right / forward | 1300 |
| 121 | y | CLS | 1900 |
| 113 | q | Move up one row | 1400 |
| 225 | Symbol Shift+A (or extended) | INPUT filename and SAVE | 2000 |
| 112 | p | Move up (same as q?) | 1500 |
| 118 | v | Move to start of next row | 1600 |
| 23 | Home (control code) | Go to top-left (0,0) | 1700 |
| 19 | End (control code) | Go to bottom-right (21,31) | 1800 |
All other key presses fall through to line 1100 where the character is printed and the cursor advances.
Cursor Movement Logic
The backspace handler (1200) decrements Y, wrapping to column 31 on the previous row when Y=0. It guards against going before position (0,0). The forward handler (1300) increments Y, wrapping to column 0 on the next row when Y=31, and guards against going past row 21. The up-row handler (1400) simply increments X (confusingly named “up” but moves down in screen terms), capped at 21. The handler at 1500 decrements X, floored at 0. The newline handler (1600) sets Y=0 and increments X, equivalent to a carriage return/line feed.
Bugs and Dead Code
- Lines 1530–1660 (
GOTO 100,NEXT N,SLOW,GOTO 100) are unreachable dead code.NEXT Nwithout a correspondingFORwould cause an error if reached.SLOWis a ZX81 keyword and is not valid on the Spectrum/TS2068, suggesting copied or ported code fragments. - The label “up” assigned to key
q(code 113) dispatches to handler 1400 which moves down a row (X=X+1), while keyp(code 112) at handler 1500 moves up (X=X-1). The naming is inverted relative to expected behaviour. - The maximum row is hard-coded as 21.
- There is no cursor boundary check when printing characters in the normal typing path (line 1100); the automatic wrap at
Y=32(line 1120) uses 32 rather than 31, which means column 31 is valid but column 32 is never reached — this is correct since columns are 0-indexed to 31.
Content
Source Code
10 LET X=0
20 LET Y=0
100 LET A$=INKEY$
105 PRINT AT X,Y;" ."
106 PRINT AT X,Y;" "
110 IF A$="" THEN GOTO 100
1010 IF CODE A$=114 THEN GOTO 1200
1020 IF CODE A$=115 THEN GOTO 1300
1030 IF CODE A$=121 THEN GOTO 1900
1040 IF CODE A$=113 THEN GOTO 1400
1050 IF CODE A$=225 THEN GOTO 2000
1060 IF CODE A$=112 THEN GOTO 1500
1070 IF CODE A$=118 THEN GOTO 1600
1080 IF CODE A$=23 THEN GOTO 1700
1090 IF CODE A$=19 THEN GOTO 1800
1100 PRINT AT X,Y;A$
1110 LET Y=Y+1
1120 IF Y=32 THEN GOTO 1150
1130 GOTO 100
1150 LET Y=0
1160 LET X=X+1
1170 GOTO 100
1200 IF Y=0 AND X=0 THEN GOTO 100
1210 IF Y=0 THEN GOTO 1250
1220 LET Y=Y-1
1230 GOTO 100
1250 LET Y=31
1260 LET X=X-1
1270 GOTO 100
1300 IF Y=31 AND X=21 THEN GOTO 100
1310 IF Y=31 THEN GOTO 1350
1320 LET Y=Y+1
1330 GOTO 100
1350 LET Y=0
1360 LET X=X+1
1370 GOTO 100
1400 IF X=21 THEN GOTO 100
1410 LET X=X+1
1420 GOTO 100
1500 IF X=0 THEN GOTO 100
1510 LET X=X-1
1520 GOTO 100
1530 GOTO 100
1600 IF X=21 THEN GOTO 100
1610 LET Y=0
1620 LET X=X+1
1630 GOTO 100
1640 NEXT N
1650 SLOW
1660 GOTO 100
1700 LET X=0
1710 LET Y=0
1720 GOTO 100
1800 LET X=21
1810 LET Y=31
1820 GOTO 100
1900 CLS
1910 GOTO 100
2000 INPUT B$
2010 SAVE B$
2020 GOTO 100
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
