This program is a four-band resistor color code decoder that uses a combination of BASIC and machine code loaded from tape. The user cycles through the first three value bands (keys 1, 2, 3) and the tolerance band (key 5) to dial in a resistor’s color combination; the program then calculates and displays both the exact resistance value and the nearest E12 preferred value. Machine code routines are called via USR at addresses 57500, 57510, 57520, 57530, 57613, 57637, 57663, and 57676, handling tasks such as drawing the graphical resistor representation and updating band colors. Resistance is formatted automatically into Ohms, Kilohms, or Megohms with the omega symbol represented as the UDG character \a. The program includes multi-page scrolling help and information screens, a COPY key for printing the screen, and a ‘Q’ key that loads the next program from tape.
Program Analysis
Program Structure
The program is organized into clearly delineated subroutine blocks, each with its own REM header. After loading machine code from tape and initializing, control enters a main polling loop at line 110 that dispatches to subroutines based on key presses. The overall flow is:
- Lines 10–50: Load machine code, set up display, initialize via
GO SUB 6000(information pages). - Lines 100–200: Main event loop — poll
INKEY$and branch on keys 1, 2, 3, 5, Z/z, I/i, H/h, C/c, Q/q. - Lines 4000–4040: Printer copy routine (BEEP + COPY).
- Lines 5000–5090: Help page display.
- Lines 6000–6600: Multi-page information display and preferred-value formatting/printing.
- Lines 7000–7090: Preferred E12 value calculation.
- Lines 7500–7520: Resistance value calculation.
- Lines 7600–7690: Resistance value formatting and printing.
- Lines 8000–8690: Band advance routines for bands 1, 2, 3, and tolerance.
- Lines 9500–9900: Variable initialization, array loading, data tables.
- Lines 9997–9999: Save/build lines (not part of normal execution).
Machine Code Integration
The program loads a binary block (“rescode”) to address 57500 and calls it extensively via USR. Eight distinct entry points are used:
| Address | Called from | Purpose (inferred) |
|---|---|---|
| 57500 | Line 8030 | Redraw band one color on graphical resistor |
| 57510 | Line 8230 | Redraw band two color |
| 57520 | Line 8430 | Redraw band three color |
| 57530 | Line 8640 | Redraw tolerance band color |
| 57613 | Line 7515 | Update resistance display graphic |
| 57637 | Line 6595 | Update preferred value display graphic |
| 57663 | Line 180 | Part of ‘I’ key info-page reset sequence |
| 57676 | Lines 180, 9795 | Draw initial resistor graphic / full redraw |
The machine code block spans 8036 bytes (57500 to 65535, filling memory to the very top). Each band advance routine first POKEs a color byte into address 65535 — the top byte of RAM — presumably as a parameter passed to the machine code routine that follows at the corresponding USR address.
Data Tables
Three arrays are populated from DATA statements during initialization:
C$(10,6): Color name strings (” Black”, ” Brown”, ” Red “, “Orange”, “Yellow”, ” Green”, ” Blue “, “Violet”, ” Grey “, ” White”), each padded to six characters.T$(2,6): Tolerance name strings (” Gold “, “Silver”).C(10): Numeric color codes passed to machine code — values 0, 22, 18, 114, 118, 36, 9, 27, 63, 127, likely attribute or pixel data.T(2): Tolerance color codes — 54 (Gold), 85 (Silver), assigned directly rather than via DATA.M(9): Multiplier array — 1, 10, 100, 1000, 10000, 100000, 1000000, 0.1, 1 — covering all standard resistor multiplier bands including the gold (×0.1) sub-ohm case.P(12): E12 preferred value series — 10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82.
E12 Preferred Value Algorithm
The subroutine at line 7000 computes the nearest E12 preferred value to the selected resistance. It first handles edge cases: values at or above 10MΩ are clamped to 10MΩ (line 7005); a two-digit mantissa below 10 is clamped to 10 (line 7025); one above 82 is clamped to 82 (line 7035). For values in between, it walks the P() array (lines 7040–7060), finding the two E12 neighbors and selecting whichever is closest by absolute difference. The result is then scaled by M(BAND3) to restore the correct decade.
Note a subtle indexing detail: in line 7015, when the two-digit mantissa is ≥ 91, the preferred value jumps directly to 10 * M(BAND3+1) — advancing the decade — rather than clamping to 82. This correctly handles values like 910Ω or 9.1kΩ rounding up to 1kΩ.
Resistance Formatting
Both the actual and preferred value formatters (lines 7600–7690 and 6510–6590) apply the same three-tier logic: below 1000 → Ohms, 1000–999999 → Kilohms (÷1000 + “K”), ≥1000000 → Megohms (÷1000000 + “M”). The omega symbol is rendered using UDG \a (character 144). The preferred value printer (line 6580) centers the string using an arithmetic expression: AT 21,(0*(LEN P$=32))+(1*(LEN P$<32)) — this evaluates the boolean conditions as 0/1 integers, effectively placing the string at column 1 unless it exactly fills the 32-character line, in which case column 0 is used to avoid a scroll.
Band Advance Logic
Band 1 cycles through values 1–9 (wraps from 10 back to 1, skipping black as the leading digit). Band 2 cycles 0–9 (wraps from 10 back to 0). Band 3 cycles 1–8, where values 1–7 use the standard multiplier color names and value 8 maps to Gold (×0.1); the label “Gold” is printed directly rather than from C$(). The tolerance band cycles between 1 (Gold, 5%) and 2 (Silver, 10%) only.
Display and POKE Setup
Lines 9510 and 40 POKE 23606 and 23607 with values 98 and 251 respectively, setting the system variable ATTR_P (permanent attributes) and configuring the display. PAPER 0: INK 9 (INK 9 = transparent/contrast ink) with BORDER 0 gives a black border and black background throughout. The FLASH 1 effect is used on “PRESS ANY KEY TO CONTINUE” prompts and on the preferred value display when it differs from the actual resistance value.
Notable Anomalies and Minor Issues
- Line 180 uses lowercase
a$for the variable, while line 120 assigns toA$. On the Spectrum these are the same variable; the mixed case is inconsistent but harmless. - Line 185 falls through without a
GO TO 120orRETURN; after the help page subroutine, execution falls into lines 186 and 187 rather than looping back. This means H also triggers the COPY and quit-load checks on the same keypress — a minor bug. - The text in line 6085 uses
\ato represent the omega symbol for “OHMS” but the surrounding prose spells it out as well, so the intent is clear even if the UDG is undefined on a fresh machine without the loaded code. - Lines 9997–9999 are save/build utilities and include a
STOPat line 9998, so they are never reached during normal use. - The
M(9)array contains value 1 at index 9 after the gold multiplier at index 8; this appears to be a sentinel or placeholder for an unused band value.
Content
Source Code
10 REM LOAD THE CODE.
20 CLEAR 50000
30 LOAD ""CODE
40 POKE 23606,98: POKE 23407,251: BORDER 0: PAPER 0: FLASH 0: CLS
50 GO SUB 6000
100 REM MAIN LOOP
110 GO SUB 9500
120 LET A$=INKEY$: IF A$="" THEN GO TO 120
130 IF A$="1" THEN GO SUB 8000: GO TO 120
140 IF A$="2" THEN GO SUB 8200: GO TO 120
150 IF A$="3" THEN GO SUB 8400: GO TO 120
160 IF A$="5" THEN GO SUB 8600: GO TO 120
170 IF A$="Z" OR A$="z" THEN GO SUB 4000: GO TO 120
180 IF a$="I" OR a$="i" THEN LET a=USR 57663: GO SUB 6000: LET a=USR 57676: GO TO 120
185 IF a$="h" OR a$="H" THEN GO SUB 5000
186 IF a$="c" OR a$="C" THEN COPY
187 IF a$="q" OR a$="Q" THEN CLEAR 65367: POKE 23606,0: POKE 23607,60: PAPER 1: CLS : PRINT AT 10,9;" Now Loading ": LOAD ""
190 GO TO 120
200 GO TO 120
4000 REM CHECK FOR PRINTER COPY
4030 BEEP .1,30: COPY : BEEP .1,30
4040 RETURN
5000 REM PRINT HELP PAGE.
5010 BORDER 2: PAPER 2: CLS
5020 PRINT PAPER 1; INK 7;AT 1,5;"RESISTOR COLOUR CODER"
5030 INK 7: PLOT 35,171: DRAW 180,0: DRAW 0,-16: DRAW -180,0: DRAW 0,16
5040 INK 6: PRINT AT 5,4;"1 Advance band one";AT 7,4;"2 advance band two";AT 9,4;"3 Advance band three";AT 11,4;"5 Advance tolerance band"
5050 REM STOP
5060 PRINT PAPER 1; INK 7; FLASH 1;AT 21,2;" PRESS ANY KEY TO CONTINUE "
5070 LET A$=INKEY$: IF A$="" THEN GO TO 5070
5080 IF a$="z" OR a$="Z" THEN GO SUB 4000: GO TO 5070
5085 GO SUB 9500
5090 BORDER 0: RETURN
6000 REM PRINT INFORMATION PAGES
6010 PAPER 0: CLS : PRINT PAPER 2; INK 6;AT 1,5;"RESISTOR COLOUR CODER"
6020 INK 7: PLOT 35,171: DRAW 180,0: DRAW 0,-16: DRAW -180,0: DRAW 0,16
6030 REM PRINT PAGE ONE
6040 PRINT AT 5,0;"This program will de-code any four band colour-coded resistor.": PRINT ''" The program presents youwith a graphical representation of a four band resistor. Thefirst three bands determine the resistance of the resistor andthese bands may be advanced by pressing keys 1,2&3 respective-ly."
6050 GO SUB 6400
6060 LET a$=INKEY$: IF A$="" THEN GO TO 6060
6062 IF a$="z" OR a$="Z" THEN GO SUB 4000: GO TO 6060
6070 REM PRINT PAGE TWO
6080 GO SUB 6450
6085 PRINT AT 5,0;"Any resistance below 1 000\a (\a is the symbol for ""OHMS"" ) isrefered to simply as Ohms - E.G.222 Ohms ( 222\a ). However resi-"
6090 PRINT "stances between 1 000\a & 919 999\a are refered to as Kilohms ( orK\a ) ) E.G. 64K\a."
6095 PRINT " In similar vein,any resist-ance over 1 000 000\a is referedto in Megohms ( or M\a ) - E.G.8.3M\a."
6100 GO SUB 6400
6105 LET a$=INKEY$: IF a$="" THEN GO TO 6105
6107 IF a$="Z" OR a$="z" THEN GO SUB 4000: GO TO 6105
6110 REM PRINT PAGE THREE
6115 GO SUB 6450
6120 PRINT AT 5,0;"The fourth band indicates thetolerance of the resistor andmay be advanced by pressing '5'.The lower the tolerance figureof the resistor the closer theactual resistance will be to thevalue indicated by the colouredbands."
6125 PRINT " What this means in practiceis that the resistance of a 5%resistor will be closer to itsindicated value than will a 10%resistor."
6130 GO SUB 6400
6135 LET a$=INKEY$: IF a$="" THEN GO TO 6135
6137 IF a$="z" OR a$="Z" THEN GO SUB 4000: GO TO 6135
6140 REM PRINT PAGE FOUR
6145 GO SUB 6450
6150 PRINT AT 5,0;"If you feel you need reminding of the keys & their operations, pressing 'H' will bring up a help page for you to peruse. "
6155 PRINT " Pressing 'I' will bring upthese information pages & press-ing 'C' will allow you to copythe current screen to your ZX-PRINTER ( if you have one attac-hed.)"
6156 PRINT " ": PRINT " "
6160 PRINT " Pressing 'Q' will quit and LOAD next program."
6165 GO SUB 6400
6170 LET a$=INKEY$: IF a$="" THEN GO TO 6170
6172 IF a$="z" OR a$="Z" THEN GO SUB 4000: GO TO 6170
6180 RETURN
6400 REM PRINT "PRESS ANY KEY"
6410 PRINT PAPER 1; INK 7; FLASH 1;AT 21,2;" PRESS ANY KEY TO CONTINUE "
6420 RETURN
6450 REM ERASE "PRESS ANY KEY"
6460 PRINT PAPER 0; INK 0;AT 21,0;" "
6470 RETURN
6500 REM PRINT NEW PREFERRED VALUE.
6510 IF PREFVAL>=1000 THEN GO TO 6530
6520 LET P$=STR$ (PREFVAL)+"\a": GO TO 6560
6530 IF PREFVAL>=1000000 THEN GO TO 6550
6540 LET P$=STR$ (PREFVAL/1000)+"K\a": GO TO 6560
6550 LET P$=STR$ (PREFVAL/1000000)+"M\a"
6560 LET P$="Nearest preferred value is "+P$
6565 IF PREFVAL<>RESVAL THEN FLASH 1
6570 PRINT PAPER 0; INK 0;AT 21,0;" "
6580 PRINT BRIGHT 1; PAPER 2; INK 6;AT 21,(0*LEN P$=32)+(1*LEN p$<32);P$
6590 FLASH 0
6595 LET a=USR 57637
6600 RETURN
7000 REM CALCULATE NEW PREFERRED RESISTANCE VALUE.
7005 IF RESVAL>=1E7 THEN LET PREFVAL=1E7: RETURN
7010 LET PREFVAL=10*BAND1+BAND2
7015 IF PREFVAL>=91 THEN LET PREFVAL=10*M(BAND3+1): RETURN
7020 IF PREFVAL>10 THEN GO TO 7030
7025 LET PREFVAL=10: GO TO 7080
7030 IF PREFVAL<82 THEN GO TO 7040
7035 LET PREFVAL=82: GO TO 7080
7039 REM PREFERRED VALUE MUST BE IN THE RANGE 1.2-6.8 INCLUSIVE
7040 FOR F=2 TO 11
7045 IF PREFVAL>=P(F+1) THEN NEXT F
7050 IF ABS (P(F+1)-PREFVAL)>=ABS (PREFVAL-P(F)) THEN LET PREFVAL=P(F): GO TO 7080
7060 LET PREFVAL=P(F+1)
7080 LET PREFVAL=PREFVAL*M(BAND3)
7090 RETURN
7500 REM CALCULATE NEW RESISTANCE VALUE.
7510 LET RESVAL=(10*BAND1+BAND2)*M(BAND3)
7515 LET a=USR 57613
7520 RETURN
7600 REM PRINT NEW RESISTANCE VALUE.
7610 IF RESVAL<1000 THEN LET P$=STR$ (RESVAL)+"\a"
7620 IF (RESVAL>=1000) AND (RESVAL<1000000) THEN LET P$=STR$ (RESVAL/1000)+"K\a"
7630 IF RESVAL>=1000000 THEN LET P$=STR$ (RESVAL/1000000)+"M\a"
7640 LET P$="Resistor value is "+P$
7650 IF TOLBAND=1 THEN LET P$=P$+" 5%"
7660 IF TOLBAND=2 THEN LET P$=P$+" 10%"
7670 PRINT PAPER 0; INK 0;AT 19,0;" "
7680 PRINT PAPER 2; INK 6; BRIGHT 1;AT 19,(((0-.5)*LEN p$)+15.5);P$
7690 RETURN
8000 REM ADVANCE BAND NNE.
8005 LET BAND1=BAND1+1
8010 IF BAND1=10 THEN LET BAND1=1
8020 POKE 65535,C(BAND1+1)
8030 LET A=USR 57500
8040 PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,2;C$(BAND1+1)
8050 GO SUB 7500
8060 GO SUB 7600
8070 GO SUB 7000
8080 GO SUB 6500
8090 RETURN
8200 REM ADVANCE BAND TWO.
8205 LET BAND2=BAND2+1
8210 IF BAND2=10 THEN LET BAND2=0
8220 POKE 65535,C(BAND2+1)
8230 LET A=USR 57510
8240 PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,9;C$(BAND2+1)
8250 GO SUB 7500
8260 GO SUB 7600
8270 GO SUB 7000
8280 GO SUB 6500
8290 RETURN
8400 REM ADVANCE BAND THREE.
8405 LET BAND3=BAND3+1
8410 IF BAND3=9 THEN LET BAND3=1
8420 IF BAND3<=7 THEN POKE 65535,C(BAND3)
8425 IF BAND3=8 THEN POKE 65535,54
8430 LET A=USR 57520
8440 IF BAND3<=7 THEN PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,16;C$(BAND3)
8445 IF BAND3=8 THEN PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,16;" Gold "
8450 GO SUB 7500
8460 GO SUB 7600
8470 GO SUB 7000
8480 GO SUB 6500
8490 RETURN
8600 REM ADVANCE TOLERANCE BAND.
8610 LET TOLBAND=TOLBAND+1
8620 IF TOLBAND=3 THEN LET TOLBAND=1
8630 POKE 65535,T(TOLBAND)
8640 LET A=USR 57530
8650 IF TOLBAND=1 THEN PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,24;" Gold "
8660 IF TOLBAND=2 THEN PRINT BRIGHT 1; PAPER 2; INK 7;AT 15,24;"Silver"
8670 GO SUB 7500
8680 GO SUB 7600
8690 RETURN
9500 REM INITIALISE VARIABLES.
9505 BORDER 0: PAPER 0: INK 9: CLS
9510 POKE 23606,98: POKE 23607,251
9520 DIM C$(10,6)
9530 RESTORE : DATA " Black"," Brown"," Red ","Orange","Yellow"," Green"," Blue ","Violet"," Grey "," White"
9540 FOR f=1 TO 10: READ a$: LET c$(f)=a$: NEXT f
9550 DIM T$(2,6)
9560 DATA " Gold ","Silver"
9570 FOR f=1 TO 2: READ a$: LET T$(f)=a$: NEXT f
9600 LET band1=2
9610 LET band2=6
9620 LET band3=5
9630 LET tolband=2
9640 LET resval=260000
9650 LET prefval=270000
9660 DIM C(10)
9670 DATA 0,22,18,114,118,36,9,27,63,127
9680 FOR F=1 TO 10: READ A: LET C(F)=A: NEXT F
9690 DIM T(2): LET T(1)=54: LET T(2)=85
9700 LET P$="Resistor value is 260k\a 10%"
9795 LET A=USR 57676
9800 DIM m(9)
9810 DATA 1,10,100,1000,10000,100000,1000000,.1,1
9820 FOR f=1 TO 9: READ a: LET m(F)=A: NEXT F
9830 DIM p(12)
9840 DATA 10,12,15,18,22,27,33,39,47,56,68,82
9850 FOR f=1 TO 12: READ a: LET p(f)=a: NEXT f
9900 RETURN
9997 CLEAR 50000: SAVE "RESISTOR" LINE 1: SAVE "rescode"CODE 57500,8036
9998 STOP
9999 CLEAR 50000: MOVE "RESISTOR.bas",1: MOVE "rescode.bin",57500,8036
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

