Published using Google Docs
ESP32Forth.Tachyon
Updated automatically every 5 minutes

TachyonESP
ESP32Forth à la Tachyon

Console and kernel enhancements for RISC-V development

 This version is only for the C3 RISCV  chip version !

by Peter Jakacki  - September 2024    (link repaired Feb 2026)        

 Tachyon Forth Model  *TachyonESP files* 

Introduction
I have used Forth since very early in my career as a hardware/software embedded systems designer. In the last few years though I have seen the proliferation of RISC-V MCUs in all shapes and sizes, so now I want to write Forth to suit this ISA. But where to start? Perhaps the ESP32-C3 is a good start because it is a very capable MCU that is readily available that also has lots of RAM, and a Forth already available. This is important because it will allow me to develop the tools I need to hand-craft a custom machine level Forth in the style of Tachyon that I used on the P1 and P2 Propeller chips.

TachyonRV will be a "hard-core" Forth, written in assembly and extracting every ounce of RISC-V goodness that can be had so that it can run on an ESP32, or a tiny 10 cent CH32V003. The aim is to have an industrial grade Forth that can be used in commercial products just as I have done with the Propeller and other chips before them.

However, this document is mainly concerned with the enhancements and changes made to ESP32Forth to accommodate hosting the Tachyon development environment.

My Linux workspace window 


FEATURES

CONSOLE
Enhanced Console supports ANSI terminal emulators
Fast Serial Batch load - echo suppressed, print line number and errors etc
History buffer uses ANSI navigation keys and allows editing ins/del etc.
ANSI support detect at boot - also sets line-width according to terminal width-10

ANSI colors

System prompts in
dark blue
User input in
bold yellow
Errors in
bold red
Colored words list highlights colon defs, immediate, constants, variables, etc
Compact stack depth prompt
Press Enter will stay on same line with a clear --- separator between user inputs and response


STACK 

Stack retention holds current values even after an error. (underflow will reset stack)
Stack print shows hex, ASCII, and decimal values in visual top to bottom stack format

AUX STACK
Simple fixed stack to complement data stack
Supports locals A B C D
PUSHA POPA pushes and pops multiple values

A@+ Fetches the long pointed to by A and increments A by 4

LOOP STACK
DO LOOP words are simple fast non-immediate runtime words and does not use the return stack
DO pushes index and limit and IP instruction pointer onto a loop stack
LOOP performs a fast increment and compare on the loop stack (as fast as FOR NEXT)
LOOP reads the stacked IP to loop (no compile-time branch needed)
Note: Only partially implemented as DO: and LOOP: at present for testing.

MEASURE
LAP timing saves previous LAP and latches current millisecond tick
.LAP calculates and reports the difference between the lap times.

NUMBER INPUT/OUTPUT
Accept % for binary
Allow passive grouping symbols such as , and _
Dedicated hex print words .L .W .B for long/word/byte

CONTROL & ANSI KEYS
Control key shortcuts - Print Stack, Clear Stack, list words, System Report, Reset, <user controls>

<ESC>        clear current entry
^C                Cancel and reset (bye)
^Q                Query stack
^S                Stack reset
^X                Re-eXecute previous entry (recall + enter)
^W                Words list
^L                Clear screen and stack, and print boot report
^?                Boot report


ANSI CSI navigation keys for editing current line or recalling previous line up to 8 levels deep (default)

UP                recall previous entry
DN                recall next entry
LEFT                navigate into current entry (non-destructive)
RIGHT        “   “
HOME        Navigate to start of current line
END                Navigate to end of current line
INS                Toggle insert/overwrite mode
DEL                Delete current entry from history




DUMP MODES

DUMP hex bytes + ASCII (16/line)
DUMPW hex words (16-bits)
DUMPL hex longs (32-bits)
DUMPA ASCII characters (64/line)
DUMPB memory blocks as a byte/block

DATA SPACE
Forth has a very primitive variable that is always one cell wide. Often the word “allot” has to be used to increase or decrease it in a rather kludgy manner. It seems to make more sense to specify the type and size of that variable as: byte bytes long longs

To allow these variables to exist in a contiguous manner rather than crammed in between Forth code, an area of 4KB is set aside and the variables are actually constants formed from the data origin pointer. The user is free to choose another area using the “org” word much as is done in assembly.
org ( addr -- )
byte bytes long longs



ALIASES
Many simple Forth symbols that are functions have been given an alias that are easier to see and read. Symbols such as dot has a PRINT alias for instance. Likewise, many operator symbols in Forth are words rather than common symbols. If Forth were consistent it would say ADD and SUBTRACT rather than + and -. But symbols are what we are familiar with for math and logic operations.

Forth

Tachyon

.

PRINT

.”

PRINT”

AND

&

OR

|

XOR

^

LSHIFT

<<

RSHIFT

>>

constant

:=


word

stack

|<

( b -- m )

Convert bit number to bit mask

>|

( m -- b )

Convert msb of bit mask to bit

++

( a -- )

Increment long

--

( a -- )

Decrement long

~

( a -- )

Clear long

~~

( a -- )

Set long




README for ESP32Forth Enhancements

Trying to keep my readme file updated for the changes I am making to ESP32Forth which also includes EXTEND.FTH.

+------------------------------+

| ESP32forth -Tachyon |

+------------------------------+

This is ESP32forth v7.0.7.15 which is being modified to be more like Tachyon Forth so

that I can port whatever tools I need to develop Tachyon Forth for RISC-V.

* USE Espressif ESP32 V2 board manager libs *

