Forum: Mikrocontroller und Digitale Elektronik Fragen zu Forth


von chris (Gast)


Lesenswert?

Hallo Zusammen,

nachdem ich mich zur Zeit mit minimalistischen Prozessorarchtitekturen 
befasse, bin ich bei der Programmiersprache "FORTH" gelandet.

Um ein wenig zu üben, verwende ich "gforth"
http://www.gnu.org/software/gforth/
( das findet man bei Ubuntu einfach im Packetmanager )

Ich kann z.B. einen eigenen Befehl mit

: befehl ." mein Testbefehl";

definieren.

Aber wie kann ich mein "Werk" abspeichern? Wie arbeitet man am besten 
mit gforth, ist die Kommandozeile als Editor geeignet?

Vielen Dank im Voraus für eine etwaige Hilfe.

chris

von (prx) A. K. (prx)


Lesenswert?

Du suchst eine IDE? Gibts nicht. Mit Editor deiner Wahl den Quellcode 
als Textfile schreiben und dann mit gforth ausführen.

von Martin (Gast)


Lesenswert?

> : befehl ." mein Testbefehl";

Zu GForth kann ich nichts schreiben. Beim AmForth (ATMega) landet der 
Befehl 'befehl' im Flashspeicher. Zum Editieren nehme ich PN und sende 
die Programme/Befehle per Loader zum Controller.

http://amforth.sourceforge.net/

von chris (Gast)


Lesenswert?

>Du suchst eine IDE? Gibts nicht. Mit Editor deiner Wahl den Quellcode
>als Textfile schreiben und dann mit gforth ausführen.

Ok, danke.
Ich erstelle also folgende Daei in einem Texteditor:

test.fs

der Inhalt:
: befehl ." mein Testbefehl";

danach tippe ich in gforth

==> include test.fs

und schaue mit

==> words

nach, ob der Befehl da ist. Ok, das geht.
Wenn ich in meinem Texeditor den Befehl editiiere und erneut

==> include test.fs

meckert gforth an, dass es den Befehl schon gibt ( redefiniton ). Der 
Befehl funktioniert dann zwar, aber er taucht zwei mal im Dictionary 
auf.

von (prx) A. K. (prx)


Lesenswert?

