CamelForth - nealcrook/multicomp6809 GitHub Wiki

CamelForth was written by Brad Rodriguez back in 1995, and was the basis for a set of articles in The Computer Journal (they are all well-worth reading).

I modified CamelForth to run on a 6809 multicomp. It acts as the boot ROM and can provide some of the capability of a debug aid as well as being a full programming environment in its own right.

CamelForth is programmed into the ROM. With the additions I have made, it only just squeezes in to 8Kbytes. It starts automatically at reset.

Learning FORTH

Historically, there have been many dialects of Forth, with subtle differences between them. CamelForth aims to comply with the 1994 ANS standard, also known as dpANS99a. The proper standards document is expensive, but the final draft is freely available online, for example here.

The ANS standard is a good reference but is not a good place to learn Forth. The traditional recommendation is Leo Brodie's "Starting FORTH" and an online version is available that has been updated to use ANS Forth. You can find it here. My preferred book is FORTH: a text and reference (Kelly & Spies, 1986) which is detailed, comprehensive and technical -- but covers FORTH 79 and FORTH 83 (earlier standards) rather than ANS FORTH.

There are also a few tutorials on-line, including two in the GNU Forth (gforth) documentation here

Saving and loading code to SDcard

I wrote low-level words for reading and writing between RAM and the SDcard. They are shown in [Program Startup]]. I wrote additional words that implement block files for CamelForth and a novel (I think) scheme for saving and reloading compiled blobs of code. They are described [here

Editor and utilities for CamelForth

The file cameforth/forthblk0.blk is a block file containing source for a screen editor and other utilities. Put in on your SD card and you will be able to type:

0 LIST
1 LIST

To learn about it and then type:

1 LOAD

To load it and add its capabilities to your system. Then type:

15 LIST
15 EDIT

To learn about the editor and then start it up.

To add it to your SDcard change your SD build script to include some lines like this:

# FORTH block files (optional)
# 4 files each of up to 256Kbytes, starting at offset 65MByte
# Block offset 256*1024 * 260/512 = 0x2.0800 (260 = 4*65)
dd if=forthblk0.blk of=multicomp09_sd.img obs=256K seek=260
# Block offset 256*1024 * 261/512 = 0x2.0A00
dd if=forthblk1.blk of=multicomp09_sd.img obs=256K seek=261
# Block offset 256*1024 * 262/512 = 0x2.0C00
dd if=forthblk2.blk of=multicomp09_sd.img obs=256K seek=262
# Copy of CamelForth Chromium source (just to give some text to look at!)
# Block offset 256*1024 * 263/512 = 0x2.0E00
dd if=chromium.scr  of=multicomp09_sd.img obs=256K seek=263

You can touch empty files to create forthblk1.blk and forthblk2.blk, or take copies of forthblk0.blk

Inspecting the source code

CamelForth is built through a near-magical process called meta-compilation, in which a Forth program running on one Forth compiler is used to generate a binary image -- maybe of a different Forth compiler, maybe of a different variant of the same Forth compiler. Maybe for the same architecture as the original, maybe not.

The source code for CamelForth comes as one lump with its meta-compiler, and it is designed to run on a sophisticated (but old) MS-DOS Forth implementation called F83, or Laxen-Perry F83 (named for the two men who developed it and generously donated it to the world). F83 runs quite happily under DOSbox so it is possible to rebuild CamelForth from source using the procedure described here. I also created an ANS version that can be rebuilt using gforth, using the procedure described here.

The file containing the source code/meta-compiler is named chromium.scr. This is a Forth "block" file which means that it is a sequence of 1Kbyte chunks intended each to be displayed as a 16 lines of 64 characters. Each chunk or "block" is referred to by its offset from the start of the file. Thus, the first block is block 0. There are no line endings and so you cannot readily load it into an editor. Also, the build process uses some blocks of the file to store the binary image that is generated by the meta-compilation process.

The PERL script bin/forth_block2ascii will format a block file for inspection or printing. Usage:

forth_block2ascii chromium.scr > chromium.lst

The companion PERL script bin/forth_ascii2block will go in the other direction. Usage:

forth_ascii2block chromium.lst > chromium.scr

These two scripts make it easy to perform edits (even complex edits and code movement) on a block file using a normal editor. The input to forth_ascii2block does not care about the block or line number fields; it only cares that there are exactly 64 characters between the line start and end markers (|). It will chunk lines up into groups of 16 and use each group as a screen. If in doubt (eg, after a significant edit) run the file back through forth_block2ascii to ensure that everything lines up properly. forth_block2ascii prints a checksum at the end of each line and a checksum at the end of each block. This is intended to make it simple to identify where blocks have changed -- for example, when you are looking at the screen and looking at a (possible old) printout. One screen of sample output is shown below.

          +----------------------------------------------------------------+
  045:00  |\ Load screen for Multicomp port                      29apr15nac|  11C8
  045:01  |DECIMAL     2 LOAD   ( metacompiler vocabularies)               |  10D4
  045:02  |DECIMAL     3 LOAD   ( image to disk, bin endian)               |  0F98
  045:03  |DECIMAL 24 26 THRU   ( DUMP AND IBM PC Intel hex file output)   |  1177
  045:04  |DECIMAL  4  7 THRU   ( target model - needed for assembler)     |  127D
  045:05  |DECIMAL 30 44 THRU   ( 6809 assembler)                          |  0D23
  045:06  |DECIMAL  8 23 THRU   ( rest of metacompiler)                    |  0F75
  045:07  |                                                                |  0800
  045:08  |ONLY FORTH META TARGET DEFINITIONS                              |  0D2F
  045:09  |DECIMAL 46 48   THRU ( MULTICOMP VER. OF 61-63)                 |  0D20
  045:10  |DECIMAL 64 118  THRU ( 6809 SOURCE CODE)                        |  0C4A
  045:11  |DECIMAL 50 59   THRU DECIMAL 121 127 THRU ( MULTICOMP EXTRAS)   |  0F27
  045:12  |DECIMAL 49      LOAD ( MULTICOMP VER. OF 119) DECIMAL 120 LOAD  |  0E94
  045:13  |ONLY FORTH ALSO META                                            |  0AFB
  045:14  |HEX E000 2000 HEXFILE 6809M.HEX  ( make hex file, IBM PC only)  |  10A5
  045:15  |.MIRRORS BYE                     ( print undef'd references )   |  1019
          +----------------------------------------------------------------+  EACD

In order to build CamelForth for the original target, follow the code from screen 1. In order to build CamelForth for multicomp, follow the code from screen 45.

The CamelForth code for starting the other environments (BASIC, FLEX etc.) is described in Program Startup.

Interfacing to code and interrupts from CamelForth

CamelForth implements FORTH on a virtual machine (VM). You can interface between the VM and raw machine code and you can run interrupt service routines (written in machine code) without interfering with the VM. A simple example is shown here: interrupts in camelforth.

More on CamelForth

https://launchpad.net/camelforth http://www.camelforth.com/ http://www.bradrodriguez.com/papers/index.html