--- title: "Hex Dec Bin" id: 57528 type: "computer_media" slug: "hex-dec-bin" url: "http://localhost/computer_media/hex-dec-bin/" markdown_url: "http://localhost/computer_media/hex-dec-bin.md" published_at: "2024-10-05T21:30:17+00:00" modified_at: "2026-03-30T21:17:25+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/283_HDB.png" excerpt: "A 16-bit number base converter that handles hex, decimal, and spaced binary input with subroutines, string arrays, and printer support." 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/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/283_HDB.png" media_type_tags: "Programming, Software, Utility" --- This program is a number base converter that translates values between decimal (0–65535), hexadecimal (4-digit), and binary (19-character with spaces) representations. It uses subroutines at lines 15, 210, 300, and 400 for binary-to-decimal, decimal-to-hex, hex-to-decimal, and binary-to-decimal conversions respectively, storing intermediate results in string arrays D$(1,19) and B$(1,4). The binary display uses a 19-character format with spaces at positions 5, 10, and 15 (skipped in loops via conditional NEXT I), representing a 16-bit value split into four nibbles. Output is presented using SCROLL and AT positioning on the lower display lines, and the program supports a COPY command for hard-copy output via a ZX printer. *** ## Program Analysis ### Program Structure The program is organized as a set of subroutines and a main input/output loop. The entry point is line 500, which presents a menu. Four subroutines handle the core conversions: | Lines | Role | | --- | --- | | 15–60 | Decimal → Binary: converts `VAL C$` into `D$(1,19)` using successive halving | | 210–255 | Decimal → Hex: converts `VAL C$` into `B$(1,4)` using base-16 division | | 300–340 | Hex → Decimal: reconstructs a decimal value from `B$(1,4)` and stores it in `C$` | | 400–440 | Binary → Decimal: converts `D$(1,19)` back to a decimal value in `C$` | The main flow branches at lines 525–540 depending on input mode (H/D/B), and all paths converge at line 700 for output display. ### Binary Representation Format The 16-bit binary value is stored in a 19-character string `D$(1,19)`. Positions 5, 10, and 15 are intentionally skipped in both the encoding loop (lines 25–55) and the decoding loop (lines 410–430) using `IF I=5 OR I=10 OR I=15 THEN NEXT I`. This means those positions act as spacers (likely spaces), visually grouping the 16 bits into four nibbles: `0000 0000 0000 0000`. Binary input (line 620) requires the user to enter exactly this 19-character format including the spaces. ### Hex Digit Encoding In the decimal-to-hex subroutine (lines 230–235), digits 0–9 are stored directly as their string character, but hex digits A–F (values 10–15) are stored using `CHR$ (A+28)`. On the ZX81/TS1000 character set, `CHR$ 38` through `CHR$ 43` correspond to printable characters — this is an unconventional encoding that avoids alphabetic characters. The hex-to-decimal subroutine at lines 300–325 compensates by pre-assigning `A=10` through `F=15`, then using `VAL B$(1,J)` to evaluate each nibble, relying on the BASIC interpreter to resolve those single-letter variable names. ### Key BASIC Idioms - `LET D$(1)=Z$` (line 622) and `LET B$(1)=Q$` (line 560) assign an entire string to a dimensioned string array row — a compact ZX81 idiom for bulk string assignment. - `VAL C$` is used throughout as the shared numeric pipeline between subroutines, with `C$` acting as a global numeric register in string form. - FAST/SLOW mode switching (lines 564, 592, 623 / line 700) brackets the computation subroutines to speed up processing while keeping display readable. - SCROLL is used repeatedly at lines 710–740 to scroll the single-line ZX81 display area, simulating multi-line output on the bottom line. ### Input Validation Each input mode includes basic validation. Hex input (line 556) checks for exactly 4 characters, then (lines 561–563) checks each character’s CODE is within the valid range (28–43), rejecting out-of-range values by re-looping to line 555. Decimal input (line 591) rejects values above 65535. Binary input (line 621) requires exactly 19 characters. None of these checks verify individual binary digit values (only ‘0’ or ‘1’), so non-binary characters in binary input would corrupt the result silently. ### Output Display The output section (lines 700–780) uses a sequence of `SCROLL` and `PRINT AT 20,0` calls to build up a multi-line summary on the display. Line 730 shows the decimal value decomposed as `256 * high_byte + low_byte = total`, computed inline using `VAL C$`. The user can then enter another number in any base, request a hard copy with `COPY`, or stop with `S`. ### Bugs and Anomalies - The hex validation at line 562 uses `CODE B$(1,I)>43 OR CODE B$(1,I)<28`. Character codes 28–37 represent digits 0–9 and codes 38–43 represent the non-standard A–F substitutes. However, this range also permits some non-hex characters that happen to fall within 28–43. - Line 591 checks `IF VAL C$>65535 THEN GOTO 585` but does not validate that `C$` is actually numeric, so non-numeric decimal input would cause a BASIC error rather than a graceful re-prompt. - After the binary input path (lines 610–630), execution falls through to line 700 directly, while the hex and decimal paths use explicit `GOTO 700` and `GOTO 700` — but the binary path at line 630 has no `GOTO 700`, relying on fall-through from line 630 to 700. This works only because there are no intervening lines between 630 and 700. ## Source Code ``` 15 LET B=32768 20 LET A=VAL C$ 25 FOR I=1 TO 19 30 IF I=5 OR I=10 OR I=15 THEN NEXT I 35 LET C=INT (A/B) 40 LET D$(1,I)=STR$ C 45 IF A>=B THEN LET A=A-B 50 LET B=B/2 55 NEXT I 60 RETURN 210 LET B=4096 215 LET C=VAL C$ 220 FOR J=1 TO 4 225 LET A=INT (C/B) 230 IF A<10 THEN LET B$(1,J)=STR$ A 235 IF A>9 THEN LET B$(1,J)=CHR$ (A+28) 240 LET C=C-A*B 245 LET B=B/16 250 NEXT J 255 RETURN 300 LET A=10 305 LET B=11 310 LET C=12 315 LET D=13 320 LET E=14 325 LET F=15 330 LET AA=VAL B$(1,4)*1+VAL B$(1,3)*16+VAL B$(1,2)*256+VAL B$(1,1)*4096 335 LET C$=STR$ AA 340 RETURN 400 LET B=0 405 LET A=1 410 FOR I=19 TO 1 STEP -1 415 IF I=15 OR I=10 OR I=5 THEN NEXT I 420 LET B=B+A*VAL D$(1,I) 425 LET A=A*2 430 NEXT I 435 LET C$=STR$ B 440 RETURN 500 DIM D$(1,19) 501 DIM B$(1,4) 505 PRINT AT 10,4;"ENTER ""H"" FOR HEXADECIMAL" 510 PRINT AT 11,10;"""D"" FOR DECIMAL" 515 PRINT AT 12,10;"""B"" FOR BINARY" 520 INPUT A$ 525 IF A$="H" THEN GOTO 545 530 IF A$="D" THEN GOTO 580 535 IF A$="B" THEN GOTO 610 540 GOTO 520 545 CLS 550 PRINT AT 20,0;"ENTER HEX NO. ""0000"" " 555 INPUT Q$ 556 IF LEN Q$<>4 THEN GOTO 555 560 LET B$(1)=Q$ 561 FOR I=1 TO 4 562 IF CODE B$(1,I)>43 OR CODE B$(1,I)<28 THEN GOTO 555 563 NEXT I 564 FAST 565 GOSUB 300 570 GOSUB 15 575 GOTO 700 580 CLS 585 PRINT AT 20,0;"ENTER DECIMAL NO. ""0 TO 65535"" " 590 INPUT C$ 591 IF VAL C$>65535 THEN GOTO 585 592 FAST 595 GOSUB 210 600 GOSUB 15 605 GOTO 700 610 CLS 615 PRINT AT 20,0;"ENTER BINARY N0.""1 OR 0"" ""0000 0000 0000 0000"" " 620 INPUT Z$ 621 IF LEN Z$<>19 THEN GOTO 615 622 LET D$(1)=Z$ 623 FAST 625 GOSUB 400 630 GOSUB 210 700 SLOW 705 PRINT AT 20,0;" A15 8 7 0 B= ";D$(1);" " 710 SCROLL 715 SCROLL 720 PRINT AT 20,0;"H= ";B$(1,1);" ";B$(1,2);" ";B$(1,3);" ";B$(1,4) 725 SCROLL 730 PRINT AT 20,0;"D= 256 *";INT (VAL C$/256);AT 20,12;"+ ";VAL C$-256*INT (VAL C$/256);AT 20,22;"=";VAL C$ 735 SCROLL 740 SCROLL 745 PRINT AT 20,0;"ENTER D,H OR B FOR NEXT NO. ENTER ""S"" TO STOP, ""C"" TO COPY" 750 INPUT A$ 755 IF A$="D" THEN GOTO 585 760 IF A$="H" THEN GOTO 550 765 IF A$="B" THEN GOTO 615 770 IF A$="C" THEN COPY 775 IF A$="S" THEN STOP 780 GOTO 745 790 SAVE "1028%3" 800 GOTO 500 ```