Calculator

Date: 1982
Type: Cassette
Platform(s): TS 1000
Tags: Home

This program implements a multi-row calculator display interface with labeled rows A through H, each capable of storing a numeric or string value. Navigation and data entry are handled via single-key presses, with keys such as V (scroll), R/L (move right/left), T (toggle a mode flag M), and X (execute a calculation pass). The program uses POKE with PEEK-based address arithmetic to store the current row identifier (Z) into memory, suggesting a machine-code or system-variable table is being maintained in parallel with the BASIC display. Block graphics characters are used to draw bordered panels for each row, and a `FAST` mode directive at line 90 speeds up display rendering. A SAVE routine at line 9000 uses USR 8192, pointing to a machine code entry point in RAM.


Program Analysis

Program Structure

The program is organized into several functional blocks, using computed line-number arithmetic throughout rather than hard-coded targets. This is a common memory-saving idiom where variables initialized elsewhere encode key line numbers.

Line RangeRole
90–160Display initialization: draws bordered rows A–H using block graphics
200–290Main input loop: polls INKEY$ and dispatches on key press
300–330Row selection handler: updates Z to selected row, refreshes display
500–570Name/label entry for a row (INPUT S$, then POKEs row ID)
600–650Value entry for a row (INPUT S$, truncates to O chars, POKEs row ID offset)
800–840Numeric INPUT Y for a row, stores B=Y, POKEs row ID
900–995Calculation pass: iterates all rows A–H, evaluates VAL S$ for each
1000–1070Subroutine: displays computed value for current row
1100–1120Subroutine: refreshes header/status line
1200–1220Subroutine: POKEs a specific memory slot, restores S$ from B$
1300–1320Subroutine: POKEs a different memory slot, restores S$ from P$
9000–9010Save routine using USR 8192 (machine code); loops via GOTO U

Variable Conventions and Computed Line Numbers

The program makes heavy use of pre-initialized numeric variables (P, Q, R, W, K, L, U, V, O, J, X, T, S, M) as both display constants and line-number components. None of these are initialized within the visible listing, implying they are set in lines not shown (likely below line 90). This technique allows GOTO P-R, GOTO R+W, GOSUB P+W, etc., to encode target line numbers compactly. VAL "number" forms like GOTO VAL "910" are also used as a memory optimization.

Key inferred variable roles (from context):

  • P — base line number (likely 1000, since GOSUB P calls line 1000)
  • R — main loop line (likely 200, since GOTO R returns to input loop)
  • W — step increment (likely 100, making P+W=1100, P+R=1200/1300)
  • Q — a display row constant; used in PRINT AT Q,L
  • L — likely 0 (column start)
  • U — likely 0 or 1 (used in U-M toggle and U-U zero test)
  • K — a column or width constant
  • O — maximum string length for value entries
  • J — row offset adjustment in AT Z+Z-J
  • S, T — PEEK base addresses for the memory table

Display Technique

Rows A through H are drawn by iterating Z from CODE "A" (65) to CODE "H" (72). Each row uses block graphic characters — ▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌ for a top border line and for the left edge — to create a bordered panel effect. The cursor position for each row’s data is computed as AT Z+Z-J, which linearly maps character codes to screen rows, with J providing the offset to align Z=65 to the first display row.

The bottom border uses ▝▀▀▀▀▀▀▀▀▀▀▀▀▀▘ with corner block graphics for a clean rounded appearance. The FAST directive at line 90 suppresses display during the drawing loop for speed.

PEEK/POKE Memory Table

Several lines use the pattern POKE PEEK S + X*PEEK T + offset, Z to write the current row identifier into a memory location. This strongly suggests a small machine code routine or data table resides in RAM (with its address stored as a two-byte value at addresses S and T, read via PEEK S + X*PEEK T as a 16-bit address: low + 256*high). The offsets (+L, +K-V, +CODE "▒") select different fields within the table. The character code of (an inverse block graphic, char code in the 130s range) used as an offset reinforces that specific numbered slots are being indexed.

Input Dispatch and Navigation

The main loop at lines 200–290 uses a PAUSE X*R then INKEY$ idiom to poll the keyboard. Dispatch is handled by a chain of IF tests:

  • CHR$ VAL "118" = "v" — triggers a scroll/view action (GOTO P-R)
  • S$>="A" AND S$<="H" — row selection jump (GOTO R+W, i.e. line 300)
  • "X" — jumps to line 910 (calculation pass, bypassing the mode guard at 900)
  • "T" — toggles mode flag M via LET M=U-M
  • "R" — jumps to L*W (likely line 0 or a specific entry handler)
  • "L" — jumps to L*W+W

Calculation Pass (Lines 900–995)

