8 Bit Laptops

Autor: Andre Adrian
Version: 05.Aug.2015

Einleitung

Der typische Laptop, Notebook oder Klapprechner hat heute ein Gewicht von 2,5 kg und einen 15-Zoll LCD. Eine Festplatte und ein DVD Laufwerk sind eingebaut. Neben diesem Laptop-Standard gibt es seit wenigen Jahren die Klasse der Netbooks wie den Asus Eee mit einem Gewicht von 1,2 kg und 10-Zoll LCD. Um Gewicht zu sparen fehlt dem Netbook das DVD Laufwerk In der Zeit von 1983 bis 1990 waren einige Laptops noch leichter als die heutigen Netbooks. Diese 8 Bit Laptops waren nicht so universell wie die heutigen Netbooks, hatten dafür aber Laufzeiten von bis zu 40 Stunden mit 4 AA (Mignon) Batterien.
Einer der ersten und wahrscheinlich erfolgreichsten frühen Laptops war das Tandy TRS-80 Model 100. Dieses Gerät hatte kein richtiges Betriebssystem im Bauch, keine Festplatte und noch nicht einmal ein Floppy Laufwerk. Durch sein geringes Gewicht und seine gute Schnittstellenausstattung mit Modem, V.24 serieller Schnittstelle und Centronics paralleler Schnittstelle war es bei Journalisten beliebt. Artikel schreiben, zum nächsten Telefon gehen und per Akustikkoppler den Artikel in die Redaktion übertragen. So war das Leben vor dem Internet.
Zur Blütezeit der 8-Bit Laptops war das Betriebssystem MS-DOS, mindestens ein Floppy Laufwerk war eingebaut und das Gewicht stieg auf mehrere Kilogramm. Kurz darauf wurden die 8-Bit Laptops mit ihrer 8088 CPU gegen Laptops mit 80286 und 80386 CPUs ausgewechselt. Mit der 80386 CPU begann die Zeit der 32 Bit Laptops, der Laptops wie wir sie heute noch kennen. Ab 1987 gab es von Toshiba den 5200 und von Compaq den Portable 386. Von Olivetti/Trimph-Adler erschien 1991 die "Walkstation 386 SX".
Wie immer, wenn eine Ära zu Ende geht, gab es Nachzügler. Die englische Firma Amstrad brachte 1992 noch einen 8 Bit Laptop auf den Markt. Bemerkenswert an diesem Gerät war das geringe Gewicht von 900 g bei einer normal großen Tastatur.
Zum Thema 8 Bit Laptops passt die Programmiersprache Forth. Eine kleine Forth Entwicklungsumgebung für Bildschirmterminal und Floppy Laufwerk benötigt 8 KByte RAM. Damit geht Forth sparsamer mit Arbeitsspeicher um als ein BASIC Interpreter. Forth Programme laufen auch deutlich schneller als BASIC Interpreter Programme.

Inhaltsverzeichnis


Tandy TRS-80 Model 100

Das Tandy Model 100 war baugleich zum Kyocera Kyotronic 85. Der Kyotronic war in Japan kein großer Erfolg, das Model 100 war ein echter Hit. Die LCD hatte 40x8 Zeichen Auflösung. Als Systemsoftware war Microsoft BASIC und das Modemprogramm TELCOM enthalten. Mit Virtual T von Stephen James Hurd und Ken Pettit wird das Model 100 auf einem MS-Windows Laptop simuliert.



IBM PC Convertible

Der IBM Convertible war 1986 der erste 8 Bit Laptop mit MS-DOS Betriebssystem, zwei 3,5 Zoll Floppy Laufwerken und einem Gewicht von 5,5 kg. Das Floppy Laufwerk konnte 720 KByte auf eine 3,5 Zoll Floppy schreiben. Die LCD Auflösung war 80x25 Zeichen. Die 80C88 CPU ist softwaremäßig 8086 kompatibel. Hardwaremäßig ist der Datenbus 8 Bit breit, der Adressbus 20 Bit.

Tandy WP-2

Der Tandy WP-2 von 1989 wurde als Portable Word Processor angeboten. Der WP-2 hatte die Model 100 Bauform und war eigentlich ein Citizen CBM-10WP. Positiv ist das große LCD mit 80x8 Zeichen. Negativ ist das fehlende BASIC. Die CPU war eine CMOS Variante des Z80. Dank einer seriellen Schnittstelle ließen sich Programme in den WP-2 laden und ausführen. Das WP-2 Programm TELCOM verstand das X-Modem Protokoll. Auf dem Partner-Computer war ein Programm wie Kermit nötig zum Datenaustausch. Das ROM war 256 KByte groß um eine Rechtschreibprüfung (spell checker) und einen Thesaurus unterzubringen. Als Sprache wurde nur amerikanisches Englisch unterstützt. Die Variante WP-3 hatte 64 KByte RAM, ein Pfund Zeichen anstelle des Dollar Zeichens auf der Tastatur und unterstützte britisches Englisch.
Für die WP-2 RAM-Disk ist ein SRAM IC nötig. Das 32 poliges 128 KByte SRAM im DIL Gehäuse vom Type 628128-70 wird in den WP-2 in Fassung IS1 eingebaut, siehe WP-2 Service Manual, Section II Disassambly Instructions. Die Pinbelegung von IS1 ist:



Tandy WP-2 CamelForth

Damit die CamelForth Portierung von John R. Hogerhuis auf dem WP-2 läuft ist ein SRAM als RAM-Disk nötig. Die Datei CAMEL.CO wird mit HyperTerminal (bei MS-Windows XP dabei) und RS232 Null-Modem-Kabel auf den WP-2 in die RAM-Disk übertragen. Die Übertragungsparameter auf der WP-2 werden mit F2 SETUP und F2 T eingestellt auf Device=RS232C, Baud rate=9600, Word length (bits)=8, Parity=None, Stop Bits=1, XON/XOFF=Disable, Printer echo=OFF, Duplex=Full, Transfer=CRC-XMODEM, Incoming CR=CR, Outgoing CR=CR und Mode=Originate.
Der Download erfolgt vom Entwicklungsrechner mit HyperTerminal. Auf dem WP-2 wird mit F2 TELCOM das Kommunikationsprogramm aufgerufen. Es meldet "RS232C is ready". Mit F1 D wird der Download auf dem WP-2 gestartet. Das Speichermenü erscheint. RAMDISK auswählen und Filename CAMEL.CO eingeben. An dem PC HyperTerminal auf 9600bps und 8-N-1 einstellen. Dann Datei senden vom HyperTerminal mit Protokoll Xmodem ausführen. Auf dem WP-2 CamelForth starten mit F2-Files, Auswahl von RAMDISK, Auswahl von CAMEL.CO und zuletzt F2-Run.

Atari Portfolio

Der Atari Portfolio ist wie der IBM Convertible ein MS-DOS Computer. Der Convertible ist ein typischer Aktentaschen Laptop, der Portfolio ist ein Manteltaschen-Laptop, oder Palmtop, mit 500 g Gewicht und 40x8 Zeichen LCD. Der Palmtop hatte weder Floppy Laufwerke noch serielle Schnittstelle. Eine serielle Schnittstelle konnte über eine Adapterkarte nachgerüstet werden, diese Adapterkarte ragte deutlich aus dem Portfolio heraus.

Amstrad NC100

Der Amstrad NC100 erschien erst 1992, deutlich nach der Blütezeit der 8 Bit Laptops. Zum Ausgleich ist der NC100 ein komplett ausgestattetes Gerät. Das LCD ist mit 80x8 Zeichen groß, eine serielle Schnittstelle ist vorhanden und auch an einem BASIC fehlt es nicht. Es ist das viel gelobte BBC BASIC eingebaut.

Texas Instruments TI83, TI84

