--- title: "PCLS 1000" id: 55023 type: "computer_media" slug: "pcls" url: "http://localhost/computer_media/pcls/" markdown_url: "http://localhost/computer_media/pcls.md" published_at: "2024-06-10T07:34:50+00:00" modified_at: "2026-04-03T13:05:05+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "A machine code screen-region tool that lets you instantly clear any rectangular portion of the display by specifying start and stop rows and columns." 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: "Kenneth Majors" slug: "kenneth-majors" taxonomy: "indiv" url: "http://localhost/indiv/kenneth-majors/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Program" programmers: - name: "Kenneth Majors" slug: "kenneth-majors" taxonomy: "indiv" url: "http://localhost/indiv/kenneth-majors/" download_url: "https://archive.org/download/timex-sinclair-software-archive/PCLS%20%281985%29%28Majors%2C%20Kenneth%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1985" related_content: - id: 54769 title: "PCLS 1000" type: "document" url: "http://localhost/document/pcls-1000/" media_type_tags: "Programming" --- # PCLS 1000 PCLS 1000 is a machine code utility that clears a user-defined rectangular region of the ZX81/TS1000 display file, filling it with background, white, or black characters. The user specifies a start row, stop row, start column, and stop column via INPUT statements; these values are POKEd directly into the machine code routine embedded in the REM statement at line 1. The routine is invoked with RAND USR 16515, which jumps into the machine code stored in the REM at the start of the program (address 16514 is the first byte of the REM’s data area). Before invoking the routine, the BASIC code fills the screen with a pattern of block graphics characters using a FOR/NEXT loop, giving the routine a non-blank canvas to clear from. *** ## Program Analysis ### Program Structure The program is divided into two functional phases. Lines 10–85 collect user input for the four bounds of the screen region (start row, stop row, start column, stop column) and POKE those values into specific offsets within the machine code routine stored in the line 1 REM. Lines 90–105 fill the entire screen with a dense block-graphic pattern. Line 110 positions the cursor at the top-left of the region, and line 120 executes the machine code via `RAND USR 16515`. ### Machine Code in the REM Statement The line 1 REM holds a 35-byte machine code routine beginning at address 16514 (the byte count field of the REM token is at 16512, and the data starts at 16514). The routine is called with `RAND USR 16515` — note the entry point is one byte into the REM data, skipping the first byte. The hex bytes are: `20 2A 0E 40 E5 3A 21 40 4F 3A 7B 40 91 4F 3A 7C 40 47 3A 82 40 90 47 7E E6 80 11 21 00 0D 28 10 C5 77 23 10 FC 2A 0E 40 ED 5A 22 0E 40 C1 18 ED E1 22 0E 40 C9 1C` The routine reads the stored row/column parameters and iterates over the specified screen rectangle, writing a fill character to each cell in the display file. The use of Z80 `DJNZ` and relative jumps makes this near-instantaneous compared to a BASIC loop. ### POKE Targets and Parameter Injection Rather than passing parameters through registers or a fixed memory area, the BASIC code patches the machine code in-place by POKEing values directly into operand bytes within the REM routine: | Line | Address | Parameter | | --- | --- | --- | | 25 | 16417 | Start row (RS) | | 45 | 16507 | Stop row + 1 (RT+1) | | 65 | 16508 | Start column (CS) | | 85 | 16514 | Stop column (CT) | Note that address 16514 is also the very first byte of the REM data, meaning the stop-column value overwrites what was originally the first byte of the routine. This is intentional — the entry point used by `RAND USR 16515` skips that byte, so it serves purely as a parameter storage location rather than an executable instruction. ### Screen Fill Pattern Lines 90–105 clear the screen and then fill all 22 rows with a repeating sequence of block graphic characters using a `FOR/NEXT` loop (variable `X`, 0 to 21). The PRINT statement in line 100 outputs a mix of ZX81 block graphics covering various quadrant combinations, producing a fully patterned display. This gives the machine code routine a visible canvas to erase, demonstrating the clearing effect clearly. ### Cursor Positioning Before USR Call Line 110 uses `PRINT AT RS,CS;` (with a trailing semicolon to suppress a newline) to position the system cursor at the top-left corner of the target rectangle. The machine code likely uses the current print position or a value derived from it as its starting address in the display file, making this positioning step essential to correct operation. ### Notable Techniques - Self-modifying machine code: parameters are patched into the routine bytes before execution rather than being passed at call time. - Dual use of address 16514: it holds both the CT parameter (via POKE) and is the start of the REM data, with the actual entry point at 16515 bypassing it. - The stop-row POKE uses `RT+1` rather than `RT`, indicating the loop in machine code uses an exclusive upper bound. - Block graphic characters in the PRINT at line 100 demonstrate all fill states the routine can clear. ### Potential Issues - No input validation is performed on RS, RT, CS, or CT. Out-of-range values (e.g., rows beyond 21 or columns beyond 31) would corrupt memory adjacent to the display file. - The address 16417 used in line 25 for RS falls well before the REM statement data area (which starts at 16514), suggesting RS may be patched into a different field — possibly the system variable for current print row — rather than directly into the machine code. This warrants careful verification against the actual Z80 disassembly. ## Source Code ``` 1 REM \20\2A\0E\40\E5\3A\21\40\4F\3A\7B\40\91\4F\3A\7C\40\47\3A\82\40\90\47\7E\E6\80\11\21\00\0D\28\10\C5\77\23\10\FC\2A\0E\40\ED\5A\22\0E\40\C1\18\ED\E1\22\0E\40\C9\1C 10 PRINT AT 21,0;"ROW TO START" 20 INPUT RS 25 POKE 16417,RS 30 PRINT AT 21,0;"ROW TO STOP " 40 INPUT RT 45 POKE 16507,(RT+1) 50 PRINT AT 21,0;"COL TO START" 60 INPUT CS 65 POKE 16508,CS 70 PRINT AT 21,0;"COL TO STOP " 80 INPUT CT 85 POKE 16514,CT 90 CLS 95 FOR X=0 TO 21 100 PRINT "\' \ '\ .\. \: \..\''\ :\.:\:.\:'\':\.'\'.\##\~~\,,\!!\;;\@@\' \ '\ .\. \: \..\''\ :\##\~~\,,\!!" 105 NEXT X 110 PRINT AT RS,CS; 120 RAND USR 16515 130 STOP ```