APPLICATIONSPROGRAMMATION ★ Anwendung des Monats: der CPC-Forth-Compiler|CPC Magazin) ★

Forth Compiler (CPC Magazin)Applications Programmation
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Wer schon immer mal mit Forth arbeiten wollte, hat jetzt die Gelegenheit dazuCliquez sur l'image pour l'agrandir

Das Programm wird folgendermaßen erzeugt:

  1. Den MC-Generator abtippen und mit SAVE”FORTH.LDR” abspeichern.
  2. Das Programm mit RUN starten. Der Maschinencode wird dann unter "FORTH.MC” abgespeichert und der Compiler gestartet.
  3. Sobald das Bereitschaftszeichen (ein nach rechts zeigendes Dreieck) erscheint, muß man noch die Befehlsbibliothek abspeichern. Das geschieht mit SAVE"FORTH (ohne Anführungszeichen hinter dem Programmnamen I). Danach können Sie Ihren CPC zurücksetzen. Von Cassette kann man jetzt den Compiler jederzeit mit RUN” neu starten. Sobald das Bereitschaftszeichen erscheint, muß die Befehlsbibiiothek mit LOAD”FORTH wieder geladen werden (auch hier ohne 2. Anführungszeichen). Für Diskettenbetrieb wird bei jedem Start ohne den MC-Generator zusätzlich das Listing "Starter” benötigt, da sonst auf Cassette umgeschaltet wird.

Zahleneingaben

Zahlen können zwischen -32768 und 65535 eingegeben werden. Dabei entsprechen sich die Bereiche -32768 bis -1 und 32768 bis 65535. Bei negativen Zahlen muß das Minuszeichen hinter der Zahl eingegeben werden. Die Eingabe muß immer dezimal erfolgen. Die Programme arbeiten mit 3 Stacks.

  • Stack 1 ist der Routinenstack, für den Programmierer allerdings unzugänglich.
  • Stack 2 ist der X-Stack, der für Parameterübergaben verwendet wird
  • Stack 3 ist der Y-Stack, der genau wie der X-Stack arbeitet.

Die Stapelzeiger zeigen immer auf das Low-Byte des letzten Eintrages. Wird eine Zahl eingetragen, so wird der Stackzeiger um 2 decrementiert, andererseits um 2 incrementiert, wenn ein Parameter vom Stack geholt wird. Es sollte jedoch darauf geachtet werden, daß die Stacks nicht über- oder unterlaufen, da ein solcher Fehler nicht angezeigt wird. Auf allen 3 Stacks ist jedoch jeweils für 512 Einträge Platz, was normalerweise ausreicht.

Speicheraufteilung

  • 01F2 - 01F3 Zeiger auf letzten Befehl (für BYE & PRGM) 01F4 - 01F9 Systemvariable 01 FA - 01FB Programmzeiger 01FC-01FD Namen-Tabellenzeiger
    01FE - 01FF Tabellenzeigerfür Adressen
  • 0200 - 79FF Programm
  • 7A00 - 89FF Namen-Tabelle
  • 8A00 - 91FF Adressen-Tabelle
  • 9200 - 95FF X-Stack
  • 9600 - 99FF Y-Stack
  • 9A00 - 9DA1 Routinen-Stack
  • 9DA2 - A4DF Compiler
  • A4E0 - A5FF Eingabe-Puffer
  • A600 - ABFF Disk-RAM, Symboltabelle etc.

Die Befehle der Programmbibliothek "FORTH belegen den Speicherbereich &0200 bis einschließlich &0902.

