Nascom Journal

  

Oktober 1981 · Ausgabe 10

Ein weiterer Fehler betrifft die Funktion: „>“. Sie erwartet die Argumente genau in der umgekehrten Reihenfolge auf dem Stack als es in FORTH üblich ist, und schließt außerdem den Fall A = B nicht aus.

Hier ist die Korrektur einfach Zeile 6038 wird geändert in:

JR NC,TESTE

Die Funktion gibt nun „Wahr“ ( = FFFFH ) auf den Stack, wenn T-1 größer als T ist, sonst 0.

Die Funktion „ROT“ ist zwar richtig beschrieben und programmiert, aber leider genau umgekehrt definiert ( Abwärtsrotation statt Aufwärtsrotation ) als es sonst in FORTH üblich ist. Um eine Sprachverwirrung auszuschalten, werden wir auch hier eine Änderung vornehmen. Es ist die Reihenfolge der PUSH-Befehle zu verändern in:

6025  PUSH DE
6026  PUSH HL
6027  PUSH BC

Die folgenden Änderungen sollen keine Fehler korrigieren, sondern werden uns später beim Programmieren in FORTH sehr nützlich sein. Sie verbessern die Zusammenarbeit mit dem Betriebssystem und gestalten sie zugleich variabler. Wir nehmen diese Änderungen direkt in Maschinensprache vor. Zunächst verwandeln wir die Constante „MEMORY“ in eine Variable. Wir tragen ab 1171H statt 5C 11 ein: 75 11.

Bevor wir die nächste Veränderung vornehmen führen wir zunächst einen Kaltstart des FORTH-Systems aus und kehren dann sofort mit RESET oder dem Befehl „91 NAS-SYS“ ins Betriebssystem zurück. Nun fügen wir eine zusätzliche Routine und ihren Namen direkt in Maschinensprache ein mit Hilfe des MODIFY-Kommandos:

16AB AD 16 E1 22 0C 0C DF ,M
16B3 E5 C3 3E 10.
1E4A 06 ,M ,0 ,D ,I ,F ,Y AB
1E52 16.

Mit „MODIFY“ kann das M-Kommando des Betriebssystems aufgerufen werden. Der Startwert wird auf dem Stack übergeben, bei der Rückkehr wird die nächste freie Speicheradresse ebenfalls auf dem Stack übergeben. (In genau dieser Weise funktioniert das natürlich nur unter NAS-SYS. T2/​T4-Anwender müssen sich das etwas umschreiben.) Bevor wir nun das System wieder starten können, müssen wir noch die Werte der beiden Variablen „CODE“ und „NAMES“ verändern, damit die neue Funktion vom Interpreter erkannt und ausgeführt wird, Wir benutzen wieder das M Kommando und tragen die neuen Werte ein:

1293 B7.
128F 4A.

Wir staten nun den Interpreter mit E1000 und werden dann dieses Tiny-FORTH zunächst dazu benutzen, das System selbst auszubauen und Schritt für Schritt eine komfortable Programmiersprache zu entwickeln. Wir beginnen mit den bereits bekannten Funktionen Constant und Variable. Es sind definierende Funktionen, die einen Namen in das Dictionary eintragen und ihnen Routinen im Code zuweisen, die einen Wert (Constant) bzw eine Adresse (Variable) auf den Stack geben.

: VARIABLE  GETWORD     ENTER
            VARBL CMPLW CMPLW ;
: CONSTANT  GETWORD     ENTER
            CONS  CMPLW CMPLW ;
4755 CONSTANT CODEADR
4158 CONSTANT NEXTADR

Diese beiden Konstanten brauchen wir gleich!

Die folgende Funktion erklärt sich selbst:

: CR 13 COUT ;

Wir brauchen sie bereits bei der nächsten Funktion, ohne die man sich gar nicht erst an größere Programmierversuche herantrauen sollte:

: DEL NAMES PEEKW DUP PRINTS CR
      FIRST + DUP PEEKW CODEADR POKEW
      INC   INC   NAMES   POKEW       ;

DEL löscht die jeweils zuletzt compilierte Funktion sowie ihren Namen, der dabei angezeigt wird. CODE­ADR gibt dabei die Adresse der Variablen CODE, die den nächsten freien Speicherplatz für den FORTH-Code enthält. Mit diesem Trick machen wir uns eine Variable zugänglich, die zwar im Code, nicht aber im Dictionary enthalten ist.

Die folgende Funktion, MCODE, ist wiederum definierend. Sie erlaubt den Einbau von Routinen in Maschinensprache in den FORTH-Code:

: MCODE GETWORD ENTER CODEADR PEEKW
        DUP INC INC DUP ROT POKEW MODIFY
		DUP 195 SWAP POKEB  INC DUP
		NEXTADR SWAP POKEW INC INC
          CODEADR POKEW

Wir wollen MCODE nun gleich benutzen, um eine Standard-FORTH-Routine in Maschinencode zu schreiben:

MCODE  OVER
1743 E1 D1 D5 E5 D5.

OVER ist ein Befehl zur Stackmanipulation wie DUP und ROT. Die Funktion kopiert den 2.

Seite 3 von 28