--- title: "Mini-Pro" id: 57643 type: "computer_media" slug: "mini-pro" url: "http://localhost/computer_media/mini-pro/" markdown_url: "http://localhost/computer_media/mini-pro.md" published_at: "2024-10-06T01:15:58+00:00" modified_at: "2026-04-03T07:58:10+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/mini-pro.png" excerpt: "A keyboard-driven screen editor with a blinking block cursor, full cursor movement, and one-key SAVE — built entirely in BASIC without machine code." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" genre: - name: "Word Processor" slug: "word-processor" taxonomy: "genre" url: "http://localhost/type/word-processor/" media_contents: - id: 56727 title: "Synchro-Sette October 1982" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-october-1982/" media_type: "Program" programmers: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" mediadate: "October 1982" images: - url: "http://localhost/wp-content/uploads/2024/10/mini-pro.png" media_type_tags: "Word Processor" --- # Mini-Pro 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: 1. **Initialisation (lines 10–20):** Sets cursor position `X` (row) and `Y` (column) to 0. 2. **Main loop (lines 100–1130):** Reads `INKEY$`, flashes the cursor, dispatches on key code, or prints the character and advances the cursor. 3. **Key dispatch (lines 1010–1090):** A chain of `IF CODE A$=n THEN GOTO` tests routing to handlers. 4. **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 N` without a corresponding `FOR` would cause an error if reached. `SLOW` is 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 key `p` (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. ## 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 ```