APPLICATIONSPROGRAMMATION ★ Stapel in Basic ★

RSX Stack (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 ★ 

Rekursion und lokale Variablen stehen mit diesem Utility zur Verfügung.

Bei STACK.BIN handelt es sich um eine RSX-Erweiterung, die mit CALL ADR aktiviert wird und dann sechs Befehle bietet: INIT, RESET,

PUSH, POP, GET.SP, SET.SP. Das Programm ist voll relokatibel und 431 Byte lang. Z80-Programmierern werden sofort die Befehle PUSH und POP einfallen, und darum handelt es sich auch. STACK.BIN bietet die Vorteile der Stapelarbeit von Basic aus.

Dafür ist zunächst mit |INIT, ADRESSE, LAENGE ein Stapel anzulegen. Der Bereich ist frei wählbar, sollte zuvor jedoch durch MEMORY ADRESSE-1 gesichert werden. Der Stackpointer zeigt nun auf die ADRESSE + LAENGE; der gesamte Stapelbereich wird mit Null-Bytes gelöscht. Gibt man INIT weniger oder mehr als zwei Parameter mit, erfolgt ein SYNTAX ERROR.

|RESET setzt den gesamten Stack zurück, d.h., er wird mit Null-Bytes gelöscht, der Stackpointer zurückgesetzt. Maßgebend sind die durch UNIT übergebenen Parameter. Die |RESET-Routine benötigt selbst also keine Parameter. Sie wird von |INIT aufgerufen.

Als wichtigste Befehle bieten PUSH und POP, äquivalent zu den Z80-Befehlen, die Möglichkeit, Werte auf dem Stapel abzulegen oder von dort wieder zu holen. Die Syntax beider Befehle ist gleich:

|PUSH, @A, @B, @C,... bzw. |POP, @A, @B, @C,...

(Das @-Zeichen ist natürlich der Klammeraffe, CHR$(64).)

Die Basic-Variablen werden in der angegebenen Reihenfolge mit PUSH bzw. POP behandelt, d.h., zuerst A, dann B, dann C usw. Beim Pushen verlieren die angegebenen Variablen ihren Wert nicht. Um den Variablentyp muß sich der Programmierer keine Gedanken machen; die Anpassung nimmt das Programm vor.

So ergibt z. B. AI = 2.49 : |PUSH, @A!
B% = 0 : |POP, @B%

für B% den Wert 2 (= 2.49 abgerundet)

oder A% = -1 : |PUSH, @A%
B! = 0: |POP, @B!

für B! den Wert 65535.

Ein Variablenwert verbraucht auf dem Stapel eine bestimmte Anzahl von Bytes, und zwar so viele, wie nötig sind, um ihn darzustellen (2 für INTEGER, 3 für STRING, 5 für REAL), plus ein Kenn-Byte, das eben jene Wert-Byte-Anzahl enthält. Insgesamt ergeben sich also 3 Byte für einen Integer-Wert, 4 für einen String-Wert und 6 für einen Fließkomma-Wert. Über das Kenn-Byte ist es dem MP möglich, Integer-Werte auf dem Stapel an eine Fließkommavariable anzupassen und ungekehrt. Nach einem PUSH bzw. POP steht der Stackpointer also wieder auf dem gleichen Wert wie vor den beiden Operationen. Bei einem PUSH wächst der Stapel nach unten (wie der Z80-Prozessorstack), bei einem POP "schrumpft er aufwärts". Hat man also einen Stack mit IINIT,&8000,&100 angelegt, so steht der Stackpointer auf &8100. Bei einem A% = & ADFC : |PUSH, @A% steht nun folgendes in den Speicherstellen:

80FD-80FF 02 FC AD
| \/
Kennbyte Wert von A

Der Stackpointer steht auf 80FD. Nach POP wird der ausgelesene Stapelbereich nicht gelöscht, und der Wert ADFC kommt in die angegebene Variable. Der Stackpointer steht wieder auf 8100, also immer auf einem Kenn-Byte, außer nach |INIT, |RESET oder in der Ursprungspösition (hier 8100).

Der Stapel ist gegen Über- bzw. Unterlaufen geschützt. Sobald der Stapelzeiger den |INIT-Bereich verläßt, d.h., wenn zu viele |PUSH oder |POP erfolgen, wird ein OVERFLOW-ERROR ausgeführt.

Man kann auch mit Strings arbeiten. In diesem Falle werden beim PUSH bzw. POP die drei Bytes des Stringdescriptors (Länge + Speicheradresse) plus Kenn-Byte ($03) verarbeitet. Eine Umwandlung in Integer- oder Real-Varia-blen kann hier natürlich nicht erfolgen. Dinge wie |PUSCH, @A$: |POP, @B% sollte man also unterlassen; der Stackpointer steht dann meist falsch. Trotzdem ist die Behandlung von Strings mit PUSH bzw. POP manchmal ganz nützlich. IPUSH, @A$, @B$: |POP, @A$, @B$ vertauscht z.B. A$ + B$ ohne den Umweg über einen dritten Hilfs-String, der dann zusätzlich Platz verbrauchen würde.

Mit |GET.SP, @VAR% und |SET.SP, @VAR% kann der Stapelzeiger ausgelesen bzw. neu gesetzt werden. VAR% enthält die absolute Adresse. Nach UNIT,&8000.&1000 : |GET.SP, @VAR% enthält VAR% den Wert -28672 (= &9000). |GET.SP und |SET.SP arbeiten nur mit Integer-Variablen.

Welche Möglichkeiten sich ergeben, wenn man einen Stapel zur Verfügung hat, weiß jeder erfahrene Programmierer. Er denkt wahrscheinlich zuerst an die vor allem von Pascal bekannte Rekursion. Grundvoraussetzung dafür sind lokale Variablen, also solche, die ihren Wert nur in einem bestimmten Programmbereich (vor allem Subroutinen) besitzen.

Die ist nun auch in Basic möglich. Zu Beginn der Routine pusht man die betreffenden Variablen, weist ihnen andere Werte zuund holt am Ende den Eingangswert zurück. So können sich Unterprogramme selbst aufrufen (beim CPC bis ca. 80mal) und für jede Rechenebene eine Variable A besitzen.

Eintipphilfe

Das wichtigste Programm ist Listing 4, der MC-Generator. Speichern Sie ihn nach dem Abtippen mit SAVE "STACK.LDR” ab. Erst dann sollten Sie ihn mit RUN starten. Daraufhin wird das Programm ”STACK.RSX” erzeugt, abgespeichert und initialisiert. "STACK.RSX” ist später vom Programmierer oder anderen Programmen einladbar, und zwar mit

MEMORY adr-1 : LOAD”STACK.RSX”, adr: CALL adr

Der Wert von adr ist im Bereich unterhalb HIMEM und oberhalb &4000 beliebig, da "STACK.RSX” voll relokatibel ist. Die Länge des RSX-Codes ist 431 Byte.

Die Listings 1 bis 3 sind klassische Rekursionsprogramme und dienen nur zur Demonstration. Sie müssen also nicht unbedingt abgetippt werden. Dabei handelt es sich
bei Listing 1 um eine Fakultätsberechnung, Listing 2 ist das bekannte Denkspiel "Türme von Hanoi” und Listing 3 ist ein nützliches Utility, nämlich "Quicksort”.

"Türme von Hanoi” fragt nach der Anzahl der Scheiben im Spiel. Sie ist auf 10 begrenzt, da 10 Scheiben schon 1023 Bewegungsoperationen verlangen. Die Bewegungen werden auch grafisch dargestellt. Selbst für 10 Scheiben reicht ein Stapel von 128 Byte völlig aus.

"Quicksort” sortiert ein Array mit anzahl Elementen, an-zahl wird vom Anwender eingegeben. Das Array feid wird mit Zufallszahlen gefüllt, umsortiert, sortiert und ausgegeben. Für 100 Elemente braucht "Quicksort” ca. 6 Sekunden.

"Fakultät” braucht eigentlich nicht erläutert zu werden. Zudem sind die Listings ausreichend mit REMs kommentiert.

Matthias Weber , CPC Magazin

★ PUBLISHER: CPC Magazin
★ YEAR: 1987
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LiCENCE: LISTING
★ COLLECTION: CPC MAGAZIN 1987
★ AUTHOR: Matthias Weber
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» RSX-Stack    (CPC  Magazin)    GERMANDATE: 2020-06-06
DL: 213
TYPE: ZIP
SiZE: 7Ko
NOTE: 40 Cyls
.HFE: Χ

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

Lien(s):
» Applications » RSX - SCNSV and SCNLD
» Applications » RSX Block Save
» Applications » 3D Megacode
» Applications » Rsx - Flashing Cursor (The Amstrad User)
» Applications » Bank Manager - Les Instructions Cachées
» Applications » Pride Utilities - Rsx Printer Pack 1
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 272 millisecondes et consultée 884 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.