Forth850
A fast Forth 2012 Standard system written in Z80 assembly for SHARP PC-G850 pocket computers. Plus new fast Z80 IEEE754 math libraries.
Install / Use
/learn @Robert-van-Engelen/Forth850README

A modern Forth 2012 standard compliant system for the vintage SHARP PC-G850(V)(S) pocket computer or any Z80 system (with a few tweaks to port).
Forth850 is under 8K and has 295 words.
A more complete 11K version forth850-full is also included with:
-
single precision floating point math words implemented with a new and efficient Z80 IEEE 754 floating point math library I wrote for Forth850. More floating point math functions that use this library are defined in Forth in examples/MATH.FTH
-
a more capable Forth line editor with replay back feature (cursor keys)
Forth850 includes stack under/overflow checks, dictionary overflow checks and can be interrupted by pressing BREAK.
You can write Forth source code in the PC-G850(V)(S) built-in TEXT editor and compile it into Forth850 with the TEXT word included in the full version.
You can extend Forth850 as you wish, including assembly code written on the
machine itself in the PC-G850(V)(S) TEXT editor and assembled with its Z80
Assembler. See ASMDEMO1.FTH for an example with an
explanation. You can also use the Monitor to set breakpoints and run Forth850
from the Monitor with G100 to trigger them.
If you want to rebuild Forth850 from source code, you will need to install the asz80 assembler part of the ASxxxx Cross Assemblers.
If you plan to use parts of Forth850 and/or the optimized Z80 code in a project that you plan to share or redistribute, then please give me credit for my work as per BSD-3 license.
Performance
I've implemented Forth850 as efficiently as possible in direct threaded code (DTC) with new Z80 code written from scratch, including faster Z80 integer and float math routines compared to other Z80 Forth implementations. See the technical implementation sections why Forth850 is fast for a DTC implementation. The Forth850 source code is included and extensively documented.
The n-queens benchmark is solved in 0.865 seconds, the fastest Forth implementation of the benchmarks. Forth850 n-queens runs 5 times faster than the C n-queens benchmark on the Sharp PC-G850VS.
Installation
In RUN MODE enter MON to enter the Monitor, then enter USER3FFF to reserve
16K memory space:
*USER3FFF
FREE:0100-3FFF
Loading via SIO (serial) requires a serial adapter. See my post on the
HP Forum
how to construct one as a DIY project. After reserving memory in the Monitor
as described above, use the R command to read the forth850.ihx file or the
forth850-full.ihx full version sent from your PC to your PC-G850(V)(S):
*R100
The R command is used to transmit/receive data in Intel hex format over SIO.
This command is for receiving machine code from a personal computer or other
device. See the Sharp PC-G850(V)(S) manual.
To load via the cassette interface, press BASIC to return to RUN MODE. Load
forth850.wav using a cassette interface CE-126P or a CE-124:
BLOADM
Load the forth850-full.wav "full version" to include many additional words and floating point words. The full version will continue to evolve with new features.
How to switch between Forth and BASIC
To return to Forth, enter CALL256 in RUN MODE.
To return to BASIC from Forth, press the BASIC key. The TEXT key takes you to the TEXT editor.
To turn the machine off, press the OFF key. The machine will also power off automatically after about 10 minutes waiting for user input at the prompt.
How to increase or decrease memory allocation for Forth850
Memory allocation can be adjusted without affecting the Forth dictionary.
In RUN MODE enter MON to enter the Monitor, then enter USERaddr with an
upper address addr larger than 23ff (9K bytes.) If words are added to
Forth850, you must make sure that addr is large enough, i.e. equal or larger
than the hex value displayed with:
HERE #708 + HEX . DECIMAL
23FF
In the Monitor specify USERaddr with the address displayed. This leaves
about 200 bytes free dictionary space plus 40 bytes for the "hold area" to run
Forth850. The largest size is USER75FF which gives about 21K free dictionary
space (but there won't be space left on the machine for files, BASIC or TEXT.)
Forth850 manual
Forth850 is 2012 standard compliant. For help, see the manual included with Forth for the Sharp PC-E500(S) and Forth 2012 Standard.
Forth850 implements a subset of the standard Forth words. A list of Forth850 words with an explanation is given below.
Forth850 words
List of Forth850 built-in words. Reference implementations in Forth are included when applicable, although many words are implemented in Z80 code for speed rather than in Forth.
(:)
-- ; R: -- ip call colon definition; runtime of the : compile-only word
(;)
-- ; R: ip -- return to caller from colon definition; runtime of the ; compile-only word
(EXIT)
-- ; R: ip -- return to caller from colon definition; runtime of the EXIT compile-only word
(;CODE)
-- ; R: ip -- set LASTXT cfa to ip and return from colon definition; a runtime word compiled by the DOES> compile-only word
(DOES)
addr -- addr ; R: -- ip calls the DOES> definition with pfa addr; a runtime word compiled by the DOES> compile-only word coded as call dodoes
(VAR)
-- addr leave parameter field address (pfa) of variable; runtime word of a VARIABLE coded as call dovar
(VAL)
-- x fetch value; runtime word of a VALUE coded as call doval
(2VAL)
-- dx fetch double value; runtime word of a 2VALUE coded as call dotwoval
(CON)
-- x fetch constant; runtime word of a CONSTANT coded as call docon
(2CON)
-- x fetch double constant; runtime word of a 2CONSTANT coded as call dotwocon
(DEF)
-- execute deferred word; runtime word of a DEFER coded as call dodef
(LIT)
-- x fetch literal; runtime word compiled by EVALUATE, INTERPRET and NUMBER
(2LIT)
-- x1 x2 fetch double literal; runtime word compiled by EVALUATE, INTERPRET and NUMBER
(SLIT)
-- c-addr u fetch literal string; runtime word compiled by S" and ."
0
-- 0 leave constant 0
0 CONSTANT 0
1
-- 1 leave constant 1
1 CONSTANT 1
-1
-- -1 leave constant -1
-1 CONSTANT -1
BL
-- 32 leave constant 32 (space)
#32 CONSTANT BL
PAD
-- c-addr leave address of the PAD; the PAD is a free buffer space of 256 bytes not used by Forth850
TIB
-- c-addr leave address of TIB; the terminal input buffer used by Forth850
TMP
-- c-addr leave address of the next temp string buffer; switches between two string buffers of 256 free bytes each; used by S" to store a string when interpreting
DROP
x -- drop TOS
DUP
x -- x x duplicate TOS
?DUP
x -- x x or 0 -- 0 duplicate TOS if nonzero
SWAP
x1 x2 -- x2 x1 swap TOS with 2OS
OVER
x1 x2 -- x1 x2 x1 copy 2OS over TOS
ROT
x1 x2 x3 -- x2 x3 x1 rotate cells
: ROT >R SWAP R> SWAP ;
-ROT
x1 x2 x3 -- x3 x1 x2 undo (or back, or left) rotate cells
: -ROT ROT ROT ;
NIP
x1 x2 -- x2 nip 2OS
: NIP SWAP DROP ;
TUCK
x1 x2 -- x2 x1 x2 tuck TOS under 2OS
: TUCK SWAP OVER ;
2DROP
xd1 xd2 -- xd1 drop double TOS
: 2DROP DROP DROP ;
2DUP
xd -- xd xd duplicate double TOS
: 2DUP OVER OVER ;
2SWAP
xd1 xd2 -- xd2 xd1 swap double TOS with double 2OS
: 2SWAP ROT >R ROT R> ;
: 2SWAP 3 ROLL 3 ROLL ;
2OVER
xd1 xd2 -- xd1 xd2 xd1 copy double 2OS over double TOS
: 2OVER >R >R 2DUP R> R> 2SWAP ;
: 2OVER 3 PICK 3 PICK ;
DEPTH
-- u parameter stack depth
: DEPTH sp0 @ SP@ - 2- 2/ ;
CLEAR
... -- purge parameter stack
: CLEAR sp0 @ SP! ;
.S
-- display parameter stack
: .S DEPTH 0 ?DO sp0 @ I 2+ CELLS - ? LOOP ;
SP@
-- addr fetch stack pointer
SP!
addr -- store stack pointer
>R
x -- ; R: -- x move TOS to the return stack
DUP>R
x -- x ; R: -- x duplicate TOS to the return stack, a single word for DUP >R
R>
R: x -- ; -- x move cell from the return stack
RDROP
R: x -- ; -- drop cell from the return stack, a single word for R> DROP
R@
R: x -- x ; -- x fetch cell from the return stack
2>R
x1 x2 -- ; R: -- x1 x2 move double TOS to the return stack, a single word for SWAP >R >R
2R>
R: x1 x2 -- ; -- x1 x2 move double cell from the return stack, a single word for R> R> SWAP
2R@
R: x1 x2 -- x1 x2 ; -- x1 x2 fetch double cell from the return stack
RP@
-- addr fetch return stack pointer
RP!
addr -- store return stack pointer
PICK
xu ... x0 u -- xu ... x0 xu pick u'th cell from the parameter stack; 0 PICK is the same as DUP; 1 PICK is the same as OVER
: PICK 1+ CELLS SP@ + @ ;
@
addr -- x fetch from cell
C@
c-addr -- char fetch char
2@
addr -- x1 x2 fetch from double cell
: 2@ DUP CELL+ @ SWAP @ ;
!
x addr -- store in cell
(TO)
x -- store in value; runtime of t
