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
> : 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/
>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.
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
constuint8_tdata[]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.
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 )
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?
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.
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?
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?
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?
>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"
>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.
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.
>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.
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.
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
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.
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.
> Was macht Ihr so damit?
Forthprogrammierer machen im allgemeinen nur eins, sie implementieren
den Interpreter auf jeden neuen Controller/CPU die rauskommt. :-)
Olaf
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.
>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.
@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):
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.
>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.
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.
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.
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 :-).
>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 )
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.
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.
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.
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.
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.
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?)
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.
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...
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.
@ 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 :-) .
>> 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.
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
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_systemshttps://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.
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?
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.
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?
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.
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.
> 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
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:
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.
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!
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
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.
>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
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]
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_
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.
>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
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.htmlhttp://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.jpghttp://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
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
>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.
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.
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.
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
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