Skip to content

25.Editing_Code

Rob Probin edited this page Apr 6, 2026 · 12 revisions

Editing Forth code on the Sinclair ZX Spectrum Next

You have three options:

  1. Edit code using blocks/screens, e.g. using edit
  2. Edit code using files, e.g. using LED
  3. Edit code using PC then use it with vForth on a Spectrum Next
  4. What about with an emulator?

You don't need to select one method - you can mix and match.

Notice, that although the third option is sometimes nice, you lose a lot of the interactive development that you would by using the first two methods. That's not to say you can't do it sometimes!

The rest of this document will give some guidance of the three approaches, along with examples.

You can also review the vForth Core PDF manual. This has sections on editing code.

1. Blocks / Screens

This is a mechanism to allow you to enter code, edit it and reload. They work well in vForth.

Screen is 1 KByte so it can store text in 16 lines and 64 columns in that fixed format. All blocks/screens are stored in the file called !Blooks-64.bin.

Detail on how to use these are covered elsewhere:

Please see these locations for much more detail - but I'd seriously suggest trying them since they are fast, easy and good for quick prototypes.

2. Editing with Files

The LED editor is similar to 'Edit', the screen/block editor, but operates on files of up to 17568 lines long and 85 characters.

Since the LED editor is based on the screen/block editor, it shares many of the commands and look-and-feel. This is can be advantage because you can switch between editing blocks and editing files using the same system. This editor is covered in more detail in section 3.3 of the vForth PDF manual.

You also need to be aware that editing files presents some challenges on the Sinclair ZX Spectrum, and so you should be aware them:

  • The vForth LED editor is a work in progress, and has a few rough edges.
  • All file editing uses RAM - that is not the case with screens/blocks which have fixed reserved space.
  • Big files use a lot of RAM! Maybe make several more smaller files - and use need or include to load them.
  • Even if LED can load very large file, the loading itself takes great amount of time and paging down is a slow operation
    • better not to use LED if the file is greater than a few hundred rows.

Memory

To load a file the LED command uses 8K pages 48 to 223 to store the file. If you are using this memory for your application, then you need to be careful. (See section 3.3, 6.3 and 7 - vForth's heap uses 8Kpages #32-39 and #40-47 are reserved. Also see https://wiki.specnext.dev/Memory_map ).

A demonstration

After loading vForth, load the large file editor (LED) and dir support.

needs led
needs dir

Show the current directory enter: dir .

Depending on how you started it will probably affect the current directory. If you started with the basic launcher, you'll probably be in the vForth directory. The dot command might be in the present directory. To show the 'root' directory type:

dir \

This shows the list of directories at the top level of the SD card.

Creating a new file

Let's edit a new file at the top level of the SD card. First I want to create a empty file. LED doesn't create files, so we need to create one.

needs touch
touch \test1.f
dir \

During DIR printing, you can use [EDIT] to pause the output. DIR also understands [BREAK] which is 'stop immediately'.

Opening an existing file

led \test1.f

You can make some edits to this blank document. Specifically with an empty file you need to insert a few lines with [EDIT]-s to shift down.

Once you have finished type [EDIT]-Q to quit.

You need to save it:

led-save

You can also duplicate a file:

led-file \test2.f

You are now editing a copy that will be saved as test2.f.

led-save

Now you have a copy on SD card.

NOTE: Within LED you can use [EDIT]-W to write without needing to quit to Forth prompt.

Look at the file size:

dir \

If you want to view the file you've just created there is a utility called view:

needs view
view \test1.f
view \test2.f

Remove Files we don't want

You have to specify the drive "c:"

needs unlink
unlink c:\test2.f

Checking how much space we have

needs unused
unused .

Editor Commands Sumnmary

After the [Edit] key (Shift + 1 using standard PC keyboard) the Editor recognizes the following single or double key-stroke commands:

  • [Edit] + Q : Quit EDIT Utility
  • [Edit] + U : Undo, that is re-read current screen from disk ignoring any modification done since last FLUSH. This feature is quite important, since it does for a single Screen what EMPTY-BUFFERS does for all of them.
  • [Edit] + H : take (or Hold) current line content and keep it in PAD
  • [Edit] + R : Replace current line with the current PAD content.
  • [Edit] + S : make Space at current cursor position shifting lower lines down; last line will be lost.
  • [Edit] + D : Delete current line shifting up lowerline,but a copy is copied to PAD before deletion,like H.
  • [Edit] + I : Insert at current cursor line position the content of PAD: it does commands S and R.
  • [Edit] + N : go to Next screen
  • [Edit] + B : go Back to previous screen
  • [Edit] + P : accepts two hexadecimal digits representing a byte and Put it at cursor position. This way, non- printable characters, i.e. ASCII code between 0 and 31 ($00 - $1F), can be stored inside a Screen, but care must be paid to avoid corrupting the display because most of them are control characters and some of them are used. Characters with ASCII code between $80 and $FF can be stored in a Screen, but they are emitted to video translated to the corresponding codes between $00 and $7F.

Any other key has no meaning and returns the flashing cursor back to its position.

Other keys:

  • [Delete] (that is Caps-Shift + ZERO) removes a character at current cursor position, shifting left the rest of the line.
  • [Break] (that is Caps-Shift + SPACE) inserts a space at current cursor position, shifting right the rest of the line.
  • [Caps-Lock] (that is Caps-Shift + 2) accounts for a keystroke, but it is interpreted by the system to change the Caps-Lock state switching between enabled ( █ ) and disabled ( ▄ ).

3. Using a PC/Mac/Linux Box with the Spectrum Next

Sometimes it's nice to use fully featured editors on modern PCs.

That's ok. This section explains different approaches to doing that.

You can save your text files using DOS/Windows line endings (CR LF, 13 10), with Unix/Linux/MacOS line endings (LF, 10), or Spectrum/Classic Mac line endings (CR, 13). You can use any file extension you like (.txt, .f, .fth, .fs, ...) as long as they are plain text.

It's suggested you don't make you files too big - because loading times are long. In practice, we suggest you make your files much shorter than LED supports.

It's also important to limit the line length to 85 or less. Some editors have a margin ruler you can set at, say, 80 characters that will show you when you are writing lines that are too long.

Transfering back to the Spectrum Next

When you've completed your changes, normaly you'd copy them to the Spectrum Next and test the words them one by one.

Remember the advantage of Forth is piecemeal 'incremental' development and debugging - which is best done on the target machine.

Method 1: Copy to the SD Card

This is by far the simpliest option for transfering files. However, it's the slowest cycle time for development when debugging on a Spectrum Next. (Perhaps you want to edit on the Spectrum Next after you've copied your changes across?)