Befehle im Direktmodus

  • LIST gibt alle bisher vorhandenen Befehle auf dem Bildschirm aus. Das Tempo kann durch Tastendruck reguliert werden.
  • #LIST druckt die Befehlsliste.
  • SAVE"Name speichert das Programm auf Cass./Disk.
  • LOAD”Name lädt ein solches Programm wieder zurück. Der Name für LOAD und SAVE muß angegeben werden und darf höchstens 8 Buchstaben lang sein.
  • USE ruft den USÈR-Modus auf (siehe dort).
  • CREATE”Name erzeugt einen neuen Befehl. Die Eingabe muß direkt hinter dem Namen enden.
  • DECREATE”Name löscht die Tabelleneinträge der
  • Routine mit dem angegebenen Namen. Die Routine selbst bleibt erhalten. Der Befehl ist dann nützlich, wenn die Tabellen überzulaufen drohen. Auch hier muß die Eingabe direkt hinter dem Namen abgeschlossen werden.
  • PRGM erzeugt ein fertiges Programm. Dazu muß nach Eingabe von PRGM die ENTER-Taste gedrückt werden. Dann kann man den Name eingeben. Das kann irgendein Dateiname mit dem Format fiiename.typ sein, wobei "filename” höchstens 8 und ”typ” höchstens 3 Zeichen lang sein darf. Ein so erzeugtes Programm kann später von Basic aus mit dem Befehl RUN”fiiename.typ geladen und gestartet werden. Der letzte Befehl des Hauptprogramms muß als letztes mit CREATE kreiert worden sein. Er darf nicht mit LOAD geladen worden sein (siehe Beispiel).

Befehle im CREATE-Modus

Routinenamen, die eingegeben werden, veranlassen den Compiler, einen Maschinensprache-CALL zu der Adresse der entsprechenden Routine in das Programm einzutragen. Außerdem versteht der Compiler folgende Kommandos:

  • PRON schaltet den Drucker ein. Darauffolgende Eingaben im CREATE-Modus werden auf dem Drucker protokolliert.
  • PROFF schaltet den Drucker wieder aus.
  • BYE vergißt alle Eingaben, die beim letzten Mal im CREATE-Modus gemacht wurden und springt zurück in den Direktmodus.
  • OK schließt die Routine ab, kontrolliert alle Schleifen und kehrt in den Direktmodus zurück.
  • REPEAT UNTIL erwartet ein Flag auf dem
  • UNTIL Stack. Ist dieses Flag =0, springt das Programm zu REPEAT zurück, ansonsten wird das Programm hinter UNTIL fortgesetzt.
  • WHILE WHILE erwartet ein Flag auf dem
  • WEND Stack. Ist dieses Flag =0, läuft das Programm hinter WEND, ansonsten hinter WHILE weiter. Erreicht das Programm den Befehl WEND, springt es zurück zu WHILE. Es darf also nicht vergessen werden, vor WEND ein Flag auf den Stack zu legen.
  • IF IF erwartet ein Flag auf dem Stack.
  • ELSE ENDIF Ist dieses Flag =0, läuft das Programm hinter ELSE, sonst hinter IF weiter. Trifft das Programm hinter IF auf . ELSE, springt es zu ENDIF. Der Befehl ELSE kann ausgelassen werden. In diesem Fall wird das Programm bei nichtgesetztem Flag hinter ENDIF fortgesetzt.

Wird OK, UNTIL, WEND, ELSE oder ENDIF eingegeben, kann es passieren, daß "Fehler Nr...." ausgegeben wird. Die Fehlernummern haben folgende Bedeutung:

  • Nr. 1. Ein IF-Befehl wurde noch nicht durch ENDIF abgeschlossen.
  • Nr. 2. Ein IF-ELSE-Befehl wurde noch nicht durch ENDIF abgeschlossen.
  • Nr. 3. Ein REPEAT-Befehl wurde noch nicht durch UNTIL abgeschlossen.
  • Nr. 5. Ein WHILE-Befehl wurde noch nicht durch WEND abgeschlossen.
  • Nr. 6. Es sind schon alle Verzweigungen und Schleifen abgeschlossen.