Die programmierbaren Taschenrechner TI-83+ und TI84+ sind ebenfalls 8 Bit Laptops. Als CPU wird eine Z80 benutzt, 24 KByte freies RAM stehen zur Verfügung. Die Anzeige ist mit 16x8 Zeichen winzig, die Tastatur ist nicht für Vielschreiber geeignet, aber dafür ist das Gewicht nur 262 g. Der TI84 wird mit USB Anschlusskabel geliefert. Damit lässt sich leicht und günstig Software vom Entwicklungsrechner auf den Zielrechner kopieren. Beim TI-83 und TI-83+ muss ein Graphlink Kabel extra gekauft werden. Die Seite ticalc hat viele Informationen über diesen als Taschenrechner verkleideten Z80. Mit Wabbitemu gibt es einen TI84+ Emulator für MS-Windows.
Der TI Emulator benötigt die TI ROMs von der TI-Download Seite. Wabbitemu kann die TI84Plus_OS.8Xu Datei in eine TI84Plus.rom Datei umwandeln. Diese ROM Datei ist 1024 KByte groß. Auf der TI Webseite gibt es auch das Handbuch.



Vergleich der 8 Bit CPUs

In den 8 Bit Laptops wurden die CPUs 8085, 8088 und Z80 eingesetzt. Die 8088 CPU konnte 1 MByte Speicher adressieren, die beiden anderen CPUs nur 64 KByte. Einige Laptops hatten eine Speicherverwaltung (Memory Management Unit, MMU) außerhalb der CPU. Dadurch konnten der Tandy Portable WP2 und der Amstrad NC100 mit mehr als 64 KByte Speicher umgehen. Keine der CPUs hatte eine Fließkommaeinheit. Alle Berechnungen wurden von einer Mathematik-Bibliothek ausgeführt. Was war die beste Mathe-Bibliothek ist eine interessante Frage für den Autor. Und lieferte der 8088 bei gleicher Taktfrequenz mehr Flops (Fließkommaoperationen pro Sekunde) als der Z80? Interessant ist auch die Frage wie die Übergabe von Funktionsparametern bei der Programmiersprache C  bei den einzelnen CPUs am besten erfolgt. Wie bekannt werden die Parameter auf dem Stack übergeben. Die 8085 und Z80 CPU verfügen über einige Assembler-Kommandos welche die Parameterübergabe unterstützten. Die besten 8085 Opcodes für diesen Zweck waren undokumentierte 8085 Opcodes. Der Z80 hatte dokumentierte Opcodes, aber ob diese beim 8080 noch nicht vorhandenen Opcodes im Hi-Tech C eingesetzt wurden ist für den Autor offen.

Jahr
Modell
CPU
RAM
System Software
1983
Tandy TRS-80 Model 100
Intel 80C85 @ 2,4 MHz
8 KByte
Microsoft BASIC
1986
Tandy Model 102 Intel 80C85 @ 2,4 MHz 32 KByte Microsoft BASIC
1986
IBM PC Convertible
Intel 80C88 @ 4,77 MHz 256 KByte
MS-DOS 3.2
1987 Toshiba T1000 Intel 80C88 @ 4,7 MHz 512 KByte MS-DOS 2.11 im ROM
1988
Tandy 1400LT
NEC V20 @ 7,16 MHz
768 KByte
MS-DOS 3.2
1989
Citizen CBM-10WP
Tandy Portable WP-2
NEC uPD7008-A @ 5,53 MHz
32 KByte
TELCOM
1989
Tandy 1100FD, 1100HD
NEC V20 @ 8 MHz 640 KByte MS-DOS 3.3
1990
Atari Portfolio
MOS 80C88 @ 4,92 MHz
128 KByte
MS-DOS 2.11 Clone im ROM
1992
Amstrad NC100
Z84C00 @ 6 MHz
32 KByte
BBC BASIC
1996
Texas Instruments TI-83 Z80 @ 6 MHz
27 KByte
TI BASIC
2004
Texas Instruments TI-84
Z80 @ 15 MHz
24 KByte
TI BASIC

Fließkomma Berechnungen auf 8 Bit CPUs

Es gibt schon so viele Mathe-Bibliotheken für den 8080, 8085, Z80 und 8086, warum noch eine weitere Mathe-Bibliothek ausdenken und programmieren? Einfach aus Spaß an der Freude. Der Autor beschäftigt sich schon lange mit der Thematik. Die Themen Quadratwurzelberechnung und Sinus- und Cosinusberechnung werden auf anderen Seiten des Autors behandelt. Was fehlt zu einer vollständigen Mathe-Bibliothek sind die Funktionen zur Normalisierung der Fließkommazahlen sowie die Funktionen für die Logarithmusberechnung.
Für das Fließkommazahlen-Format gibt es mit dem Standard IEEE754 ein sehr ausgereiftes Format. Für die Logarithmusberechnung können Reihenentwicklungen nach Taylor oder Chebychev benutzt werden. Schneller für CPUs der Z80 Klasse dürfte aber die Logarithmusberechnung nach der Potenzreihe sein.

IEEE754 für 8 Bit CPUs

Eine 32 Bit Fließkommazahl nach IEEE754 besteht aus 1 Bit Vorzeichen, 8 Bit Exponent und 24 Bit Mantisse. Die grundlegenden Operationen wie Addition und Multiplikation erfolgen somit mit 24 Bit Zahlen im Bereich 1,0 bis 1,9999999. Werden zwei 24 Bit Zahlen addiert, entsteht maximal eine 25 Bit Zahl. Werden zwei solche Zahlen multipliziert entsteht maximal ein 48 Bit Ergebnis. Bei 8 Bit Speicherzellen und 8 Bit CPU Registern sind für das Multiplikationsergebnis 6 Register oder Speicherzellen nötig. Die Multiplikation- und Division-Algorithmen benötigen für die Eingangs- und Ausgangswerte einen 48 Bit Speicher und einen 24 Bit Speicher, ein Überlauf-Bit (Carry) sowie einen Schleifenzähler. Insgesamt werden 10 Register oder Speicherzellen benötigt.  Die 8085 CPU hat die wenigsten Register. Es gibt einen Akkumulator und 6 Register. Die Z80 CPU hat die gleichen 7 Register wie die 8085, kann aber zwischen zwei Registerbänken hin- und her-schalten. Dadurch verdoppelt sich die Anzahl der Register auf 14 Register. Zusätzlich gibt es noch zwei Indexregister. Die 8086 hat 16 Bit Register anstelle von 8 Bit Register. Es stehen 6 Register zur Verfügung. Die 6502 CPU hat nur drei 8-Bit Register. Zum Ausgleich gibt es die Zero-Page Adressierung, auf die ersten 256 Byte des Arbeitsspeicher kann besonders schnell zugegriffen werden.
Wie man sieht ist die Registerzahl bei jeder CPU knapp. Das Kopieren der Daten zwischen Register und Arbeitsspeicher kostet Zeit, deshalb versucht man alle nötigen Werte in den Registern zu halten oder wenigstens die Anzahl der Kopieroperationen klein zu halten.

CPU
8 Bit Register
16 Bit Register
6502 A, X, Y
8085
A
BC, DE, HL
Z80
A, A'
BC, DE, HL, BC', DE', HL', IX, IY
8088

AX, BX, CX, DX, SI, DI

Der Z80 hat die meisten Register, der 8088 hat die meisten gleichzeitig ansprechbaren Register. Dank Zero Page Adressierung ist die 6502 der 8085 überlegen.

Der IEEE754 belegt im Single Format nur 23 Bit für die Mantisse. Bei den Rechnungen ist die Mantisse aber 24 Bit lang. Weil bei einer normalisierten Zahl im Bereich 1,0 bis 1,9999999 die erste Stelle immer 1 ist, muss dieser konstante Werte nicht in der IEEE754 Fließkommazahl abgelegt werden.

msb means most significant bit
lsb means least significant bit
 1    8              23             ... widths
+-+-------+-----------------------+
|s|   e   |           f           |
+-+-------+-----------------------+
   msb lsb msb                 lsb  ... order

