1616: Forth Manual

Version 0.107
March, 1999

Applix 1616 microcomputer project Applix pty ltd

1616 Forth Manual

Even though Applix has tested the software and reviewed the documentation, Applix makes no warranty or representation, either express or implied, with respect to software, its quality, performance, merchantability, or fitness for a particular purpose. As a result this software is sold "as is," and you the purchaser are assuming the entire risk as to its quality and performance.

In no event will Applix be liable for direct, indirect, special, incidental, or consequential damages resulting from any defect in the software or its documentation.

The original version of this manual was written by Peter Fletcher Additional introductory and tutorial material by Eric Lindsay Comments about this manual or the software it describes should be sent to:

Applix Pty Limited
324 King Georges Road
Beverly Hills 2209
N.S.W. Australia
(02) 758 2688

© Copyright 1986 Peter Fletcher and Applix Pty Limited. All Rights Reserved.

Revised material © Copyright 1990 Eric Lindsay

ISBN 0 947341 ?? ?

MC68000®™ is a trademark of Motorola Inc.

Table of Contents

1	Getting started with FORTH 	
	The Stack	
	Arithmetic	
	Simple Programs	
	More stack words	
	Arithmetic Words 	
	Printing words	
	Input/Output words	
	Useful words	
	Variables etc	
	Structured Statements 	
	Dictionary	
	Return stack	
	Memory management	
	Structured and unstructured statements	
	do/loop 	
	if/else/then 	
	begin/while/until/again/repeat 	
	case/:-/|/default/endcase	
	goto/label:/return 	
	Writing programs with the editor	
	Saving programs to disk	
	Using Variables	
	Constants	
	Variables	
	Automatics	
	Local variables and recursion	
	Structures and Arrays 	
	The return stack	
	Testing and debugging	
	Error messages	
	Trace mode	
	Altc and stack checking 	
	Coding conventions	
	Nesting	
	Word names	
	Vocabulary names	
	Using help.f 	
	Library files	
	Immediate words	
	Bugs
2	Kernel words									
	FORTH memory map: 								
	Suggested format for .f files							
	Quick reference: 								

3	File manipulation words, in file.f 						
	Summary 									

4	Floating point words, in float.f 						
	Summary 									
	Floating point format: 								

5	Turn off VIA interrupts, irqkill ( -- ) 					

6	Screen/Graphics words								
	Summary 									
	Window examples									
7	The files on the Forth disk are: 						
8	The Last Read Me file

Getting started with FORTH

To start up FORTH from the /bin directory, type (ignoring the prompt):

f0//bin>ff

This is a loader program which will allocate memory for FORTH, load it in and execute it.

FORTH will clear the screen and print a startup message. If it doesn’t, check that you’ve got the disk in the correct drive and you’re in the correct directory.

Now that FORTH has been loaded in, we can start to experiment.

Forth is typically somewhat uncommunicative in its responses. All you will see on the screen after most commands is the interactive Forth prompt, which is > . Type in a few numbers, leaving a space between each. Forth accepts a space as its input delimiter, so spaces are very important. Everything separated by spaces is either a number, or a Forth ‘word’ (a subroutine).

>4 5 6 7 Enter
>

Not very exciting, is it? All that happened is that the numbers were put on the ‘parameter stack’ (which is an area of memory pointed to by register A6, for those of you into assembler). In fact, this is all Forth ever does with any number that you enter. This simple concept helps make Forth relatively easy to implement. By the way, in future, we won’t show the Enter key at the end of each line, but don’t you forget it.

To get rid of these four entries, type (don’t forget, the > you see is merely the prompt, you don’t type that).

>drop drop drop drop

Congratulations, you just entered your first Forth ‘word’. As we mentioned, each Forth word is the equivalent of an assembler subroutine. In this case, it is simply addq #4,a6 , which just moves the parameter stack pointer so that it ignores the top 32 bit number on the stack (not that you really need to know why it works yet).

The Stack

All operations FORTH performs rely upon its ‘parameter stack’. This is a simple last-in-first-out stack which stores 32 bit values. Let’s give it a try. Try typing:

>1 2 3

When you press return, nothing happens. However, you have put three values on the parameter stack. You can print them one at a time, if you type ‘.’ (spoken as ‘dot’) and press return:

3
>.
2
>.
1

(Why do they come out backwards ?)

‘.’ is a FORTH ‘word’. All FORTH programs (words) are built out of smaller words (programs). We’ll see how to define them later.

The stack is now empty - what happens if you try to print one more value?

>.
 [some number]
?Stack underflow.
>

You’ll probably see this message a lot when you’re trying things out. Unfortunately, FORTH doesn’t do too much of this sort of checking when it’s running, so if you’re careless you can crash the machine very easily. Don’t worry - you can always reboot everything after such crashes, and any substantial work you’ve done should be in a file anyway.

Arithmetic.

Now let’s do some real computing; let’s add two numbers:

>1 5 + .
 6
>

Now we’re really getting places. The strange way FORTH does arithmetic is called ‘reverse polish notation’. You may recognize it from Hewlett Packard calculators.

Now let us try a more complex expression: 5*(3+7)*(3*(2+3))

FORTH doesn’t do arithmetic this way, so we’ll have to translate it into RPN. It takes a while to get used to, but it’s not hard when you’ve written a few programs this way.

>5 3 7 + * 3 2 3 + * * .
 750
>

There! It’s easy, isn’t it?

Simple Programs.

Now that we’ve mastered arithmetic (you could try ‘mod’, ‘/’, ‘-’ too), let’s start writing programs.

There’s a special FORTH word for defining more words; it’s the colon: ‘:’. Let’s try it. Remember to type all the spaces:

>: first_word
>1000000 * .
>

(Remember to type all the spaces)

Hey! Why didn’t FORTH print something when you entered the dot? Because the ‘: first_word’ made FORTH enter ‘compile mode’, where any words that you enter are ‘compiled’ instead of being executed. So, the million, the times and the dot have been compiled away somewhere. How do we tell FORTH that our word does everything we want it to do and finish the definition? We use another FORTH word, semicolon: ‘;’.

>;
>0 .
 0
>

So, we’re back to normal (by the way, if ‘;’ is just another FORTH word, why doesn’t FORTH just compile it, too???). Lets try executing our newly defined word:

>42 first_word
 42000000
>

Our very first word multiplies numbers by a million! Nifty, huh?

More stack words.

After all that excitement, it’s time to get back to the parameter stack. Try this:

>1 2 3 4 5
>.s
1 2 3 4 5
>

‘.s’ is a word which prints out the parameter stack, bottom element first. It does not affect the stack in any way, so it’s useful to see what’s on the stack. Now try these new words:

>abort
>.s

‘abort’ seems to clear the parameter stack (but it does a lot more- see later).

>42 dup .s
 42 42
>32 swap
 42 32 42
>over .s
 42 32 42 32
>+ .s
 42 32 74
>rot .s
 32 74 42
>drop drop .
 32

Try and work out what nip, tuck, rot-, 2dup, pick and roll do. We’ve now learnt the main stack words. A complete list is:

dup swap over rot rot- drop
2dup 2swap 2drop
nip tuck
roll pick

Now you’ve got a start, look in the file kern.txt , where all the kernel words are explained. An incomplete list is given here.

Arithmetic Words

+ - * / mod ~ abs min max
*q /q
1+ 2+ 3+ 4+ 5+ 6+ 7+ 8+
1- 2- 3- 4- 5- 6- 7- 8-
2* 4* 8* 16*
2/ 4/ 8/ 16/
base hex decimal

Printing words.

.
.s
."
.str type

Input/Output words.

expect dexpect pad
fopen fclose
fget fput fgetc fputc

Useful words.

load save words
trace+ trace-
debug+ debug-
echo+ echo-
altc+ altc-
edit delete dir ]
load? forget? vocab

1-4 Forth Getting started with FORTH

-->

Variables etc.

constant variable automatic struct ends string
array arraym
larray larraym uses
dconst dauto
@ ! +! to
w@ c@ d@ w@x
w! c! d!
addr.of size.of
locals|
base0 base1
chk+ chk-

Structured Statements

do .. loop i j
if .. then
if .. else .. then
begin .. again
begin .. until
begin .. while .. repeat
case
.. :- .. |
.. :- .. |
.. => ..
endcase
dropcase dropdo case@
return
label: goto

Dictionary.

find search dsearch vdel forget dict
allot literal , ,l next@ next! ’
compile code

Return stack

>r <r r1 r2 r3 r4 dropr
mlink

Memory management.

link link@ unlink allocmem freemem allot
mem

Structured and unstructured statements.

FORTH allows all the structures of most common languages, yet it takes a little while to get used to the strange order in which words are specified.

do/loop

One of the most common operations in any language is looping. FORTH has several ways of looping, and the most often used is the ‘do/loop’ loop, which is very similar to the for/next loop in BASIC. To see how fast FORTH can do nothing, try the following:

>: do1000000
> 1000000 1 do loop ;
>do1000000

It’s pretty fast! However, it’s not often we need to do nothing, so lets try something more useful: we’ll read in ten numbers and print their sum.

>: add10
>  0
>  10 1 do
>         i +
>  loop ." The sum of the first ten numbers is:" . ;
>add10
The sum of the first ten numbers is: 55
>

(Try entering this word with tracing enabled)

The loop indexes must be specified backwards (largest number first). If you want to loop down instead of up, or want a step other than one, use ‘+loop’ or ‘-loop’.

if/else/then

To make decisions with FORTH, there is an if/then statement. Remember that everything is backwards with FORTH: you must do everything in the right order:

{condition} if {condition true statements}
else {condition false statements}
then
{etc.}

The ‘else’ part may be left out.

>: doif
>  cget asc a = if
>         ." An ’a’ was pressed"
>  else
>         ." An ’a’ was not pressed"
>  then ;
begin/while/until/again/repeat

The word ‘begin’ is used in combination with while, until, repeat and again. However, these four words may not be mixed and matched indiscriminately; the allowable combinations are:

begin {body1} {condition} while {body2} repeat
begin {body} again
begin {body} until

To show what these words do, here are a few examples. Be careful with the first one; it goes for some time! The stuff between ( brackets ) is comments.

: star_forever ( print lots of stars )
  begin asc * emit again ;
: star_key ( print stars ’til key pressed )
  begin asc * emit c? until ;
: keys_prt ( print keypresses while altc not pressed )
  begin cget
          dup 0>= while ( altc? )
          emit
  repeat ;> 
case/:-/|/default/endcase.

The case statement is useful when many choices have to be made from one piece of data.

: case1
  cget
  case
	asc 1 :- ." one"	|
	asc 2 :- ." two"	|
	asc 3 :- ." three"	|
	asc 4 :- ." four"	|
	asc 5 :- ." five"	|
	asc 6 :- ." six"	|
	asc 7 :- ." seven"	|
	asc 8 :- ." eight"	|
	asc 9 :- ." nine"	|
	asc 0 :- ." zero"	|
	default :- . " Not a digit."
  endcase ;

Note that the last choice does not have a terminating ‘|’. If the default case is left out and the choice does not appear in the list, the ‘case’ statement does nothing. If you need to get out of a case statement, you need to use ‘dropcase’ along with ‘return’ or ‘goto’.

The case statement is not smart; it simply checks the conditions in the order that they are entered. However, this makes it possible to simply check a flag in a case statement; see ‘=>’.

goto/label:/return

If you need to do something out of the ordinary, such as exiting upon an error condition, ‘goto’, ‘label’ or ‘return’ may be used. They need some care in their use, because many words temporarily store information on the return stack, which is where FORTH stores the return address to the word that called the word it is currently executing; if you write a ‘goto’ or ‘return’ that does not take care of this extra stuff on the return stack, the poor 68000 will attempt to return to an address given by a piece of data, which is not likely to do good things.

: spaghetti
  1 .
  goto fred
  ( this code is never executed )
  9999 .
label: fred
  2 .
  goto count
label: mary
  i .
  i 5 = if dropdo crlf ." Done." return then
  goto jill
label: count
  5 3 do
	goto mary
label: jill
loop
(this code is never executed either)
9999 . ;

As you can see, goto should be used rarely (if at all). If for some reason a label is never specified for a ‘goto’, the goto statement will do nothing. There is nothing to stop you ‘goto’ing between words, but this is asking for trouble. Writing programs with the editor.

Let’s now try writing a program to print a times table. When writing any programs larger than a few lines, it’s better to edit them in a file so you can change them easily (it also means you can load them again later on). If you’re lazy, you could peek ahead and load the file ‘demo1.f’.

Try the following:

>edit forth1.f

You should now be in the editor. If you don’t want to write on your FORTH disk, you should put in a blank formatted disk at this stage. Now try entering the following program:

forget? forth1
vocab forth1
: timestab	( -- | print a five times table )
( ----- print start message )
  crlf
  ." This is a times table for numbers from 1 to 5." crlf
  crlf
( ----- print a header )
  tab rvson
  5 1 do
          i . tab
  loop rvsoff crlf
( ----- print the table )
  5 1 do
  rvson i . tab rvsoff		( ----- print first number )
	  5 1 do
		    i j * . tab	( ----- print table )
	  loop
	  crlf			( ----- start a new line )
  loop ;
interactive

What you’ve just entered needs a little explaining. The first line, ‘forget? forth1’, tells FORTH that a new vocabulary is being loaded, so if there is already anything by the name of ‘forth1’, it would be best forgotten. This allows the same file to be loaded lots of times in between edits, so there are no problems with words being redefined.

The next line, ‘vocab forth1’, tells FORTH that a new vocabulary called ‘forth1’ is being started in the dictionary.

The next lines form a colon definition for a word to print a times table. The last line, ‘interactive’, tells forth that the current file it’s reading has come to an end, so it should close the file and return to the user (or the previous file it was reading).

