245 lines
10 KiB
Plaintext
245 lines
10 KiB
Plaintext
|
pfth Version 1.02
|
||
|
August 19, 2013
|
||
|
Dave Hein
|
||
|
(with additions from G. Herzog)
|
||
|
|
||
|
INTRODUCTION
|
||
|
------------
|
||
|
|
||
|
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, and 38 of the 45 core ext
|
||
|
words. pfth will run on any Propeller board that supports the standard serial
|
||
|
interface. The default settings of the serial port are 115200 baud, 8 bits, no
|
||
|
parity and 1 stop bit.
|
||
|
|
||
|
After loading and communications is established, use 'words' to verify that the
|
||
|
display is correct. The CR word is defined to emit both a carriage return and
|
||
|
a line feed. If your terminal displays an extra line you can either disable
|
||
|
the linefeed character on your terminal, or re-define CR to only emit a
|
||
|
carriage return.
|
||
|
|
||
|
|
||
|
VERSIONS OF SPIN FILES
|
||
|
----------------------
|
||
|
|
||
|
There are four versions of pfth.
|
||
|
|
||
|
The first 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.
|
||
|
|
||
|
A second 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 third version is named ospfth.spin, and runs under the Spinix operating
|
||
|
system. When Spinix starts up pfth it provides information about the SD pins,
|
||
|
the current working directory and a parameter list. The OS version of pfth
|
||
|
uses this information to initialize the SD card driver and change to the
|
||
|
working directory. It includes the file given by the parameter list.
|
||
|
|
||
|
The final version is called chess.spin, and implements a chess program. After
|
||
|
the program is loaded type "chess" to start playing. A move is entered by
|
||
|
typing the source and destination postions separated by a "-". As an example,
|
||
|
the move "D2-D4" will move the white queen's pawn two spaces ahead.
|
||
|
|
||
|
|
||
|
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.
|
||
|
|
||
|
Some of the kernel words are shown below.
|
||
|
|
||
|
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
|
||
|
swap
|
||
|
dup
|
||
|
|
||
|
|
||
|
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 16-bit 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.
|
||
|
|
||
|
ted.fth - a simple line-oriented text editor based on the ED text editor.
|
||
|
|
||
|
linux.fth - implements some basic linux commands, such as ls, cat, rm and cp.
|
||
|
|
||
|
|
||
|
STARTING FORTH 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
|
||
|
|
||
|
|
||
|
CELL SIZE
|
||
|
---------
|
||
|
|
||
|
The cell size for pfth is 32 bits. The words !, @ and "," words access 32-bit
|
||
|
values that are 32-bit aligned. Additional words are provide for smaller unit
|
||
|
access, such as w! and w@ for word access, and c! and c@ for byte access.
|
||
|
|
||
|
The compiled list cell size is 16 bits. The compile, word must be used when
|
||
|
compiling execution tokens into a list rather than just using the "," word.
|
||
|
|
||
|
|
||
|
DICTIONARY ENTRY FORMAT
|
||
|
-----------------------
|
||
|
|
||
|
The format for the pfth dictionary entry is shown below. The beginning of a
|
||
|
word entry and its body are long-aligned. The link pointer contains the
|
||
|
address of the previous word in the dictionary.
|
||
|
|
||
|
The flags byte contains various flag bits that indicate if the word is an
|
||
|
immediate word, a literal number or string, or a jump word. The name length
|
||
|
byte and the name string specify the name of the word. It is followed by
|
||
|
padding bytes that ensure long alignment.
|
||
|
|
||
|
The code pointer contains the cog address of the PASM code that is to be
|
||
|
executed. The execution token for a word points to this field. The does>
|
||
|
pointer contains the hub address of a list of execution tokens that is to be
|
||
|
called.
|
||
|
|
||
|
The body is a variable length field that contains the contents of a variable or
|
||
|
the list of execution tokens for a compiled word. The list for a compiled word
|
||
|
consists of one execution token per word, and is terminated by a zero-valued
|
||
|
word.
|
||
|
|
||
|
Offset Content Size
|
||
|
------ ------- ----
|
||
|
0 Link Pointer word
|
||
|
2 Flags byte
|
||
|
3 Name Length byte
|
||
|
4 Name String Len bytes
|
||
|
4+Len Padding (-Len) & 3 bytes
|
||
|
4+(Len+3)&(-4) Code Pointer word
|
||
|
6+(Len+3)&(-4) DOES> Pointer word
|
||
|
8+(Len+3)&(-4) Body Variable
|
||
|
|