Eher so wie es das Manual schreibt:
1
~/test $ gforth forth1.fs
2
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
3
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
4
Type `bye' to exit
5
befehl mein Testbefehl ok
6
bye

Oder gleich kombiniert in forth2.fs
1
: befehl ." mein Testbefehl" CR ;
2
befehl
3
bye
und dann
1
~/test $ gforth forth2.fs
2
mein Testbefehl

von chris (Gast)


Lesenswert?

ah ... ja ...
Ich dachte, man kann in gforth bleiben und interaktive entwickeln. Ok, 
ich werde es mal auf die Art versuchen.
Mein FORTH-Programm soll folgendes machen:
1. eine Binärdatei lesen
2. die Binärdatei für AVR-GCC lesbar schreiben, also z,B.
1
const uint8_t data[] PROGMEM={
2
128 ,128 };

Gerade eben habe ich die Umwandlung eines Bytes in HEX gemacht:
1
\ convert a the lower part of a byte into HEX-ASCII and print it
2
: hexdig ( -- n ) 15 and dup 10 < if 48 else 55 then + emit ;
3
4
\ convert a byte to HEX-ASCII and emit
5
: hexbyte ( -- n ) dup 4 rshift hexdig hexdig ;

Jetzt muss ich noch raus kriegen, wie man Dateien liest und schreibt.

von (prx) A. K. (prx)


Lesenswert?

chris schrieb:
> Ich dachte, man kann in gforth bleiben und interaktive entwickeln.

Nicht wirklich. Interaktiv testen geht, schreiben nicht.

Aber wie üblich kann man eine Art IDE kriegen, indem man Emacs benutzt.
http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Emacs-and-Gforth.html#Emacs-and-Gforth

von chris (Gast)


Lesenswert?

Jetzt probiere ich schon eine ganze weile herum.

File schreiben klappt. Aber ein File Byte für Byte lesen ... ist 
schwierig.
Hat jemand eine Idee ?

von (prx) A. K. (prx)


Lesenswert?

File "1" byteweise lesen:

s" 1" r/o open-file . . 0 22321088  ok
22321088 key-file . 35  ok
22321088 key-file . 32  ok
22321088 key-file . 49  ok
22321088 key-file . 32  ok
22321088 key-file . 34  ok
22321088 key-file . 97  ok
22321088 key-file . 115  ok
22321088 key-file . 103  ok
22321088 key-file . 49  ok
22321088 key-file . 46  ok
22321088 key-file . 99  ok
22321088 key-file . 34  ok

von chris (Gast)


Lesenswert?

Danke.

Interessanterweise geht der Befehl, obwohl er nicht im Manual ist:
http://www.delorie.com/gnu/docs/gforth/gforth_278.html#cp_K

Wie kann man EOF feststellen?

von (prx) A. K. (prx)


Lesenswert?

Hier wirds interessant, wenn du Binärfiles liest. Offenbar am EOT 
Zeichen (Code 4).

von chris (Gast)


Lesenswert?

Hmm .. eine 4 als Endzeichen für ein Binär-File ist tatsächliche etwas 
unhandlich.
Ich habe das Kommando file-size endeckt. Damit konnte ich das Programm 
realisieren:
1
\ FORTH binary file to AVR header file converter
2
\ converts a 16 bit intel binary to a 16 bit AVR-header file ( bytes reversed )
3
\
4
\ file tutorials
5
\ http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Files-Tutorial.html
6
\ http://rosettacode.org/wiki/File_IO#Forth
7
\ http://www.public.iastate.edu/~forth/gforth_77.html#IDX1035
8
\
9
\ 11.8.2013 chris
10
11
\ create file handles
12
0 value infile
13
0 value outfile
14
15
\ char output to file
16
: emitof ( u )
17
    outfile if
18
        pad c! pad 1 outfile write-file throw
19
    else
20
        emit
21
    then
22
;
23
24
\ convert a the lower part of a byte into HEX-ASCII and write it
25
: hexdig ( -- n ) 15 and dup 10 < if 48 else 55 then + emitof ;
26
27
\ convert a byte to HEX-ASCII and write it
28
: hexbyte ( -- n ) dup 4 rshift hexdig hexdig ;
29
30
: open-input-file ( addr u -- )  r/o open-file throw to infile ;
31
: close-input-file outfile close-file throw ;
32
33
: create-output-file w/o create-file throw to outfile ;
34
: close-output-file outfile close-file throw ;
35
36
: convert-file ( -- )
37
   s" j1.bin" open-input-file
38
   s" avrData.c" create-output-file
39
   s" const uint16_t data[] PROGMEM={" outfile write-line throw
40
   infile file-size throw drop 2 / for 48 emitof 120 emitof infile key-file infile key-file hexbyte  hexbyte 44 emitof next
41
   s" 0};" outfile write-line throw
42
   close-output-file
43
;
44
convert-file

Das war jetzt ein echt "schwere Geburt".

Vielen Dank A.K. :-)

von chris (Gast)


Lesenswert?

Nachdem ich mich jetzt eine Weile mit Forth befasst habe, stelle ich 
folgendes fest:
Es ist relativ schwierig, den Stack vor dem "inneren Auge" zu haben. Es 
passiert ziemlich leicht, dass man bei den Daten auf dem Stack den 
Überblick verliert und einen Wert zu viel oder zu wenig zurück gibt.
Da Frage ich mich: Könnte man nicht einen übergelagerten Compiler 
entwerfen, der den Stack in Form von Variblen Definitionen im Blick 
behält?

von Fred (Gast)


Lesenswert?

chris schrieb:

> Nachdem ich mich jetzt eine Weile mit Forth befasst habe, stelle ich
> folgendes fest:
> Es ist relativ schwierig, den Stack vor dem "inneren Auge" zu haben. Es
> passiert ziemlich leicht, dass man bei den Daten auf dem Stack den
> Überblick verliert und einen Wert zu viel oder zu wenig zurück gibt.
> Da Frage ich mich: Könnte man nicht einen übergelagerten Compiler
> entwerfen, der den Stack in Form von Variblen Definitionen im Blick
> behält?

Antwort: FORTH ist nicht die richtige Sprache für dich.

von Yalu X. (yalu) (Moderator)


Lesenswert?

chris schrieb:
> Es ist relativ schwierig, den Stack vor dem "inneren Auge" zu haben.

Du hast ja auch gerade erst mit Forth angefangen. Dein inneres Auge muss 
erst für solche Stack-Abläufe trainiert werden.

Erst wenn du nach ein paar Wochen Übung immer noch die gleichen Probleme 
hast, solltest du dir Gedanken um Alternativen machen.

chris schrieb:
> Da Frage ich mich: Könnte man nicht einen übergelagerten Compiler
> entwerfen, der den Stack in Form von Variblen Definitionen im Blick
> behält?

Einen Compiler, der von "variablenorientiert" nach "stackorientiert" 
übersetzt, ist schon machbar, aber ist es dann nicht sinnvoller, gleich 
einen Compiler für C, Pascal oder Basic zu nehmen, der dir sofort 
Assemblercode ohne den Umweg über Forth generiert?

von chris (Gast)


Lesenswert?

Ich hätte nicht gedacht, dass es im Forum so viele Leute mit 
FORTH-Erfahrung gibt.
Was macht Ihr so damit?
Ich suche den Source-Code für den Kommandozeileninterpreter ( in Forth 
). Hat jemand einen Tipp?

von (prx) A. K. (prx)


Lesenswert?

chris schrieb:
> Was macht Ihr so damit?

Seit ca. 3 Jahrzehnten nichts mehr. Für einen 6502 war das eine recht 
brauchbare Sprache.

> Ich suche den Source-Code für den Kommandozeileninterpreter ( in Forth
> ). Hat jemand einen Tipp?

Schon auf die Idee gekommen, dass das "g" in gforth von GNU kommt und 
die Software folglich unweigerlich als Sourcecode vorliegt?

von chris (Gast)


Lesenswert?

>Seit ca. 3 Jahrzehnten nichts mehr. Für einen 6502 war das eine recht
>brauchbare Sprache.

Vor ca. 30 Jahren in der Schulzeit habe ich damit einen Plottertreiber 
auf einem Atari ST programmiert. Nach so viel Zeit ist mir allerdings 
einiges entfallen und die Sprache hat sich auch weiter entwickelt.

>Schon auf die Idee gekommen, dass das "g" in gforth von GNU kommt und
>die Software folglich unweigerlich als Sourcecode vorliegt?
Klar doch ;-) :
http://www.complang.tuwien.ac.at/forth/gforth/gforth-0.7.2.tar.gz

Die Frage ist nur, ob es ein reduziertes FORTH auf einem Mikrocontroller 
etwas Übersichtlicheres gibt.

>Einen Compiler, der von "variablenorientiert" nach "stackorientiert"
>übersetzt, ist schon machbar, aber ist es dann nicht sinnvoller,

Wie ist das mit Java und der JVM ? Ich glaube, die JVM ist auch 
"stackorientiert"

von chris (Gast)


Lesenswert?

>Einen Compiler, der von "variablenorientiert" nach "stackorientiert"
>übersetzt, ist schon machbar, aber ist es dann nicht sinnvoller, gleich
>einen Compiler für C, Pascal oder Basic zu nehmen, der dir sofort
>Assemblercode ohne den Umweg über Forth generiert?

Um das Thema noch ein wenig zu vertiefen, hier der Vergleich der JVM ( 
stack based ) und Dalvik ( der JVM Ersatz für Android )
http://stackoverflow.com/questions/2719469/why-is-the-jvm-stack-based-and-the-dalvik-vm-register-based

Die Java Virtual Machine ( JVM ) hat eine Stack bassierte Architektur.
Eine Aussage zur Stack-bassierten Architektur der JVM:
1
There are a few attributes of a stack-based VM that fit in well with Java's design goals:
2
3
    A stack-based design makes very few assumptions about the target hardware (registers, CPU features), so it's easy to implement a VM on a wide variety of hardware.
4
5
    Since the operands for instructions are largely implicit, the object code will tend to be smaller. This is important if you're going to be downloading the code over a slow network link.

Hier ein Beispiel für einen C++ zu Java Converter:
http://www.tangiblesoftwaresolutions.com/Product_Details/CPlusPlus_to_Java_Converter_Details.html

Es gibt also Gründe, warum man eine Sprache in eine andere konvertieren 
will: Man kann die darunter liegende VM nutzen.

von Fritz (Gast)


Lesenswert?

chris schrieb:
> Es ist relativ schwierig, den Stack vor dem "inneren Auge" zu haben. Es
> passiert ziemlich leicht, dass man bei den Daten auf dem Stack den
> Überblick verliert und einen Wert zu viel oder zu wenig zurück gibt.

Das ist halt eine Stackorientierte Sprache! Wenn du den Überblick 
verlierst, solltest du dich fragen, ob du das Problem richtig angegangen 
bist, meist hilft es dann, ein Wort in mehrere Wörter aufzuteilen oder 
anders zu organisieren um einen besseren Überblick zu erhalten.
In vielen Forthimplementationen gibt es auch lokale Variablen mit denen 
man dann weniger Stackdjungle hat. Mag zwar stimmen, geht aber etwas von 
der Philosophie von Forth weg.
Übrigens hast du
http://www.forthfreak.net/thinking-forth.pdf
gelesen, ist zwar im Ansatz uralt, aber trotzdem sehr gut.

von chris (Gast)


Lesenswert?

>http://www.forthfreak.net/thinking-forth.pdf
>gelesen, ist zwar im Ansatz uralt, aber trotzdem sehr gut.
Werde ich mal durchlesen.
Durch den Artikel bin ich auf den Wikipedia Artikel über Charles Moore 
gestoßen:
http://de.wikipedia.org/wiki/Charles_H._Moore

Interessanter Mensch. Er scheint immer noch aktive mit Greenarrays und 
dem 144 Kern Forth Prozessor.

von Weinga U. (weinga-unity)


Lesenswert?

Hallo chris (und andere),

das ist ja interessant, ich bin ebenfalls gerade (wieder einmal) dabei 
und beschäftige mich mit Virtual-Machines.

Meine Motivation und Wunschvorstellung:
=======================================
Eine VM als C-Code, welche zugriff auf IO, Uart, ... vom uC/PC hat um 
Anwendungslogik abarbeiten zu können (z.B. Schaltfunktionen bei 
Hausbusknoten). Die VM sollte gut skalierbar sein um eben einfache 
Schaltfunktionen auf kleinen µCs unterzubringen (wenig ram und flash) 
aber auch komplexere Aufgaben wie Regelungalgorithmen (32bit float) auf 
stärkerer Hardware realisieren zu können.

Eine Möglichkeit zum Debuggen im System wäre natürlich der Oberhammer.

Anwendungen:
============
 - Hausautomatisation
 - Regelungen: d.h. Algorithmus auf der VM implementieren. VM ist in 
Form eines Matlab/Simulink bzw. Scilab/Scicos Blocks realisiert und man 
kann dem Block das Binary angegeben. So kann in der Simulation alles 
getestet werden. Ist die Simulation OK, gibt es eine Hardware mit µC der 
ebenfalls die VM drauf hat. Das Binary des Reglers in die VM eingespielt 
und die Regelung sollte wie erwartet funktionieren.

Meine Ansätze  Versuche  Funde:
=================================
1 - Versuch: Ich hab mir einen kleinen Befehlssatz überlegt, einen 
Assembler dazu geschrieben und konnte so auf einen ATMega16 eine VM 
betrieben (sogar mit Debugen und Assembler-Einzelschritt und 
Registeranzeigen usw.). Nachteil: Kein C-Compiler, Begrenzung mit 512 
Byte Addressbereich.

2 - Versuch: Anderer nicht resourchen schonender Befehlssatz. Im XML 
Format eine bequemere Hochsprache definiert und mit XSLT Binary 
generieren lassen. Fazit: etwas bequemere Programmerstellung, sonst wie 
Versuch 1.

3 - Überlegung: Instruction Set von µC/Softcore ala 8051, AVR, Mico8 von 
Lattice implementieren. Vorteil: C-Compiler verfügbar. Nachteil: 
Teilweise massive Speicherlimitierungen (8051, Mico8) oder Speicher 
fressender ISA (AVR mit 16bit, Mico8 mit 18bit breite OP-Codes; 8051 ist 
optimal).

4 - Fund: ZPU. Vorteil GCC verfügbar und extrem kleiner ISA. Nachteil: 
alles ist 32bit und somit massiv überdimensioniert und speicherhungrig 
für Licht ein/Licht aus Anwendungen.

5 - Fund (Hören/Sagen): Mips16e (oder TinyMIPS???). GCC gibts 
(anscheinend). Hat 16bit op-codes (angeblich). Mein Problem: schlechte 
bzw. mangelnde Dokumentation um wirklich eine VM implementieren zu 
können.

6 - Weitere Funde:
     - Sweet16 (schöner ISA, keine Hochsprachen gefunden)
     - NEKO
     - LLVM (ich verstehs bis heute nicht...)
     - P-Code (Versteh ich auch noch nicht. Gibts da jetzt einen ISA 
oder nicht?).


Aktueller Stand:
================
Wie chris bin ich nun auch über Forth gestolpert und frage mich, gibts 
da jetzt einen einheitlichen ISA (mit byte/bitweiser Aufschlüsselung)? 
Wie ist da die Speicherorganisation? Wie breit ist der Stack? Wenn man 
eine Funktion definiert, wo liegt die dann im Speicher?

Ich lese immer, dass von den unterschiedlichen Projekten das Ziel ist 
die Plattformunabhängigkeit zu erzielen und auf den Embedded-Bereich 
abzielen. Dann wird auch noch oft die Tool-Chain erklärt oder 
seitenweise beschrieben wie jeder Befehl funktioniert, jedoch 
Informationen wie das Programm und die Befehle im Binary liegen und die 
Breite des Stacks (8bit, 16bit, 32bit) sind, so hat es den Anschein, 
uninteressant für die Implementierung der VM für mich jedoch fehlende 
Informationen um die Implementierung durchführen zu können.

Ein nettes Gegenbeispiel ist der 8051 mit einer ausgezeichneten 
Dokumentation. Vielleicht wäre es für meine Anwendungen am Besten den 
8051 zu virtualisieren. ISA und RAM sind halt unschön (z.B. 
Registerbänke).



Vielleicht kann mich der eine oder andere korregieren und vielleicht von 
mir falsch Verstandene richtig stellen. Oder hat jemand bereits eine 
geeignete Lösung dazu gefunden?

Schönen Abend noch.

von chris (Gast)


Lesenswert?

Hey, das ist ja hochinteressant. Da bist Du am selben Thema dran wie 
ich.
Die ZPU habe ich vor längerere Zeit auch schon mal in Betracht gezogen. 
Ein riesen Vorteil ist antürlich GCC. Allerdings ist es wie Du schon 
erwähnt hast: Der Resourcenverbrauch ist ziemlich hoch.

Im Moment experimentiere ich gerade mit der J1 CPU:
http://www.excamera.com/sphinx/fpga-j1.html
Das Design ist fantastisch. Es kommt dem was ich seit längerem suche, 
schon sehr nahe.

Bester Gruß,
chris

von Weinga U. (weinga-unity)


Lesenswert?

Hallo Chris,

J1 hab ich auch schon gesehen. ISA und Speicherorganisation ist auf den 
ersten Blick dokumentiert. Wo für mich ein absolutes Fragezeichen ist 
ist die Toolchain. Wie kommt man zum binary aus den Forth Dateien?

Sonst wäre das auch interessant für mich.

von c-hater (Gast)


Lesenswert?

Weinga Unity schrieb:

> Begrenzung mit 512
> Byte Addressbereich.

Dann war wohl der Befehlssatz zu klein...

> 8051 ist
> optimal).

Wofür? Der Begriff "optimal" ergibt nur dann einen Sinn, wenn man das 
(genau ein!) Optimierungsziel definiert oder für den (üblichen) Fall, 
daß es deren mehrere gibt, alle Ziele sowie deren relative Wichtung 
angibt.

> Ich lese immer, dass von den unterschiedlichen Projekten das Ziel ist
> die Plattformunabhängigkeit zu erzielen

Hehres Ziel, aber niemals auch nur andeutungsweise wirklich erreicht...

> Informationen wie das Programm und die Befehle im Binary liegen und die
> Breite des Stacks (8bit, 16bit, 32bit) sind, so hat es den Anschein,
> uninteressant für die Implementierung

So ist es. Das alles muß idealerweise nur der Codegenerator für das 
Zielsystem wissen. Blöderweise ist das reale Leben selten ideal. 
Praktisch alle Sprachen machen leider schon im Sprachumfang Annahmen 
über diverse Eigenschaften des Zielsystems. Forth z.B. muß auf die 
Schnauze fallen, wenn das Zielsystem überhaupt nicht über einen Stack 
verfügt.

Die einzige konsequente Sprache ist Assembler, denn das macht niemals 
Annahmen über das Zielsystem, sondern wurde jeweils genau dafür 
erschaffen. Blöderweise macht genau diese Eigenschaften Assemblercode 
nahezu vollkommen inportabel (bestenfalls innerhalb der 
MCU/CPU-Familie).

> Vielleicht kann mich der eine oder andere korregieren und vielleicht von
> mir falsch Verstandene richtig stellen. Oder hat jemand bereits eine
> geeignete Lösung dazu gefunden?

Man legt sich einfach auf ein Zielsystem fest. Gerade bei Sachen mit 
sehr geringer algorithmischer Komplexität, wie sie offensichtlich dein 
Ziel sind, steckt der meiste Code ohnehin in den "Gerätetreibern". Und 
dieser Code ist unabhängig von der verwendeten Sprache ohnehin 
weitgehend unportierbar.

von Olaf (Gast)


Lesenswert?

> Was macht Ihr so damit?

Forthprogrammierer machen im allgemeinen nur eins, sie implementieren 
den Interpreter auf jeden neuen Controller/CPU die rauskommt. :-)


Olaf

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Forth z.B. muß auf die
> Schnauze fallen, wenn das Zielsystem überhaupt nicht über einen Stack
> verfügt.

Keineswegs. Die einzige Voraussetzung für eine effektive Umsetzung ist 
die effiziente Fähigkeit zur Adressierung über mehrere Adress- oder 
Indexregister (vorzugsweise mindestens 3), oder vergleichbare 
Mechanismen. Ob die Inkrementierung/Dekrementierung implizit oder 
explizit erfolgt ist hingegen ziemlich unwichtig.

Ein Return-Stack in Hardware ausserhalb des RAMs ist für beide 
Forth-Stacks hingegen völlig nutzlos.

von chris (Gast)


Lesenswert?

>Wo für mich ein absolutes Fragezeichen ist
>ist die Toolchain. Wie kommt man zum binary aus den Forth Dateien?

Hier gibts einen Simulator für die Kommandozeile:
http://www.excamera.com/files/j1c.tar.gz
Es gibt zusätzlich eine "Forth-Cross-Compiler" ( wird unter gforth 
ausgeführt ). Damit kann man ein Binary erzeugen und laufen lassen. ( 
man muss eingentlich nur die Schritte wie im Makefile ausführen ).

>Ein nettes Gegenbeispiel ist der 8051 mit einer ausgezeichneten
>Dokumentation. Vielleicht wäre es für meine Anwendungen am Besten den
>8051 zu virtualisieren. ISA und RAM sind halt unschön (z.B.
>Registerbänke).
Dafür hatte ich mal einen Simulator geschrieben und auf einem NiboBee 
Roboter laufen lassen ( Atmega16 ). Damit konnten dann Leute den Roboter 
in 8051 Assembler programmieren. ( Ich habe mir schon überlegt, einen 
Thread hier im MC-Netz dafür aufzumachen. z.B. mit dem Titel "8051 
Assembler auf einem Atmega laufen lassen" :-)  )

Insgesamt ist mir der Code für die 8051 CPU Simulation aber zu groß, da 
die CPU recht viele Befehle hat. Für eine VM zu unelegant. Die 
J1-Implementierung dagegen ist sehr viel schlanker und sehr 
minimalistischer.

von Weinga U. (weinga-unity)


Lesenswert?

@chris:

J1 ist verglichen zu 8051 wirklich massiv einfacher zu implementieren.
Kannst du bereits sagen wie es mit floating point aussieht? Funktioniert 
das wenn auch in software emuliert?

J1 hat bei der ALU Instruction einen interessanten Ansatz verwendet wie 
man unterschiedliche Operationen in einer Instruction unterbringen kann.


@c-hater:
> > 8051 ist
> > optimal).

> Wofür? Der Begriff "optimal" ergibt nur dann einen Sinn, wenn man das
> (genau ein!) Optimierungsziel definiert oder für den (üblichen) Fall,
> daß es deren mehrere gibt, alle Ziele sowie deren relative Wichtung
> angibt.

Mein benötigtes Optimum ist wie folgt definiert (entspricht einer 
Wunschvorstellung):

nogcc = 1 wenn kein gcc, sonst 0

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

c-hater schrieb:
>> Ich lese immer, dass von den unterschiedlichen Projekten das Ziel ist
>> die Plattformunabhängigkeit zu erzielen
>
> Hehres Ziel, aber niemals auch nur andeutungsweise wirklich erreicht...
>

Klar, in deiner Lieblingsprogrammiersprache nicht. :-)

Aber NetBSD ist natürlich auch nicht in Assembler geschrieben.

chris schrieb:
> Aber wie kann ich mein "Werk" abspeichern?

Das ursprüngliche Massenspeicherkonzept von FORTH war sehr einfach
gestrickt.  Die Idee dabei war, dass FORTH auf den entsprechenden
mikroprozessorbasierten Computern die Rolle des Betriebssystems
übernimmt und damit auch den Massenspeicher (= Diskette) selbst
verwaltet.  Entsprechend gibt es kein Dateisystem, sondern der
Massenspeicher wird in logischen Blöcken zu 1 KiB verwaltet, das
entspricht jeweils einem Editor-Bildschirm mit den Abmessungen der
damaligen Zeit (16 Zeilen je 64 Zeichen) und wird in 8 hintereinander
liegenden Diskettensektoren gespeichert.

Musst mal schauen, ob es eine Emulation dieses Prinzips auch nach
wie vor noch gibt.  Das, was damals auf eine Diskette gepasst hat,
kann man ja heute locker in einer einzigen kleinen Datei im
Dateisystem unterbringen.

von chris (Gast)


Lesenswert?

>Musst mal schauen, ob es eine Emulation dieses Prinzips auch nach
>wie vor noch gibt.
Im Moment verwende ich die von A.K. vorgeschlagene Methode: Im Editor 
die Forth-Dateien extern erstellen und abspeichern. Nur für das 
Cross-Compiling gforth aufrufen und eine Binär-Datei für die J1 
erzeugen.

>Kannst du bereits sagen wie es mit floating point aussieht?

Es gibt in der J1 keine Floating-Point Operationen, diese müsste man 
emulieren und sie wären sehr langsam. Ich bin mir sicher, dass es einige 
FORTH-Bilbliotheken gibt, die Floating-Point auf Integer abbilden.

Das FORTH-Prinzip ist der J1 ist allerdings relativ einfach zu 
erweitern.

1. Jeder Befehl ( Forth Wort ) besteht aus nur 16 Bit
2. Es gibt den Basis-Instruktionssatz der J1.
3. Der Basis-Befehlssatz läst sich relativ einfach in FORTH-Worter 
umwandeln.
4. Forth Worte höhere Ordnugn werden immer als "call" auf den jeweiligen 
Code realisiert. Dieser is auch in 16 Bit codiert:
1
  call        0  1  0 --------TARGET -------------


Nehmen wir z.B. ein paar Definitionen aus "basewords.fs":
1
: dup       T     T->N          d+1 alu ;
2
3
: drop      N                   d-1 alu ;
4
5
: !         T     N->[T]        d-1 alu
6
            N                   d-1 alu ;

Es gibt folgende Register
T: Top of Stack
N: Das Datenwort im Stack unterhalb vom Top

Das Wort "over" holt N auf den Top, macht gleichzeitig den alten Top zum 
N und erhöht den Data-Stack-Pointer um 1.

Das Wort " ! ( store )" welches den Wert von TOP in den Zentralspeicher 
schiebt, besteht aus 2 J1 Instruktionen: Nimm den Wert von N und 
speichere den Wert in die Speicherzelle auf die Top zeigt und erniedrige 
den Datastack um 1. Als nächstes mach N zu Top und erniedrige den 
Datastack noch mal um 1.

Floating point Instruktionen lassen sich einfach als "call" auf eine 
native C Routine oder Assembler implementieren, wenn sie schnell sein 
sollen. Der Vorteil der J1 ist allerdings die sehr platzsparende 
Realierbarkeit auf einem FPGA, was bei native Floating Pointer wieder 
schwierig wäre.

von chris (Gast)


Lesenswert?

Man kann auf eine VM verzichten und jeden FORTH-Befehle als 
C-Funktonsaufruf realisieren. Diesen Weg geht Grasp-Forth 
http://forthfreak.net/index.cgi?GraspForth
Damit erhält man dann einen sehr schnellen Forth-Interpreter. Die 
Eleganz der J1, die schnelle Portierparkeit auf eine andere Architektur 
und die Möglichkeit den J1-Code auf einem kleinen FPGA laufen zu lassen, 
geht damit allerdings verloren.

von Fritz (Gast)


Lesenswert?

Hallo an alle Forth-Freunde

Habe mir das J1 Projekt einmal angesehen. Es war schon lange der Wunsch 
der Forth-Community eine "Nativ-Forth-CPU" zu bauen. Also eine CPU die 
Forthcode mehr oder weniger direkt ausführt. Diese Ansätze (z. B. RX2000 
wenn ich mich recht erinnere) waren eher kommerziell nicht erfolgreich 
und wurden bald eingestellt. Einer der Hauptgründe dafür ist mMn, dass 
man eine sehr proprietäre CPU hat, die zu praktisch nichts irgendwie 
kompatibel ist. Der J1-Ansatz eines TCP/IP-Stacks mag zwar 
funktionieren, aber es gibt Unmengen von Anwendungen in C die man erst 
darauf anpassen muß, bzw. man wegen der fehlenden C-Kompilierbarkeit 
nicht verwenden kann.
Ich habe seit Jahr(zehnt)en mit Forth mehr oder weniger intensiv 
gearbeitet und auch einige kommerzielle Anwendungen damit durchgeführt. 
Begonnen habe ich mit einem fig.forth für den Z80. Mit einem Forth für 
den PC damals noch 16bit-Forth wurde ich auf Grund der wirklich vielen 
guten Programmierumgebungen (z.B. Turbopascal und danach Delphi ...) für 
den PC auf Dauer nicht wirklich glücklich und verwendete Forth nur mehr 
im embedded Bereich. Ein von mir ausgebautes fig-forth für die 68k-CPU 
brachte mir die Möglichkeit, nur mit einem Terminalprogramm über die 
serielle Schnittstelle komplette Gerätesoftware zu entwickeln. Ein 
einfacher preemptiver Multitasker ermöglichte es auch mir am laufenden 
Gerät/Applikation die Anwendung zu überprüfen und debuggen, da ich 
defakto einen Kommandozeileninterpreter = Forthprompt jederzeit zur 
Verfügung hatte. Ist aber jetzt auch schon wieder einige Jährchen her.

Aus allen diesen Gründen sehe ich für mich den J1 bzw. ein Forth auf 8 
oder 16bit CPUs für nicht interessant.
Momentan bin ich gerade dabei ein Forth für den Cortex M4 zu 
implementieren. Wenn man sich nicht scheut Assembler zu verwenden kommt 
da auch recht effektiver Code zustande.

von Weinga U. (weinga-unity)


Lesenswert?

Fritz schrieb:

> Es war schon lange der Wunsch
> der Forth-Community eine "Nativ-Forth-CPU" zu bauen. Also eine CPU die
> Forthcode mehr oder weniger direkt ausführt.

So fomuliert ist dies eine berechtigte Herangehensweise. Wenn ich nun 
geistig die Sache angehe stellt sich sofort folgende Frage: Wie führt 
man Forthcode direkt aus? Vorweg, ich habe nochnie mit Forth 
programmiert.

Beispiel einer Word-Definition (aus dem Netz)
    : indexed-array ( n -- ) ( i -- a)
         create cells allot
         does> swap cells + ;

Aufruf:
    20 indexed-array foo  \ Make a 1-dimensional array with 20 cells
     3 foo                \ Put addr of fourth element on the stack

So, wie würde nun die CPU tun? Den String beim Aufruf solange 
durchwursteln bis er endlich die Definition von indexed-array findet, 
oder bietet da z.B. gforth bereits ein besser verwendbare Darstellung an 
in Form eines Binaries mit Forth Grundbefehlen und Sprungbefehlen an 
absolute Speicheradressen?

Leichter Themenschwenk:
Die Akzeptanz einer VM ist abhängig von den verfügbaren 
Programmiersprachen. C ist schon einmal ein guter Anfang. IEC61131-3 
hören die Leute auch gerne. IEC61131-3 hat sich die Mühe gemacht 
unterschiedliche Darstellungsformen (IL, ST, ...) zu definieren. Wie 
diese dann ausführbar gemacht werden wurde diversen Firmen überlassen 
die damit Geld verdienen. Jeder bietet die Sprache an und hat noch die 
eine oder andere Erweiterung dazu gemacht. Ich hätte es persönlich 
absolut Klasse gefunden, wenn IEC61131-3 die unterschiedlichen Sprachen 
IL, ST, ... und eine VM+Instruction Set+IO Interface dazu definiert 
hätte. Dann gäbe es einen gemeinsamen Nenner und die ganze Angelegenheit 
hätte meinem Empfinden nach einen nachhaltigeren Character. Die Firmen 
hätten immer noch IDEs, Debugger, Compiler usw. dazu verkaufen können. 
Einen GCC hätte es auch vielleicht dafür gegeben :-).

von chris (Gast)


Lesenswert?

>So fomuliert ist dies eine berechtigte Herangehensweise. Wenn ich nun
>geistig die Sache angehe stellt sich sofort folgende Frage: Wie führt
>man Forthcode direkt aus?

Es werden nur die Low-Level Befehle direkt ausgeführt. Wie eben die 
weiter oben beschriebenen Befehle. z.B. dup es dupliziert den oberen 
Wert auf dem Stack. Oder "+" es addiert den Stack und einen Wert 
darunter.

Um ein Gefühl dafür zu bekommen, könntest Du gforth runterladen und eine 
Seite dieses Tutorials ausprobieren:
http://www.forth.com/starting-forth/sf1/sf1.html

Auch sehr aufschlussreich ist dieses Miniforth in einem kurzen Pythons 
Scribt realisiert:
http://openbookproject.net/py4fun/forth/forth.html

An den Befehlen dieser Java-JVM
http://www.harbaum.org/till/nanovm/index.shtml
sieht man sehr gut, dass es von FORTH inspieriert ist ( z.B. der Befehl 
dup )

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Oh, Forth.

Erinnert sich noch jemand an den ersten (und wohl einzigen) 
"Home-Computer", der mit einem Forth im ROM geliefert wurde, den Jupiter 
Ace?

So ein Ding war mein erster Computer ... erstaunlich, daß ich danach 
nicht angefangen habe, Pferde zu züchten, oder Wirt (ohne h) zu werden.

von Andreas B. (andreas_b77)


Lesenswert?

Weinga Unity schrieb:
> So, wie würde nun die CPU tun? Den String beim Aufruf solange
> durchwursteln bis er endlich die Definition von indexed-array findet,
> oder bietet da z.B. gforth bereits ein besser verwendbare Darstellung an
> in Form eines Binaries mit Forth Grundbefehlen und Sprungbefehlen an
> absolute Speicheradressen?

Nein, das ist Source Code. Das Suchen der Definition in der Wortliste 
wird vom Interpreter durchgeführt, der das gefundene Wort im 
Compiler-Modus an die aktuelle Definition anhängt statt sie auszuführen.

gforth ist eine eher schlechtes Beispiel für klassische Forth-Systeme, 
da es portabel in C geschrieben ist und deshalb einiges anders machen 
muss.

http://www.bradrodriguez.com/papers/moving1.htm ist ein Tutorial zum 
Design eines Forth-Systems von Grund auf und beschreibt auch die 
verschiedenen möglichen Threading-Mechanismen.


chris schrieb:
> An den Befehlen dieser Java-JVM
> http://www.harbaum.org/till/nanovm/index.shtml
> sieht man sehr gut, dass es von FORTH inspieriert ist ( z.B. der Befehl
> dup )

Naja, nicht so unbedingt. Die JVM ist eine Stack-Maschine und benötigt 
somit zwangsläufig Befehle zum Verwalten des Stacks. Um den Befehl zum 
Duplizieren des obersten Wertes dup zu nennen, muss man nicht wirklich 
von Forth inspiriert gewesen sein.

von Konrad S. (maybee)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Erinnert sich noch jemand an den ersten (und wohl einzigen)
> "Home-Computer", der mit einem Forth im ROM geliefert wurde, den Jupiter
> Ace?

Mein erster Rechner mit Forth im ROM war eine Sun.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Konrad S. schrieb:
> Mein erster Rechner mit Forth im ROM war eine Sun.

Wann?

von (prx) A. K. (prx)


Lesenswert?

Andreas B. schrieb:
> Um den Befehl zum
> Duplizieren des obersten Wertes dup zu nennen, muss man nicht wirklich
> von Forth inspiriert gewesen sein.

Genauso gut könnte man behaupten, dass die JVM von HP Taschenrechnern 
inspiriert wurde. ;-)

Kurioserweise gab es mit den INMOS Transputern eine Stack-Architektur, 
die ursprünglich kein DUP implementierte. Weil die einzig vorgesehene 
Sprache Occam es auf den T2xx/T4xx nicht benötigte. Bei einer Umsetzung 
von C war das recht nervig. Erst beim T800 mit FPU wurde DUP eben dafür 
erforderlich und folglich implementiert.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
>> Mein erster Rechner mit Forth im ROM war eine Sun.
>
> Wann?

Suns haben das schon lange, zumindest alle (Ultra-)SPARC-Varianten
bis zuletzt.  (Ich weiß nicht, ob die späteren AMD-basierten Server
auch noch einen FORTH-basierten OBP hatten.)

Allerdings merkt man normalerweise nicht sehr viel davon, wenn man
nicht gerade mal explizit am Bootprompt eine FORTH-Schleife oder
sowas eingibt.

von Konrad S. (maybee)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Wann?

Ca. 1994.

Jörg Wunsch schrieb:
> (Ich weiß nicht, ob die späteren AMD-basierten Server
> auch noch einen FORTH-basierten OBP hatten.)

Nein, das ist was anderes, evtl. was EFI-artiges. Ist 'n bisschen 
strange (wenn man OBP gewohnt ist).

> Allerdings merkt man normalerweise nicht sehr viel davon, wenn man
> nicht gerade mal explizit am Bootprompt eine FORTH-Schleife oder
> sowas eingibt.

Hach, seufz! Die gute alte Zeit! ;-)
(Braucht einer noch 'ne SS1000?)

von Weinga U. (weinga-unity)


Lesenswert?

Mir ist in den Sinn gekommen, dass ma ja eine Floating-Point Einheit als 
IO-Device an den J1 anschließen könnte. So hätte man schnelle 
floating-point Operationen obwohl J1 dies nicht unterstützt.

von (prx) A. K. (prx)


Lesenswert?

Weinga Unity schrieb:
> Mir ist in den Sinn gekommen, dass ma ja eine Floating-Point Einheit als
> IO-Device an den J1 anschließen könnte

Wenn du heute noch eine findest...

von chris_ (Gast)


Lesenswert?

Ein paar sehr interessante Links habe ich noch gefunden:
pforth ( portrable Forth written in C ) http://code.google.com/p/pforth/
Darin findet man schöne Beispiele für die Implementierung des 
Basiswortschates in C.
Und hier einen BASIC Interpreter in FORTH geschrieben.

Damit könnte man auf der J1 Basic laufen lassen.

von chris_ (Gast)


Lesenswert?


von Weinga U. (weinga-unity)


Lesenswert?

@ A.K.:
>> Mir ist in den Sinn gekommen, dass ma ja eine Floating-Point Einheit als
>> IO-Device an den J1 anschließen könnte

>Wenn du heute noch eine findest...

Da mein Ziel ist die den Core (z.B. J1) sowieso nur in Software zu 
emulieren, ist eine FPU in Software nicht das Problem :-) .

von chris_ (Gast)


Lesenswert?

>> An den Befehlen dieser Java-JVM
>> http://www.harbaum.org/till/nanovm/index.shtml
>> sieht man sehr gut, dass es von FORTH inspieriert ist ( z.B. der Befehl
>> dup )

>Naja, nicht so unbedingt. Die JVM ist eine Stack-Maschine und benötigt
>somit zwangsläufig Befehle zum Verwalten des Stacks.

Wann wohl die erste Stack-Maschine gebaut wurde?

vor 1969: Forth 
http://de.wikipedia.org/wiki/Forth_%28Programmiersprache%29
1972: HP35 Taschenrechner http://de.wikipedia.org/wiki/HP-35
1983: Transputer http://de.wikipedia.org/wiki/Transputer
1991: Java www.sauer-daaden.de/java-ag/java-geschichte.pdf‎

>Genauso gut könnte man behaupten, dass die JVM von HP Taschenrechnern
>inspiriert wurde. ;-)

Könnte schon sein, allerdings waren die HP-Taschenrechner 3 Jahre später 
als FORTH.

von chris_ (Gast)


Lesenswert?

Virtuelle Maschinen scheint es auch schon lange vor JAVA und der JVM zu 
geben:
http://de.wikipedia.org/wiki/P-Code
Den P-Code gab es wohl schon auf dem Apple II

von (prx) A. K. (prx)


Lesenswert?

chris_ schrieb:
> Wann wohl die erste Stack-Maschine gebaut wurde?

Ob es die erste war weiss ich nicht, aber 1961 brachte Burroughs die 
B5000. Die erste eine Reihe von Mainframes, die als Stack-Maschinen 
gebaut waren. Chuck Moore wurde von einer B5500 inspiriert: 
https://en.wikipedia.org/wiki/Burroughs_large_systems
https://en.wikipedia.org/wiki/Talk:Burroughs_large_systems#Assembler

Wer solche Architekturen heute vermisst: Es gibt gute Gründe, weshalb 
man keine Stack-Maschinen mehr baut. Jenseits ihres sehr einfaches 
Aufbaus sind sie ausgesprochen ineffizient.

von Drogbart (Gast)


Lesenswert?

A. K. schrieb:

> Wer solche Architekturen heute vermisst: Es gibt gute Gründe, weshalb
> man keine Stack-Maschinen mehr baut.

Welche Gründe wären die wichtigsten?

> Jenseits ihres sehr einfaches Aufbaus sind sie ausgesprochen ineffizient.

Auf welche Weise ineffizient?

von (prx) A. K. (prx)


Lesenswert?

Wenn wir mal von einer simplen Grundmaschine von Neumann'schen Aufbaus 
mit Stack im RAM ausgehen, dann besteht bei einer Stackmaschine eine 
simple Addition jeseits des instruction fetch/decode vereinfacht aus:
- oberstes Wort laden
- nächstes Wort laden
- addieren
- oberstes Wort schreiben
Da nur ein Speicherbus vorhanden ist, sind diese Operationen 
sequentiell. Überlappungen sind aufgrund des einfach vorhandenen 
Speicherbusses nur begrenzt möglich.

Bei einer einfachen Registermaschine haben wir statt dessen.
- beide Register lesen
- addieren
- Register schreiben,
wobei sich der erste und der letzte Schritt oft recht einfach mit der 
vorherigen/nachfolgenden Operation überlappen kann (pipelining).

Dieses einfache Modell führt also bei einer Registermaschine effektiv 
eine Operation pro Takt aus, bei der Stackmaschine eine Operation alle 4 
Takte. Da ein Registerzugriff weniger Strom benötigt als ein 
Speicherzugriff, sinkt auch der Stromverbrauch.

Naheliegenderweise hat man Stackmaschinen bald so gebaut, dass sich die 
obersten Worte in Registern befinden. Der dabei entstehende Cache ist 
nun allerdings nicht weniger komplex als ein Registersatz gleicher 
Grösse, wodurch der Vorteil der strukturellen Einfachheit perdu ist. 
Dafür handelt man sich bei einem adressierbaren Stack (Forth: PICK) die 
Notwendigkeit ein, die Adressen von Lade/Speicherbefehlen gegen die 
Register zu prüfen.

Historisch gesehen liegt der Vorteil von Stackmaschinen in der einfachen 
Umsetzung von Hochsprachen. Die erwähnten Burroughs Mainframes konnten 
Algol sehr gut umsetzen, ohne dafür hochkomplexe optimierende Compiler 
mit audgrund Speichermangels vielen Durchläufen zu benötigen. Die 
Compiler hat man heute allerdings, dieses Argument ist also keines mehr.

von (prx) A. K. (prx)


Lesenswert?

Wenn man einen Schritt weiter geht, sich also von dem traditionellen 
streng sequentiellen Maschinenmodell löst, dann sind Stackmaschinen 
zunächst völlig unbrauchbar. Denn viele Befehle basieren auf dem 
Ergebnis des vorherigen Befehls, was eine parallele Ausführung 
ausschliesst - schon einfaches Pipelining von den mehrtaktigen 
Operationen, wie Multiplikationen oder Fliesskommaoperationen, bringt 
nur noch wenig.

Mit diesem Problem musste Intel beispielsweise bei der FPU kämpfen. Die 
x87 Register sind als Stack aufgebaut, weshalb die erste gepipelinete 
FPU, im Pentium P5/P54, einen recht üblen Klimmzug mit der FXCH 
Operation einbauen musste, um mit einer Pipeline überhaupt etwas 
anfangen zu können. Die Abkehr von x87 Befehlen zugunsten von SSE hat 
auch damit zu tun, in den 64-Bit Programmiermodellen der üblichen 
Betriebssysteme kommen die x87 Befehle nicht mehr vor.

Erste wenn man dutzende Befehle im Pool betrachtet, wie das bei heutigen 
highend CPUs mit ihrer out of order execution der Fall ist, könnte man 
bei einer Stackmaschine wieder gewisse Parallelitäten nutzen. Aber 
weshalb sollte man das tun?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Selbst bei den VMs sind sich die Experten nicht mehr sicher, ob eine 
Stack-Maschine das richtige Modell dafür ist. So wurde bei den 
Android-Smartphones die stackorientierte Java-VM durch eine 
registerorientierte ersetzt. Es wird allerdings noch darüber diskutiert, 
ob das registerorientierte Konzept wirklich die erwarteten Vorteile 
bringt.

Fritz schrieb:
> Es war schon lange der Wunsch der Forth-Community eine "Nativ-Forth-CPU" zu
> bauen.

Auch Atmel hatte so etwas im Programm, nämlich den MARC4. Im Vordergrund 
stand dabei nicht die Ausführungsgeschwindigkeit, sondern der einfache 
Aufbau und der niedrige Stromverbrauch. Ein dazu passender Compiler 
(qFORTH) wurde von Atmel ebenfalls geliefert.

von (prx) A. K. (prx)


Lesenswert?

Yalu X. schrieb:
> Selbst bei den VMs sind sich die Experten nicht mehr sicher, ob eine
> Stack-Maschine das richtige Modell dafür ist. So wurde bei den
> Android-Smartphones die stackorientierte Java-VM durch eine
> registerorientierte ersetzt.

Das ist eine Frage des Aufwands. Von Androids Dalvik-VM zu leidlich 
gutem Maschinencode geht zwar einfacher und fixer als von Java Bytecode. 
Aber Suns Hotspot-Compiler für die JVM soll letztlich schnelleren Code 
produzieren als Android mit der Dalvik-VM.

von chris_ (Gast)


Lesenswert?

> Es war schon lange der Wunsch der Forth-Community eine "Nativ-Forth-CPU" > zu 
bauen.

Es gibt eine mit 144 Cores. Der Forth Efinder persöhnlich ist an der 
Firma beteiligt:
http://www.greenarraychips.com/index.html m

von chris_ (Gast)


Lesenswert?

Es gibt auch größere FORTH-Prozessoren in Open-Cores:
http://opencores.org/project,myforthprocessor
Benutzt wird ein Xilinx Spartan 3 FPGA

von chris_ (Gast)


Lesenswert?

Im Moment versuche ich gerade, einen eigenen kleinen FORTH-Interpreter 
zu programmieren. Ich hänge allerdings an einer Stelle: Wie kann man ein 
IF implementieren.
Im Forth Code der J1 scheint das realtiv elegant gelöst:
1
( Conditionals                               JCB 13:12 09/03/10)
2
: if
3
    there
4
    0 0branch
5
;
6
7
: resolve
8
    dup t@ there 2/ or swap t!
9
;
10
11
: then
12
    resolve
13
    s" (then)" setlabel
14
;
15
16
: else
17
    there
18
    0 ubranch 
19
    swap resolve
20
    s" (else)" setlabel
21
;
( aus http://www.excamera.com/files/j1c.tar.gz in crossj1.fs )

Hat jemand eine Idee, wie man die Condional Loops implementiert?

von Gerhard H. (Firma: Rentner) (spectro)


Lesenswert?

Spitze gemacht!
Leute, das für Win kennt Ihr aber schon?
http://sourceforge.net/projects/win32forth/
Auch ein Geheimtipp! ;-)

von gerhard h. (Gast)


Lesenswert?

Übrigens: Die Sache mit Forth kann ganz schön teuer kommen:

http://www.forth.com/forth/

Von wegen toter Programmiersprache.. ;-)

von chris_ (Gast)


Lesenswert?

Bei FORTH gibt es die Möglichkeit, Wörtern für den Compile-Vorgang einen 
"immediate" Anteil mitzugeben. Dieser "immediate" Anteil wird dann 
während des Compilierens ausgeführt.
Es gibt wohl einige FORTH-Implementierungen, die ein Flag im 
Dictionary-Eintrag zur Kennzeichnung eines "Immediate"-Wortes verweden. 
Ich frage mich, ob das nicht mit weniger Speicherverbrauch geht, in dem 
man einfach als ersten Befehl im Wort ein "immediate" mitcompilert.
Das hätte dann den Vorteil, dass man nicht für alle Wörter das Flag im 
Dictionary reservieren muss, sondern nur für die "immediate"-Wörter. Das 
spart Speicherplatz.

von Fritz (Gast)


Lesenswert?

chris_ schrieb:
> Das hätte dann den Vorteil, dass man nicht für alle Wörter das Flag im
> Dictionary reservieren muss, sondern nur für die "immediate"-Wörter. Das
> spart Speicherplatz.

Die meisten Forths wie ich sie kenne, haben ein Byte für die Länge des 
Word-namens und die Flags reserviert. Z.B bit 0 - 6 sind die Länge des 
Namens und bit 6 und 7 sind die beiden Flags smudge und immediate!
Also 1 bit sparen ist wirklich alles andere als sinnvoll!

von chris_ (Gast)


Lesenswert?

Im Moment fasziniert mich FORTH sehr.
Deshalb habe ich zum Erkenntnisgewinn und Spass einen kleinen Forth 
Compiler/Interpreter in C geschrieben und eine virtuelle Maschine auf 
einem Arduino Uno programmiert.

http://www.hobby-roboter.de/forum/viewtopic.php?f=4&t=145

von Weinga U. (weinga-unity)


Lesenswert?

Hallo chris_,

eine liebe kleine VM die du da gebastelt hast. Portabel und 
resourcenschonend (wenn man 1k Ram noch zur Verfügung hat :-) ). 
Ähnlichkeiten vom VM-Aufbau zu meiner VM die ich vor Längerem gemacht 
habe sind da und über dein RAM hats du anhand dem seriellen Interface 
schön gezeigt wie man auf die Hardware zugreifen kann. Die externe 
C-Funktion ist auch bestimmt praktisch.

Wie hast du den Compiler von Forth auf dein Programm-Array realisiert? 
Übersetzt Forth sich selbst? Gibts da funktionale Einschränkungen?
Das würde mich noch stark interessieren.

von chris_ (Gast)


Lesenswert?

>eine liebe kleine VM die du da gebastelt hast. Portabel und
>resourcenschonend (wenn man 1k Ram noch zur Verfügung hat :-) ).

Hallo Weinga,

es freut mich ja sehr, dass Dir die VM gefällt. Ich hatte ja schon die 
Befürchtung, dass sich keiner dafür interessiert.
Die 1K-Ram sind wilkürlich gewählt, weil der Atmega328 auf dem Arduino 
2K hat. Eigentlich wollte ich die VM auf einem Attiny85 laufen lassen, 
da ich aber gerade keine Lust hatte, die Umgebung aufzusetzen, habe ich 
das Arduino-Board genommen. Ausserdem wäre es dann mit dem Demo-Programm 
schwierig geworden. Eine blinkende LED ist vermtulich nicht so 
beeindruckend, wie die serielle Ausgabe von Rechenergebnissen.

Die Struktur der VM ist vermutlich nicht aussergewöhnlich, die Befehle 
werden letzendlich via switch-case interpretiert. Das Format der 
Konstanten und der Jumps sind von der J1 inspiriert.

Im Moment ist die Ausführungsgeschwindigkeit ca. 10.000 bis 60.000 
Befehle pro Sekunde. Vermutlich lässt sich das Ganze noch stark 
optimieren, wenn man die Befehle nach Häufigkeit in der switch-case 
Abfrage ordnet und die Range-Checks für die Stacküberläufe heraus nimmt.

Den Compiler werde ich veröffentlichen. Ich hoffe, dass ihn jemand 
ausprobiert. Er ist mit gcc gemacht und beinhaltet 
Compiler/Interpreter/Debugger.

Nehmen wir folgenden Befehl:

: dtest 1 2 3 . . . ;

mit

debug dtest

erhält man als Ausgabe

 CALL 07c0   (dtest)       stack:
adr:07c0  push          stack:  0001
adr:07c2  push          stack:  0001  0002
adr:07c4  push          stack:  0001  0002  0003
adr:07c6  CALL 002c   (.)       stack:  0001  0002  0003
    3 adr:07c8  CALL 002c   (.)       stack:  0001  0002
    2 adr:07ca  CALL 002c   (.)       stack:  0001
    1 adr:07cc  rts          stack:


Gruß,
chris

von Weinga U. (weinga-unity)


Lesenswert?

D.h. das ist ein Compiler von Forth auf deine VM?

von chris_ (Gast)


Lesenswert?

Eigentlich ein ganzes Entwicklungssystem :-)

>D.h. das ist ein Compiler von Forth auf deine VM?
Der Source Code des Arrays in der VM ist in Forth geschrieben:

[code]
: multest ( n -- ) dup str type space s" square:" type dup * str type cr 
;
: hello s" if you see this, qrzVM is running calc square" type cr ;
: test init hello d# 0 100 0do 1+ dup multest loop ;

\ screen address access on PC makes screeen visible
: show h# 6000 @ 6000 ! ;

main test    \ set main jmp instructionTest

\ save       \   save memory to disk

[\code]

von Blende22 (Gast)


Lesenswert?

Hallo Chris!
Mich interessiert Dein Projekt sehr!
Derzeit bin ich da dran:
https://sites.google.com/site/libby8dev/fignition
https://sites.google.com/site/figgipad/the-pcb
Gruss Gerd

von chris_ (Gast)


Lesenswert?

Hi Gerd,

super gemacht ! Dein Forth dürfte ca. 100 mal schneller laufen, als das 
Forth auf meiner VM.
Vielleicht lässt sich später mal eines von Deinen Spielen in meinem 
VM-Code umsetzen und dann auf dem FPGA zum laufen bringen.

Gruß chris_

von chris_ (Gast)


Lesenswert?

So, jetzt habe ich den Code von  "qrzForth" einigermaßen dokumentiert. 
Ich hoffe, Ihr könnt euch darin zurecht finden:
http://www.hobby-roboter.de/forum/viewtopic.php?f=4&t=145

Besondere Features:

see "word"       :disassembliert das Wort
debug "word"     :debugged das Wort
y                :Anzahl der Instructionen, die das letzte Wort bei der 
Ausführung gebraucht hat.

>https://sites.google.com/site/libby8dev/fignition
Schade, dass es beim Arduino nur den Terminal Ausgang gibt. Für Spiele 
wäre ein VGA-Anschluss besser.
Vielleicht fällt euch was ein, was man mit der Terminal-Ausgabe Richtung 
Spiel machen könnte.

von Blende22 (Gast)


Lesenswert?

Hi Chris,
sag, die Bezeichnung 'qrz' hat nicht zufällig etwas mit Amateurfunk zu 
tun? ;-)
Gruss
Gerd

von chris_ (Gast)


Lesenswert?

>sag, die Bezeichnung 'qrz' hat nicht zufällig etwas mit Amateurfunk zu
>tun? ;-)

Hallo Gerd,

leider nein, aber im File qrzForth.c wird die Entstehungsgeschichte des 
Namens verraten ( bei den Kommentaren zur VM ).

Was hast machst Du mit der Fignition Platine für ein Projekt? Es würde 
mich interessieren.
Vielleicht
Gerade habe ich die Idee, qrzForth auf einem Arduino Due laufen zu 
lassen.
Vielleicht könnte man zum Spaß einen VGA-Anschluss an einen Arduino Due 
löten:
http://pi.gadgetoid.com/article/arduino-due-vga-output

Dann könnte man vielleicht auch die Spiele der Fignition darauf 
probieren.

Gruß,
chris

von Blende22 (Gast)


Lesenswert?

Hi Chris,

> Was hast machst Du mit der Fignition Platine für ein Projekt? Es würde
mich interessieren

Du, das ist wirklich eine gute Frage! Ich hab noch kein's! ;-) Aber, ich 
hab' mich mit sämtlichen FORTH-Seiten, die es im Internet gibt intensiv 
befasst. Und mein Lieblingsbuch habe ich mir ersteigert: Leo Brodie, 
Programmieren in Forth. In englischer Sprache gibt es ja Einiges im 
Netz, aber das Buch hatte ich schon mal und habe es unsinnigerweise und 
sträflicherweise vor etwa 25 Jahren "entsorgt".

Kurz gesagt, ich begann mal in grauer Vorzeit mit dem autodidaktischen 
Aneignen dieser Sprache, nachdem mir Assembler, C und Pascal auf dem 
C64-er nicht genug waren. :-)  (Das gab es wirklich alles für den 
Spiel-Rechner!)

Für den "Jupiter Ace" holte ich mir die Handbücher aus dem Netz.
Es gibt da ja so Vieles an interessanten Seiten, wenn man sich mit einer 
Computersprache befassen möchte, die ursprünglich zum Ansteuern von 
Radioteleskopen gedacht war und die möglichst wenig Speicher brauchen 
sollte.

http://oldcomputers.net/jupiter-ace.html
http://www.jupiter-ace.co.uk/usermanual.html

Nun, vor einigen Monaten entdeckte ich zufällig in der 
Trödler-Abraham-Bucht den Leo wieder und kurz drauf die verrückte 
Fignition-Seite und nahm Kontakt mit Carl aus Essex auf, der da recht 
rührig am Werk ist mit FORTH.
Das Konzept ist ja grosse Klasse, nur, das Arbeiten mit den Tastern ist 
nicht das Wahre, obwohl es sehr gut durchdacht ist.
Carl arbeitete fleissig an einer Erweiterung, um eine billige PS/2 - 
Tastatur verwenden zu können.

Man konnte bei ihm einen Bausatz haben, der allerdings kein PCB 
beinhaltete. Nachdem ich seit 1973 meine "printed curcuit boards" selber 
mache (anfangs mit schlechtem Erfolg und zuerst nur als Prototypen 
(30MHz - ZF für 10GHz Transceiver z.B.)), habe ich eine Platine für den 
Tastatur-Zusatz mit Sprint ( 
http://www.abacom-online.de/html/sprint-layout.html ) gefertigt. Ist 
kein EAGLE oder OrCAD, aber ich benötige keine Multilayer.

http://up.picr.de/15950244ra.jpg

http://up.picr.de/15895639am.jpg

Inzwischen habe ich mich von dem Forum hier bekehren lassen und 
begonnen, intensiv C zu lernen. AVR-Studio, die zwei Pollin-Bretter und 
"mySmartUSB light". ;-)

Das hat mich natürlich wieder in FORTH eingebremst, aber auch hier gilt 
der weise Spruch, dass das Eine das Andere ja nicht ausschliesst und bei 
FORTH bleibe ich bestimmt dran!  Ist irgendwie eine verschrobene 
Gemeinde.. So eine Art Sekte quasi. ;-) Nicht?

Herzliche Grüsse

Gerd

von Blende22 (Gast)


Lesenswert?

Nachtrag:
1.) Ich hab oben einen Beistrich vergessen! ;-)
2.) Es ist bestimmt vernünftiger, den Zusatzprint unter die Hauptplatine 
zu setzen, sonst kommt man an die Taster nur mehr schwer heran, obwohl 
davon nur einer zum Updaten benötigt wird.
saludos cordiales
Gerd

von chris_ (Gast)


Lesenswert?

>http://up.picr.de/15950244ra.jpg
Hey, die Platine ist ja perfekt geworden. So gleichmäßig habe ich das 
bis jetzt noch nie geschafft.

>Inzwischen habe ich mich von dem Forum hier bekehren lassen und
>begonnen, intensiv C zu lernen. AVR-Studio, die zwei Pollin-Bretter und
>"mySmartUSB light". ;-)

Welche Pollin Bretter hast Du denn? Vielleicht könnte man diese mit der 
qrzVM versehen, dann kannst Du wieder Forth machen.
Eine Idee wäre, das Pollin-Ethernet Board mit der VM auszustatten, dann 
könnte man den Code via Internet updaten.

>Das hat mich natürlich wieder in FORTH eingebremst, aber auch hier gilt
>der weise Spruch, dass das Eine das Andere ja nicht ausschliesst und bei
>FORTH bleibe ich bestimmt dran!  Ist irgendwie eine verschrobene
>Gemeinde.. So eine Art Sekte quasi. ;-) Nicht?

Ja, Forth ist ein wenig "altbacken". Ich bin jetzt auch nur wieder 
zufällig darauf gestoßen, weil ein Freund eine CPU auf einem FPGA machen 
will. Aber es ist ja unglaublich, wie viele Forth-Varianten man 
mittlerweile im Internet findet.
Da es etwas schwierig ist, einen eigenen C-Compiler zu schreiben, habe 
ich FORTH als "High-Level" Programmiersprache angeboten.
Außerdem interessiere ich mich schon seit langem für eine Methode, den 
gleichen Code auf unterschiedlichsten Maschinen laufen zu lassen.

von chris_ (Gast)


Lesenswert?

Noch eine kleine Anmerkung zur VM:

Ich habe gerade einen Test mit einer leeren do loop Schleife gemacht

10000 do loop duration: 1171 Millisekunden

Eine leere 0do loop Schleife sieht so aus:

adr:280e  281a  <= index of next entry
adr:2810  c822  CALL 0822   (empty)
adr:2812  6d65  em
adr:2814  7470  pt
adr:2816  0079
===== code =======
adr:0822  8020  >r
adr:0824  8021  r>
adr:0826  8004  1-
adr:0828  8022  dup
adr:082a  8000  0=
adr:082c  a822  JMPZ 0822
adr:082e  8023  drop
adr:0830  803e  rts

d.h. 6 Befehle pro loop.
Das ergibt ca. 48000 Befehle pro Sekunde. Mal sehen, ob man das durch 
umordnen etwas schneller bekommt.

von chris_ (Gast)


Lesenswert?

Jetzt habe ich das Programm mal auf einem Arduino Due ausprobiert.
http://arduino.cc/de/Main/ArduinoBoardDue
- SAM3X8E ARM Cortex-M3 CPU
- 84 MHz Taktung
Interessanterweise lässt sich die VM ohne Änderungen zum Arduino Uno 
kompilieren, obwohl die typischen AVR-Programmzugriffe im Code stehen:
#include <avr/pgmspace.h>

#define FORTHCODESIZE 1041 // words

PROGMEM uint16_t programMemory[] ={

Das Ergebnis:

10000 do loop duration: 266 Millisekunden

D.h. 220.000 Instruktionen/Sekunde
also etwas mehr als 4 mal schneller.

von Blende22 (Gast)


Lesenswert?

Hallo Chris!

> So gleichmäßig habe ich das
>bis jetzt noch nie geschafft.

Du, das ist eigentlich nicht mehr so schwierig, wenn man endlich weiss, 
wie es am besten geht. ;-) Ich drucke das Layout zweimal auf 
Inkjet-Folie (oder Overhead-Folie) aus, lege die Folien passgenau 
übereinander und fixiere sie mit Tesafilm. Auf diese Art wird die 
Vorlage wirklich lichtdicht.
Ich belichte zwischen 5 und 10 Minuten mit einem Gesichts-Bräunungsgerät 
aus etwa 40cm Abstand.  Entwickelt wird mit einem gestrichenem Teelöffel 
voll mit Ätznatron-Granulat (Natriumhydroxyd), wobei die 
Wassertemperatur so um die 35°C betragen sollte (Ist nicht so genau, 
aber kalt soll das Wasser nicht sein).
Geätzt wird mit 80ml HCl (30%), dazu 20ml Wasser und 15ml H2O2 
(Wasserstoffperoxydlösung 30%).
Mit der Methode geht eigentlich nie was daneben. Die Belichtungszeit ist 
unkritisch, wenn die Vorlage wirklich lichtdicht ist. Besser länger 
belichten als zu knapp.

> Welche Pollin Bretter hast Du denn?

Die beiden Billigsdorfer Dinger:

http://up.picr.de/16429092et.jpg

Ich habe dem Board noch einen Nullkraftsockel spendiert.

Die Zusatzplatine für das Fignition-Board habe ich etwas abgeändert, 
damit man zum Update-Taster dazu kommt.

http://up.picr.de/16429091hm.jpg

Die Status-LED und eine Power-On-LED ist auch noch drauf.

Toll, wie Du Dich in Dein Forth-Projekt hineinsteigerst! Hinsichtlich 
Programmierung komme ich da auf keinen Fall mit.

Ich habe Etliches in Bascom gemacht und mit dem Eigenbau-Board hier 
gearbeitet:

http://up.picr.de/13096350fr.jpg

Da war z.B. ein "Dunkelkammer-Computer" mit beleuchteten Sensortasten 
dabei:

http://up.picr.de/10512588ek.jpg

oder eine Schrittmotorsteuerung zum Parabolisieren eines Newton-Spiegels 
(Foucault-Tester):

http://up.picr.de/13096343ia.jpg

So, jetzt bin ich aber sehr weit weg vom Thema. Gelobe, mich zu bessern. 
;-)

> D.h. 220.000 Instruktionen/Sekunde
>also etwas mehr als 4 mal schneller.

Prima hast Du das hingekriegt!

Grüsse,

Gerhard

von Blende22 (Gast)


Lesenswert?

Zusatz-Anmerkung: Die Menge Ätznatron gilt für 500ml Wasser.

von chris_ (Gast)


Lesenswert?

Hier gibt es eine universelle VM, die sich auch selber emulieren kann. 
Außerdem gibt es diese VM in fast allen Sprachen:

http://boundvariable.org/code.shtml

von chris_ (Gast)


Lesenswert?

Zum besseren Herunterladen gibt es jetzt ein GITHUB repository:
https://github.com/ChrisMicro

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.