Die USR-Befehle
EinAusBeschreibung
*n1 n2n3n3=n1*n2
+n1 n2n3n3=n1+n2
-n1 n2n3n3=n1-n2
/n1 n2n3n3=n1/n2
<n1 n2ff=-1=n1 kleiner n2, sonst 0
<=n1 n2ff=-1 =n1 kleiner/gleich n2,
<>n1 n2ff=-1=n1 nicht gleich n2,
=n1 n2ff=-1=n1 gleich n2, sonst 0
>n1 n2ff=-1=n1 größer n2, sonst 0
>=n1 n2ff=-1=n1 größer/gleich n2,
?n n wird positiv ausgegeben.
?$n Das Low-Byte von n wird als Zeichen ausgegeben.
?$$n Eine Zeichenkette ab der Adresse n wird ausgegeben, bis der Wert 0 gefunden wurde.
?-n n wird mit Vorzeichen ausgegeben.
ABSn1n2n2= positiver Wert von n1.
ANDn1 n2n3n3=n1 and n2.
BASEn n legt die Basis des Zahlen-systems für INPUT,? und ?-fest.
BORDERn1 n2 em Bildschirmrand werden die Farben n1 und n2 zugewiesen.
CHANGEn1 n2n2 n1Die letzten beiden Stackeinträge werden vertauscht.
CLG Grafikfenster löschen
CLS Textfenster löschen.
CODE n Der Speicherbereich ab n
DECn1n2n2=n1-1
DEEKn1n2Der Zwei-Byte-Wert ab der
DOKEn1 n2 Der Zwei-Byte-Wertn2 wird ab Adresse n1 abgelegt.
DRAWn1 n2 Es wird eine Linie zur absoluten Position n1, n2 gezogen.
DRAWRn1 n2 Es wird eine Linie gezogen um n1 und n2, relativ zur momentanen Position des Grafikcursors.
DROPn Der letzte Stackeintrag wird gelöscht.
DUBn Der oberste Stackeintrag wird verdoppelt.
EDIT$n Der Text ab Ad resse n kann editiert werden.
GPAPERn Die Hintergrundfarbe des Grafikfensters wird von n bestimmt.
GPENn Der Farbstift für Grafikaus gaben wird ausgewählt.
HEIGHTn1 n2 Die Höhe des Grafikfensters wird festgelegt: n1 =oben, n2=unten.
INn1n2n2 wird vom Port n1 gelesen.
INCn1n2n2=n1+1
INKn1 n2 n3 Dem Farbstift n1 werden die Farben n2 und n3 zugewiesen.
INPUT nEs wird eine Zahleneingabe erwartet. Bei Zahlensystemen, deren Basis größer als 10 ist, müssen die Buchstaben groß eingegeben werden. Das Minuszeichen hat vor der Zahl zu stehen.
INPUT$ nEs wird auf einen Tasten druck gewartet. Der entsprechende ASCII-Wert wird auf den Stack gelegt.
JOY nIn n wird der Joystickstatus übergeben.
KEY$ nWie INPUT$, es wird jedoch nicht auf einen Tastendruck gewartet.
LOADn1 n2 Ab Adresse n1 muß der Name des zu ladenden Files stehen. Dieses File wird an Adresse n2 geladen.
LOCATEn1 n2 Der Textcursor wirdandie Position n1, n2 verschoben.
MAXn1 n2n3n3=n2 wenn n2>n1, sonst n3=n1
MINn1 n2n3n3=n2 wennn2<n1, sonst n3=n1
MODn1 n2n3n3 enthält den Rest von n1/n2.
MOVEn1 n2 Der Grafikcursor wird an die absolute Position n1, n2 verschoben.
MOVERn1 n2 Der Grafikcursor wird um n1 nach rechts (minus=links) und um n2 nach oben (minus=unten) verschoben.
NEGn1n2n2=-n1
NOSIGN Die Rechenoperationen *,/, MOD und \ werden auf positive Logik umgeschaltet.
NOTf1f2f2=-1 wenn fl =0, sonst f2=0.
ORn1 n2n3n3=n1 or n2
OUTn1 n2 n2 wird auf Port n1 aus gegeben
PAPERn Texthintergrundfarbe festlegen.
PEEKn1n2n2 entspricht dem Wert an Adr. n1.
PENn Textschreibstift aus wählen.
PLOTn1 n2 An der absoluten Position n1, n2 einen Punkt setzen.
PLOTRn1 n2 Wie PLOT, jedoch keine absoluten, sondern relative Koordinaten.
POKEn1 n2 Wert von n2 an Adr. n1 ablegen.
POS n1Gibt die Spalte des Text cursors zurück.
ROTn1 n2 n3n2 n1 n3Der oberste Stackeintrag wird wischen den 3. und 4. geschoben.
SAVEn1 n2 n3 Ab Adresse n1 steht der Name des abzuspeichernden Files. n2 ist die Startadresse und n3 die Länge.
SCREENn Bildschirmmodus setzen.
SGNn1n2n2 enthält das Vorzeichen von n1.
SIGN Die Rechenfunktionen *,/, MOD und \ werden auf vorzeichenbehaftete Zahlen eingerichtet.
SOUNDn1 n2 Das Soundregister n1 wird mit dem Wert n2 geladen.
SP.In1 n2 Die Blinkzeiten der Farbstifte werden festgelegt.
SP.Kn1 n2 Bei der Tastatur Wiederholung n1 und Geschwindigkeit n2 setzen.
SP.Wn1 n2 Synchronisationsbyte n1 und Baudrate n2 setzen. n2=333333/Baudrate, n1 soll zwischen 10 und 25 liegen. Je höher die Baudrate, desto kleiner n1.

