--- title: "RLEPro" id: 70823 type: "computer_media" slug: "rlepro" url: "http://localhost/computer_media/rlepro/" markdown_url: "http://localhost/computer_media/rlepro.md" published_at: "2026-08-23T15:08:05+00:00" modified_at: "2026-08-23T20:40:55+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Decode and display run-length-encoded hi-res artwork loaded from tape, then automatically save the finished screen as a picture file." 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: "John Ryan" slug: "john-ryan" taxonomy: "indiv" url: "http://localhost/indiv/john-ryan/" genre: - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_type: "Program" programmers: - name: "John Ryan" slug: "john-ryan" taxonomy: "indiv" url: "http://localhost/indiv/john-ryan/" download_url: "https://archive.org/download/timex-sinclair-software-archive/RLEPro%20%281986%29%28Ryan%2C%20John%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1986" media_type_tags: "Graphics" --- # RLEPro RLEPro decodes and displays run-length-encoded (RLE) picture data loaded as machine code from tape into memory at address 40000, then renders it using PLOT commands to build a high-resolution bitmap image. The decoder scans for a two-byte header sequence (values 71 and 72) that marks the start of the picture data, then interprets alternating run-count and color bytes. Attribute memory (22528–23295) is filled with INK 7 (white) via a POKE loop when an end-of-data sentinel is detected. After drawing, the completed screen can be saved back to tape as a SCREEN$ file, with the program prompting for a filename if one was not already supplied. *** ### Program Structure The program is organized into a linear initialization phase, a main decode loop, and several subroutines. Lines 4–12 handle setup: setting display attributes, prompting for a filename, loading binary data to address 40000, and initializing coordinate variables. Lines 50–230 form the main decode loop. Lines 500–550 and 600–640 are subroutines that read the run-count and color fields respectively. Lines 700–750 perform the actual PLOT rendering. Lines 800–820 handle saving the completed screen. Line 900 is a standalone tape-save routine for the BASIC program itself. ### RLE Data Format and Header Detection The binary data blob loaded at address 40000 uses a simple synchronization header. The decoder first scans for byte value 27 (ESC) at line 60–80, then scans for byte 71 (‘G’) at lines 100–120, then byte 72 (‘H’) at lines 140–160. This three-byte sequence `ESC G H` marks the beginning of the encoded picture data. Line 9 ensures the first byte at 40000 is 27 if it is not already, providing a fallback entry point for the scan. ### Decode Loop Logic Starting at line 180, the loop alternates between two subroutine calls and a draw call: 1. Line 180 calls subroutine 500, which reads a run-count byte and stores `C = PEEK A - 32`. 2. Line 200 calls subroutine 600, which reads a color/attribute byte (stored in `C` again, overwriting the run-count). 3. Line 211 skips the draw call if `C=0`, then line 220 calls subroutine 700 to PLOT `C` pixels. The subtraction of 32 from each raw byte offsets the data into a printable-ASCII-friendly encoding range, so a byte of 32 decodes as 0 (end of run or transparent), and values below 32 trigger the end-of-picture routine. ### Coordinate Management The drawing origin is `X=0, Y=175` (top-left in Spectrum PLOT coordinates, since Y=175 is near the top of the 176-row display). Subroutine 500 advances `X` by the run-count and wraps to the next scanline when `X` exceeds 255. Subroutine 700 increments `X` one pixel at a time for each plotted point, also performing scanline wrap at lines 715–716. When `Y` goes negative the picture is complete and execution jumps to line 800. ### Attribute Coloring When the end-of-data condition is detected (a byte less than 32 is read), a `FOR` loop POKEs the entire attribute file (addresses 22528 to 23295) with the value 7, setting every cell to INK 7 on PAPER 0 (white on black). This is done in subroutines 500 and 600 as well as in subroutine 700, covering all possible exit paths from the decode loop. ### Screen Save Feature After drawing completes, line 800 checks whether a filename was supplied. If so, it prompts the user to press a key twice (the double-pause idiom with `PAUSE 0` followed by `INPUT ""`) before saving with `SAVE a$ SCREEN$`. If no filename was given, line 810 prompts for one interactively using a lower screen `INPUT AT` statement before proceeding to the save. ### Notable Bugs and Anomalies - **Color byte overwritten:** The variable `C` is used for both the run-count (subroutine 500) and the color value (subroutine 600). After subroutine 600 returns, `C` holds only the color byte; the original run-count from subroutine 500 is lost. Subroutine 700 then uses `C` as the pixel count to plot, meaning it is actually plotting *color-count* pixels rather than run-count pixels. Whether this is intentional or a bug depends on the RLE data format conventions used by the encoder. - **CLEAR before LOAD:** Line 5 uses `CLEAR 39999` to lower RAMTOP before the machine code load at line 8, protecting the loaded data from being overwritten by BASIC’s memory management — a correct and necessary technique. ### Key Variables | Variable | Role | | --- | --- | | `A` | Current read pointer into the data block at 40000 | | `B` | Raw byte value from PEEK A | | `C` | Decoded value (B−32); used as run-count then color count | | `D` | Pixel counter within subroutine 700 | | `X` | Current horizontal pixel position | | `Y` | Current vertical pixel position (counts down from 175) | | `a$` | Tape filename for loading and saving | ## Source Code ``` 1 REM RLE Picture program, © 1986...John Ryan 2 REM 3 REM Modified by Carl Forst to automatically clear Ramtop & LOAD M/C @ 40000 as well as to SAVE SCREEN$ after picture is drawn. (GOTO 900 to save this program to tape) 4 BEEP .5,40: BORDER 0: PAPER 0: INK 7: CLS : PAUSE 10: BEEP .75,40: PRINT AT 10,10; FLASH 1;"STOP TAPE": PAUSE 200 5 CLEAR 39999: PRINT AT 7,0;"Run-Length-Encoded Picture Prog.";AT 10,3;"(High-Resolution Graphics)" 6 INPUT " INPUT Pic. File Name (if known)";"(10 Chars.Max.) or just : "; LINE a$ 8 LOAD a$CODE 40000 9 IF PEEK 40000<>27 THEN POKE 40000,27 10 LET A=40000 11 LET X=0 12 LET Y=175 50 CLS 60 LET B=PEEK A 70 IF B=27 THEN GO TO 90 80 LET A=A+1: GO TO 60 90 LET A=A+1 100 LET B=PEEK A 110 IF B=71 THEN GO TO 130 120 GO TO 90 130 LET A=A+1 140 LET B=PEEK A 150 IF B=72 THEN GO TO 170 160 GO TO 140 170 LET A=A+1 180 GO SUB 500 190 LET A=A+1 200 GO SUB 600 210 LET A=A+1 211 IF C=0 THEN GO TO 180 220 GO SUB 700 230 GO TO 180 500 LET B=PEEK A 510 LET C=B-32 520 IF C=0 THEN RETURN 530 IF C<0 THEN FOR q=22528 TO 23295: POKE q,7: NEXT q: GO TO 800 540 LET X=X+C: IF X>255 THEN LET X=X-256: LET Y=Y-1 550 RETURN 600 LET B=PEEK A 610 LET C=B-32 620 IF C=0 THEN RETURN 630 IF C<0 THEN FOR q=22528 TO 23295: POKE q,7: NEXT q: GO TO 800 640 RETURN 700 LET D=0 715 IF 255255 THEN GO TO 730 720 PLOT X,Y 730 LET D=D+1 731 LET X=X+1 740 IF D=C THEN RETURN 750 GO TO 710 800 IF a$<>"" THEN PRINT #0;AT 0,0;"Press any key (twice) to save",a$;" pic. or BREAK to Stop.": PAUSE 0: INPUT "": GO TO 820 810 INPUT AT 0,0;"Type Name of picture for saving:";"(10 Chars. max.) "; LINE a$ 820 SAVE a$SCREEN$ : GO TO 9999 900 SAVE "RLEPRO" LINE 4: VERIFY "": STOP 9999 PRINT #0;AT 0,1;a$: PAUSE 0::::::: REM ```