The default message shown after a reset of Mecrisp Forth is this prompt:
Mecrisp-Stellaris RA 2.3.6 for STM32F103 by Matthias Koch
Nothing else, no hint that you can start entering commands. With a board.fs
file from Embello loaded, we get an extra line with some useful status
information (and an “ok.”):
Mecrisp-Stellaris RA 2.3.6 for STM32F103 by Matthias Koch 64 KB <g6s>
32212433 ram/flash: 17024 19456 free ok.
But the fact remains that the “ok.” prompt is in a not-so-common spot, at the end of each line:
1 2 + . 3 ok.
1 ok.
2 ok.
+ ok.
. 3 ok.
With the prompt.fs code, we can change that - yes, in Forth nearly everything can be changed:
R#0 > 1 2 + .
3
R#0 > 1
R#1 > 2
R#2 > +
R#1 > .
3
R#0 >
Where “R” means we’re compiling to RAM (“F” is flash), the “#” means the number base is currently set to decimal, and the number tells us the number of items on the data stack.
The way this works is that Mecrisp calls hook-quit
after each command line.
This lets us switch to our own read-eval-print-loop, or
REPL - as this interactive
process is usually called.
Note that this interferes with Folie’s handling of the prompt and will somewhat
confuse it - it’s better to use picocom
or some other terminal emulator if you
want to alter Forth in this way.
Mecrisp Forth does not have a lot of math support built-in. But everything can
be added on top, as the
sqrt.fs
and
sine.fs
files llustrate. These were copied over from the Mecrisp
distribution.
The sqrt
function operates on 32-bit unsigned integers, as you can see here:
1000000000 sqrt . 31622 ok.
4000000000 sqrt . 63245 ok.
The sine
and cosine
functions, however, operate on “32.32” fixed-point
number, i.e. a 64-bit value represented as two 32-bit words in Forth, with the
decimal point assumed to be in-between these words. In other words, fixed
32-bit integer and fractional parts. In practice, this precision (over 9 digits
each) and the range of values which can be represented is more than enough for
many use cases. The benefit of this representation, is that the operations
require no hardware floating point support and are quite efficient (more on that
in an upcoming article).
In Mecrisp Forth 32.32 fixed point values can be entered by inserting a comma in the value:
123456789,987654321 f. 123456789,98765432089567184448242187500000 ok.
123456789,987654321 9 f.n 123456789,987654320 ok.
Note the somewhat excessive printed precision with “f.
” (in case you’re
printing them out in base-2!) and how the number of decimals can be limited with
“f.n
”. Note also the unavoidable loss of precision when it comes to
representing a base-10 mantissa as a base-2 value:
0,1 f. 0,09999999986030161380767822265625 ok.
Back to sines and cosines. The
sine.fs
code also defines constants for pi
and pi/2
, but not pi/4
, so let’s add
that and verify that the sine and cosine of 45° (π/4 in radians) are almost the
same:
pi 4,0 f/ 2constant pi/4
pi/4 sine f. 0,70710678072646260261535644531250 ok.
pi/4 cosine f. 0,70710678095929324626922607421875 ok.
We’re using f/
here to divide two 32.32 fixed point values. It’s also
worth pointing out that there are no f+
and f-
, because they’re the same as
their 64-bit integerd+
and d-
counterparts.
Anyway, so much for some basic maths. Matthias has recently added the arctan
function and some other convenience definitions. These functions all rely on the
CORDIC algorithm.
As final item in the list of extensions which are readily available with Forth, there’s a 32-bit pseudo-random number generator (PNRG), available as random.fs in the Embello repository:
random . -1412445179 ok.
random . 1559860420 ok.
random . 910593606 ok.
random . -493546331 ok.
random . -1177063378 ok.
To verify that the generated numbers are indeed randomly distributed, we can run a small test:
2000000 tally counts
999707
999541
1001010
1001118
999600
999359
1000272
999002
999779
1000194
999404
1000235
1000026
1000394
1000672
999687 ok.
This generates 2,000,000 random numbers of each 32-bit, cuts them up into 4-bit pieces, and counts how often each of the 0000..1111 patterns occur. If evenly distributed, all the counts will be very similar most of the time - as indeed confirmed in the above printout.
Check out the ex/prompt.fs, ex/random.fs, and ex/trig.fs demos to see how it’s done in Forth.