-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanual.txt
579 lines (429 loc) · 19.8 KB
/
manual.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
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
CERBERUS Z80 FORTH
(C) Copyright 2022, L.C. Benschop
Released under GPL v3
This program contains Z80 code originally copyrighted 1994, 1995 by
Brad Rodriguez.
1 Introduction
This FORTH system is designed to run on the Z80 CPU of the Cerberus 2080
or 2100 computer.
A useful introduction to FORTH can be found here.
http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm
The FORTH system does not have all features mentioned in that document, such
as local variables and floating point.
1.1 Package contents
The cerberus-z80-forth package contains the following files.
- manual.txt (the user manual).
- forth80.bin (the FORTH binary to run on Cerberus-2080).
- COPYING (the GPLv3 license file).
- glossary.txt (a list of all words in FORTH with a short explanation).
- squares.4th (a short example program).
- primes.4th (a primes benchmark example).
- testcode.4th (example for code definitions).
- restit.4th a Tetris-like game.
- serpent.4th a Snake-like game.
- tester.4th and core.4th (a regression test suite). Note that this is
by a different author and not covered by the GPLv3.
- glosgen.4th and doglos.4th Tools used to generate the glossary.txt file.
These cannot be run on Cerberus Z80 FORTH, but you can run them from gforth
or any other ANSI standard FORTH with the FILE extension wordset.
- crossz80.4th Can be run from gforth to generate Cerberus Z80 FORTH from
source.
- metaz80.4th. The metacompiler, used to generate Cerberus Z80 FORTH from
source.
- asmz80.4th. Source of the FORTH assembler.
- asmtst80.4th assembler file containing all types of instructions. Can
be cross assembled and then the output checked with a disassembler.
- editor.4th. Source of the FORTH editor.
- kernl80a.4th, kernl80b.4th, kernl80c.4th, and extend80.4th: sourcees of
Cerberus Z80 FORTH.
1.2 Prerequisites
You need Dean Belfield's BIOS with additional functions to load and save
files. If you run BBC Basic on the Z80, you will already have this.
https://github.com/breakintoprogram/cerberus-bbc-basic/tree/main/cat
You need to reprogram the CAT chip on your board with this version of BIOS
if you want to run Cerberus 2080 FORTH.
Cerberus 2100 has this version of BIOS as a standard, so you do not need
to reprogram CAT on this machine.
2 Getting started
2.1 Starting up.
Make sure you have the files from the ZIP file on the SD-card, in particular
the forth80,bin file. In addition you also need the chardefs.bin file
on your card.
Make sure you are in Z80 mode, so please type the commands
z80
fast
At the Cerberus command prompt type:
load forth80.bin
Then type the command:
run
You should now see a message like this:
Cerberus Z80 Forth, 2023-08-11 GPLv3
(c) 2023 L.C. Benschop, Brad Rodriguez
You are now at the FORTH command prompt. You can type a FORTH command
like this:
12 23 * .
You should see the the line change to
12 23 * . 276 OK
Forth is a stack-based language and formulas you type use Reverse
Polish Notation. What you just typed:
12 puts the number 12 on the stack,
13 puts the number 13 on the stack.
* takes two numbers from the stack, multiplies them and puts the result
on the stack.
. takes the top number from the stack and prints it.
What FORTH replied to you:
276 is the result of the '.' command the printed result of the multiplication.
OK is a response to tell that there were no errors.
You can add new words to the FORTH language as follows. Type the following
commands:
: SHOW-NUMBERS 20 0 DO I . LOOP ;
Start with a colon (':') and end with a semicolon (';').
After typing this, you should see OK
Then type:
SHOW-NUMBERS
You should now see:
SHOW-NUMBERS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 OK
The colon starts the definition of a new FORTH word. In this case it is
SHOW-NUMBERS. DO and LOOP create a loop (start at 0, run up to but not
including 20). The word I puts the loop index onto the stack. The word
'.' prints this number. The semicolon ends the currently defined word.
You can load a source file by typing the following command:
FLOAD squares.4th
Then Type:
20 SQUARES
You should see:
1 1
2 4
...
20 400OK
You can now view and/or edit the loaded source file with the ED
command. Press the ESC key to leave the editor.
You can go back to the Cerberus command prompt by pressing the F12
key.
From there you can restart FORTH simply by typing the run command again.
Your changes to the dictionary and the loaded source file in memory will
stay intact.
If your FORTH program gets stuck in an endless loop, you can go back
to the command prompt by pressing F12 and go back to the FORTH prompt
by entering the 'run' command.
2.2 Helpful commands
.S
This command shows you the contents of the stack, the word Empty when
the stack is empty.
.S Empty OK
1 2 3 4 .S 1 2 3 4 OK
DUP .S 1 2 3 4 4 OK
+ SWAP - .S 1 2 5 OK
DROP DROP DROP .S Empty
WORDS
This command shows all available words in the FORTH (there may be
additional words in separate word lists). You can stop the command
halfway by pressing the ESC key or you can pause it by pressing any
other key (pressing one further key resumes it).
FORGET <word>
This removes the specified word and any later definitions from the FDRTH
dictionary. When you look at the squares.4th file, you see that it starts
with FORGET SQUARES. You can edit and reload that file many times and each
time it will forget the old definition of SQUARES before compiling the new
one.
2.3 File related commands
Cerberus Z80 FORTH can have one source file in memory, that you can then
edit. The following commands are related to this.
NEW
Create a new empty source file in memory.
OPEN <name>
Load the specified source file into memory. Example:
OPEN squares.4th
SAVE <name>
Save the source file that is stored in memory. Example:
SAVE squares2.4th
OK
Run (compile and/or interpret) the source file that is stored in memory.
ED
Edit the source file stored in memory. Leave the editor by pressing the ESC
key. In fact the editor can edit any ASCII text files, not just FORTH
sources. In principle you can edit this readme.txt file. The commands
OPEN, SAVE and ED work on any text files.
FLOAD <name>
Load the specified file into memory and immediately run it. This is equivalent
to OPEN <name> OK
The commands FLOAD, OPEN, OK and ED are the same as in the F-PC forth
for MS-DOS, introduced in 1988.
CAT
Show all files on disk. You can stop the command by pressing ESC,
pause and resume by pressing any other key.
DELETE <name>
Delete the specified disk file.
addr len BLOAD <name>
Load a file into a specified memory region. For example:
$F000 $800 BLOAD chardefs.bin
addr len BSAVE <name>
Save a memory region into the specified file. For example
$F000 $800 BSAVE mychars.bin
SAVE-SYSTEM <name>
Save the current FORTH dictionary into the specified file. You can later
load this file at the Cerberus command prompt and run it.
Example:
SAVE-SYSTEM myapp.bin
2.4 Glossary file
The file glossary.txt gives a short explanation for every FDRTH word.
This file is generated from the source files.
Each word is accompanied by a stack diagram, like this:
+ ( n1 n2 --- n3)
The numbers shown left of the --- are the numbers that the word expects
as inputs, the numbers shown to the right are the numbers produced by the
word as results. So in this case, '+" expects two numbers n1 and n2 as
inputs and produces one number n3 as a result.
3 The editor
The editor handles both files with LF-only line endings (Unix style) and
files with CR-LF line endings (DOS/Windows style). It keeps the same
line endings when adding more lines and the file will be save with the
same type of line endings as it was loaded.
Typically the editor will show 14 lines from the text file on the screen.
As the screen width is only 40 characters, a line of up to 79 characters will
occupy 2 lines on the screen. 14 lines of 79 characters will fit into 28
screen lines. Cursor up and cursor down move to the next line of the text
file, not to the next line on the screen.
The bottom line of the screen shows the current line number, the file
size and the line-ending style.
The following keys can be used.
ESC leave the editor. The file will not be saved by the editor itself,
use an explicit SAVE command for this.
Page up and Page down step through the file 14 lines at a time.
The cursor keys move through the file as expected.
Backspace will delete the character left of the cursor. If the cursor is
at the start of a line, the end-of-line of the previous line will be
deleted and the current line is joined to the end of the previous line.
Enter will insert an end-of-line. When at the end of a line it will
start a new empty line after the current line, when pressed in the middle
of a line, it will split the current line into two separate lines.
TAB will insert a TAB character
Any printable ASCII character key (SPACE, letters, digits, symbols) will insert
that character at the cursor position.
There are currently no functions for cut/copy/past and for search/replace.
They could be added later.
4 The assembler
This is a prefix assembler, like F-PC used to have. The assembler instructions
look the same as you learned them, as opposed to more traditional FORTH
assemblers, where instructions have a postfix notation. Postfix makes the
implementation of the assembler simpler. In particular for the Z80, most
FORTH assemblers either only implement the 8080 subset of instructions or use a strange mix of 8080 and Z80 mnemonics that are completely nonstandard.
I wanted my Z80 code to look like Z80 code in other assemblers.
However, there are a few small differences:
- You need to attach a comma to each source operand and separate it from
the destination operand by a space, so we write:
ADD HL, BC
ADD A, E
It will not work if you write ADD HL,BC or ADD HL , BC
- Comments to end-of-line are backslashes, not semicolons.
- Direct loads use (), and ()
LD A, $1234 () instead if LD A,(1234h)
LD $4567 (), HL instead of LD (4567h),HL
- Indexed uses (IX+), and (IY+)
ADD A, 4 (IX+) instead of ADD A,(IX+4)
LD -5 (IY+), B instead of LD (IY-5),B
- Support for labels is very limited. It is supported only in the cross
assembler and only for backward references.
Instead you use BEGIN..UNTIL,
BEGIN..WHILE..REPEAT and IF..ELSE..THEN constructs.
Jumps and calls to constant addresses are fine.
Later versions of the assembler my add labels and forward references.
Example code definition:
CODE 3* ( n1 --- n2)
\G Multiply a number by 3
LD L, C
LD H, B \ Copy TOS to HL
ADD HL, HL \ Times 2
ADD HL, BC \ Add original value, so times 3
LD C, L
LD B, H \ Copy result to TOS
NEXT
END-CODE
A code definition starts with CODE and ends with END-CODE.
The word NEXT expands to the instruction sequence to execute the next
threaded code definition. This should be the last thing executed by
(almost) every code definition.
You can use constructs like IF..THEN and BEGIN..UNTIL like this:
CODE CLZ ( u --- n)
\G Count leading zeros.
LD L, C
LD H, B \ Copy TOS to HL
LD A, L
OR H \ Test HL=0
0= IF
LD BC, $10 \ If zero we have 16 leading zeros.
ELSE
LD BC, $FFFF \ Start at -1 as we increment 1 more than leading zeros.
BEGIN
ADD HL, HL \ Shift left
INC BC \ Count one more
U< UNTIL \ Until the last bit shifted out is 1.
THEN
NEXT
END-CODE
The IF, ELSE and UNTIL words expand to (conditional) JR instructions.
For example 0= IF expands to a forward JR NZ to the point at the corresponding
ELSE (or THEN when there is no ELSE).
The U< UNTIL corresponds to a backward JR NC to the point at the corresponding
BEGIN. Only 0=, 0<>, U< and U>= are allowed as conditions.
Plus the weird looking B--0=, which expands to DJNZ.
5 Internals
5.1 Memory Map
0000 Reset vector
0066 NMI handler, empty handler, just RETN
0080-00FF TIB (terminal input buffer)
0100-01FF Return stack
0200-0205 BIOS mailboxes
0205-HERE Forth executable+dictionary
HERE-PAD word buffer, numeric conversion buffer
PAD-PAD+80 temporary workspace
-7FFF Free space
8000-EFFD Source file buffer
EFFE-EFFF Mailbox for expansion slot (Cerberus 2100)
F000-F7FF Character definitions
F800-FCAF Video RAM
FCB0-FD2F LINEBUF (line from file).
FD30-FE2F POCKET (to store literal strings)
FE2F-FFFF Data stack
5.2 Threading model
Cerberus Z80 FORTTH uses the Z80 registers as follows:
DE is the instruction pointer, it points to a list of word addresses inside
a colon definition.
BC is the top of stack
SP is the (data) stack pointer.
IX is the return stack pointer.
All other registers (including the shadow registers) are free to use.
It is a direct threaded FORTH, which means that the NEXT routine jumps
to the Code Field address of the code word. The code field of machine code
words (like + or !) contains machine code. The code field of all other words
contains a CALL instruction to the handler of that type of word.
5.3 Dictionary structure
Cerberus Z80 FORTH uses hashing to speed up dictionary searches. A hash
value is computed from the name by XOR and shift operations on the length,
the first and second (if applicable) characters of the name. The number of
hash chains is a power of 2 (typically it is set to 4) and the hash values
are then 0, 1, 2, 3. Each name is stored in the hash chain corresponding to
its hash value, therefore it needs to be looked up in that same chain.
Splitting the dictionary into multiple chains speeds up searching.
Each wordlist data structure has the following fields.
VOC-LINK 1 CELL, link to previously defined wordlist. FORGET traverses them
all.
#THREADS 1 CELL, the number of hash chains used by this wordlist,
heads #THREADS cells: the heads of the linked lists for each hash chain.
The VOCABULARY defining word has the wordlist data structure in its
parameter field.
Each word has a header that contains the following fields.
Link field 1 CELL contains the address of the name field of the
previous definition in the same hash chain.
Name field Count byte (bits 4..0 specify name length), bit 7 always set.
bit 6 set for IMMEDIATE words, bit 5 unused
followed by as many ASCII characters as specified in count byte.
Code field. directly follows the last byte of the name.
For code words, machine code starts here.
For all other words: contains a CALL to the handler of the word
(call is 3 bytes).
Parameter field: data belonging to the word. For colon definitions this
is a list of code addresses
6 How to recompile
6.1 introduction
Cerberus Z80 FORTH is cross-compiled (meta-compiled) from
FORTH. Originally it was cross-compiled from gforth (a FORTH running
under Linux), but the tools are designed such that they can also run
from Cerberus Z80 FORTH itself. It can be cross-compiled in both ways.
Compiling occurs in two stages:
- The cross-compile stage will produce a bare-bones FORTH system called
kernel80.bin. This system misses many features, but it is powerful
enough to load and compile its own extensions.
- The extension stage will ALWAYS run on Cerberus 2080 (or an emulator of it),
even if kernel80.bin was generated from another FORTH version.
The extension stage is started by running kernel80.bin and loading
several FORTH source files from it. Those source files compile
several additional important FORTH words, the editor and the assembler.
After this you can save the extended system to the SD-card using the
SAVE-SYSTEM command.
6.2 Cross compile from gforth
Run the following command:
gforth crossz80.4th
This file will load asmz80.4th, metaz80.4th, kernl80a.4th, kernl80b.4th and
kernl80c.4th adnd will save kernel80.bin afterwards.
The file kernel80.bin must be copied to an SD-card together with the
source files used in the extension stage.
6.3 Cross compile from Cerberus Z80 Forth.
First run forth80.bin. The standard version of forth80.bin has the
Z80 assembler already loaded. Form a customized version without the assembler
you may need to load the assembler asmz80.4th first.
From Cerberus 2080 FORTH, run the following commands:
FLOAD metaz80.4th
FLOAD kernl80a.4th
FLOAD kernl80b.4th
FLOAD kernl80c.4th
Type the BSAVE command as shown at the end of the compilation process, for
example
17735 7810 BSAVE kernel80.bin
This will write the kernel80.bin file that you need for the extension stage.
Leave FORTH by pressing F12 so you can load and run it next.
6.4 Extension stage.
On the Cerberus 2080 prompt, load and run kernel80.bin
load kernel80.bin
run
This starts a minimal FORTH system. You can now load the extensions.
FLOAD extend80.4th
FLOAD editor.4th
FLOAD asmz80.4th
When extend80.4th and asmz80.4th are loaded a lot of Redefining
messages are shown. This is normal. The editor and assembler are
optional, but extend80.4th is always required.
After loading these packages, save the complete FORTH system using
SAVE-SYSTEM forth80.bin
You may need to delete the old file first by
DELETE forth80.bin
Note: SAVE-SYSTEM and DELETE are loaded by extend80.4th, they are not yet
available in kernel80.bin when it is started.
7 Origin
The machine-independent code and the metacompiler were based on SOD32
FORTH that I wrote in 1994. SOD32 was a virtual 32-bit stack machine.
Much of the design of that FORTH was based on public domain FORTH
implementations of the 1980s, like F-83 by Laxen & Perry and F-PC by
Tom Zimmer and Robert L. Smith.
Later in 1994-1995 I wrote a FORTH for the 6809, based on SOD32
FORTH. This one used a prefix assembler, just like the one used in
F-PC and like the one I now wrote for the Z-80.
When I wanted to create a FORTH for the Cerberus-2080, I wanted to have it
for the Z80 as that is the CPU that I am most familiar with and that IMHO
is more suitable for running FORTH. Besides, Alexandre Dumont was already
working on a FORRTH for the 65C02.
I had a few loose requirements:
- It would be a metacompiled FORTH, generated from an existing FORTH system.
Once it would be complete, it would be able to recompile itself
(be self-hosting). F-83 and F-PC also had this feature.
- The alternative to metacompiling is building the FORTH system using
a traditional assembler. For example Camel Forth is written using a
macro assembler. The problem with this is that you are not self-hosting
and that most FORTH implementations depend on very specific macro features
found in one specific cross assembler that may not be available or only
runs under DOS.
- Like F-PC it would load source code from text files. I also considered a
block-based system, but I decided against it for the following reasons.
- BIOS would only allow to read and write files in one go. It would not
support the random access that allowed you to maintain a very large
disk file and have only a few blocks in memory at once.
- Blocks have traditionally 16 lines of 64 characters each. This did not
work well with the 40 column screen of Cerberus. 40 columns is not
ideal for text files, but one can write text files with short lines.
- It would contain a text file editor, like F-PC.
- It had to be loosely ANS Forth based.
- It had to have a prefix assembler, like F-PC.
I ended up using most of the primitives of Camel Forth, a FORTH
written for the Z80 by Brad Rodriguez in 1994 and 1995. Cerberus Z80
Forth is NOT Camel Forth, it just contains code from it. I could have
picked the Z80 primitives from my old ZX-Spectrum FORTH instead, but
CamelForth promised to be faster.
The main thing missing was a Z80 assembler. I could not find any good
ones written in FORTH. The Z80 assembler I used for my ZX Spectrum
Forth was a postfix assembler (I think I could even live with that),
but it also had weird mnemonics unlike the well-known Z80 mnemonics
and more like the 8080 mnemonics, but not quite that. So I decided to
write my own Z80 assembler in FORTH that was a prefix assembler. This
was more of a challenge than I thought at first, but I got it done.
Others who read my source code can now at least recognize the
assembler instructions.