Die Felder Vorzeichen, Exponent und Mantisse sind so angeordnet, dass ein Vergleich für 32 Bit Ganzzahlen (Integer) auch Fließkommazahlen vergleichen kann. Für die little endian CPUs wie 8085, Z80 und 8088 liegen an niedriger Adresse die niederwertigen Bits einer Zahl und an der höheren Adressen die höherwertigen Bits einer Zahl. Eine IEEE754 Zahl im Speicher einer little endian CPU hat folgende Belegung:

      7 6 5 4 3 2 1 0
     +---------------+
n    |       f       |
     +---------------+
n+1  |       f       |
     +-+-------------+
n+2  |e|     f       |
     +-+-------------+
n+3  |s|     e       |
     +-+-------------+

Um den 8 Bit Exponenten von einem 8 Bit Register in die IEEE754 Anordnung zu bringen kann mit Schiebe- und Rotieren-Opcodes gearbeitet werden. Das Register welches die obersten 8 Bit der Mantisse enthält wird um eine Stelle nach links geschoben. Dann wird das Registerpaar aus Exponent und obersten Mantissen Byte um eine Stelle nach rechts geschoben. In Z80 Assembler schreibt man:

Natürlichen Logarithmus berechnen

Die Mathematik-Bibliothek berechnet eine Näherung für den natürlichen Logarithmus y = ln(x). Es wird eine Potenzreihenentwicklung benutzt welche auf der Potenzreihenentwicklung der Areatangens Hyperbolicus Funktion beruht. Für Werte von x zwischen 0 und der Eulerschen Zahl e genügen 9 Summanden. Für x kleiner oder gleich 0 ist der Logarithmus nicht definiert. Der IEEE754 Standard definiert die Nonnumber, Nichtzahl, als Ergebnis einer nicht erlaubten Rechenoperation. Der Logarithmus von 0 liefert bei IEEE754 die Nichtzahl NaN (Not a Number).

#define N 9

float a[N] = {
    2.0,
    2.0 / 3.0,
    2.0 / 5.0,
    2.0 / 7.0,
    2.0 / 9.0,
    2.0 / 11.0,
    2.0 / 13.0,
    2.0 / 15.0,
    2.0 / 17.0,
};

/* ln(x) fuer 0 < x < e, NaN sonst */
float ln(float x) {
    if (x <= 0.0) return NaN.f;    ;    // Not a Number
    float b = (x - 1.0) / (x + 1.0);
    float bb = b * b;
    float y = 0.0;
    int k;
    for (k = 0; k < N; ++k) {
        y += a[k] * b;
        b *= bb;
    }
    return y;
}

Ist der Wert von x größer als e wird das Argument reduziert. Aus dem Argument x wird die Quadratwurzel gezogen. Diese Operation wird solange wiederholt bis das Argument kleiner als e wird. Dann wird der Logarithmus berechnet. Das Ergebnis wird mit n multipliziert. Dabei entspricht n dem Wurzelgrad. Mathematisch entspricht die Argument-Reduktion der Rechenregel



Der natürliche Logarithmus für beliebige Argumente wird mit dieser C Funktion berechnet:

/* ln(x) fuer x > 0, NaN sonst */
float ln(float x) {
    if (x <= 0.0) return NaN.f;    // Not a Number
    int m = 1;
    while (x > 2.7182818) {
        x = sqrt(x);
        m += m;        // m wird verdoppelt
    }
    float b = (x - 1.0) / (x + 1.0);
    float bb = b * b;
    float y = 0.0;
    int k;
    for (k = 0; k < N; ++k) {
        y += a[k] * b;
        b *= bb;
    }
    return m*y;l
}


Umgekehrte Polnische Notation

Die Programmiersprachen FORTRAN, BASIC, Pascal, C und Java sind Geschwister, sie alle benutzen die Infix Notation. Die Sprache Lisp benutzt die Prefix Notation und Forth benutzt die Postfix Notation.

Infix
1 + 2 * 3
Prefix
(+ 1 (*  2 3) )
Postfix
1 2 3 * +

Die Reihenfolge der Zahlen bei den drei Notationen ist immer 1, 2, 3. Die Notationen unterschieden sich in der Platzierung der Operatoren + und *.
Die Infix Notation lernen wir in der Schule. Für einen Compilerbauer und auch für manchen Grundschüler ist Infix gar nicht so einfach. Die Regel "Punktrechnung geht vor Strichrechnung" ist nur eine Schwierigkeit von Infix. Eine Funktion mit einem Operator, wie die Quadratwurzelfunktion, wird geschrieben als Wurzelzeichen, Zahl. Zur Berechnung am Taschenrechner wird eingeben Zahl, dann Quadratwurzel-Taste.
Die Postfix Notation wird auch Umgekehrte Polnische Notation (UPN) genannt. Viele Hewlett Packard Taschenrechner hatten dieser Notation eine gewisse Bekanntheit gegeben. Die Eingabe bei einem UPN Taschenrechner wie dem HP 12C erfolgt immer nach dem Muster Zahl, Funktion. Die Eingabe für das Beispiel oben sind 1 ENTER 2 ENTER 3 * +. Für erste Versuche mit UPN genügt ein HP12C Emulator.




CP/M Emulatoren unter MS-Windows XP

Das 8080, 8085 und Z80 Betriebssystem CP/M bildet eine gute Entwicklungsumgebung für 8 Bit Laptop Programme, die CP/M Manuals sind leicht zu finden. Der direkte, kürzeste Weg zu einem komplexen Ziel ist oft der Umweg. Der Autor will ein Z80 Programm schreiben welches auf dem Tandy WP-2 läuft. Der erste Anlauf war leider nicht erfolgreich. Der Umweg ist nun ein Z80 Programm unter einem CP/M Simulator zu schreiben, und in der Zwischenzeit nach Infos über download und ausführen von Z80 Maschinensprachprogramme auf der WP-2 zu suchen.
Ein guter CP/M Emulator soll unter MS-Windows XP laufen, soll eine einfache Methode zum Dateiaustausch zwischen CP/M und MS-Windows anbieten und soll ein Terminal emulieren.

YAZE-AG

Von Frank D. Cringle und Andreas Gerlich stammt "Yet Another Z80 Emulator-AG". Hier vorgestellt wird die Version yaze-ag-2.30-pre01-winbinaries.exe für MS-Windows. YAZE ist ein Z80 Simulator welcher das Betriebssystem CP/M ausführt. Der Datenaustausch zwischen CP/M und Host-Betriebssystem erfolgt durch W.COM und R.COM. Mit dem CP/M Kommando W wird eine CP/M Datei auf die MS-Windows Festplatte geschrieben, mit R wird eine Datei gelesen. Mit E wird der Simulator verlassen.
Der Simulator hat eine augenfreundliche Anzeige mit schwarzem Text auf weißem Grund. Lobenswert ist auch der eingebaute ANSI (VT100) Terminalemulator. Das CP/M Programm Volks4TH benutzt ANSI Escape Sequenzen welche YAZE-AG problemlos verarbeitet.




Altair 8800

Der Altair 8800 Simulator ist ebenfalls ein Z80 Simulator auf welchem das Betriebssystem CP/M läuft. Die Seite bietet eine Menge alte Software, wie einen FORTRAN Compiler, LISP und den VEDIT Editor. Der Simulator liefert eine klassische Anzeige mit weißer Schrift auf schwarzen Grund. Der Datenaustausch erfolgt wie bei YAZE-AG mit den CP/M Programmen W.COM und R.COM. Leider enthält dieser Simulator keinen Terminalemulator. Der Bildschirm zeigt einen Aufruf von VEDIT. Die Bildschirmausgaben sind in der Menge der ANSI Escape Sequenzen kaum zu sehen.




WriteRoom Editor für CP/M

