Tiny-Forth-Compiler zum Abtippen
Die Programmiersprache Forth ist zur Zeit in aller Munde. Unser Listing des Monats gibt Ihnen die Möglichkeit, Forth einmal praktisch zu erleben.
Forth ist eine der jüngsten Programmiersprachen. Sie wurde 1969 von Charles Moore am National Radio Astronomy Observatory in den USA entwickelt. Der Name der Sprache lautete eigentlich Fourth (das Vierte), aber der IBM-Computer, auf dem Forth entwickelt wurde, ließ nur fünf Buchstaben als Namensangabe zu, so entstand »Forth«.
Forth ist eine der schnellsten Programmiersprachen, die es gibt. Vor allem auf Heimcomputern wird es deshalb gerne eingesetzt. Dazu kommt, daß Forth nicht viel Speicherplatz beansprucht. Die Sprache besteht nicht nur aus einem Compiler, sondern auch aus einem Interpreter; beide arbeiten Hand in Hand.
Die wohl auffälligste Eigenart von Forth ist die Art und Weise, in der Forth rechnet. Es ist die sogenannte »UPN« (Umgekehrte Polnische Notation), auch Postfix-Notation genannt. Sie ist es unter anderem, die Forth die Geschwindigkeit verleiht (10 bis 20mal so schnell wie Basic). Doch was bedeutet UPN?
Ein Beispiel: Sie wollen das Ergebnis von 8 + 5 auf dem Bildschirm ausgeben. In Basic sähe das dann so aus: »PRINT 8 + 5«. In Forth schreibt sich das etwas anders: »5 8 + .«. Scheinbar verwirrend, aber nur auf den ersten Blick. Denn das Prinzip ist einfach. Im Mittelpunkt von Forth steht der Stack (Stapel). Man stelle sich einen Stapel Papier vor, auf den man Blätter obenauflegen kann und auch nur von oben wieder nehmen kann. Das bedeutet, das Blatt, welches Sie zuletzt draufgelegt haben, wird als erstes wieder heruntergenommen. Man nennt dieses System auch »LIFO« (Last In — First Out). Doch wie kann man damit rechnen? Kommen wir wieder zu unserem Beispiel zurück. Der Computer legt als erstes die Zahl 5 auf den Stack. Bild 1 verdeutlicht das Prinzip. Der TOS (Top of Stack) hat jetzt den Wert 5. Dann folgt die »8« nach dem gleichen Verfahren. Darauf addiert der Computer die zwei obersten Zahlen und legt das Ergebnis auf den Stack, dafür ist »+« verantwortlich. Jetzt haben wir zwar das Ergebnis auf dem Stack, können es aber nicht sehen. Für die Ausgabe von 16 Bitzahlen ist der Befehl ».« zuständig. Damit wird immer der jeweilige Wert des TOS ausgegeben.

