Zeptoforth on the PicoCalc

There is a longstanding FORTH on the PicoCalc thread, but I have decided to create a new thread because I wanted to post something about new developments on the zeptoforth front but I would use up my three-posts-in-a-row as I did not originally create the FORTH on the PicoCalc thread myself.

For those not aware, zeptoforth is a batteries-included Forth implementation for ARM Cortex-M microcontrollers, including the RP2040 and RP2350 in the Raspberry Pi Pico-family boards.

Forth is a dynamic-and-interactive-but-very-low-level language that exposes a REPL to the user while simultaneously allowing the user direct access to the underlying hardware which avoids the code-compile-flash-run-debug loop typical of many languages in the embedded world (with the exception of high-level languages such as MMBasic/PicoMite and MicroPython). Forth is really for those comfortable with doing arithmetic on addresses in memory and manually managing their own memory; if these things give you pause, Forth should give you pause.

zeptoforth specifically supports more advanced features as Forths go, including preemptive multitasking (including multicore on the RP2040 and RP2350), a user-friendly module system on top of traditional Forth wordlists, an object system, and local variables (which are not something all Forths have, it should be noted; many people consider these to be ‘un-Forthy’ but I find these to be very practical).

zeptoforth in particular provides extensive support for the PicoCalc, including both graphical and, for those constrained memory-wise (e.g. using an RP2040) who consequently do not want to have a framebuffer, text-only terminal emulators, which expose ANSI-compatible terminals to the user and, in the case of the graphical terminal emulator, allow arbitrary RGB332 graphics to be drawn to the display via a framebuffer, FAT32 support (note: long file names are not currently supported) on the SD card and also in on-board flash and (if you have a Pimoroni Pico Plus 2 (W) in your PicoCalc) in PSRAM (as a RAM disk), basic sound support (currently just fixed mono tones, sorry), a multi-buffer screen text editor (named ‘zeptoed’), and (if you have a Pico 2 W or Pimoroni Pico Plus 2 W in your PicoCalc) optional WiFi with either IPv4 or IPv6 support (with the IP stack itself named ‘zeptoIP’).

Note that when installing zeptoforth on your PicoCalc you need to use specifically the kernel UF2 files (the rp2040_big platform is highly recommended if you are using the RP2040, the rp2350 platform is RP2350 boards with 4 MiB of flash such as the Raspberry Pi Pico 2 (W), and the rp2350_16mib platform is for RP2350 boards with 16 MiB of flash such as the Pimoroni Pico Plus 2 (W)) and then build the remainder of zeptoforth on top of it per the directions in USING_THE_PICOCALC.md because there are too many possible configuration combinations to make it practical to distribute pre-built UF2 files for all of these. Note that the arm-none-eabi toolchain is needed only if you plan on rebuilding the kernel itself; you will most likely not need to do this. (Running make specifically and only builds the kernel, it should be noted.)

I will not distribute UF2 files including CYW43439 firmware for the Raspberry Pi Pico {1,2} W and Pimoroni Pico Plus 2 W because to my knowledge this firmware is not truly free. I do distribute the firmware itself in a separate repo for the sake of convenience.

Currently uf2loader is not supported, but support for uf2loader is in the works (the main blocker is that currently only an experimental version of uf2loader supports UF2 files with ‘holes’ in them like those used by zeptoforth).

The zeptoforth GitHub can be found at:

For starters, I will paste a link to my latest release post here:

More content is to follow.

2 Likes

As for the latest developments, I have ported the famous puff.c DEFLATE algorithm implementation from zlib to zeptoforth as zeptoforth/test/common/puff.fs at master · tabemann/zeptoforth · GitHub and implemented a gzip decompressor and validator along as zeptoforth/test/common/gunzip.fs at master · tabemann/zeptoforth · GitHub. These need to be loaded in that order, and require zeptoforth/extra/common/crc32.fs at master · tabemann/zeptoforth · GitHub to be loaded ahead of time, but if you are using zeptoforth on a PicoCalc this will likely already be loaded.

Note that this is not a practical gzip decompressor, mind you, as it currently requires both the compressed and the uncompressed data to both fit in SRAM simultaneously, mind you.

Currently uf2loader is not supported, but support for uf2loader is in the works (the main blocker is that currently only an experimental version of uf2loader supports UF2 files with ‘holes’ in them like those used by zeptoforth).

I’ve just accepted cathiele’s changes for this to the main uf2loader repo. I’ve not made an official 2.5 release yet - there’s no good reason to upgrade to it yet except for those people who want to play with zeptoforth and can send me bug reports. But if you fall in that category please give it a go!

Thanks! I’ll be awaiting an official release containing @cathiele’s changes. In the meantime I will look into merging @cathiele’s changes into zeptoforth.

