Nach dem noch immer richtungweisenden Maschinensprache-Monitor »Supermon« aus unserem zweiten Schneider-Sonderheft (Ausgabe 1/86) haben wir nun einen weiteren besonderen Leckerbissen für Sie: einen Zwei-Pass-Label-Assembler, der sogar die wichtigsten illegalen Befehle des Z80 kennt und verarbeitet. Für die Programmierung in Maschinensprache ist ein Assembler ein unerläßliches Hilfsmittel. Einfache, in Basic geschriebene Assembler erfüllen schnell die gestellten Anforderungen nicht mehr, und so muß meist ein professioneller Assembler her. Leider sind jedoch gute Assembler meist nicht billig; Preise über 100 Mark sind keine Seltenheit. Unser Listing »RITA« erspart Ihnen solche Ausgaben. RITA (»Resident Inline Turbo-Assembler«) ist ein Assembler, der mit Recht den Zusatz professionell verdient. Zu seiner vollen Leistungsfähigkeit blüht RITA beim Einsatz eines Diskettenlaufwerks auf. Hier einige Daten in Stichworten: - alle Standard-Pseudo-Befehle (DS, DB, DW, DM ORG EQU, END)
- erweiterte Pseudo-Befehle (DF, DC, DEF)
- bedingte Assemblierung (IF, ELSE, ENDIF)
- Nachladen von Quellcodeteilen (NAME, APPEND, LINK DRIVE)
- Assemblieren in den Arbeitsspeicher oder auf Diskette; im Zusammenhang mit dem Nachladen von Quellcode-Teilen fast unbegrenzte Objectcodelänge
- Protokoll aller Bildschirmausgaben auf Drucker
- Find-Funktion
- Befehle zur Nutzung der Indexregister als Halb-(8-Bit-) Register
- Beeinflussung des Assemblers mit zahlreichen Funktionen
- Anzeige jedes JP-Befehls, der sich durch einen relativen JR-Sprung ersetzen läßt
- Übersetzungsgeschwindigkeit von zirka 2 KByte Quellcode pro Sekunde
- Maschinencode-Unterroutinen sind direkt als Quellcode in Basic-Programme zu integrieren
Geben Sie zunächst Listing 1 ein und speichern Sie diesen Basic-Lader sicherheitshalber vor dem ersten Probelauf. Alle Besitzer von Vortex-Laufwerken müssen vor dem Speichern von RITA noch die Zeilen aus den Listings 2 oder 3 einfügen. Der fertige DATA-Lader erzeugt die Binärdatei »RITA.BIN«, die Sie mit Listing 4 laden. Diese Laderoutine enthält das Titelbild, belegt die Tastatur hilfreich für die Arbeit mit RITA und initialisiert die fünf neuen RSX-Befehle: |LABEL,p : gibt die Labeltabelle aus. HIMEM wird automatisch soweit herabgesetzt, daß die Tabelle auch bei »NEW« erhalten bleibt. Die Option »p« leitet die Ausgabe auf den Drucker. |WERT, "LABEL1 ","LABEL2",..,"LABELX" : gibt den Wert der angegebenen Label zurück. Dieser Befehl ist beispielsweise bei langen Labeltabellen sinnvoll, um sich die Suche nach einem Label zu sparen. |FIND, "text" : sucht den String < text > im Quellcode und gibt jede Zeile aus, die diesen Text enthält. |ASM, "optionl", "option2", "option3" : startet die Assemblierung. Dem Aufruf darf eine Reihe von Parametern folgen, die den Assembler bei seiner Arbeit beeinflussen: - NO (No Objectcode): RITA legt keine Objectcode-Datei an.
- TM (To Memory): Der Code wird direkt in den Speicher assembliert.
- NL (No Listing): Unterdrückt das Listen während der Assemblierung.
- NLT (No Label-Table): Unterdrückt die Ausgabe der Labeltabelle.
- P (Printer): Protokoll aller Ausgaben auf dem Drucker.
- WE (Wait on Error): Wartet nach jeder Fehlermeldung auf einen Tastendruck.
- DAT (DATA-Lader): Speichert den erzeugten Objectcode als DATA-Lader.
- JP (Jump): Unterdrückt die Meldung der durch JR ersetzbaren JP-Befehle.
Diese Parameter müssen Sie in Großbuchstaben übergeben und in beliebiger Reihenfolge direkt an den RSX-Befehl anhängen. Beachten Sie aber, daß sich einige Optionen gegenseitig ausschließen. Ein Aufruf sieht beispielsweise folgendermaßen aus: |ASM,WE,NL,NLTAchten Sie bei »TM« darauf, den Assembler nicht zu überschreiben. Er belegt den Speicherbereich von 8A00 bis zirka A400 hex. Von 89FF hex legt RITA die Labelnamen und -adressen in Richtung kleiner werdender Adressen ab. Auch die Speicherbereiche von ACA4 bis ADA5 hex (Eingabepuffer) und B61A bis B680 hex (Hüllkurven-Puffer) sind von RITA besetzt, weil der Assembler dort wichtige Daten zwischenspeichert. Assemblieren Sie aber direkt auf Diskette, spielt der im Arbeitsspeicher belegte Adreßbereich natürlich keine Rolle. |H leistet Ihnen während der Arbeit mit RITA eine kleine Hilfestellung, denn es ruft einen Hilfstext auf. Ihre Quellcodes geben Sie mit dem Basic-Editor als REMark-Zeilen ein. Setzen Sie dafür jeweils hinter die Zeilennummer ein Apostroph < SHIFT+7 > und schalten Sie mit der Taste < CAPS LOCK > auf permanente Großschreibung um. Arbeiten Sie mit einer Textverarbeitung, können Sie den Quellcode auch damit erzeugen, wenn Sie ihn als ASCII-Datei speichern. Ein Konvertierprogramm, das vor jede Textzeile Zeilennummer und Apostroph setzt, finden Sie in Listing 5. Label müssen mit einem Buchstaben beginnen und dürfen nicht länger als sechs Zeichen sein. Leerzeichen, Kommata, Plus, Minus und Klammern sind Trennzeichen und dürfen deshalb nicht in einem Labelnamen auftreten. Kommentare beginnen mit einem Semikolon »;«. Eine Quellcodezeile hat also prinzipiell folgenden Aufbau: Zeilennummer ' Label Befehl Operand ; Kommentar In der jeweiligen Zeile nicht vorkommende Teile lassen Sie einfach weg. Überzählige Leerzeichen zwischen den einzelnen Teilen überliest RITA, nur die Operanden vor und hinter dem Komma dürfen keine enthalten. RITA verarbeitet Zahlen in dezimaler, hexadezimaler und binärer Darstellung. Dezimaizahlen müssen positiv sein und im Bereich zwischen 0 und 65535 liegen. Die Schreibweise ist identisch mit der des Basic-Interpreters, also »&« vor hexadezimalen und »&X« vor binären Werten. Es gibt aber noch mehr Formen der Übergabe. Die folgenden Zeilen führen zum selben Ergebnis: 10 'LD A,65 20 'LD A,&41 30 'LD A,&X01000001 40 'LD A,"A" 50 'LD A,60+5 60 'LD A,"C"-2Werte - egal ob absolute oder Labels - lassen sich nach Belieben addieren und subtrahieren. Das Listen des Quellcodes während der Assemblierung hält auf Tastendruck an. Ein weiterer Tastendruck setzt das Listing fort, < ESC > bricht den Assembliervorgang ab. Fehlermeldungen erfolgen mit Angabe der fehlerhaften Zeile. RITA bietet auch einige sehr leistungsfähige Pseudo-Befehle zur Steuerung des Assemblers: - DS nn : fügt ab der aktuellen Position »nn« Null-Byte ein.
- DF nn,nn : wie DS, der zweite Wert bestimmt das Füllbyte.
- DB nn(,nn(,nn,...)) : fügt das Byte »nn« an der augenblicklichen Position in den Objectcode ein. Hinter DB dürfen beliebig viele, durch Komma getrennte Werte stehen.
- DW nnnn(,nnnn(,nnnn,...)) : wie DB, aber für 16-Bit-Werte, die im Low-/Highbyte-Förmat abgelegt werden.
- DM "text" : fügt den Text zwischen den Anführungszeichen in den Objectcode ein.
- DC "text" : wie DM, nur wird beim letzten Buchstaben das Bit 7 gesetzt. Das ist zum Beispiel bei der Programmierung neuer RSX-Befehle hilfreich:
DC "SCALE"ersetzt die BefehlsfolgeDM "SCAL" DB "E "+&80 - ORG nnnn : definiert die Adresse, an der das erste Byte des Objectcodes abgelegt wird (ORiGin).
- END nnnn : beendet die Assemblierung. Die Eingabe dieses Befehls ist nicht zwingend. Der Wert hinter END bestimmt wahlweise die Startadresse des Objectcodes.
- EQU nnnn : weist dem Label vor EQU den Wert »nnnn« zu (EQUal) und darf pro Label nur einmal verwendet werden.
- DEF nnnn : wie EQU, ist aber mehrmals für ein Label zu verwenden.
- LIST : schaltet die Quellcodeausgabe auf Bildschirm oder Drucker ein beziehungsweise aus. Für den LIST-Befehl gibt es vier Variationen:
- LIST ON : schaltet Bildschirmausgabe ein.
- LIST OFF : schaltet sie wieder aus.
- LIST P.ON : schaltet Druckerausgabe ein.
- LIST P.OFF : schaltet sie wieder aus.
- IF nnnn : ist der Wert »nnnn« ungleich Null (logisches False), übersetzt RITA die folgenden Z80-Befehle nicht, bis er auf ein ELSE, ENDIF oder das Ende des Quellcodes stößt.
- ELSE : kehrt die Funktion von IF um. Hat der Computer hinter IF nicht assembliert, fährt er jetzt mit der Assemblierung fort und umgekehrt.
- ENDIF beendet die IF- und ELSE-Befehle. Nach ENDIF wird also in jedem Fall weiter assembliert. Auch beim END-Befehl oder am physikalischen Ende des Quellcodes wird ENDIF automatisch einmal aufgerufen. Ein Beispiel für die Anwendung von IF, ELSE und ENDIF sehen Sie in Listing 6.
- LINK : dateiname lädt den Quellcode-Teil »dateiname« zum Speicherinhalt hinzu, sofern der Speicherplatz dafür ausreicht. Wenn das Ende des hinzugeladenen Quellcodes erreicht ist, fährt RITA an der Stelle hinter dem LINK-Befehl im Quellcode mit der Assemblierung fort. Der LINK-Befehl ist nützlich bei häufig gebrauchten Routinen und Unterprogrammen, die Sie so einfach in das Hauptprogramm einbinden können, ohne sie neu eingeben zu müssen. Sie dürfen aber keine verschachtelten LINK-Aufrufe verwenden.
- APPEND dateiname : liest den Quellcode »dateiname« anstelle des im Speicher befindlichen Quellcodes ein und setzt die Assemblierung damit fort. Dadurch ist die Länge des Quell- beziehungsweise des Objectcodes nur noch durch die Kapazität der angeschlossenen Laufwerke begrenzt.
- NAME dateiname : vor dem ersten APPEND müssen Sie den Namen des ersten Quellcodeteils (»dateiname«) angeben, damit RITA ihn nach dem ersten Durchgang (Pass) wieder laden kann.
- DRIVE nn : schaltet auf das Laufwerk mit dem Kennbuchstaben »nn« um. Zum Beispiel wird nach
DRIVE Bder Quellcode fortan von Laufwerk B geladen, der Objectcode aber immer auf Laufwerk A geschrieben.
Für alle, die RITA ihren Wünschen entsprechend ändern oder erweitern wollen, hier noch einige wichtige Patch-Adressen: A01D hex: Drucker-Steuersequenz für »Unterstreichen ein«. Das erste Byte gibt die Länge der Steuersequenz an, darauf folgt der Code. Besitzer des NLQ 401 oder kompatibler Drucker brauchen hier nichts zu ändern. Ab dieser Adresse sind insgesamt sechs Byte für andere Codes frei. A023 hex: Steuersequenz für »Unterstreichen aus«. Es gelten die gleichen Bedingungen wie oben. 8A46 hex: Standard-Assemblieradresse (Origin). Sie liegt normalerweise auf 5000 hex. 958D und 9915 hex: Anzahl der DATA-Werte pro Zeile für die Erzeugung von Basic-Ladern (normalerweise 8). Außerdem lassen sich bis zu zehn weitere Pseudo-Befehle definieren, ohne große Änderungen im Programm vorzunehmen. Zu diesem Zweck brauchen Sie nur den Namen des neuen Pseudo-Befehls mit gesetztem Bit 7 beim letzten Buchstaben an das Ende des Programms anzuhängen und mit einem Null-Byte dahinter das neue Ende der Pseudo-Befehlsnamenstabelle anzugeben. Dann geben Sie nur noch die absolute Adresse der neuen Routine als 2-Byte-Wert im Bereich von 8CCB bis 8CDE hex (normalerweise alle Null) an und erhöhen den Wert in Adresse 8B58 hex um 1. Haben Sie bereits die ersten Schritte in der Assembler-Programmierung hinter sich oder sind Sie gar schon Routinier, steht Ihrem Vergnügen mit RITA nichts mehr im Weg. Den Einsteigern unter Ihnen sei jedoch unser Maschinen-sprache-Grundkurs aus dem 5. Schneider-Sonderheft (Ausgabe 10/86) wärmstens empfohlen. Er erleichtert Ihnen nicht nur den Start, sondern bietet Ihnen auch noch eine vollständige Übersicht über die Z80-Maschinenbefehle. RITA verarbeitet jedoch als Besonderheit auch »verborgene« Z80-Befehle. Der Befehlssatz umfaßt normalerweise knapp 700 Befehle. Einige ersetzen fast kleine Programme; denken Sie nur an die Blocksuch- und Blockladebefehle. Der Z80 besitzt insgesamt 22 Register, von denen der alternative Registersatz (AF', BC', DE', HL) für CPC-Besitzer wegen der Banking- und Interrupt-Logik jedoch nicht nutzbar ist. Da Zugriffe auf CPU-Register schneller arbeiten als Speicherzugriffe, macht sich dieser Verlust stark bemerkbar. Besonders bei aufwendigen Berechnungen oder anderen zeitkritischen Aufgaben wäre es gut, stünden mehr Register zur Verfügung. Alle logischen und Vergleichs-Befehle (AND, OR, XOR und CP) sowie alle Rotier- und Schiebe-Befehle (RLC, SLA) arbeiten nur mit 8-Bit-Registern, also nutzt man sie auch entsprechend intensiv. Aus diesem Grund besitzt RITA die Fähigkeit, Befehle zu verarbeiten, die kaum ein anderer Assembler übersetzt und die auch in fast keinem Buch zum Z80 beschrieben sind. Gemeint sind Befehle, die die beiden 16-Bit-lndexregister einzeln als vier 8-Bit-Register ansprechen. Diese vier Register, der Einfachheit halber hier XL, XH, YL, und YH (IX-Register-Lowbyte, IX-Register-Highbyte, IY-Register-Lowbyte, und lY-Register-Highbyte) genannt, lassen sich bei allen Befehlen einsetzen, bei denen auch das L- oder das H-Register Verwendung finden und die nur ein Byte Opcode benötigen. Zum Beispiel sind beim DEC-Befehl das L- und H-Register getrennt zu benutzen, also auch die Register XL, XH, YL und YH: 2D=DEC L DD 2D=DEC XL FD 2D=DEC YL25=DEC H DD 25=DEC XH FD 25=DEC YH Bei den BIT-, SET- und RES- Befehlen ist dies nicht möglich, weil ihnen ein 2 Byte langer Opcode zugeordnet ist. Eine Tabelle der verwendbaren Befehle mit den dazugehörigen Opcodes finden Sie weiter unten. Es sind immerhin 44. Die einzige Einschränkung dabei ist jedoch, daß - wie bei allen Indexregister-Operationen - die Opcodes mit DD hex bei IX beziehungsweise FD hex für IY beginnen müssen. Dadurch werden sie doppelt so lang und entsprechend langsamer abgearbeitet als normale 8-Bit-Register. Sie sind aber immer noch schneller als direkte Speicherzugriffe, die mindestens drei Byte lang sind (zum Vergleich: »LD A,(&0000)« hat den Code 3A 00 00, »LD A,XH« ist mit DD 7C codiert). Viel Spaß nun beim Ausprobieren und Experimentieren! Code | Mnemonic | Erklärung | DD 8D DDEC DD 85 DD 84 DD 5A DD A4 DD B0 DD BC DD 2D DD 25 DD 2C DD 24 DD 7D DD 7C DD B5 DD B4 DD 9D DD 9C DD 95 DD 94 DD AD DD AC | ADC XL ADC XH ADD XL ADD XH AND XL AND XH CP XL CP XH DEC XL DEC XH INC XL INC XH LD A,XL LD A,XH OR XL OR XH SBC XL SBC XH SUB XL SUB XH XOR XL XOR XH | addiere Lowbyte IX-Reglster mit Carry zum Akku addiere Highbyte IX-Reglster mit Carry zum Akku addiere Lowbyte IX-Reglster zum Akku addiere Highbyte IX-Reglster zum Akku logisches UND mit Lowbyte IX-Register logisches UND mit Highbyle IX-Register vergleiche mit Lowbyte IX-Reglster vergleiche mit Highbyte IX-Register dekrementiere Lowbyte IX-Register dekrementiere Highbyte lY-Register inkrementiere Lowbyte IX-Register inkrementlere Highbyte IX-Register lade Akku mit Lowbyte IX-Register lade Akku mit Highbyte IX-Reglster logisches Oder mit Lowbyte IX-Register logisches Oder mit Hlghbyte IX-Register subtrahiere Lowbyte IX-Register mit Carry subtrahiere Highbyte IX-Register mit Carry subtrahiere Lowbyte IX-Reglster subtrahiere Hlghbyte IX-Register logisches Exklusiv-Oder mit Lowbyte IX-Register logisches Exklusiv-Oder mit Hlghbyte IX-Register | Tabelle. Diese illegalen Opcodes verarbeitet RITA. Für das IY-Register steht im ersten Byte FD anstatt DD hex. |
(Gerd Weinand/ja), HC ★ AMSTRAD CPC ★ DOWNLOAD ★ |
|
CPCrulez[Content Management System] v8.7-desktop/c Page créée en 220 millisecondes et consultée 269 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. |
|
|