Das Editor Programm WriteRoom von Jesse Grosjean für Apple Computer ist ein Full screen Editor wie vi für UNIX oder VEDIT für CP/M. WriteRoom besteht aus einem schwarzen Bildschirm mit grünen Buchstaben. Ein echtes Stück Retro-Software für die heutige Klicki-Bunti Welt. Ein visual Editor für CP/M wird aus Mangel an Speicherplatz immer minimalistisch sein, WriteRoom gönnt sich den Luxus minimalistisch zu sein.
In der Programmentwicklung werden zuerst die Limitierungen aufgestellt. Die Limitierungen begrenzen die "Ideenfläche". Die erste und wichtigste Limitierung war schon der Wunsch "einen Editor wie WriteRoom" zu erzeugen. WriteRoom kann Texte nicht formatieren und WriteRoom kann Text nicht fett, kursiv oder in verschiedenen Schriftgrößen darstellen. Weitere Limitierungen für den CP/M Editor sind maximal 128 Zeichen pro Zeile, die maximale Textgröße wird durch den Arbeitsspeicher bestimmt. Noch mehr ins Detail geht die Limitierung, daß der Editor nur eingeschränkt 8 Bit Zeichensätze verarbeiten kann. Von den 32 ASCII Steuerzeichen dürfen im Text nur die Steuerzeichen Tabulator und Linefeed benutzt werden. Der Editor kann nicht Binärdateien bearbeiten.
Der gleiche C Quelltext soll funktionsfähig sein unter CP/M mit dem Hitech-C Compiler, unter MS-DOS mit dem Turbo C Compiler, unter Windows XP mit Visual C++ 2010 Express und unter Linux mit dem gcc Compiler. Der MS-DOS Emulator DOSBox versteht die ANSI Escape Sequenzen, unter einem echten MS-DOS muss ansi.sys installiert werden Unter Windows XP ist die Installation von ANSICON nötig für ANSI Escape Sequenzen.
Nach den Limitierungen ist nun Zeit die geplanten Editor Fähigkeiten vorzustellen. Soweit wie unter CP/M möglich sollen typische Editieraufgaben mit den Cursor-Tasten und den Spezial-Tasten ausgeführt werden.

Taste
Funktion
Cursor rechts
Schreibmarke im Text eine Spalte nach rechts bewegen.
Cursor links
Schreibmarke im Text eine Spalte nach links bewegen.
Tabulator
Schreibmarke im Text auf die nächste ohne Rest durch 8 teilbare Spalte bewegen.
Shift Tabulator
Schreibmarke im Text auf die vorherige ohne Rest durch 8 teilbare Spalte bewegen.
Pos1
Schreibmarke im Text zum Zeilenanfang bewegen.
Ende
Schreibmarke im Text zum Zeilenende bewegen.
Linefeed
Die aktuelle Zeile an der Schreibmarke in zwei Zeilen aufteilen und die Schreibmarke an den Anfang der zweiten Zeile bewegen.
Backspace
Das Zeichen links von der Schreibmarke löschen. Wenn die Schreibmarke am Zeilenanfang steht die aktuelle Zeile mit der vorherigen Zeile verbinden.
Entf
Das Zeichen unter der Schreibmarke löschen. Wenn die Schreibmarke am Zeilenende steht die aktuelle Zeile mit der folgenden Zeile verbinden.
Cursor ab
Schreibmarke im Text eine Zeile nach unten bewegen.
Cursor auf Schreibmarke im Text eine Zeile nach oben bewegen.
Bild ab
Schreibmarke im Text um 12 Zeilen nach unten bewegen.
Bild auf
Schreibmarke im Text um 12 Zeilen nach oben bewegen.
Einfg
Vom Editor-Überschreib-Modus in den Editor-Einfügen-Modus wechseln und zurück.
Esc
Vom Editiermodus in den Kommandomodus wechseln.

Die beschriebenen Funktionen dürften für die meisten Benutzer selbsterklärend sein. Im Kommandomodus werden Fähigkeiten wie Datei Speichern, Suchen usw. untergebracht. Der Editor soll die vorhandene Tastatur gut ausnutzen. Wenn Spezialtasten wie "Bild ab" fehlen, aber Funktionstasten wie F1, F2 vorhanden sind, dann sollen die Spezialtasten auf Funktionstasten abgebildet werden. Auf freie Funktionstasten werden Kommando-Funktionen gelegt. Wenn weder Cursor-Tasten noch Spezial-Tasten noch Funktions-Tasten zur Verfügung stehen, dann werden die Editieraufgaben mit der Tastenkombination Strg-Taste und Buchstabentaste aufgerufen.


Tastatur testen

Die ersten Anforderungen an den CP/M visual Editor V.COM sind geschrieben. Nun beginnt der erste Spiraldurchlauf der Realisierung nach dem Spiralmodell. Programmiert kann eine Funktionserweiterung immer dann, wenn der Akzeptanztest genau beschrieben werden kann. Die Version 0.01 des Programms V.COM ruft die Tastatur-Einlese-Funktion getch() auf. Lässt sich der eingelesene Wert als druckbares ASCII Zeichen darstellen wird der Wert unverändert ausgeben, sonst wird der Wert als hexadezimale Zahl ausgegeben. Das Programm funktioniert richtig, wenn es nach Betätigung der Taste a das Zeichen a auf den Bildschirm schreibt. Nach Betätigung von Strg-Taste und Taste a soll <01> auf dem Bildschirm erscheinen.
Nach Beschreibung der Funktionserweiterung und Beschreibung des Tests der Funktionserweiterung darf nun programmiert werden. Das Programm v01.c kompiliert ohne Errors unter Microsoft Visual C++ 2010 Express unter MS-Windows und unter HI-TECH C unter CP/M. Der ältere C Compiler erschien 1987, der neue C++ Compiler erschien 2010. Über 23 Jahre eine Programmiersprache auf unterschiedlichen Betriebssystemen kompatibel zu halten ist schon eine Leistung. Unter YAZE wird der C Quelltext mit R.COM von der MS-Windows Festplatte eingelesen. Mit C.COM auf der CP/M Floppy H: wird kompiliert. Der Programmstart erfolgt durch Eingabe von CPM-IO.
Der Akzeptanztest wird ohne Probleme bestanden. Leider ist die Suche nach brauchbaren Cursortasten unter YAZE recht erfolglos. Die Tastenkombination Strg-Taste und Buchstabentaste funktioniert, die Cursortasten, Spezialtasten und Funktionstasten liefern aber keine unterscheidbaren Werte.




Terminalemulation testen

Nach dem Test der Eingabe ist der Test der Ausgabe sinnvoll. Für den zweiten Spiraldurchlauf sollen die grundlegenden Cursorfunktionen getestet werden. Die Anforderungen, beschrieben als Testfälle sind: Nach Eingabe von Strg-W soll die Schreibmarke sich auf dem Bildschirm um eine Zeile nach oben bewegen, nach Eingabe von Strg-S eine Zeile nach unten, nach Strg-A eine Spalte nach links und nach Strg-D eine Spalte nach rechts.
Akzeptanztest definiert, nun wird programmiert. Leider fehlt noch die Information über die ANSI Escape Sequenzen für die Cursorbewegung. Die ANSI Escape Sequenzen sind definiert im ECMA-48 Standard oder wortgleich im ISO/IEC 6429 Standard.