Usually, if you have a single SD card in your Spectrum Next, you would:

  • Invoke REMOUNT (from Forth or from BASIC), but leave your Spectrum Next waiting for keypress
  • Remove the SD card and put it in your PC
  • Copy the files over to a suitable directory on the SD card
  • Eject the SD card from your PC and put it back into the Spectrum Next
  • Hit Y key to complete the remount cycle.

It's not necessary to power down the Spectrum Next as long as you are not using the SD card at the time.

To remount from Forth:

needs REMOUNT
remount

Hit Y to complete the remount.

Loading the new code

There are two ways of loading a specific file:

  • needs <name> where is the name of your file without the .f at the end. NOTE: needs looks in the inc and then lib directories for file.
  • include <filepath-and-filename> where refer to a full-path filename with explicit extension.

NOTE: NEEDS lookups up whether it's loaded in the dictionary first - so you don't get duplicate defintions. If you are using needs then you will need to use forget or markers to make the dictionary forget.

Include will include it everytime - but you will get duplicate defintions, which is not a big problem but you might run out of memory since it does'nt erase the old versions.

Method 2: Transfer electronically

Theoretically it's possible to transfer the files via Wi-Fi or other methods.

Options:

There are also SD cards that can accept a remote connection - but reports are that these are hard to come by and they don't always work well. I would not suggest this option.

WARNINGS:

  • Only copy what you need
  • Don't copy giant files.
    • e.g. You should not copy the 16 Mbyte '!Blocks-64.bin' file.

sync

https://solhsa.com/specnext.html

Get Next Sync release. Currently this is v1.2. https://github.com/Threetwosevensixseven/specnext/releases/

