How the JOYSTIK editor (BASIC front-end) works

← Voltmace Delta 14B Driver

The JOYSTIK editor (BASIC front-end)

This describes the BBC BASIC program in voltmace-delta-14b-driver-joystik.bas — the user-facing half of the Voltmace Delta 14B JOYSTIK software. Line numbers below refer to that program.

What it is for

The Delta 14B handset has a two-axis analogue joystick, two fire buttons, and (via the Delta 14B/1 adaptor) a keypad. Games written for the keyboard can't use it directly. This program lets you map joystick directions, fire buttons and keypad keys onto keyboard keys, then installs a small machine-code resident driver that makes those inputs look like key presses to any game that reads the keyboard with INKEY(-key) (lines 500–510 explain that convention to the user).

You pick a joystick configuration, choose a ready-made mapping for an Acornsoft game (or define your own), optionally test and tune it, and finish. The resident driver then stays at &A00–&AFF while your game is loaded and run.

The companion machine code — the two resident-driver templates this program configures and installs — is covered by the disassemblies in driver-a.asm and driver-b.asm.

Shape of the program

Lines Role
10–170 Startup, protection clean-up, OS check, array DIMs
190–240 Main flow: intro, init, game select, edit, build, menu
250–272 Error handling
280–520 PROCINTRO — copyright, joystick-configuration choice, help
530–600 Screen furniture (PROCCONT, PROCWARN, PROCSCREEN, PROCFUNCTION)
610–990 PROCGAME — pick a preset game mapping or user-define; the DATA tables
1020–1070 Key display/entry (PROCEDIT, PROCDEFAULTPRINT)
1080–1190 PROCINIT — key-name, INKEY-value, sensitivity and channel tables
1200–1240 PROCKEY — read a key definition
1250–1370 PROCFINI — how to save the resident driver and load your game
1380–1460 PROCTERM — the Edit / Test / Sensitivity / Finish menu
1470–1710 PROCTEST — live display of joystick, buttons and keypad
1720–1870 PROCASSEM — build and install the resident driver
1880–1930 PROCJOY — adjust joystick sensitivity
1960–2010 Finish: wipe the program, leave the resident driver running

Startup and protection (10–170)

Line 10 is a REM whose length byte is stored as 0 and repaired to &17 by the loader before the program runs. Line 50 selects MODE 7, clears Z%, and saves the current BYTEV (OVL%=?&20A:OVH%=?&20B) — the previous OSBYTE vector, which the resident driver will chain to. As in the KEYPAD editor, Z% is a resident integer (at &468) that selects protected behaviour (Z%=0) over an unprotected/developer mode (Z%=1); it is 0 here and nothing changes it, so the protected path always runs. Lines 60–80 accordingly reprogram the BREAK key: a BBC Micro has no f10 key, so soft key 10 (*KEY10) is the "break string" a soft (single) BREAK types into the input. They set it to a self-destruct — empty the program at PAGE, zero &1902–&5000, and print "PROGRAM PROTECTED" — arming the trap rather than firing it now. Line 90 reads the OS version (?&F0C7/?&F0C8); line 130's *FX200,2 additionally clears user memory on the next BREAK (OSBYTE 200 bit 1) while leaving ESCAPE (bit 0) working as the handled "restart" path; and lines 140–150 dimension the working arrays.

Intro and joystick configuration (280–520)

PROCINTRO shows the copyright, then (lines 350–400) asks which configuration is in use:

Lines 420–510 explain that the resident driver simulates up to J% keyboard keys and is compatible with games that read the keyboard via INKEY(-key).

Choosing a mapping (610–990)

PROCGAME lists eight choices (line 610): user-defined plus seven ready-made mappings for Acornsoft games, named in the T$ table (line 1150). Selecting one (line 640) RESTOREs to the matching DATA line — 890–960 for the single joystick, 810–880 for the adaptor configurations — and reads a preset list of key codes into V%(), the key each joystick input should emulate for that game.

How a preset row is encoded

Each preset is a positional list of key codes, read one value per input by PROCGAME's loop FOR E%=0 TO H%: READ L% (line 970) — so H%+1 values in all: 8 for the single joystick, 36 for the adaptor. The position E% is the input, and its on-screen label is C$(E%) (line 1170):

