--- title: "Math II" id: 58432 type: "computer_media" slug: "math-ii" url: "http://localhost/computer_media/math-ii/" markdown_url: "http://localhost/computer_media/math-ii.md" published_at: "2024-11-17T13:10:50+00:00" modified_at: "2026-04-03T07:58:02+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/11/RSC.jpeg" excerpt: "Five math routines in one package — complex arithmetic, function plotting with compiled machine code, Runge-Kutta integration, and axis scaling — packed into a single BASIC program." 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: "Mathematics" slug: "mathematics" taxonomy: "genre" url: "http://localhost/type/mathematics/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Math%20II%20%28198x%29%28UNK%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/11/RSC.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/RTFND.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/RUKU.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/Tape-11-scaled.jpg" media_type_tags: "Mathematics" --- Multiple math routines. - Plot = Super Function Plot – See REMs for instructions - RSC = Scaling Program - RUKU = 4th Order Runge Kutta - RTFND = Transcendental Equation Solution - CMAR = Doesn’t run Math II is a collection of five mathematical routines for the ZX81/TS1000: a complex number calculator (CMAR), a function plotter (Super Function Plot), a scale-interval calculator (RSC), a fourth-order Runge-Kutta ODE integrator (RUKU), and a transcendental equation solver (RTFND). The function plotter compiles a 386-byte machine code routine into RAM starting at address 16514, allowing subsequent plotting via RAND USR 16514 without re-running the BASIC. RUKU implements the classical four-stage Runge-Kutta method, accepting the derivative function as a string evaluated with VAL R$ at runtime. The complex number calculator (CMAR) stores a history of operands in array X(8) and supports 12 operations (selected by jumping to line 50*F) including addition, subtraction, multiplication, division, reciprocal, and square root of complex numbers, though the routine is noted as non-functional. *** ## Program Analysis ### Program Structure The listing contains five independent programs loaded separately. Each is identified by a REM label at its start. The five components are: 1. **CMAR** — Complex number calculator (noted as non-functional) 2. **Super Function Plot** — Graphing utility with machine code compilation 3. **RSC** — Axis scaling calculator 4. **RUKU** — Fourth-order Runge-Kutta ODE integrator 5. **RTFND** — Transcendental equation solver (listing not included) ### CMAR — Complex Number Calculator CMAR uses a single array `X(8)` as a register stack, storing the current complex number in `X(1)`/`X(2)` and history entries in higher slots. The operation selector at line `20` accepts an integer `F` from 1 to 12, then dispatches via `GOTO 50*F`, placing each operation’s code at line multiples of 50. This is a compact computed-GOTO idiom that avoids a long IF-THEN chain. The 12 operations mapped to line numbers are: | Line | Operation | | --- | --- | | 50 | Enter R, I (input new complex number) | | 100 | Push history (shift X array up by 2) | | 150 | Swap X and Y registers | | 200 | Store to K, M memory | | 250 | Recall from K, M memory | | 300 | Add: (R+X(3), J+X(4)) | | 350 | Subtract: (X(3)−R, X(4)−J) | | 400 | Multiply: (R·X(3)−J·X(4), R·X(4)+J·X(3)) | | 450 | Divide: uses D=R²+J² as denominator | | 500 | Reciprocal: (R/D, −J/D) | | 550 | Square root: principal square root formula | | 600 | Real part of square (R²−J²) | Line `74` computes `D=R*R+J*J` (the modulus squared) immediately after each entry, making it available for division and reciprocal operations. The subroutine at line `1000` shifts the result array down by 2 positions after binary operations, maintaining register-stack semantics. The square root at line `554` uses the standard formula `SQR((R+|Z|)/2)` with the imaginary part derived as `J/(2·re)`; special-casing for zero is handled at lines `550`–`553`. ### Super Function Plot — Machine Code Compilation This is the most technically sophisticated component. Line `0` contains a long REM statement that encodes a 386-byte machine code routine as character data within the REM body. Lines `2`–`5` fill the screen rapidly in FAST mode as a side-effect of the initialization. The program then accepts three inputs: a function expression string (e.g., `SIN X`), a lower X limit, and an upper X limit. The plotting proceeds in two passes. The first pass (lines `70`–`110`) scans all 64 X values to find the function’s minimum `L` and maximum `H`, enabling auto-scaling. The second pass (lines `130`–`150`) uses POKE to write the machine code plot data into RAM starting at address `N=16514`. Each iteration advances `N` by 6 bytes. Key idioms used: - `SGN PI` evaluates to 1 — used as a loop start value to avoid the literal digit `1` - `CODE "RND"` evaluates to `82` (ASCII of ‘R’) — used as an upper loop bound of 64 via `CODE "RND"` which is actually 82; the loop at line `70` runs `TO CODE "RND"` which is 82 steps, matching the 63-step increment from line `40` (`DX=(A-X)/VAL "63"`) - `NOT PI` evaluates to 0 — used as loop start in the second pass - `CODE "Z"` = 90 — used as upper bound for the POKE loop - `VAL "16514"`, `VAL "2"`, `VAL "43-..."`, `VAL "6"` — all use `VAL` of string literals for constants, a memory-saving technique since numeric literals stored in BASIC lines carry a 5-byte floating-point overhead - `UNPLOT NOT USR VAL "16514",RND` at line `500` calls the machine code at 16514 via `USR`; `NOT` of the return value (typically non-zero) yields 0, so `UNPLOT 0,RND` is a harmless no-op used purely to trigger the USR call - `GOTO PI*PI` at line `600` jumps to approximately line 9 (PI²≈9.87), which rounds down to the nearest existing line Line `133` computes the Y screen coordinate inline within a `VAL` string: `VAL "43-(H-VAL A$)/(H-L)*43"`, where `A$` holds the function expression. This evaluates the user’s function and scales the result to the 44-row display in a single expression. Lines `9900`–`9930` provide a self-listing routine that uses LPRINT and LLIST to produce a hard-copy listing on a printer, repeating 20 times. Line `9999` contains the full user instructions as a REM. ### RSC — Scaling Program RSC computes aesthetically “round” axis tick intervals given a data range and a desired number of intervals. It mirrors standard chart-scaling algorithms: 1. Compute raw interval `D=(Y-X)/N` 2. Find the order of magnitude `E=INT(LN D/LN 10)` 3. Normalize to `F=D/10^E` and snap to 1, 2, 5, or 10 using square-root thresholds (lines `240`–`260`) 4. Compute rounded minimum and maximum bounds aligned to the chosen tick size The tolerance variable `J=D/1E5` guards against floating-point rounding at lines `290` and `320`, adjusting boundary indices when the computed value is within `J` of an integer. The program loops back to line `40` after each result, allowing repeated scaling queries. ### RUKU — Fourth-Order Runge-Kutta Integrator RUKU numerically integrates a first-order ODE dy/dx = f(x,y) using the classical RK4 algorithm. The derivative function is entered as a string in `R$` and evaluated at runtime via `LET R=VAL R$` at line `1000`. The variables `X` and `Y` must appear in the function string — they are set directly by the integrator before each `GOSUB 1000` call. The four RK4 stages are computed at lines `270`–`460`: - `K = G·f(F, H)` - `L = G·f(F+G/2, H+K/2)` - `M = G·f(F+G/2, H+L/2)` - `N = G·f(F+G, H+M)` - Update: `H = H + K/6 + L/3 + M/3 + N/6` The variable `G` holds the signed step size (`SGN(D-B)*A`), allowing integration in either direction. After the main loop, a partial step is taken if the endpoint `D` is not exactly reached (lines `210`–`230`). A `PAUSE 20` at line `450` slows output display between steps. The program loops at line `260` back to the interval prompt, allowing repeated integrations. ### Notable Techniques and Anomalies - The `GOTO 50*F` dispatch in CMAR is a computed-GOTO pattern that keeps the code compact and eliminates a multi-branch IF structure. - Super Function Plot’s use of `VAL` strings for numeric constants throughout is a systematic memory optimization, since BASIC stores each unquoted numeric literal with a 5-byte binary float. - The machine code written by Super Function Plot is encoded character-by-character in the line `0` REM, a common technique for embedding binary data in BASIC programs. - The `VAL R$` trick in RUKU for runtime function evaluation is a powerful but fragile idiom — it works only because `X` and `Y` are simple BASIC variable names accessible in the evaluation context. - RSC’s use of square-root thresholds (`SQR 50`, `SQR 10`, `SQR 2`) for interval rounding is mathematically elegant: each threshold is the geometric mean of adjacent standard values (5 and 10, 2 and 5, 1 and 2), giving a logarithmically fair rounding rule. - CMAR is explicitly noted as non-functional; inspection of the code does not reveal an obvious syntax error, but the logic at line `73` prints `X(3)` and `X(4)` before they are initialized on first entry, which would display undefined values. ## Source Code ``` 5 REM "CMAR" 10 DIM X(8) 15 PRINT 18 PRINT "OPERATION 1-12?"; 20 INPUT F 25 PRINT F 27 IF F<>INT F OR F<1 OR F>12 THEN GOTO 18 40 GOTO 50*F 50 PRINT "ENTER R,I?"; 55 INPUT X(1) 60 PRINT X(1); 65 INPUT X(2) 67 PRINT ",";X(2) 70 LET R=X(1) 72 LET J=X(2) 73 PRINT " REAL","IMAGINARY","Y: ";X(3),X(4),"X: ";R,J 74 LET D=R*R+J*J 75 GOTO 15 100 FOR I=8 TO 3 STEP -1 105 LET X(I)=X(I-2) 110 NEXT I 115 GOTO 70 150 LET X(1)=X(3) 165 LET X(2)=X(4) 170 LET X(3)=R 175 LET X(4)=J 180 GOTO 70 200 LET K=R 205 LET M=J 210 GOTO 70 250 LET X(1)=K 255 LET X(2)=M 260 GOTO 70 300 LET X(1)=R+X(3) 305 LET X(2)=J+X(4) 310 GOTO 1000 350 LET X(1)=X(3)-R 355 LET X(2)=X(4)-J 360 GOTO 1000 400 LET X(1)=R*X(3)-J*X(4) 405 LET X(2)=R*X(4)+J*X(3) 410 GOTO 1000 450 LET X(1)=(R*X(3)+J*X(4))/D 455 LET X(2)=(R*X(4)-J*X(3))/D 460 GOTO 1000 500 LET X(1)=R/D 505 LET X(2)=-J/D 510 GOTO 1000 550 IF R<>0 OR J<>0 THEN GOTO 554 551 LET X(1)=0 552 LET X(2)=0 553 GOTO 70 554 LET X(1)=SQR ((R+SQR (R*R+J*J))/2) 555 LET X(2)=J/2/X(1) 560 GOTO 70 600 LET X(1)=R*R-J*J 610 GOTO 70 1000 FOR I=3 TO 6 1010 LET X(I)=X(I+2) 1015 NEXT I 1020 GOTO 70 0 REM ' LN %M"' ' ''LN %M"' ': LN %M"' '':'LN %M"' . ,,LN %M"' : "LN %M"' .'£LN %M"' :':LN %M"' ##?LN %M"' ,,(LN %M"' ~~>LN %M"' ";LN %M"' <,LN %M"' =.LN %M"' +0LN %M"' -0LN %M"' *1LN %M"' /2LN %M"' ;2LN %M"' ,3LN %M"' .3LN %M"' 04LN %M"' 15LN %M"' 25LN %M"' 36LN %M"' 46LN %M"' 57LN %M"' 67LN %M"' 78LN %M"' 88LN %M"' 99LN %M"' A9LN %M"' B9LN %M"' CALN %M"' DALN %M"' EBLN %M"' FBLN %M"' GBLN %M"' HCLN %M"' ICLN %M"' JDLN %M"' KDLN %M"' LDLN %M"' MELN %M"' NELN %M"' OELN %M"' PFLN %M"' QFLN %M"' RFLN %M"' SGLN %M"' TGLN %M"' UGLN %M"' VHLN %M"' WHLN %M"' XHLN %M"' YHLN %M"' ZILN %M"TAN AA 2 FAST 3 FOR L=SGN PI TO 44 4 PRINT "% % % % % % % % % % % % % % % % "; 5 NEXT L 6 SLOW 10 INPUT A$ 14 LET N=VAL "16514" 15 LET T=PI+PI 20 INPUT X 25 LET X1=X 30 INPUT A 35 FAST 40 LET DX=(A-X)/VAL "63" 50 LET H=VAL A$ 60 LET L=H 70 FOR I=SGN PI TO CODE "RND" 75 LET Z=VAL A$ 80 IF HZ THEN LET L=Z 100 LET X=X+DX 110 NEXT I 120 LET X=X1 130 FOR I=NOT PI TO CODE "Z" 132 POKE N+SGN PI,I 133 POKE N+VAL "2",VAL "43-(H-VAL A$)/(H-L)*43" 135 LET X=X+DX 140 LET N=N+VAL "6" 150 NEXT I 170 SLOW 500 UNPLOT NOT USR VAL "16514",RND 600 GOTO PI*PI 9900 FOR L=1 TO 20 9905 LPRINT " *** SUPER FN PLOT ***",,, 9910 LLIST 9920 LPRINT ,,,,,,,, 9930 NEXT L 9999 REM WELCOME TO SUPER FNPLOT. WHEN YOU RUN THE PROGRAM,THE COMPUTER WILL REQUEST THREEINPUTS. ANSWER THE FIRST WITH AFUNCTION, SUCH AS "SIN X" OR "X*X+5*X-3". THE NEXT TWO INPUTSARE THE LOWER AND UPPER LIMITS,RESPECTIVELY, ON "X" IN THEFUNCTION. IF YOU WERE USING"SIN X", THEN YOU MIGHT WANT TOUSE THE LIMITS OF 0 AND 2*PI. ASAN ADDED CONVEINANCE, THE LETTER"T" CAN BE SUBSTITUTED FOR 2*PI.AFTER PLOTTING THE FIRST FN, TRYTHIS: STOP THE PROGRAM AND TYPE"RAND USR 16514" AND THE SAME FNWILL BE RAPIDLY PLOTTED. THIS ISBECAUSE THE PROGRAM COMPILES AMACHINE CODE ROUTINE AT 16514THAT IS 386 BYTES LONG. THOSEOF YOU WHO HAVE EPROM/CMOS/64KMEMORIES MAY WANT TO RELOCATETHE MC TO WHERE IT CAN BE CALLED LATER. 10 REM "RSC" 20 CLS 30 PRINT "SCALING PROGRAM" 40 PRINT 45 PRINT "ENTER MINIMUM?"; 50 INPUT X 60 PRINT X 70 PRINT "ENTER MAXIMUM?"; 80 INPUT Y 90 PRINT Y 100 IF Y>X THEN GOTO 130 110 PRINT "ERROR, MIN>=MAX" 120 GOTO 40 130 PRINT "ENTER APPR. NO. OF INTERVALS?"; 140 INPUT N 150 PRINT N 160 IF N>0 AND N=INT ABS N THEN GOTO 190 170 PRINT "ERROR" 180 GOTO 130 190 LET D=(Y-X)/N 200 LET J=D/1E5 210 LET E=INT (LN D/LN 10) 220 LET F=D/10**E 230 LET V=10 240 IF F