Funktion
ANSI Escape Sequenz
Cursor rechts, CUF cursor forward
ESC [ C
Cursor links, CUB cursor back
ESC [ D
Cursor ab, CUD cursor down
ESC [ B
Cursor auf, CUU cursor up
ESC [ A

Der Akzeptanztest des Programms v02.c erfolgt ohne Probleme. Die Tastatur verfügt über eine Tastaturwiederholung. Dies ist sehr angenehm bei der Cursorsteuerung. Im Bild unten ist die Funktion der Schreibmarke unter YAZE zu sehen: Die Schreibmarke invertiert ein Zeichen. Die Schreibposition ist die linke senkrechte Seite des Cursor-Rechtecks.




Speicherverwaltung testen

Die schrittweise Realisierung eines Programms geht von außen nach innen. Die Benutzeroberfläche, unsere Tastatur und unser Bildschirm, gehören zu dem "Außen" eines Programms. Zum "Innen" eines Programms gehört die Speicherverwaltung. Unter C ist dies die Funktion malloc(). Der CP/M visual Editor soll vom Betriebssystem möglichst viel Arbeitsspeicher anfordern.
Für den Akzeptanztest soll die durch malloc() erfolgreich reservierte Speichergröße angezeigt werden. Für ein CP/M 3.0 System wird 58 KByte erwartet, für ein CP/M 2.2 System 52 KByte.
Im Programm v03.c wird zuerst versucht 63 KByte Arbeitsspeicher anzufordern. Falls dies nicht gelingt werden 62 KByte angefordert, usw. Die untere Grenze ist 2 KByte, falls diese Speicheranforderung nicht gelingt, endet das Programm.
Mit 55296 Bytes wird der Akzeptanztest für CP/M 3.0 nicht erfüllt. Wahrscheinlich liegt der Fehler in der Anforderung, nicht im Programm.




Datei laden testen

Der Editor lädt eine bestehende Textdatei zum ändern, oder mit Hilfe des Editors wird eine neue Datei erzeugt. Der Name der Datei wird als Kommandoparameter übergeben. Der Editor versucht die Datei in den Arbeitsspeicher zu laden.
Für den Akzeptanztest soll die Dateilänge im Arbeitsspeicher ausgegeben werden. Diese Dateilänge soll der Dateilänge auf dem Datenträger entsprechen. Dabei ist zu berücksichtigen, daß eine CP/M Datei als Zeilenumbruch Carrige Return und Linefeed enthält, im Arbeitsspeicher aber nur Linefeed alleine als Zeilenumbruch benutzt wird.
Die Implementierung in v04.c war teilweise einfacher als gedacht. Die Umwandlung von CR, LF auf LF führt die C STDIO aus. Es gab einen Fehler an unerwarteter Stelle. Unter CP/M und dem HiTech-C Compiler muss zuerst die Datei geöffnet werden und dann erst der Arbeitsspeicher belegt werden, sonst ist fopen() erfolglos. Wahrscheinlich hat sonst die fopen() Funktion nicht genug Heapspeicher.



Datei anzeigen testen

Nach Datei laden ist Datei anzeigen das nächste Ziel. Mit v05.c macht der Visual Editor einen großen Schritt nach vorne. Zum ersten Mal sieht der Bildschirm wie bei einem Editor aus, oder wenigsten wie bei einem Dateibetrachter.




Zwischenziel Dateibetrachter

Auch wenn es am Anfang des Projektes nicht geplant war, es wurde ein Zwischenziel erreicht. Der Visual Editor ist noch nicht fertig, aber ein Dateibetrachter. Mit den Cursortasten Strg-X, Strg-W, Strg-D und Strg-A kann durch die Datei geblättert werden. Das Programm endet nach Strg-C. Die Version v06.c funktioniert unter dem CP/M Simulator YAZE, MS-Windows und unter Linux. Wer nicht selbst kompilieren möchte findet in der Zip-Datei v06.zip alle Programmdateien. Hier gezeigt wird die MS-Windows Version unter ANSICON:



Exkurs Editoren

Ein früher Editor war TECO von Dan Murphy. TECO wurde 1962 entwickelt, zu einer Zeit als Fernschreiber anstelle von Bildschirmterminals benutzt wurden. Die TECO Befehle bestehen aus einzelnen Buchstaben. Die TECO Programmiersprache ist Turing vollständig. Unter UNIX gibt es die Zeileneditoren ed von Ken Thompson und ex von Bill Joy. Ken Thompson führte Reguläre Ausdrücke bei den Editoren qed und ed ein. Im US-Patent 3568156, eingereicht 1967, wird die Thompson Methode zur Erzeugung von Maschinensprache "on-the-fly" für die Erkennung von regulären Ausdrücken beschrieben. Der UNIX Editor vi (visual) von Bill Joy ist der Bildschirmterminal-Modus des UNIX Editor ex. Der vi Editor arbeitet modal, es gibt den Einfüge-Modus und den Befehls-Modus welcher ex Kommandos ausführt. Der Emacs Editor von Richard Stallman ist ein nichtmodaler Editor und somit der Vorläufer aller heute üblichen Editoren wie Nedit oder Notepad++.


Die Programmiersprache Forth

Charles Moore entwickelte Forth zwischen den Jahren 1968 und 1971. In dem Artikel Forth - The Early Years beschreibt er sein Aha-Erlebnis 1971 so: "Now Forth was complete. And I knew it. I could write code more quickly that was more efficient and reliable. Moreover, it was portable." In dem Artikel FORTH - A Language for Interactive Computing beschreibt Moore die Forth Entwicklung auf der IBM 1130, einem 16 Bit Computer mit 8 KByte Arbeitsspeicher. Im Netz gibt es einen IBM 1130 Simulator. Wegen dem kleinen Arbeitsspeicher war das Kompilieren von FORTRAN Programmen auf der Zielmaschine schwierig. Oft wurden größere Computer (Mainframes) und Crosscompiler benutzt um ausführbare Programme für die IBM 1130 zu erzeugen. Das Ziel von Charles Moore war, für sich auf der IBM 1130 eine komfortable Entwicklungsumgebung zu schaffen. Schon das erste Forth war eine integrierte Entwicklungsumgebung. Ein klassisches Forth System enthält das Betriebssystem, den Quelltext Editor und den Forth-Compiler in einem Paket. Neben der IBM 1130 arbeitete Moore 1969 mit einer Burroughs B-5500. Die Burroughs hatte eine Wortbreite von 48 Bit. Sechs Opcodes mit 8 Bit wurden im einem Wort gespeichert. Solch kleine Opcodes genügten weil die Burroughs eine Stack Maschine war. Laut Moore stammen die Forth-Funktionen DUP, DROP und SWAP direkt von der B-5500. Das Betriebssystem von Burroughs hat den Namen Master Control Program (MCP). Die Nachfolger der B-5500 inklusive MCP werden heute noch von Unisys hergestellt. Auf der Clear Path Libra 450 wird die Stack Maschine und MCP auf Intel Xeon CPUs emuliert. Wer möchte kann zwischen MCP und Forth sowie Multics und UNIX Parallelen ziehen. In beiden Fällen hat sich die kleine Lösung Forth oder UNIX durchgesetzt. Die große Lösung Multics ist gar nicht mehr am Markt und der Marktanteil von Clearpath/MCP dürfte auch sehr klein sein.
Zwischen 1974 und 1976 erschienen die 8 Bit Mikroprozessoren 8080, 6502 und Z80. Zu dieser Zeit war der Arbeitsspeicher knapp, weil teuer. Der Commodore VC-20 von 1981 hatte ab Werk nur 5 KByte RAM. Die Blütezeit von Forth liegt zwischen den Standards FORTH-79 und FORTH-83, zwischen den Jahren 1979 und 1983. Die August 1980 Ausgabe von Byte enthielt nur Artikel über Forth, zu diesem Zeitpunkt erreichte Forth seine größte Bekanntheit. Die Ideen hinter Forth sind heute noch in voller Blüte. Die Druckersprache Postscript benutzt wie Forth die Postfix Notation. Die Computer von SUN benutzen OpenBoot um den Boot-Vorgang des Computers zu steuern, ebenfalls eine Postfix Computersprache. OpenBoot und Open Firmware wurden in IEEE 1275-1994 standardisiert. Die Java Virtuelle Maschine (JVM) ist ebenfalls eine Stack Maschine. Der Java Bytecode besteht aus 8 Bit langen Opcodes, wie bei der Burroughs.
Wenn die komplette Entwicklungsumgebung und das zu entwickelnde Programm in wenigen Kilobytes Speicher untergebracht werden sollen, muss die Programmiersprache sparsam mit Speicher umgehen. Forth benutzt Threaded Code anstelle von Jump Subroutine (JSR) und Return für den Aufruf von Forth-Funktionen. Die Z80 CPU benötigt für den Aufruf einer Forth-Funktion 2 Bytes, für ein JSR aber 3 Bytes. Speicherplatzbedarf und Ausführungsgeschwindigkeit sind Gegenpole, auch bei Forth. Der Aufruf einer Forth-Funktion erfolgt durch den inneren Forth Interpreter. Ein Forth-Funktions-Aufruf kostet mehr Zeit als ein Jump Subroutine.
Eine weitere Speicherplatz sparende Eigenschaft von Forth ist der Umgang mit dem Stack. Bei Pascal und C werden Parameter und Return-Adressen auf den gleichen Stack gelegt. Forth benutzt zwei Stacks, einen Parameter-Stack und einen Return-Stack. Weiterhin hat der Forth-Programmierer volle Kontrolle über beide Stacks. Bei Pascal und C erfolgt die Stackverwaltung automatisch durch den Compiler. Der Compiler räumt die Parameter vom Stack wenn der Funktionsaufruf beendet ist. Der Forth Programmierer bestimmt selbst, wann die Parameter vom Stack geräumt werden. Frühes Abräumen der Parameter vom Stack durch die Verarbeitung der Parameter oder durch das Abspeichern der Parameter außerhalb des Stacks kann die Stackverwaltung vereinfachen und beschleunigen.
Forth benutzt die Postfix Notation für mathematische Berechnungen. In einem Compiler wird die Infix Notation zuerst in eine Postfix Notation umgesetzt welche dann in Maschinensprache umgesetzt wird. Die Benutzung von Postfix Notation für den Quelltext der Programmiersprache vereinfacht den Forth-Compiler (Forth Threaded Code Generator).

Die Programmiersprache Forth wurde als Forth-79, Forth-83 und ANSI X3.215-1994 (ANS-Forth) standardisiert. Der Forth-83 Standard verlangt folgende Forth-Funktionen (Forth-Worte):

Nucleus layer
!  *  */  */MOD  +  +!  -  /  /MOD  0<  0=  0>  1+  1-  2+ 2-  2/  <  =  >  >R  ?DUP  @  ABS  AND  C!  C@  CMOVE CMOVE>  COUNT  D+  D<  DEPTH  DNEGATE  DROP  DUP  EXECUTE EXIT  FILL  I  J  MAX  MIN  MOD  NEGATE  NOT  OR  OVER  PICK R>  R@  ROLL  ROT  SWAP  U<  UM*  UM/MOD  XOR
Device layer
BLOCK  BUFFER  CR  EMIT  EXPECT  FLUSH  KEY  SAVE-BUFFERS SPACE  SPACES  TYPE  UPDATE
Interpreter layer
#  #>  #S  #TIB  '  (  -TRAILING  .  .(  <#  >BODY  >IN ABORT  BASE  BLK  CONVERT  DECIMAL  DEFINITIONS  FIND FORGET  FORTH  FORTH-83  HERE  HOLD  LOAD  PAD  QUIT  SIGN SPAN  TIB  U.  WORD
Compiler layer
+LOOP  ,  ."  :  ;  ABORT"  ALLOT  BEGIN  COMPILE  CONSTANT CREATE  DO  DOES>  ELSE  IF  IMMEDIATE  LEAVE  LITERAL  LOOP REPEAT  STATE  THEN  UNTIL  VARIABLE  VOCABULARY  WHILE  [ [']  [COMPILE]  ]

Das Forth System kann als UPN Taschenrechner benutzt werden. Die Eingabe 1 2 3 * + . liefert die Ausgabe 7. Eine kleine Forth-Funktion soll aus dem Kreis-Radius den Kreis-Umfang berechnen. Der Quelltext der Funktion ist:

    : UKreis 710 113 */ ;

Das Zeichen : beginnt die Forth-Funktion mit dem Namen UKreis. Der übergebene Wert wird mit 710 multipliziert und dann durch 113 dividiert. Der Bruch 355 / 113 ist eine gute Näherung für π. Da bei der Umfangs-Berechnung der Radius mit 2*π multipliziert wird ist der Skalierfaktor 710 / 113. Die Kreisfläche wird in Forth berechnet mit der Funktion:

    : FKreis DUP * 355 113 */ ;

Das Forth-Wort DUP dupliziert den Parameter, das Forth-Wort * multipliziert deshalb den Parameter mit sich selbst. Die Multiplikation mit π erfolgt durch die Skalierung mit dem Bruch 355 / 113. Die gerade definierten Forth-Funktionen können im Forth Taschenrechner Modus getestet und benutzt werden. Forth unterstützt nur die Bottom-Up Entwicklung. Zuerst werden grundlegende Forth-Funktionen wie UKreis oder FKreis geschrieben, dann höhere Funktionen wie die Ausgabe einer Kreis-Radius- und Kreis-Fläche-Tabelle.

    : TabKreis 10 1 DO I . I UKreis . I FKreis . CR LOOP ;

Die Zählschleife wird in Forth mit DO LOOP realisiert. Das Forth-Wort I legt den Index auf den Stack, das Forth-Wort . gibt die Zahl aus und CR gibt einen Zeilenvorschub aus. Die Forth DO LOOP Schleife würde in C so aussehen:

    int I; for (I = 1; I < 10; ++I)

Werden die drei Forth-Funktionen im Forth Taschenrechner Modus eingegeben und die Forth-Funktion TabKreis mit Eingabe von TabKreis aufgerufen zeigt sich unter volksFORTH die Anzeige:



Forth Implementierungen

Von der Programmiersprache Forth gibt es viele Implementierungen. Einmal weil Forth auch auf der aller-kleinsten 8-Bit CPU wie der Intel 8051 läuft, dann auch weil ein Forth System ein kleines System ist und deshalb viele Informatiker ihr eigenes Forth bauen wollten. Der Autor hat ja auch dieses Ziel. Unter den vielen Forth Implementierungen gibt es einige bekannte und bewährte Ausgaben die hier vorgestellt werden sollen:

Name
Jahr
Autor

figForth79
1979
Forth Interest Group
16 Bit Forth-79 für 8080 CP/M
figForth79

Charlie Krajewski
16 Bit Forth-79 für 8086 MS-DOS
volksForth
ab 1985
Forth Gesellschaft e.V 16 Bit Forth-83 für 8086 MS-DOS, Z80 CP/M, 6502, 65816, 68000
eForth ab 1990 Bill Muench, Dr. C. H. Ting
Forth für 8086 MS-DOS, Z80, 8051, 68HC12, 68HC16, 68000, PIC 17C42, 56002
hForth 1997 Dr. Wonyong Koh, Neal Crook 16 und 32 Bit Forth für Z80, 8086 und StrongARM
gforth ab 1996 Anton Ertl, Bernd Paysan
32 Bit ANS-Forth für 80386 MS-Windows, x86_64, Digital Alpha, PowerPC, SUN SPARC
CamelForth
ab 1994
Bradford Rodriguez 16 Bit ANS-Forth für 8086, Z80, 6809, 1802, 8051, 8052, MSP430
CamelForth

Douglas Beattie Jr. 16 und 32 Bit ANS-Forth für Z80, eZ80, Z380, ZNEO
CamelForth
2005
John Hogerhuis
16 Bit ANS-Forth für Z80 Tandy WP-2
colorForth
ab 2001
Charles Moore
Forth mit Syntax Highlighting für 80386 MS-Windows
Pygmy ab 2005 Frank C. Sergeant Forth für 8086 MS-DOS, ARM


Von Charles Moore, dem Forth Erfinder, stammt colorForth. Die Funktion der Forth-Worte in colorForth wird über die Farbe bestimmt. Für die Eingabe werden nur 27 Tasten auf der Tastatur benutzt. Die Tastenbelegung wechselt dabei zwischen verschiedenen Modi.



Aufbau einer Forth Funktion

Jede Forth-Funktion hat einen Namen, wie - oder LIT. Dieser Name steht im Arbeitsspeicher vor der Implementierung der Forth-Funktion. Alle Forth-Funktionen zusammen ergeben das Forth-Lexikon. In diesem Forth-Lexikon sucht der Forth-Compiler nach den schon definierten Forth-Funktionen. Wird im Forth Taschenrechner Modus TabKreis eingegeben, wird das Forth-Lexikon nach dem Namen TabKreis durchsucht. Wird ein übereinstimmender Name gefunden, wird die entsprechende Forth-Funktion ausgeführt. Damit der Compiler das Forth-Lexikon durchsuchen kann, ist das Lexikon als Liste organisiert. Jede Forth-Funktion enthält einen Zeiger auf den Namen der nächsten Forth-Funktion.
Die grundlegenden Forth Funktionen wie + bestehen aus Maschinensprache. Höhere Forth Funktionen wie : bestehen aus Threaded Code, einer Folge von Forth-Funktions-Aufrufen. Eine Forth Funktion bei einem Direct Threaded Code Forth beginnt mit einem Maschinensprache-Befehl. Bei einer primitiven Forth Funktion folgenden weitere Maschinensprache-Befehle bis der Zweck der Funktion erfüllt ist. Bei einer Hochsprache-Forth-Funktion startet der Maschinensprache-Befehl den inneren Forth Interpreter. Der innere Forth Interpreter versteht die folgenden Daten als Zeiger auf Forth-Funktionen und führt diese Funktionen aus.
Eine Forth Funktion besteht aus dem Funktions-Kopf (Header) welcher den Namen der Forth-Funktion (Name) und die Lexikon-Verkettung zur nächsten Forth-Funktion (Link) enthält. Dann folgt der Funktions-Körper (Body). Dieser besteht aus einem Maschinensprache-Befehl (Code Field). Nach diesem ersten Befehl folgen weitere Maschinensprache-Befehle (MACHINE CODE) oder es folgt ein Array von Zeigern auf Forth-Funktionen (PARAMETER FIELD).

      +------+------+------------+-----------------+
      | Name | Link | Code Field |  Machine Code   |  = Primitive Forth Funktion
      +------+------+------------+-----------------+


      +------+------+------------+-----------------+

      | Name | Link | Code Field | Parameter Field |  = Hochsprache Forth Funktion
      +------+------+------------+-----------------+


Die einzelnen Forth Versionen unterscheiden sich stark im Name Feld. Einige Forth Versionen wie polyFORTH verwenden eine feste Namen-Feld Länge von z.B. 4 Bytes. Das erste Byte enthält die Länge des Namens, dann folgen in drei Bytes die ersten drei Zeichen des Namens. Der Name DATUM wird im Namen-Feld abgelegt als Länge 5 und Zeichenkette DAT. Andere Forth Versionen wie FORTH-79 erlauben maximal 31 Zeichen für das Namen-Feld. Meistens wird in dem letzten Zeichen des Namen das achte Bit auf 1 gesetzt um das Ende des Namen zu signalisieren. Etliche Forth Versionen benutzen beide Möglichkeiten. Es gibt ein Längen Feld und ein Namen Feld mit variabler Länge.

Forth Register

Die Programmiersprache Forth bevorzugt eine gewisse CPU Architektur. Von Charles Moore wurde 1985 die Novix NC4016 Forth CPU vorgestellt. Die J1 Forth CPU von James Bowman besteht aus 200 Zeilen Verilog und ist damit eine sehr kleine, aber immer noch nützliche 16 Bit CPU. Einen Program Counter (Instruction Pointer) benötigt die Forth CPU wie jede andere CPU. Die Forth CPU verfügt über zwei Stack Pointer. Einen für den Parameter (Data) Stack, einen anderen für den Return Stack. Die Rechenoperationen einer Forth CPU werden auf dem Parameter Stack ausgeführt. Ein CPU Register für den obersten Stack-Wert, dem TOS, ist aber praktisch. Wird Forth auf einer traditionellen CPU ausgeführt ist ein Working Register für verschiedene Zwischenrechnungen nötig. Das Bild der Canonical Stack Machine stammt aus dem Buch Stack Computers: the new wave von Philip J. Koopman, Jr.



Jede Forth Implementierung versucht die vorhandenen CPU Register möglichst geschickt auf die Forth Register abzubilden. Für die 6502 CPU Zuordnung gibt es wenig Möglichkeiten bei nur drei CPU Registern. Bei der 6502 wird wegen dem schnelleren Zugriff Zero Page Memory benutzt. Für die 8085 CPU stammt die Zuordnung von AAForth. Die 8086 CPU Zuordnung stammt zum größten Teil von eForth. Den Top of Stack in einem Register zu halten kommt als Optimierung von CamelForth. Die Z80 CPU Zuordnung kommt ebenfalls von CamelForth.

Forth Register
6502 8085
Z80
8086
IP Interpreter Pointer
Memory DE
DE SI
PSP Parameter Stack Pointer X SP
SP SP
RSP Return Stack Pointer SP Memory
IX BP
TOS Top of Stack
BC
BC BX
W Working register Memory HL
HL
AX

Forth in Z80 Assembler

Der Kern einer Forth Entwicklungsumgebung kann in Assembler-Sprache geschrieben werden. Der Kern enthält die Initialisierung des Computers, die Verwaltung von Tastatur, Bildschirm und Massenspeicher sowie die primitiven Forth-Funktionen. Nachdem der Doppelpunkt-Compiler : realisiert ist, kann die Weiterentwicklung in Forth stattfinden. Ein Maschinensprache-Assembler in Forth erleichtert die Realisierung von neuen primitiven Forth-Funktionen.
In den folgenden Abschnitten soll ein Forth für den Tandy WP-2 entwickelt werden. Der Tandy WP-2 ist ein dankbarer Kandidat: Dieser 8 Bit Laptop hat keine Programmiersprache ab Werk, die CPU ist eine Z80 und der RAM Speicher kann durch einen 128KByte SRAM IC billig auf Vollausbau gebracht werden. Die folgenden Abschnitte beschreiben die Entwicklung Schritt für Schritt. Wie bei dem Self compiling Compiler BASICO liegt es dem Autor am Herzen die Entwicklung zu zeigen, nicht nur das Endprodukt. Nach dem Spiralmodell soll jeder Spiraldurchlauf ein (Zwischen-)Ergebnis liefern, welches man anfassen (begreifen) und testen kann. Ziel jedes Spiraldurchlaufes ist ein System, welches schon einen Teil des Funktionsumfanges des ausgewachsenen Systems hat.
Für den Tandy WP-2 gibt es schon CamelForth. Für den TI-84 Taschenrechner scheint es noch kein Forth zu geben.

1. Der innere Interpreter

Die Frage "Was ist das Wichtigste und das Dringendste für den nächsten Spiraldurchlauf?" steht immer am Anfang. Für das Forth System ist der innere Interpreter das Allerwichtigste. Nach Ansicht des Autors ist der innere Interpreter sogar wichtiger als die Ein-/Ausgabe auf dem Zielrechner Tandy WP-2. Mit Hilfe eines Z80 Simulator lässt sich der innere Interpreter testen, ohne das die Ein-/Ausgabe auf dem WP-2 schon vorhanden ist. Als Z80 Simulator wird der Z80DT benutzt. Z80DT wird bei MS-Windows XP und höher am besten unter dem MS-DOS Emulator DOSBOX gestartet.
Die Anforderungen an einen Spiraldurchlauf sind erst dann komplett, wenn die Tests und die erwarteten Testergebnisse präzise formuliert sind. Erst die erfolgreich bestandenen Tests des Spiraldurchlaufes schließen den Spiraldurchlauf ab.
Der innere Interpreter soll folgende Hochsprache-Forth-Funktionen ausführen. Diese Funktionen werden von Hand compiliert:

    : T01 7000 2000 1000 ;  \ lege 3 Konstanten auf den Parameter-Stack
    : T02 - - ;             \ subtrahiere drei Zahlen
    : T03 T01 T02 ;         \ Berechne 7000-2000-1000 = 4000

Damit die drei Test-Funktionen ausgeführt werden können, sind die Forth-Funktionen ENTER, NEXT, EXIT, BYE, LIT und - zu implementieren. Alle sechs Forth-Funktionen sind Primitive. Damit das System bei Programmstart sinnvoll konfiguriert wird, ist eine Initialisierung-Routine INIT nötig. Am Ende von INIT wird die Forth-Funktion T03 aufgerufen. Nach T03 wird BYE aufgerufen. BYE stoppt den Simulator mit dem Z80 Opcode HALT. Auf den Parameter-Stack soll nur der Wert 4000 liegen, der Return-Stack soll leer sein.
Beim Test von AAForth1.Z80 (Z80 Version) oder AAForth1.85 (8085 Version) war der Stopp von Forth mit HALT ein Problem, das EXIT von T03 passte nicht zu dem Quelltext in INIT. Nachdem die Forth Primitive BYE geschrieben war stoppte der Simulator wie erwartet. In der Z80DT Simulator Anzeige sind die Testergebnisse abzulesen. Das Register BC enthält den Wert 1770H, dies entspricht dem Wert 6000 - da ist noch etwas falsch.



Der Fehler liegt nicht im Programm, sondern das erwartete Testergebnis enthält einen Denkfehler. VolksForth liefert ebenfalls das Ergebnis 6000. Forth berechnet das Ergebnis von rechts nach links (rechts assoziativ). Zuerst wird 2000 minus 1000 berechnet, dies ergibt 1000. Dann wird 7000 minus dem Zwischenergebnis 1000 berechnet, dies ergibt 6000. In Infix Notation ausgedrückt hat Forth 7000 - (2000 - 1000) berechnet und nicht (7000 - 2000) - 1000. Fehler gibt es überall. Beim nächsten Spiraldurchlauf werden die Test-Funktionen vorher mit VolksForth überprüft.



2. Download auf Zielhardware

Das Forth System soll auf dem Tandy WP-2 laufen. Um im dritten Spiraldurchlauf das Zusammenspiel zwischen Forth und Tastatur und Bildschirm testen zu können, ist zuerst die Möglichkeit zu schaffen ein Programm vom Entwicklungsrechner auf den Zielrechner zu übertragen. Der erste Spiraldurchlauf war sehr Software-lastig, der jetzige Spiraldurchlauf ist Hardware-lastig. Diesmal heißt es nicht Editor, Assembler und Simulator sondern Nullmodemkabel und korrekte Übertragungsparameter. Bei einer Hardware-lastigen Entwicklungsrunde ist ein Null-Test als Zwischenschritt sinnvoll. Das Wort Null-Test hat zwei Bedeutungen: Einmal ist dies der (uninteressante) Test Nummer 0, welcher vor den interessanten Tests 1, 2, 3 durchgeführt wird. Zweitens ist für den Null-Test keine Software zu programmieren. Der erste Test im zweiten Spiraldurchlauf ist eine Datenübertragung zwischen Entwicklung- und Zielrechner durchzuführen mit der vorhandenen Software. Welche Software vorhanden ist erklärt die Dokumentation des Zielrechners. Auf club100.org gibt es das WP-2 User Manual. Im Kapitel FILE TRANSFER wird die Datenübertragung von ASCII Dateien von der WP-2 auf einen PC beschrieben. Damit ist der erste Test definiert: Erfolgreich eine ASCII-Datei von der WP-2 auf den PC übertragen. Als Übertragungsparameter sollen in F2 SETUP, F2 T eingestellt werden Device=RS232C, Baud rate=9600, Word length (bits)=8, Parity=None, Stop Bits=1, XON/XOFF=Disable, Printer echo=OFF, Duplex=Full, Transfer=CRC-XMODEM, Incoming CR=CR, Outgoing CR=CR und Mode=Originate.
Der Download erfolgt vom Entwicklungsrechner mit HyperTerminal. Auf dem WP-2 wird mit F2 TELCOM das Kommunikationsprogramm aufgerufen. Es meldet "RS232C is ready". Mit F1 D wird der Download auf dem WP-2 gestartet. Das Speichermenü erscheint. RAMDISK auswählen und Filename wp2-io.co eingeben. Dann Datei senden vom Hyperterminal mit Protokoll Xmodem ausführen.

Im WP-2 Service Manual gibt es im Kapitel IV-17 ein Beispiel Run File Programm. Der Assembler Text wp2-io.z80 wird mit Z80DT übersetzt und liefert ein Hex file wp2-io.hex. Das Hex file ist eine ASCII Darstellung des Binärprogrammes. Vor der Programmausführung muss das Hex file noch in eine Binärdatei gewandelt werden mit hex2bin oder binex. Der Z80DT liefert leider kein Standard konformes Hex file. Deshalb habe ich meine eigene Version von hex2bin geschrieben. Der Quelltext von hex2bin ist in C geschrieben. Die Datei wp2-io.bin wird als Datei wp2-io.co auf dem WP-2 gespeichert. Leider funktioniert das Programm wp2-io nicht wie erwartet. Nach dem Programmstart funktioniert auf dem WP-2 nicht mehr F2 EXIT. Ein Reset ist nötig um den WP-2 wieder einzufangen.

Um schnelle Erfolge zu erreichen wird kurzerhand die Zielhardware ausgewechselt. Die neue Zielhardware ist der CP/M Emulator Altair8800 und MS-Windows.

3. Tastatureingabe, Bildschirmausgabe

Das Wichtigste und Dringendste für den dritten Spiraldurchlauf ist Eingabe und Ausgabe auf dem Zielrechner. Im WP-2 Service Manual werden im Anhang D die ROM CALLS aufgelistet. Die wichtigsten Aufrufpunkte sind:

CHARSENSE
100H
Check keyboard buffer
CHARGET
103H
Get one character
SETLOC
109H
Set cursor location
CHAROUT
118H
Output character to console
STROUT
11BH
Output string to console
CLS
11EH
Clear screen

Die CP/M 2.2 BDOS Aufrufpunkte sind:

CSTAT
11
Console status
CREAD
1
Console read
CREADSTR 10 Buffered console input
CWRITE
2
Console write
CWRITESTR
9
Output string

Das CP/M Testprogramm cpm-io.z80 benutzt CREAD und CWRITE um die eingegebenen Zeichen auf der Console auszugeben. Das CP/M Programm cpm-io.com wurde mit hex2bin als cpm-io.bin erzeugt und dann umbenannt.


Literatur

Zwei Perlen der Computerliteratur sind die Bücher von Leo Brodie über Forth. Auch wenn man Forth nicht einsetzen will oder kann, diese beiden Bücher erweitern den Horizont. Und die Cartoons in den Büchern bringen den Leser zum schmunzeln.

Band 1 ist die Übersetzung von Starting Forth.
Leo Brodie; Programmieren in Forth; Hanser, Prentice Hall International; 1984
Eine Online Version von Starting Forth ist verfügbar von Forth Inc.

Band 2 ist die Übersetzung von Thinking Forth. Thinking Forth beschreibt Software-Entwicklung-Methoden bis zur "Component Programming". Der "Object Oriented Programming" Ansatz ist in Thinking Forth noch nicht enthalten.
Leo Brodie; In Forth denken; Hanser, Prentice Hall International; 1986
Die LaTeX Version von Thinking Forth ist verfügbar auf Sourceforge, eine PDF Version von Thinking Forth gibt es auch.

In Berlin erschien folgendes Buch über Forth. Es werden FORTH-79 und FORTH-83 im Detail beschrieben.
Gert-Ulrich Vack; Programmieren mit Forth; VEB Verlag Technik; 1990

Das Microsoft Macro Assembler Package wurde für CP/M mit 8-Zoll Floppy geliefert.
Microsoft Corporation; Microsoft Macro Assembler Package for CP/M 80; Microsoft; 1981

Der Microsoft Macro Assembler war auch für MS-DOS lieferbar. In der Version von 1987 sind die Assemblerbefehle von 8086, 8088, 80286, 80386, 8087, 80287, 80387 enthalten.
Microsoft Corporation; Microsoft Macro Assembler 5.1; Microsoft; 1987