In the actual definition of ‘timestab’, several things should be noted. On the line the definition opens, ‘( -- | etc’ appears. This is simply a comment, but it serves an essential purpose. Firstly, it explains what the word does. Just as importantly, however, it shows what the word expects on the stack before it executes, and shows what the word will leave. Every word you write should have such a comment. The definition is spread liberally with comments, which for a word such as this are probably not necessary. However, FORTH code is reknowned for its impenetrability, so a few comments here and there cannot hurt. Unlike most languages, comment brackets may be nested successfully. Now, exit the editor and you will be returned to the FORTH prompt. Load the file you’ve just entered with:

>load forth1

If any error messages occur, or things don’t seem to work any more, try the fol- lowing:

>abort	( just in case )
>;		( in case you’ve left off the semicolon )
> ) ) )	( in case you’ve left some comments open )
>system	( if things are really bad )
reset button!	(FORTH is not extra forgiving)

You can see the new vocabulary in place by typing:

>words
forth1
sys
kern2
kern1
>words forth1
timestab {perhaps more words}
>

‘words’ allows you to list all vocabularies, or, if a vocabulary is specified, all words in a vocabulary. Try the following:

>words sys
>words kern2 i
>words *

Now you can try executing the new word:

>timestab

A beautiful times table should appear.

Saving programs to disk.

Rather than loading words from disk all the time, you may wish to save your current FORTH environment to disk. Just by typing

>save

you will have a copy of your current FORTH environment on disk, ready to be reloaded (Be careful: it will be given the name ‘forth’ unless you change the values if the string variables ‘name’ and ‘vname’.

If you want to create turnkeyed applications, look up ‘turnkey’ and ‘word1’.

Using Variables.

Constants.

FORTH has several types of variables. The simplest is not a variable at all. Try this:

>1000000 constant 1million >1million . 1000000

A constant can be used whenever you would enter a number. Constants are convenient, but they are slightly more expensive than entering straight numbers in terms of both speed and storage.

Variables.

The standard FORTH variable can be created with the FORTH word ‘variable’:

>variable a
>a .
24738

This number (which may be different when you try it) is the address of variable ‘a’. To access the contents of ‘a’, you need to use two words to access a’s contents. The first of these, ‘!’ (’store’), stores a value in ‘a’. The second, ‘@’ (’get’ or ‘load’) retrieves a’s contents.

>56 a !
>a dup @ . .
56 24738

‘@’ and ‘!’ are not used just for variables; they can be used for arrays, structures or anything else you put them to use on. These words always load four bytes (a longword) from the address you give to them, so if you accidentally pass them garbage you’ve got a good chance of causing an address error exception, which is very time consuming. Use them with a bit of care, and they’ll give you no trouble.

When using arrays and structures, allocating four bytes to each element is very expensive on memory usage. FORTH allows bytes and words to be loaded and stored just as easily, using the words ‘w@’, ‘c@’, ‘w!’ and ‘c!’.

Automatics.

Automatic variables, although not standard FORTH, are faster, smaller and easier to learn than standard variables. They also use the same syntax as local variables, which are explained later.

>automatic z
>zz .
9999

Automatic variables do not need the ‘@’ word; they leave their value on the stack as soon as they are executed. Some value had to be stored in z when it was initialized, and so 9999 was used because it was not zero. How do we store values in automatics ?

>-57 to z
>z .
 -57
<--

Getting started with FORTH Forth 1-11 -->

Local variables & recursion.

Another sort of FORTH variable is the ‘local variable’. Local variables are a little trickier to use than the other sorts, but they have many advantages. They are faster again than automatic or standard variables, and allow FORTH to execute truly recursive algorithms. No storage space is allocated to local variables in either the dictionary or the code area, so they keep your vocabularies compact and neat. However, local variables are only ‘alive’ in the word in which they are defined, so their use is only local to the word in which they are defined.

Try this:

: fibonacci ( n -- fib(n) | calculate fibonacci number )
locals| fibo |	( get (n) from the stack )
( ----- zero or negative fibonacci number is a nono! )
fibo 0<= if
	" Cannot get fibonacci of negative or zero number!"
	error
then
( ----- fib(1) or fib(2) equals 1 )
1 fibo =
2 fibo =
or if
	1
else
	fibo 1- fibonacci ( calculate fib(n-1) )
	fibo 2- fibonacci ( calculate fib(n-2) )
	+
then ;

This word demonstrates the power of local variables. The same word could have been written using only the parameter stack, but it would have had lots of dup’s and drop’s, and would have been more difficult to fathom. Give it a try! However, this word is quite a heavy stack user (and very inefficient, the way it is written), so you may need to resize the parameter stack. The default parameter stack size is 256 entries (or 1024 bytes). To increase the stack size to 10000 entries, enter

>free .
 222482
>40000 resize
>free .
 183506

This example of recursion is about as complex as you’d normally need. However, if you’re into writing mutually recursive words, look up ‘::’.

Now let’s try a different application:

thingo ( n p -- | print n to the p’th power )
1 locals| a power n |
power if
	power 1 do
		a n * to a
	loop
then
n . ." to the" power . " ’th power is: " a . ;

Note that local variables are listed in the opposite order to their initializing values on the stack, and a’s initial value (1) was put into the word definition, and is not passed to it when calling ‘thingo’. ‘to’ is used to give a local variable a new value, just as with automatics. If you need to find the address of a local variable (or an automatic), use ‘addr.of’.

Structures and Arrays

FORTH allows structures to be defined with ‘struct’:

struct complex
	long:	.real
	long:	.imag
ends

Now the word ‘complex’ can be used just like ‘variable’, ‘automatic’ and ‘constant’:

complex z1

Let’s see how to use them:

complex z1
complex z2
complex result
: c*	( complex1 complex2 -- | multiply two complex structures. Return in ‘result’. )
	locals| c2 c1 |
	c1 .real @
	c2 .real @ *
	c1 .imag @
	c2 .imag @ * ~
	+ result .real !

	c1 .real @
	c2 .imag @ *
	c1 .imag @
	c2 .real @ *
	+ result .imag !

	result ;

Now we’ll try it out:

>1 z1 .real !
>1 z1 .imag !
>5 z2 .real !
>3 z2 .imag !
>z1 z2 c*
>result .real @ .
 2
>result .imag @ .
 8

The field words, ‘.real’ and ‘.imag’ simply add an offset to the base address of the structure, and ‘z1’ and ‘z2’, just like standard variables, return the address of their contents.

To create an array, we use the word ‘array’. Firstly you must specify the size of each element, then the number of elements.

Arrays either start at element 0 or element 1, depending on which of ‘base0’ or ‘base1’ has been specified before declaring the array. If ‘chk+’ is executed before the array is defined, code will be compiled into the array definition to check the bounds of the array.

>chk+
>base1
>size.of complex 10 array zfred
>0 fred
?Bad array index.
>0 1 fred .real ! ( store 0 in fred[1].real )
>0 1 fred .imag ! ( store 0 in fred[2].imag )
>11 fred
?Bad array index.
>

To save space in the object area, there is another type of array: the ‘larray’. This array is defined exactly as with a normal array, but no space is allocated for it when it is declared. Space is allocated with the word ‘uses’, and the storage space for the array will remain around for as long as the word which ‘uses’ it is executing.

>chk+ base1
>1 80 larray characters
>: get80
>   uses characters
>   80 1 do
>		cget dup emit
>		dup 13 = if
>			drop 0 i characters c! lastdo
>		else
>			i characters c!
>		then
> loop
> 80 1 do
>		i characters c@ if
>			i characters .str crlf
>		else
>			lastdo
>		then
> loop ;
>get80
Type something!
ype something!
pe something!
e something!
something!
something!
omething!
mething!
ething!
thing!
hing!
ing!
ng!
g!
!

The return stack.

When writing FORTH words, it is convenient to be able to stash away a value (or several values) somewhere else temporarily. One way to do this is with the ‘return stack.’ There are several FORTH words to push, pop and examine the top of the return stack.

‘>r’ and ‘<r’ push and pop values to the return stack ‘r@’ looks at the top element on the return stack ‘dropr’ drops the top element on the return stack ‘r1’, ‘r2’, ‘r3’ and ‘r4’ look at the first, second, third and fourth element on the return stack (‘r1’ is equivalent to ‘r4’).

Testing and debugging.

FORTH is notoriously unforgiving. However, to compensate partially for this fact, 1616 FORTH has a number of features to allow debugging a little easier.

Error messages

As an aid to debugging, FORTH prints lots of warning messages when you do something wrong (if it doesn’t crash). The most often encountered is the ‘whazzat’ error:

>nosewash
nosewash?
>
This error message does not appear very useful, but all it is saying is that ‘nosewash’
is not a word in FORTH’s vocabulary.
The ‘whazzat’ error occurs at other times, but it usually appears in conjunction
with other error messages.
The other messages that you may find are the following:
?Definition word only.

Some words may only be used in colon definitions. If you attempt to use this word in direct mode, this error will be generated. If this word occurs while loading a file that looks OK, check that ‘interactive’ appears at its end.

?Stack mismatch in colon.

A compound statement (such as if/then, begin/until) was incorrectly nested.

?Division by zero.
Division by zero. Note that ‘/q’ will generate a genuine 68000 exception,
as it uses the ‘DIVU’ instruction.
?Double local definition.
Only one locals| definition is allowed per word.
?Out of memory.
An attempt was made to ‘link’ or ‘allot’ more memory than was available.
Use ‘free’ to find out how much space is available.
?Bad stack in load.
When a file is loaded, it must leave the parameter stack in the same state
as when the load began (file nesting information is stored on the parameter
stack).
?EOF in load.
’interactive’ was not encountered before a forth file ended.
?No file.
File not found when attempting to load. If multiple files are being loaded,
turn on file echoing with ‘echo+’ to see where in the load the error occurs.
Break.
Either altc was pressed with altc checking turned on (altc+), or an ‘altc’
was executed while an altc was active, or a ‘stop’ was encountered. ‘cont’
can be used to continue from this point.
?Stack overflow. ?Stack underflow.
The stack over/underflowed. This condition is usually not checked for
when a word is executing, so if your program unexplainedly crashes,
underflow or overflow might be the cause. (See the description of ‘trace
mode’ below for help)
?Word not unique.
FORTH will not let you redefine a word that has already been defined.
If you need to do such a thing, turn this checking off with ‘unique-’.
Trace mode.
When initially developing a program, it would be nice to have a facility to
single-step code. This is possible by executing a ‘trace+’ before compiling your
code; when the code is called, each word will be displayed before it is executed,
and the 1616 will wait for a key. When a key is pressed, the contents of the stack
after execution of the word will be displayed and the next word printed. Pressing
‘space’ will execute 24 words before waiting for the next key.
If trace mode is turned off with ‘trace-’, none of this information will be displayed,
but altc and stack bounds will be checked after the execution of each word.
Altc & stack checking
Trace mode adds a large overhead to developing programs, so there is a mode
which allows stack and altc to be checked regularly, without the overhead.
Executing ‘altc+’ will turn this checking on; any programs compiled with this flag
turned on will have stack and altc checking compiled with them. The call to check
these things is added after every ‘do’ and ‘begin’ in the code.
If ‘altc’ is pressed while such a program is executing, the message "Break." will
be displayed and the prompt will appear as ‘~’. While the prompt looks like this,
a stopped program may be restarted with ‘cont’. You must ensure that the parameter
stack is the not changed when you continue a stopped word. If you do not wish
to continue execution of the word, enter ‘abort’.
Coding conventions.
The ideas mentioned here are not rules; they are not even followed rigourously in
the FORTH kernel. However, if you stick roughly to these conventions you should
find it much easier to read your own code (and that of anybody else).
Getting started with FORTH

Nesting.

It is useful when writing code to indent the program text to give some idea of
nesting level. One tab per nest is usually reasonable; if the code is being squashed
too far to the right, either breaking the word up into simpler components or using
a nesting level of four, say, would be reasonable.
Example:
: nest
10 1 do
	10 1 do
		10 1 do
			." 1000 times."
		loop
	loop
	crlf
loop ;
It’s also a good idea to break each line at logical breaks in the code, rather than
when the line begins to fill up. This is sometimes a rather arbitrary choice to make,
but as long as you’re consistent it should make it easier to read.
Word names.
All FORTH objects are built out of the same stuff, so it is necessary to give some
artificial guidelines to stick to to make different types of object recognizable.
%word	Automatic variables
$word	Constants
.word	Structure field names
(word)	Low-level words of minor importance
	(and some direct 1616 calls)
wordf	Floating point versions of standard words
word>	Codewriting words
word?	Words that leave flags or info on the stack
~@~	Words that load some object from memory
~!~	Words that store some object to memory
make_	Structure creating words
wword	Window words
Vocabulary names.
A vocabulary should be given the name of the file which contains it.
Using help.f
While you’re learning FORTH, you may find it hard to remember what all the
words in the vocabulary do. As an aid, you may want to load the file ‘HELP.F’
before you start work. To use this word, type:
>help {word}
Help will then scan through all the source files it knows about looking for a
definition of {word}. If it finds it, it will print out the first line of the definition
(which hopefully contains comments about the word’s use).
Alternatively, if you want to look at the definition of a FORTH word, use the word
‘list’ instead of ‘help’.
For either word, if you know the file the definition appears in, you may specify
the file name on the line with ‘help’:
>help wopenq screen.f
This will only scan the file screen.f
Library files.
If you want to write assembler routines for FORTH, a library loading word is
available in LIBLOAD.F.
Format of library file:
org	$0000
	dc.l	fin-start
start	{code}
	.
	.
	{code}
	dc.b	len,’word1’
	dc.l	label
	dc.b	len,’word2’
	dc.l	label2
	dc.w	0
	end
Immediate words.
Many words defined in the FORTH kernel are not compiled when they are used
in a colon definition, but execute while a word is being defined. Words such as
‘if’, ‘do’, ‘to’ and ‘;’ do their work as the words which use them are being compiled.
Some other words, such as ‘dup’, ‘>r’ and ‘1+’ are immediate words, yet all they
do is compile themselves into the word being defined. The reason this is done is
because such words may be compiled in two bytes rather than the usual four,
resulting in faster and smaller FORTH programs.
Getting started with FORTH
Forth 1-19
A word can be made immediate by executing ‘immediate’ immediately after it is
defined.
This concept takes a little getting used to, and is not necessary for writing most
FORTH programs. However, if you are interested in increasing FORTH’s pool
of structured statements, look at the definitions (in FORTH) of many of the kernel
words in the file WORDS.F, or even in the assembler source file FORTH.S.
Bugs.
FORTH is not perfect; however, none of the known ‘bugs’ which follow should
present too many difficulties if you’re aware that they exist.
‘do/loop’ statements are always executed at least once; if this is not desirable, it
is necessary to enclose the loop with an ‘if/then’.
Unlike standard FORTH, the highest loop index is counted as within the range of
a do loop: for example, ‘10 1 do’ executes ten times with 1616 FORTH, nine times
with standard FORTH.
Return stack overflow is not checked for with recursive calls, so a word which
calls itself indefinitely will cause a crash. Similarly, parameter stack over/under-
flow is not always checked for unless one of trace or altc modes are turned on.
If FORTH is very low on memory, (less than 32K is unsafe), using the editor or
transient programs may crash the machine.
When windows are open (using SCREEN.F) and an error occurs, an ‘abort’ should
be executed immediately to ensure that the current window structure is reset to the
default 1616 window.
When using the fast dot plotting routines (DOTFAST.F), the coordinates used are
always relative to the whole screen, rather than the current window. If the screen
may have scrolled, a ‘walign’ should be executed to ensure the CRTC scroll register
is zeroed.
68000 hardware exceptions, such as bus error, address error, zero divide will crash
the machine as expected.
Some operations of FORTH will move the return stack, which is a problem if any
absolute addresses (such as window structures) reference or occur inside the return
stack. These operations are:
i) A word added to the vocabulary, if the vocabulary space is full
ii) A ‘resize’ or ‘vocresize’
iii) Initializing the heap with the words in HEAP.F
However, all of these conditions can be avoided whilst a word is executing.

