This program implements a spreadsheet application, written by Kristian Boisvert and published by Byte Power in 1987. The BASIC loader shell manages screen setup, file I/O (SAVE/LOAD of a CODE block at address 45840), and error handling for cell formula evaluation, while the bulk of the spreadsheet logic resides in machine code loaded separately. The program uses PEEK 65535 as a dynamic dispatch mechanism—jumping to whatever address is stored at the top of the 64KB address space—to hand control back to the machine code engine after each BASIC operation. Three separate CODE blocks are saved to tape: a print driver expected at address 29000 (up to 900 bytes), a main engine block at 29976 (15864 bytes), and a small block at 64494 (920 bytes).
Program Structure
The listing is purely a BASIC shell; the real spreadsheet logic lives in machine code loaded from tape. The program divides into clearly labelled sections:
- Lines 6–8: Initialisation — sets ink/paper/border, clears memory to 28999, dimensions a work string, then immediately dispatches to machine code via
GO TO PEEK 65535. - Lines 9–20: Formula calculation stub — evaluates
VAL a$(the cell formula) inside anON ERRguard, then patches five bytes of machine code with the result and returns control to the engine. - Lines 100–110: Quit — calls
USR 0to force a hard reset. - Lines 200–270: File I/O — SAVE and LOAD of the spreadsheet data as a CODE block (45840, length 18654).
- Lines 7000–7020: Error handler — prints a formatted error message including the offending cell address read from system variables, beeps, and waits for a keypress.
- Lines 8000–8020: File-name input subroutine with a 10-character length check.
- Lines 9000–9020: Splash screen and tape loader — loads two CODE blocks, optionally auto-runs.
- Line 9999: Master SAVE — saves the BASIC program, then the two CODE blobs, then verifies all three.
Dynamic Dispatch via PEEK 65535
The most striking idiom is the repeated use of GO TO PEEK VAL "65535" (lines 8, 20, 270, 7020). Because GO TO expects a line number, the machine code engine stores the target BASIC line number as a single byte at address 65535 (the last byte of the 64 KB address space). This gives the engine a lightweight, one-byte callback mechanism: it sets the byte and then triggers the appropriate BASIC line by falling through to a GO TO. Known targets visible in the listing are line 270 (redraw/continue) and whatever value is set for lines 8 and 20.
Machine Code Integration
| Address | Length | Purpose |
|---|---|---|
| 29000 | ≤900 bytes | Print driver (loaded separately, not in this listing) |
| 29976 | 15864 bytes | Main spreadsheet engine |
| 44952 | 5 bytes patched | Result-injection point (line 20 POKE loop) |
| 45840 | 18654 bytes | Spreadsheet data/workspace (SAVEd as user file) |
| 64494 | 920 bytes | Small auxiliary code block |
| 65535 | 1 byte | Dispatch register (target BASIC line number) |
Line 20 uses PEEK 23627 and PEEK 23628 to read the system variable STKEND (the top of the calculator stack), offset by 262, to locate the floating-point result of VAL a$. It then copies five bytes (the standard five-byte float format) into address 44952, injecting the computed value directly into machine code data.
Formula Evaluation Technique
Cell formulas are evaluated entirely through BASIC’s own expression evaluator. The machine code places the formula text into a$ (dimensioned to 255 characters at line 6), then triggers line 10 which executes LET e=VAL a$. This piggybacks on the built-in floating-point parser at zero implementation cost in the machine code. The ON ERR GO TO 7010 guard on line 10 catches any syntax or arithmetic error in the formula.
Error Reporting
The error handler at line 7010 decodes the offending cell address from two dedicated memory locations:
PEEK 65533— column index (offset by 1 and 64 to produce a letter viaCHR$)PEEK 65534— row number, with a leading zero suppressed by the("0" AND …<10)conditional string trick
The expression CHR$ VAL "((PEEK 65533)+1+64)" converts a 0-based column index to a letter (A=65 in ASCII). The row display uses the classic Sinclair idiom of multiplying a string by a boolean: ("0" AND condition) yields "0" when the condition is true, or "" when false.
Loader and Auto-Boot
Line 9006 loads two anonymous CODE blocks in sequence with LOAD ""CODE. Line 9010 checks PEEK 23681 (system variable FLAGS2, specifically the printer-buffer flag area) for zero; if zero it lists line 9999 and stops, presumably a development/save mode. Otherwise line 9020 runs the program normally. The PRINT AT 0,0; at line 7 before LET l=VAL "USR 29976" is used to set the print position before calling the machine code, which likely uses it as a signal.
Key BASIC Idioms
VAL "number"used pervasively for all numeric literals — a token-saving technique that stores the number as a short string rather than a five-byte float in the BASIC line.ON ERR GO TO/ON ERR RESET— TS2068 extended error-trapping keyword (rendered as{in zmakebas source).PRINT #0;in line 7010 directs output to stream 0 (the lower screen/editor area) for the error message.GO SUB VAL "8000"for the filename input subroutine, consistent with the VAL idiom throughout.
Content
Source Code
0 REM SPREADSHEET WRITTEN BY KRISTIAN BOISVERT ©1987 BYTE POWER
2 REM PRINT DRIVER SHOULD BE AT 29000 AND SHOULDN'T BE MORE THAN 900 BYTES LONG!!!
6 INK VAL "0": PAPER VAL "7": BORDER VAL "7": CLEAR VAL "28999": DIM a$(VAL "255"): LET E=VAL "0"
7 PRINT AT VAL "0",VAL "0";: LET l=VAL "USR 29976"
8 GO TO PEEK VAL "65535"
9 REM CALCULATE---DON'T MESS WITH THIS PART!!!
10 ON ERR GO TO VAL "7010": LET e=VAL a$
20 ON ERR RESET : LET A=VAL "PEEK 23627+256*PEEK 23628+262": FOR F=VAL "0" TO VAL "4": POKE F+VAL "45902",PEEK (A+F): NEXT F: PRINT AT VAL "0",VAL "0";: LET A$="": LET L=USR VAL "44952": GO TO PEEK VAL "65535"
100 REM QUIT PROGRAM
110 PRINT USR 0
200 REM SAVE FILE
210 GO SUB VAL "8000": IF B$="" THEN GO TO VAL "210"
220 SAVE B$CODE VAL "45840",VAL "18654"
230 PRINT AT VAL "20",VAL "0";"REWIND TO VERIFY ";B$: VERIFY B$CODE
240 GO TO VAL "270"
250 REM LOAD FILE
255 GO SUB VAL "8000"
260 LOAD B$CODE VAL "45840"
270 PRINT AT VAL "0",VAL "0";: LET L=VAL "USR 38619": GO TO PEEK VAL "65535"
7000 REM ON ERROR IN FORMULA
7010 PRINT #VAL "0";AT VAL "0",VAL "0";TAB VAL "7";"ERROR IN CELL "; FLASH VAL "1";CHR$ VAL "((PEEK 65533)+1+64)";("0" AND VAL "PEEK 65534<10");PEEK VAL "65534"
7020 ON ERR RESET : BEEP VAL ".5",VAL "20": PAUSE VAL "0": PRINT AT VAL "0",VAL "0";: GO TO VAL "270"
8000 REM GET STRING
8010 INPUT "FILE NAME:"; LINE B$: IF LEN B$>VAL "10" THEN GO TO VAL "8010"
8020 RETURN
9000 CLS : PRINT AT VAL "8",VAL "3";"JUST ANOTHER SPREADSHEET!";AT VAL "10",VAL "8";"©1987 BYTE POWER";AT VAL "12",VAL "2";"WRITTEN BY KRISTIAN BOISVERT"
9005 PRINT AT VAL "20",VAL "0";"STILL LOADING..."
9006 INK VAL "7": PRINT AT VAL "15",VAL "0";: LOAD ""CODE : PRINT AT VAL "15",VAL "0";: LOAD ""CODE
9010 INK VAL "0": PRINT AT VAL "20",VAL "0";TAB VAL "31";" ": IF VAL "PEEK 23681=0" THEN PRINT AT VAL "15",VAL "0";: LIST VAL "9999": STOP
9020 RUN
9999 SAVE "SHEET" LINE VAL "9000": SAVE "SHEET"CODE VAL "29976",VAL "15864": SAVE "SHEET"CODE VAL "64494",VAL "920": VERIFY "SHEET": VERIFY "SHEET"CODE : VERIFY "SHEET"CODE
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