Baudraten1n2
100025667
200018333
30001033

ST*EX X-Stack und Y-Stack tauschen.
ST*X X-Stack auswählen.
ST*Y Y-Stack auswählen.
SYSn Routine an Adr. n aufrufen.
TESTn1 n2n3n3 enthält die Farbstift nummer der Grafikposition n1,n2.
TESTRn1 n2 Wie TEST, jedoch wird die Position relativ zur Grafikcursorposition gemessen.
TIMEn1 n2 Uhrzeit setzen ;n1 enthält den höheren Wert, n2 den. niedrigeren.
TIME? n2 n1Uhrzeit abfragen; n1 enthält den höheren Wert, n2 den niedrigeren.
VPOS nDie Zeile, in der der Text-cursor steht, wird erfragt.
WIDTHn1 n2 Breite des Grafikfensters festlegen; n1=links, n2=rechts.
XORn1 n2n3n3=n1 xor n2
XPOS nX-Position des Grafik-cursors erfragen.
YPOS nY-Position des Grafik-cursors erfragen.
ZEROn1 n2 Nullpunkt für Grafikbefehle setzen.
\n1 n2n3 n4n3=n1/n2n4=n1 mod n2
@ Den USER-Modus verlassen.

Der Sound-Befehl

Er hat die Form SOUND n1 n2, wobei das Soundregister n1 mit dem Wert n2 geladen wird.

Sound-Register n2-Wert

  • 0 Low-Byte Tonperiode Kanal A (8 Bit)
  • 1 High-ByteTonperiode Kanal A (4 Bit)
  • 2 Low-Byte Ton periode Kanal B (8 Bit)
  • 3 High-Byte Tonperiode Kanal B (4 Bit)
  • 4 Low-Byte Tonperiode Kanal C (8 Bit)
  • 5 High-Byte Tonperiode Kanal C (4 Bit)
  • 6 Rauschen, mittlere Periodendauer (5 Bit)
  • 7 Kontrollregister (8 Bit)
    • Bit 7: Datenrichtung Port B: 1 =out, 0=in
    • Bit 6: Datenrichtung Port A: 1 =out, 0-in
    • Bit 5: Rauschen Kanal C: 1 =aus, 0=an
    • Bit 4: Rauschen Kanal B: 1 =aus, 0=an
    • Bit 3: Rauschen Kanal A: 1-aus, 0=an
    • Bit 2: Ton Kanal C: 1 =aus, 0=an
    • Bit 1: Ton Kanal B: 1 =aus, 0=an
    • Bit 0: Ton Kanal A: 1 =aus, 0-an
  • 8 Lautstärke Kanal A
    • Bit 0 bis 3: analog (ansteigend) (4 Bit)
    • Bit 4: Hardwarehüllkurve: 1=an,0=aus (5 Bit)
  • 9 Lautstärke Kanal B (siehe Reg. 8)
  • 10 Lautstärke Kanal C (siehe Reg. 8)
  • 11/12 Periodendauer Hardwarehüllkurve
  • 11 Low-Byte (8 Bit)
  • 12 High-Byte (8 Bit)
  • 13 Hardwarehüllkurve (s.u.) (4 Bit)
  • 14 Datenregister Port A (siehe Reg. 7, Bit 7) (8 Bit)
  • 15 Datenregister Port B (siehe Reg. 7, Bit 6) (8 Bit)

Hardwarehüllkurven (Reg. 13)

Bit 3: continue Bit 2: attack Bit 1: alternate Bit 0: hold 0 0??

0 1 ? ?
1 0 ? ?
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

Der CODE-Befehl

Dieser Befehl gibt den Wert der Adresse aus, auf die zugegriffen wird. Danach kann man einen neuen Wert eingeben (hexadezimal), aber erst nach wird der neue Wert gespeichert. Nach wird der Wert dieser Speicherstelle nicht mehr verändert, und das Programm verläßt die CODE-Routine.

