Tutorial 6: Extending ZX BASIC
Adapted from Spectranet: Tutorial 6.
The Spectranet ROM provides a mechanism for extending the ZX BASIC interpreter. This is built around the Spectrum's normal error path: when BASIC rejects syntax, it executes RST 8 with an error code, and the Spectranet can trap that path before the Spectrum ROM handles the error.
How extensions work
The Spectranet ROM examines a table of registered commands. If the text rejected by BASIC matches a registered extension, Spectranet calls the command handler. If not, control returns to the Spectrum ROM and the normal BASIC error is reported.
Command handlers may be written in assembly, C, or a mixture. They can run from main RAM, Spectranet static RAM, or a ROM module. Code running from a Spectranet ROM module is normally assembled for paging area B at 0x2000 to 0x2FFF.
Registering a simple command
A command is registered by filling a basic_cmd structure and passing it to addbasicext. A simple command normally uses the "Nonsense in BASIC" trap code.
#include <stdio.h>
#include <spectranet.h>
char *token = "*simple";
void simpleCmd();
main()
{
struct basic_cmd bc;
bc.errorcode = TRAP_NONSENSE;
bc.command = token;
bc.rompage = 0;
bc.function = simpleCmd;
if (addbasicext(&bc) < 0) {
printk("Failed to add extension\n");
return;
}
printk("Added basic extension.\n");
}
After installation, entering *simple in BASIC runs simpleCmd.
Command handlers
Handlers must cooperate with the ZX BASIC parser. A no-argument command should check for statement end before doing the real work. When it finishes successfully, it must return through the Spectranet ROM routine that restores BASIC correctly.
The original tutorial also covers a more complex *poke x,y command, showing how a handler can call Spectrum ROM parser routines through the Spectranet CALLBAS mechanism. While Spectranet memory is paged in, RST 0x10 followed by a two-byte address acts like a call into the Spectrum ROM and returns with Spectranet memory paged back in.
C library caution
When a BASIC extension calls Spectranet ROM routines, use the non-paging library variant. If a default paging library pages Spectranet out before the handler jumps to a Spectranet ROM return routine, the machine will crash because the Spectrum ROM will be visible at that address.