forked from lawrencewoodman/xAce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
forth.txt
316 lines (258 loc) · 11.3 KB
/
forth.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
- C R A S H C O U R S E I N F O R T H -
by Edward Patel, Jan 1998
Abstract.
Forth is a small and effective programming language. Not many are
aware of its existence or how its is used. This crash course was
written together with the Jupiter ACE emulator, xace, to show how
Forth is used on the Jupiter ACE. Jupiter ACE is the *outsider*
micro from the 80's. Instead of the common BASIC it has Forth as
its programming language.
I will not give a full description of Forth but rather a small
picture how it works and is used. Forth is also a set of flavours
that differ in some parts. The Jupiter ACE has the FORTH-79 as its
base but lacks some of its words, it has also some additional words
for its own purpose, i.e using tapes as storage.
For a better understanding about Forth read a book like Leo
Brodie's 'Starting FORTH' or try the web-tutor for '4tH' (Jan98)
http://www.geocities.com/SiliconValley/Bay/2334/4thtutor.htm
The Vocabulary.
Forth is a set of words that when they are executed they carry out
some predefined actions. To execute a word just type it and press
enter. To see a list of all words that can be used type 'vlist'
and press enter. This set of words can easily be extended. Example:
: hello ." Hello, world!" cr ;
This example show how a word 'hello' is defined and that it will when
executed print 'Hello, world!' on the screen. The colon means 'compile
word' and the word after it, here 'hello', will be the name of the
new word. The '."' is also a Forth word because Forth interprets all
clusters of non-space characters as words. The word '."' means (will
mean - in a strictly forth manner) print to screen all characters up
to the first '"' and here that will be 'Hello, world!'. The '"' is
the end-of-output delimiter and the next word will be 'cr' that means
output a carriage-return character. The last word ';' means end of the
compiled words actions.
A word can be defined several times. A new definition does not remove
the old one but rather means that any new use of the word will use the
new definition. Example:
: abc ." old definition" cr ;
: test abc ;
: abc ." new definition" cr ;
test
In this example the word 'test' uses the word 'abc' which by the order
of defining is the word that prints 'old definition'. When the new 'abc'
is defined it will not alter 'test' or the old 'abc' but rather declare
a new 'abc' for future use. Because Jupiter ACE doesn't make use of
whats known as the EDITOR, that is used during software development,
it has a special word 'redefine' that will change old words and their
usage to new ones. After 'redefine abc' will 'test' in the example
above print 'new definition'.
A word that can't be found in the vocabulary will Forth try to
interpret as a number and place on the stack. If the word can't be
interpreted as a number will Forth print a '?' at the word.
The Stacks.
Forth uses a stack to exchange parameters between words. A calling word
should first place the parameters on the stack for a word that will be
executed and then execute it. When a called word is finished it should
place the result on the stack so that a calling word can then use it.
The values are often numbers or memory addresses. The word '.' will
print what is on top of the stack (and remove it). Example:
3 2 1 . . . will print 1 2 3
The basic operators '+', '-', '/' and '*' uses two values from the stack
and places the result on the stack. Example:
1 1 + . will print 2
3 1 - . will print 2
4 2 / . will print 2
2 3 * . will print 6
Forth work with integers, here 16 bit. The Jupiter ACE has extra build
in words to handle floating-point numbers. These are 'f+', 'f-', 'f*',
'f/', 'f.', 'fnegate', 'int' and 'ufloat', and to input a floating-point
number add a '.' at the appropriate place, i.e '1.' for 1 or '.1' for
0.1. Note that the floating-point values occupy two values (items) on
the stack.
The stack can be manipulated in different ways. Words for this are;
'dup', 'swap', 'drop', 'rot', 'pick'. 'dup' duplicates the top of stack
value. 'swap' exchanges the two values on top of the stack values. 'drop'
removes the top of the stack value. 'rot' rotates the three values on top
of the stack making the value on top of the stack the second value, the
second value the third and the third value on to of the stack. 'pick'
takes the value on top of the stack and looks up that number of steps
down the stack and gets that value. Examples:
1 dup . . will print 1 1
2 1 swap . . will print 2 1
2 1 drop . will print 2
3 2 1 rot . . . will print 3 1 2
4 3 2 1 3 pick . . . . . will print 3 1 2 3 4
Example of value passing through the stack.
: add4 4 + ;
: add8 add4 add4 ;
5 add4 . will print 9
5 add8 . will print 13
Forth has also a second stack called the return stack. This stack is used
to store return addresses during execution of a called word and other misc
things. The words 'r>' and '>r' is often used to move values back and
forth between the stack and return stack. '>r' means move a value from the
stack to the return stack and 'r>' means move a value from the return stack
to the return stack.
Constants and Variables.
A constant can be created as;
: max.x 63 ;
which is a word 'max.x' that places the value 63 on the stack. Because
this a common thing to do Forth has a word just for creating constants and
its name is 'constant'. Example:
63 constant max.x
This does the same as the previous example. A variable is similar but the
user is able to change its value. When the variables name (word) is
executed it rather gives a value that can be used to access the value
of the variable, both for reading and writing. Example:
12 variable x
x @ . will print 12
13 x ! will set x to 13
x @ . will print 13
The word 'variable' takes a name and a value from the stack and allocates
some memory for the variable. When the new word for the variable is
executed it places a value on the stack (the address). The word '@' takes
a value from the stack and looks up in memory the value stored at that
address. The word '!' takes two values from the stack, the top of stack
is the address where the second value will be stored.
Repetitions and Decisions.
The simples way of doing a repetition is by using the words 'do' and
'loop'. Example:
: test 100 0 do ." >" loop ;
test will print 100 '>' characters
The word 'do' takes two values from the stack. The top of stack is the
starting value (here 0) and the second (here 100) the value when the
repetition should be ended. With the word 'i' can one access the current
value for the repetition. Example:
: test 10 4 do i . loop ;
test will print 4 5 6 7 8 9
Note that the 10 is not printed in the above example. Note also that
the word 'loop' increases the value by one all the time. There is a
special variation of the word 'loop' that is '+loop' which takes a values
from the stack and uses that as the increment. Example:
: test 0 5 do i . -2 +loop ;
test will print 5 3 1
More complicated repetitions are available with the words 'begin',
'until', 'while' and 'repeat'. The word 'begin' marks where the
repetition begins (returns to). The word 'until' takes a value from
the stack, if it is zero (false) it will repeat the loop from the word
'begin'.
: test begin dup . 1- dup 0= until drop ;
5 test will print 5 4 3 2 1
The word '1-' is an optimized shortcut for the pair '1' and '-'. The
word '0=' is an optimized shortcut for the pair '0' and '='. The word
'=' is a test operator that takes two values from the stack and if they
are equal it will place a one (true - or minus one depending on the
Forth) on the stack and if they are not equal it will place zero (false)
on the stack.
The next repetition construction uses the words 'begin', 'while' and
'repeat'. The word 'begin' work like in the 'until' case but in this
case will the word 'repeat' unconditionaly repeat the loop from the
word 'begin'. The word 'while' is placed somewhere inbetween a 'begin'
and a 'repeat' and it takes a value from the stack. If the value is
zero (false) it will leave the repetition and continue executing after
the word 'repeat'. If the value is not zero (true) it will not do
anything which in effect means that it will continue to the word 'repeat'
and there repeat the repetition from the word 'begin'. Example:
: test begin dup while dup . 1- repeat ;
5 test will print 5 4 3 2 1
For simple decisions there are the words 'if', 'else' and 'then'.
The word 'if' takes one value of the stack. If the value is zero (false)
will 'if' ignore everything until the word 'else' (or 'then' if the 'else'
is missing) and continue executing after the word 'else'. If the value is
not zero (true) will everything inbetween the word 'if' and the word 'else'
(or 'then' if the 'else' is missing) be executed and everything inbetween
the word 'else' and the word 'then' will be ignored. Example:
: test 0= if ." in" then ." complete!" ;
0 test will print 'incomplete!'
1 test will print 'complete!'
: test if ." True!" else ." False!" then ;
0 test will print 'False!'
1 test will print 'True!'
Note that 'if' constructions can be nested. Example:
if -----+
if ---+ |
else ---+ |
if -+ | |
then -+ | |
then ---+ |
else -----+
if -+ |
then -+ |
then -----+
Compiling words.
TBD. Creating your own compiling words.
Jupiter ACE words.
save
save <name> saves the vocabulary as <name>
load
load <name> loads the vocabulary <name>
verify
-
bsave
s l bsave <name> saves l bytes from the memory
starting at address s as <name>
bload
s l bload <name> loades 0 bytes to the memory
starting at address s as <name>. If s or l is
zero will their value be taken from the file.
bverify
-
list
list <word> lists the definition of <word>
edit
edit <word> loads the <word> so the user can
edit it. When the user presses enter will a
new definition be compiled. Use 'redefine' to
update the new definition for older usages
of the word.
redefine
redefine <word> removes the old definition of
<word> and updates the older usages of it.
f+, f-, f*, f/, f., fnegate, int, ufloat
floating-point number words
ascii
ascii <word> puts the first letter in <word> on the
stack as its ascii value
at
l c at sets the next printing position on the screen,
l can be from 0 to 22 and c can be from 0 to 31.
beep
T t beep - sounds the beeper with tone T
(specially calculated value) for t milliseconds
call
addr call will call Z80 machine code at addr, should
be terminated with a 'jp (iy)'
cls
clears the screen
fast
disables some error checking routines making it all
run 25% faster
in
does a Z80 IN (x) - used for communicating with
external hardware
inkey
reads the keyboard, puts the ascii value of the key
or 0 if no key is pressed
invis
disables the printing to the upper part of the screen
line
interprets the input buffer as a normal FORTH line
number
-
out
does a Z80 OUT(x) - used for communicating with
external hardware
plot
x y m plot - plots a dot at position (x,y) with
mode m. (0,0) is the lower left corner and (63,45)
is the upper right corner.
retype
-
slow
enables some error checking routines (normal execution)
vis
enables the printing to the upper part of the screen
definer <name> ... does>
is the same as : <name> CREATE ... DOES>
compiler <name> ... runs>
-