I had really, really hoped to get this finished before Spring, but the weather has turned warm too early and people are insisting I start doing stuff in the garden instead of sitting in front of the computer. So, I'm presenting an almost-finished ("Alpha") variant of Forth I have been working on: Tali Forth for the 65c02.
Tada!Tali Forth is a Subroutine Threaded Code (STC) implementation specifically for the 65c02, modeled on the ANS Forth standard. I wrote it because I wanted to understand the inner workings of Forth and have a modern version of the language for my Übersquirrel. Its aims are, in rough order of priority:
Simple. The primary aim is to help understand me a complete Forth system byte by byte. This is why the STC format was chosen, and why the dictionary has a bizarre structure (more on that later). This is also the reason the source code is perversely over-commented.
Specific. A lot of other Forths are written with a general structure and then ported. This is for my favorite 8-bit MPU and that MPU only, with its strengths in mind.
Standardized. One problem with FIG Forth is that it is ancient, and learning Forth with it feels like trying to learn English by reading Chaucer. Tali Forth follows the ANS Draft Standard 200x where it can. For example, it uses PARSE-NAME instead of WORD.
Speedy. Tali Forth places speed over size (within reason). Still, the aim is to keep the core stuff and the kernel routines in 8k of ROM.
This is what I managed to code before global warming forced me out of the cellar:
Code:
ELSE THEN IF WORDS DROP 2DROP ! @ >R R> R@ OVER 2OVER DUP ?DUP 2DUP SWAP 2SWAP NIP TUCK ROT DEPTH 1- 1+ FALSE TRUE BRANCH (BRANCH) 0BRANCH (0BRANCH) BEGIN AGAIN ABS DABS + - * / */ */MOD UM* M* UM/MOD UD/MOD SM/REM FM/MOD MOD /MOD M+ AND OR XOR INVERT NEGATE DNEGATE MAX MIN LSHIFT RSHIFT S>D D>S D+ D- <# # #S HOLD SIGN #> U. U.R UD. . .R D. D.R 2 1 0 < = > 0= 0< COUNT >IN TYPE EMIT CHAR TOUPPER KEY BASE HERE PAD UNUSED ERASE FILL CELL+ CELLS CHAR+ CHARS C, C! C@ CMOVE CMOVE> ALIGN ALIGNED ALLOT , ' >BODY >NAME EXECUTE EVALUATE STATE COMPILE, : ; ] [ POSTPONE IMMEDIATE CREATE VARIABLE +! SOURCE DECIMAL HEX BINARY DIGIT>NUMBER NUMBER >NUMBER BL CR SPACE SPACES ." (.") S" (S") .( ( \ /STRING -TRAILING FIND ACCEPT PARSE PARSE-NAME .S SEE DUMP QUIT ABORT LITERAL (LITERAL) BYE
(WORDS returns a few more, but those are just dictionary headers without code). The most important stuff still missing are the loop structures such as DO, LOOP, UNTIL, then DOES>, and some stuff like CONSTANT and MOVE I probably could do in a few hours if I wasn't busy planting radishes. Reference design is gForth, so what works in Tali Forth should produce identical results or have a good reason not to. There is a .ods (for Windows users: .xls) file with more details, though it is not complete. I've followed the Forth tradition of putting the code in the public domain.
I cannot stress enough that this is alpha-level code. When it says "tested" on the spreadsheet, that means I've tried one or two trivial cases and it didn't blow up in my face. There is little error checking, nothing has been optimized, and a lot of stuff was coded at odd times of the day. You'll see the source code is riddled with "TODOs". I hope to be able to work on it some more in the coming months, but I know how
that turned out last year, so I'm presenting what I have in the hope it might be interesting to somebody while I'm digging the veggie patch.
There is a binary included in the attached ZIP package called ophis.bin that will run on py65mon at your own risk. Load with
Code:
py65mon --mpu 65C02 -r ophis.bin
It currenty loads as 16k at C000 because I'm too lazy to change the default input/output address of py65mon from F000.
I'll talk about the dictionary structure in a follow-up here soon. Comments and suggestions are of course most welcome, and thanks to everybody who made this possible here and in other parts of the net!