3 Kernel words

!		( val addr -- )
		See also:	@ c@ w@ w@x c! w! +!
		Stores the longword {val} at {addr}.
"		( -- str )
		Usage:		" {string}"
		See also:	." .str
		Immediate:
		Writes {string} into the dictionary and 
		leaves its address on the stack.
		Definition:
		Writes {string} into dictionary. 
		When code is executed, the string’s address is left on the stack.
%abase		
%achk		
%ccase		
%struct		( -- val )
		See also:	array case struct chk+ chk- base0 base1 larray
		Automatic variables used by case & structure declaring words.
’		( -- address )
		Usage:	’ {token}
		See also:		dict search
		Reads next token immediately and leaves its code address on the stack.
’c		( -- )
		Usage:		’c {token}
		See also:	’ compile
		Immediately read next token and compile it into the dictionary.
		Use this word to compile immediate words (such as if " dup etc.)
(		( -- )
		Usage:	( {comments} )
		Start of a comment. Comment is terminated with ‘)’.
		Comments may be nested and span multiple lines.

(.)		( n addr1 -- addr2 )
		See also:	. .str pad expect dexpect
		Converts the number {n} to a text string in the current base. 
		{n} is right justified in a 35 byte field at {addr1}; 
		{addr2} points to the first non-blank character of {n}.
		At least 36 bytes should be provided at {addr1}.

(do)		( -- )
		Word compiled by ‘do’.
*		( n1 n2 -- n1*n2 )
		See also:		*q /q mod
*q		( n1 n2 -- n3 )
		16x16 bit multiply using 68000 MULU instruction. Faster than *.
+		( n1 n2 -- n1+n2 )

+!		( n address -- )
		See also:	!
		Adds longword n to value at address.
+loop		( n -- )
		See also:	do loop -loop
		Adds n to loop counter, and if result is less than or equal 
		to loop terminator,
		branches back to corresponding ‘do’.
,	
-		
-loop
.
."
.card
.s
.str
/
/mod
/modq
/q
0<
0<>
0>
2-2 Forth
,l
( n -- )
See also:		code literal > >!l

Writes 16 or 32 bit value into object code area Use to put 68000 machine instructions into word definitions.

( n1 n2 -- n1-n2 )
( n -- )
See also:		do loop +loop
Subtracts n from loop counter, and if result is greater than or equal to the
loop terminator, branches back to the corresponding ‘do’.
( n -- )
See also:		number base (.) tab emit ."
Prints out value of n in current base.
( -- )
Usage:		." {string}"
See also:		" .str crlf
Prints {string}. May be used only in colon definitions.
( n -- )
See also:		. (.)
Write out n with no leading sign
( -- )
See also:		trace+
Nondestructively prints out contents of stack, lowest element first. Note
that this is opposite to some other Forths.
( string -- )
See also:		type
Prints null-terminated string.
( n1 n2 -- n1/n2 )
( n1 n2 -- (n1/n2) (n1 mod n2) )
32 bit divide & modulus.
( n1 n2 -- (n1/n2) (n1 mod n2) )
32 by 16 bit divide & modulus.
( n1 n2 -- n1/n2)
32 by 16 bit divide using 68000 DIVU instruction. Faster than /.
0<=
0=
0>=
( n -- f )
See also:		if until while
Test n and leave a flag on the stack. -1=true, 0=false.
Kernel words.1+
2+
3+
4+
5+
6+
7+
8+
1-
2-
3-
4-
5-
6-
7-
8-
2*
4*
8*
16*
256*
2/
4/
8/
16/
256/
2drop
2dup
2swap
:
:-
::
;
Kernel words.
( n -- n+1 )
( n -- n+2 )
( n -- n+3 )
( n -- n+4 )
( n -- n+5 )
( n -- n+6 )
( n -- n+7 )
( n -- n+8 )
( n -- n-1 )
( n -- n-2 )
( n -- n-3 )
( n -- n-4 )
( n -- n-5 )
( n -- n-6 )
( n -- n-7 )
( n -- n-8 )
( n -- n*2 )
( n -- n*4 )
( n -- n*8 )
( n -- n*16 )
( n -- n*256 )
( n -- n/2 )
( n -- n/4 )
( n -- n/8 )
( n -- n/16 )
( n -- n/256 )
See also:		+ - * / /mod /q /modq *q >> << >>x
( n1 n2 -- )
( n1 n2 -- n1 n2 n1 n2 )
( n1 n2 n3 n4 -- n3 n4 n1 n2 )
See also:		dup swap rot over drop
( -- )
Usage:		: {token} {definition} ;
See also:		immediate ; :: forward
Defines {token} as an executable word, which will execute all the code in
{definition} when it is invoked.
( {test} -- )
See also:		case endcase default dropcase
Selector in case statement.
( -- )
Usage:		:: {token} {definition} ;
See also:		forward makes
Redefines {token} as an executable word by coding a BRA to {definition}
into the previous definition. Use this word for writing mutually recursive
words. Do not use this word for redefining kernel words unless you are
sure that the redefinitions are permanent.
( -- )
See also:		:
Completes a colon definition. Semicolon codes a RTS into the dictionary
and checks that the parameter stack is the same as it was when ‘:’ was
executed.
Forth 2-3<
<<
<=
<>
<r
=
>
>!l
>!w
>=
>>
>altc
>local
>r
>struct
>uses
?>
@
2-4 Forth
( n1 n2 -- f )
See also:		> < <= >= = 0= if while until
True (-1) if n1 < n2.
( n1 count -- n1<<count )
See also:		2* 4* 8* 16* 256* >> >>x
Left shift. Multiplies n1 by 2^count.
( n1 n2 -- flag )
See also:		<
( -- value )
See also:		>r r@ r1 r2 r3 r4 dropr
Pops top value from return stack.
( n1 n2 -- flag )
See also:		<
(
See also:		literal ,
Codes a move.l $xxxx,-(a6) or a move.l $xxxxxxxx,-(a6) into dictionary.
( n1 n2 -- flag )
See also:		<
( n1 count n1>>count )
See also:		2/ 4/ 8/ 16/ 256/ >>x <<
Shifts n1 right ‘count’ times, with no sign extension.
(
See also:		altc+ altc- altc stop
If altc checking has been enabled, compile an ‘altc’ into the current word
definition. Otherwise, do nothing.
( n -- )
See also:		locals| local? local> to
Word to compile a store to a local variable.
( n -- )
See also:		<r r1 r2 r3 r4 dropr
Pushes n to return stack.
( n -- n )
See also:		struct
Word to create & compile a structure field.
( address -- )
See also:		larray uses
Word compiled by ‘uses’
( -- )
See also:		if
Compiles TST.L (A6)+ into dictionary.
( addr -- val )
See also:		c@ w@ w@x c! w!
Loads a longword {val} from {addr}
Kernel words.]
abort
abs
addr.of
again
align.w
allot
aload
altc
altc+
altc-
altc?
Kernel words.
( -- )
Usage:		] {1616 command}
See also:		exec sexec shell system
In immediate mode, allows a 1616 command to be executed. FORTH
copies itself to the stack when ] is executed, so transients may be freely
executed.
( anything . . . -- )
See also:		error cont stop
Closes all files currently being LOADED, resets parameter stack, return
stack, deallocates space from links,turns off compile flag, turns off colon
mode & (if screen.f loaded) resets default window.
( n -- +n )
See also:		~ - max min
Convert n to positive integer.
( -- address )
Usage:		addr.of {auto. or local var}
See also:		locals| to @ ! automatic
Leaves the address of automatic or local variable on stack.
( -- )
See also:		begin repeat while until return
Used with a ‘begin’, causes code between ‘begin’ and ‘again’ to be
executed forever.
( n -- n aligned on even byte boundary )
( space -- )
See also:		link forget next!
Allot ‘space’ bytes in object area. To find the address of this space, execute
a ‘next@’ before allotmentment. An attempt to allot too much space will
result in an out of memory error.
( -- )
See also:		load args
If an argument was specified when FORTH was invoked, load it as a
FORTH file.
( -- )
See also:		stop altc+ altc- cont
If altc has been pressed, ‘stop’. Otherwise, check the stack for over/underflow.
( -- )
See also:		>altc altc-
Tells FORTH to put checks into compiled code so that if altc is pressed,
execution will halt immediately. If code has already been compiled, altc+
has no effect.
( -- )
See also:		>altc altc+
Turns off run-time checking of altc. Code that has been compiled with the
altc flag on will still check for altc.
( -- flag )
See also:		cget c? cget? altc
If altc has been pressed, flag is true (-1). This word also clears the altc
status.
Forth 2-5
amul
and
args
array
See also:		array larray
Word to compile multiplication part of array definition.
( n1 n2 -- n1 and n2 )
See also:		eor or not
( -- address )
See also:		aload
Returns a pointer to the array containing information about the command
line arguments passed to FORTH when it was invoked. 
See 1616 documentation for arguments format.
( elsize nels -- )
Usage:		{el. size} {no. els} {token}
See also:		chk+ chk- base0 base1 larray size.of marray
Create an array with {nels} elements, each of size {elsize}.
Example:
base1
4 10 array values
: sum10
( sum 10 numbers from keyboard )
10 1 do
32 pad expect ( get number )
pad number ( convert it )
if
i values !
else
" Bad number" error
then
loop
0 10 1 do
i values @ +
loop . ;
asc
automatic
This word reads 10 numbers from the keyboard, calculates the sum and
prints the result.
( -- value )
Usage:		asc {chr}
See also:		emit
Leave ascii value of {chr} on stack.
( -- )
Usage:		automatic {token}
{token} -> ( -- value )
See also:		to addr.of variable constant dauto
Defines {token} to be an automatic variable, whose value is placed on the
stack when executed. The initial value is assigned to be 9999.
Example:
>automatic a
( create a )
>a .
( get a’s value )
9999
>42 to a
( assigns 42 to a )
>a .
42
>addr.of a @ .
42
base
( -- value )
See also:		hex decimal number .
System variable containing the current numeric base in use for numeric
conversions and printing.
base0
2-6 Forth
Kernel words.base1
begin
(
See also:		array larray
If base0 is executed before defining arrays, array indices will start at zero.
If base1 is executed, array indices start at 1.
( -- )
See also:		while repeat until again
Marks the start of a begin/again, begin/while/repeat or begin/until loop.
Examples:
: star_forever ( print lots of stars )
begin asc * emit again ;
: star_key ( print stars ‘til key pressed )
begin asc * emit c? until ;
: keys_prt ( print keypresses while altc not pressed )
begin cget
dup 0>= while (altc?)
emit
repeat ;
bell
beq>
bne>
bra>
bmove
byte:
bytes:
c!
c?
c@
Kernel words.
( -- )
Emits a bell character (7 emit)
( -- )
Codes a branch instruction into dictionary.
( src dst count -- )
See also:		move
Does a block move. bmove always moves a multiple of four bytes, and
{src} and {dst} must be alingned on a four-byte boundary. Use ‘move’ for
moving character strings.
 addr offs -- addr offs+1 )
