Wer schon immer mal mit Forth arbeiten wollte, hat jetzt die Gelegenheit dazu Das Programm wird folgendermaßen erzeugt: - Den MC-Generator abtippen und mit SAVE”FORTH.LDR” abspeichern.
- Das Programm mit RUN starten. Der Maschinencode wird dann unter "FORTH.MC” abgespeichert und der Compiler gestartet.
- 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 | | Ein | Aus | Beschreibung | * | n1 n2 | n3 | n3=n1*n2 | + | n1 n2 | n3 | n3=n1+n2 | - | n1 n2 | n3 | n3=n1-n2 | / | n1 n2 | n3 | n3=n1/n2 | < | n1 n2 | f | f=-1=n1 kleiner n2, sonst 0 | <= | n1 n2 | f | f=-1 =n1 kleiner/gleich n2, | <> | n1 n2 | f | f=-1=n1 nicht gleich n2, | = | n1 n2 | f | f=-1=n1 gleich n2, sonst 0 | > | n1 n2 | f | f=-1=n1 größer n2, sonst 0 | >= | n1 n2 | f | f=-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. | ABS | n1 | n2 | n2= positiver Wert von n1. | AND | n1 n2 | n3 | n3=n1 and n2. | BASE | n | | n legt die Basis des Zahlen-systems für INPUT,? und ?-fest. | BORDER | n1 n2 | | em Bildschirmrand werden die Farben n1 und n2 zugewiesen. | CHANGE | n1 n2 | n2 n1 | Die letzten beiden Stackeinträge werden vertauscht. | CLG | | | Grafikfenster löschen | CLS | | | Textfenster löschen. | CODE n | | | Der Speicherbereich ab n | DEC | n1 | n2 | n2=n1-1 | DEEK | n1 | n2 | Der Zwei-Byte-Wert ab der | DOKE | n1 n2 | | Der Zwei-Byte-Wertn2 wird ab Adresse n1 abgelegt. | DRAW | n1 n2 | | Es wird eine Linie zur absoluten Position n1, n2 gezogen. | DRAWR | n1 n2 | | Es wird eine Linie gezogen um n1 und n2, relativ zur momentanen Position des Grafikcursors. | DROP | n | | Der letzte Stackeintrag wird gelöscht. | DUB | n | | Der oberste Stackeintrag wird verdoppelt. | EDIT$ | n | | Der Text ab Ad resse n kann editiert werden. | GPAPER | n | | Die Hintergrundfarbe des Grafikfensters wird von n bestimmt. | GPEN | n | | Der Farbstift für Grafikaus gaben wird ausgewählt. | HEIGHT | n1 n2 | | Die Höhe des Grafikfensters wird festgelegt: n1 =oben, n2=unten. | IN | n1 | n2 | n2 wird vom Port n1 gelesen. | INC | n1 | n2 | n2=n1+1 | INK | n1 n2 n3 | | Dem Farbstift n1 werden die Farben n2 und n3 zugewiesen. | INPUT | | n | Es 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$ | | n | Es wird auf einen Tasten druck gewartet. Der entsprechende ASCII-Wert wird auf den Stack gelegt. | JOY | | n | In n wird der Joystickstatus übergeben. | KEY$ | | n | Wie INPUT$, es wird jedoch nicht auf einen Tastendruck gewartet. | LOAD | n1 n2 | | Ab Adresse n1 muß der Name des zu ladenden Files stehen. Dieses File wird an Adresse n2 geladen. | LOCATE | n1 n2 | | Der Textcursor wirdandie Position n1, n2 verschoben. | MAX | n1 n2 | n3 | n3=n2 wenn n2>n1, sonst n3=n1 | MIN | n1 n2 | n3 | n3=n2 wennn2<n1, sonst n3=n1 | MOD | n1 n2 | n3 | n3 enthält den Rest von n1/n2. | MOVE | n1 n2 | | Der Grafikcursor wird an die absolute Position n1, n2 verschoben. | MOVER | n1 n2 | | Der Grafikcursor wird um n1 nach rechts (minus=links) und um n2 nach oben (minus=unten) verschoben. | NEG | n1 | n2 | n2=-n1 | NOSIGN | | | Die Rechenoperationen *,/, MOD und \ werden auf positive Logik umgeschaltet. | NOT | f1 | f2 | f2=-1 wenn fl =0, sonst f2=0. | OR | n1 n2 | n3 | n3=n1 or n2 | OUT | n1 n2 | | n2 wird auf Port n1 aus gegeben | PAPER | n | | Texthintergrundfarbe festlegen. | PEEK | n1 | n2 | n2 entspricht dem Wert an Adr. n1. | PEN | n | | Textschreibstift aus wählen. | PLOT | n1 n2 | | An der absoluten Position n1, n2 einen Punkt setzen. | PLOTR | n1 n2 | | Wie PLOT, jedoch keine absoluten, sondern relative Koordinaten. | POKE | n1 n2 | | Wert von n2 an Adr. n1 ablegen. | POS | | n1 | Gibt die Spalte des Text cursors zurück. | ROT | n1 n2 n3 | n2 n1 n3 | Der oberste Stackeintrag wird wischen den 3. und 4. geschoben. | SAVE | n1 n2 n3 | | Ab Adresse n1 steht der Name des abzuspeichernden Files. n2 ist die Startadresse und n3 die Länge. | SCREEN | n | | Bildschirmmodus setzen. | SGN | n1 | n2 | n2 enthält das Vorzeichen von n1. | SIGN | | | Die Rechenfunktionen *,/, MOD und \ werden auf vorzeichenbehaftete Zahlen eingerichtet. | SOUND | n1 n2 | | Das Soundregister n1 wird mit dem Wert n2 geladen. | SP.I | n1 n2 | | Die Blinkzeiten der Farbstifte werden festgelegt. | SP.K | n1 n2 | | Bei der Tastatur Wiederholung n1 und Geschwindigkeit n2 setzen. | SP.W | n1 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.Baudrate | n1 | n2 | 1000 | 25 | 667 | 2000 | 18 | 333 | 3000 | 10 | 33 |
| ST*EX | | | X-Stack und Y-Stack tauschen. | ST*X | | | X-Stack auswählen. | ST*Y | | | Y-Stack auswählen. | SYS | n | | Routine an Adr. n aufrufen. | TEST | n1 n2 | n3 | n3 enthält die Farbstift nummer der Grafikposition n1,n2. | TESTR | n1 n2 | | Wie TEST, jedoch wird die Position relativ zur Grafikcursorposition gemessen. | TIME | n1 n2 | | Uhrzeit setzen ;n1 enthält den höheren Wert, n2 den. niedrigeren. | TIME? | | n2 n1 | Uhrzeit abfragen; n1 enthält den höheren Wert, n2 den niedrigeren. | VPOS | | n | Die Zeile, in der der Text-cursor steht, wird erfragt. | WIDTH | n1 n2 | | Breite des Grafikfensters festlegen; n1=links, n2=rechts. | XOR | n1 n2 | n3 | n3=n1 xor n2 | XPOS | | n | X-Position des Grafik-cursors erfragen. | YPOS | | n | Y-Position des Grafik-cursors erfragen. | ZERO | n1 n2 | | Nullpunkt für Grafikbefehle setzen. | \ | n1 n2 | n3 n4 | n3=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: - Der Programmzeiger (Adresse 506 bzw. &1 FA) muß anschließend hinter die neue Routine zeigen.
- 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.
- 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.
- 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.
- Die Routine muß mit RET (&C9) abgeschlossen werden.
- Einen Parameter vom Stack holen und in HL speichern:
LD, L, (IX+00) LD H, (IX+01) INC IX INC IX - Einen Parameter aus HL auf den Stack legen:
DEC IX DEC IX LD (IX+00), L LD (IX+01), H
Noch ein paar Tips - 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. - 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. - 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 ★ AMSTRAD CPC ★ DOWNLOAD ★ |
|
CPCrulez[Content Management System] v8.7-desktop/c Page créée en 164 millisecondes et consultée 2450 foisL'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. |
|
|