--- title: "ROM Check" id: 53846 type: "computer_media" slug: "romcheck" url: "http://localhost/computer_media/romcheck/" markdown_url: "http://localhost/computer_media/romcheck.md" published_at: "2024-05-13T19:02:05+00:00" modified_at: "2026-03-30T21:45:13+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A ROM diagnostic tool verifies memory integrity and floating-point accuracy using byte-sum checksums and deliberate arithmetic rounding-error accumulation tests." 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_contents: - id: 55361 title: "SINCUS Exchange Tape 102 – Utilities & Business" type: "computer_media" url: "http://localhost/computer_media/sincus-exchange-tape-102-utilities-business/" media_type: "Program" mediadate: "198" images: - url: "http://localhost/wp-content/uploads/2024/05/rom-check.png" media_type_tags: "Utility" --- # ROM Check This program performs a diagnostic check of the TS2068’s 16K main ROM by summing all byte values (expected total: 1,752,253) and counting zero-valued bytes (expected count: 609) using PEEK across addresses 0 to 16383. A third test evaluates floating-point arithmetic accuracy by accumulating rounding errors from expressions like `i*0.5 – i/2`, `i*0.1 – i/10`, and `i – SQR(i*i)` over a range of 101 integers, comparing the average against a hardcoded expected value of 1.3391177E-7. The program explicitly notes that the additional 8K ROM used for Command Cartridge support and bank switching is not tested. A SAVE with auto-run is included at line 9998 for convenient storage and reload. *** ## Program Analysis ### Program Structure The program is divided into three logical phases preceded by a startup prompt: 1. **Setup and prompt (lines 1–19):** Clears the screen, sets display attributes, prints a title, and waits for the user to press 1 before continuing. 2. **ROM byte checks (lines 20–95):** Iterates over all 16,384 ROM addresses (0 to 16383), accumulating a byte sum in `a` and a zero-byte count in `b`, then validates both against expected constants. 3. **Arithmetic accuracy check (lines 100–270):** Accumulates floating-point rounding errors across 101 iterations and compares the average to a hardcoded expected value. ### ROM Integrity Tests The first check (line 80) verifies that the sum of all 16,384 bytes of ROM equals `1752253`. This is a simple checksum that will catch any single-byte corruption. The second check (line 90) counts the number of zero bytes in the ROM and expects exactly `609`. Together these two tests provide complementary coverage: the sum alone could pass if errors cancel out, while the zero count catches differences in the distribution of values. The loop at line 40 uses `FOR i=0 TO 16*1024-1`, which evaluates `16*1024` at runtime. Writing it as `16383` would be marginally faster, but the expression makes the intent clear. ### Arithmetic Accuracy Test Lines 140–180 test the ROM’s floating-point routines by deliberately creating expressions that should yield zero but may accumulate rounding error: - `i*0.5 - i/2` — multiplying vs. dividing by 2; both should be exact in binary floating point for integers, but the accumulation in `c` probes any hidden discrepancy. - `i*0.1 - i/10` — since 0.1 is not exactly representable in binary, this reliably produces small non-zero residuals, accumulated in `d`. - `i - SQR(i*i)` — tests the square root routine’s rounding behavior, accumulated in `e`. The combined average `(C+D+E)/300` at line 205 divides by 300 (101 iterations × 3 accumulators — note: 101 iterations but only 300 used as denominator, which suggests the programmer intended 100 iterations or adjusted the constant empirically). The expected value `AEA = 1.3391177E-7` is hardcoded at line 185 rather than being computed at runtime, making this a signature-based test of the specific ROM’s arithmetic behavior. ### Notable Techniques and Idioms - The input gate at lines 16–17 uses a numeric `INPUT F` and loops back with `GO TO 15` if `F<>1`, a common BASIC form of a validated prompt. - Variable `AEA` is used as a long variable name (line 185), which is valid — BASIC allows multi-character variable names starting with a letter followed by letters or digits, though only the first character is significant for numeric variables on this platform. This means `AEA` is treated as the variable `A`, which conflicts with the ROM byte-sum variable `a` (BASIC is case-insensitive for variable names). This is a latent bug: assigning `AEA=1.3391177E-7` at line 185 overwrites the value of `a` computed in the first ROM check. However, since `a` is only read at line 80 (before line 185), the overwrite does not affect the output of the first check. - The `BEEP 1,0` calls at lines 10 and 270 produce a one-second middle-C tone to signal the start and end of the test run. - Line 250 uses a long unbroken string for the disclaimer note, relying on automatic word-wrap for display rather than manual `TAB` positioning. ### Variable Summary | Variable | Effective Name | Purpose | | --- | --- | --- | | `a` | a | Sum of all ROM bytes | | `b` | b | Count of zero bytes in ROM | | `i` | i | Loop counter (ROM address / arithmetic range) | | `c` | c | Accumulated error from multiply-vs-divide-by-2 | | `d` | d | Accumulated error from multiply-vs-divide-by-10 | | `e` | e | Accumulated error from SQR roundtrip | | `AEA` | a (same as `a`!) | Hardcoded expected arithmetic error average | | `F` | f | User input for start confirmation | ### Bugs and Anomalies The most significant issue is the variable name collision between `a` (ROM byte sum, lines 20–80) and `AEA` (line 185). Because BASIC treats multi-character variable names as single-character (only the first letter matters), `AEA` is the same storage location as `a`. The assignment at line 185 silently destroys the ROM checksum result. As noted above, this does not affect the printed output because line 80 uses `a` before it is overwritten, but it would cause incorrect behavior if the program were restructured or if `a` were referenced again later. The arithmetic error average denominator at line 205 is hardcoded as `300`. The loop runs from 1000 to 1100 inclusive, giving 101 iterations across 3 accumulators, for a true total of 303 accumulated terms. Using 300 instead of 303 slightly skews the computed average, but since both the test value and the comparison constant `AEA` were presumably derived from the same ROM under the same conditions, the test remains self-consistent. ## Source Code ``` 1 REM TS2068 16K ROM CHECK 5 CLS : FLASH 0: BORDER 1: PAPER 6: INK 0: BRIGHT 0: INVERSE 0: CLS 9 PRINT 10 BEEP 1,0 11 PRINT TAB 6;"TS2068 16K ROM CHECK" 12 PRINT 13 PRINT TAB 4;"RUN TIME IS FOUR MINUTES" 14 PRINT 15 PRINT TAB 3;"TO BEGIN PRESS 1 AND ENTER" 16 INPUT F 17 IF F<>1 THEN GO TO 15 18 PRINT 19 CLS 20 LET a=0 30 LET b=0 40 FOR i=0 TO 16*1024-1 50 LET a=a+PEEK i 60 IF PEEK i=0 THEN LET b=b+1 70 NEXT i 72 PRINT " TS2068 16K ROM CHECK" 78 PRINT 80 IF a=1752253 THEN PRINT TAB 5;"FIRST ROM CHECK IS OK" 85 PRINT 90 IF b=609 THEN PRINT TAB 5;"SECOND ROM CHECK IS OK" 95 PRINT 100 REM rom accuracy check 110 LET c=0 120 LET d=0 130 LET e=0 140 FOR i=1000 TO 1100 150 LET c=c+i*.5-i/2 160 LET d=d+i*.1-i/10 170 LET e=e+i-SQR (i*i) 180 NEXT i 185 LET AEA=1.3391177E-7 190 PRINT TAB 3;"ARITHMETIC ERRORS AVERAGE = ";AEA 201 PRINT 205 IF (C+D+E)/300<=AEA THEN PRINT TAB 2;"ARITHMETIC ERRORS AVERAGE IS CORRECT" 240 PRINT 245 PRINT 250 PRINT "NOTE......THE ADDITIONAL 8K ROM DEDICATED TO COMMAND CARTRIDGE CAPABILITIES AND BANK SWITCHING IS NOT INCLUDED OR TESTED BY THIS PROGRAM" 270 BEEP 1,0 280 STOP 9998 SAVE "ROMCHECK" LINE 1 9999 VERIFY "" ```