--- title: "Flow Chart" id: 71040 type: "computer_media" slug: "flow-chart" url: "http://localhost/computer_media/flow-chart/" markdown_url: "http://localhost/computer_media/flow-chart.md" published_at: "2026-08-26T02:00:45+00:00" modified_at: "2026-08-26T02:02:35+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/flow-chart.png" alt: "Flow Chart screen" excerpt: "This self-documenting utility reads its own program's tokenized memory and draws a live flowchart diagram, classifying every statement type by its keyword token byte." 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/" genre: - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Flow%20Chart%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/flow-chart.png" alt: "Flow Chart screen" media_type_tags: "Utility" --- # Flow Chart Flow Chart is a BASIC self-analysis utility that reads its host program’s own tokenized source from memory and renders a visual flowchart on screen. It walks the BASIC line table starting from the address stored in system variables at addresses 23635–23636, decoding token bytes to classify statement types and drawing corresponding flowchart symbols using PLOT, DRAW, and CIRCLE commands. Different statement categories — loops, conditionals, GOTO/GOSUB calls, and plain sequential statements — each produce a distinct geometric shape, with diamonds for IF/NEXT, rectangles for most statements, and rounded forms for loop constructs. The program uses direct PEEK operations on the tokenized program area to extract line numbers and keyword tokens, and prints line numbers alongside statement abbreviations in a side panel while plotting the diagram on the graphics area of the screen. *** ### Program Structure The program is organized as a single large routine spanning lines 9900–9952, which suggests it is designed to be appended to the end of any BASIC program and will analyze everything preceding it. The high line numbers ensure it runs last and also serve as a sentinel: the check `IF l >=9900` at lines 9904 and 9948 is how the routine detects it has reached its own code and should stop processing. Execution flow can be broadly divided into these phases: 1. **Initialization (9900–9903):** Sets display attributes, reads the BASIC program start address from system variables, and initializes drawing coordinates. 2. **Main line loop (9903–9922):** Reads each line’s number and advances the pointer past the line header. 3. **Statement classification (9905–9941):** Examines the first token byte of each statement and dispatches to an appropriate drawing subroutine. 4. **Flowchart drawing (9911–9938):** Uses PLOT/DRAW/CIRCLE to render the appropriate symbol. 5. **Pagination / output (9942–9949):** When 22 text rows are consumed, pauses and offers the user a view/print choice before continuing. 6. **String-skip subroutine (9951–9952):** Scans past a quoted string literal in the token stream. ### Memory Traversal Technique The program locates the start of the BASIC program area using `PEEK 23635 + 256 * PEEK 23636`, which reads the PROG system variable (address 23635–23636). It then walks the tokenized line table manually: `PEEK (a+1) + 256 * PEEK a` at line 9903 reads the big-endian line number from the two-byte line header, and `a = a + 4` steps past the four-byte header (line number + length word) to reach the token stream. The inner loop at lines 9916–9920 advances byte by byte through the token stream, with special handling for: - Token byte `14` — the five-byte floating-point number embedding; line 9917 skips four extra bytes (`a = a + 4`, making five total with the outer `a+1`). - Token byte `34` — an opening quote, triggering the string-skip subroutine at 9951. - Token byte `13` — newline (end of line), triggering advance to next line. - Token byte for `:` — a statement separator, triggering multi-statement handling at 9939. ### Token-Based Statement Classification The core classification logic at lines 9907–9910 tests the first token byte `b` of each statement against known Spectrum keyword token values: | Token value(s) | Keyword(s) | Shape drawn | | --- | --- | --- | | 226, 234, 242, 254 | FOR, LPRINT, LLIST, COPY (loop/output) | Rounded rectangle (arcs via DRAW with –PI) | | 228–230, 232, 235, 241, 247, 249, 253 | Various (NEXT, INPUT, etc.) | Plain rectangle (right-angle DRAW) | | CODE “NEXT “, CODE “IF “ | NEXT, IF | Diamond shape | | CODE “GO TO “, CODE “GO SUB “ | GO TO, GO SUB | Circle + extended arrow | | All others | General statements | Default rectangle from 9911 | Using `CODE "NEXT "` and similar expressions to derive token values at runtime is a portable technique that avoids hardcoding token numbers directly for keywords whose byte values the author may not have memorized. ### Flowchart Symbol Drawing All symbols are drawn relative to the current pixel position (`x`, `y`), which starts at (130, 175) — near the top-right of the screen — and decrements by 8 pixels per statement via `y = y - 8` at line 9912. The drawing routines use only PLOT, DRAW (including arc form with a third argument of `–PI` for rounded ends), and CIRCLE, keeping the code compact. The downward connector arrow (line 9914) is only drawn for non-terminal statement types, controlled by another token check. ### Pagination and Output The variable `c` tracks the current print row in text coordinates, incrementing by 2 per statement. When `c = 22` (checked at lines 9921 and 9939), the program branches to line 9942 and pauses, printing a prompt in the lower screen area using `INVERSE SGN PI` (i.e., INVERSE 1) for highlighted text. The user can press `v` to continue viewing or `p` to print a hardcopy via COPY before resuming. After the pause, line 9946 resets `d`, `e`, `c`, `x`, and `y` and calls CLS, restarting the display area for the next page. ### GO TO / GO SUB Annotation For GO TO and GO SUB statements (line 9933 onward), the routine goes further than just drawing a symbol: it hunts through the token stream for the embedded floating-point value (token `14`) of the target line number, reads the two-byte integer part from bytes 3–4 of the five-byte FP block at line 9936, and prints the target line number beside the diagram using `PRINT AT c-2, 26; g`. Similarly, for IF and NEXT statements, it locates token byte 203 (the `THEN` token) and prints the character following it as a destination hint at column 19. ### Notable Idioms and Anomalies - `NOT PI` evaluates to 0 (since PI is non-zero, NOT PI = 0), and `SGN PI` evaluates to 1. These are used throughout as compact numeric literals: `LET c = NOT PI` initializes `c` to 0, and `INVERSE SGN PI` means INVERSE 1. - `VAL "number"` is used for GO TO targets (e.g., `GO TO VAL "9946"`), a standard memory-saving technique on this platform. - The subroutine at 9951–9952 uses a tight loop with no explicit counter, relying on finding a closing quote byte (34) to return; it does not handle escaped quotes within strings, which could cause it to misparse string literals containing quote characters. - Line 9917 advances `a` by 4 when a floating-point embedding token (14) is found, but the outer loop at 9920 adds 1 more, giving the correct total skip of 5 bytes for the FP embedding (1 token + 1 type + 2 integer + 1 exponent). - The DRAW arc syntax `DRAW dx, dy, angle` with `–PI` as the angle draws a semicircular arc, used at line 9923 to produce the rounded ends of loop symbols. ## Source Code ``` 9900 OVER NOT PI:INVERSE NOT PI:BRIGHT NOT PI:FLASH NOT PI:BORDER 7:PAPER 7:INK NOT PI:CLS 9901 LET a= VAL "PEEK 23635+256* PEEK 23636" 9902 LET c= NOT PI:LET y= VAL "175":LET x= VAL "130" 9903 LET l= PEEK (a+1)+256* PEEK a:LET a=a+4 9904 IF l >=9900 THEN GO TO VAL "9948" 9905 PRINT l; TAB 5; CHR$ PEEK a:LET c=c+2:PRINT 9906 PLOT x,y:LET b= PEEK a 9907 IF b=226 OR b=234 OR b=242 OR b=254 THEN GO TO 9923 9908 IF b>227 AND b<231 OR b=232 OR b=235 OR b=241 OR b=247 OR b=249 OR b=253 THEN GO TO 9924 9909 IF b= CODE "NEXT " OR b= CODE "IF " THEN GO TO 9925 9910 IF b= CODE "GO TO " OR b= CODE "GO SUB " THEN GO TO 9933 9911 DRAW 16,0:DRAW -4,-8:DRAW -28,0:DRAW 4,8:DRAW 12,0 9912 LET y=y-8 9913 IF b=226 OR b=236 OR b=237 OR b=254 THEN GO TO 9915 9914 PLOT x,y:DRAW 0,-7:DRAW 4,4:DRAW -4,-4:DRAW -4,4 9915 LET y=y-8 9916 LET b= PEEK a:IF b=34 THEN GO SUB 9951 9917 IF b=14 THEN LET a=a+4 9918 IF b=13 THEN GO TO 9921 9919 IF b= CODE ":" THEN GO TO 9939 9920 LET a=a+1:GO TO 9916 9921 IF c=22 THEN GO TO 9942 9922 LET a=a+1:GO TO 9903 9923 DRAW 12,0:DRAW 4,-8,- PI:DRAW -24,0:DRAW -4,8,- PI:DRAW 12,0:GO TO 9912 9924 DRAW 16,0:DRAW 0,-8:DRAW -32,0:DRAW 0,8:DRAW 16,0:GO TO 9912 9925 DRAW 8,-4:DRAW 8,0:DRAW -4,4:DRAW 4,-4:DRAW -4,-4:DRAW 4,4:DRAW -8,0:DRAW -8,-4:DRAW -8,4:DRAW 8,4 9926 IF b=243 THEN GO TO 9932 9927 LET a=a+1:LET f= PEEK a 9928 IF f=14 THEN LET a=a+4 9929 IF f <>203 THEN GO TO 9927 9930 LET a=a+1:LET f= PEEK a:PRINT AT c-2,19; CHR$ f:PRINT 9931 IF f=236 OR f=237 THEN GO TO 9934 9932 GO TO 9912 9933 CIRCLE x,y-4,4:PLOT x+4,y-4:DRAW 64,0:DRAW -4,4:DRAW 4,-4:DRAW -4,-4:PLOT x,y 9934 LET a=a+1:LET f= PEEK a 9935 IF f <>14 THEN GO TO 9934 9936 LET a=a+3:LET g= PEEK a+256* PEEK (a+1) 9937 PRINT AT c-2,26;g:PRINT 9938 GO TO 9912 9939 IF c=22 THEN GO TO 9942 9940 LET a=a+1:PRINT " : "; CHR$ PEEK a:PRINT :LET c=c+2 9941 GO TO 9906 9942 PRINT #0; INVERSE SGN PI;" PRESS ""V"" TO VIEW:""P"" TO PRINT " 9943 IF INKEY$="v" THEN GO TO VAL "9946" 9944 IF INKEY$="p" THEN INPUT ;:COPY :GO TO VAL "9946" 9945 GO TO VAL "9943" 9946 CLS :LET d=0:LET e=22:LET c=d:LET x=130:LET y=175 9947 IF PEEK a= CODE ":" THEN GO TO 9940 9948 IF l >=9900 THEN PRINT # NOT PI;" End of Basic Program":PAUSE NOT PI:STOP 9949 GO TO 9922 9951 LET a=a+1:LET b= PEEK a:IF b=34 THEN RETURN 9952 GO TO 9951 ```