Mit dieser Routine kann man direkt Maschinencode in das Programm einfügen. Dabei muß folgendes beachtet werden:

  1. Der Programmzeiger (Adresse 506 bzw. &1 FA) muß anschließend hinter die neue Routine zeigen.
  2. Die Routinenadresse wird in die Adreßtabelle eingetragen. Der Zeiger der Adreßtabelle steht bei Adresse 510 bzw. &1 FE und muß um 2 erhöht werden.
  3. Der Name wird in die Namentabelle eingetragen. Beim letzten Zeichen muß Bit 7 gesetzt sein. DerTabellenzeiger (Adr. 508 bzw. &1 FC) muß ebenfalls korrigiert werden.
  4. Das IX-Register zeigt immer auf den gerade benutzten Stack, das IY-Register auf den anderen. Die Register zeigen auf das Low-Byte des letzten Eintrages.
  5. Die Routine muß mit RET (&C9) abgeschlossen werden.
  6. Einen Parameter vom Stack holen und in HL speichern:
    LD, L, (IX+00)
    LD H, (IX+01)
    INC IX
    INC IX
  7. Einen Parameter aus HL auf den Stack legen:
    DEC IX
    DEC IX
    LD (IX+00), L
    LD (IX+01), H

Noch ein paar Tips

  1. Hat man mit CREATE einen Befehl erzeugt, der nicht zufriedenstellend läuft, kann man ihn folgendermaßen vollständig (nicht nur die Tabelleneinträge) löschen:
    DECREATE"Name
    USE
    506 \
    498 \
    DEEK / Programmzähler zurücksetzen
    DOKE /
    @ /
    Es muß der zuletzt kreierte Befehl sein, der gelöscht werden soll.
  2. Der Befehlsname eines neuen Befehls darf keine Verlängerung eines schon vorhandenen Befehlsnamen sein. Es darf also kein Befehl mehr mit ?, @ oder ähnlichem anfangen. Andersherum ist es jedoch erlaubt, z.B.:
    1. Befehl MOVER
    2. Befehl MOVE
    Das ist auch der Grund, warum die Befehle SCREEN und ZERO nicht MODE und ORIGIN heißen.
  3. Die Parameterangaben bei der Befehlsliste sind von links nach rechts zu lesen. Die links stehenden Parameter sind also zuerst einzugeben bzw. auszulesen. Ansonsten arbeitet der Stack nach dem LIFO-Prinzip (Last In, First Out).

Beispielprogramm

CREATE”dez-hex
REPEAT
10 I Basis \ dezimal
base / festlegen
input Zahl eingeben
13 \
10 \ Cursor
?$ / zum Beginn der nächsten
?$ / Zeile
16 \ Basis hexadezimal
base / festlegen
DUB Stackeintrag duplizieren
? Zahl ausgeben
13 \
10 \ Cursor
?$ / zum Beginn der nächsten
?$ / Zeile
NOT Flag setzen, falls Zahl=0 war
UNTIL Wiederholung, falls Flag=0
OK

Dieses kurze Programm wandelt solange eingegebene Dezimalzahlen in Hexdezimalzahlen um, bis man 0 eingibt. Wenn Sie das Programm unter Basic ausprobieren wollen, müssen Sie noch folgendes nach der Eingabe von OK tun:

PRGM < ENTER >
DEZ-HEX.SUB < ENTER > warten
< CTRL > < SHIFT > < ESC >
RUN”DEZ-HEX.SUB” < ENTER >

Sönke Ostertun-Gaekel, CPC Magazin

★ PUBLISHERS: CPC Magazin , CPC Magazin Codex
★ YEAR: 1986
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LiCENCE: LISTING
★ COLLECTION: CPC MAGAZIN 1985 1986
★ AUTHOR: Sönke Ostertun-Gaekel
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» FORTH  Compiler    GERMANDATE: 2013-01-17
DL: 382
TYPE: ZIP
SiZE: 8Ko
NOTE: Extended DSK/40 Cyls
.HFE: Χ

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Nightingale Software - Amsmon
» Applications » Ams-Asm
» Applications » Hexmonitor (Schneider Aktiv)
» Applications » Hisoft - Devpac80
» Applications » DésaCPC (CPC Revue)
» Applications » E-Basic
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 373 millisecondes et consultée 2444 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.