FORTH on the PicoCalc

I’d have to see your code to say. Note that zeptoforth is designed to make it difficult for more than one task to write to the framebuffer at a time, as multiple tasks accessing it concurrently is liable to result in undefined behavior.

For this reason picocalc-term::with-term-display acquires a lock for the duration of what it calls. While you could get around this by saving the address of the display it passes somewhere and then accessing that after it returns, that is very liable to act in an undesirable fashion.

Edit: If you mean one of the tasks is generating lines twice as fast as the other, that is not surprising, as the task that runs on the same core as the PicoCalc terminal emulator tasks will run more slowly than the task that is not sharing a core with them.

The issue is what you mentioned, one of the tasks generates faster, namely exactly twice as fast. So the reason is that it runs terminal emulator.

(as of writing to the framebuffer: since one of the tasks generates the even lines, and the other generates the odd ones, they will never try to write to the same location at a time.)

Isn’t it possible to turn it off while generating?

What I have considered is separating out the core task for the terminal emulator into two tasks which each wait on different things, so when they aren’t doing anything they can just not execute at all (whereas currently it checks each thing in sequence and then gives up control of the CPU in a loop). This would probably avoid the issue you’re seeing (even though there would still be a bit of CPU usage from the BIOS-polling task, which runs far less frequently because most of the time it is time-delayed).

BTW, the biggest problem with multiple tasks writing to the framebuffer at the same time is the use of ‘dirty rectangles’ to keep track of what portions of the framebuffer have been written to, as the logic for maintaining them assumes that one task is accessing the display object at a time (and having multiple tasks drawing at a time is liable to corrupt the dirty rectangle).

Note that the role of dirty rectangles are to minimize the portions of the display that are actually transmitted to the display hardware; pixels outside the display rectangle simply are not transmitted when update-display is called.

Also note that update-display in particular cannot be called more than once simultaneously for a given display, as it relies on a specific hardware resource, in this case an SPI peripheral, that can only be used for one thing at a time to operate.

Of course, you could have multiple tasks write to a framebuffer at a time if they do so with low level writes to the framebuffer memory directly rather than through the <pixmap8> API, and then manually set the whole display to be dirty and call update-display when everything is all done from within a single task.

And is this a plan, or just a old idea? :slight_smile:

Another, bit more memory - intensive solution is to draw into two different bitmap buffers, then combine the result into one, then to a pixmap8.

It’s something I have considered doing but have not gotten around to. While I have been distracted by working on zeptoforth-V (for those not aware here, it’s a port of zeptoforth to RISC-V that is in the works), I could circle back and implement splitting the main terminal emulator task into two.

Waiting for it eagerly :slight_smile:

The code is in the master and devel branches and has been given a cursory testing; there appears to now be less overhead as there are now separate terminal emulator input, output, and screenshot tasks which block rather than poll. However, as separate tasks are used there is more memory overhead (which may be significant when using the graphical terminal emulator on the RP2040).

Also, erroneous escape-code sequences for some function keys have been fixed.

Note, however, that there is no new release including this code as of yet (I don’t have the time to put out a new release tonight).

I’ll put out a new release shortly including the updated terminal emulator, but unless bugs are found and fixed between now and then the code will be identical to what is currently in the master branch, so I would highly recommend rebuilding the code now rather than waiting for the release.

I did find that when I built zeptoforth for the PicoCalc such that the terminal emulator would run on core 0 running my graphical “Matrix” demo (on core 0 as well) was noticeably faster than when I had run it previously with the terminal emulator running on core 0.

I will, but I can only try it tomorrow. Thank you :slight_smile:

zeptoforth 1.15.2 is out!

You can get this release from:

This release:

  • breaks the core PicoCalc terminal emulator task, which polled for IO, into three tasks, one for input, one for output, and one for screenshots, which all block, resulting in lower CPU usage at the expense of somewhat higher SRAM usage.
  • fixes the escape key combos generated by some of the function keys in the PicoCalc terminal emulator.
1 Like

Thanks for another version of your wonderful work Travis! :smiley:

1 Like

Hi, Just got my PicoCalc yesterday and I’ve yet to assemble it. Do you have an absolute beginners guide on how to install and use ZeptoForth for the first time? I’ve never used either the PicoCalc or FORTH of ANY kind. I’ll be using the supplied Pico RP2040 to start with. However, I will be buying a Pimoroni Pico Plus 2W when they are back in stock. Thanks.

There is a detailed description in github.

To cut the long story short:

1, you need a Linux PC or a Windows PC with WSL (Windows Subsystem for Linux)

1, Download latest zeptoforth.

2, unpack it under Linux : tar xzf

3, install kernel: in the bin directory from the unpacked zeptoforth, install the “kernel” version uf2 file of the appropriate cpu (2040 or 2350 depending on what cpu you have.) It is highly recommended to use Pico 2 for ZeptoForth.

3, unplug the pico from the pc, and connect the USB C port of PicoCalc to PC.

4, run the utils/build_picocalc.sh script with the necessary parameters.

If you use WSL, then you will have to attach the USB C port to Linux using usbipd under Windows. This might require some googling. It is something like

usbpid attach -w -b 2-1

(2-1 might be something else, use usbpid list to check it.)

1 Like

A Mac or xBSD should also work. Also, if you are on Windows and for some reason do not want to use WSL2 there are manual instructions using zeptocom.js in zeptoforth/USING_THE_PICOCALC.md at master · tabemann/zeptoforth · GitHub , which you should read in detail one way or another.

1 Like

One important note – if you will be using the Pico H which came with your PicoCalc, I would specifically recommend using the text-only PicoCalc terminal emulator unless you particularly want to run graphical demos because not much RAM is left over on the RP2040 after the graphical terminal emulator’s framebuffer is factored in. For instance, if you want to use the text editor zeptoed on the Pico H with the graphical terminal emulator you have to explicitly reduce its RAM usage or else it will crash the system.

Also, as you say you are new to Forth I would highly recommend reading Starting Forth (which is available online at Starting FORTH - FORTH, Inc) as well as reading the wiki and the docs and looking over the test programs.

An additional note: if you are using the RP2040 you will generally want to use the rp2040_big platform so enough room will be allocated in flash to install everything you want (e.g. if you select the rp2040 platform the build script will not install zeptoed, which you want, as there simply will not be enough room in the flash dictionary for it).

I am just writing a post to check whether @tabemann after my post is allowed to write again after being blocked following three posts in a row.

i believe this limitation doesn’t apply to threads you started yourself, fwiw

(and i just checked that he didn’t start this thread, so whoops)