index

NCS-1983: A Forth-like Language

Based on threaded code and similar to Forth, this language and interpreter/compiler aimed to be simple, easy to implement in ROM, and fit into only 2K, or 8K or both, depending on which version I was working on at the time.

This is a language and interpreter/compiler based on threaded code and resembling Forth, which I invented mostly during 1982-1983 to run on an Ohio Scientific Challenger IIp, a 6502-based microcomputer from 1979. More detail about the history of the language and projects attempting to implement it.

This machine had no persistent storage but a cassette tape unit, a simple extended ASCII video display of 25 lines of 40 characters (iirc), and some homebrew circuit mods to allow the MSB of ASCII codes to show a character as black on white instead of white on black, and produce audio.

Antique 8-bit microcomputer: Ohio Scientific Challenger

My main interests in developing a language were: controlling hardware, audio and sensor signal processing in fixed point, and seeing what I could cram into an 8K ROM. I was also quite interested in the inner workings of compilers and interpreters.

Basic Concepts

These are elaborated upon in the more detailed pages, but a quick overview may be helpful:

Dictionary
Linked list (or somesuch) which associated words e.g. "=?" with chunks of code. The chunk of code may be executed each time the word is entered on the command line, or a call to it compiled, typically when a new word is being defined.
Machine Stack
The usual built-in stack mechanism for return address. The 6502 reserved addresses 0100 - 01FF for this stack. This is built into the chip circuitry.
Data Stack
Where data is worked upon. A number or variable's value is pushed onto this. Items are signed 16-bit integers, unless used an an address in which case it's unsigned.
Control Stack
A separate stack used to keep track of loops. Existed during development, but eventually I figured out how to use the machine stack. My notes may be inconsistent in use of a "control stack".

Threaded Code

The languages worked on the idea of "threaded code". This has nothing to do with multiple parallel sequences of execution, common since the 1990s, but is a notion of writing machine code used for implementing Forth. In my NCS, two types of executable code exist

  1. Plain 6502 opcodes
  2. Monobyte code

More details are in the other pages, especially MonoByte Code page.

Three Approaches

If one wants a microprocessor to execute a sequence of operations, each operation defined in a self-contained way by a machine code subroutine ending with RET, and no handling of intermediate values, there are three ways to go about it:
  1. Series of subroutine calls. JSR $076D, JSR $0789, JSR $081C, ... This takes up three bytes per call, which is bad news for anyone with small ROM or RAM.
  2. Keep just the addresses: 6D 07 89 07 1C 08 .... This takes 2/3 the space, but slower as a tight machine code loop must scan these address and do an indirect jump to subroutine. (Which I don't think the 6502 had, but it could be faked.)
  3. The ideal is one byte per operation. Somewhere, a lookup table indexed by a byte (perhaps of limited range, such as 0 to 63) would provide the address of the operation's subroutine. This is tighter code spacewise, but even slower as the execution loop must do a lookup then jump indirect to the subroutine. This is the approach of MBC.

In those days, the prefix '$' indicated a hexadecimal number. The 'C' language and its notation for hex wasn't well known yet. I certainly hadn't heard of it. In most places in these HTML-transcribed notes, I've changed hex numbers to C-style, 0x076D, since that's what everyone has been using in all languages since the 1990s.

Monobyte Code

Monobyte code, "MBC", is a series of one-byte instructions, each invoking some keyword of the NCS language. A sequence of MBC would be interpreted by a small fast routine in 6502. Such a sequenced ended with a special return opcode, causing execution to return to the caller, which could be 6502 or MBC.

Every keyword of NCS could be defined in either 6502 or MBC. A definition could start with 6502 but convert to MBC.

Further Details

References

BYTE August 1980 - special language issue for 1980 covered Forth


The Evolution of FORTH, an Unusual Language, by Charles H Moore, BYTE August 1980 p 76+. History of how FORTH came about, from its inventor.

What is FORTH? A Tutorial Introduction, John S James, p100+. Explains the language and its inner workings.

BREAKFORTH Into FORTH! A. Richard Miller and Jill Miller, p 150. Details a real-time video game written in Forth for the TRS-80.

FORTH Extensibility - Or How to Write a Compiler in 25 Words or Less, Kim Harris, p. 164. THe juiciest article with inner workings of compiling, managing the dictionary, and executing.

FORTH GLossary, with the most common Forth words, gathered by Byte editor Gregg Williams, page 186.

Books

Threaded Interpretive Languages, R. G. Loeliger, BYTE/McGraw-Hill, 1980

Conclusion

There is a conclusion at the end of the page for the Magellan Project. Galaxy didn't get as close to having a near-final body of source code; there is no specific conclusion to draw from that work. Overall, these points may be noted:


Daren Scot Wilson's personal site
linkedin