This is being tested on an ESP32-C3 XIAO module using the older V2.0.17 Espressif ESP32 board manager libraries in Arduino 2.3.2

Note: Espressif V3 libs do not work

* Editing and compiling *

I am editing the files in VS Code and running a terminal in minicom in a separate window, although you can use the Arduino 2 IDE edit and terminal of course.

When I make a change I disengage the minicom terminal with a ^A P which brings up the coms parameter window and this permits the coms port to be used by the Arduino uploader.

Then I toggle to the Arduino window and hit ^U to compile and upload.

Once it is done I go back to the minicom window and hit escape to cancel the coms parameter window, and not the terminal is ready to use.

I set minicom to 921600 baud with zero delays and there is an EXTEND.FTH file that I am also using at present.

--------------------------------------------------------------------

NEW:

--------------------------------------------------------------------

DEBUG

* Formatted dumps such as

DUMP hex plus ASCII

DUMPW eight 16-bit words/line

DUMPL eight 32-bit longs/line

DUMPA 64 ASCII characters/line

DUMPB ( addr cnt blksiz -- ) - dump memory as a byte/block where the byte is an average

.L Print as 8 digit hex

.B print byte as 2 digit hex

.L_ print as 8 digit hex 6C00_1400

.h ( n cnt -- ) Print hex digits

LAP - capture ms-ticks into lap latch (save old lap)

.LAP - Print the timing difference between last and previous LAP

CWORDS - list words in color

plain = colon defs

red = immediate

green = constants/values

yellow = variables

magenta =

blue = unknown

.WORDS - detail one/line list of words with address etc

NUMBERS

* Add % as binary number prefix

* Allow , and _ within numbers (useful digit group separator) 1,234,567 $6000_C240 etc

* Stack freeze on errors - it won't reset the stack just because you made a mistake

* .S now prints each item on a new line from top to bottom as hex, ascii, and decimal

CONSOLE

* prompt - only displays fixed size stack depth, base symbol, and arrow. - revector via _prompt

* ANSI colors used to distinguish prompts, user, response, and errors.

* Control keys - now you can use control keys for shortcuts and even add your own at runtime

^Q Query Stack

^S Stack init

^W WORDS list

See ^ctrl in EXTEND for more options

Unused control keys are discarded (no errors)

Use your own custom ctrl keys - default is ' ^ctrls is ?ctrls

( NOTE: moving this to EXTEND for easy edits )

BATCH LOAD

ESP32 - The keyword ESP32 will place the console into non-echo mode only reflecting line numbers and errors.

- this also ensures that this source file is designed for the ESP32

*END* - ends batch mode and reports download stats.

STRUCTURES

* DO: LOOP: is a very fast do loop with its own loop stack - as fast as for next

DO: push index and limit and current IP onto loop stack

LOOP: increment index and loop with saved IP if <> limit - else unloop

I: loop stack index

AUX STACK

@A ( -- a ) - address of A in A stack

A! ( n -- ) - store n in A (top of A stack)

A ( -- n ) - top of A stack value

>A ( n -- ) - Push n onto A stack

A> ( -- n ) - Pop A stack

PUSHA ( <n> cnt -- ) - push cnt values onto the A stack

POPA ( cnt -- <n> ) - Pop cnt values from the A stack

A@+ ( -- n ) Read long from pointer in A and increment A by 4

AW@+ ( -- n ) Read 16-bit word from pointer in A and increment A by 2

B ( -- n ) - Read B = second A stack item

OPERATORS:

~ ( addr -- ) - clear the cell to zeros

~~ ( addr -- ) - set the cell to ones (-1)

++ ( addr -- ) - increment variable

-- ( addr -- ) - decrement variable

>< ( n min max -- f ) - within inclusive

MASK ( bit -- mask )

[^] - to compile the control key value of an ascii character

FUNCTIONS:

LOOKDOWN ( ch str cnt -- index+1|0 )

LOOKUP ( index str cnt -- byte )

CSIKEY ( -- keycode ) - return with ascii or compressed CSI code

HIGH ( pin -- ) - make the pin an output and set high

LOW ( pin -- ) - make the pin an output and set low

INP ( pin -- ) - make the pin an input

ON ( -- 1 )

OFF ( -- 0 )

KERNEL MODS:

Reassign HIGH and LOW as functions ( simpler and faster )

Added ON and OFF as true and false values ( very general constants )

--------------------------------------------------------------------

CHANGES:

--------------------------------------------------------------------

renamed prompt to eol because it is an end of line action

made eol and prompt revectorable within code for batch loader

renamed ?arrow. to prompt because that is what it is - also _prompt is the variable

added --- separator on the same line when the return is pressed

added stack underflow and reset check (the only time I want it to reset on an error)

add in ANSI colors and apply to console prompts etc and words list

--------------------------------------------------------------------

TO DO:

--------------------------------------------------------------------

Make ?ctrls into a user table of vectors - perhaps in EXTEND

Add escape to cancel the current accept line

Add history buffer to tib - use ^R to recall (or arrow up if CSI keys added)

Check system timer operation

Have fun!

Peter Jakacki

--------------------------------------------------------------------

NOTES:

--------------------------------------------------------------------

Linux users may use the send script from the VSCode terminal

while the minicom terminal window is still active (no need to close etc)

If your ESP32 creates an ACM0 port for instance:

./send EXTEND ACM0 3

where send is

ascii-xfr -s -n -l $3 $1.FTH > /dev/tty$2

minicom color:

Here is a script which I name as tty to easily open a minicom terminal with color etc

minicom --color=on -w -b 921600 -D /dev/tty$1

usage: ./tty ACM0