Usage:		byte: {token}
See also:		long: word: string: struct ends bytes:
Declares {token} to be a byte length field in a structure.
( addr offs nbytes -- addr offs+nbytes )
Usage:		{n} bytes: {token}
See also:		long: word: string: struct ends byte:
Declares {token} to be a field of length {nbytes} in a structure. ‘bytes:’ is
equivalent to ‘string:’.
( byte addr -- )
See also:		 c@ @ ! w@ w!
Store {byte} at {address}.
( -- f )
See also:		altc? cget cget?
f is true (-1) if a key has been pressed. c? does not detect altc.
( addr byte -- )
See also:		 c! @ ! w@ w!
Loads {byte} from {addr}.
Forth 2-7call
case
( addr -- ?? )
See also:		compile
Call the assembler subroutine (or forth word) at {addr}. This routine
should preserve a2-a5, a7 and d3-d7, and a6 should still point to a position
in the FORTH stack. The routine should terminate with a ‘rts’. Note that
this instruction is not simply a ‘jsr’; it checks to see whether or not (addr)
contains 68000 code or a special FORTH construction.
( value -- value )
See also:		:- default | endcase dropcase
case is similar to if/then, but it allows many options to be checked for.
Example:
: fred
case
1 :- ." one" |
2 :- ." two" |
3 :- ." three"
endcase ;
cget
cget?
chk+
chk-
clear
code
compile
2-8 Forth
Note that the last choice does not have a terminating ‘|’. The final choice
may be ‘default’. Case stores the condition to be checked for on the return
stack, so any exits from within the case statement must be handled carefully
with ‘dropcase’. If a logical expression rather than a comparison with the
condition needs to be checked for, use ‘=>’.
( -- chr )
See also:		c? cget? altc?
Wait for a key from the keyboard and return its ascii value. If altc has been
pressed, cget returns -1.
( -- [chr] flag )
See also:		c? cget altc?
As for cget, but does not wait for a key. Instead, cget? returns false (0) if no
key has been pressed.
(
See also:		array base0 base1 larray
If chk+ has been previously executed, array declarations will be generated
with code to check bounds.
( -- )
Prints a clear screen character (12 emit).
( -- )
See also:		, literal hex
Within a colon definition, all numbers will be compiled directly into the
dictionary rather than compiled as literals. This word is used for compiling
68000 code into words. This word sets the base to 16; after a word with
‘code’ has been compiled, the base should be reset do decimal by executing
‘decimal’.
( address -- )
See also:		execute :
Compile a ‘JSR address’ into dictionary. If {address} is greater that $8000,
a long JSR or relative BSR will be coded instead of the usual short JSR.
Kernel words.
constant
cont
copy
create
crlf
debug+
debug-
decimal
default
delete
delim?
Kernel words.
( value -- )
See also:		variable automatic
Usage:		{expression} constant {token}
Generates a new word which, when executed, leaves a value on the stack.
Constants are identical to automatic variables in some cases, but beware:
small-valued constants are compiled as
MOVEQ #n,d0
MOVE d0,-(a6)
for efficiency.
(
See also:		altc stop abort
If a ‘stop’ or an ‘altc’ has occurred, indicated by the ‘~’ prompt, cont will
continue execution of a forth word at the point it left off. All registers,
return stack, program counter and parameter stack pointer are restored.
( -- )
See also:		 {see VLIST SYS}
Usage:		 copy {srcfile} {destfile}
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( -- )
Usage:		create {token}
See also:		variable allot header token
Reads the next token and make a header in the dictionary pointing to the
current position in the object area.
( -- )
Prints a c/r linefeed. (13 emit 10 emit)
( -- )
See also:		trace+ altc+
Executing ‘debug+’ tells forth not to ignore text entered after ‘\’ on a line.
‘debug-’ (the default) forces forth to ignore text after ‘\’. Use the ‘\’ in front
of debugging code in your files.
( -- )
See also:		hex base . number
Sets current base to ten. (10 base !)
( -- n )
See also:		case :- endcase dropcase
Default test for case statement.
( -- )
Usage:		delete {filename}
See also:		edit dir
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( chr -- flag )
flag is set true if chr is tab, space or null.
Forth 2-9
dexpect
dfind
dict
dir
dirs
do
( n addr -- )
See also:		expect pad (.) .str
Input a line of text from the keyboard, of maximum length {n} characters,
to {addr}. If a string already appears at {addr}
(that is, if the first character is non-zero), display it on the line and allow it
to be edited. If the string is longer than {n} characters, the string’s length
will be the maximum.
( -- addr )
See also:		dict dsearch find immediate ’
Find address of current token in the vocabulary table. This word returns the
address of the dictionary entry, not the code, for a word. For the structure
of each dictionary entry see dict.
( -- address )
See also:		’ ’d dfind find? find search token
Returns a pointer to the dictionary pointer. dict @ points to the dictionary
entry of the most- recently-compiled word.
Dictionary structure:
{count}
{characters . . .}
{code address}
{count} is a one byte character count, or’d with 128 to indicate immediate
execution
{characters . . .} are {count} characters of the word, possibly with a zero fill
byte
{code address} is a longword
( -- )
Usage:		dir
or:
dir {pattern}
or:
dir {blk driver}
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( last first -- )
See also:		loop +loop -loop lastdo i j
Marks the start of a do/loop structure. The previous loop indices are placed
upon the return stack.
Example:
: timestab
1 5 do
( print 1-5 times table )
5 1 do
tab i j * .
loop
crlf
1 -loop ;
docheck
2-10 Forth
( element top -- element )
See also:		chk+ chk- array larray
Checks array bounds. This word is compiled into an array definition if
chk+ has been executed.
Kernel words.drop
dropcase
dropr
dsearch
dup
echo+
echo-
edit
efcopy
else
emit
endcase
ends
eor
Kernel words.
( n -- )
See also:		dup swap rot over 2drop
Drops top element from stack.
( -- )
See also:		case :- endcase return dropdo
This word must be used when escaping from a case statement with a ‘re-
turn’ or ‘goto’. The case check is stored on the return stack, so this word is
equivalent to ‘dropr’.
( -- )
See also:		>r <r r1 .. r4
Drops top value from return stack.
( -- [address] flag )
See also:		search token find dfind ’d
Searches for current token in dictionary and returns its dictionary table
address if it is found.
( n -- n n )
See also:		swap rot over drop 2dup nip tuck
Duplicates top entry on stack.
( -- )
See also:		load
echo+ and echo- determine whether or not a file is echoed to the screen
when it is loaded.
( -- )
Usage:		edit {filename}
See also:		] exec sexec dir delete
Calls 1616 editor on filename. Be warned: FORTH copies itself to the
return stack when edit is invoked, so there may not be enough memory to
load all your file. However, this ensures that FORTH is not overwritten by
large text files.
( -- )
Usage:		efcopy {files} {block driver}
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( -- )
See:
if then
( chr -- )
See also:		type .str .
Outputs character to screen (or stdout)
( n -- )
See also:		case default dropcase :- |
Terminates a case statement.
( addr offs -- )
See also:		struct byte: long: word:
Terminates a struct definition.
( n1 n2 -- n1 eor n2 )
See also:		and or not
Forth 2-11
error
esc
exec
expect
f0/
f1/
fclose
fcopy
fget
fgetc
find
fkey
flip
float:
2-12 Forth
( string -- )
See also:		abort
Prints ?{string} then performs an abort.
( -- )
Prints an escape character ( 27 emit )
( string -- )
See also:		sexec ] syscall shell system
Executes a 1616 command. Cannot be used for transients.
( n addr -- )
See also:		dexpect pad .str
Input a line of text from the keyboard, of maximum length {n} characters,
to {addr}.
( -- )
Usage:		f0/
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( fdesc -- status )
See also:		 fopen fget fput fgetc fputc
Close a file. Note that FORTH file descriptors always have an offset of 16
added to them, to allow file descriptors to be used directly in calls that may
use devices such as cent:.
( -- )
Usage:		fcopy {source file} {dest block driver}
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( fdesc -- n )
See also:		fput fgetc fopen fclose
Get a 32 bit (4 byte) integer from file (or device) {fdesc}.
( fdesc -- c )
See also:		fput fget fopen fclose
Get a byte from file (or device) {fdesc}.
( -- address )
See also:		whazzat dfind ’
Searches for current token, giving error message if not found, or the code
address.
( -- )
Usage:		fkey .n "{string}"
As per the standard 1616 command. This command may only be used in
direct mode, and must be the first and only FORTH word on the command
line. All the system words are in FORTH vocabulary ‘sys’
( w1w2 -- w2w1 )
Swap the two words of the top element on the stack.
See ‘struct’
Kernel words.fopen
forget
forget?
forward
free
goto
header
hex
i
i+
if
Kernel words.
( name mode -- fdesc )
Open a file on the current block device, with mode being 1 for read, 2 for
append/write, 3 for read/write. See ’file.f’ for more usefule file manipula-
tion words/constants. If an error occurs, fdesc will be -1.
( -- )
Usage:		forget {token}
See also:		vdel vocab
Removes {token} and all after it from the dictionary, and resets next (a5) to
the code address of {token}.
Beware: if the dictionary is out of order, (as with a libload) forget may have
unpredictable results, as definitions may be removed from the code area
while their dictionary entries are not. It is safest to forget vocabularies.
( -- )
Usage:		forget? {token}
See also:		oad? forget
If token exists, forget it. This word should appear at the head of every forth
file to ensure that if a file is loaded twice, its previous incarnation is
removed.
( -- )
Usage:		: {token} forward ;
See also:		::
This word does not do a thing, but is useful for indicating that the real defi-
nition for {token} lies ahead. Essential for writing mutually recursive
words.
( -- value )
See also:		mem vocfree allot link used vocused
Returns the amount of space it is possible to allot or link. The value
returned by free allows 4k between the bottom of the return stack and the
top of FORTH for interrupts etc.
( -- )
Usage:		goto {label}
See also:		label:
Jump to {label}. See ‘label:’ for warnings about the use of ‘goto’.
( -- )
See also:		create dict next@ unique+ unique-
Creates a dictionary entry for the current token. If the token already exists,
an error message is generated unless the unique flag has been turned off.
( -- )
Sets the current base to 16.
See also:		base number . decimal
( -- n )
See also:		i+ j do loop +loop -loop
Returns the current value of the do/loop counter (d3).
( n -- n+i )
See also:		i j do loop +loop -loop
Adds the current value of the loop counter to n.
( flag -- )
Usage:

if {code1} then
or:
if {code1} else {code2} then
See also:		then case else if0

If flag is non-zero, execute {code1} [else execute {code2}]

Forth 2-13

Example:

: iftst
cget
asc a = if
." Was an ""a"""
else
." Was not an ""a"""
then
crlf ;
if0
imm?
immediate
immword
incase?
instruct?
interactive
j
join
label:
larray

2-14 Forth

( flag -- )

As for if, but code is executed if flag is zero.
( -- flag )

{flag} is false if executed while a word is being
defined.

( -- )
See also:		immword dict

Changes dictionary entry for the most recently compiled word so that it will
execute inside colon definitions rather than be compiled.

( -- )

Check imm? flag, and if word is not being used inside a colon definition,
error.

( -- )
See also:		case

Checks that :-, default, dropcase or endcase are executed while a case state-
ment is active.

( -- )
See also:		struct

Checks that we’re inside a struct definition.

( fdesc marker -- )
See also:		load

Indicates to FORTH that the current file has come to an end. It must be
used at the end of every word definition file.
( -- n )
See also:		do i loop

Returns the value of an outer loop counter.

( addr -- )
See also:		split if

Fills in a previously compiled forward branch so that it jumps to the current
dictionary position.

( -- )
See also:		goto dropdo dropcase dropr return

Usage:

label: {labelname}

Specifies a label for a goto inside a word definition. A label may be
declared before or after the corresponding goto, and may be in a separate
word. However, any do loops, case statements or return stack pushes left
hanging are likely to have nasty effects, so it is best to jump to labels within
the same word, being very careful about cleaning up.