Diese Art des Rechnens mittels UPN mag für Menschen sehr gewöhnungsbedürftig sein, für den Computer ist sie ideal. Doch Forth besitzt neben seiner Geschwindigkeit auch noch weitere Vorteile:
- In Forth können Sie Ihre eigenen Befehle definieren. Es gibt dann in der Benutzung keinen Unterschied mehr zwischen den vordefinierten und Ihren eigenen Befehlen.
- Forth besteht nicht nur aus einem Compiler, sondern auch aus einem Interpreter. Dies gibt Ihnen die Möglichkeit, selbstentwickelte Befehle sofort zu testen.
- Eine sehr hohe Geschwindigkeit beim Compilieren (1 Pass-Compiler)
- Strukturierte Programmierung ohne GOTO
Sie sehen also, Forth ist eine Sprache, mit der zu beschäftigen es sich lohnt.
(Alexander Schindowski/ev)Forth ist sicher eine der interessantesten Programmiersprachen überhaupt. Unser neues Listing des Monats stellt diese Sprache jedem C 64-Besitzer zur Verfügung.
Die folgende Anleitung zur Handhabung des Forth-Compilers kann natürlich kein Lehrbuch ersetzen. Falls Sie mit Foth noch keinerlei Erfahrungen haben, finden Sie im Anhang eine Übersicht über Forth-Literatur. Doch nun zur Beschreibung unseres Tiny-Forth-Compilers.
Die folgenden Befehle haben so gut wie alle einen Einfluß auf den Stack. Deshalb wird eine verkürzte Schreibweise verwendet, um das Verhalten der einzelnen Befehle darzustellen: »(Stack vorher - - - Stack nachher) «.
Die verwendeten Symbole haben folgende Bedeutung: n = 16-Bit-Zahl, b = 8-Bit-Zahl, c = ASCII, addr = Adresse, f = Flag (0/1).
Die einzelnen Befehle des Tiny-Forth-Compilers sind in Tabelle 1 noch einmal übersichtlich dargestellt. Im folgenden werden die Befehle genauer beschrieben:
Arithmetikbefehle
Addition »+« (n2 n1 - - - n3)
Der Additionsbefehl holt die ersten beiden Argumente (n1,n2) vom Stack, addiert sie miteinander und legt das Ergebnis (n3) in den TOS (Top of Stack).
Subtraktion »-« (n2 n1 - - - n3)
Der Subtraktionsbefehl holt, wie bei der Addition, die ersten zwei Argumente (n1,n2) vom Stack, das Ergebnis (n3) wird wieder im TOS abgelegt.
Multiplikation »*« (n2 n1 - - - n3)
Die Multiplikation verhält sich analog zur Addition und Subtraktion.
Division »/« (n2 n1 - - - n3)
Analog zu Multiplikation.
Modulo »MOD« (n2 n1 - - - n3)
Ähnlich einer Division, es wird aber nicht das Ergebnis der Division, sondern der Divisionsrest auf den Stack gelegt.
Vergleichsbefehle
Gleich »=« (n2 n1 - - - f1)
Es werden die zwei obersten Werte auf Gleichheit geprüft.
Größer »<« (n2 n1 - - - f1)
Es wird geprüft, ob n2 größer als n1 ist.
Kleiner »>« (n2 n1 - - - f1)
Es wird geprüft, ob n2 kleiner als n1 ist.
Logische Verknüpfungen
AND (n2 n1 - - - n3)
Zwischen den Werten n1 und n2 wird eine logische UND-Operation ausgeführt.
OR = (n2 n1 - - - n3)
Es wird ein logisches ODER ausgeführt.
XOR (n2 n1 - - - n3)
Es wird ein logisches exklusives ODER ausgeführt.
NOT (f1 - - - f2)
Das oben liegende Flag wird invertiert.
Stackoperatoren
DROP (n2 n1 - - - n2)
Der oberste Wert wird vom Stack entfernt.
DUP (n1 - - - n1 n1)
Der oberste Wert auf dem Stack wird dupliziert.
SWAP (n2 n1 - - - n1 n2)
Die obersten beiden Werte werden vertauscht.
OVER (n2 n1 - - - n2 n1 n2)
Kopiert den zweiten Wert zum neuen TOS.
PICK (n1 n - - - n1 n2)
Pick holt den n-ten Wert in den TOS.
ROT (n3 n2 n1 - - - n2 n1 n3)
Rot läßt die ersten drei Elemente des Stack gegen den Uhrzeigersinn rotieren.
@ (addr - - - n1)
Holt eine 16-Bit-Zahl aus der Adresse addr.
! (n1 addr - - -)
Speichert eine 16-Bit-Zahl in der Adresse addr.
c@ (addr - - - b1)
Holt eine 8-Bit-Zahl aus der Adresse addr.
c! (b1 addr - - -)
Speichert eine 8-Bit-Zahl in der Adresse addr.
Kontrollstrukturen
BEGIN — UNTIL (f - - -)
Der Programmteil zwischen BEGIN und UNTII wird solange ausgeführt, bis der TOS bei UNTIL ungleich Null ist.
BEGIN — WHILE — REPEAT (f - - -)
Der Programmteil zwischen BEGIN und REPEAT wird solange ausgeführt, wie der TOS bei WHILE ungleich Null ist.
IF — ENDIF (f - - -)
Der Programmteil zwischen IF und ENDIF wird nur dann ausgeführt, wenn der TOS bei IF ungleich Null ist.
IF — ELSE — ENDIF (f - - -)
Bei erfüllter Bedingung wird der Programmteil zwischen IF und ELSE ausgeführt, bei nichterfüllter Bedingung der zwischen ELSE und ENDIF.
Schleifen
DO (n2 n1 - - -)
DO legt die Argumente n1 (Endwert), n2 (Startwert) auf den Returnstack und leitet eine Schleife ein.
LOOP (- - -)
LOOP erhöht den Schleifen-Zähler um 1, ist der Endwert nicht erreicht, wird wieder zu dem auf DO folgenden Befehl gesprungen.
I (- - - n)
Der Befehl I legt den Wert des Schleifenzählers auf den TOS.
+LOOP (n - - -)
+LOOP erhöht den Schleifenzähler um n, weiter wie LOOP.
Ein-/Ausgabeoperatoren
KEY (- - - c)
Holt den ASCII-Wert, der gerade gedrückten Taste in den TOS, ist keine Taste gedrückt, so wird eine 0 in den TOS gelegt.
GET (- - - c)
Wartet, bis eine Taste gedrückt wird und legt dann ihren ASCII-Wert in den TOS.
EXPECT (addr n - - -)
Erwartet eine Eingabe, die mit Return abgeschlossen wird, und legt sie bei addr mit einer maximalen Länge n im Speicher ab. Als Abschlußzeichen wird eine 13 in den Speicher gesetzt.
EMIT (c - - -)
EMIT gibt den auf dem TOS liegenden ASCII-Wert auf dem Bildschirm aus.
TYPE (addr n - - -)
TYPE gibt n Zeichen, welche ab addr im Speicher stehen, auf dem Bildschirm aus.
CR (- - -)
CR bewirkt einen Zeilenvorschub.
CLS (- - -)
Löscht den Bildschirm.
."TEXT" (- - -)
Gibt den Text zwischen »."« und »"« aus (funktioniert nur in compilierter Form).
Definitionsbefehle
n CONSTANT ⟨Name⟩ (n - - -)
CONSTANT definiert eine Konstante mit dem Wert n und dem Namen ⟨Name⟩. Wird ⟨Name⟩ im Programm aufgerufen, so wird n auf den TOS gelegt.
n VARIABLE ⟨Name⟩ (n - - -)
VARIABLE definiert eine Variable mit dem Wert n und dem Namen ⟨Name⟩. Wird ⟨Name⟩ im Programm aufgerufen, so wird die Adresse der Varible auf den Stack gelegt. Ein Wert wird mit @ (lies: Fetch) auf den TOS geholt und mit! (lies: Store) an eine Variable übergeben.
n MEMORY ⟨Name⟩ (n - - -)
MEMORY definiert einen Speicherbereich mit dem Namen ⟨Name⟩ und der Länge n. Wird ⟨Name⟩ im Programm aufgerufen, so wird die Adresse des Speicherbereichs übergeben. In Adresse-2 ist die Länge zu finden und kann mit @ ausgelesen werden. MEMORY ist kein Standardwort!
: ⟨Name⟩…; (- - -)
Der Doppelpunkt definiert ein neues Forth-Wort mit dem Namen ⟨Name⟩. Die Definition muß mit »;« abgeschlossen werden.
Systembefehle
BASIC: Kehrt zum Basic zurück.
RESET: Kehrt zum Ausgangszustand zurück.
LIST n: Listet Screen n auf dem Drucker oder dem Bildschirm. CLEAR n: Löscht SCREEN n auf der Diskette.
LOAD n: Compiliert Screen n in das Vocabulary.
FORGET ⟨Name⟩: Löscht das Wort ⟨Name⟩ aus dem Vocabulary.
VLIST: Listet das Vocabulary.
SAVE-SYSTEM ⟨Name⟩: Speichert den Objektcode und Vocabulary-Einträge aller selbstdefinierten Befehle auf Diskette.
LOAD-SYSTEM ⟨Name⟩: Lädt den Objektcode und die Vocabulary-Einträge wieder. Das System muß vorher mit RESET wieder in den Ausgangszustand gebracht werden und in Zeile 380 muß die Variable VOC denselben Wert wie beim Speichern haben, da sonst die Sprungadressen im Objektcode nicht stimmen.
EDIT n: Ruft den Bildschirmeditor auf, n ist die Nummer des Screens.
Spezialbefehle
CALL (addr - - -)
Ruft ein Maschinenprogramm mit der Adresse addr auf. Es können, wie bei SYS in Basic, in den Speicherzellen 780 das A-, 781 das X-, 782 das Y-Register mit übergeben werden.
R⟩ (- - - n)
Bringt das oberste Element des Return-Stacks auf den Stack.
⟩ R (n - - -)
Bringt das oberste Element des Stacks auf den Return-Stack.
;S (- - -)
Dieser Befehl sorgt für den vorzeitigen Abbruch des aktuellen Befehls.
Das Programm
Das Programm wurde mit Absicht sehr flexibel gehalten. Nach oder während des Abtippens können Sie einige Dinge nach Ihrem eigenen Ermessen ändern. So zum Beispiel die Startadresse des Objektcodes in Zeile 380; die Variable VOC enthält den Startwert. Allerdings sollten Sie nicht unter VOC=5 * 4096 gehen, da sonst eine Kollision mit dem String-Bereich möglich ist. Dies macht sich durch eine »OUT OF MEMORY«-Meldung oder durch einen Systemabsturz bemerkbar. Das Programm kann nur mit 16-Bit-Zahlen arbeiten und umfaßt nicht den gesamten Forth-Standard. Das Programm besteht aus einem Compiler, der in den Zeilen 1540 bis 2610, und einem Interpreter, der in den Zeilen 700 bis 1530 steht. Der Interpreter ist nicht in der Lage, alle Befehle auszuführen. Um Ihnen zu helfen, welche Befehle interpretierbar sind und welche nicht, sind nur die interpretierbaren im Vocabulary aufgeführt. Andere Befehle wie VARIABLE, MEMORY, etc., kurzum alle Definitionsbefehle, dürfen nicht im Compilermodus angewendet werden.
Das Programmieren in Forth
Nach dem Starten des Programms wird zuerst das Maschinenprogramm »VOCABULARY« in den Bereich 49152 bis 50160 geladen. Nach etwa einer Sekunde erscheint ein blinkender Cursor; jetzt können Sie Ihre Eingaben machen. Sie befinden sich im Interpretermodus, das heißt alle eingegebenen Befehle werden sofort ausgeführt. Daß dies im Interpretermodus so langsam geht, liegt nur daran, daß der Interpreter in Basic geschrieben ist; compilierte Befehle laufen dagegen etwa 10- bis 20mal so schnell wie Basic (sie werden vollkommen in Maschinensprache übersetzt). Vielleicht geben Sie mal das folgende Beispiel ein: »8 5 + .« (RETURN). Sie müßten jetzt 13 auf dem Bildschirm erhalten; wenn nicht, dann müssen Sie irgendwo im Programm einen Fehler gemacht haben. Sie können auch Kommentare einfügen, sie werden mit einer »(« begonnen und mit »)« abgeschlossen. Jeder Befehl wird durch ein Leerzeichen (oder Return) vom anderen getrennt.
Doch wie definiert man einen neuen Befehl? Diese Frage wird Ihnen sicher schon lange auf den Lippen brennen. Doch auch hier macht es Ihnen Forth sehr einfach. Um die Definition eines neuen Befehls einzuleiten wird »:« benutzt, gefolgt von dem Namen des neuen Befehls (bitte vergessen Sie nicht das Leerzeichen hinter jedem Befehl.) Dann folgen die Befehle, die in das Wort compiliert werden sollen. Ein »;« beendet die Definition. Danach ist der Befehl wie jeder andere Befehl benutzbar. Auf Fehler reagiert der Compiler, indem er die Compilation abbricht. Danach sollte man den Befehl mit FORGET löschen, da sonst das Programm abstürzt, wenn Sie den Befehl aufrufen.
Der Editor
Nun ist es ziemlich zeitaufwendig, wenn man bei jedem Fehler den Befehl neu eingeben muß, deshalb bietet Forth einen zweiten Editor. Es ist ein Bildschirmeditor, welcher mit dem Systembefehl »EDIT n« aufgerufen wird, n bezeichnet hier die Nummer des Screens, der editiert werden soll. Ein Screen ist einfach eine Bildschirmseite, auf der der zu compilierende Sourcecode steht.
Geben Sie einmal »EDIT 1« ein. Das System versucht nun, Screen 1 von der Diskette zu laden. Ist der Screen nicht auf Diskette vorhanden, so wird trotzdem in den Editor gesprungen, nur daß der Screen leer ist. Nachdem sich das System im Editor befindet, sehen Sie links die Zeilennummern von 0 bis 23 mit folgendem Doppelpunkt (dieser Doppelpunkt hat keine Bedeutung). Sie können nun mit dem Cursor hinter den Doppelpunkt fahren und eine Zeile eingeben. Jede Zeile muß mit RETURN abgeschlossen werden. Eine Zeile darf nicht länger als 35 Zeichen sein. Geben Sie doch einmal das vorherige Beispiel ein. Die Nummer am Anfang jeder Zeile entspricht in etwa einer Zeilennummer in Basic.
Um nun den Editor zu verlassen, gibt es zwei Möglichkeiten, einmal mit »e«, damit der Screen n abgespeichert wird und mit »s«, so wird der Editor ohne Änderung des Screens verlassen. Die Buchstaben müssen in der ersten Spalte einer Zeile stehen, also dort, wo die Zeilennummer steht. Es gibt noch mehr dieser Editorbefehle (siehe Tabelle 4). Zum Einfügen von Zeilen benützen Sie »I Zeile Anzahl«, mit »D Zeile Anzahl« löschen Sie Zeilen. Mit »L« listen Sie den Screen noch einmal, das ist dann von Nutzen, wenn Sie versehentlich die CLR-Taste betätigt haben. Mit »N Nummer« ändern Sie die Nummer eines Screens. Das Compilieren eines Screens geschieht mit LOAD n. Soll der nächste Screen (n + 1) auch noch compiliert werden, so muß in der letzten Zeile des Screens n der Befehl »-->« vorhanden sein. Experimentieren Sie doch mal ein bißchen mit dem Editor.
In den Bildern 2 bis 6 finden Sie einige selbstdefinierte Befehle. Die Befehle J und LEAVE in Bild 3 möchte ich näher erklären. J gibt den Schleifenwert der zweitinnersten Schleife aus. Die Befehle R> und >R manipulieren den Returnstack (der Returnstack funktioniert genauso wie der normale Stack). Hier werden Werte für Schleifen zwischengespeichert und zwar im Format Endwert, Zähler. R> holt den obersten Wert des Returnstacks auf den Stack, >R tut das Gegenteil. Die 704 ist nur Zwischenspeicher. LEAVE schließt eine Schleife vorzeitig ab, indem Endwert und Zähler gleichgesetzt werden.
Viel Spaß beim Programmieren in Forth.
(Alexander Schindowski/ev)Info: Literatur zu Forth:
- Paul M. Chirlien, Der Einstieg in Forth, Markt & Technik 1985, 338 Seiten, 58 Mark.
- E. Floegel, Forth-Handbuch, Ing. W. Hofacker Verlag 1983, 192 Seiten, 39 Mark.,
- Monadjemi, Das Trainingsbuch zu Forth, Data Becker 1985, 300 Seiten, 39 Mark.
- Ronald Zech, Die Programmiersprache Forth, Franzis-Verlag 1984, 312 Seiten, 69 Mark.
- Weitere Literatur mit Informationen über Forth sind zu beziehen über die deutsche Sektion der Forth Interest Group (FIG). Kontaktadresse: Forth Gesellschaft Deutschland (FIG), Postfach 20 22 64, 2000 Hamburg 20. Da die FIG nicht kommerziell arbeitet, bitte bei Anfragen Freiumschlag beifügen.
1) Rechenoperationen: | |
1.1) + |
(n2 n1 - - - n3) |
1.2) - |
{n2 n1 - - - n3) |
1.3) * |
(n2 n1 - - - n3) |
1.4) / |
(n2 n1 - - - n3) |
1.5) MOD |
(n2 n1 - - - n3) |
2) Vergleichsoperatoren: | |
2.1) = |
(n2 n1 - - - f) |
2.2) > |
(n2 n1 - - - f) |
2.3) < |
(n2 n1 - - - f) |
3) Logische Verknüpfungen: | |
3.1) AND |
(n2 n1 - - - n3) |
3.2) OR |
(n2 n1 - - - n3) |
3.3) NOT |
(f1 - - - f2) |
3.4) XOR |
(n2 n1 - - - n3) |
4) Stackoperatoren: | |
4.0) DROP |
(n1 - - -) |
4.1) DUP |
(n1 - - - n1 n1) |
4.2) SWAP |
(n2 n1 - - - n1 n2) |
4.3) OVER |
(n2 n1 - - - n2 n1 n2) |
4.4) PICK |
(n1 n - - - n1 n2) |
4.5) ROT |
(n3 n2 n1 - - - n2 n1 n3) |
4.6) @ |
(addr - - - n1) |
4.7) ! |
(n1 addr - - -) |
4.8) c@ |
(addr - - - b1) |
4.9) c! |
(b1 addr - - -) |
5) Kontrollstrukturen: | |
5.1) BEGIN — UNTIL |
(f - - -) |
5.2) BEGIN — WHILE — REPRAT |
(f - - -) |
5.3) IF — ENDIF |
(f - - -) |
5.4) IF — ELSE — ENDIF |
(f - - -) |
6) Definitionsworte: | |
6.1) VARIABLE |
(n - - -) |
6.2) CONSTANT |
(n - - -) |
6.3) MEMORY |
(n - - -) |
6.4) : ... ; |
|
7) Ein-/Ausgabe: | |
7.1) EXPECT |
(addr n - - -) |
7.2) TYPE |
(addr n - - -) |
7.3) KEY |
(- - - c) |
7.4) GET |
(- - - c) |
7.5) EMIT |
(c - - -) |
7.6) ." |
(- - -) |
7-7) • |
(n - - -) |
7.8) CR |
(---) |
7.9) CLS |
(- - -) |
8) Schleifen: | |
8.1) DO |
(n2 n1 - - -) |
8.2) LOOP |
(- - -) |
8.3) +LOOP |
(n - - -) |
8.4) I |
(- - - n) |
9) Sonstige Befehle: | |
9.1) call |
(addr - - -) |
9.2) >R |
(n - - -) |
9.3) R> |
(- - - n) |
9.4) DEPTH |
(- - - n) |
A,X,I,Z | Lauf- und Hilfsvariablen |
VOC | Vocabulary-Zeiger |
BE | Beginn des Vocabulary |
SP | Zeiger für Compilerstack |
AN | Anzahl der Vocabulary-Einträge |
ZE$ | Eingabezeile |
BE$ | Einzelner Befehl |
COMP | Flag für Compilation |
AD | Adressen-Zwischenspeicher |
OK | Zahlenumwandlung geglückt? |
A$ | Hilfsvariable |
WO$(X) | Wörterverzeichnis |
AD(X) | Startadressen-Verzeichnis |
BLOCK | Flag für Compilation von Diskette |
Z1 | Zeilenzähler |
XX | Umgewandelte Zahl |
X | Top of Stack (TOS) |
BASIC | Zurück zu Basic |
RESET | Zurück in Ausgangsstellung |
VLIST | Listet das Vocabulary |
FORGET | Lösche ein Wort |
FLOPPY | Gibt einen Befehl an die Floppy |
SAVE-SYSTEM | Speichert das Vocabulary ab |
LOAD-SYSTEM | Lädt das Vocabulary |
LIST n | Listed eine Screen |
LOAD n | Compiliert eine Screen |
CLEAR n | Löscht eine Screen |
EDIT n | Ruft den Editor auf |
E | Beendet das Editieren und speichert die Screens ab |
S | Beendet das Editieren |
L | Listet die Screens |
I (z,a) | Fügt Zeile(n) ein |
D (z,a) | Löscht Zeile(n) |
N (x) | Ändert die Screen-Nummer |
100 rem **************************** 110 rem * * 120 rem * forth-compiler * 130 rem * * 140 rem * fuer * 150 rem * * 160 rem * commodore-64 * 170 rem * * 180 rem **************************** 190 rem * * 200 rem * alexander schindowski * 210 rem * * 220 rem * 6000 frankfurt/main 50 * 230 rem * * 240 rem * rudolf-hilferding-str.49 * 250 rem * * 260 rem **************************** 270 rem * * 280 rem * telephon:(069)/570520 * 290 rem * * 300 rem **************************** 310 : 320 : 330 : 340 if a=0 thena=1:load"vocabulary",8,1 350 def fnh(x)=(int(x/256)) 360 def fnl(x)=(x-256*fnh(x)) 370 poke 53272,23:print"{clr}{lblu}";chr$(8); 380 voc=6*4096:be=voc:sp=0:z1=0 390 poke 55,fn l(be):poke 56,fn h(be) 395 dim st(20),sc$(24),wo$(100),ad(100) 400 print tab(14);"Forth-Compiler" 410 print tab(17);"fuer den" 420 print tab(15);"Commodore-64" 430 print"----------------------------------------"; 440 print" Von Alexander Schindowski 1985{down}{down}{down}{down}{down}{down}{down}{down}" 450 data 38 460 data "+",49563 470 data "cls",49158,"depth",49968 480 data "@",50012,"drop",49236 490 data "emit",49855,"expect",49936 500 data "=",49410,"i",49766 510 data "key",49880 520 data "+loop",49821,"mod",49733 530 data "not",49458,"over",49284 540 data ".",49163,"-",49578 550 data "swap",49248,">r",49751 560 data "and",49497,"cr",49384 570 data "/",49721,"do",49757,"!",49977 580 data "dup",49239,"xor",49541 590 data "get",49862,">",49434 600 data "<",49452,"loop",49811 610 data "*",49596,"or",49519 620 data "c@",50030,"c!",49996 630 data "r>",49745,"type",49915 640 data "pick",50062,"call",50047,"rot",50085 650 read an 660 for i=1 to an 670 read wo$(i),ad(i) 680 next i:poke 2,0:poke 252,0 690 gosub 3830 693 : 695 rem ************************** 700 rem *** befehls-auswertung *** 705 rem ************************** 708 : 710 gosub 2630 715 : 720 if be$=":" then 1540 725 : 730 for i=an to 1 step -1 740 if be$=wo$(i) then 760 750 next i:goto 770 760 sys ad(i):goto 700 765 : 770 gosub 3030 780 if ok=0 then 830 790 poke 781,fn l(xx) 800 poke 780,fn h(xx) 810 sys 49194 820 goto 700 825 : 830 if be$="reset" then run 835 : 840 if be$="basic" then end 845 : 850 if be$<>"vlist" then 900 860 print:for i=an to 1 step-1 870 print wo$(i)" "; 880 next:print 890 goto 700 895 : 900 if be$<>"forget" then 950 910 gosub 2630:for i=an to 1 step-1 920 if be$<>wo$(i) then next i 930 if i>an then print be$" I can't find":goto 700 935 : 940 voc=ad(i):an=i-1:goto 700 950 if be$<>"(" then 980 960 if be$<>")" then gosub2630:goto960 970 goto 700 975 : 980 if be$<>"edit" then 1020 990 gosub 2630 :sc=val(be$) 1000 print"Screen:";sc:gosub 3280 1010 if be$="-->"then ze$="":sc=sc+1:goto1000 1012 goto 700 1015 : 1020 if be$<>"load" then 1050 1030 gosub 2630:sc=val(be$) 1040 block=1:z1=0:gosub 3110:goto 700 1050 if be$<>"-->" then 1070 1060 sc=sc+1:gosub3110:comp=1:block=1:z1=0:goto 700 1070 : 1080 if be$<>"variable" then 1145 1085 gosub 2630:an=an+1:wo$(an)=be$ 1090 ad(an)=voc:xx=voc+8 1095 gosub 3470:poke voc,169 1100 poke voc+1,fn h(xx) 1105 poke voc+2,162 1110 poke voc+3,fn l(xx) 1115 poke voc+4,32:poke voc+5,42 1120 poke voc+6,192:poke voc+7,96 1125 poke voc+8,fn l(x) 1130 poke voc+9,fn h(x) 1135 voc=voc+10 1140 goto 700 1145 : 1150 if be$<>"memory" then 1220 1155 gosub 2630:an=an+1:wo$(an)=be$ 1160 ad(an)=voc 1165 gosub 3470:poke voc,169 1170 poke voc+1,fn h(voc+12) 1175 poke voc+2,162 1180 poke voc+3,fn l(voc+12) 1185 poke voc+4,32:poke voc+5,42 1190 poke voc+6,192:ad=voc+12+xx 1195 poke voc+7,96 1200 poke voc+8,fn l(ad):poke voc+9,fn h(ad) 1205 poke voc+10,fn l(xx):poke voc+11,fn h(xx) 1210 voc=ad:goto 700 1220 : 1230 if be$<>"constant" then 1280 1240 gosub 2630:a$=": "+be$+" " 1250 gosub 3470 1260 ze$=a$+str$(x)+" ;"+ze$ 1270 goto 700 1280 : 1290 if be$<>"clear" then 1350 1300 gosub 2630:sc=val(be$) 1310 for ze=0 to 24 1320 sc$(ze)="" 1330 next ze:gosub3220 1340 goto700 1350 : 1360 ifbe$="save-system"then3510 1365 : 1370 ifbe$="load-system"then3720 1380 : 1390 if be$<>"floppy" then 1420 1400 gosub2630 1410 open1,8,15,be$:close1:goto 700 1420 : 1430 ifbe$<>"list" then 1520 1440 gosub2630:sc=val(be$):gosub3110 1450 input"Auf Drucker (y/n)";a$:a=3:ifa$="y"thena=4 1460 open4,a,-7*(a=4) 1470 for z=0 to 23 1480 print#4,right$(str$(z),2)":"sc$(z) 1490 next z:close4 1500 ifa=3thenpoke198,0:wait198,1 1510 comp=0:goto700 1520 : 1530 printbe$" I can't find":goto 700 1533 : 1535 rem ************************* 1540 rem *** compiler *** 1545 rem ************************* 1548 : 1550 gosub2630:an=an+1:wo$(an)=be$ 1560 ad(an)=voc:comp=1 1570 : 1580 gosub 2630 1590 for i=1 to anz 1600 if be$<>wo$(i) then next i 1610 ad=ad(i) 1615 : 1620 if be$<>"begin" then 1640 1630 st(sp)=voc:sp=sp+1:goto 1570 1635 : 1640 if be$<>"until" then 1730 1650 poke voc,32 1660 poke voc+1,180:poke voc+2,194 1670 poke voc+3,176:poke voc+4,3 1680 poke voc+5,76 1690 sp=sp-1:ad=st(sp):if sp<0 then65535 1700 poke voc+6,fn l(ad) 1710 poke voc+7,fn h(ad) 1720 voc=voc+8:goto 1570 1725 : 1730 if be$=";" then poke voc,96:voc=voc+1:comp=0:goto 700 1735 : 1740 gosub 3030 1750 if ok=0 then 1800 1760 poke voc,169:poke voc+1,fn h(xx) 1770 pokevoc+2,162:pokevoc+3,fn l(xx) 1780 poke voc+4,32:poke voc+5,42 1790 poke voc+6,192:voc=voc+7:goto 1570 1800 : 1810 if be$<>"if" then 1870 1820 poke voc,32:poke voc+1,180 1830 poke voc+2,194:poke voc+3,176 1840 poke voc+4,3:poke voc+5,76 1850 st(sp)=voc+6:sp=sp+1 1860 voc=voc+8:goto 1570 1870 : 1880 if be$<>"endif" then 1930 1890 sp=sp-1:ad=st(sp) 1900 poke ad,fn l(voc) 1910 poke ad+1,fn h(voc) 1920 goto 1570 1930 : 1940 if be$<>"else" then 2010 1950 ad=st(sp-1) 1960 st(sp-1)=voc+1 1970 poke voc,76:voc=voc+3 1980 poke ad,fn l(voc) 1990 poke ad+1,fn h(voc) 2000 goto 1570 2010 : 2020 if be$="while" then 1820 2030 : 2040 if be$<>"repeat" then 2110 2050 ad=st(sp-1):a2=st(sp-2) 2060 sp=sp-1 2070 poke voc,76 2080 poke voc+1,fn l(a2) 2090 poke voc+2,fn h(a2) 2100 voc=voc+3:goto 1980 2110 : 2120 if be$<>"."+chr$(34) then 2225 2125 a$="":ze$=mid$(ze$,2) 2130 if left$(ze$,1)<>chr$(34) then a$=a$+left$(ze$,1):ze$=mid$(ze$,2):goto2130 2135 ze$=mid$(ze$,2):a$=a$+chr$(0) 2140 ad=voc+10 2145 poke voc,169 2150 poke voc+1,fn h(ad) 2155 poke voc+2,162 2160 poke voc+3,fn l(ad) 2165 poke voc+4,32:poke voc+5,234 2170 poke voc+6,194:poke voc+7,76 2175 ad=voc+10+len(a$) 2180 poke voc+8,fn l(ad) 2185 poke voc+9,fn h(ad) 2190 voc=voc+10 2200 for i=0 to len(a$)-1 2205 poke voc+i,asc(mid$(a$,i+1,1)) 2210 if left$(ze$,1)=" " then ze$=mid$(ze$,2):goto 2210 2215 next i 2220 voc=ad:goto 1570 2225 : 2230 if be$<>"text"+chr$(34) then2320 2235 a$="":ze$=mid$(ze$,2) 2240 if left$(ze$,1)<>chr$(34) then a$=a$+left$(ze$,1):ze$=mid$(ze$,2):goto2240 2245 ze$=mid$(ze$,2):a$=a$+chr$(0) 2250 ad=voc+10 2255 poke voc,169 2260 poke voc+1,fn h(ad) 2265 poke voc+2,162 2270 poke voc+3,fn l(ad) 2273 poke voc+4,32:poke voc+5,42:poke voc+6,192 2275 poke voc+7,76 2280 ad=voc+10+len(a$) 2285 poke voc+8,fn l(ad) 2290 poke voc+9,fn h(ad) 2295 voc=voc+10 2300 for i=0 to len(a$)-1 2305 poke voc+i,asc(mid$(a$,i+1,1)):next 2310 if left$(ze$,1)=" " then ze$=mid$(ze$,2):goto 2310 2315 voc=ad:goto 1570 2320 : 2330 if be$<>"do" then 2390 2340 poke voc,32 2350 poke voc+1,fn l(ad) 2360 poke voc+2,fn h(ad) 2370 voc=voc+3:st(sp)=voc 2380 sp=sp+1:goto 1570 2390 : 2400 if be$<>"loop" and be$<>"+loop" then 2500 2410 poke voc,32 2420 poke voc+1,fn l(ad) 2430 poke voc+2,fn h(ad) 2440 poke voc+3,176:poke voc+4,3 2450 sp=sp-1:ad=st(sp) 2460 poke voc+5,76 2470 poke voc+6,ad-256*int(ad/256) 2480 poke voc+7,int(ad/256) 2490 voc=voc+8:goto 1570 2500 : 2510 if be$<>"(" then 2540 2520 gosub 2630:if be$<>")" then 2520 2530 goto 1570 2540 : 2550 if be$=";s" then poke voc,96:voc=voc+1:goto 1570 2560 : 2570 if i>an then print be$" I can't find":comp=0:goto 700 2575 : 2580 poke voc,32 2590 poke voc+1,ad-256*int(ad/256) 2600 poke voc+2,int(ad/256) 2610 voc=voc+3:goto 1570 2615 : 2620 rem ************************ 2630 rem ** hole befehl in be$ ** 2635 rem ************************ 2637 : 2640 if ze$="" then gosub 2750 2650 if left$(ze$,1)=" "then ze$=mid$(ze$,2):goto 2650 2660 be$="":for i=1 to len(ze$) 2670 if left$(ze$,1)=" " then 2710 2680 be$=be$+left$(ze$,1) 2690 ze$=mid$(ze$,2) 2700 next i 2710 return 2720 : 2730 rem ************************* 2740 rem *** hole zeile in ze$ *** 2750 rem ************************* 2755 : 2760 if block=1 then 2880 2770 if comp=0 then print" ok." 2780 sys 42336 2790 ze$="" 2800 for z=512 to 600 2810 a=peek(z) 2820 if a=0 then 2850 2830 ze$=ze$+chr$(a) 2840 next z 2850 if left$(ze$,1)=" "then ze$=mid$(ze$,2):goto 2850 2860 if ze$="" then 2770 2870 return 2880 ze$=sc$(z1):print right$(str$(z1),2);":";ze$ 2890 if len(ze$)<2 then ze$="( )" 2900 z1=z1+1 2910 if z1=24 then block=0 2920 return 2980 : 2990 rem ************************** 3000 rem ** wandele zahl um ** 3010 rem ** in xx ** 3020 rem ************************** 3030 : 3040 ok=1:x=1 3050 if left$(be$,1)="-" and val(be$)<0 then be$=mid$(be$,2):x=-1:goto 3080 3060 if left$(be$,1)>="0" and left$(be$,1)<="9" then 3080 3070 ok=0:return 3080 xx=val(be$)*x 3090 if xx<0 then xx=(256*256)+xx 3100 return 3103 : 3105 rem ************************* 3110 rem ***** lade screen ***** 3115 rem ************************* 3118 : 3120 open1,8,15 3130 open 2,8,2,"scr"+str$(sc)+",s,r" 3140 input#1,a 3150 if a<>0 then close2:close1:for i=0to24:sc$(i)="":next i:return 3160 for ze=0 to 24:b$="" 3170 poke251,2:sys830 3180 for i=512 to 600:x=peek(i):if x then b$=b$+chr$(x):next i 3190 sc$(ze)=b$ 3200 next ze 3210 close2:close1:return 3213 : 3215 rem ************************** 3220 rem ***** save screen ***** 3225 rem ************************** 3228 : 3230 open 1,8,2,"@:scr"+str$(sc)+",s,w" 3240 for ze=0 to 24 3250 print#1,sc$(ze) 3260 next ze 3270 close1:ze$="":print"{clr}";:return 3273 : 3275 rem *********************** 3280 rem **** edit a screen **** 3285 rem *********************** 3288 : 3290 gosub 3400 3300 print"{home}";:comp=1 3310 gosub 2750 3315 if left$(ze$,1)="n" then gosub2630:gosub2630:sc=val(be$):gosub3420:goto3300 3320 if left$(ze$,1)="e" then ze$="":comp=0:goto 3220 3321 if left$(ze$,1)<>"i" then 3330 3322 gosub 2630:gosub 2630:z=val(be$):if z<0 or z>23 then gosub 3420:goto 3300 3323 gosub 2630:a=val(be$):if a<0 or a>23 then gosub 3420:goto 3300 3324 for i=22-a to z step-1:sc$(i+a)=sc$(i):sc$(i)="":next 3325 gosub 3420:goto 3300 3330 if left$(ze$,1)="s" then ze$="":print"{clr}";:comp=0:return 3331 if left$(ze$,1)<>"d" then 3337 3332 gosub 2630:gosub 2630:z=val(be$):if z<0 or z>23 then gosub3420:goto 3300 3333 gosub 2630:a=val(be$):if a<0 or a>23 then gosub 3420:goto 3300 3334 for i=z to 22-a:sc$(i)=sc$(i+a):sc$(i+a)="":next 3335 gosub 3420:goto 3300 3337 if left$(ze$,1)="l" then gosub 3420:goto 3300 3340 ze=val(ze$) 3350 ze$=mid$(ze$,3) 3360 if ze>9 then ze$=mid$(ze$,2) 3370 sc$(ze)=ze$ 3380 gosub 2630:if be$="-->" then goto 3220 3390 goto 3310 3393 : 3395 rem ************************* 3400 rem ***** list screen ***** 3405 rem ************************* 3408 : 3410 gosub 3110 3420 print"{clr}"; 3430 for ze=0 to 23 3440 print right$(str$(ze),2);":"; 3450 print left$(sc$(ze),38) 3460 next ze:return 3463 : 3465 rem *********************** 3470 rem ** hole wert vom tos ** 3475 rem *********************** 3480 ad=52992+peek(2) 3490 x=peek(ad-1)+256*peek(ad-2) 3500 poke 2,peek(2)-2:return 3503 : 3505 rem *********************** 3510 rem *** save-system *** 3515 rem *********************** 3518 : 3520 gosub 2630 3530 open1,8,15,"s:"+be$+".*":close1 3540 open2,8,2,be$+".voc,p,w" 3550 print#2,an:print#2,voc 3560 for ze=39 to an 3570 print#2,wo$(ze) 3580 print#2,ad(ze) 3590 next ze 3600 close 2:be$=be$+".code" 3610 poke 187,fn l(720):poke 188,fn h(720) 3620 for i=1 to len(be$) 3630 poke 719+i,asc(mid$(be$,i,1)) 3640 next i:poke 183,len(be$) 3650 poke 186,8:poke 185,1 3660 poke 251,fn l(be):poke 252,fn h(be) 3670 poke 780,251 3680 poke 781,fn l(voc) 3690 poke 782,fn h(voc) 3700 sys 216+256*255 3710 goto 700 3713 : 3715 rem *************************** 3720 rem **** load system **** 3725 rem *************************** 3728 : 3730 gosub 2630 3740 open 2,8,2,be$+".voc,p,r" 3750 input#2,an,voc 3760 for ze=39 to an 3770 input#2,wo$(ze) 3780 input#2,ad(ze) 3790 next ze:close 2 3800 sys 50139,be$+".code",8 3810 goto 700 3813 : 3815 rem *************************** 3820 rem *** data *** 3825 rem *************************** 3828 : 3830 data166,251, 32,198,255,160, 0, 32,207,255,201, 13,240, 7,153, 0 3840 data 2,200, 76, 69, 3,169, 0,153, 0, 2, 76,204,255 3850 for i= 830to 858:read a:poke i,a:z=z+a:next i 3860 if z<>3379 then print"{rvon}Fehler in Data{rvof}":end 3870 return
PROGRAMM : VOCABULARY C006 C3EB ----------------------------------- C006 : A9 93 4C D2 FF 20 3F C0 66 C00E : 85 62 86 63 A2 90 A5 62 DC C016 : 30 09 A9 20 20 D2 FF 38 42 C01E : 4C D4 BD A9 2D 20 D2 FF 98 C026 : 18 4C D4 BD 85 FE 86 FD B7 C02E : A6 02 A5 FE 9D 00 CF E8 09 C036 : A5 FD 9D 00 CF E8 86 02 A4 C03E : 60 A6 02 CA BD 00 CF 85 F1 C046 : FD CA BD 00 CF 85 FE 86 4A C04E : 02 A5 FE A6 FD 60 4C 3F 4A C056 : C0 20 3F C0 20 2A C0 4C FD C05E : 2E C0 20 3F C0 8D 00 C0 D6 C066 : 8E 01 C0 20 3F C0 8D 02 DD C06E : C0 8E 03 C0 AD 00 C0 AE 89 C076 : 01 C0 20 2A C0 AD 02 C0 28 C07E : AE 03 C0 4C 2A C0 C6 02 2F C086 : C6 02 20 3F C0 E6 02 E6 56 C08E : 02 E6 02 E6 02 4C 2A C0 0D C096 : A6 FC CA BD 00 CE 85 FD AD C09E : CA BD 00 CE 85 FE 86 FC 85 C0A6 : A5 FE A6 FD 60 85 FE 86 6F C0AE : FD A6 FC A5 FE 9D 00 CE 6D C0B6 : E8 A5 FD 9D 00 CE E8 86 CB C0BE : FC 60 38 AD 00 C0 ED 02 70 C0C6 : C0 8D 04 C0 AD 01 C0 ED 28 C0CE : 03 C0 8D 05 C0 60 18 AD 00 C0D6 : 00 C0 6D 02 C0 8D 04 C0 DC C0DE : AD 01 C0 6D 03 C0 8D 05 60 C0E6 : C0 60 A9 0D 4C D2 FF 20 7E C0EE : 3F C0 8E 00 C0 8D 01 C0 2F C0F6 : 20 3F C0 8E 02 C0 8D 03 1A C0FE : C0 4C C0 C0 20 ED C0 AD FC C106 : 04 C0 0D 05 C0 F0 06 A9 4D C10E : 00 AA 4C 2A C0 A9 00 A2 5A C116 : 01 4C 2A C0 20 ED C0 30 B5 C11E : 06 A9 00 AA 4C 2A C0 A9 BB C126 : 00 A2 01 4C 2A C0 20 60 2B C12E : C0 4C 1A C1 20 3F C0 05 DC C136 : FD F0 06 A9 00 AA 4C 2A 3D C13E : C0 A9 00 A2 01 4C 2A C0 C4 C146 : 20 3F C0 8E 00 C0 8D 01 46 C14E : C0 20 3F C0 8E 02 C0 8D 1D C156 : 03 C0 60 20 46 C1 AD 00 FF C15E : C0 2D 02 C0 85 FD AD 01 4E C166 : C0 2D 03 C0 85 FE 4C 2E 74 C16E : C0 20 46 C1 AD 00 C0 0D 00 C176 : 02 C0 85 FD AD 01 C0 0D F9 C17E : 03 C0 85 FE 4C 2E C0 20 9C C186 : 46 C1 AD 00 C0 4D 02 C0 18 C18E : 85 FD AD 01 C0 4D 03 C0 A1 C196 : 85 FE 4C 2E C0 20 46 C1 1D C19E : 20 D4 C0 AE 04 C0 AD 05 35 C1A6 : C0 4C 2A C0 20 60 C0 20 77 C1AE : 46 C1 20 C0 C0 AE 04 C0 08 C1B6 : AD 05 C0 4C 2A C0 20 46 55 C1BE : C1 A0 00 8C 04 C0 8C 05 E3 C1C6 : C0 A0 10 0E 04 C0 2E 05 A5 C1CE : C0 2E 02 C0 2E 03 C0 90 5D C1D6 : 1D 18 AD 04 C0 6D 00 C0 E4 C1DE : 8D 04 C0 AD 05 C0 6D 01 61 C1E6 : C0 8D 05 C0 90 08 EE 02 CF C1EE : C0 D0 03 EE 03 C0 88 D0 AF C1F6 : D2 AE 04 C0 AD 05 C0 4C D7 C1FE : 2A C0 20 46 C1 A0 10 A9 0E C206 : 00 8D 04 C0 8D 05 C0 2E 46 C20E : 02 C0 2E 03 C0 2E 04 C0 6B C216 : 2E 05 C0 38 AD 04 C0 ED D8 C21E : 00 C0 AA AD 05 C0 ED 01 EF C226 : C0 90 06 8D 05 C0 8E 04 FA C22E : C0 88 D0 DB 2E 02 C0 2E 34 C236 : 03 C0 60 20 00 C2 AE 02 8A C23E : C0 AD 03 C0 4C 2A C0 20 07 C246 : 00 C2 AE 04 C0 AD 05 C0 E2 C24E : 4C 2A C0 20 96 C0 4C 2A D8 C256 : C0 20 3F C0 4C AB C0 20 74 C25E : 60 C0 20 57 C2 4C 57 C2 83 C266 : 20 51 C2 E6 FC E6 FC 60 78 C26E : 20 51 C2 20 57 C0 20 51 8A C276 : C2 20 60 C0 20 ED C0 30 4D C27E : 08 20 54 C0 20 54 C0 38 DC C286 : 60 E6 FC E6 FC 20 9B C1 38 C28E : 20 57 C2 18 60 A9 00 A2 A6 C296 : 01 20 2A C0 4C 6E C2 20 CD C29E : 3F C0 E6 02 E6 02 A5 FE 4A C2A6 : 10 C6 20 51 C2 20 57 C0 58 C2AE : 20 51 C2 4C 7A C2 20 3F 6E C2B6 : C0 05 FD F0 02 38 60 18 2A C2BE : 60 20 3F C0 8A 4C D2 FF 6D C2C6 : 20 87 EA E0 FF F0 04 E0 DA C2CE : 0D B0 02 A2 00 A9 00 4C EE C2D6 : 2A C0 20 C6 C2 20 57 C0 4D C2DE : 20 B4 C2 B0 06 20 54 C0 53 C2E6 : 4C D8 C2 60 86 FD 85 FE C7 C2EE : A0 00 B1 FD F0 06 20 D2 20 C2F6 : FF C8 D0 F6 60 20 3F C0 F2 C2FE : 86 F7 20 3F C0 A0 00 B1 E4 C306 : FD 20 D2 FF C8 C4 F7 D0 FC C30E : F6 60 20 3F C0 86 F9 20 8D C316 : 3F C0 86 F7 85 F8 A2 00 00 C31E : A0 00 20 CF FF 91 F7 C9 C0 C326 : 0D F0 06 E8 C8 C4 F9 D0 86 C32E : F1 60 A5 02 4A AA A9 00 9A C336 : 4C 2A C0 20 3F C0 86 F7 CF C33E : 85 F8 20 3F C0 A0 01 91 68 C346 : F7 8A 88 91 F7 60 20 3F 58 C34E : C0 86 F7 85 F8 20 3F C0 0F C356 : A0 00 8A 91 F7 60 20 3F 4D C35E : C0 86 F7 85 F8 A0 00 B1 08 C366 : F7 AA C8 B1 F7 4C 2A C0 27 C36E : 20 3F C0 86 F7 85 F8 A0 FF C376 : 00 B1 F7 AA A9 00 4C 2A C2 C37E : C0 20 3F C0 AD 0C 03 AE DB C386 : 0D 03 AC 0E 03 6C FD 00 8D C38E : 20 3F C0 A4 02 8C 00 C0 19 C396 : 8A 0A 85 02 20 3F C0 AC 1F C39E : 00 C0 84 02 4C 2A C0 20 B9 C3A6 : 3F C0 8E 00 C0 8D 01 C0 E7 C3AE : 20 3F C0 8E 02 C0 8D 03 D2 C3B6 : C0 20 3F C0 8E 04 C0 8D 95 C3BE : 05 C0 AE 02 C0 AD 03 C0 16 C3C6 : 20 2A C0 AE 00 C0 AD 01 C0 C3CE : C0 20 2A C0 AE 04 C0 AD AA C3D6 : 05 C0 4C 2A C0 20 FD AE F6 C3DE : 20 D4 E1 A9 01 85 B9 A9 8C C3E6 : 00 4C D5 FF FF 51
( *** Zusatz-Befehle 0 *** ) ( Processor-Register ) 780 constant a-reg 781 constant x-reg 782 constant y-reg ( ---------------------- ) ( Die folgenden Befehle ) ( sollen zeigen,dass es ) ( mit dem recht beschei- ) ( denen Grundvokabular ) ( moeglich ist,doch ein ) ( sinnvolles,zweckmaess- ) ( iges zu erstellen. ) -->
( *** zusatz-befehle 1 ***) ( 2. Schleifenindex ) : j r> r> r> dup 704 ! >r >r >r 704 @ ; ( Verlasse Schleife ) : leave r> r> drop dup >r >r ; -->
( *** Zusatz-Befehle 2 *** ) ( open (addr l log nr sec --) ) : open 185 c! 186 c! 184 c! 183 c! 187 ! 65472 call ; ( close (log --) ) : close cr 65484 call a-reg c! 65475 call ; -->
( *** Zusatz-Befehele 3 *** ) ( Ausgabe auf File (log --) ) : out x-reg c! 65481 call ; ( Eingabe von File (log --) ) : in x-reg c! 65478 call ; -->
( *** Zusatz-Befehle 4 *** ) ( Ausgabe auf Drucker ) : printer 0 0 4 4 7 open 4 out cr ; ( Ausgabe auf Display ) : display cr 4 close ; ( * ende * )