Math II

Date: 198x
Type: Program
Platform(s): TS 1000

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:

LineOperation
50Enter R, I (input new complex number)
100Push history (shift X array up by 2)
150Swap X and Y registers
200Store to K, M memory
250Recall from K, M memory
300Add: (R+X(3), J+X(4))
350Subtract: (X(3)−R, X(4)−J)
400Multiply: (R·X(3)−J·X(4), R·X(4)+J·X(3))
450Divide: uses D=R²+J² as denominator
500Reciprocal: (R/D, −J/D)
550Square root: principal square root formula
600Real 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 550553.

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 25 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 70110) scans all 64 X values to find the function’s minimum L and maximum H, enabling auto-scaling. The second pass (lines 130150) 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 99009930 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 240260)
  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 270460:

  • 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 210230). 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.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

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"' :-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 H<Z THEN LET H=Z
  90 IF L>Z 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<SQR 50 THEN LET V=5
 250 IF F<SQR 10 THEN LET V=2
 260 IF F<SQR 2 THEN LET V=1
 270 LET C=V*10**E
 280 LET G=INT (X/C)
 290 IF ABS (G+1-X/C)<J THEN LET G=G+1
 300 LET A=C*G
 310 LET H=INT (Y/C)+1
 320 IF ABS (Y/C+1-H)<J THEN LET H=H-1
 330 LET B=C*H
 340 PRINT "NEW MIN=",A,"NEW MAX=",B,"NEW INTERVAL=",
 345 PRINT C,"NO. INTERVALS=",H-G
 360 GOTO 40
 
  10 REM "RUKU"
  20 PRINT "4-TH ORDER RUNGE KUTTA"
  22 PRINT "ENTER FUNCTION DY/DX=F(X,Y)=?"
  26 INPUT R$
  28 PRINT "DY/DX=";R$
  30 PRINT "INTEGRATION INTERVAL H?";
  40 INPUT A
  50 PRINT A
  60 IF A<=0 THEN GOTO 30
  70 PRINT "ENTER X0,Y0,XLAST?";
  80 INPUT B
  90 PRINT B;
 100 INPUT C
 110 PRINT ",";C;
 120 INPUT D
 130 PRINT ",";D
 135 IF B=D THEN GOTO 70
 140 LET E=INT ABS (D-B)/A
 150 LET F=B
 160 LET G=SGN (D-B)*A
 170 LET H=C
 180 FOR I=1 TO E
 190 GOSUB 270
 200 NEXT I
 210 IF F=D THEN GOTO 240
 220 LET G=D-F
 230 GOSUB 270
 240 PRINT 
 245 PRINT "Y(";D;")=";H
 250 PRINT 
 260 GOTO 30
 270 LET X=F
 280 LET Y=H
 290 GOSUB 1000
 300 LET K=G*R
 310 LET X=F+G/2
 320 LET Y=H+K/2
 330 GOSUB 1000
 340 LET L=G*R
 350 LET Y=H+L/2
 360 GOSUB 1000
 370 LET M=G*R
 380 LET X=F+G
 390 LET Y=H+M
 400 GOSUB 1000
 410 LET N=G*R
 420 LET H=H+K/6+L/3+M/3+N/6
 430 LET F=F+G
 440 PRINT F;",";
 450 PAUSE 20
 460 RETURN 
 1000 LET R=VAL R$
 1010 RETURN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top