5. Running programs¶
The short version: give JNEXT a file.
jnext game.nex
jnext game.tap
jnext game.sna
The format is recognised from the extension — .nex, .jns, .sna, .szx,
.z80, .tap, .tzx, .wav and .rzx are all understood. (.jns is
JNEXT's own whole-machine snapshot; see 5.9 Snapshots, which also says
which machine each snapshot format loads as.) A bare filename is
exactly the same as --load FILE; you cannot use both at once. A .pok is not
a program but a list of cheats for the one that is running: in the window it
opens the trainers dialog (5.11 POK trainers), and on the
command line it is refused.
A NEX V1.3 file can declare a buffer for an argument line, and --nex-args
fills it:
jnext --load game.nex --nex-args "level 3"
The program finds that text zero-terminated at the address the file declares,
exactly as it would when launched with arguments from NextZXOS; DE then holds
that address plus the buffer's size, which is where the Next's V1.3 loader
leaves it (not the address itself, as the format's notes say). A line longer than the
buffer the file declares is truncated to fit. Only V1.3 files have the buffer,
so with anything else the option warns and is ignored.
Note that NEX V1.3 is an experimental format and is not supported in any
way. Loading a V1.3 file needs an explicit opt-in: on the command line, add
--experimental-nex-v1.3 (without it the load is refused with an error); in
the window, JNEXT shows a warning dialog and only proceeds if you confirm.
V1.0–V1.2 files load normally, no opt-in involved.
Some NEX files are larger than the program their header describes. When the header asks for the file to stay open, the program can read the extra data from its own file, and JNEXT lets it. When it does not, JNEXT does what the Next's own loader does: it loads the declared part, ignores the rest and runs the program. More than 16 KB of ignored data is reported with a warning.
In the window, File > Load NEX File… (Alt+O) opens the same loader and accepts every one of those formats despite its name. Tapes have their own entry, Tape > Open Tape File… (Alt+T), covered in 5.5. A file that cannot be loaded — missing, truncated, or not the format its extension says — gets a warning dialog naming it, from either menu and from File > Play RZX Recording…; the log says what was wrong with it. A file whose extension JNEXT does not know and that is not a NEX file is refused in the same way, before anything is reset, so the game you were playing is still there.
File > Recent Files lists the last ten programs and tapes you loaded from
the File and Tape menus, newest first, numbered 1 to 9 and 0; hovering an entry
shows its full path. Choosing one loads it exactly as File > Load NEX File…
does. A file that has been deleted since is dropped from the list and the status
bar says so. A program started with --load is recorded once it has loaded; a
load that failed, and Quick Load, are not. Like Load NEX File…, an entry cold-boots the machine, so a
.tap or .tzx entry boots and auto-loads rather than just inserting the tape.
File > Reload Last File (Alt+L) loads the newest entry again in one keystroke, handy
when you rebuild a program and want to run it again. Clear Recent Files empties the list. The list is kept between runs in
~/.jnext/jnext.conf ([recent] files), and Load NEX File… and Open Tape
File… open with the file you loaded last selected when it is still in the
folder they open in.
Programs in ZIP archives¶
A program downloaded as game.tap.zip or game.nex.zip loads without
unzipping it, from the command line (jnext game.tap.zip) and from File >
Load NEX File…. JNEXT loads the one program inside the archive (a file with
one of the extensions above) exactly as if you had given it on its own, and
ignores the screenshots, .scr files and text files that usually travel with
it. A name ending in .zip is always taken as an archive; a file with any other
extension, or none, is taken as one when it starts like a ZIP file.
- Several programs (side A and side B of a tape, say): the command line refuses and lists them, so you can unzip it and name the one you want; the window asks which one to load, and Cancel leaves the running game alone.
- Refused, with the reason: an archive with no program in it, one that is
not a ZIP file, a password-protected one, one compressed with a method other
than the usual deflate (bzip2, LZMA and the like), a ZIP64 or multi-disk one,
an archive file or a member over 256 MiB, and a member whose name is an absolute path or climbs
out with
... - A bundled
.pok(a cheat list for the game; see 5.11 POK trainers): when the archive holds one named like the program, or the only one, File > Load NEX File… makes it the open trainer list without showing it, and says so in the status bar. Open it with Machine ▸ POK Trainers….
The program is unpacked to a temporary file in JNEXT's configuration directory
(~/.jnext/archive-load/) that is deleted when JNEXT exits; leftovers of a
crashed run are swept after a week.
A program loaded either way brings its debugging files with it when they sit
beside it: game.sld (an sjasmplus source map) and, for a .nex,
game.Memory.txt (NextBuild / Boriel ZX Basic symbols). See
Loading a source map.

The toolbar buttons are, from the left: Power Reset, Soft Reset, Pause, Load, Screenshot, NMI (the Multiface button) and, on its own, Debug. Hovering a button shows its name. The icons are drawn in the window's text colour, so they follow a light or a dark desktop theme, including a switch made while JNEXT is running.
Light and dark. JNEXT's windows, the debugger included, follow your
desktop's light or dark setting, and change with it while running. On Linux
that is the setting your desktop publishes to applications (GNOME's Dark
style, KDE's colour scheme); on Windows and macOS it is the system
appearance. The legacy Windows packages (Windows 7 and 8) stay light. To force
one regardless (not in the legacy packages), start JNEXT with JNEXT_COLOR_SCHEME=dark or
JNEXT_COLOR_SCHEME=light in its environment.
The status bar along the bottom tracks the session: frame rate, the emulated CPU clock, the emulator speed, tape state, and the current machine.
Pausing. To freeze the machine where it is, press the Pause button on the toolbar, choose Machine > Pause, press the Pause key, or press Alt+U (⌘U on a Mac, whose keyboards mostly have no Pause key); press it again to carry on. The button stays pressed, its icon turns into a play triangle, and a Paused cell appears in the status bar while the machine is stopped. Sound goes quiet without a click, and the debugger window does not open. The Pause key and Alt+U (⌘U) also work in fullscreen, where the menu and toolbar are hidden. If you open the debugger while paused it shows the same pause, and closing it resumes the machine, as it always does.
Everything else in this chapter is about shaping that session.
Programs that need NextZXOS¶
Loading a file directly (with --load, a bare file name, or File > Load NEX
File…) skips NextZXOS's loader: nothing navigates a menu, and NextZXOS is
not the thing that starts your program. (The machine underneath it is still one
NextZXOS booted, for a NEX file — see the section below.)
That is all most games and demos need. On a real Next, though, every
NEX program is started by NextZXOS, and some programs also use it while they
run: to ask which drive they are on, to save a high score, or to read their
levels, music or settings from files next to them.
For a NEX file loaded directly, JNEXT stands in for the NextZXOS services such programs most often ask for:
- the current drive, which is always
C:; - one small file kept in memory, so a high score or a settings file can be saved and read back during the session (it is not written to disk, and it is gone when JNEXT closes);
runof another NEX file in the same folder, for programs that come in several parts.
Everything else is refused with an error. In practice:
- A program that only checks its drive or saves a high score runs normally.
- A program that needs data files from disk (levels, music, a configuration
file) stops with its own error message, or runs with parts missing. NXtel,
for example, says it cannot read
NXTEL.CFG.
There are two ways round that. The first is
--esxdos-stub-root, which hands a
directly loaded program a real directory on your computer to read its files
from — the quickest route while you are developing one. The second is to do
what a real Next does: boot NextZXOS from the SD card image and start the
program from the Browser, with its files next to it on the card. Many
programs, games included, are already on the image JNEXT uses by default. To
add your own, copy them in with JNEXT itself:
jnext --sdcard-file-add game.nex --sdcard-file-dest /DEMOS/game.nex
jnext --sdcard-file-add mygames
The first copies one host file to /DEMOS/game.nex; the second copies the
whole mygames directory, everything in it included, to /mygames. Either
way JNEXT copies and exits without starting the machine. --sdcard-file-dest
is optional: without it the file or directory goes into the root of the card
under its own name, and with --sdcard-file-dest / a directory's contents go
straight into the root. Missing directories on the way are created, existing
ones are merged into, and a file that is already there is refused unless you
add --sdcard-file-force. A copy that cannot be completed is refused or undone
as a whole, never left half-done; the jnext(1) man page, under PUTTING A
FILE ON THE CARD, lists exactly what is refused and why.
(A NEX file whose header asks to keep its own file open can also read that file, and read files next to it, when loaded directly. It cannot write them.)
The machine a NEX file starts on¶
Loading a NEX file directly still starts it on a Next that the firmware made. There is no option for this and nothing to turn on:
jnext game.nex
The first time you load a NEX file with a given SD card image, JNEXT cold-boots
that image the way it does with no arguments — the FPGA boot ROM, then
TBBLUE.FW, then NextZXOS — and saves the resulting machine under
~/.jnext/warm-start/. That takes about three and a half seconds, and JNEXT
prints a line saying it is doing it and another when it is done. Every load
after that restores the saved machine instead of booting.
What your program gets is a Next with NextZXOS resident and its ROM paged in — the environment a NEX file is written for, because on real hardware every NEX file is launched by NextZXOS. The alternative, which is what JNEXT did before version 1.0.11, is a machine JNEXT assembles: its settings are JNEXT's idea of what the firmware would have left rather than what it actually left, and some of them are states real hardware never reaches.
This does not replace booting NextZXOS from the card. The program still starts directly, so the section above still applies: files next to it on your computer are not visible to it. What changes is the machine underneath.
When it cannot be done¶
JNEXT never falls back quietly. If it cannot record or restore the machine it prints an error naming the reason and starts the program on the assembled machine instead. The reasons are:
- no SD card image is mounted, so there is no firmware to boot;
- the card has no firmware on it, or the boot does not end with NextZXOS resident;
- the saved machine will not load back, or is not NextZXOS-resident once it has been through a file.
The 48K, 128K and +3 are not one of those cases: they run no firmware at all, so there is nothing to record and nothing is reported. The same goes for tapes and snapshots, which are loaded by mechanisms a NextZXOS-resident machine does not have — a snapshot replaces the whole machine, and a tape is read through a 48K ROM routine that is not paged in. Those load exactly as they always have.
Where it is kept, and refreshing it¶
The saved machine is recorded from your image, on your computer, and is never shipped with JNEXT: it contains NextZXOS's own ROM, and JNEXT does not redistribute firmware — which is also why it downloads the SD card image rather than including one.
It is one file per machine type, a little over 100 KB, keyed by the size and
modification time of the SD card image, the machine type and the save format.
Change any of those — replace the image, switch machine, install a JNEXT update
that changes the format — or let JNEXT itself write to the card, and it
re-records itself on the next load. The card's contents are not read, so
loading stays fast on any card size. The one case this cannot see: an image
replaced or edited outside JNEXT that ends up with the same size and the same
modification time (for example cp -p, or touch -r) is served the old
recording. Use --warm-start-regenerate when in doubt.
If you update TBBLUE.FW or NextZXOS on the card in a way you want re-recorded
straight away, --warm-start-regenerate forces it:
jnext --warm-start-regenerate game.nex