( elsize #els -- )

Usage:

{expr1} {expr2} larray {token}
See also:		uses array chk+ base0

Creates a locally useable array whose element size is {expr1} and has
Kernel words.{expr2} elements. Using larray to define an array does not allocate any
space for the array: the word ‘uses’ must be used inside a definition to allo-
cate space for the array on the return stack.

Example:

base0 4 10 larray fred
: fred_is_used ( fill fred with zeroes )
uses fred
9 0 do
0 i fred !
loop
loop ;
( fred is now deallocated )
lastdo
line!
line?
line@
link
link@
( -- )
See also:		do loop

Sets the loop counter to its terminal value, so that when ’loop’ is next
encountered the loop will terminate.

( addr -- )

Set the address of the interpreter’s line buffer. Not very useful.

( -- addr )

Get the address of the first character of the interpreter’s line buffer.

( -- address )
See also:		token

Returns the current pointer within FORTH’s command line (a4). This word
is useful for examining command lines directly.
( n -- )
See also:		link@ unlink locals|

Allocates n bytes in memory. The space is freed when the word containing
the link completes, unless the top element of the return stack is temporarily
popped when the link is executed, in which case the space will be freed
when the calling word terminates. Executing an abort or causing an error
will cause all linked blocks to be freed. Only 256 link’ed blocks may be in
use at any one time.

( -- addr )
See also:		link unlink

Returns the address of the last link.

Example:

: slinky ( fdesc -- | gets line from file & print )
128 link
( allocate space )
link@ swap fgets ( get line )
link@ .str
( print line )
crlf
;
( return & deallocate space )
If it is necessary to keep the allocated space on the stack for the calling
word (see wopen@ in screen.f), use the following method:
: slinky2 ( fdesc -- addr | gets line from file )
<r 128 link >r ( allocate space )
link@ swap fgets ( get line )
;
( return )
literal

Kernel words.

The space on the stack will be deallocated when the word beneath com-
pletes.

( n -- )
See also:		constant number

Compiles code in the object area to put n on the stack.

Forth 2-15

load
load?
local>
local?
locals|
( -- fdesc marker )

Usage:

load {filename}
See also:		interactive aload

Causes FORTH to open {filename} and read lines from it instead of the
keyboard until ‘interactive’ is encountered. Don’t put more commands on
the line with the load, as FORTH will attempt to execute them before the
file is loaded.

Loads may be nested to a depth of 16 (limited by number of open files
allowed).

If the file specified is not found, FORTH tries adding a ’.f’ extension (save
does not do this).

’load’ stores nesting information on the parameter stack, so the stack should
be left in the same state when ‘interactive’ is executed as when a file began
loading.

( -- fdesc marker ) or ( -- )

Usage:

load? {token} {filename}
See also:		forget?

If {token} doesn’t exist, load {filename}. This word should be put at the
head of word files to ensure that any other necessary word files have been
loaded, and the token will usually be a vocabulary name.

( local# -- )
See also:		local? >local

Compiles a local variable.

( -- [local#] f )

If current token is a local variable, f is true and local# is its index.

( a1 .. an -- )

Usage:

locals| v1 v2 v3 v4 |
See also:		mlink to addr.of

Declares local variables and loads their values from the stack. Only one
locals definition is allowed per word.

The pointer to local variables is (a2).

Example:

: quadratic ( x c0 c1 c2 -- n | n=x*x*c2+x*c1+c0 )
0 locals| xx c2 c1 c0 x |
x x * to xx
c0
c1 x *
c2 xx *
+ + ;

A ‘.’ appearing before a local variable will declare it to be a double (or
floating). For example (using FLOAT.F):

: quadratic ( . x . c0 . c1 . c2 -- . n )
0 0 locals| . xx . c2 . c1 . c0 . x |
x x *f etc ... ;
logoff
long:

2-16 Forth

( -- )
See also:		save turnkey

Copies the vocabulary above the object area and sets internal pointers
appropriately for a save.

( addr offs -- addr offs+4 )
See also:		struct
Longword field for structure.

Kernel words.loop

makes

( -- )
See also:		do +loop -loop

Adds one to the loop index (i), checks it, and if <= loop
terminator, go back to do.

( -- )

Usage:

’ {token1} makes {token2}
See also:		vdel

Allows more than one token to be linked to the same piece of code. This
allows several synonyms to be defined for convenience. By the use of
‘makes’ with ‘vdel’, words may be redefined.

Example: redefine emit to print control characters as
[val]

’ emit makes oldemit
unique-
( allow emit to be redefined )
: emit
dup 32 < if
asc [ oldemit
.
asc ] oldemit
else
oldemit
then ;
vdel oldemit
unique+
mark
mark++
mark--
max
mem
min
mlink
mod
Kernel words.

Note that words defined with the older version of emit will execute
unchanged.

( -- addr )
See also:		split join

Leaves the current object pointer on the stack to allow calculation of
branches in if’s, again’s etc.

( -- addr )
( -- offset )

’mark++’ and ‘mark--’ as a pair calculate the offset for a backward branch.
( n1 n2 -- max{n1,n2} )

( -- )
See also:		vocused free used HEAP.F

Prints info about current memory usage.

( n1 n2 -- min{n1,n2} )
( a1 .. an n -- )
See also:		locals| link mlink

Allocates n*4 bytes on the return stack with link, then reads n values from
the stack into this space. locals| uses this word. Note that (a2) is set to
point to local variables, so that future links will not supersede the local defi-
nitions. The link pointer (a3) is also set to point to the local variables, but
any future link will supercede this.

( n1 n2 -- n1 mod n2 )
See also:		 modq /q /modq /mod

32 by 32 bit integer modulus. Should only be used with positive numbers.

Forth 2-17

modq
move
msg1
newline
next!
next@
next_vocab
next_word
nip
nop
not
number
one.of
or.of
or
org
over
pad

2-18 Forth

( n1 n2 -- n1 mod n2 )
See also:		mod /q /modq

32 by 16 bit integer mod. This uses the 68000 DIVU instruction, so it is
quick.

( src dst #bytes -- )
See also:		bmove

Move {#bytes} bytes from {src} to {dst}. This is a byte move, so will be
slower (but more flexible) than bmove.

( -- string )
See also:		word1

Message first printed by FORTH when it is invoked.

( -- )

Put a null into FORTH’s input buffer so that no more words will be
executed from the current input line.

( addr -- )
( -- addr )
See also:		allot header compile
Set/read the code pointer (a5).
( addr -- addr+offs )
See also:		vlist type_word

Used by vlist to find the next vocabulary/word in the FORTH dictionary.

( n1 n2 -- n2 )
See also:		 dup tuck rot swap over drop

( -- )

Execute nothing.

( addr -- addr eor $ffffffff )
See also:		0= ~

One’s complement. This is not a logical not: use ‘0=’ for this purpose.
( string -- [number] flag )
See also:		line . (.)

Convert {string} to a number. If the conversion was successful, flag is true
(-1).

See ‘struct’.

( n1 n2 -- n1 or n2 )
See also:		not and eor

( -- addr )

Returns the address FORTH was loaded at ($4000).

( n1 n2 -- n1 n2 n1 )
See also:		rot dup swap drop

( -- addr )
See also:		expect dexpect (.) number

Returns the address of a 512-byte buffer, suitable for inputting lines from
the keyboard, building strings or anything else. The space at ‘pad’ is totally
unused by the FORTH kernel.

Kernel words.pick
prompt
r1
r@
r2
r3
r4
rd/
rename
repeat
resize
return
( n -- val )
See also:		roll

Pick the n’th value from the stack; ‘1 pick’ is equivalent to ‘dup’, ‘2 pick’ is
equivalent to ‘over’.

( -- )

Type a prompt: ‘>’ or ‘~’, printing a carriage return if necessary.

( -- n )
See also:		>r <r dropr do case

Get a value from the return stack. r1 is (a7), r2 is 4(a7), r3 is 8(a7), r4 is
12(a7) and r@ is equivalent to r1.

( -- )

Usage:

rd/
rename {file1} {file2}
See also:		edit dir

As per the standard 1616 commands. These commands may only be used
in direct mode, and each must be the first and only FORTH word on the
command line. All the system words are in FORTH vocabulary ‘sys’.

( -- )
See also:		 begin while again until
Marks the end of a begin/while/repeat loop.

( space -- )
See also:		vocresize bmove

Moves the return stack to give the parameter stack more/less room. Any
absolute addresses pointing within the return stack will become meaning-
less, but local variables will survive. By using local variables and links, the
256 entries provided by default by FORTH should be plenty for any
program.

( -- )
See also:		dropdo dropcase

Gets out of a word early. Be careful that all case, return stack pushes and
loops have been correctly killed.

Example:

: rtntst
10 1 do
cget case
asc q :- dropcase dropdo
return |
13
:- 10 13 emit emit |
default :- case@ emit
endcase
loop ;
Kernel words.
Forth 2-19roll
rot
rot-
rp@
rtnhi
rts>
rvsoff
rvson
save
sbod
search
shell
size.of
sp@
split
split0

2-20 Forth

( a1 a2 a3 .. an n -- an a1 a2 a3 .. an-1 )
See also:		 pick

Roll {n} elements in the stack. This word is not very fast; it should only be
used if really necessary.

( n1 n2 n3 -- n2 n3 n1 )
( n1 n2 n3 -- n3 n1 n2 )
See also:		swap drop over dup

( -- addr )
See also:		sp@ rtnhi

Returns the return stack pointer.

( -- address )
See also:		rp@

Returns the base of the return stack.

( -- )
See also:		return

Codes a RTS into the object area.

( -- )

Turns off & on reverse field printing.

( -- )

Usage:

save {filename}
See also:		turnkey word1

Saves current FORTH environment to disk. 
The ‘.f’ extension is not automatically supplied.
Save routine used by save and turnkey.

( -- [address] flag )
See also:		dict find

Searches for current token. If it is found, its code address and true (-1) is
left on the stack. If it is not found, false (0) is left on the stack.

( -- )
See also:		system ] exec sexec

Temporarily exit FORTH to the 1616os shell. Transients can be executed,
as FORTH saves itself on the return stack.

( -- size )

Use: size.of {structure}
See also:		addr.of struct

Returns the size of a structure to allow arrays, links etc. to be declared of
appropriate size.

( -- addr )
See also:		r@ stkhi

Returns the pointer to the parameter stack: that is, {addr} points to the entry
below itself.

( -- addr )
See also:		join mark split0

Code a beq into the dictionary and leave an address to allow a later join.
Used by if, while.

( -- addr )

As for split, but uses bne.

Kernel words.ssasm
ssddutil
stkhi
stklen
stop
string
string:
struct

( -- )

Usage:

ssasm {filename}
( -- )

Usage:

ssddutil

As per the standard 1616 commands. These commands may only be used
in direct mode, and each must be the first and only FORTH word on the
command line. All the system words are in FORTH vocabulary ‘sys’

( -- addr )
See also:		sp@ rtnhi

Returns variable containing base of parameter stack.

( -- addr )
See also:		resize
Returns variable containing size of parameter stack (maximum number of
entries is size/4)

( -- )
See also:		cont abort error

Saves registers, stack pointers and sets cont flag before returning to FORTH
prompt.

( size -- )

Usage:

string {token}
See also:		.str " ."

Creates a string variable which, when executed, returns a pointer to a buffer
of {size} bytes.

( addr offs size -- addr offs+size+1 )

Usage:

{expr} string: {token}
See also:		struct

Creates a string field for a structure.

( -- )
See also:		size.of

Begins a structure definition.

Example:

struct wind
word: .xstart
word: .ystart
word: .xend
word: .yend
word: .bg_col
word: .fg_col
word: .curs_x
word: .curs_y
long: .wsave
long: .oldwin
ends (wind can now be used to create variables: )
wind wtest
( create wtest )
0 wtest .xstart !word
80 wtest .xend !word
0 wtest .ystart !word
25 wtest .yend !word
size.of wind 10 array 10windows ( create a ten-element array
)
swap

Kernel words.

( n1 n2 -- n2 n1 )
See also:		drop dup rot over 2swap nip tuck

Forth 2-21

syscall
system
tab
then
to
token
trace+
trace++
trace-
trace--
tuck
turnkey
( an .. a1 #args call# -- return )
See also:		] exec sexec

1616 os system call.

Example:

y x 2 55 syscall . ( read pixel colour at (x,y) )

( -- )
See also:		shell

Quit forth permanently.

( -- )

Print a tab (9 emit).

( -- )
See also:		if

( -- )

Usage:

{expr} to {token}
See also:		locals| automatic addr.of

Sets the value of a local or automatic variable to {expr}. If variable is
double-size (8 bytes), two entries are taken from the stack.

( -- )
See also:		search find ’
Read the next token from the input line.

( -- )

Turn on trace mode - words compiled when trace mode is on will be com-
piled with trace information. Words executed with trace mode on which
contain this information may be single stepped through each word, with the
parameter stack being shown after each step. If the trace mode is of while
the trace’d word is executed, no single-step information will be printed out,
but altc and stack over/underflow will be checked for with each word
executed. trace’d code is about twice the size of un-trace’d code.

( -- )

Turn on trace mode from within a colon definition to trace tiny sections.
This word will not turn trace mode on when the word is executed; the trace
mode must be on for the trace’d code to be single-stepped.

( -- )

Turn off trace mode.

( -- )

Turn off trace mode from within a colon definition.

( n1 n2 -- n2 n1 n2 )
See also:		nip dup over rot drop swap

( -- )

Usage:

turnkey {filename}
See also:		save

Save FORTH without the vocabulary to conserve space. For this to work,
word1 must be redefined. Please save FORTH applications for public dis-
tribution with ‘turnkey’, not ’save’.

Example: create a turnkey application to clear the screen.

>:: word1 clear system ; ( define first word exec’d )
>turnkey clear.exec ( save forth environment )
>system
( quit forth )
f0>clear.exe
( clear screen )
2-22 Forth
Kernel words.type
type_word
unique+
unique-
unlink
until
until0
used
uses
variable
( buffer count -- )
See also:		.str emit " ." crlf

Emit {count} bytes from {buffer}.
( addr -- )
See also:		next_word next_vocab vlist

Used by vlist to type a word from the dictionary.
( -- )

Turns on and off a check to ensure all newly defined words are unique.

( -- )
See also:		locals| link mlink
Deallocate space from last link, mlink, locals| etc. Whatever data was there
will be clobbered within the next twenty milliseconds by the retrace inter-
rupt.
’unlink’ must be executed at the same nesting level as the initial ‘link’ or
‘locals|’ was.
( flag -- )
See also:		begin

If flag is true (-1), fall through to the next statement. Otherwise, go back to
the last begin.
( flag -- )

As for until, except a flag of zero indicates termination.
( -- space )
See also:		mem free
Returns code space used.
( -- )

Usage:

uses {larray}
See also:		link larray
Allocates space within a word for an array defined with larray. Other words
may use the array after ‘uses’ has been executed, but ‘uses’ may not be
nested with one array.
( -- )

Usage:

variable {token}
See also:		automatic constant
Creates a variable which, when executed, returns the address of its four byte
value. Although non-standard, ‘automatic’ and local variables are more
efficient and easier to use than ‘variable’.
Example:
>variable xxx
>57 xxx !
>xxx @ .
57
vdel
Kernel words.
( sets value of xxx )
( get value )
( -- )

Usage:

vdel {token}
See also:		forget makes
Removes {token} from the dictionary, but leaves object code intact. vdel is
a useful word for non-destructively redefining kernel words.
Forth 2-23vlist
vocab
vocfree
vochi
voclen
vocmove
vocpnt
vocresize
vocused
w!
w@
2-24 Forth
( -- )

Usage:

vlist
vlist {vocabname}
vlist {vocabname} i
vlist *
See also:		immediate vocab
’vlist’ on its own will list vocabularies present in the dictionary. ‘vlist {vo-
cabname}’ will list all words contained in vocabulary {vocabname}, while
appending ‘i’ to the command will list all immediate words in {vocabname}
in reverse field. ‘vlist *’ will list all words in all vocabularies.
( -- )

Usage:

vocab {vocabname}
See also:		load? forget? forget vlist
Marks the start of a new vocabulary. Use this word at the beginning of
forth files, as explained in the section at the end of this document.
( -- space )
See also:		vocused free used
Returns amount of free space for vocabulary. Free space is automatically
allocated in 1k chunks when this runs out.
( -- address )
Returns a variable pointing to the top of the vocabulary space.
( -- address )
Returns a variable pointing to the total amount of space allocated to the
vocabulary.
( -- )
See also:		word1
Moves vocabulary from just above the object code area into the vocabulary
area. This word is only called once when FORTH is initially invoked. ’voc-
move’ should appear in the definition of ‘word1’ before a ‘save’ for
FORTH to function correctly, but should not appear in ‘turnkey’ed
‘word1’s.
( -- addr )
When FORTH is initially invoked, vocpnt points to the end of the vocabu-
lary sitting above the object area.
( space -- )
Moves the return stack and parameter stack down to allow more space for
the vocabulary. vocresize is automatically called when vocab space runs
out. Calling ‘vocresize’ with {space} less than that returned by ‘vocused’
will almost certainly crash the FORTH system.
( -- space )
Calculates how much vocabulary space has been used.
( word addr -- )
See also:		! c@ c! w@
Store the 16-bit value {word} at {addr}.
( addr -- {word} )
See also:		@ ! c@ c! w!
Get the 16-bit value from {addr}.
Kernel words.whazzat
while
while0
word1
word:
words
|
~
( -- )
See also:		error
Prints a currently offending token followed by a question mark. Aborts any
load currently in progress.
( flag -- )
See also:		begin repeat until
If flag is false (0), exit begin/while/repeat loop.
( flag -- )
As for while, except that loop is exitted if flag is non-zero.
( -- )
See also:		save :: turnkey vocmove
Word called when FORTH is invoked. It can be modified to print a differ-
ent sign-on message or start a turnkey application. Look in ‘WORDS.F’ for
its default definition.
Initially word1 is defined as follows:
: word1
msg1
( sign-on message )
.str
( print it )
vocmove ( move vocabulary into place )
aload
( load a FORTH file passed as arg )
;
word1 can be redefined with ::
:: word1 {turnkey application} system ;
( addr offs -- offs+2 )
See also:		struct
Specifies a word length field in a structure definition.
( -- )
See also:		vlist

A synonym for ‘vlist’.

( -- )
See also:		case endcase default dropcase :-
Separates choices in a case statement.
( n -- -n )
FORTH memory map:
HIGH MEMORY -------------------------------------
1616os original return stack
-------------------------------------
FORTH system buffers
line input buffer
<- line@ (a4)
512 byte user scratch<- pad
miscellaneous
-------------------------------------<- vochi @
Vocabulary moving down
.
.
Kernel words.
Forth 2-25forget?
voclen @ {
trace++
trace--
.
.
newestword
<- dict @
vocfree {
*** free vocab space
hfree
{
Heap space if HEAP.F loaded
-------------------------------------<- stkhi @
Parameter stack moving down
stklen @
{
<- sp@ (a6)
*** free stack space
-------------------------------------<- rtnhi @
Return stack moving down
Local arrays,
Local vars,
<- (a2)
Linked data,
Last linked data
<- link@ (a3)
------------------------------------- <- r@ (a7)
4096 byte safe area
-------------------------------------
free
{
*** free space
used
Original vocab loaded with<- vocpnt
FORTH
Newly read tokens
-------------------------------------<- next@ (a5)
{
Object code
-------------------------------------<- org ($4000)
Suggested format for .f files.
For a file containing vocabulary ‘fred’, using the supplementary files screen.f’,
‘file.f’ and ‘float.f’, the fred.f file might look like this:
forget? fred
( if fred is already loaded, forget it )
load? file file.f
( if the vocabulary ‘file’ is not loaded, load it )
load? floats float ( if ‘floats’ is not loaded, load float.f )
load? screen screen
vocab fred
{word definitions...}
interactive
2-26 Forth
( that’s the end! )
Kernel words.Quick reference:
!
"
%abase
%achk
%ccase
%struct
’
’c
(
(.)
(do)
*
*q
+
+!
+loop
,
,l
-
-loop
.
."
.s
.str
/
/mod
/modq
/q
0<
0<=
0<>
0=
0>
0>=
1+
1-
16*
16/
2*
2+
2-
2/
256*
256/
2drop
2dup
2swap
3+
3-
4*
4+
4-
4/
5+
5-
6+
6-
7+
7-
8*
8+
8-
8/
:
Kernel words.
:-
::
;
<
<<
<=
<>
<r
=
>
>!l
>!w
>=
>>
>>x
>altc
>local
>r
>struct
>uses
?>
@
]
abort
abs
addr.of
again
align.w
allot
aload
altc
altc+
altc-
altc?
amul
and
args
array
asc
automatic
base
base0
base1
begin
bell
beq>
bmove
bne>
bra>
byte:
bytes:
c!
c?
c@
call
case
case@
cget
cget?
chk+
chk-
clear
code
compile
constant instruct? rvsoff
cont
interactive
copy
j
create
join
crlf
label:
decimal
larray
default
lastdo
delete
line!
delim?
line?
dexpect
line@
dfind
link
dict
link@
dir
literal
dirs
load
do
load?
docheck
local>
drop
local?
dropcase
locals|
dropdo
logoff
dropr
long:
dsearch
loop
dup
makes
echo+
mark
echo-
mark++
edit
mark--
efcopy
max
else
mem
emit
min
endcase
mlink
ends
mod
eor
modq
error
move
esc
msg1
exec
newline
expect
next!
f0/
next@
f1/
next_vocab
fclose
next_word
fcopy
nip
fget
nop
fgetc
not
find
number
fkey
or
flip
org
float:
over
fopen
pad
forget
pick
forget?
prompt
forward
r1
fput
r2
fputc
r3
free
r4
goto
r@
header
rd/
help
rename
hex
repeat
i
resize
i+
return
if
roll
if0
rot
imm?
rot-
immediate
rp@
immword
rtnhi
incase?
rts>
rvson
save
sbod
search
sexec
shell
size.of
sp@
split
split0
ssasm
ssddutil
stkhi
stklen
stop
string
string:
struct
swap
syscall
system
tab
then
to
token
trace+
trace++
trace-
trace--
tuck
turnkey
type
type_word
unique+
unique-
unlink
until
until0
used
uses
variable
vdel
vlist
vocab
vocfree
vochi
voclen
vocmove
vocpnt
vocresize
vocused
w!
w@
w@x
whazzat
while
while0
word1
word:
words
|
~
Forth 2-27!
"
%abase
%achk
%ccase
%chksize
%maxoffs
%oneoffs
%struct
’
’c
(
(.)
(array)
(dims)
(do)
(rseed)
(struct) >>x
(unlink) >altc
(uses)
*
*q
+
+!
+loop
,
,l
-
-loop
.
."
.card
.s
.str
.token
/
/mod
/modq
/q
0<
0<=
0<>
0=
0>
0>=
1+
1-
16*
16/
2*
2+
2-
2/
256*
256/
2drop
2dup
2swap
3+
3-
4*
4+
4-
4/
5+
5-
6+
2-28 Forth
8+
8-
copy
create
8/
:
crlf
d!
:-
::
;
<
<<
<=
<>
<r
=
=>
>
>=
>>
d@
dauto
debug+
debug-
decimal
default
delete
delim?
dexpect
dfind
dict
dir
dirs
do
docheck
>local
>r
?>
@
]
abort
abs
addr.of
again
align.w
allocfmem
allocmem
allot
aload
altc
altc+
altc-
altc?
amul
and
args
array
arraym
asc
automatic
base
base0
base1
begin
bell
beq>
bmove
bne>
bra>
byte:
bytes:
c!
c?
c@
call
case
case@
cd
cget
cget?
chk+
chk-
clear
load?
loc@
drop
dropcase
dropdo
dropr
dsearch
dup
dvar
echo
echo+
echo-
edit
efcopy
else
emit
end.of
endcase
ends
entries
eor
error
esc
exec
execute
expect
fclose
fcopy
fget
fgetc
find
fkey
flip
float:
fopen
forget
forget?
forward
fput
fputc
free
freemem
goto
header
help
hex
i
i+
if
if0
interactive
j
join
label:
larray
larraym
lastdo
libload
line?
link
link@
literal
literal!
ssasm
literal@ ssddutil
litlea
llce
load
string
string:
local>
local?
locals|
logon
long:
loop
makes
mark
mark++
mark--
max
mem
min
mkdir
mlink
mod
modq
move
msg1
name
needed
newline
next
next_vocab
next_word
nextend
nip
nop
not
number
one.of
option
or
or.of
org
over
pad
pick
prompt
r1
r2
r3
r4
r@
random
rename
repeat
resize
rp@
rtnhi
rts>
rvsoff
rvson
save
search
shell
size.of
sp@
split
split0
stkhi
stklen
stop
struct
swap
syscall
sysfree
system
tab
then
ticks?
tline
to
tokbuf
token
trace+
trace++
trace-
trace--
tuck
turnkey
type
type_word
unique+
unique-
unlink
until
until0
used
uses
variable
vdel
vlist
vname
vocab
vocfree
vochi@
voclen
voclo
vocused
w!
w@
w@x
whazzat
while
while0
word1
word:
words
|
~
Kernel words.6-
7+
7-
8*
Kernel words.
code
imm?
compile
immediate
constant immword
cont
instruct? rot-
return
roll
rot
Forth 2-293
File manipulation words, in file.f
%ferror
.fbakup
.fblock#
.fdate
.flen
.fload
.fname
.ftype
.funused
closeall
d$cent:
d$con:
d$sa:
d$sb:
eof?
f$abs
f$eof
f$skip
f$char
f$comp
f$exec
f$pict
f$temp
f$text
f$xtxt
f$r/w
f$read
f$write

3-1 Forth
( -- f )
See also:		 ferror+ ferror-

Automatic variable set to true if automatic reporting
is turned on; set false if errors ignored.
( buf -- buff+offs )
See also:		 fstat fstatus
Field names for file status structure. See ‘fstat’ for
structure description.
( -- )
See also:		 fclose fopen eof?
Close all currently open files.
( -- 3 )
( -- 0 )
( -- 1 )
( -- 2 )

Constants representing file descriptors for devices.
( fdesc -- f )
See also:		 ferror? ferror+ ferror-

If {fdesc} represents a file at EOF or {fdesc} is invalid,
{f} is true. Otherwise, {f} is false.
( -- 0 )
( -- 2 )
( -- 1 )
See also:		 fseek

Constants for different types of seek mode.
( -- n )
( -- n )
( -- n )
( -- n )
( -- n )
( -- n )
( -- n )
See also:		 fcreate

Each of these is an obsolete file type, used in 1616OS versions
1.x. In the fcreate system call, a file type of 0 is now used.
( -- 2 )
( -- 0 )
( -- 1 )
See also:		 fopen fcreate

File opening modes.

File manipulation words, in file.ffclose

fcreate
fdout
ferrmes
ferror
ferror+
ferror-
ferror?
fget
fgetc

f$r/w indicates a random-access file that may be both written
to and read from.

f$read indicates a file which may be read from but not written to.

f$write indicates a file to be appended to.

( fdesc -- status )
See also:		 ferror+

Close a file. Status will be zero if the file was successfully
closed, otherwise will be negative.
( ld.addr (type) name -- fdesc )
See also:		 ferror+

Create a file. If the file is non-executable, the load address
should be zero. For systems with 1616os 2.x, {type} should
be zero. {name} should be a null-terminated string of fewer
than 32 characters. If an error occurred while creating
the file, {fdesc} will be negative.
( n -- n+16 )
See also:		Convert a 1616 file descriptor to a FORTH file descriptor.
FORTH disk files are always offset by 16 to ensure that
they are compatible with all system calls. Only devices
will have file descriptors smaller than 16.
( -- addr )
See also:		 ferror+
A fifty byte string for error messages.
( error -- addr )
See also:		 ferrmes
Convert a negative error status to a string.
( -- )
See also:		 ferror- ferror? ferror ferrmes
Turn on automatic error checking. After this word is
executed, any errors occurring while using FORTH file
words will cause an abort with appropriate error message.
( -- )
See also:		 ferror+
Turn off error checking. After this word is executed,
the user (or a FORTH program) must check for errors
after every file operation.
( status -- status )
See also:		 ferror+
If {status} is negative and error checking has been
turned on with ‘ferror+’, abort with an appropriate
error message.
( fdesc -- n )
See also:		 fput fget fputc fgetc putchar getchar
Get a 32 bit (four byte) number from {fdesc}. Numbers
will be input most significant byte first.
( fdesc -- ch )
See also:		 fget fput fputc putchar getchar ferror+
Get a byte from {fdesc}. If an error occurs, {ch} will
be negative.
File manipulation words, in file.f
Forth 3-2fgets
( buf fdesc -- )
See also:		 fget eof?
Read a crlf-terminated string from {fdesc} into {buf}.
’fgets’ will not detect errors, but a null string will
be stored at {buf}. If error detection is required,
use the word ‘eof?’.
fkill
( name -- status )
See also:		 fcreate fopen
Delete a file.
fopen
( mode name -- fdesc )
See also:		 f$read f$write f$r/w fclose eof? ferror+
Open a file.
fpos
( fdesc -- pos/error )
See also:		 fseek eof?
Find the position (in bytes read) of the current file.
fput
( date fdesc -- status )
See also:		 fget
Write a 32 bit number to {fdesc}.
fputc
( char fdesc -- status )
See also:		 fgetc getchar
Write a character to {fdesc}.
fputs
( buf fdesc -- )
See also:		 fgets putcrlf
Write a null-terminated string to {fdesc} from {buf}.
’fputs’ does not write a crlf after the string; use
’putcrlf’ to do so.
fread
( #bytes buf fdesc -- status )
See also:		 fwrite
Read {#bytes} to {buf} from {fdesc}.
frename
( oldname newname -- status )
See also:		 fkill fcreate
Rename a file.
fseek
( seekmode offset fdesc -- newpos/status )
See also:		 fpos f$abs f$eof f$skip
Seek to a position in a file. If newpos/status is negative,
an error has occurred.
fstat
( 64bytebuf name -- code )
See also:		 fstatus
Get the status of a file.
fstatus
( -- )
See also:		 fstat .fbakup
Structure definition used for accessing a file’s status
record. Its definition is as follows:
struct fstatus
32
bytes: .fname
8
bytes: .fdate
word: .ftype
long: .fload
long: .flen
3-3 Forth
File manipulation words, in file.f10
ends
fwrite
getchar
istatus
ostatus
putchar
putcrlf
set_sip
set_sop
sgetc
sputc
stdin
stdout
word: .fbakup
word: .fblock#
bytes: .funused
( #bytes buf fdesc -- status )
See also:		 fread
Write {#bytes} to {fdesc} from {buf}.
( -- char/error )
See also:		 putchar stdin set_sip
Get a character from standard input. This word
is similar to ‘cget’, but will not return an ‘altc’.
( -- #chars )
See also:		 ostatus stdin set_sip
Return the number of characters ready at stdin.
If standard input is a file, this call will
usually return 1.
( -- #chars )
See also:		 istatus stdout set_sip
Return the number of characters needed to fill the
output buffer of stdout.
( chr -- status )
See also:		 fputc
Write a character to stdout.
( fdesc -- )
See also:		 fputs putc
Write a crlf to {fdesc}.
( fdesc -- old_stdin )
See also:		 set_sop istatus stdin
Set standard input.
( -- )
See also:		 set_sip ostatus stdout
Set standard output.
( fdesc -- #chars )
See also:		 istatus
Return number of characters ready at {fdesc} for reading.
( fdesc -- #chars )
See also:		 ostatus
Returns number of characters needed to fill the output buffer
of {fdesc}.
( -- fdesc )
See also:		 stdout set_sip istatus sgetc
Returns file descriptor of standard input.
( -- fdesc )
See also:		 stdin set_sop ostatus sputc
Returns file descriptor of standard input.
File manipulation words, in file.f
Forth 3-4ty
ungetc
( -- )

Usage:

ty {filename}
See also:		Prints a file to the screen. ‘ty’ may only be
used in direct mode.
( char -- )
See also:		 fgetc getchar
Put a character back onto standard input. Only one
character at a time may be put back into the input.
Summary
%ferror d$sb:
.fbakup eof?
.fblock#
.fdate
.flen
.fload
.fname
.ftype
.funused
closeall f$read
d$cent: f$skip
d$con:
d$sa:
3-5 Forth
f$write
f$xtxt
f$abs
f$char
f$comp
f$eof
f$exec
f$pict
f$r/w
fkill
fopen
fclose
fcreate
fdout
ferrmes
ferror
ferror+
ferror-
ferror?
fget
f$temp
f$text
istatus
ostatus
fpos
fput
fputc
fputs
fread
frename
fseek
fstat
fstatus
fgetc
fgets
putchar
putcrlf
set_sip
set_sop
sgetc
sputc
stdin
stdout
ty
fwrite
getchar
ungetc
File manipulation words, in file.f4
Floating point words, in float.f
!f
$1/e
$1/log10
$e
$log10
$pi
$pi*2
$pi/2
*f
+!f
( ne nm addr -- )
See also:		 @f varf constf

Store 6 bytes at {addr}
( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 /f +f -f >=<f

Multiply two floating point numbers.
( ne nm addr -- )
See also:		 @f !f +f varf
Add f.p. to that at {addr}
+c? ( n1 n2 -- n1+n2 f )
See also:		 <<?
Add n1 and n2. f is true if a carry was generated.
+f ( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 -f *f /f
Add two f.p. numbers.
+real ( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 +f

Add two (unsigned) f.p. numbers (should not be used).
( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 +f *f /f

Subtract fp#2 from fp#1.
( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 -f

Subtract two (unsigned) f.p. numbers (should not be used).
( ne nm -- )
See also:		 .fe .fu
Print out a floating point number. If the number is
within range, it is printed out in decimal format.
Otherwise, it is printed in exponential notation.
-f
-real
.f
Floating point words, in float.f
Forth 4-1.fe
.fu
.int
/f
/real
0maxf
1/10f
10*f
( ne nm -- )
See also:		 .f .fu
Print a floating point number in exponential notation,
with leading sign, nine significant digits and signed
exponent.
( ne nm #dp #sigfigs -- )
See also:		 .f .fe

Print a floating point number with dp decimal places and
sigfigs significant digits.
( n -- )
See also:		 .fe

Print a 2-digit integer with leading sign. This word prints
the exponent of ‘.fe’.
( ne1 nm1 ne2 nm2 -- xe xm )
See also:		 *f +f -f

Divide fp#1 by fp#2.
( ne1 nm1 ne2 nm2 -- xe xm )
See also:		Divide two (unsigned) f.p. numbers (should not be used).
( ne nm -- ne nm or 0 0 )
See also:		 maxf minf

If f.p. number is positive, leave it. Otherwise,
return f.p. 0.

Constant
( ne nm -- xe xm )
See also:		 10f 2*f 2/f 1/10f
Multiply f.p. number by 10.
10f ( -- ne nm )
See also:		 10*f $e
Constant: 10
1f ( -- ne nm )
See also:		 10f $e
Constant: 1
2*f ( ne nm -- xe xm )
See also:		 2/f 10*f
Multiply f.p. number by 2.
( ne nm -- xe xm )
See also:		 2*f 10*f
Divide f.p. number by 2.
2/f
4-2 Forth
Floating point words, in float.f2dupf
ne2 nm2 )
( ne1 nm1 ne2 nm2 -- ne1 nm1 ne2 nm2 ne1 nm1
See also:		 dupf swapf dropf
Duplicate two f.p. numbers.
<<?
<<f
<f <=f <>f
( n -- n<< cnt )
See also:		 +c?
Shift n left until the sign bit is set; leave the count
of the number of shifts on the top of the stack.
( ne nm cnt -- ne’ nm’ )
See also:		 >>f 2*f 2/f
Multiply by 2^cnt
( ne1 nm1 ne2 nm2 -- f )
See also:		 >f =f >=<f
f is true if fp#1>fp#2.
=f ( ne1 nm1 ne2 nm2 -- f )
See also:		 <f >f >=<f
f is true is fp#1>fp#2.
>=<f ( ne1 nm1 ne2 nm2 -- f )
See also:		 <f >f =f
f is +ve if fp#1 > fp#2
f is 0 if fp#1 = fp#2
f is -ve if fp#1 < fp#2.
>=<real ( ne1 nm1 ne2 nm2 -- f )
See also:		 >=<f
Unsigned version of >=<f
>f >=f (ne1 nm1 ne2 nm2 -- f )
See also:		 >=<f <f =f
f is true if fp#1>fp#2
@f ( addr -- ne nm )
See also:		 !f +!f varf
Load a six byte f.p. number from {addr}.
( n1 n2 -- x1 )
See also:		 /f
No longer in use.
( ne nm -- +ne +nm )
See also:		 ~f
Returns the absolute value of f.p. number.
( ne nm -- arctan(ne nm) )
See also:		 tanf sinf cosf
( ne nm -- arctan(ne nm) )
See also:		 tanf sinf cosf
_/f
absf
acosf
asinf
Floating point words, in float.f
Forth 4-3atnf
autof
chkexp
clip
constf
cosf
( ne nm -- arctan(ne nm) )
See also:		 tanf sinf cosf
( -- )

Usage:

autof {token}
See also:		 constf varf @f !f +!f
Create a floating point variable. When {token} is executed,
it will leave a f.p. number on the stack. Use ‘to’ to
change the variable’s value.
( ne nm -- ne nm )
See also:		 *f /f
’?Overflow error’ if ne>2047. Underflow is not checked for.
( ne nm -- n )
See also:		 fix
Truncate the decimal portion of a number (that is, all
numbers are rounded towards zero).
( ne nm -- )
See also:		 varf f"

Usage:
 constf {token}
Define a f.p. constant.
( ne nm -- cos(ne nm) )
See also:		 sinf tanf acosf
Returns the cosine of a number.
digit? ( chr -- f )
See also:		 .f f"
f is true if {chr} is a decimal digit.
dropf ( ne nm -- )
See also:		 dupf 2dupf swapf
Drop a f.p. number from the stack.
dupf ( ne nm -- ne nm ne nm )
See also:		 2dupf dropf swapf
Duplicate a f.p. number.
( xe xm -- ne nm )
See also:		 sinf $e $1/e
Return e^x.
( -- ne nm )
See also:		 .f scanf float
Treat the next token in the FORTH input stream as a f.p.
number; leave its value on the stack (can be used in either
immediate mode or definitions).
( n -- addr )
See also:		 expf sinf
Table of coefficients for calculation of sin and exp.
expf
f"
fcoeff
4-4 Forth
Floating point words, in float.ffix ( ne nm -- n )
See also:		 clip float
Round a f.p. number down (that is, positive numbers towards
0, negative numbers towards negative infinity).
float ( n -- ne nm )
See also:		 fix f"
Convert an integer to f.p. format.
log10f ( ne nm -- ne’ nm’ )
See also:		 expf $e $1/e log10f
Calculate log base 10
( ne nm -- ne’ nm’ )
See also:		 expf $e $1/e log10f
Calculate log base e
( n -- addr )
See also:		 sinfq sinfq_init
Local array used for the quick sine routines. ‘lsines’
must be initialized by sinfq_init before use by sinfq.
logf
lsines
maxf ( ne1 nm1 ne2 nm2 -- ne nm )
See also:		 minf 0maxf
Returns the maximum of fp#1 and fp#2.
maxint ( -- $80000000 )
See also:		 minint
Returns minimum integer (corresponds to sign bit in the
mantissa of a f.p. number)
( ne1 nm1 ne2 nm2 -- ne nm )
See also:		 maxf 0maxf
Returns the minimum of fp#1 and fp#2.
minf
minint
normalize
odd?
oflow
( -- $7fffffff )
See also:		 maxint
Returns maximum integer (corresponds to the unsigned
portion of the mantissa)
( ne1 nm1 -- ne1+offs nm1<< )
See also:		 float +f -f
Changes an unsigned f.p. number to have a 1 in the
most-significant bit, changing the exponent accordingly.
( n -- f )
Returns true if n is odd.
( -- )
See also:		 chkexp
Force an overflow error. This word is a link for
the machine language library.
Floating point words, in float.f
Forth 4-5scanf ( addr -- ne nm )
See also:		 f"
Transform the character string at {addr} to a f.p.
number.
sinf ( ne nm -- xe xm )
See also:		 expf sinfq sinfq_init
Calculate the sine of f.p. number in radians.
sinfq ( n -- x )
See also:		 sinfq_init lsines
Return the integer sine (-32767 to +32767) of n. The
length of one cycle of this sine wave is 1024. sinfq_init
must have been called before this word will work.
sinfq_init ( -- )
See also:		 sinfq
Initialize the sine table used by sinfq. The table stored
in ‘lsines’ will be deallocated when the word containing
’sinfq_init’ terminates.
sqrt ( ne nm -- xe xm )
See also:		 sinf expf
Calculate the square root of a f.p. number.
swapf ( ne1 nm1 ne2 nm2 -- ne2 nm2 ne1 nm1 )
See also:		 dupf 2dupf dropf
Swap two f.p. numbers.
tanf ( ne nm -- tan(ne nm) )
See also:		 cosf sinf atanf
Returns the tangent of a number.
( -- )

Usage:

varf {token}
See also:		 autof constf @f !f +!f
Create a floating point variable. When {token} is executed,
it will leave the address of a six byte area ready for
storing a f.p. number.
( ne nm me me -- ne’ nm’ )
Evaluate n^m.
( ne nm -- xe xm )
See also:		 -f +f absf
Negate a f.p. number.
varf
y^x
~f
Summary
!f
$1/e
$1/log10
$e
4-6 Forth
-f
-real
.f
.fe
<<f
<=f
<>f
<f
constf
cosf
digit?
dropf
minf
minint
normalize
odd?
Floating point words, in float.f$log10
$pi
$pi*2
$pi/2
(.fu)
(atnf)
(atnf1) 10*f
(atnf2) 10/f
(fo)
(scanf) 10f
*f
+!f
+c?
+f
+real
.fu
.int
/f
/real
0maxf
1/10f
=f
>=<f
>=<real
>=f
>>f
>f
@f
_/f
10^x
absf
acosf
1f
2*f
2/f
2dupf
<<?
asinf
atnf
autof
chkexp
clip
dupf
expf
f"
fcoeff
fix
float
floats
swapf
get_exponent
varf
get_frac_part
get_int_part
~f
log10f
logf
lsines
maxf
maxint
oflow
scanf
sinf
sinfq
sinfq_init
sqrt
y^x
Floating point format:
Mantissa: MSB (bit 31) is sign - 1=-ve, 0=+ve
for operations, MSB is assumed to be 1 (unless number is
zero) other bits in mantissa form a binary weighted fraction
Exponent: Exponent is zero iff number is zero.
Otherwise, value is .mantissa*2^(exponent-1024)
Example:
Mantissa: $50000000
( 01010000 00000000 00000000 00000000 )
Exponent: 1025
Sign bit is 0, so number is positive.
Implicit 1 makes mantissa = .1101
Exponent multiplies mantissa by 2^(1025-1024)=2
Resulting number = 1.101 = 1.625
Floating point words, in float.f
Forth 4-75
Turn off VIA interrupts, irqkill ( -- )
See also:		 install
imsg
install
istack
5-1 Forth
( -- address )
A variable whose value is left on the stack for the
currently executing interrupt routine. The value left
on the stack by the interrupt routine is in turn left
in imsg.
See also:		 install irqkill istack
( rate address -- )
Installs an interrupt service routine, using the VIA
timer interrupts.
Before using this word, the following initializations are
necessary:
the variable istack must point to
enough space for a parameter stack for
the routine
imsg can be given a value to pass to the routine
rate is inversely proportional to the calling rate: as a
rough guide, 3748 for rate corresponds to about 50 hz.
See also:		 istack imsg irqkill
( -- address )
Points to a pointer to the parameter stack used
by the interrupt routine.
See also:		 install imsg irqkill
Turn off VIA interrupts, irqkill ( -- )6
Screen/Graphics words.
(640mode)
(cursor)
(dotmode)
(move_wind)
(open640)
(pall)
(pallette)
(rseed)
(w320)
(w640)
(wclose)
(wget)
( 0/1 -- )
See also:		 open640 open320 close320 close640
1616 syscall to clear/Set 640 pixel mode.
( mask enable rate -- )
See also:		 cursor_on cursor_off cursor?
1616 syscall to set the cursor mode.
( dotmode -- )
See also:		 dot_xor dot_write dot_or dot_and
1616 syscall to set the point plotting mode.
( mode buff -- )
See also:		 wopenq wcloseq (wget) wopen wclose (wsize)
1616 syscall to move current window contents to/from {buff}
See also:		 open640 close640 open320 close320
Utility word to open a new screen mode.
( -- )
See also:		 .pal0 .pal1 .pal2 .pal3 make_pallette
Structure used for pallete definitions.
( colour pallettepos -- )
See also:		make_pallette
1616 syscall to set a palette entry.
( -- addr )
See also:		 random
Variable containing current 32-bit random seed value.
( -- w.addr )
See also:		 open320 open640 close320 close640 make_window
Window structure for default 320 pixel window.
( -- w.addr )
See also:		 open320 open640 close320 close640 make_window
Window structure for default 640 pixel window.
( -- )
See also:		 wclose wcloseq close320 close640 (wopen)
Close a window without restoring original screen contents.
( w.addr -- )
See also:		 (move_wind)
Put the contents of the window {w.addr} is defined for
into a buffer on the return stack, setting the appropriate
fields in {w.addr}
Screen/Graphics words.
Forth 6-1(wind)
(window)
(wopen)
(wput)
(wset)
(wsize)
(x)
(y)
.bg_col
.curs_x
.curs_y
.fg_col
.oldwin
.wsave
.xend
.xstart
.yend
.ystart

6-2 Forth

( -- )
See also:		 make_window
Structure definition of a window.
( w.addr/0/1 -- w.addr )
See also:		 make_window w_default w_default?

w_current? w_reset

1616 syscall to set the current window.
( w.addr -- )
See also:		 (wclose) wopen wclose
Open a screen window without saving its contents.
( -- )
See also:		 (wget) wclose
Restore a window’s original contents.
( w.addr -- )
See also:		 (window)
Set the current window.
( w.addr -- size.in.bytes )
See also:		 (wget) (wput)
Returns the number of bytes needed to store the
contents of {w.addr}.
( -- x-value )
See also:		 line_to (y) dot_pos
Last x-value used in a line_to or dot_pos.
( -- )
See also:		 line_to (x) dot_pos
Last y-value used in a line_to or dot_pos.
( w.addr -- w.addr+offs )
See also:		 make_window (wind) wopen wclose
Words to access the fields of a window structure.
word: background colour mask
word: cursor pos x rel. to current window
word: cursor pos y rel. to current window
word: foreground colour mask
longword: link to previously open window
longword: link to buffer containing previous screen contents
word:
x right boundary+1
word:
x left boundary
word:
y bottom boundary+1
word:
y top boundary
( p.addr -- p.addr+offs )
See also:		 make_pallette pallette? show_pallette
Words to access the four colours in a palette.
Each is a byte in length.
Screen/Graphics words..pal0
.pal1
.pal2
.pal3
640?
abort
bd_col
bg_col
bg_col?
close320
close640
colour
colour?
colourdot
cursor?
( -- f )
See also:		 open640 close640
f is true (1) if the current screen mode is 640 pixels.
( -- )
See also:		 edit shell
Same as kernel ‘abort’, except that ‘abort’ now closes down
any open windows, turns the cursor on and sets the screen
mode to 640.
( colour -- )
See also:		 fg_col bg_col
Set the border colour.
( colourmask -- )
See also:		 bd_col fg_col .bg_col bg_col?
Set the screen backgroud colour (will not affect text already
on the screen).
( -- colourmask )
See also:		 bg_col
Returns the current background colour.
( -- )
See also:		 open320
Closes the currently open 320 pixel screen and returns
to the previous window, restoring the previous graphics
mode.
( -- )
See also:		 open640
Closes the currently open 640 pixel screen and returns
to the previous window.
( colour -- )
See also:		 dot line_to colour? colourdot
Sets the current graphics drawing colour.
( -- colour )
See also:		 colour dot line colourdot
Returns the current graphics colour.
( colour y x -- )
See also:		 dot line
Plots a dot in colour {colour}.
( -- f )
See also:		 cursor_on cursor_off cursor_pos?
f is true (-1) if the cursor is currently on.
Screen/Graphics words.
Forth 6-3
cursor_off
cursor_on
cursor_pos
cursor_pos?
dot
dot?
dot_and
dot_or
dot_write
dot_xor
dot_pos
downarrow
edit
fg_col
fg_col?
flushc
6-4 Forth
( -- )
See also:		 cursor_on cursor? cursor_pos
Turn cursor off.
( -- )
See also:		 cursor_off cursor? cursor_pos
Turns cursor on.
( y x -- )
See also:		 cursor_pos? cursor?
Set the cursor position on the screen.
( -- y x )
See also:		 cursor_pos cursor?
Returns the cursor position on the screen.
( y x -- )
See also:		 dot? colour colourdot line line_to
Set a point on the screen in the current graphics colour.
( y x -- colour )
See also:		 dot colour colourdot line line_to
Returns the colour of the dot at (x,y).
( -- )
See also:		 dot line (dotmode)
Set cursor plot mode.
( y x -- )
See also:		 line_to
Set position for subsequent ‘line_to’
( -- ch )
See also:		 uparrow leftarrow rightarrow
Returns the ascii value of the downarrow character.
( -- )
See also:		 abort shell
The original kernel ‘edit’, except that the current
screen is saved & 640 pixel mode entered when edit
is invoked.
( colourmask -- )
See also:		 bg_col .fg_col
Set text foreground colour.
( -- colourmask )
See also:		 bg_col? .bg_col
Get text foreground colour.
( -- )
See also:		Screen/Graphics words.home
line
line_to
make_pallette
make_window
open320
open640
pallette?
random
rightarrow
shell
Flush any characters from the keyboard buffer.
( -- )
See also:		Home the cursor (put it at (0,0) relative to current window)
( y1 x1 y2 x2 -- )
See also:		 line_to colour dot_pos
Draw a line in the current graphics colour from (x1,y1)
to (x2,y2).
( x y -- )
See also:		 line dot_pos
Draws a line from (x,y) to the previous dot_pos. (x,y)
becomes the next dot_pos.
( p3 p2 p1 p0 -- )
See also:		 make_window .pal0 show_pallette pallette?

Usage:

n3 n2 n1 n0 make_pallette {token}
Makes a palette file for setting the palette in 640 pixel
mode.
( yend xend ystart xstart -- )
See also:		 wopen wclose
Usage:		{ye} {xe} {ys} {xs} make_window {token}
Makes a window structure called {token}.
( -- )
See also:		 wopenq close320 wopen open640
Opens the whole screen as a window and sets the current
graphics mode to 320 pixels. ‘open320’s may be nested.
( -- )
See also:		 wopenq close640 wopen open320
Opens the whole screen as a window and sets the current
graphics mode to 640 pixels. ‘open640’s may be nested.
( -- pall.addr )
See also:		 make_pallette .pal0
Returns the address of the default palette structure.
( n -- rand# )
See also:		 (rseed)
Returns a random number between 0 and (n-1), inclusive.
’random’ may only be used to generate random numbers
between 0 and 65535, although the cycle length of
the generator is 2^32.
( -- chr )
See also:		 leftarrow downarrow uparrow
Returns the ascii value of the rightarrow character.
( -- )
See also:		 abort edit
Screen/Graphics words.
Forth 6-5
show_pallette
ticks?
uparrow
w_copy
w_current?
w_default
w_default?
w_reset
6-6 Forth
The same as the kernel ‘shell’, except when screen is loaded
’shell’ sets the screen mode to 640 pixels upon entry
and restores the FORTH window after ‘quit’.
( pall.addr -- )
See also:		 make_pallette pallette? .pal0
Put the palette structure at pall.addr into the 1616’s
hardware palette register.
( -- n )
See also:		 wait
Returns the number of 50Hz ticks counted since 1616 turn-on.
This word is useful for timing things.
Example:
: time1000000
ticks
1000000 1 do loop ( loop 1000000 times )
ticks - ~ ( calculate ticks taken )
. ." ticks taken to loop 1000000 times." crlf ;
( -- chr )
See also:		 downarrow leftarrow rightarrow
Returns the ascii character for uparrow.
( src.w.addr dst.w.addr -- )
See also:		 wopenq make_window
Copies the contents of {src.w.addr} to {dst.w.addr}. This
word is usually used to copy template windows into the
return stack, so that the same window may nested several
times.
( -- w.addr )
See also:		 wopen make_window w_reset w_default?
w_default

This word returns the window structure currently in use. As well as returning its address, this word also causes the current cursor position etc. to be copied into the window structure.

( -- )
See also:		 w_reset w_default? wopen abort
This word resets the current window to be the default 1616
window, so if the current window has become corrupted,
w_default will restore the 1616 window to be the original.
( -- w.addr )
See also:		 w_default w_reset wopen
Returns the address of the default 1616 window.
( -- )
See also:		w_default
Resets the current window to be the default, and sets 
the cursor position to (0,0), resets the background colour 
and sets the margins to their usual state.
Screen/Graphics words.wait
wclose
wcloseq
wopen
wopenq
( n -- )
See also:		 ticks
Waits for {n} ticks, or n/50 seconds.
( -- )
See also:		 wopen open320 wopenq (wclose)
Closes the currently open window and restores the previous
window contents. If no previous window was opened, or
an attempt is made to perform this in direct mode, a crash
is possible. ‘wclose’ does not free the space allocated
on the return stack for the screen buffer; this space
will only be freed when either an ‘unlink’ is executed
or the word containing ‘wopen’ terminates.
( -- )
See also:		 wclose close320 (wclose)
Closes the window currently opened with ‘wopenq’ and restores
the previous window contents. See ‘wclose’ for more info.
Note that a window opened with ‘wopenq’ requires two ‘unlink’s
to free the space allocated to it.
( w.addr -- )
See also:		 wopenq open320 wclose
Opens the window structure pointed to by w.addr, saving
the screen contents. wopen’s with the same w.addr may
not be nested.
( -- )
See also:		 wopen open320 wcloseq
Open a new window with the same characteristics as the current
window, saving the screen contents. wopenq’s may be nested.
Summary
(640mode)
(cursor)
(dotmode)
(move_wind)
(open640)
(pall)
(pallette)
(rseed) .pal0
(w320)
(w640)
(wclose)
(wget)
(wind)
(window)
(wopen)
(wput)
(wset)
(wsize) abort
(x)
(y)
.bg_col
.curs_x
.curs_y
.fg_col
.oldwin
bd_col
bg_col
bg_col?
close320
close640
colour
colour?
colourdot
.pal1
.pal2
.pal3
.wsave
.xend
.xstart
.yend
.ystart
640?
Screen/Graphics words.
home
cursor?
cursor_off
cursor_on
cursor_pos
cursor_pos?
dot
dot?
dot_and
dot_or
dot_pos
shell
dot_write
dot_xor
downarrow
edit
fg_col
fg_col?
flushc
w_reset
line
line_to
make_pallette
make_window
open320
open640
pallette?
random
rightarrow
show_pallette
ticks?
uparrow
w_copy
w_current?
w_default
w_default?
wait
wclose
wcloseq
wopen
wopenq

Forth 6-7
Window examples.
1.
Opening a simple full-screen window
: wtest1
wopenq
( opens window and saves contents )
clear
1000 1 do i . loop
cget drop
wcloseq
( fill the screen with garbage )
( wait for a key & drop it )
( closes window & restore screen
contents )
;
2. Opening a small message window
15 60 10 20 make_window messagewindow( make a window )
hex 5555 constant col1 decimal( constant for background col )
col1 messagewindow .bg_col w!( set its bg colour )
: wtest2
messagewindow wopen
( opens 5x40 window & saves contents )
clear
crlf crlf ."
cget drop
wclose
This is a message."
;
3.
Plotting points in 320 pixel mode
: plot3
open320
wopenq
clear
cursor_off
15 colour
begin
200 random
320 random
dot
cget?
until
drop
cursor_on
wcloseq
(
(
(
(
( set screen mode to 320 pixels )
save screen contents )
clear screen )
turn off annoying cursor )
set default colour )
(
(
(
(
(
(
(
( get random y )
get random x )
plot point )
key pressed ? )
if no, back to begin )
drop keypress )
on again! )
must close windows in right
order )
close320
;
For more examples, see the numerous demo programs.
6-8 Forth
Screen/Graphics words.7
The files on the Forth disk are:
FORTH.S
FORTH
WORDS.F
SCREEN.F
FLOAT.F
FILE.F - Source code for FORTH
- Assembled code
- Kernel word definitions
- Screen words
- Floating point words
- File manipulation words
START.TXT
KERN.TXT
FLOAT.TXT
FILE.TXT
SCREEN.TXT - Little tutorial
- Kernel documentation
- Float documentation
- File documentation
- Screen documentation
MAND3.F
HEAP.F
DEMO.F
IRQ.F
KERN.F
FSORT.F
SPHERE.F
HELP.F
STRING.F
SIEVE.F
GRAV.F - Demo program - start with ‘mshell’
- Heap management words
- Demo program - start with ‘demostart’
- IRQ demos
- Help helper
- File sorter
- Demo program - start with ‘spheres’
- Help program - ‘help {word} [{file}]’
- String comparisons/copies
- Prime number calculator - start with ‘sieve’
- Gravity demo - start with ‘grav’
README
MEM
TY
SESAME
SSASM
MSCREEN - What you read now
- Print free memory (transient)
- Type a file (transient)
- SSASM a file & leave listing file in errors.
- SSASM
- Screen for mand3.f
To get FORTH started, type:
*FORTH words.f
To get an idea of what it does,
>load demo.f
>demostart
Enjoy!

The files on the Forth disk are:

The Last Read Me file

Here is a working version of my FORTH for the new version of the operating system. The documentation has not yet been fully upgraded; however, ninety percent of it is correct.

To start it up, you must ‘cd /f0/bin’ before executing ‘ff’, which allocates 64k of space for FORTH, and the loads and executes it. To load most FORTH stuff, you must be in the /f0/forth directory. It would be nice to add a search path for FORTH later on.

I’ve written a bit more since the last version you would have seen. The floating point routines have been debugged and speeded up somewhat, and a tiny Pascal->FORTH compiler thingy and a small LISP interpreter have been hacked together.

I’ve found only three actual bugs in the OS which you probably already know about: firstly, cd doesn’t always work, and secondly, there are some crashes I’ve been in which produce another error each time the reset button is pushed; turning the machine off was the only solution. The third bug is that the system fails to close files after a program finishes.

Other nice features worth having:

For some screen applications (that is, games and graphics), the clock is a pain: however, turning it off by freeing its interrupt slot is not the right solution, as it cannot be turned back on. Does the MRD stuff allow you to turn things like this off and on ?

Is it possible to guarantee the status of registers not involved in syscalls? I haven’t checked since the first version of the roms I had, but one or two syscalls trashed registers: having to save all registers in use before every syscall is wasteful. The new graphics routines in 80 column mode are lovely and fast: however, the 40 column routines don’t seem as fast. (Perhaps this is the fault of my FORTH, not your routines).

The memory manager gets very slow when lots of little blocks have been allocated, especially when freeing them all after completing a program. It would be nice to be able to open a file given a search path, or even just open a file on the execution path./p>

’Bye, Peter.

PS: I’ll be contactable at home from about the first of July until the fourteenth on (062) 86 2964./p>