zeptoforth 1.16.2 is out!

You can get this release from:

This release:

  • fixes a bug in schan::schan-full? that made it incorrectly report a full condition when an schannel contained only one message.
  • adds support for setting bus priorities on the RP2040 and RP2350 with the busctrl module.
  • adds support for obtaining the number of free blocks with block::free-block-count@.
  • adds a 6x12 font (note that as an oversight, the zeptoforth PicoCalc installer has not been updated to support this font).
  • adds support for ST7796S displays, including for PicoCalc emulation.
  • adds support for LCD1602 with PCF8574 interface, as opposed to AiP31068L.
3 Likes

This is not a new formal release (yet), but I have added the ability to read raw keypress info from the STM32 and I fixed the installers in the main branch to support the 6x12 font. These changes are now in the master branch.

Reading raw keypresses is enabled and disabled with:

picocalc-term::raw-keys-enabled! ( enabled – )

Note that changing this setting clears the key queue.

You can also get this setting with:

picocalc-term::raw-keys-enabled@ ( – enabled )

To get whether a raw key is available call:

picocalc-term::raw-key>? ( – available )

Note that this always returns false if raw keys are not available.

To get a raw key call:

picocalc-term::raw-key> ( – attribute key )

Note that this is a blocking call and will block until a raw key becomes available. If raw keys are not available this will block until they are enabled and the user presses or releases a key.

The key codes and attributes are the raw values sent by the STM32 firmware.

I have now added support for a keymap, a way of keeping track of the status of multiple keys at once without having to manually check individual raw keys.

This functionality is in extra/rp_common/picocalc_keys.fs, and has to be specifically compiled by the user.

Once loaded, this adds the following words:

picocalc-keys::clear-keymap ( – )

Clear the keymap so as if all keys were unpressed.

picocalc-keys::update-keymap ( – )

Update the keymap based on all the queued raw keys in a non-blocking fashion.

picocalc-keys::wait-update-keymap ( – )

Update the keymap based on all the queued raw keys in a blocking fashion (i.e. if no raw keys are queued, block until a raw key is queued).

picocalc-keys::keymap@ ( keycode – pressed )

Get whether a given key by keycode is pressed as of the last time picocalc-keys::update-keymap or picocalc-keys::wait-update-keymap was called.

Note that this relies on raw keys being enabled with picocalc-term::raw-keys-enabled!.

1 Like

I have added more functionality to the keymap, particularly the ability to specifically detect whether a key has been pressed or released in the past, and the ability to reset this state for all keys or an individual key.

To that effect I have added the following words:

picocalc-keys::reset-keymap ( – )

Reset the pressed and released states of all keys to false.

picocalc-keys::reset-key ( keycode – )

Reset the pressed and released state of a specific key to false.

picocalc-keys::keymap-pressed@ ( keycode – pressed )

Get whether a key by keycode has been pressed since the last time it was reset.

picocalc-keys::keymap-released@ ( keycode – released )

Get whether a key by keycode has been released since the last time it was reset..

1 Like

zeptoforth 1.16.3 is out!

You can get this release from:

This release:

  • adds support for ‘raw keys’ on the PicoCalc as a mechanism for directly exposing key press codes reported by the STM32 microcontroller.
  • adds a ‘keymap’ mechanism on top of ‘raw keys’ on the PicoCalc as a means of conveniently querying whether a given key has been pressed or released.
  • adds support for the 6x12 font to the PicoCalc installers.
1 Like

I just fixed some important bugs in master and devel in the screenshot tool, specifically that it previously took up a prohibitively large amount of return stack space, which had often resulted in crashes if one used it outside the context of a task such as the PicoCalc terminal emulator’s screenshot task with a specifically large amount of return stack space, and the screenshot tool for the text-only PicoCalc terminal emulator was previously broken for fonts other than 5x8, 6x8, and 7x8, which I discovered today when I tried to use it with the 5x8_v2 font.

These will get into a future release, but for the time being I recommend cloning the repo and using that for installing zeptoforth for the PicoCalc.

zeptoforth 1.16.3.1 is out!

It has only been a day, but there is already a new bug-fix release for zeptoforth.

You can get this release from:

This release:

  • fixes return stack usage issues with the PicoCalc screenshot tools, which were causing crashes when run in tasks other than the PicoCalc terminal emulator screenshot task due to return stack exhaustion.
  • fixes an issue with the text-only PicoCalc screenshot tool where it would crash when the font was other than 5x8, 6x8, or 7x8.
  • adds a new version of the ‘Bricks’ (a Breakout clone) game that uses the new ‘keymap’ mechanism.

Note that this release uses the same kernels as release 1.16.3, so the reported version is still 1.16.3.