SECND, a FORTH

SECND is a contemporary implementation of the FORTH programming system for the 65C02 (the CMOS version of the venerable MOS 6502 processor). The FORTH language is so named because its inventor, Chuck Moore, thought of it as a "Fourth-generation" language, but the system he was using at the time only allowed five-character filenames. Since this is my second FORTH implementation (the first one having been written 30 years ago), SECND seemed like an appropriate name.

FORTH is an unusual programming language, to say the least. If you are used to modern languages, you are going to find FORTH a bit of a switch. It has absolutely no syntax, and it eschews most of the values of modern software engineering. On the other hand, it is extremely efficient, especially on systems with limited resources, which is why it was often a go-to language for early microcomputers in the 1970s and 1980s. My Mite single-board computer project is designed in the spirit of those, and so FORTH made sense as the first language to implement.

More interestingly, perhaps, FORTH has a distinct personality. All programming languages have a philosophy, but, in my experience, for no language is that philosophy so deeply bound up with the personality, experience, and attitudes of one person as for FORTH. Chuck Moore's particular avocations and values are at the forefront. A dive into the language is a dive into his psyche. Foremost is "programmer productivity". Nothing is tolerated that would get in the way of a programmer doing just what she or he wants to do . Modern languages are designed with safety and reliability in mind, but pretty much any language allows you to shoot yourself in the foot one way or another. In FORTH, you are provided with a fully-loaded automatic weapon, and encouraged at the same time to run with scissors, play with fire, walk a tightrope, and eat food well beyond its sell-by date.

Forth is often described as an interpreted language, although that is not quite correct. Forth is an interactive language; one develops programs by typing them directly to the computer. Forth expressions are interpreted directly, but a FORTH system includes a compiler, which one also uses interactively. The compiler and interpreter are deeply integrated; indeed, many of the standard words (as FORTH calls its functions or procedures) are themselves elements of a compiler. The compiler and interpreter depend on each other so directly that it doesn't make sense to think of them separately. This, plus the absence of syntax (all FORTH programs are merely a sequence of words separated by spaces, with each word performed individually in sequence) means that writing a program is often more like extending the language so that it is specialized to your particular application.

The main features of SECND are:

ANS-ish/FORTH-200x-ish. FORTH implementations tend to be somewhat idiosyncratic, but there have been a number of standards over the years, at least informally. Although my implementation is not complete, I have tended to adopt semantics and nomenclature from the 1994 ANS FORTH standard and from the subsequent FORTH-200x community effort.

Largely assembly language implementation. Some FORTHs have a minimal core written in assembly language, and then build up the rest of FORTH in FORTH itself. For performance, mine is implemented almost entirely in 65C02 assembly language. The entire system, including the components below, is about 12kB.

ROM/RAM. It has been RAM-resident while I've been designing it but is designed to be ROM-based in regular daily use. (More recent versions have been ROM-resident, with a basic SD-card interactive file manager as the boot-up code.)

FAT16/SD card support. My 6502-based system would most likely have relied on cassette tape or perhaps floppy disks back when people produced these designs, but those are not effective options these days. SECND includes a subsystem to communicate with SD cards by bit-banging the SPI protocol via a 65C22 interface adapter. It has a transfer rate of around 8kB/s on a machine clocked at 2MHz. (I could certainly make it go faster at the expense of some code space, although since the entire RAM capacity of my machine is only 32k, it seems unnecessary. Filling the entire memory in 4s is fine for now.) SECND also implements (parts of) the FAT16 filesystem so that I can move files on SD card back and forth between the 6502 machine and more modern computers.

Screen editor. Traditional FORTH systems are self-hosting; more contemporary implementations rely on underlying operating system functions for editing and file processing. However, there's no underlying operating system for my system; indeed, increasingly other "systems" software relies upon and is absorbed into SECND. So it relies upon an internal editor, but the traditional line-editor of classic FORTH systems just wasn't an acceptable option. SECND uses the standard FORTH "block" editing system, but has a screen-based editor (with EMACS-like commands) to edit code. (It also allows files to be loaded from external files.)

The current (September 2018) full list of implemented words is:

using? */mod 2* 2/ dodoes (does) does> [char] char base decimal hex unused execute , create sm/rem um/mod um* ud. base save-buffers iobuf accept cmove> cmove move compare /string -trailing ;s sp@ use load list edit first flush prev update buffer block using include fload show dir loadblock mount count dump tuck nip key? cload upload abort d.r dmin dmax d< dabs d0< .r u. 0 fill dnegate immediate ' forget /mod ( .s +! ?dup pick negate abs */ rshift lshift 2drop 2over 2dup 2swap d. m* d0= d= m+ d- d+ s>d type sliteral s" constant \ recurse repeat while invert (leave) leave 2- 2+ 1- 1+ 0= xor or and key min max k j (+loop) +loop (loop) loop (do) do words else until begin then if ." i r@ r> >r ; : bye allot here - variable cells c! ! c@ @ false rot over emit cr < > depth = mod / drop swap dup branch <> . lit true 0branch * + exit

They're in a pretty random order (basically, the reverse of the order in which they were implemented). A few are internal bits and pieces for testing. One day this will be tidied up.

SECND is available on Github. My use of github is a little odd; each major version is maintained as a separate file. It relies on some basic stack code that can be found in my monitor elsewhere on github. Once it stabilizes, I'll reorganize the files for more convenient access and browsing (not to mention more convenient assembling and linking). I have been using xa65 as my cross-assembler.