Instructions are provided with Sync in the file nextsync.txt. You should install on your PC/Mac and Next in /dot/ directory as described in that text file.

  1. run python nextsync.py as explained in the text file.
  2. Run vForth from the BASIC loader (currently Forth17_load.bas)
  3. Type bye
  4. Press a key then type .sync on a new line from inside the basic program
  5. Type run to take you back to the Forth environment
  6. Now load your program, say with include dev\myfile.f`

When you want to reload you program, forget previous definitions (or use marker words) and then repeat from 3 to sync the changes from your machine.

zxnftp

See https://github.com/varmfskii/zxnext_tools - links to https://github.com/varmfskii/zxnftp

(Info to be added)

Serial - DeZog

This might be useful - but is not usually used with vForth development.

DeZog usage documentation has the basic guidance https://github.com/maziac/DeZog/blob/main/documentation/Usage.md

You can use this with either a real Spectrum Next or an emulator such as MAME, CSpect or ZEsarUX.

The details on hardware are here: https://github.com/maziac/DeZog/blob/main/documentation/Usage.md#zx-next--serial-interface

4. What about with an emulator?

Of course, you can use the options above - 1 (Blocks) and 2 (File Editor) - with an emulator but it tends to be less comfortable than using a native application where the keyboard symbols and shift keys are different.

You can also change the SD card and load the emulator each time. However this is very slow because although the emulators (including CSpect, ZEsarUX and MAME) boot quite quickly you need to get into vForth, load everything else before loading the code you just changed. This is the slowest option available to us.

Of course, you can use 'Method 1: Copy to the SD Card'. This is where we unattach the SD card image and re-mount - but we can actually improve on this with dynamic updates to the SD card as long as we are careful.

Changing a live SD card

First read the section titled 'Method 1: Copy to the SD Card' above.

The summary is:

  • Invoke REMOUNT as above, but leave your Spectrum Next waiting for keypress.
  • Use hdfmonkey to modify your image - for example copy the files over to a suitable directory on the SD card.
  • Hit Y key to complete the re-mount cycle.

NOTE: some emulators (ZEsarUX) keep caches of the MMC in memory - so you might need to flush that cache as well.

So you need to inject your file into the .mmc image. The standard tool for this is hdfmonkey.

hdfmonkey put your-sdcard.mmc yourfile.fth /yourdirectory/yourfile.fth

You can setup a script, batch file, make file, Python program or sync to automate the copying of changed files. (Theoretically you could do this bi-directionally if you were making changes on both sides).

Then you can trigger this script from your favourite development environment or editor - or just from the command line, or with a mouse click. For example you might setup your development environment to use Control-B to run a 'build' where it could run a script that copies the files to the target.

There's also a GUI wrapper called Py-Hdfm-Gooey if you prefer not to use the command line.

Example

This is using MAME

Before SD Card

./hdfm-0-5-7-1-jjjs/macos-mn/hdfmonkey put zxnext_uk_hosted_2gb_April2026/cspect-next-2gb.img test.txt /home/

./hdfm-0-5-7-1-jjjs/macos-mn/hdfmonkey ls zxnext_uk_hosted_2gb_April2026/cspect-next-2gb.img

    264	README.txt
    11	test.txt

After SD Card

Core HDFMonkey Commands

create <image> <size> <name>: Creates a new HDF image file.
put <image> <host_path> <hdf_path>: Copies files or directories from your computer into the HDF image.
get <image> <hdf_path> <host_path>: Extracts files or directories from the HDF image to your computer.
ls <image> <path>: Lists files within the HDF image.
mkdir <image> <path>: Creates a new directory inside the image.
rm <image> <path>: Removes a file from the image.
rmdir <image> <path>: Removes a directory from the image.
help: Displays command usage
putdir <image> <host_path> <hdf_path>: Copies files or directories from your computer into the HDF image.

Emulator Automation

Theoretically it's also possible to even automate the emulator to do the re-mount cycle and more complex things.

  • ZEsarUX has ZRCP (ZEsarUX Remote Control Protocol) — a telnet-based interface that lets you control almost everything in the emulator remotely.
  • MAME has input recording and playback, and the ability to use Lua Scripting to automate keypresses, read/write memory and hook into emulation events.
  • CSpect has a plugin API (C#) and a remote debugger interface, or you could use seperate GUI scripting to inject events.

ZRCP

For automation of a ZX Spectrum Next specifically, ZEsarUX with ZRCP is the most capable and straightforward option. It's particularly well suited to automated testing pipelines where you want to boot the machine, load a program, send inputs, and verify behaviour — all from a script.

ZRCP is a TCP-based API. It's disabled by default — enable it from Settings → Debug, or with --enable-remoteprotocol on the command line. The default port is 10000. On Windows it's only supported on the ZEsarUX-pthreads version.

Maybe mmc-reload (Reload the MMC image from disk) would be useful, along with send-keys <text> (Send text as keypresses). Potentially smartload <file> (Load a file directly) might be useful to get vForth running quickly on a start script.

Other methods

You might be tempted to map part of your computer filesystem into the emulator space using the the ESXDOS handler.

ESXDOS is the operating system/firmware that runs on top of the DivMMC hardware. The MMC emulation provides the low-level hardware layer - whereas the ESXDOS provides the FAT filesystem. Technically, NextZXOS implements the esxDOS Application Programming Interface (API) so programs will work anyway - you don't actually need to be running ESXDOS - and aren't normally running it on the Spectrum Next.

ZEsarUX also offers a shortcut called the ESXDOS Handler, which bypasses the MMC hardware emulation entirely. If you enable the ESXDOS handler, file access will use files from your hard drive directly. You can have ESXDOS enabled alongside DivMMC/MMC settings, or just the ESXDOS handler alone. If you enable both DivMMC, MMC, and the ESXDOS handler together, file access will use your files from your hard drive.

However, as the ZEsarUX FAQ says it is not recommended to enable both divmmc and esxdos handler on ZX Spectrum Next, as many system calls may fail.

Enabling just the ESXDOS handler would require a full NextZXOS image and vForth - and this configuration has not been tested - and probably will cause problems on the Spectrum Next.

References

Why Editing and Testing Quickly Important?

We want to test Forth as we write it, and the cycle time between writing code and testing that code is very important.

We are aiming for a method that allows us to create or change small pieces of Forth code and test them very quickly. This is called stepwise refinement or incremental development - and is a method to get things working very quickly, allow you to learn about what works, and ensure you test as you go.

It's especially good when you don't precisely know the problem you are trying to solve - which is often the case with interactive applications like games that are hard to fully specify ahead of time.

Clone this wiki locally