An attempt at Forth for the MEGA65. This is heavily influenced by FIG FORTH release 1.1
This publication has been made available by the
Forth Interest Group, P. O. box 1105, San Carlos, CA 94070
Note that we have actually switched to font A (the ASCII font). The \
word shows up correctly on screen but the screenshot from m65 assumes the default font.
This is still in the early stages of developement - check the status table below for details on what is and is not supported so far. The most important missing pieces right now are likely support for MARKER
and/or FORGET
, an editor and an assembler word set. Programs can be entered manually or read from pre-existing sequential files, however, and much of the core dictionary is implemented and fairly stable.
The next priorities are:
MARKER
has been implemented, but it might be worth trying to get a workingFORGET
too.- We can now run the complete preliminary, core, core plus and core extension tests unmodified, but there are a number of failures that need to be addressed.
- Move more of the implementation from assembler to Forth. As this happens, getting a functional
SEE
is becoming more and more important (even if it's just a hex dump at first).
My apologies if this isn't the greatest Forth implementation. I don't really have much experience with Forth. I'm doing this because I've always been intrigued by Forth, and with a new MEGA65 sitting on the dining room table, it seemed the perfect project to learn about Forth, shake decades of dust off my 6502 programming skills, and learn about some of the MEGA65-specific features.
An attempt will be made to:
- Be more Forth 2012 compliant, or at least ANS Forth (94). Things that have been removed in 2012 (such as
TIB
) almost certainly won't be implemented. Things that are obsolescent in 2012 (such as[COMPILE]
) may not be implemented either. - Provide access to MEGA65 features. I'll likely look at least at SUPER FORTH 64 (which was based on MVP-FORTH) for API ideas here, and possibly others, but I may not retain compatability.
I haven't looked at geoForth yet, but intend to at some point. Making some sort of equivalent for the MEGA65 GEOS might be interesting, and give me an excuse to dig into GEOS a bit. No promises here though.
Eventually, I want to sort out how to take advantage of more than 64K without breaking compliance with the Forth 2012 specification. It would be nice if we could move much of the standard dictionary to bank 1, for example.
- ACME: I was using the one from MEGA65 github but switched to the svn version to get access to some of the more recent features, but I'm not certain I ended up using them. It could be that the MEGA65 one will still work.
There is a build script in bin/build.sh
that can be used. Right now it doesn't do a huge amount, but eventually I expect
that the build process will get more involved:
- Compiling the builtins
- Use a MEGA65 or xemu to compile the rest of the standard dictionary, possibly for multiple configurations (a minimal set, a complete set, etc)
- Run a test suite
- Run benchmarks
- Building tools (an assembler word set? an editor?)
- Assembling a disk image with various build configuration, source code, examples, tools
- VICE for c1541 and petcat to manipulate d81 images
- m65, mega65_ftp from MEGA65 Tools
- m65dbg
- Xemu
These should get us to the point of bootstrapping with a dictionary written in forth and running unit tests:
- CORE
- Need to reimplement the multiplication/division operations using the math unit.
- EXCEPTION
- Need to be able to throw exceptions from assembler. This likely means changing the
THROW
implementation to be native code instead of Forth bytecode. - Many bits of code need to be updated to throw an exception for error conditions.
- Need to be able to throw exceptions from assembler. This likely means changing the
- FILE
- Handle file access modes.
- Fix I/O status handling (when is status from READSS reset?).
- Fix handling of I/O error cases.
- Error checking (and throwing the appropriate exception)
- Unaligned address.
- Divide by zero.
- Pictured numeric output string overflow.
- Parsed string overflow?
- Mismatched control structures.
- Invalid name.
- File I/O error.
- Unexpected EOF.
- Moving more of the implementation from assembler to Forth.
-
READ-LINE
-
ACCEPT
-
REFILL
-
EVALUATE
possibly? (would need to tweak the bootstrap code)-
SAVE-INPUT
-
RESTORE-INPUT
-
SOURCE
-
-
UNUSED
possibly? would need access to DAREA
-
- Tests
- Test suite
- Some reasonable way of capturing test results.
- It might make sense to have a way to redirect
EMIT
to a file. gforth makesEMIT
a deferred, which might be the cleanest option.
- It might make sense to have a way to redirect
- Benchmarks
- Compiling the dictionary?
- Something without I/O?
There'll be lots more to do after that.
Note that some of these are implemented in Forth and the bootstrap process is not yet automated.
The code is getting to the point where automating the test suite makes sense. I do want to have some way to redirect output to make extracting results simpler.
Test | Status | Comments |
---|---|---|
Preliminaries | PASS | 1 expected2 error reported. |
BLOCK | TBD | Too early to attempt |
CORE, CORE plus | FAIL | Some problems with UM/MOD . 17 errors reported, 9 of which are expected2. |
CORE-EXT | PASS | 4 expected2 errors reported. |
DOUBLE | TBD | Too early to attempt |
EXCEPTION | PASS | |
FACILITY | TBD | Too early to attempt |
FILE | TBD | Too early to attempt |
LOCALS | TBD | Too early to attempt |
MEMORY | TBD | Too early to attempt |
SEARCH | PASS | |
STRING | TBD | Too early to attempt |
TOOLS | TBD | Too early to attempt |
The cause of these failures has not yet been determined.
From core plus:
INCORRECT RESULT: t[ 0 max-uint 0 ustep gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 0 max-uint -ustep gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 max-int min-int step gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 min-int max-int -step gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 0 0 ustep +uwrap? 256 gd9
INCORRECT RESULT: t[ 0 -max-int negate -max-int over gd8 -2> 2 ]t
INCORRECT RESULT: t[ 0 min-int 1+ 1 min-int gd8 -> 2 ]t
From string (looks like PETSCII things?):
INCORRECT RESULT: t[ s11 s12 compare -> 1 ]t
INCORRECT RESULT: t[ s12 s11 compare -> -1 ]t
Because we are using the PETSCII character set and not ASCII some tests are expected to fail. I'm not considering these as errors.
From preliminaries:
error #47: testing [CHAR]
From core:
INCORRECT RESULT: t[ char X -> 58 ]t
INCORRECT RESULT: t[ char HELLO -> 48 ]t
INCORRECT RESULT: t[ gc1 -> 58 ]t
INCORRECT RESULT: t[ gc2 -> 48 ]t
INCORRECT RESULT: t[ gc3 -> 58 ]t
INCORRECT RESULT: t[ gc4 drop dup c@ swap char+ c@ -> 58 59 ]t
INCORRECT RESULT: t[ gp1 -> <true> ]t
From core plus:
INCORRECT RESULT: t[ 'z' -> 122 ]t
INCORRECT RESULT: t[ 'z' -> 7a ]t
From core extensions:
INCORRECT RESULT: t[ ssq3 drop 1 chars + c@ -> 8 ]t \ \b BS Backspace
INCORRECT RESULT: t[ ssq3 drop 3 chars + c@ -> 12 ]t \ \f FF Form feed
INCORRECT RESULT: t[ ssq3 drop 14 chars + c@ -> 97 ]t \ a a Hex follow on
INCORRECT RESULT: t[ ssq3 drop 16 chars + c@ -> 120 ]t \ x x Non hex follow on
INCORRECT RESULT: t[ max-uint max-uint um* max-uint um/mod -> 0 max-uint ]t
- Lots of the implementation comes from FIG FORTH release 1.1 (public domain).
- The implementations of some of the words comes from the reference implementations. These are being released under a CC0 license.
- Test suite.