pfth Version 0.72 December 16, 2012 Dave Hein (This version has been altered by G. Herzog, June 20, 2013 for minor reading improvements & ease startup for new users.) pfth is an ANS Forth interpreter that runs on the Propeller. It is written in PASM and Forth, and it can be built using the Prop Tool or BST. pfth implements all 133 of the ANS Forth core words plus about two-thirds of the core ext words. pfth will run on almost Propeller board that supports the standard serial interface at initial default settings of 115200 baud 8N1. After loading and communications are established, use 'words' to verify display is correct. If only one line is displayed and over-written, reconfigure your serial terminal to add a Linefeed to Carridge Returns. VERSIONS OF SPIN FILES There are two versions of pfth. One of the version interfaces to an SD card and can execute Forth programs on the SD card. This version is in sdpfth.spin. The program is set up for the C3 card, but it can be modified to support other cards. The second version can be used to build stand-alone Forth applications. It is in pfth.spin. In this version, Forth programs are included using the Spin FILE directive. LEXICON pfth has over 50 kernel words, with most of them from the ANS core word set. The source code for pfth is contained in pfth.spin, init.fth and other Forth programs included at the end of pfth.spin. Two of the non-standard words implemented by pfth are cog@ and cog!. These are are used to read and write cog memory locations. Their main purpose is to access the Prop registers, such as CNT, INA and OUTA. Another non-standard word is cogx1, which is used to execute native Prop instructions. The TOS contains the Prop instruction, and the next value on the stack is used for the destination register value. The result of the execution of the instruction is returned on the stack. Some other non-standard words are _lit, _gethex, _jz and .x. _lit is used to encode literal values. _gethex is used during the boot phase to convert numeric strings to hex values. _jz implements a jump-on-zero primitive. .x is used for debug purposes, and it prints values as 8-digit hex numbers. .x is commented out by default. The kernel words are as follows: Interpreter Words Math and Logical Words Memory Access ----------------- ---------------------- ------------- evaluate + ! execute - @ find * c! word / c@ refill mod create and Console I/O : or ----------- ; xor emit < key = accept Program Termination > ------------------- lshift Primitive Words abort rshift --------------- exit _lit quit Variables _gethex --------- _jz Stack Operations #tib .x ---------------- tib drop >in Propeller Words pick base --------------- roll dp cog! >r last cog@ r> state cogx1 depth pfth also contains a small number of pre-compiled Forth words written in Forth. These words are here, allot, ",", _jmp and count. The definition of these words is as follows. : here dp @ ; : allot dp @ + dp ! ; : , here ! 4 allot ; : _jmp r> @ >r ; : count 0 pick 1 + 1 roll c@ ; AT START UP When pfth starts up, it runs a small boot interpreter that compiles the ANS dictionary contained in init.fth. This file is included in the PASM binary image using the PASM FILE directive. Other Forth source files may be included after init.fth to add additional words and to implement a specific application. The boot interpreter can only handle hex numbers, so pfth is in the hex mode when first starting up. The boot interpreter has no error handling capability, and is only used to build the initial dictionary. The boot interpreter uses a limited vocabulary consisting of the following 20 kernel words. dp state _lit _gethex : ; c@ @ ! + = pick roll drop r> >r word find execute refill The boot interpreter is shown below in a pseudo-Forth language. The labels (label1), (label2), etc. are actually encoded as PASM labels, but they are shown symbolically in the code below. : xboot (label1) 20 word 0 pick c@ _jz (label2) ( Get word, refill if empty ) find 0 pick _jz (label3) ( Find word, get number if not found ) state @ = _jz (label4) ( Go execute if not compile mode or immediate ) , _jmp (label1) ( Otherwise, compile and loop again ) (label4) execute _jmp (label1) ( Execute and loop again ) (label3) drop count _gethex ( Get number ) state @ _jz (label1) ( Loop again if not compile mode ) _lit _lit , , _jmp (label1) ( Otherwise, compile number and loop again ) (label2) drop refill _jmp (label1) ( Refill and loop again ) ; The boot interpreter compiles init.fth, which then runs the main interpreter. The main interpreter performs some error handling by checking for undefined words and stack underflows. It also handles negative numbers and numbers in any base. SOURCE PROGRAMS There are a number of additional Forth source programs included in this distribution that can be run by pfth. Open and read these as text files to learn more details. comus.fth provides a several useful non-standard words that are commonly used. starting.fth contains samples of code from the "Starting Forth" tutorial. rc4time.fth implements the RC4 code included in the Wikipedia Forth entry. It also displays the time required to run the RC4 code. i2c.fth is a Forth implementation of Mike Green's basic_i2c_driver from the OBEX. fds.fth implementes some of the functions from the FullDuplexSerial driver. It uses the binary PASM code from FullDuplexSerial. toggle.fth will start up a cog running the Forth interpreter. It toggles P15, but it can easily be modified to toggle another pin. STARTING COGS Forth cogs are started with cognew or coginit by specifying the Forth cog image as the execution pointer and a 5-long structure as the data pointer. The 5-long structure is defined as follow First long: Address of the body of a word that will be executed on startup Second long: Initial value of the stack pointer Third long: Address of the beginning of the stack Fourth long: Initial value of the return stack pointer Fifth long: Address of the beginning the the return stack