Line 900 guards the pass with IF M=U-U THEN GOTO R, which evaluates to IF M=0 — skipping calculation when the mode flag is off. Lines 920–980 iterate Z over all eight row codes, calling GOSUB P+R (line 1200 or 1300 depending on P and R values) to load each row’s stored string into S$. If S$ is non-empty, it evaluates VAL S$ as a numeric expression (stored in H) via line 960, then calls GOSUB P (line 1000) to display the result.

USR 8192 Save Routine

Line 9000 calls USR 8192, which transfers execution to machine code at address 8192 (the start of the free RAM area on a 16K machine). The result is printed alongside a "SAVE:P:CALCULATOR:" string. This is a common pattern for invoking a machine code SAVE helper. Line 9010 loops with GOTO U, likely returning to the start of the program.

Notable Idioms and Anomalies

  • VAL CHR$ Z at line 1000 converts the numeric character code in Z back to a character (e.g., Z=65 → “A”) and then applies VAL — this only works if the character stored is a digit, suggesting rows may be remapped to digit codes during calculation.
  • W$(LEN S$+U TO Y) at line 630 uses a string slice of W$ (likely a padding/blank string) to erase trailing characters after a shorter replacement entry.
  • The S$=S$( TO O) truncation at line 620 enforces a maximum entry width of O characters.
  • Lines 1200 and 1300 each restore S$ from a saved string variable (B$ and P$ respectively), acting as context-switching subroutines for different row data fields.
  • The variable Y is used both as a saved row-cursor register (LET Y=Z / LET Z=Y) and as a numeric INPUT target at line 810, which could cause conflicts if the two uses overlap — a potential latent bug depending on call ordering.

Content

Appears On

Related Products

Perform numerical computations, much like a hand calculator— but considerably more powerful and it’s easier to use. It can be...

Related Articles

Related Content

Image Gallery

Source Code

  90 FAST
 100 PRINT "(C)1982 J. GISHEN",
 102 LET Y=Z
 105 FOR Z=CODE "A" TO CODE "H"
 110 PRINT "▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌","▐";
 120 GOSUB P
 122 GOSUB O*W
 125 PRINT TAB Q-L;"▌ ";CHR$ Z;TAB K;S$
 130 NEXT Z
 140 LET Z=Y
 160 PRINT "▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘",,,,,"RULE:"
 170 GOSUB P+W
 200 PRINT AT Z+Z-J,CODE "(";" ";CHR$ (Z+CODE "█");" "
 210 PAUSE X*R
 220 LET S$=INKEY$ 
 230 IF S$=CHR$ VAL "118" THEN GOTO P-R
 240 IF S$>="A" AND S$<="H" THEN GOTO R+W
 250 IF S$="X" THEN GOTO VAL "910"
 255 IF S$="T" THEN LET M=U-M
 260 IF S$="R" THEN GOTO L*W
 270 IF S$="L" THEN GOTO L*W+W
 290 GOTO R
 300 PRINT AT Z+Z-J,CODE ")";CHR$ Z
 310 LET Z=CODE S$
 320 GOSUB P+W
 330 GOTO R
 500 PRINT AT Q,L;"[>]"
 510 INPUT S$
 560 POKE PEEK S+X*PEEK T+L,Z
 562 LET H$=S$
 565 GOSUB P+W
 570 GOTO P-W
 600 PRINT AT Z+Z-J,K-U;"[>]"
 605 GOSUB O*W
 607 LET Y=LEN S$
 610 INPUT S$
 620 IF LEN S$>O THEN LET S$=S$( TO O)
 630 PRINT AT Z+Z-J,K;S$;W$(LEN S$+U TO Y)
 635 POKE PEEK S+X*PEEK T+L,Z+K-V
 640 LET O$=S$
 650 GOTO R
 800 PRINT AT Z+Z-J,CODE "(";"[<]"
 810 INPUT Y
 820 POKE PEEK S+X*PEEK T+L,Z
 830 LET B=Y
 840 GOSUB P
 900 IF M=U-U THEN GOTO R
 910 LET Y=Z
 920 FOR Z=CODE "A" TO CODE "H"
 930 GOSUB P+R
 940 IF S$="" THEN GOTO P-Q
 950 POKE PEEK S+X*PEEK T+L,Z
 960 LET H=VAL S$
 970 GOSUB P
 980 NEXT Z
 990 LET Z=Y
 995 GOTO R
 1000 PRINT AT Z+Z-J,U;W$( TO K-L);AT Z+Z-J,U;VAL CHR$ Z;
 1070 RETURN
 1100 GOSUB P+R
 1110 PRINT AT Q,L;W$( TO V);W$;AT Q,L+U;S$
 1120 RETURN
 1200 POKE PEEK S+X*PEEK T+CODE "▒",Z
 1210 LET S$=B$
 1220 RETURN
 1300 POKE PEEK S+X*PEEK T+K-V,Z+K-V
 1310 LET S$=P$
 1320 RETURN
 9000 PRINT USR 8192;"SAVE:P:CALCULATOR:"
 9010 GOTO U

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

People

No people associated with this content.

Scroll to Top