5.10 NextPi on the Raspberry Pi¶
NextPi is the software that runs on the Raspberry Pi of the Spectrum Next,
the small computer on its GPIO header. The Next talks to it over its second
UART, and NextZXOS comes with the tools that use it: .pisend, .piget,
.piput, the NextPi UI, and programs that hand speech, music and tape
streaming to the Pi.
JNEXT does not emulate the Pi. It does the next best thing: it runs a real NextPi under QEMU and connects it to the Next's UART, so those tools talk to the genuine article.
Turning it on¶
You need QEMU installed — on macOS brew install qemu; on Fedora
sudo dnf install qemu-system-arm qemu-img; on Debian or Ubuntu
sudo apt install qemu-system-arm qemu-utils; on Windows install QEMU for
Windows and either add its folder to your PATH or set the QEMU binary under
Settings ▸ Preferences ▸ NextPi. On Windows the Pi is reached over a local
(loopback) socket, which may raise a firewall prompt the first time. Then either tick Start
NextPi under Settings ▸ Preferences ▸ NextPi and restart JNEXT (the tick
starts NextPi when JNEXT starts the ZX Next), or start it for one run, with any
machine, with:
jnext --nextpi
JNEXT checks for QEMU (and, before the first start, qemu-img) first, and
stops with that install hint if it is missing, before offering or downloading
anything.
The first time, JNEXT offers to download NextPi, the way it offers to download
the SD card image: about 6 GB, with a progress bar, into ~/.jnext/nextpi. It
needs about 22 GB free while the image is unpacked, and about 15 GB afterwards.
Every later start skips all of that. If you say No, JNEXT starts without NextPi,
even with --nextpi, and asks again next time.
If the download stops (network trouble, Cancel, closing JNEXT), the part already
fetched is kept as NextPi-<release>.tar.gz.part in the NextPi directory, and the
next start continues from there after asking; delete that file to start over.
A download that finished but could not be put in place is used as it is on the next
start.
If no data arrives for a few seconds, the progress dialog says the download has stalled and for how long; after 30 seconds without data JNEXT stops waiting and says why. Cancel works at any time.
Checking the mirror (the list of releases, the checksum) shows the same progress dialog, stall
notice included, when it takes more than a second. Without the dialog (--headless, or a build
with no Qt window) a check that takes more than a second prints one line on the terminal and in
the log, naming what it is doing and the address (Fetching the NextPi checksum... and the
address of the checksum), and any download that gets no data for five seconds prints the same
stalled notice as the dialog; a quick check prints nothing. When any of these fails, JNEXT says which
address it was fetching, what went wrong in plain words (with the error code after it) and what
it does next, and in the graphical version the message is in a dialog whose text can be selected
and copied: try the address in a web browser to see whether the mirror can be reached at all.
If you already have NextPi, or prepare it by hand¶
Put NextPi-<release>.tar.gz from the mirror (and, if you have it, its .md5)
in the NextPi directory (~/.jnext/nextpi; on Windows %USERPROFILE%\.jnext\nextpi).
JNEXT checks it against the MD5 and unpacks it without downloading, then deletes
the archive.
To prepare the directory by hand instead: nextpi.img is the .img inside the
archive, renamed; boot/kernel.img and boot/bcm2708-rpi-zero.dtb are copied
from the image's first (FAT) partition; and a file release holds the release
name, which must be the NextPi release set in Preferences (default 1_93D).
When JNEXT cannot use what is there, the question and the log say which file is
missing or which check failed. A run started from an icon shows no log: add
--log-file FILE to its shortcut to keep one.
NextPi takes about a minute to boot. Then, at the NextZXOS command line:
.pisend -q
.pisend -c nextpi-play_speech "Hello from the Spectrum Next"
The first finds the Pi; the second asks it to speak. On Linux and macOS the Pi's
sound goes through the Next's own mixer, as on the real machine: it plays with the rest of the
Next's sound, a video or WAV recording of the session includes it, and NextREG
0xA2 turns it on and off (NextPi's tools turn it on themselves). It arrives a
little late — about a tenth of a second — and at the 10-bit quality of the
Next's input. With bit 0 of NextREG 0xA2 set, the Pi's sound goes to the EAR
input instead, the tape signal port 0xFE bit 6 reads, which is how a Next loads
a tape the Pi plays to it.
QEMU runs in the background for as long as JNEXT does, and stops with it. A
soft or hard reset of the Next leaves the Pi running, as it would on the real
machine. Changing the machine neither starts nor stops it. --no-nextpi
leaves the Pi off for one run even when the preference is ticked.
The NextPi settings¶
Everything except the on/off tick has a sensible default, and an empty field in the Preferences tab means that default:
| Setting | Default | What it is |
|---|---|---|
| NextPi directory | ~/.jnext/nextpi |
where the download goes and NextPi runs from |
| NextPi release | 1_93D |
a release name on the NextPi mirror, or latest for the newest one there |
| QEMU | qemu-system-arm on your PATH |
the QEMU to run; qemu-img is expected beside it |
| Pi audio | the Next's mixer | or host to play it on your computer's default output (pa on Linux, coreaudio on macOS, dsound on Windows), a QEMU audio driver to play it straight to your computer, none to mute it, or wav:FILE to record it on its own |
| Extra QEMU arguments | none | added after JNEXT's own when NextPi starts |
Each setting also has an optional command-line flag, for one run and over the
saved value, in a headless session too: --nextpi-dir DIR, --nextpi-release
NAME, --nextpi-qemu PROGRAM, --nextpi-audio SPEC and --nextpi-qemu-args
"ARGS". An empty value means the default. They go with --nextpi (or a saved
preference that starts NextPi), which alone starts NextPi with the defaults.
Given when NextPi is not enabled for the run, a flag is ignored and JNEXT warns
in its log, naming it.
Changes made in Preferences take effect the next time JNEXT starts. Changing the release makes the
next start offer to download that one in place of the installed one. With
latest, JNEXT checks the mirror each time it starts; if it cannot reach it, it
carries on with the release it has, and says so, with the address it tried.
The Pi's SD card image is never changed: everything NextPi writes goes to
overlay.qcow2 in the NextPi directory. Delete that file to start again from a
pristine image. QEMU's own messages go to qemu.log there too, which is the
place to look if the Pi never answers.
Extra QEMU arguments¶
The box under Extra QEMU arguments (or --nextpi-qemu-args "...") is added to the end of the QEMU command
line when NextPi starts. It is split into arguments on spaces, so one box
holding -serial telnet:127.0.0.1:2357,server,nowait is two arguments,
-serial and the address. Single or double quotes keep spaces inside one
argument (-name 'my pi'); there are no escapes, so a backslash is an ordinary
character and a Windows path can be pasted as it is. Nothing is expanded
($HOME, ~ and * stay as typed) and no shell is involved. A quote that is
never closed stops NextPi from starting, with a message naming where it opens.
When NextPi starts, the log shows how the box was split: NextPi: 2 extra QEMU
arguments, after JNEXT's own: "-serial" "telnet:127.0.0.1:2357,server,nowait".
The arguments come after JNEXT's own, so a -serial of yours is the Pi's second
serial port (its mini UART, ttyS0) and the NextPi console stays where JNEXT
connected it. That makes a second telnet console possible:
-serial telnet:127.0.0.1:2357,server,nowait. Write the address as shown:
telnet::2357 listens on every network interface, and without nowait QEMU
waits for a client to connect before it boots the Pi. NextPi as shipped runs
nothing on ttyS0, so the port accepts a connection but stays silent until you
set up a login (a getty) on it inside NextPi.
JNEXT does not check the arguments. One that conflicts with JNEXT's own (a
second -M or -kernel, a -chardev with the id pi) can stop NextPi, and
QEMU's reason is in qemu.log. Like every NextPi setting, the box is read only
by sessions with a window, not by --headless (use --nextpi-qemu-args there).
When nothing arrives¶
On a real Next the Pi's UART pins only reach the Next once a program sets
NextREG 0xA0 to 0x30, and JNEXT follows that: until then the Pi's bytes are
lost and the Next's never reach it. NextPi's own tools set it themselves; a
program of your own has to do the same. The first time traffic is lost this
way, JNEXT says so once in its log. Everything the Pi prints while it boots is
lost the same way, which is harmless: .pisend -q starts a fresh conversation.
The Pi also cannot be heard while NextREG 0x0B gives the same UART to the
joystick port (5.7).
What it does not do¶
- It is not saved in snapshots. Rewinding and RZX playback do not resend anything to the Pi, and the Pi is not rewound either.
- Only the serial link and the sound cross over, not the Pi's other GPIO pins.