The value L% at each position is the magnitude of the negative-INKEY code for the key that input should emulate. The reader recovers the key by scanning the N%() code table (line 1120) for a matching code (line 980, last match wins) and names it through K$() (lines 1100–1110). The code 24 — the - key — serves as the "unused" filler for inputs a game leaves unmapped.

The seven game presets

The T$ entries are stored as the program spells them on screen — including ACORNSOFT ARCADIAN and ACORNSOFT METEOR (both singular), which are the program's labels for Acornsoft's Arcadians and Meteors:

# Game (as stored) ↑ Up ↓ Down ← Left → Right Fire 1 Fire 2
0 USER DEFINED (default) ↑ ↓ ← → RETURN SPACE
1 ACORNSOFT SNAPPER : / Z X – –
2 ACORNSOFT MONSTERS : / Z X F D
3 ACORNSOFT PLANETOID A Z SPACE SHIFT RETURN TAB
4 ACORNSOFT METEOR SHIFT – CAPSLOCK CTRL RETURN SPACE
5 ACORNSOFT ARCADIAN – – CAPSLOCK CTRL RETURN RETURN
6 ACORNSOFT ROCKET RAID A Z SPACE SHIFT RETURN TAB
7 ACORNSOFT SUPER INVADERS – – Z X RETURN RETURN

The table shows the single-joystick presets (H%=7, DATA 890–960), with each fire button's a/b pair collapsed to one column (every preset sets both halves alike). The – filler explains the shape of these rows: Snapper (a maze game) has no fire, and the left/right-only shooters (Arcadian, Super Invaders, Meteor) park the unused vertical axis on –.

The adaptor presets (H%=35, DATA 810–880) carry 36 slots for the two handsets. They drive the joystick on handset B with the same directions and fire keys as above, leave handset A unmapped, and for three games map the keypad keys to fire as well: Monsters → F/D, and Planetoid and Meteor → TAB/SPACE, so keypad presses double as fire buttons.

Initialisation tables (1080–1190)

PROCINIT sets the sensitivity (SEN%, and the thresholds SL%/SH%, line 1080), then reads:

K$() and N%() are one table in two halves: index i names a key (K$(i)) and gives its code (N%(i)). The code is the BBC's internal key number — the value you negate to test the key with INKEY(-code), and the number the resident driver returns a "pressed" answer to. So SHIFT=1, CTRL=2, SPACEBAR=99 (&63), RETURN=74 (&4A), ESCAPE=113 (&71). This is the Rosetta stone the whole editor turns on: the game presets (Choosing a mapping, above) are stored as these codes and decoded back to names through it, and PROCKEY (Defining and displaying keys, below) identifies a held key by scanning INKEY(-N%(n)) across the table.

Each half spans two DATA lines only because 73 entries (indices 0–72) don't fit on one: K$() runs f0…SLASH on 1100 then ESCAPE…cursor keys on 1110, and N%() runs 72 codes on 1120 with the 73rd spilling onto 1130. That last entry pairs a blank name with code 3 — internal key number &03 is one of the keyboard's row-0 startup-link (DIP-switch) lines, not a pressable key, so it names nothing and acts as an inert end-stop the presets never select.

Defining and displaying keys (1000–1240)

For user-defined mappings, PROCEDIT (line 1020) restores the saved BYTEV so the keyboard reads normally, then PROCKEY (line 1200) waits for you to hold a key, identifies it by scanning INKEY(-N%(n)) for every key, and records its INKEY value in V%(). PROCDEFAULTPRINT (line 1040) shows the current mapping.

Building the resident driver (1720–1870)

PROCASSEM turns the mapping into a working resident driver:

Test, tune and finish (1380–2010)

PROCTERM (line 1380) offers Edit / Test / Alter sensitivity / Finish. PROCTEST (line 1470) shows a live grid: PROCDISAD/PROCDISLOW/PROCDISHIGH threshold the analogue axes (ADVAL), PROCDISFIRE reads the fire buttons (ADVAL(0)), and PROCDISUP reads the keypad matrix through the User VIA. PROCJOY (line 1880) re-computes SL%/SH% from a 1–9 sensitivity and re-pokes &AFD/&AFE live. PROCFINI (line 1250) tells you how to *SAVE the resident driver (*SAVE <name> A00 +100) and re-install it later (*KEY10 CALL &A00). The finish code (lines 1960–2010) blanks and detaches the program, leaving only the configured resident driver.