Support ROM for Retro Hardware's Advanced Digital Joystick Interface cartridge for the Acorn Electron/BBC Master 128.
Based in part on the Slogger Electron Expansion 2.02 ROM: https://github.com/tom-seddon/SloggerElectronExpansion
Requires Electron or Master 128.
Connect the joystick interface to one of the cartridge slots, and plug a 9-pin joystick into the 9-pin plug.
Use the DIP switches on the cartridge to select the joystick number, relating to the address the joystick will use. You can pick any, they're all the same, provided it won't conflict with some other piece of hardware attached to the computer.
The DIP switch settings and corresponding number and address (and known problems) are as follows:
Switches | Number | Address | Notes |
---|---|---|---|
D D | 1 | &FCC0 | Not compatible with Electron+Plus 3 |
U D | 2 | &FCD0 | |
D U | 3 | &FCE0 | |
U U | 4 | &FCF0 |
The ROM can run from any bank, including sideways RAM.
There is a special version of the ROM for use with the original Slogger Switched Joystick Interface cartridge. This doesn't support a 2nd fire button, but is otherwise fully-featured!
This ROM reports itself as (1F)
in the *HELP
output.
Note that *JKEYS
still requires a valid number to be specified for
the second fire button, even though the value is ignored. *JSETUP
will suggest 0
.
To test it out, use *JTEST
. This takes one parameter: the joystick
number, 1-4, corresponding to the DIP switch settings on the cartridge
(see above).
The joystick test screen reads the joystick, and shows on screen which directions and/or buttons are being pressed.
The ADJI supports 2 independent fire buttons if the joystick has them.
You'll be prompted for the following. Press Escape at any time to cancel.
Joystick no (1/2/3/4)?
- enter the joystick number.
Joystick/Keys (J/K)?
- press J
to have the joystick behave as an
analogue joystick, or K
to have it translated into keypresses for
games.
If behaving as an analogue joystick, it behaves as if it's the first
analogue joystick, and its state can be read with ADVAL
or OSBYTE
&80:
ADVAL(0)
reports the fire button - both are treated the sameADVAL(1)
reports the digital left/right axisADVAL(2)
reports the digital up/down axis
If behaving as keys, it hooks into the processing of INKEY
and
OSBYTE &81 - the goal being to support its use with games. The
joystick can't be used for ordinary text input.
Press UP:
, Press DOWN:
, Press LEFT:
, Press RIGHT:
, Press FIRE1:
, Press FIRE2:
- if you opted for keys mode, you'll be
prompted for the key that each joystick action should correspond to.
Press each key in turn.
SHIFT
behaves slightly differently: hold SHIFT
and press ESCAPE
to cancel; hold SHIFT
and press CTRL
to have no key bound to that
action; or, to use SHIFT
specifically, tap SHIFT
(it will be
recognised when you release it without having pressed another one
meanwhile).
Xvector/Overlay (X/O)?
- pick the method the ROM uses to hook into
the keyboard and joystick processing.
Xvector
uses the extended vectors, which would be the Acorn-approved
method, but many games overwrite the relevant OS workspace and so you
may experience crashes or hangs.
Overlay
installs a short routine somewhere in RAM to handle the
hooking. (The routine is 15 bytes on the Master, and 18 bytes on the
Electron.) There's no best place for this to go, so you'll be prompted
for an address!
The default of &150, which will be used if you just press Return when prompted, should be good for many games. If you still experience problems, unfortunately some experimentation may be necessary. These other options are all worth trying:
- &100-&140 inclusive - also in the stack area
- &880-&8A0 inclusive - the printer buffer
- &380-&3C0 inclusive (disk only) - OS tape workspace
If using the printer buffer, you must then avoid using the printer, and if using the OS tape workspace, you must then avoid using tapes!
When providing an address in hex, precede with &
, as per BASIC.
Once the questions are over, *JSETUP
will install the hooks and
finish. Last thing it does is print a *JKEYS
(see below) or *JJOY
(see below) command line, that you can note down and use later to set
up the same settings non-interactively (e.g., from !BOOT
or a loader
program).
The *JSETUP
settings will persist across a SHIFT+BREAK or BREAK if
you do it straight away after *JSETUP
. Note that after running a
game, they might not survive a subsequent BREAK, even if the joystick
was working fine in game.
*HELP ADJI
will print (active)
or (inactive)
to indicate the
ADJI joystick status.
Cancels any *JSETUP
/*JJOY
/*JKEYS
settings and makes the ADJI
inactive again.
No parameters required.
*JJOY
takes 2 parameters:
- Joystick number, 1-4, as per
*JTEST
- Overlay address (precede with
&
if in hex), orX
to use extended vectors
The settings will persist across a soft BREAK as per *JSETUP
.
Run *JPRESET
with no parameters to see the list of presets
available, numbered from 0 upwards. Each one lists the keys for that
preset: up, down, left, right, fire button 1, and fire button 2 (not
shown if using the 1F
ROM).
To select a preset, supply 3 parameters to *JPRESET
:
- Joystick number, 1-4, as above
- Preset number, 0 upwards, as above
- Overlay address or
X
, as above
Like *JSETUP
, the settings will persist across a soft BREAK.
(Note that if using the 1F
ROM, some presets are identical, as they
differ only in the key assigned to the 2nd fire button.)
*JKEYS
takes 7 parameters, with all keys specified as negative INKEY
values:
- Joystick number, 1-4, as above
- Key for up
- Key for down
- Key for left
- Key for right
- Key for fire button 1
- Key for fire button 2 (ignored if using the
1F
ROM) - Overlay address or `X', as above
Easiest thing to do is use *JSETUP
, which will prompt you for the
keys and print a command line you can use again.
The settings will persist across a soft BREAK as per *JSETUP
and
*JPRESET
.
A key can be specified as its negative INKEY value (either in decimal
or hex), or its name, as per the following tables. (Key numbers 0-9
are not valid, so there is no ambiguity when using the number keys.)
You can abbreviate key names with .
, some as BASIC keywords and star
commands - e.g., RET.
is shorthand for RETURN
.
Keys common to all systems:
Name | Dec | Hex | Name | Dec | Hex | Name | Hex | Hex | ||
---|---|---|---|---|---|---|---|---|---|---|
A | -66 | &BE | S | -82 | &AE | - | -24 | &E8 | ||
B | -101 | &9B | T | -36 | &DC | ; | -88 | &A8 | ||
C | -83 | &AD | U | -54 | &CA | : | -73 | &B7 | ||
D | -51 | &CD | V | -100 | &9C | , | -103 | &99 | ||
E | -35 | &DD | W | -34 | &DE | . | -104 | &98 | ||
F | -68 | &BC | X | -67 | &BD | / | -105 | &97 | ||
G | -84 | &AC | Y | -69 | &BB | SPACE | -99 | &9D | ||
H | -85 | &AB | Z | -98 | &9E | ESCAPE | -113 | &8F | ||
I | -38 | &DA | 0 | -40 | &D8 | DELETE | -90 | &A6 | ||
J | -70 | &BA | 1 | -49 | &CF | RETURN | -74 | &B6 | ||
K | -71 | &B9 | 2 | -50 | &CE | UP | -58 | &C6 | ||
L | -87 | &A9 | 3 | -18 | &EE | DOWN | -42 | &D6 | ||
M | -102 | &9A | 4 | -19 | &ED | LEFT | -26 | &E6 | ||
N | -86 | &AA | 5 | -20 | &EC | RIGHT | -122 | &86 | ||
O | -55 | &C9 | 6 | -53 | &CB | COPY | -106 | &96 | ||
P | -56 | &C8 | 7 | -37 | &DB | SHIFT | -1 | &FF | ||
Q | -17 | &EF | 8 | -22 | &EA | CTRL | -2 | &FE | ||
R | -52 | &CC | 9 | -39 | &D9 | CAPS | -65 | &BF |
There's also an additional special key, corresponding to no key on the keyboard. Use this if you don't want a given joystick action to correspond to a key.
Name | Dec | Hex |
---|---|---|
NONE | -128 | &80 |
Keys specific to Master:
(The names starting with N
are for the numeric keypad.)
Name | Dec | Hex | Name | Dec | Hex | |
---|---|---|---|---|---|---|
@ | -72 | &B8 | N0 | -107 | &95 | |
[ | -57 | &C7 | N1 | -108 | &94 | |
\ | -121 | &87 | N2 | -125 | &83 | |
] | -89 | &A7 | N3 | -109 | &93 | |
^ | -25 | &E7 | N4 | -123 | &85 | |
_ | -41 | &D7 | N5 | -124 | &84 | |
TAB | -97 | &9F | N6 | -27 | &E5 | |
SHIFTLOCK | -81 | &AF | N7 | -28 | &E4 | |
f0 | -33 | &DF | N8 | -43 | &D5 | |
f1 | -114 | &8E | N9 | -44 | &D4 | |
f2 | -115 | &8D | N+ | -59 | &C5 | |
f3 | -116 | &8C | N- | -60 | &C4 | |
f4 | -21 | &EB | N/ | -75 | &B5 | |
f5 | -117 | &8B | N# | -91 | &A5 | |
f6 | -118 | &8A | N* | -92 | &A4 | |
f7 | -23 | &E9 | N, | -93 | &A3 | |
f8 | -119 | &89 | NRETURN | -61 | &C3 | |
f9 | -120 | &88 | NDELETE | -76 | &B4 | |
N. | -77 | &B3 |
-
Joystick keys don't affect OSRDCH, so you can't use them to press keys at the BASIC prompt, or when using
INPUT
, etc. -
*JJOY
effectively disables both analogue joysticks
The joystick appears as a single byte in page &FC, location depending on the DIP switch settings, as per the table above.
The value read is a 6-bit quantity, bits as follows. Each used bit is set if the corresponding button is pressed, or the joystick is moved in that direction.
(Raw value
shown in the *JTEST
output will show the exact value
read.)
Bit | What |
---|---|
7 | Indeterminate - ignore |
6 | Indeterminate - ignore |
5 | Fire 2 |
4 | Fire 1 |
3 | Right |
2 | Left |
1 | Down |
0 | Up |
On the Electron, you can read the value directly. A%=?&FCC0
from
BASIC, for example, to read the joystick state into A%
. Or something
like lda &FCC0
from assembly language.
On the Master but page &FC needs to be redirected to the cartridge
first, by setting bit 5 of ACCCON (&FE34): ?&FE34=?&FE34 OR &20
, or
lda #&20:tsb &FE34
. Once you've done this, the joystick can be read
same as on the Electron.
Changing this setting may interfere with any devices connected to the 1 MHz bus, so you might want to save the old value of ACCCON and restore it afterwards.
There isn't tons of spare memory, so the ROM's state has to be squeezed in. Here's where it lives.
The ROM stores all of its state in the Master's filing system workspace (aka HAZEL). 2 filing system info blocks are used.
The ROM sneaks its data into 7 otherwise-unused bytes of OS workspace. One byte is used for flags:
- &0290 - unused by Electron OS
The remaining 6 are used when the joystick behaves as keys, to store the key assignments:
- &02A8 (ROM flags for the keyboard's other ROM bank)
- &02A9 (ROM flags for the keyboard's ROM bank)
- &02AA (ROM flags for the BASIC ROM's other ROM bank)
- &02F5 (unused by Electron OS)
- &02F6 (unused by Electron OS)
- &027E (unused by Electron OS)
To handle persistence across a BREAK, the following areas are also used:
- &39F-&3A6 (unused by Electron OS) - copy of the ROM state above
- &287-&289 (BREAK intercept routine) - xvector/overlay settings info
See https://github.com/tom-seddon/ADJI/blob/main/games.md