It adds a bunch of convenience features over and above what e4thcon provides...
persistent history
fast download
filename completion on \i (and \d)
paste code from the clipboard
It is written specifically for quintus, but should work with any mecrisp forth.
The fast download (\d filename) is accomplished at the expense of a
large RAM buffer, and the forth code is included in the repo.
Basically it streams the file into the RAM buffer then evaluates that
buffer. I found this will download at the full baudrate (I use 3000000
baud!). The problem with waiting for each line is that the USB/CDC
turnaround time is very slow, and increasing the baudrate does not
actually help the download time.I found that this method downloads as
fast as (if not faster) than swdcom (which I love but doesn't work for
rp2350 or rp2050/pico).
\i filename will do the usual ping pong waiting for ok.
Feedback welcome as I have not tested on platforms other than linux on
x64 and arm64. Binaries for mac and windoze are included (but
untested) courtesy of go.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It seems it works in win11, it has uploaded a large file fine.. I wonder what is the line delay hardcoded in there (if any)?
PS: with "words" I got the "line too long"
Yea that is the only command that gives that error. There is a line length limit of 1024 characters, I modified my copy of list to break up the lines to that length. words4 works though.
Thanks for testing on windows!
There is no line delay for \d it just streams as fast as it can. \i also has no line delay it just waits for ok. or an error.
The reason I did the \d was that there IS a delay in the USB drivers on most operating systems (windows and linux) that make the ping pong very slow, at least a lot slower than it should be. (ping pong being the action of sending a line then waiting for a response then sending the next line). I ran into this issue a long time ago with gcode senders and never found a solution as it appears to be a USB thing. FWIW on Linux the /dev/ACMx driver does not have that issue so much, but the /dev/USBx driver does.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have updated the forth/dl.fs words to not allocate the large download buffer, it basically uses as much free memory as it can between the top of the dictionary and the end of RAM (basically in the middle of that), it uses 1/4 of the unused amount, on the RP2350 that is about 50K, on smaller systems it will be less. This should work fine so long as the files you download with \d are within that size. The only way I was able to get fast downloads was to just stream the files as fast as they would go with no delay and copy the data directly into the buffer, at least on an RP2350 this seems to be able to keep up. I have not tested it on slower MCUs yet. So if you get corruption on fast download just use \i instead.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Jim, one thing I always wanted to have is to assign a special char or char sequence or a special color when the mecrisp returns "?" (because of an error in words defs) as to find the returned "?" within a large upload is difficult..
I've been using TeraTerm in Win11 (my fpga wired over serial/ usb chip) and I need at least 15ms line delay there. Interestingly it uploaded with your terminal fine. Hopefully not matter of luck :) :)
Last edit: Igor M 2026-02-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yea color coding can be done, there is a mecrisp version that adds color to those prompts as well. In the case of \i it stops as soon as it gets an error anyway so it will be the last thing on the screen.
\d however is really only for files you already know have no errors. Adding color coding to forthcon will be something I'll look into, the prompt is already color coded. The line delay is only really needed if the returned ok. is not checked for every line. This is what e4thcom does as well as the xfr.py program that is somewhere on the mecrisp site. Also color coding the error is really only useful if it does not stop sending when an error is received.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is now 2456 bytes (incl. spaces between words), I think 4kB buffer/line would be ok..
Hmm, that is for 16kB mecrisp in fpga, people with large 32bit mcus might get it even bigger.
So 64kB line would be perhaps ok.. :) :)
Last edit: Igor M 2026-02-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There is no buffer limit now it just prints what it gets. However if the line is not terminated with a \n then it may not get flushed, I'm looking into it. There does not appear to be a stdout flush in go, I'll look harder.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Another interesting observation - when printing out the mandelbrot demo (made of chars) it waits till the \n and then prints out the entire line. In TTerm I see the individual chars coming (there are large diffs in the speeds it prints out the individual chars because of math). So in the first moment I thought it got frozen.. :-)
Last edit: Igor M 2026-02-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes it is line based, it reads a line at a time a line being terminated by \n, if it does not have a \n it gets buffered until it either gets a \n or it gets 1024 bytes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok I found the error, it will take a while to fix it... it only happens if there are very long lines that are not terminated by \n. I'll update github when I have fixed it.
Thanks for the help :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok I think I fixed it at the expense of adding a \n to a partial line that exceeds 1024 bytes. Now list seems to return all the words, albeit some are split by a newline. I think getting lines over 1024 is an edge case anyway and list is the only thing that seems to do it. Give it a try now.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is with my longest words list..
It periodically cuts making \n after aprox 1025 bytes (the yellow arrows show where ).
It does not miss words.
Your bin from 13:13..
They do not appear to be missing, they are split with a newline as I said I had to insert a newline at 1024 bytes. Can I see what the list looks like with your other terminal? Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I initially just sent the buffer with no \n, but for some reason it then does miss several hundred characters. I think it is a flushing or buffering issue, I am not sure, but there is no flush option on the write. Go says that output to stdoout is non-buffered, so it maybe the readline library. I'll let you know if I can fix that. for now inserting a \n is the easiest solution.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
I have produced another forth console similar to e4thcon but written in go.
It is here (with precompiled binaries for various platforms)
https://github.com/wolfmanjm/forth-console
It adds a bunch of convenience features over and above what e4thcon provides...
It is written specifically for quintus, but should work with any mecrisp forth.
The fast download (\d filename) is accomplished at the expense of a
large RAM buffer, and the forth code is included in the repo.
Basically it streams the file into the RAM buffer then evaluates that
buffer. I found this will download at the full baudrate (I use 3000000
baud!). The problem with waiting for each line is that the USB/CDC
turnaround time is very slow, and increasing the baudrate does not
actually help the download time.I found that this method downloads as
fast as (if not faster) than swdcom (which I love but doesn't work for
rp2350 or rp2050/pico).
\i filename will do the usual ping pong waiting for ok.
Feedback welcome as I have not tested on platforms other than linux on
x64 and arm64. Binaries for mac and windoze are included (but
untested) courtesy of go.
It seems it works in win11, it has uploaded a large file fine.. I wonder what is the line delay hardcoded in there (if any)?
PS: with "words" I got the "line too long"
Last edit: Igor M 2026-02-20
Yea that is the only command that gives that error. There is a line length limit of 1024 characters, I modified my copy of list to break up the lines to that length. words4 works though.
Thanks for testing on windows!
There is no line delay for \d it just streams as fast as it can. \i also has no line delay it just waits for ok. or an error.
The reason I did the \d was that there IS a delay in the USB drivers on most operating systems (windows and linux) that make the ping pong very slow, at least a lot slower than it should be. (ping pong being the action of sending a line then waiting for a response then sending the next line). I ran into this issue a long time ago with gcode senders and never found a solution as it appears to be a USB thing. FWIW on Linux the /dev/ACMx driver does not have that issue so much, but the /dev/USBx driver does.
I have updated the forth/dl.fs words to not allocate the large download buffer, it basically uses as much free memory as it can between the top of the dictionary and the end of RAM (basically in the middle of that), it uses 1/4 of the unused amount, on the RP2350 that is about 50K, on smaller systems it will be less. This should work fine so long as the files you download with \d are within that size. The only way I was able to get fast downloads was to just stream the files as fast as they would go with no delay and copy the data directly into the buffer, at least on an RP2350 this seems to be able to keep up. I have not tested it on slower MCUs yet. So if you get corruption on fast download just use \i instead.
Hi Jim, one thing I always wanted to have is to assign a special char or char sequence or a special color when the mecrisp returns "?" (because of an error in words defs) as to find the returned "?" within a large upload is difficult..
I've been using TeraTerm in Win11 (my fpga wired over serial/ usb chip) and I need at least 15ms line delay there. Interestingly it uploaded with your terminal fine. Hopefully not matter of luck :) :)
Last edit: Igor M 2026-02-20
Yea color coding can be done, there is a mecrisp version that adds color to those prompts as well. In the case of \i it stops as soon as it gets an error anyway so it will be the last thing on the screen.
\d however is really only for files you already know have no errors. Adding color coding to forthcon will be something I'll look into, the prompt is already color coded. The line delay is only really needed if the returned ok. is not checked for every line. This is what e4thcom does as well as the xfr.py program that is somewhere on the mecrisp site. Also color coding the error is really only useful if it does not stop sending when an error is received.
Ok I have fixed the "line too long" issue in forthcon, I just write out the long line. No need to fix the list word now :)
I rebuilt my fpga and the 921600 upload works fine. The syncing with "ok" is/was the way to go, sure..
The words shows more words now, but not all.. My words are 2456 bytes, and not all uploaded yet..
Last edit: Igor M 2026-02-20
ok I'll take a look... can you post the list word you are using?
It is now 2456 bytes (incl. spaces between words), I think 4kB buffer/line would be ok..
Hmm, that is for 16kB mecrisp in fpga, people with large 32bit mcus might get it even bigger.
So 64kB line would be perhaps ok.. :) :)
Last edit: Igor M 2026-02-20
There is no buffer limit now it just prints what it gets. However if the line is not terminated with a \n then it may not get flushed, I'm looking into it. There does not appear to be a stdout flush in go, I'll look harder.
Another interesting observation - when printing out the mandelbrot demo (made of chars) it waits till the \n and then prints out the entire line. In TTerm I see the individual chars coming (there are large diffs in the speeds it prints out the individual chars because of math). So in the first moment I thought it got frozen.. :-)
Last edit: Igor M 2026-02-20
Yes it is line based, it reads a line at a time a line being terminated by \n, if it does not have a \n it gets buffered until it either gets a \n or it gets 1024 bytes.
Ok I found the error, it will take a while to fix it... it only happens if there are very long lines that are not terminated by \n. I'll update github when I have fixed it.
Thanks for the help :)
Ok I think I fixed it at the expense of adding a \n to a partial line that exceeds 1024 bytes. Now list seems to return all the words, albeit some are split by a newline. I think getting lines over 1024 is an edge case anyway and list is the only thing that seems to do it. Give it a try now.
words - here with the long list I have now - it starts ok, then it misses X words periodically after 1025bytes, finishes ok..
CORRECTION: it does not miss but inserts \n - so my bad..
Last edit: Igor M 2026-02-20
Did you try the latest version?
This is with my longest words list..
It periodically cuts making \n after aprox 1025 bytes (the yellow arrows show where ).
It does not miss words.
Your bin from 13:13..
Last edit: Igor M 2026-02-20
They do not appear to be missing, they are split with a newline as I said I had to insert a newline at 1024 bytes. Can I see what the list looks like with your other terminal? Thanks
I corrected my findings above - it does not miss but inserts newline as you wrote.. The full list you may find above in the jpg picture
I initially just sent the buffer with no \n, but for some reason it then does miss several hundred characters. I think it is a flushing or buffering issue, I am not sure, but there is no flush option on the write. Go says that output to stdoout is non-buffered, so it maybe the readline library. I'll let you know if I can fix that. for now inserting a \n is the easiest solution.
Could it be because the serial_COM to usb dongle (ftdi in my case). Those work with such chunks/packets.
Last edit: Igor M 2026-02-20