home .. products ..
MFORTH

MFORTH is an ANS Forth environment for the TRS-80 Model 100 laptop computer. MFORTH is provided as a 32KB Option ROM image and can be used alongside your existing M100 applications.

MFORTH running in Virtual-T, showing a "Hello World"
application.

All MFORTH development can be done on the M100 using the built in TEXT editor. MFORTH can read .DO files from memory and supports multiple levels of source file inclusion. Interactive development is supported by way of the standard Forth text interpreter.

The best way to use MFORTH is with REX on the real Model 100 hardware. REX is a plug and play flash memory upgrade for your laptop that allows you to easily use a variety of Option ROM images on your M100.

You can also use MFORTH in Virtual-T, which is especially helpful when working on the MFORTH kernel itself. I primarily develop MFORTH in Virtual-T and then move MFORTH builds to my Model 100/102 laptops for testing and application development.

 
Installation

MFORTH must be added to the system menu before it can be used. Perform the following steps on your Model 100 or Model 102 laptop in order to use MFORTH for the first time:

  1. Select BASIC from the system menu.
  2. Type CALL 63012 at the Ok prompt and hit ENTER.
  3. MFORTH will load and add itself to the system menu.
  4. Type bye to return to the system menu. MFORTH should now appear on the system menu and can be accessed by selecting MFORTH and pressing ENTER.
 
Architecture

The design of MFORTH was inspired by the undocumented LHLX instruction in the 8085 CPU. This instruction loads HL with the contents of the address pointed to by DE. LHLX allows MFORTH to perform the function of NEXT, the Forth inner interpreter, in only four machine instructions. This is much faster and more efficient than 8080 fig-Forth, which requires 11 instructions to perform the same operation.

MFORTH also makes use of a unique dictionary layout, first proposed by Robert L. Smith in his Forth Dimensions I/5 article titled “A Modest Proposal for Dictionary Headers”. In a nutshell, the name of each word is stored in reverse order in memory and the Link Field Address of each word points to the start of the preceding word’s name. This allows constant offsets to be used to convert between Name, Code, and Parameter Field addresses.

I discovered soon after completing the first version of MFORTH that the text interpreter was very slow. There was a noticeable delay between hitting return in the interpreter after entering a series of words and when the ok prompt would reappear. Compiling the smallest of source files was unbearable. I wasn’t ready to believe that the M100 was quite this slow, so I added a profiler to MFORTH (the PROFILE and TIMED-EXECUTE words) in order to track down the problem.

Rewriting FIND, NEXT-LINE (part of the file-reading routines), and WORD produced a 13x improvement in my benchmark. I was pleased with the results, but still felt that the code could be faster. I considered my options and decided to trade space – I had more than 20KB left in the ROM – for performance. My solution was to implement the ROM-based dictionary as a perfect hash. That improvement increased the performance of the text interpreter to almost 48x the speed of the original code. A file that used to take more than four seconds to load now took less than ninety milliseconds.

The perfect hash is based on a Cuckoo Hash and is generated by a second build pass. The first build pass creates the standard ROM, with the traditional, linked list dictionary structure. MFORTH’s PhashGen tool then reads the dictionary out of the ROM file, generates the hash tables, and writes those hash tables out as an assembler file. The second build pass compiles the hash tables into the ROM and enables the hash-based dictionary search.

(FIND) (the internal word used by FIND and other CORE words) traverses the dictionary as a linked list until the traversal enters the ROM address space. At that point (FIND) locates the word using the pre-generated hash table, a constant-time operation.

Additional documentation regarding MFORTH’s internals can be found in the highly-commented source code. main.asm provides details on register usage, the memory and dictionary layouts, and the locations of transient regions used by MFORTH.

 
Next Steps

Version 1.1 added a full 8085 assembler, enabling end-to-end development on the M100 itself. The MFORTH multitasking system was also completed in 1.1. Next up on the feature list is support for the serial port as well as web-based documentation for the non-ANS parts of MFORTH (the multitasker, assembler, etc.).