5167
UTILITY -> Other
© Kleincomputer (1989)
 
 
 
CC 1001 - Assmon
cpc
 
 

NOTICE / MANUAL

TXT (1)

NOTICE TEXTE n° 1 (173.68 Ko)

veb mikroelektronik "wilhelm pieck" mühlhausen Ohne Genehmigung des Herausgebers ist es nicht gestattet, das Buch oder Teile daraus nachzudrucken oder auf fotomechanischem Wege zu vervielfältigen. ASSMON # Inhaltsverzeichnis I n h a l t s v e r z e i c h n i s 1. Einleitung............................................ 5 2. Editor................................................ 6 2.1. Einführung............................................ 6 2.2. Editor-Kommandos...................................... 7 2.3. Lade- und Rette-Kommandos............................. 9 2.4. weitere Kommandos..................................... 11 3. Assembler............................................. 13 3.1. Die Arbeitsweise des Prozessors....................... 13 3.2. Die Registerstruktur des U880......................... 14 3.3. Flag-Bits............................................. 16 3.4. Interrupt-System...................................... 17 3.4.1. Nichtmaskierbarer Interrupt........................... 17 3.4.2. Maskierbarer Interrupt................................ 18 3.5. Adressierungsarten.................................... 19 3.6. Syntax der Assemblersprache........................... 20 3.6.1. Zeilennummern......................................... 21 3.6.2. Marken................................................ 21 3.6.3. Operationscode........................................ 22 3.6.4. Operanden............................................. 22 3.6.5. Kommentare............................................ 23 3.6.6. Pseudo-Befehle........................................ 23 3.6.7. bedingte Pseudo-Befehle............................... 24 3.6.8. Assembler-Kommandos................................... 25 3.6.9. Markentabelle......................................... 26 3.7. Befehlssatz des Assemblers............................ 27 3.7.1. 8-Bit-Ladebefehle..................................... 29 3.7.2. 16-Bit-Ladebefehle.................................... 30 3.7.3. Registeraustauschbefehle.............................. 32 3.7.4. Blocktransfer- und -suchbefehle....................... 34 3.7.5. 8-Bit-Arithmetik- und Logikbefehle.................... 35 3.7.6. 16-Bit-Arithmetikbefehle.............................. 38 3.7.7. Programmverzweigungsbefehle........................... 39 3.7.8. Unterprogrammbefehle.................................. 41 3.7.9. Rotations- und Verschiebebefehle...................... 43 3.7.10. Einzelbitbefehle...................................... 46 3.7.11. CPU-Steuerbefehle..................................... 47 3.7.12. Ein- und Ausgabebefehle............................... 48 3.8. Abarbeitung des Assemblers............................ 51 3.8.1. Assembler-Optionen.................................... 51 3.8.2. Fehlermeldungen....................................... 51 3.8.3. Assemblerliste........................................ 52 4. Disassembler / Debugger............................... 53 4.1. Einführung............................................ 53 4.2. Bildschirmausgaben.................................... 53 4.3. Kommandos............................................. 54 4.3.1. Disassembler.......................................... 54 4.3.2. Speicherzeigerkommandos............................... 55 4.3.3. Abarbeiten von Code................................... 56 4.3.4. Speicher- und Registeränderungen...................... 57 4.3.5. Lade- und Rette-Kommandos............................. 58 4.3.6. weitere Kommandos..................................... 58 5. Programmbeispiel...................................... 60 6. Literaturhinweise..................................... 64 Anhang A Befehlscode-Tabelle................................. 65 Anhang B Pseudobefehle und Assembler-Kommandos............... 70 Anhang C Übersicht ASSMON1 und ASSMON2....................... 71 Anhang D Fehlermeldungen..................................... 73 Anhang E Reservierte Wörter.................................. 74 ASSMON # 1. Einleitung 1. E i n l e i t u n g Die Programme ASSMON1 und ASSMON2 stellen ein komplettes U880- Assemblerentwicklungssystem dar. Das Programm ASSMON1 enthält einen Editor und einen 2-Pass-Assembler. Im Programm ASSMON2 sind ein Testmonitor und ein Disassembler zusammengefaßt. Die Lage der Programme im Speicher muß vom Anwender vor dem Laden festge- legt werden, ist also nicht vorgegeben. Die Syntax des verwende- ten Assemblers entspricht der UDOS-Sprachversion. Für eine effektive Programmierung des KC compact in Maschinen- sprache ist das zum Computer gehörige Systemhandbuch unbedingt erforderlich, welches im Fachhandel erhältlich ist. Darin sind unter anderem alle wichtigen Systemunterprogramme und Arbeits- zellen beschrieben. Neben dem Assembler im Programm ASSMON1 wird dem Programmierer mit dem Programm ASSMON2 ein Debugger und Disassembler bereitge- stellt. Damit wird ein Rückübersetzen in Befehlsmnemonik, ein schrittweises Abarbeiten oder ein Abarbeiten in Echtzeit von bereits vorhandenem Maschinencode möglich. In der nachfolgenden Beschreibung werden gleichzeitig zu betäti- gende Tasten mit "-" (z.B. ^CTRL_-^A_) und nacheinander zu betä- tigende Tasten mit "+" (z.B. ^X_+^Y_) zwischen den Tasten darge- stellt. Die beiden Programme ASSMON1 und ASSMON2 sind jeweils mit ihren Ladeprogrammen hintereinander auf der Kassette CC1001 abgespeichert. Soll ein Programm geladen werden, wird die Kassette an den Programmanfang des jeweiligen Ladeprogrammes gespult und RUN" ^RETURN_+^weitere Taste_ in den Computer eingegeben. Nach dem Einlesen des Ladeprogramms ist gegebenenfalls der Kassettenrecorder zu stoppen, wenn keine Motorschaltung vorhanden ist. Das Ladeprogramm startet selbstän- dig und fordert vom Bediener die Eingabe der eigentlichen Lade- adresse von ASSMON1 bzw. ASSMON2. Es können Zahlen zwischen 1000 und 30000 eingegeben werden. ASSMON1 sollte sinnvollerweise im unteren RAM-Bereich (Eingabe von 1000) geladen werden, da das Quellprogramm, die Adreßtabelle und die Maschinenphase im Normal- fall hinter ASSMON1 abgelegt werden. ASSMON2 muß jeweils in den RAM-Bereich gelegt werden, der nicht vom zu testenden Programm belegt wird. Sollen beide Programme gleichzeitig im Speicher gehalten werden, wird ASSMON1 unten (Adresse 1000) und ASSMON2 oben (Adresse 30000) in den RAM geladen. In diesem Fall muß ASSMON2 zuerst geladen werden. Die Programme sind auf der Kassette wie folgt angeordnet: Programm ! Zählerstand ! Geracord ! LCR-C ---------------------------------------------- ASSMON1 ! 010 ! 018 ASSMON2 ! 060 ! 090 Auf der A-Seite sind die Programme mit 1000 Baud und auf der B- Seite mit 2000 Baud Übertragungsrate abgespeichert. Dabei kann die B-Seite mit 2000 Baud nur bei optimal eingestelltem Kassettenrecorder eingelesen werden. ASSMON # 2. Editor 2. E d i t o r 2.1. Einführung Der Editor, der in ASSMON1 enthalten ist, ist ein einfacher, zeilenorientierter Aufbereiter. Die Quellprogramme können mit seiner Hilfe eingegeben und geändert werden. Ähnlich wie in BASIC erfolgt hier die Bearbeitung über einen Puffer, dessen Inhalt erst mit dem Zeilenabschluß (^ENTER_) in die Textdatei übernommen wird. In der Textdatei werden Zwischenräume komprimiert, um Speicherplatz zu sparen. Die Zeile wird deshalb bei der Übernahme vom Puffer in die Textdatei auf Zwischenräume kontrolliert. Gefundene Zwischenräume werden durch ein Tabulatorzeichen ersetzt. Das erleichtert nachher auch die formatierte Ausgabe auf dem Bildschirm oder dem Drucker. Im Kommentar werden Zwischenräume nicht komprimiert. Nach dem Einladen von ASSMON1 wird unter anderem folgendes Hilfsmenü auf dem Bildschirm angezeigt: Assemble Bye Current+ State Delete Edit Find Get text Help Insert CTRL/J -> ASSMON2 List Move reNumber Object Put text Q put ASCII Run Separator Tape speed Upper line Verify Width teXt info Y print length Z print text Danach erscheint das Promptzeichen '>' und der Editor wartet auf Kommandos. Als Kommandos werden nur einzelne Buchstaben eingegeben. Bei den angezeigten Kommandos des Hilfsmenüs ist jeweils ein Buchstabe groß geschrieben. Dieser Buchstabe muß eingegeben werden, um das jeweilige Kommando zu starten. Kommandozeilen haben folgendes allgemeingültiges Format: >K a,b,c,d ^RETURN_ K ... Kommando, welches ausgeführt werden soll a,b ... Zahl von 1 - 32767 c,d ... Zeichenkette maximal 20 Stellen Die Anzahl der verlangten Argumente ist vom Kommando abhängig. Der Editor speichert die eingegebenen Argumente. Diese können dann bei nachfolgenden Kommandos weiterverwendet werden. Beim Programmstart sind a und b auf den Wert 10 gesetzt und die Zeichenketten sind leer. Die Kommandobuchstaben können in Klein- oder Großbuchstaben eingegeben werden. Bei fehlerhaft eingegebener Kommandozeile erscheint die Fehlermeldung 'PARDON?'. In den folgenden Abschnitten werden die einzelnen Kommandos beschrieben. Falls ein Argument in den Zeichen '^_' eingeschlossen ist, muß dieses Argument unbedingt angegeben werden, um das Kommando durchführen zu können. 2.2. Editor-Kommandos Texteingabe ----------- Zur Texteingabe gibt es zwei Möglichkeiten, genau wie in BASIC. Zum einen kann man Zeile für Zeile durch Eingabe der Zeilennummer und des zugehörigen Textes eingeben. Zum zweiten besteht die Möglichkeit der automatischen Zeilennummernbereitstellung (in BASIC: AUTO-Kommando). Kommando: I n,m (Insert) n ... 1.Zeile m ... Schrittweite Zeilennummerierung Wird eine bereits vorhandene Zeilennummer eingegeben, wird die zugehörige Zeile in der Textdatei mit der neuen Zeile überschrieben bzw. gelöscht, wenn nur die Zeilennummer und ^RETURN_ eingegeben wurde. Es sind Zeilennummern von 1 bis 32767 zulässig. Bei der Texteingabe sind folgende Kontroll-Funktionen möglich: ^RETURN_ ... Abschluß der Eingabe einer Zeile ^TAB_ ... Sprung zur nächsten Tabulatorposition ^CTRL_-^X_ ... Löschen der Zeile bis zum Beginn ^ESC_ ... Rückkehr in den Kommandomodus ^DEL_ ... Löschen des Zeichens vor der Cursorposition Nähert sich die Textdatei dem RAM-Ende, gibt der Editor die Meldung 'Bad Memory' aus. Es kann an dieser Stelle kein weiterer Text eingegeben werden, und die Datei sollte auf Band gesichert werden. Textausgabe ----------- Kommando: L n,m (List) n ... 1. auszugebende Zeile m ... letzte auszugebende Zeile Ohne Argumentangabe werden immer die Standardwerte 1 und 32767 angenommen. Die Auflistung erfolgt in formatierter Form. Falls Zeilennummer m noch nicht erreicht ist, werden immer 24 Zeilen ausgegeben. Danach kann man mit ^ESC_ in den Kommandomodus zurückkehren oder mit Betätigung jeder anderen Taste weiter- listen. Textbearbeitung --------------- Die nachfolgend beschriebenen Kommandos sind die eigentlichen Editierkommandos. Sie unterstützen das Verändern der gesamten Textdatei bzw. einer einzelnen Zeile. Kommando: E n (Edit) n ... Zeilennummer Die Zeile mit der Nummer n wird zur Bearbeitung in den Eingabepuffer kopiert. Alle Bearbeitungen finden im Puffer statt und nicht in der Textdatei. Bis zur Übernahme des Pufferinhaltes in die Datei mit ^RETURN_ kann jederzeit wieder auf die Original- zeile zurückgegriffen werden. Nach Aufruf von 'E n' wird die Zeile auf den Bildschirm geschrieben und die gleiche Zeilennummer mit nachfolgendem Cursor darunter ausgegeben. Der Cursor bildet einen gedanklichen Zeiger, der über die Zeile bewegt werden kann. Folgende Unterkommandos stehen zur Verfügung: ^SPACE_ erhöht Zeiger um 1 ^DEL_ vermindert Zeiger um 1 ^RETURN_ Beenden der Aufbereitung, Pufferinhalt wird in die Textdatei übernommen ^Q_ Verzichten auf Veränderung der Zeile, Pufferinhalt wird nicht in die Textdatei übernommen ^R_ erneutes Laden der Textdatei aus der Datei in den Puffer ^L_ Rest der Zeile ausgeben, Zeiger steht danach wieder am Zeilenanfang ^K_ Lösche Zeichen, auf dem der Zeiger steht ^Z_ Lösche alle Zeichen von Zeigerposition bis Zeilenende ^F_ Suche nächstes Vorkommen der Zeichenkette f (siehe Kommando F) in der Textdatei, bei keinem weiteren Vorkommen wird das Kommando abgebrochen ^S_ Ersetze gefundene Zeichenkette f mit der vorher definierten Zeichenkette s und suche nächstes Vorkommen der Zeichenkette f ^I_ Einfügen von Zeichen an der Zeigerposition, der Einfüge-Cursor wird als "*" dargestellt, verlassen wird der Einfügemodus mit ^RETURN_ ^X_ setzt Zeiger auf Zeilenende und ruft Unterkommando I auf ^C_ Aufruf der Änderungsfunktion innerhalb des Editier- Modus, Zeichen auf Zeigerposition werden durch Tasteneingabe überschrieben und der Zeiger um 1 erhöht, verlassen wird dieses Unterkommando durch ^RETURN_ oder automatisch, wenn das Zeilenende erreicht wird, während des "Änderungsmodus" wird der Cursor als "+" dargestellt. Kommando: D ^n,m_ (Delete) n ... 1.Zeile m ... letzte Zeile Die Zeilen von n bis m werden in der Textdatei gelöscht. Für eine Einzelzeile muß n=m sein. Eine Einzelzeile kann auch durch Eingabe von Zeilennummer und ^RETURN_ gelöscht werden. Kommando: M n,m (Move) n ... Quellzeile m ... Zielzeile Zeile n wird in Zeile m kopiert. Dabei wird m, wenn vorhanden, überschrieben und Zeile n gelöscht. Kommando: N ^n,m_ (Renumber) Es wird eine Neunumerierung der Zeilen ab Zeile n mit der Schrittweite m durchgeführt. Sollte durch Renumber eine Zeilen- nummer größer 32767 gebildet werden, wird Renumber nicht ausgeführt und die alte Numerierung bleibt erhalten. Kommando: F n,m,f,s Die Textdatei wird von der Zeile n bis zur Zeile m nach der Zeichenkette f durchsucht. Wird die Kette gefunden, wird in das Kommando E verzweigt. Dort können dann die dort möglichen Unterkommandos benutzt werden. Wurde der Zeilenbereich und die Zeichenkette bereits bei einem vorhergehenden Kommando eingegeben, braucht zur Suche lediglich noch 'F' eingegeben zu werden. 2.3. Lade- und Rette-Kommandos Die nachfolgend beschriebenen Kommandos dienen allgemein dem Datenaustausch zwischen dem RAM des Computers und einem externen Datenträger (Kassette oder Diskette). Es können Textdateien oder Objektcode (Maschinenprogramme) gerettet bzw. geladen werden. Kommando: P n,m,s (Put text) n ... 1.Zeile m ... letzte Zeile s ... Name der Datei Die Textdatei wird von der Zeile n bis zur Zeile m unter dem Dateinamen s auf Band gerettet. Wurden n,m und s durch vorher- gehende Kommandos bereits gesetzt, werden diese alten Werte verwendet. Vor der Eingabe des Kommandos P muß der Kassetten- recorder auf Aufnahme gestellt werden. ASSMON # 2. Editor Kommando: Q n,m,s (put ASCII) n ... 1.Zeile m ... letzte Zeile s ... Dateiname Die Textdatei kann auch als reine ASCII-Datei ohne Zeilennummerierung auf Band abgelegt werden. Es gelten die gleichen Bedingungen wie bei 'P'. Kommando: G,,s (Get text) s ... Dateiname Die Textdatei mit dem Namen s soll vom Magnetband geladen werden. Ist s ein leerer String, wird die erste gefundene Textdatei geladen. Nach Kommandoaufruf muß der Recorder auf Wiedergabe gestellt werden. Es beginnt jetzt die Suche nach einer Datei mit dem angegebenen Namen, bzw. bei Leerstring wird die zuerst gefundene Textdatei geladen. Wenn die Datei gefunden wird, wird die Meldung 'LOADING filename' ausgegeben, ansonsten wird 'FOUND filename' angezeigt und die Suche wird fortgesetzt. Befindet sich bereits eine Textdatei im Speicher, wird die neu geladene Datei hinten angefügt, und es erfolgt eine neue Durchnumerierung der Zeilen beginnend mit 1 und der Schrittweite 1. Kommando: V,,s (Verify) s ... Dateiname Mit diesem Kommando kann eine mit 'P' gerettete Textdatei auf Übereinstimmung mit der momentan im Speicher vorhandenen Datei überprüft werden (Probe, ob sich Datei später auch laden läßt). Als Ergebnis wird 'VERIFIED' (Übereinstimmung) oder 'FAILED' (Fehler) ausgegeben. Kommando: T n (Tape speed) n ... Zahl >0 Mit 'T' kann die SAVE-Geschwindigkeit zwischen 1000 und 2000 Baud gewechselt werden. Fehlt das Argument n, wird auf 1000 Baud eingestellt. Wird n mit >0 angegeben, wird auf 2000 Baud einge- stellt. Kommando: O,,s (Objekt) s ... Dateiname Mit 'O' wird der bei der letzten Assemblierung entstandene Objektcode auf Band gerettet. Vor der Eingabe von 'O' muß der Recorder auf Aufnahme gestellt werden. Der gerettete Objektcode kann nicht mehr mit ASSMON1 geladen werden. Um diese Datei zu laden, muß man sich in ASSMON2 oder BASIC befinden. 2.4. Weitere Kommandos Kommando: H (Help) Mit 'H' können die in ASSMON1 möglichen Kommandos auf dem Bild- schirm angezeigt werden. Kommando: Z n,m (print text) n ... 1.Zeile m ... letzte Zeile Mit 'Z' kann die Textdatei von der Zeile n bis zur Zeile m auf einem Drucker ausgegeben werden. Fehlen die Argumente n und m, wird die gesamte Datei ausgedruckt. Sollte kein Drucker angeschlossen sein, wird 'No Printer' auf dem Bildschirm ausgegeben. Mit beliebigem Tastendruck wird das Drucken gestoppt und mit ^ESC_ abgebrochen. Nach dem Druckstopp kann mit beliebiger Taste (außer ^ESC_) fortgesetzt werden. Kommando: B (Bye) Mit diesem Kommado wird zu BASIC zurückgesprungen. Um in ASSMON1 zurückzukehren, muß mit CALL die Ladeadresse von ASSMON1+4 für Warmstart oder Ladeadresse + 2 für Kaltstart aufgerufen werden. Kommando: S,,d (Separator) d ... Trennzeichen Zum Trennen der Argumente in der Kommadozeile wird ',' verwendet. Mit 'S' kann aber auch jedes andere Zeichen dafür definiert werden. Dazu ist der String d einzugeben. Ist d länger als ein Zeichen, wird jeweils das erste Zeichen genommen. ^SPACE_ ist als Trennzeichen nicht zulässig. Kommando: C (Current State) Das Kommado 'C' bewirkt die Ausgabe der zuletzt definierten bzw. Standardargumente a und b für die zwei Zeilennummern und c und d für die Zeichenketten. Sinnvoll ist dieses Kommando immer dann, wenn die Argumente bei späteren Kommandos verwendet werden sollen, um deren Inhalt zu prüfen. Kommando: X (text info) Mit 'X' wird die Start- und Endadresse der Textdatei dezimal angezeigt. Das ist zur weiteren Verwendung des Textes von BASIC aus oder zur Überprüfung des noch freien Speichers nützlich. Kommando: W (Width) Das Kommando 'W' schaltet zwischen den Bildschirmmodi 1 und 2 um, so daß wahlweise 40 oder 80 Zeichen pro Zeile angezeigt werden. Kommando: Y (print lenght) 'Y' legt die Anzahl der Zeilen pro Seite bei Druckerausgabe fest. Kommando: U (Upper line) Soll Quelltext gerettet oder gelöscht werden, interessiert oft die letzte verwendete Zeilennummer. Mit 'U' wird diese auf dem Bildschirm ausgegeben. Kommando: ^CTRL_-^J_ (JUMP to ASSMON2) Mit ^CTRL_-^J_ wird in das Programm 'ASSMON2' gesprungen, falls es geladen ist. Kommando: A (Assemble) Mit 'A' wird der im Speicher befindliche Quelltext assembliert. Dieses Kommando wird ausführlich im Abschnitt 3.8. beschrieben. Kommando: R (Run) 'R' startet ein assembliertes Programm auf der Adresse, die im Quelltext mit 'ENT' festgelegt wurde (siehe Abschn. 3.6.6.). ASSMON # 3. Assembler 3. A s s e m b l e r Der Assembler ist der wichtigste Programmteil in 'ASSMON1'. Er übersetzt den Quelltext in den gewünschten Maschinencode, der vom U880 direkt verarbeitet werden kann. Verwendet wurde hierfür ein 2-Phasen-Assembler, der alle Standard-U880-Befehle, verschiedene Pseudo-Befehle und Assembler-Kommandos verarbeiten kann. Weitere Möglichkeiten bietet das bedingte Assemblieren, d.h. Teile des Quellprogramms werden nur unter bestimmten Bedingungen in Maschi- nencode umgesetzt. Es sei darauf hingewiesen, daß es mehrere verschiedene Assembler- sprachen für die U880 bzw. Z80 CPU gibt. Der hier beschriebene Assembler verarbeitet Quellprogramme in ZILOG-Mnemonik (wie z. B. die Assembler der Bürocomputer A5120/30 unter den Betriebs- systemen UDOS und SCPx). 3.1. Die Arbeitsweise des Prozessors Mit dem U880-Prozessor stehen dem Programmierer über 600 Opera- tionscodes für arithmetische, logische, Programmorganisations-, Datentransfer- sowie Ein-/Ausgabe-Befehle zur Verfügung. Sämt- liche Befehle eines abzuarbeitenden Maschinenprogramms stehen in externen Speicherbausteinen (dem sog. Hauptspeicher) des Rech- ners. Die Befehlsabläufe ("Befehlszyklen") sehen alle im Prinzip gleich aus (s. Abb. 3.1). Taktzyklus ! ! ! ! / / / / / / / / / / / / ! ! ! ! ! ! ! ! ! ! ! ! T1 T2 T3 T4! T1 T2 T3! T1 T2 T3! ! ! ! ! !Maschinenzyklus! ! ! ! M1 ! M2 ! M3 ! ! ! ! Befehlszyklus ! Abb. 3.1: Beispiel eines Befehlszyklus Man ersieht aus Abb. 3.1, daß folgende Hierarchie besteht: Die Befehlszyklen bestehen aus mehreren "Maschinenzyklen". Die Anzahl der Maschinenzyklen pro Befehl ist unterschiedlich (zwischen 1 und 6). Jeder Maschinenzyklus besteht seinerseits aus mehreren "Taktzyklen" (3 bis 6 Taktzyklen). Die Dauer eines Taktzyklus ist durch die Frequenz des Taktgenerators der CPU gegeben. Beim KC compact beträgt die Taktfrequenz 4 MHz, d. h. die Dauer eines Taktzyklus beträgt 250 ns. Im Abschnitt 3.7 ist für die einzelnen Befehle der CPU die Gesamtanzahl der Taktzyklen jeweils angegeben. Man kann hieraus die Ausführungszeit eines Befehls ermitteln, was z. B. für Programme mit Zeitschleifen notwendig ist. 3.2. Die Registerstruktur des U880 Der U880-Prozessor hat die in Abb. 3.2 dargestellte Register- struktur. Hauptregister Hintergrundregister ----------------- ----------------- Akkumulator/Flags ! A ! F ! ! A' ! F' ! ----------------- ----------------- ----------------- ----------------- ! B ! C ! ! B' ! C' ! ----------------- ----------------- Allgemeine ----------------- ----------------- ! D ! E ! ! D' ! E' ! Register ----------------- ----------------- ----------------- ----------------- ! H ! L ! ! H' ! L' ! ----------------- ----------------- ----------------------------- ! IX ! Index- ----------------------------- register ----------------------------- ! IY ! ----------------------------- ----------------------------- Befehlszähler ! PC ! ----------------------------- ----------------------------- Stackpointer ! SP ! ----------------------------- Interruptvektor-/ ----------------------------- Refresh-Register ! I ! R ! ----------------------------- Abb. 3.2: Registerstruktur Die einzelnen Register bestehen aus 16-Bit-Speichern, die entsprechend der in der Abbildung dargestellten Aufteilung wahl- weise als 8-Bit-Register oder als 16-Bit-Registerpaare benutzt werden können. Der Zahlenbereich der 8-Bit-Register geht von 0 bis 255 (bzw. -128 bis +127 bei vorzeichenbehafteten Zahlen) und der Zahlenbereich der 16-Bit-Register von 0 bis 65535 (bzw. -32768 bis +32767). Nach dem Einschalten des Rechners wird immer der Hauptregister- satz angesprochen. Das Umschalten auf die Hintergrundregister geschieht durch 2 Austauschbefehle (s. Abschn. 3.7.2.) getrennt für Akkumulator/Flag und Allgemeinregister. Danach beziehen sich alle Befehle bis zum erneuten Umschalten auf die Hintergrund- register. Beim KC compact wird der Hintergrundregistersatz im System für die Interruptbehandlung verwendet und steht dem Nutzer deshalb nicht zur freien Verfügung. Akkumulator ----------- Das 8-Bit-Register A dient bei arithmetischen und logischen Befehlen zur Aufnahme eines Operanden. Der andere Operand kommt aus einem anderen Register oder aus dem Speicher. Das Ergebnis der Operation wird wieder im Akkumulator abgelegt, und steht dort für eine weitere Verarbeitung zur Verfügung. Allgemeine Register ------------------- Diese können als 8-Bit-Register (B, C, D, E, H, L) oder als 16- Bit-Registerpaare (BC, DE, HL) benutzt werden. Die Register kann man frei als Zwischenspeicher verwenden, jedoch beziehen sich bestimmte Befehle auf einzelne Register. So dient das HL- Registerpaar der indirekten Speicheradressierung. Das DE- Registerpaar kann mit dem Registeraustauschbefehl über HL dem selben Zweck dienen. Bei einigen Befehlen werden beide Registerpaare als Adressenspeicher für Quell- und Zieladressen benutzt (z. B. LDIR). Das Register B bzw. BC wird vorwiegend als Zählregister ver- wendet. Befehlszähler -------------- Das 16-Bit-Register PC enthält den aktuellen Befehlszählerstand. Beim Einschalten des Rechners wird der Befehlszähler auf Null gesetzt. Bei Sprung- und Unterprogrammbefehlen wird er mit einem neuen Wert geladen, sonst wird er automatisch jeweils um die Befehlslänge erhöht. Stackpointer ------------ Der Stackpointer SP enthält die 16-Bit-Adresse der aktuellen Spitze des Kellerspeichers der CPU. Der Kellerspeicher arbeitet nach dem Prinzip, daß die zuletzt gespeicherten Daten wieder als erste ausgegeben werden ("last in - first out"). Er dient vorwie- gend zur Aufnahme der Rückkehradressen bei Unterprogramm-Aufrufen und Interruptroutinen. Außerdem kann er zum Ablegen (PUSH) und Wiedereinlesen (POP) von 16-Bit-Daten aus den Registern ver- wendet werden. Durch Setzen des Stackpointers im Initialisie- rungsprogramm des Rechners wird die Lage des für den Keller- speicher zur Verfügung stehenden Teils des Operativ-Speichers (RAM-Bereich) festgelegt. Die Größe ist zunächst nicht begrenzt. Beim Programmerstellen ist aber zu beachten, daß für das jewei- lige Programm ausreichend Kellerspeicherplätze zur Verfügung stehen müssen. Der Stackpointer wird beim Abspeichern im Keller um 2 Byte ver- kleinert und beim Einlesen um 2 Byte erhöht. Er zeigt immer auf den zuletzt eingespeicherten Wert. Ein Unterprogrammaufruf kellert den Befehlszählerstand ein, ein Rückkehrbefehl kellert den PC wieder aus. Außerdem können in den Unterprogrammen Daten mit PUSH und POP zwischengespeichert werden. Damit nicht versehentlich Befehlszähler und Daten verwechselt werden, ist bei der Verwendung von PUSH und POP größte Sorgfalt auf ein symmetrisches Ein- und Auskellern zu legen. Indexregister ------------- Die Indexregister IX und IY werden zur indizierten Adressierung (s. Abschn. 3.5.) verwendet oder können als 16-Bit-Datenregister verwendet werden. Bei der indizierten Adressierung kann auf einen Speicherbereich in einer Umgebung von -128 bis +127 um den im Register gespei- cherten Adressenwert direkt zugegriffen werden. Interruptvektorregister ----------------------- Dieses Register beinhaltet den höherwertigen Adreßteil der Tabelle für die Interruptroutinen (s. dazu Abschn. 3.4.). Refreshregister --------------- Dieses 7-Bit-Register wird bei jeder Befehlsverarbeitung um 1 erhöht. Es dient zum Auffrischen der Inhalte der dynamischen RAM- Speicher und ist für den Programmierer kaum von Bedeutung. 3.3. Flag-Bits Die CPU verfügt über zwei Status-(Flag-)Register (s. Abb. 3.2). Durch Veränderung einzelner Bits wird über die Art des Ergeb- nisses der letzten Prozessoroperation Auskunft gegeben. Diese Auskunft wird hauptsächlich dazu benutzt, bedingte Sprünge vorzunehmen, d. h. je nach Ergebnis der Prüfung eines dieser Bedingungsbits die eine oder aber eine andere Aktion durchzu- führen. Die Stellung der einzelnen Bits innerhalb des Flag- Registers F zeigt folgende Tabelle: 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0 ---!---!---!---!---!---!---!--- S ! Z ! X ! H ! X !P/V! N ! C Hierbei bedeuten: C - Übertragsbit (Carry-Flag) N - Additions-/Subtraktionsbit (Add/Subtract-Flag) P/V - Paritäts-/Überlaufbit (Parity/Overflow-Flag) H - Halb-Byte-Überlaufbit (Half-Carry-Flag) Z - Nullbit (Zero-Flag) S - Vorzeichenbit (Sign-Flag) X - nicht verwendet Das Carry-Flag wird gesetzt (=1), wenn bei der Addition zweier Operanden ein Übertrag von Bit 7 entsteht, sowie wenn bei der Subtraktion ein Bit geborgt werden muß (das Ergebnis negativ wird). Darüber hinaus fungiert das Carry-Flag als Bit-Speicher bei Verschiebe- und Rotationsbefehlen. Das Zero-Flag wird gesetzt, wenn das Ergebnis einer Operation den Wert Null ergibt. Bei Einzelbitbefehlen dient es zur Übergabe ausgelesener Bits. Die Funktion des P/V-Flags hängt von der verwendeten Operation ab. Bei logischen und Verschiebebefehlen wird die Parität des Ergebnisses angezeigt (gerade Parität: P/V = 1; ungerade Parität P/V = 0). Bei arithmetischen Befehlen wird das P/V-Flag als Vorzeichen-Überlaufkennzeichnung benutzt; es wird z. B. gesetzt, wenn das Ergebnis zweier Vorzeichenzahlen außerhalb des zulässi- gen Bereiches von -128 bis +127 liegt. Das Sign-Flag zeigt nach Additionen und Subtraktionen an, ob das Ergebnis positiv ist (S = 0) oder negativ (S = 1). Das Half-Carry-Flag wirkt wie das Carry-Flag, jedoch wird der Übertrag von Bit 3 auf Bit 4 angezeigt. Mit dem Add/Subtract-Flag wird gekennzeichnet, ob als letzter Befehl eine Addition (N = 0) oder eine Subtraktion (N = 1) durch- geführt wurde. Die genaue Reaktion der Flags auf die einzelnen Befehle kann der Befehlsliste (Anhang A) entnommen werden. 3.4. Interruptsystem Soll der Rechner auf externe Ereignisse reagieren, so hat man die Möglichkeit, entweder den betreffenden Eingabekanal ständig abzu- fragen oder das laufende Programm mittels Interrupt zu unter- brechen, und nach Reaktion auf das Eingabesignal (Inter- ruptprogramm) das ursprüngliche Programm fortzusetzen. Die Tastaturabfrage im KC compact wird z.B. über Interrupt reali- siert. Die U880-CPU hat zwei getrennte Signaleingänge zur Auslösung von Interrupts: NMI - nichtmaskierbarer Interrupt höchster Priorität INT - maskierbarer Interrupt (kann in 3 verschiedenen Inter- rupt-Modi betrieben werden) 3.4.1. Nichtmaskierbarer Interrupt (NMI) ------------------------------------------ Die NMI-Signalzuführung kann nicht gesperrt werden. Ein NMI- Signal führt also in jedem Fall zu einer Unterbrechung des laufenden Programms und zu einem erzwungenen Unterprogrammsprung zur Speicheradresse 0066H. An dieser Stelle muß die Interruptbe- handlungsroutine vom Programmierer eingetragen sein. Die Inter- ruptroutine muß am Ende mit einem Rücksprung ins unterbrochene Programm (mit dem Befehl RETN) abgeschlossen werden. 3.4.2. Maskierbarer Interrupt (INT) ------------------------------------- Die INT-Signalzuführung kann mit Hilfe der Befehle EI - eingeschaltet (enable interrupt) und mittels DI - ausgeschaltet (disable interrupt) werden (maskieren). Ist das Interruptsystem nicht freigegeben (DI), so werden INT- Anforderungen ignoriert. Die Steuerung des INT-Eingangs der CPU erfolgt über zwei Merker IFF1 und IFF2 (Interruptflipflops). Der Befehl EI setzt beide auf 1 und DI beide auf 0. IFF2 dient als Merker der Stellung von IFF1 bei der NMI-Behandlung (während der NMI-Behandlung, d. h. bis RETN, ist kein INT möglich). Wird nun ein anstehendes INT-Signal erkannt, so führt die CPU hardwaremäßig eine DI-Operation aus, d. h. IFF1 und IFF2 werden auf 0 gesetzt. Sollen weiterhin Interrupts zugelassen werden, so ist spätestens vor Verlassen der Interruptbehandlungsroutine mit RETI der Befehl EI zu programmieren. Der maskierbare Interrupt INT kann in 3 Arbeitsweisen betrieben werden, die mit den Befehlen IM 0, IM 1 bzw. IM 2 eingeschaltet werden. Der KC compact arbeitet im Interrupt-Mode IM 1. Interrupt-Mode IM 0 ------------------- Wird ein INT-Signal akzeptiert, so wird gleichzeitig ein auf dem Datenbus vom Interruptauslöser (peripherer Baustein) bereitzu- stellender 1-Byte-Befehl eingelesen und anschließend ausgeführt. Im Normalfall werden dazu die Restart-Befehle RST n (n = 0, 8, #10, #18, #20, #28, #30, #38) verwendet, die einen Unterprogrammaufruf zur Speicheradresse n bewirken, an der die Interruptbehandlungsroutine beginnen muß. Interrupt-Mode IM 1 ------------------- Beim Akzeptieren des INT-Signals wird unabhängig von den anderen Eingängen ein Unterprogrammsprung zur Adresse #38 durchgeführt (ähnlich wie NMI). Der KC compact arbeitet in diesem Modus. Genauere Aussagen zum Interruptverhalten des KC compact lesen Sie bitte in /1/ nach. Interrupt-Mode IM 2 ------------------- Diese Betriebsart der CPU ist die leistungsfähigste und gestattet die individuelle Behandlung unterschiedlicher peripherer Bau- steine. Die Interruptbehandlung läuft nach folgendem Schema ab: In der CPU wird aus dem Wert des Interruptregisters I und dem vom peripheren Baustein auf dem Datenbus bereitzustellenden Inter- ruptvektor IV eine 16-Bit-Adresse gebildet. Das Interruptregister I bildet dabei den höherwertigen Adressteil und der Interrupt- vektor IV den niederwertigen. Von dieser und der folgenden Speicheradresse wird die eigentliche Startadresse der Interrupt- behandlungsroutine ausgelesen und ein Unterprogrammsprung dorthin durchgeführt. Die Interruptbehandlungsroutine muß mit RETI beendet werden, wobei ggf. zuvor das Interruptsystem mit EI einzuschalten ist. Mit dem Interruptregister I wird also die Lage der Tabelle der Startadressen für die Interruptbehandlungsroutinen im Speicher festgelegt. Durch den vom peripheren Baustein bereitgestellten Interruptvektor IV, der geradzahlig sein muß, wird eine der 128 möglichen Startadressen ausgewählt, an der die Interruptroutine beginnt. 3.5. Adressierungsarten Der Befehlssatz des Prozessors beinhaltet 6 verschiedene Adressierungsarten zur Bereitstellung von Register-, Speicher- oder Ein/Ausgabe-Adressen für zu spezifizierende Datenwörter: Direkte Adressierung -------------------- Der Operationscode beinhaltet vollständig die entsprechende Adresse. z.B.: LD A,B LD (#0200),HL Implizite Adressierung ---------------------- Der Operationscode bezieht sich fest auf bestimmte Speicherplätze oder Register. z.B.: EXX SCF Unmittelbare Adressierung ------------------------- Dem Operationscode folgt unmittelbar eine 8- oder 16-Bit-Kon- stante im Speicher. z.B.: LD A,6 XOR #20 Indirekte Adressierung ---------------------- Die 16-Bit-Adresse befindet sich in einem Registerpaar der CPU. Der Befehl bezieht sich indirekt auf diese Adresse. z.B.: LD A,(HL) LDIR Indizierte Adressierung ----------------------- Der Operationscode beinhaltet ein Datenbyte (zwischen -128 und +127), das zum Inhalt des Doppelregisters IX oder IY addiert die vollständige Adresse ergibt. z.B.: LD A,(IX+6) 3.6. Syntax der Assemblersprache Der hier beschriebene Assembler verarbeitet die ZILOG-Mne- monik (spezielle U880-Assembler-Mnemonik). Dabei gelten aller- dings einige Einschränkungen und Besonderheiten, auf die in diesem Abschnitt an entsprechender Stelle eingegangen wird. Ein Assemblerprogramm (Quellprogramm) besteht, wie schon erwähnt, aus einer Folge von Anweisungen (sog. Statements), die zusammen das Anwenderprogramm ergeben. Jede der Quellprogrammzeilen ist aus einem Markenfeld, einem Operationscodefeld (mnemonische Ausdrücke), einem Operandenfeld und einem Kommentarfeld aufge- baut. Beispiel für eine Quellprogrammzeile: Zeilen- Markenfeld Operations- Operanden- Kommentar- Nr. codefeld feld feld 10 START: LD A,6 ;Akku laden Je nach Art der Befehle können oder müssen einzelne dieser Felder wegfallen. Die einzelnen Felder müssen durch eine beliebige Anzahl von Leerzeichen oder Tabulatoren voneinander getrennt werden. Im Quellprogramm wird außer in Zeichenketten nicht zwischen Groß- und Kleinbuchstaben unterschieden. Die Zeile wird vom Assembler wie folgt verarbeitet: Als erstes wird immer das 1. Zeichen der Zeile untersucht. Folgende Fälle sind möglich: 1. Zeichen ! Bedeutung ----------------------------------------------------------------- ; ! die ganze Zeile ist Kommentar * ! das (die) folgende(n) Zeichen wird (werden) ! als Assembler-Kommando erwartet Zeilenende- ! markierung ! Leerzeile --> wird ignoriert Leerzeichen ! wird ignoriert, das nächste Zeichen wird ! untersucht Tabulator ! wird ignoriert, das nächste Zeichen wird ! untersucht ASCII ! Die Zeile wird nach einem nachfolgenden Leer- ! ,Tabulatorzeichen oder ':' untersucht. ! Bei ':' wird die Zeichenkette als Marke ! erkannt, bei Leer- oder Tabulatorzeichen ! versucht der Assembler, die Zeichenkette als ! Assemblerbefehl zu deuten. Nach der Verarbeitung der ersten Zeichenkette versucht der Assembler, die nächste Zeichenkette als Operation, falls vorher eine Marke erkannt wurde, oder als Operanden, falls vorher eine Operation erkannt wurde, die Operanden benötigt, zu deuten. Nach den Operanden wird dann ein Kommentar oder eine Zeilenendemar- kierung erwartet. 3.6.1. Zeilennummern -------------------- Vor jeder Quellprogrammzeile steht ähnlich wie in BASIC eine Zeilennummer. Diese dienen der eindeutigen Identifizierung von Quelltextzeilen, da ja der Editor zeilenorientiert arbeitet. Für die Zeilennummern ist der Zahlenbereich von 1 bis 32767 zulässig. 3.6.2. Marken ------------- Marken sind symbolische Bezugspunkte innerhalb des Programms. Sie werden verwendet, um in einer anderen Anweisung auf den momen- tanen Befehlszählerstand, auf eine andere Marke oder auf eine Konstante Bezug nehmen zu können. Eine Marke muß in der ersten Spalte der Programmzeile beginnen und kann bis zu 16 Zeichen lang sein, wobei nur die ersten 6 Zeichen signifikant sind. Das erste Zeichen muß ein Buchstabe sein, als weitere sind Buchstaben, Ziffern, und die Zeichen ^, _, -, ., ' zulässig. Marken müssen mit Doppelpunkt abgeschlossen werden. Ein Markenname (Bezeichner) darf selbst kein reserviertes Wort sein (s. Anhang E). Zulässige Bezeichner sind z.B.: LOOP: loop: Q^14_: LDIR: EINS-ZWEI-DREI: J': 3.6.3. Operationscodes ---------------------- Im Operationscodefeld steht eine der ZILOG Maschinenbefehls- mnemoniken oder eine der Assembler-Pseudoanweisungen. 3.6.4. Operanden ---------------- Je nach Art des Operationscodes muß das Operandenfeld entweder leer sein, oder es enthält einen oder zwei (durch ein Komma getrennte) Operanden, die eine Adresse (Speicher, Register oder Ein/Ausgabe-Kanal), eine Konstante oder eine Flag-Bedingung repräsentieren. Die Operanden ergänzen die jeweiligen Anweisungen durch eine Information darüber, mit welchen Parametern die Operation durchzuführen ist. Es sind folgende Schlüsselwörter für die Operandenfelder reser- viert - Die Namen der internen Register der CPU, die jeweils den 8- Bit-Inhalt eines dieser Register ansprechen. Die Registernamen sind: A, B, C, D, E, F, H, L, I und R. - Die Namen der Doppelregister und Registerpaare. Doppelregister sind die 16-Bit-Register IX, IY, SP und PC. Über die Regi- sterpaar-Bezeichnungen AF, BC, DE und HL lassen sich die oben bezeichneten 8-Bit-Register der CPU paarweise (als 16- Bit- Wörter) vom Assemblerbefehl ansprechen. - Die in der CPU integrierten Zweitregister werden in der Assemblersprache mit einem Hochkomma gekennzeichnet. Die Namen sind AF', BC', DE' und HL'. Von diesen Namen ist jedoch lediglich die Kombination AF' als Operand zulässig (in der Anweisung EX AF,AF'). - Der Zustand der 4 vom Assemblerprogramm testbaren Bedingungs- Bits wird in der Flag-Bedingung wie folgt notiert: Bedingungs-Bit- ! Bedingung ! Bedingung Bezeichnung ! erfüllt ! nicht erfüllt ! (Flag-Bit = 1)! (Flag-Bit = 0) -----------------!---------------!--------------- Übertrags-Bit ! C ! NC (Carry) ! ! -----------------!---------------!--------------- Null-Bit ! Z ! NZ (Zero) ! ! -----------------!---------------!--------------- Vorzeichen-Bit ! M ! P (Sign) ! (negativ) ! (positiv) -----------------!---------------!--------------- Paritäts-/ ! ! Überlauf-Bit ! PE ! PO (Parity/Overflow)! (gerade-even) !(ungerade-odd) ------------------------------------------------- (vgl. Abschn. 3.3.) Operanden können auch Ausdrücke sein. Sie bestehen aus einem oder mehreren Termen (Formelteilen), welche durch einen Operator getrennt sind. Für Terme sind folgende Schreibweisen zulässig: Dezimale Konstante z.B. 12102 Hexadezimale Konstante z.B. #FA02 Binäre Konstante z.B. %10101101 Zeichenkonstante z.B. "H" Namen z.B. LOOP23 Zusätzlich darf "$" für den momentanen Befehlszählerstand ver- wendet werden. Folgende Operatoren sind zulässig: + Addition - Subtraktion & logisches UND logisches ODER ! logisches XOR * Multiplikation / Division ? MOD-Funktion (a?b = a-(a/b)*b), d.h. Rest einer Division 3.6.5. Kommentare ----------------- Kommentare dienen Dokumentationszwecken und der Erhöhung der Übersichtlichkeit von Quellprogrammen. Sie sind kein funktionel- ler Bestandteil des Programms und werden beim Assemblier- vorgang übersprungen. Ein Kommentar darf in jeder Spalte der Programmzeile beginnen und er endet mit dem Zeilenende. Das erste Zeichen eines jeden Kommentars muß ein Semikolon ';' sein. 3.6.6. Pseudo-Befehle --------------------- Pseudooperationen sind Anweisungen an den Assembler zur Steuerung der Übersetzung des Quellprogramms. Es gibt daher zu Pseudo- oanweisungen keinen U880-Maschinencode. Sie sind aber wie ausfür- bare Anweisungen aufgebaut; können also mit einer Marke versehen und mit einem Kommentar beendet werden. Normalerweise beginnt ein Assemblerprogramm mit einer ORG-Pseudo- anweisung. Sie legt fest, auf welche Adresse der Beginn des Maschinenprogramms gelegt wird. Wird sie weggelassen, so legt der Assembler den Anfang auf den ersten freien Speicherplatz hinter dem Quelltext und der Markentabelle fest. Als Operand kann eine Marke, eine hexadezimale Zahl oder eine Verknüpfung stehen. Der Assembler verarbeitet folgende Pseudoanweisungen: ORG Ausdruck Setzt den Adreßzähler auf den Wert des Ausdrucks. Üblicherweise wird damit der Speicherbeginn eines Maschinenprogramms definiert. Würde beim Assemblieren durch die ORG-Anweisung 'ASSMON1', die Quelldatei oder die Markentabelle überschrieben, wird die Assemblierung abgebrochen und die Fehlermeldung 'Bad Org!' ausgegeben (siehe auch Abschnitt 3.8.1.). Marke EQU Ausdruck Weist der Marke den Wert des Ausdrucks zu. Damit kann im Assemblerprogramm mit symbolischen Bezeichnungen anstelle von Konstanten gearbeitet werden. Der Ausdruck darf kein Bezeichner sein, dem nicht nicht vorher schon ein Wert zugewiesen wurde. DEFB Ausdruck "Definiere Byte" - legt den durch den Ausdruck festgelegten Byte- Wert auf die nächste Speicherstelle (z.B. DEFB 25). DEFW Ausdruck "Definiere Wort" - legt den durch den Ausdruck festgelegten 2- Byte-Wert (Wort) auf die nächsten beiden Speicherstellen. Dabei wird zunächst das niederwertige Byte und danach das höherwertige Byte abgelegt. DEFM "Text" Legt die ASCII-Werte der durch 'Text' definierten Zeichenkette im Speicher ab. Die Zeichenkette muß in Hochkommas eingeschlossen sein. Z.B. DEFM "HALLO" legt die Bytefolge #48, #41, #4C, #4C, #4F in den Speicher. DEFS Ausdruck Reserviert einen Speicherbereich, dessen Länge durch den Ausdruck festgelegt wird, bzw. erhöht den Befehlszähler durch den Wert des Ausdrucks. Der reservierte Bereich wird mit Nullen gelöscht. ENT Ausdruck Legt die Startadresse des Maschinenprogramms fest. Diese Anwei- sung ist notwendig, um das übersetzte Programm zu Testzwecken von 'ASSMON1' aus mit 'R' zu starten. Fehlt die ENT-Anweisung, wird kein Ersatzwert eingetragen. 3.6.7. Bedingte Pseudo-Befehle ------------------------------ Bedingte Pseudo-Befehle ermöglichen es, Teile des Quellprogramms nur unter bestimmten Bedingungen assemblieren zu lassen, bzw. eine Verzweigung zu erreichen. Folgende Befehle sind möglich: IF Ausdruck Ergibt der Ausdruck den Wert Null, wird der Quelltext vom Assembler bis zu 'ELSE' oder 'END' ignoriert. Ist der Wert des Ausdrucks ungleich Null, wird die Assemblierung normal fortgesetzt. ELSE Durch 'ELSE' wird die Assemblierung fortgesetzt oder aufgehoben, je nachdem, ob der Ausdruck hinter 'IF' den Wert Null ergab oder nicht (siehe IF THEN ELSE in BASIC). END END schaltet das Ignorieren von Quelltext ab. Es ist zu beachten, daß 'IF ELSE END'-Konstruktionen nicht geschachtelt werden dürfen. 3.6.8. Assemblerkommandos ------------------------- Genau wie Pseudo-Befehle werden Assemblerkommandos nicht in Maschinencode übersetzt. Sie beeinflussen den Ausdruck der Assemblerliste, gestatten es, Quelltext vom Band zu assemblieren oder den assemblierten Maschinencode gleich während der Assem- blierung auf Band auszugeben. Das ist bei langen Quelltexten nützlich, oder wenn mehrere Quellen zusammen assembliert werden sollen. Assemblerkommandos werden durch ein vorangestelltes '*' in der Zeile gekennzeichnet. Der Buchstabe nach dem '*' bestimmt die Funktion und muß groß geschrieben werden. Einige Kommandos erwarten nach dem Buchstaben noch bestimmte Parameter, z.B. '+', '-' oder Zeichenketten. Außer '*F' werden alle Assemblerkommandos erst im 2. Assembler-Pass ausgewertet. Folgende Kommandos sind möglich: *L- Beginnend mit dieser Zeile wird die Auflistung unterdrückt. *L+ Beginnend mit dieser Zeile erfolgt wieder eine Auflistung. *D- Die Ausgabe des Befehlszählers erfolgt ab dieser Zeile hexadezimal. *D+ Die Ausgabe des Befehlszählers erfolgt ab dieser Zeile dezimal. *E Veranlaßt die Ausgabe von drei Leerzeilen auf dem Bildschirm, bzw. Blattvorschub bei Druckerausgabe. *Hs Der String s wird als Kopfzeile definiert und wird nach jedem '*E' ausgegeben. '*H' führt automatisch '*E' aus. *S Die Assemblierung (Auflistung) wird an dieser Stelle gestoppt. Durch Drücken einer beliebigen Taste wird die Assemblierung fortgesetzt. '*S' unterbricht das Assemblieren nicht, wenn '*L-' aktiv ist. *T+s Dieses Kommando bewirkt, daß der Objektcode während der Assemblierung auf Band ausgegeben wird. Mit s wird der Name der abzulegenden Maschinencode-Datei festgelegt. Durch '*T-', ORG-Anweisung oder Abschluß der Assemblierung wird die Bandausgabe beendet. *T- Beendet die Bandausgabe, die mit '*T+' begonnen wurde. *Fs Mit diesem wirkungsvollen Kommando kann Quelltext vom Band assembliert werden. Es besteht also die Möglichkeit, weit größere Quellprogramme (zerteilt in mehrere Stücke) zu assemblieren, als es die Größe des Quelltextspeichers (RAM) zuläßt. Der Name s der Datei, die eingefügt werden soll, darf bis zu acht Zeichen lang sein. Fehlt die Namensangabe, wird die erste auf Band gefundene Datei eingefügt. Bei jedem gefundenen '*F' wird der Bediener zum Einschalten des Recorders und dem Betätigen einer Taste aufge- fordert. Da die Datei bei beiden Assembler-Pässen eingelesen werden muß, muß nach dem ersten Pass zurückgespult werden oder die Datei muß sich zweimal hintereinander auf dem Band befinden. Wird ein Recorder ohne Motorschaltung verwendet, muß gegebenen- falls nach einem gelesenen Block einer Datei die Pausentaste am Recorder gedrückt werden, bis der gelesene Block assembliert wurde. Die so verwendeten Dateien sind mit dem Kommando 'P' des Editors auf Band zu speichern. 3.6.9. Markentabelle -------------------- Im ersten Assemblerlauf wird eine sogenannte Symbol- oder Markentabelle erstellt. Beim ersten Auftreten eines Namens (Marke) wird er zusammen mit dem Befehlszählerstand oder dem Wort in der 'EQU'-Anweisung und zwei Informationsbytes in der Tabelle abgelegt. Die beiden Informationsbytes dienen der alphabetischen Einordnung. Die Länge des Eintrags in der Tabelle hängt von der Namenslänge ab (8 bis 13 Bytes). Ist die Assemblierung beendet, wird die Größe der benötigten Markentabelle ausgegeben. Wurde ein Name nicht definiert oder wurde ihm kein Wert zugewiesen, wird am Ende die Meldung '*WARNING* symbol absent' ausgeben. 3.7. Befehlssatz des Assemblers In diesem Abschnitt wird der syntaktische Aufbau und die Wirkungsweise der einzelnen Assemblerbefehle beschrieben. Der U880-Prozessor verfügt über einen sehr umfangreichen Befehlssatz, der nicht nur 8-Bit-, sondern auch 16-Bit-Befehle umfaßt. Mit der großen Befehlsliste stehen dem Programmierer meist verschiedene Möglichkeiten zur Verfügung, ein und dasselbe Problem mehr oder weniger elegant zu lösen. Viel hängt dabei von der Übung und den Erfahrungen des Programmierers ab. Besonders zu beachten ist, daß z. B. verschiedene Assembler- befehle nur für spezielle Operanden gelten. Die Gültigkeit des verwendeten Befehls ist also anhand der in diesem Abschnitt angegebenen Übersicht über alle erlaubten Befehle sorgfältig zu überprüfen. Der Befehlssatz läßt sich in folgende Gruppen einteilen: - Lade- und Austauschbefehle - Blocktransfer- und Blocksuchbefehle - Arithmetik- und Logikbefehle - Programmverzweigungsbefehle - Unterprogrammbefehle - Rotations- und Verschiebebefehle - Einzelbitbefehle - Steuerbefehle - Ein- und Ausgabebefehle Die Ladebefehle transportieren Daten zwischen den Registern oder zwischen Registern und dem Speicher. Registeraustauschbefehle erschließen dem Programmierer die Hintergrundregister der CPU, Blocktransferbefehle transportieren ganze Datenblöcke zwischen verschiedenen Speicherbereichen. Mit einem Blocksuchbefehl kann man einen Speicherbereich nach einem Datenbyte durchmustern. Die Arithmetik- und Logikbefehle arbeiten mit einem Akkumulator (A, HL, IX oder IY) als ersten Operanden und einem Register, Speicherstelle oder Konstanten als zweiten Operanden. Das Ergebnis der Operation (z. B. einer Addition) steht wieder im Akkumulator und es werden die entsprechenden Flag-Bits gesetzt. Die Programmverzweigungsbefehle gestatten es, in Abhängigkeit von den Flag-Bits Sprünge (relative oder absolute) zu anderen Programmteilen durchzuführen. Im Unterschied zu den Sprungbefehlen bieten die Unterprogramm- befehle die Möglichkeit, nach Abarbeitung des aufgerufenen Programmstücks wieder das ursprüngliche Programm fortzusetzen. Die Rotations-, Verschiebe- und Einzelbitbefehle verwendet man, um den Inhalt einzelner Bits der Register oder von Speicher- stellen abzufragen oder zu verändern. Die Steuerbefehle dienen zur Beeinflussung des Interruptsystems der CPU. Mit den Ein- und Ausgabebefehlen kann man spezielle Toradressen zur Kommunikation mit externen Bausteinen (PIO, SIO, CTC) ansprechen und Daten ein- oder ausgeben. Der U880-Prozessor hat variable Befehlswortlänge (1 bis 4 Byte). Die Byteanzahl und die Kodierung der einzelnen Befehle kann man der Befehlscode-Tabelle im Anhang A entnehmen. Der Befehlscode erscheint auch im Listing des Assemblers. In den Abschnitten 3.7.1 bis 3.7.12 werden alle Assemblerbefehle und deren Wirkungsweise erläutert. Dabei werden die folgenden Abkürzungen verwendet: Abkürzungsverzeichnis: ----------------------- r, r' - Einfachregister A, B, C, D, E, H, L dd - Doppelregister BC, DE, HL, SP qq - Doppelregister AF, BC, DE, HL pp - Doppelregister BC, DE, SP n - 8-Bit-Konstante nn - 16-Bit-Konstante, Adresse d - Verschiebung bei Adressierung über Indexregister, im Bereich -128 = d = +127 b - Bit, das in den Einzelbitbefehlen behandelt werden soll, 0 = b = 7 (HL) - Inhalt des durch HL adressierten Speicherplatzes. Register L beinhaltet dabei die niederwertigen 8 Bits und Register H die höherwertigen 8 Bits der Adresse des Speicherplatzes. p - Einer der Werte #00,#08,#10,#18,#20,#28,#30,#38 CY - Carry-Flag T - Anzahl der Taktzyklen des Befehls Bei Befehlen, die Flag-Bedingungen für Programmsprünge auswerten sind 2 Taktzyklen angegeben. Dabei bezieht sich die zweite Zahl auf den Fall, daß kein Sprung durchgeführt und mit dem nächsten im Speicher stehenden Befehl weitergearbeitet wird. T*250 Nanosekunden ist die Befehlsausführungszeit auf dem KC compact. Flag-Beeinflussung der Befehle (s. 3.3.): ------------------------------------------ In der letzten Spalte der folgenden Befehlsübersicht ist für die einzelnen Flag-Bits C, N, P/V, H, Z, S deren Wert nach der Ausführung des Befehls angegeben. Dabei bedeutet: 1 - gesetzt (=1) 0 - zurückgesetzt (=0) - - unverändert * - entsprechend dem Ergebnis der Operation,d. h.: gesetzt wenn erfüllt, zurückgesetzt wenn nicht erfüllt x - unbestimmt V - Overflow-Funktion P - Parity-Funktion F - Inhalt des Interrupt-Flip-Flops IFF2 (vgl. Abschn 3.4.2) 3.7.1. 8-Bit-Ladebefehle ------------------------ Die Ladebefehle transportieren 8-Bit-Daten intern zwischen Registern oder zwischen Registern und dem Speicher. Dabei steht im Operandenfeld als erstes der Zielspeicherplatz und danach (durch Komma getrennt) der Quellspeicherplatz. Der Inhalt des Quellspeicherplatzes wird bei diesen Befehlen nicht verändert. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! LD r,r' ! 4! Inhalt des Registers r' wird in das Re- !------ ! ! gister r umgespeichert ! ! ! ! LD r,n ! 7! Die 8-Bit-Konstante n wird in das Regi- !------ ! ! ster r geladen ! ! ! ! LD r,(HL) ! 7! Inhalt des durch Registerpaar HL adres- !------ ! ! sierten Speicherplatzes wird in das ! ! ! Register r geladen. ! ! ! ! LD r,(IX+d)!19! Inhalt des durch Register IX (bzw. IY) !------ LD r,(IY+d)!19! plus Verschiebung d adressierten Spei- !------ ! ! cherplatzes wird in Register r geladen ! ! ! ! LD (HL),r ! 7! Transportiert ein Byte aus Register r !------ ! ! auf den durch Registerpaar HL adressier-! ! ! ten Speicherplatz. ! ! ! ! LD (IX+d),r!19! Bringt Daten aus dem Register r an den !------ LD (IY+d),r!19! Speicherplatz, dessen Adresse durch den !------ ! ! Inhalt des IX (bzw. IY)-Registers plus ! ! ! Verschiebung d spezifiziert ist ! ! ! ! LD (HL),n !10! Bewirkt den Transport der Konstanten n !------ ! ! an den durch Registerpaar HL adressier- ! ! ! ten Speicherplatz. ! ! ! ! LD (IX+d),n!19! Bewirkt den Transport der Konstanten n !------ LD (IY+d),n!19! an den Speicherplatz, dessen Adresse !------ ! ! durch den Inhalt des IX (bzw. IY)-Regi- ! ! ! sters plus Verschiebung d spezifiziert ! ! ! ist ! ! ! ! LD A,(BC) ! 7! Der Inhalt des durch Registerpaar BC !------ ! ! adressierten Speicherplatzes wird in ! ! ! den Akkumulator (A-Register) geladen ! ! ! ! LD A,(DE) ! 7! Der Inhalt des durch Registerpaar DE !------ ! ! adressierten Speicherplatzes wird in ! ! ! den Akkumulator (A-Register) geladen ! ! ! ! LD A,(nn) !13! Der Inhalt des Speicherplatzes nn wird !------ ! ! in den Akkumulator (A-Register) geladen ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ LD (nn),A !13! Der Inhalt des Akkumulators (A-Register)!------ ! ! wird auf den Speicherplatz nn geladen ! ! ! ! LD (BC),A ! 7! Der Inhalt des Akkumulators (A-Register)!------ ! ! wird auf den Speicherplatz geladen, ! ! ! dessen Adresse im Registerpaar BC steht ! ! ! ! LD (DE),A ! 7! Der Inhalt des Akkumulators (A-Register)!------ ! ! wird auf den Speicherplatz geladen, ! ! ! dessen Adresse im Registerpaar DE steht ! ! ! ! LD A,I ! 9! Der Inhalt des Interruptregisters I wird!**0F0- ! ! in den Akkumulator (A-Register) geladen ! ! ! ! LD A,R ! 9! Der Inhalt des Refresh-Registers I wird !**0F0- ! ! in den Akkumulator (A-Register) geladen ! ! ! ! LD I,A ! 9! Der Inhalt des Akkumulators (A-Register)!------ ! ! wird in das Interruptregister I geladen ! ! ! ! LD R,A ! 9! Der Inhalt des Akkumulators (A-Register)!------ ! ! wird in das Refresh-Register R geladen ! ! ! ! 3.7.2. 16-Bit-Ladebefehle ------------------------- Die 16-Bit-Ladebefehle transportieren 16-Bit-Daten intern zwischen den Registern oder zwischen Registern und dem Speicher. Der Inhalt des Quellspeichers wird dabei nicht verändert. Spezielle 16-Bit-Befehle sind die PUSH- und POP-Befehle. Mit Ihnen werden 16-Bit-Daten aus Doppelregistern in den Keller- speicher gebracht bzw. zurück in die Doppelregister geholt. Man verwendet sie häufig zum Retten von Registerinhalten z. B. in Unterprogrammen: UP: PUSH HL PUSH DE PUSH BC ... ) Unterprogramm- ... ) Befehle ... ) POP BC POP DE POP HL RET Nach Beendigung des Unterprogramms besitzen die Register BC, DE, HL die gleichen Inhalte wie vor dem Aufruf. Zu beachten ist, daß 16-Bit-Daten im Speicher auf 2 Byte mit aufeinanderfolgenden Adressen nn und nn+1 abgespeichert werden. Die unteren 8 Bit (niederwertiger Teil) stehen auf der Adresse nn und die oberen 8 Bit (höherwertiger Teil) auf der Adresse nn+1. Alle 16-Bit-Wörter (auch in Maschinencodes) werden vom Prozessor grundsätzlich auf diese Weise (erst niederwertiger, dann höher- wertiger Teil) abgespeichert. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! LD dd,nn !10! Die 16-Bit-Konstante nn wird in das Dop-!------ ! ! pelregister dd geladen ! ! ! ! LD IX,nn !14! Die 16-Bit-Konstante nn wird in das In- !------ LD IY,nn !14! dexregister IX (bzw. IY) geladen !------ ! ! ! LD HL,(nn)!16! Inhalt der Speicherplätze nn und nn+1 !------ ! ! wird in das Doppelregister HL geladen ! ! ! Inhalt von nn+1 --> Register H ! ! ! Inhalt von nn --> Register L ! ! ! ! LD pp,(nn)!20! Inhalt der Speicherplätze nn und nn+1 !------ ! ! wird in das Doppelregister pp geladen ! ! ! Inhalt von nn+1 --> höherwertiges Reg ! ! ! Inhalt von nn --> niederwertiges Reg! ! ! ! LD IX,(nn)!20! Inhalt der Speicherplätze nn und nn+1 !------ LD IY,(nn)!20! wird in das Indexregister IX (bzw. IY) !------ ! ! geladen ! ! ! Inhalt von nn+1 --> höherwert. Teil ! ! ! Inhalt von nn --> niederwert. Teil ! ! ! ! LD (nn),HL!16! Inhalt des Doppelregisters HL wird auf !------ ! ! die Adressen nn und nn+1 transportiert ! ! ! Register H --> Inhalt von nn+1 ! ! ! Register L --> Inhalt von nn ! ! ! ! LD (nn),pp!20! Inhalt des Doppelregisters pp wird auf !------ ! ! die Adressen nn und nn+1 transportiert ! ! ! höherwertiges Reg --> Inhalt von nn+1 ! ! ! niederwertiges Reg --> Inhalt von nn ! ! ! ! LD (nn),IX!20! Inhalt des Indexregisters IX (bzw. IY) !------ LD (nn),IY!20! wird auf die Adressen nn und nn+1 trans-!------ ! ! portiert ! ! ! höherwert. Teil --> Inhalt von nn+1 ! ! ! niederwert. Teil --> Inhalt von nn ! ! ! ! LD SP,HL ! 6! Inhalt des Doppelregisters HL wird in !------ ! ! den Stackpointer (Kellerzeiger) trans- ! ! ! portiert ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! LD SP,IX !10! Inhalt des Indexregisters IX (bzw. IY) !------ LD SP,IY !10! wird in den Stackpointer (Kellerzeiger) !------ ! ! transportiert ! ! ! ! PUSH qq !11! Inhalt des Doppelregisters qq wird in !------ ! ! Kellerspeicher (Stack) transportiert: ! ! ! erniedrigen von SP ! ! ! höherwertiges Reg --> Inhalt von SP-Adr ! ! ! erniedrigen von SP ! ! ! niederwertiges Reg --> Inhalt von SP-Adr! ! ! ! PUSH IX !15! Inhalt des Indexregisters IX (bzw. IY) !------ PUSH IY !15! wird in den Kellerspeicher (Stack) !------ ! ! transportiert: ! ! ! erniedrigen von SP ! ! ! höherwert. Teil --> Inhalt von SP-Adr ! ! ! erniedrigen von SP ! ! ! niederwert. Teil --> Inhalt von SP-Adr! ! ! ! POP qq !10! Inhalt der von Stackpointer SP adres- !------ ! ! sierten 2 Speicherstellen wird in das ! ! ! Doppelregister qq übertragen: ! ! ! Inhalt von SP-Adr --> niederwertiges Reg! ! ! erhöhen von SP ! ! ! Inhalt von SP-Adr --> höherwertiges Reg ! ! ! erhöhen von SP ! ! ! ! POP IX !14! Inhalt der von Stackpointer SP adres- !------ POP IY !14! sierten 2 Speicherstellen wird in das !------ ! ! Indexregister IX (bzw. IY) übertragen: ! ! ! Inhalt von SP-Adr --> niederwertig. Teil! ! ! erhöhen von SP ! ! ! Inhalt von SP-Adr --> höherwertig. Teil ! ! ! erhöhen von SP ! ! ! ! 3.7.3. Registeraustauschbefehle ------------------------------- Diese Befehle dienen dem schnellen Austausch von Doppelregister- inhalten und erschließen dem Programmierer die Hintergrund- register. Zum Beispiel UP: EXX ... ) Unterprogramm- ... ) Befehle ... ) EXX RET rettet die Registerinhalte BC, DE, HL für das Hauptprogramm. Im Unterschied zur Verwendung von PUSH und POP gehen die Inhalte der Hintergrundregister ggf. im Unterprogramm verloren. Durch den Befehl EX DE,HL kann für in DE enthaltene Adressen auch die indirekte Adressierung (über HL) verwendet werden. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! EX DE,HL ! 4! Die 16-Bit-Inhalte der Registerpaare DE !------ ! ! und HL werden ausgetauscht ! ! ! DE ---> HL ! ! ! ! EX AF,AF' ! 4! Die 16-Bit-Inhalte der Registerpaare AF !------ ! ! und AF' werden ausgetauscht ! ! ! AF ---> AF' ! ! ! ! EXX ! 4! Die 16-Bit-Inhalte der nachstehenden !------ ! ! Registerpaare werden ausgetauscht ! ! ! BC ---> BC' ! ! ! DE ---> DE' ! ! ! HL ---> HL' ! ! ! ! EX (SP),HL!19! Der Inhalt des Registers L wird gegen !------ ! ! den Inhalt der Speicherstelle ausge- ! ! ! tauscht, die durch den Inhalt des Stack-! ! ! pointers SP adressiert ist. Der Inhalt ! ! ! des Registers H wird gegen den Inhalt ! ! ! der Speicherstelle ausgetauscht, die ! ! ! durch den Inhalt des Stackpointers SP ! ! ! plus 1 adressiert ist. ! ! ! H ---> (SP+1) ! ! ! L ---> (SP) ! ! ! ! EX (SP),IX!23! Der niederwertige Teil des Indexregi- !------ ! ! ! EX (SP),IY!23! sters IX (bzw. IY) wird gegen den Inhalt!------ ! ! der Speicherstelle ausgetauscht, die ! ! ! durch den Inhalt des Stackpointers SP ! ! ! adressiert ist. Der höherwertige Teil ! ! ! des Indexregisters IX (bzw. IY) wird ! ! ! gegen den Inhalt der Speicherstelle aus-! ! ! getauscht, die durch den Inhalt des ! ! ! Stackpointers SP plus 1 adressiert ist. ! ! ! höherwertiger Teil ---> (SP+1) ! ! ! niederwertiger Teil ---> (SP) ! ! ! ! 3.7.4. Blocktransfer- und -suchbefehle -------------------------------------- Mit einem einzigen Befehl können beliebig große Datenmengen im Speicher verschoben werden, bzw. es kann in einem Speicherbereich nach einem Datenbyte gesucht werden. Die Suche wird dabei beendet, wenn das Byte gefunden wurde bzw. der gesamte Bereich durchsucht wurde. Beispiel: Die Befehlsfolge LD HL,#C000 LD DE,#C001 LD BC,#3FFF LD (HL),0 LDIR beschreibt den gesamten Bildwiederholspeicher mit Null-Bytes (löscht den Bildschirm mit PEN 0). Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! LDI !16! Transport eines Datenbytes von der Spei-!--0*0- ! ! cherstelle, die durch das Registerpaar ! ! ! HL adressiert wird nach der Speicher- ! ! ! stelle, die durch das Registerpaar DE ! ! ! adressiert wird. Die Register DE und HL ! ! ! werden um 1 erhöht, und das Register BC ! ! ! wird um 1 vermindert. ! ! ! BC = 0 --> PV = 0 ! ! ! BC > 0 --> PV = 1 ! ! ! ! LDIR !21! Transport mehrerer Datenbytes ab der !--000- !16! Speicherstelle, die durch das Register- ! ! ! paar HL adressiert wird nach der Spei- ! ! ! cherstelle, die durch das Registerpaar ! ! ! DE adressiert wird. Bie Byteanzahl ist ! ! ! im Registerpaar BC enthalten. Nach jeder! ! ! Byteübertragung wird der Inhalt von HL ! ! ! und von DE um 1 erhöht und BC um 1 ver- ! ! ! mindert. Die Übertragung endet, wenn ! ! ! der Inhalt von BC Null ist. ! ! ! ! LDD !16! Der Befehl wirkt wie LDI, nur werden die!--0*0- ! ! Register DE und HL um 1 vermindert ! ! ! ! LDDR !21! Der Befehl wirkt wie LDIR, nur werden !--000- !16! die Register DE und HL um 1 vermindert ! ! ! ! CPI !16! Vergleich des Inhalts des durch HL !****1- ! ! adressierten Speicherplatzes mit dem In-! ! ! halt des Akkumulators (A-Register): ! ! ! A = (HL) --> Z = 1 ! ! ! A > (HL) --> Z = 0 ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! ! ! Anschließend wird das Register HL um 1 ! ! ! erhöht und das Registerpaar BC um 1 ! ! ! vermindert. Das Registerpaar BC kann als! ! ! Bytezähler arbeiten: ! ! ! BC = 0 --> PV = 0 ! ! ! BC > 0 --> PV = 1 ! ! ! ! CPIR !21! Vergleich des Inhalts des Akkumulators !****1- !16! (A-Register) mit dem Inhalt eines adres-! ! ! sierten Speicherbereiches. Die Anfangs- ! ! ! adresse des Bereiches ist im Register- ! ! ! paar HL enthalten, Die Länge des Berei- ! ! ! ches im Registerpaar BC. Der Vergleich ! ! ! endet, wenn A = (HL) oder wenn BC = 0 ! ! ! ist. Der Befehl ist also ein wiederhol- ! ! ! ter Aufruf von CPI mit den Abbruchbedin-! ! ! gungen Z = 1 oder PV = 0. ! ! ! ! CPD !16! Der Befehl wirkt wie CPI, nur das Regi- !****1- ! ! ster HL wird vermindert ! ! ! ! CPDR !21! Der Befehl wirkt wie CPIR, nur das Regi-!****1- !16! ster HL wird vermindert ! ! ! ! 3.7.5. 8-Bit-Arithmetik- und -Logikbefehle ------------------------------------------ Diese Befehle arbeiten mit Daten, die sich im Akkumulator (Register A als ersten Operanden) und mit Daten in anderen Registern oder auf Speicherplätzen (als zweiten Operanden) befinden. Das Ergebnis dieser Operationen wird im Akkumulator abgelegt. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! ADD A,r ! 4! Der Inhalt von Register r wird zum Akku-!***V0* ! ! mulatorinhalt addiert ! ! ! ! ADD A,(HL) ! 7! Der Inhalt des durch das Registerpaar HL!***V0* ! ! adressierten Speicherplatzes wird zum ! ! ! Inhalt des Akkumulators addiert ! ! ! ! ADD A,n ! 7! Die Konstante n wird zum Inhalt des !***V0* ! ! Akkumulators addiert ! ! ! ! ADD A,(IX+d)!19! Der Inhalt des durch das Indexregister !***V0* ADD A,(IY+d)!19! IX (bzw. IY) plus Adreßverschiebung d !***V0* ! ! adressierten Speicherplatzes wird zum ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! ! ! Inhalt des Akkumulators addiert. Das Er-! ! ! gebnis steht im Akkumulator ! ! ! ! ADC A,r ! 4! Der Inhalt von Register r plus Carry- !***V0* ! ! Flag wird zum Akkumulatorinhalt addiert ! ! ! ! ADC A,(HL) ! 7! Der Inhalt des durch das Registerpaar HL!***V0* ! ! adressierten Speicherplatzes plus Carry-! ! ! Flag wird zum Inhalt des Akkumulators ! ! ! addiert ! ! ! ! ADC A,n ! 7! Die Konstante n plus Carry-Flag wird zum!***V0* ! ! Inhalt des Akkumulators addiert ! ! ! ! ADC A,(IX+d)!19! Der Inhalt des durch das Indexregister !***V0* ADC A,(IY+d)!19! IX (bzw. IY) plus Adreßverschiebung d !***V0* ! ! adressierten Speicherplatzes plus Carry-! ! ! Flag wird zum Inhalt des Akkumulators ! ! ! addiert. Das Ergebnis steht im Akkumula-! ! ! tor. ! ! ! ! SUB r ! 4! Der Inhalt von Register r wird vom Akku-!***V1* ! ! mulatorinhalt subtrahiert ! ! ! ! SUB (HL) ! 7! Der Inhalt des durch das Registerpaar HL!***V1* ! ! adressierten Speicherplatzes wird vom ! ! ! Inhalt des Akkumulators subtrahiert ! ! ! ! SUB n ! 7! Die Konstante n wird vom Inhalt des !***V1* ! ! Akkumulators subtrahiert ! ! ! ! SUB (IX+d)!19! Der Inhalt des durch das Indexregister !***V1* SUB (IY+d)!19! IX (bzw. IY) plus Adreßverschiebung d !***V1* ! ! adressierten Speicherplatzes wird vom ! ! ! Inhalt des Akkumulators subtrahiert. Das! ! ! Ergebnis steht im Akkumulator. ! ! ! ! SBC A,r ! 4! Der Inhalt von Register r plus Carry- !***V1* ! ! Flag wird vom Akkumulatorinhalt subtra- ! ! ! hiert ! ! ! ! SBC A,(HL) ! 7! Der Inhalt des durch das Registerpaar HL!***V1* ! ! adressierten Speicherplatzes plus Carry-! ! ! Flag wird vom Inhalt des Akkumulators ! ! ! subtrahiert ! ! ! ! SBC A,n ! 7! Die Konstante n plus Carry-Flag wird vom!***V1* ! ! Inhalt des Akkumulators subtrahiert ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! SBC A,(IX+d)!19! Der Inhalt des durch das Indexregister !***V1* SBC A,(IY+d)!19! IX (bzw. IY) plus Adreßverschiebung d !***V1* ! ! adressierten Speicherplatzes plus Carry-! ! ! Flag wird vom Inhalt des Akkumulators ! ! ! subtrahiert. Das Ergebnis steht im Akku-! ! ! mulator. ! ! ! ! AND r ! 4! Logische UND-Verknüpfung eines Regi- !**1P00 AND (HL) ! 7! sters, Speicherbytes oder Konstanten mit!**1P00 AND n ! 7! dem Akkumulator. Das spezifizierte Byte !**1P00 AND (IX+d)!19! wird bitweise mit dem Inhalt des Akkumu-!**1P00 AND (IY+d)!19! lators konjunktiv verknüpft. Das logi- !**1P00 ! ! sche UND ist nur dann 1, wenn beide Bits! ! ! 1 sind. ! ! ! ! OR r ! 4! Logische ODER-Verknüpfung eines Regi- !**0P00 OR (HL) ! 7! sters, Speicherbytes oder Konstanten mit!**0P00 OR n ! 7! dem Akkumulator. Das spezifizierte Byte !**0P00 OR (IX+d)!19! wird bitweise mit dem Inhalt des Akkumu-!**0P00 OR (IY+d)!19! lators disjunktiv verknüpft. Das logi- !**0P00 ! ! sche ODER ist nur dann 0, wenn beide ! ! ! Bits 0 sind. ! ! ! ! XOR r ! 4! Exklusiv-ODER-Verknüpfung eines Regi- !**0P00 XOR (HL) ! 7! sters, Speicherbytes oder Konstanten mit!**0P00 XOR n ! 7! dem Akkumulator. Das spezifizierte Byte !**0P00 XOR (IX+d)!19! wird bitweise mit dem Inhalt des Akkumu-!**0P00 XOR (IY+d)!19! lators exklusiv verknüpft. Das Exklu- !**0P00 ! ! siv-ODER ist dann 1, wenn ein Bit = 1 ! ! ! und das andere Bit = 0 ist. ! ! ! ! CP r ! 4! Der Inhalt eines Registers, eines Spei- !***V1* CP (HL) ! 7! cherbytes oder eine Konstante wird mit !***V1* CP n ! 7! dem Akkumulator verglichen. Der ur- !***V1* CP (IX+d)!19! sprüngliche Inhalt des Akkumulators !***V1* CP (IY+d)!19! bleibt dabei erhalten. Das Vergleichs- !***V1* ! ! ergebnis ist durch die Flag-Stellungen ! ! ! erkennbar. ! ! ! ! INC r ! 4! Der Inhalt des Registers r wird um 1 er-!***V0- ! ! höht ! ! ! ! INC (HL) !11! Der Inhalt des durch HL adressierten !***V0- ! ! Speicherplatzes wird um 1 erhöht ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! INC (IX+d)!23! Der Inhalt des durch IX (bzw. IY) plus !***V0- INC (IY+d)!23! Verschiebung d adressierten Speicher- !***V0- ! ! platzes wird um 1 erhöht ! ! ! ! DEC r ! 4! Der Inhalt des Registers r wird um 1 !***V1- ! ! vermindert ! ! ! ! DEC (HL) !11! Der Inhalt des durch HL adressierten !***V1- ! ! Speicherplatzes wird um 1 vermindert ! ! ! ! DEC (IX+d)!23! Der Inhalt des durch IX (bzw. IY) plus !***V1- DEC (IY+d)!23! Verschiebung d adressierten Speicher- !***V1- ! ! platzes wird um 1 vermindert ! ! ! ! DAA ! 4! Korrigiert nach Addition / Subtraktion !***P-* ! ! zweier gepackter BCD-Zahlen den Akkumu- ! ! ! latorinhalt so, daß im Akkumulator wie- ! ! ! der die gepackte BCD-Darstellung er- ! ! ! reicht wird ! ! ! ! CPL ! 4! Bitweises Negieren (Komplementieren) des!--1-1- ! ! Akkumulatorinhalts ! ! ! ! NEG ! 8! Subtrahieren des Akkumulatorinhalts von !***V1* ! ! Null. Entspricht wertmäßig dem Zweier- ! ! ! komplement ! ! ! ! CCF ! 4! Komplementieren des Carry-Flags !--x-0* ! ! ! SCF ! 4! Setzen des Carry-Flags !--0-01 ! ! ! 3.7.6. 16-Bit-Arithmetikbefehle ------------------------------- Arbeiten ähnlich wie die 8-Bit-Arithmetikbefehle, jedoch mit Doppelregistern. Als Akkumulator wird eines der Register HL, IX oder IY benutzt. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! ADD HL,dd !11! Der Inhalt des Registerpaares dd wird !--x-0* ! ! zum Inhalt des Registerpaares HL addiert! ! ! ! ADD IX,IX !15! Der Inhalt des Indexregistes IX (bzw.IY)!--x-0* ADD IY,IY !15! wird mit sich selbst addiert. Diese Ver-!--x-0* ! ! doppelung ist gleichbedeutend mit einer ! ! ! Linksverschiebung der 16 Bit um eine ! ! ! Position ! ! ! ! ADD IX,pp !15! Der Inhalt von pp wird zum Inhalt des !--x-0* ADD IY,pp !15! Indexregisters IX (bzw. IY) addiert !--x-0* ! ! ! ADC HL,dd !15! Der Inhalt von dd plus Carry-Flag wird !**xV0* ! ! zum Inhalt des Registerpaares HL addiert! ! ! ! SBC HL,dd !15! Der Inhalt von dd plus Carry-Flag wird !**xV1* ! ! vom Inhalt des Registerpaares HL subtra-! ! ! hiert ! ! ! ! INC dd ! 6! Der Inhalt des Doppelregisters dd wird !------ ! ! um 1 erhöht ! ! ! ! INC IX !10! Der Inhalt des Indexregisters IX (bzw. !------ INC IY !10! IY) wird um 1 erhöht !------ ! ! ! DEC dd ! 6! Der Inhalt des Doppelregisters dd wird !------ ! ! um 1 vermindert ! ! ! ! DEC IX !10! Der Inhalt des Indexregisters IX (bzw. !------ DEC IY !10! IY) wird um 1 vermindert !------ ! ! ! 3.7.7. Programmverzweigungsbefehle ---------------------------------- Es ist zwischen unbedingten und bedingten Sprüngen zu unter- scheiden. Es sind weiterhin relative Sprünge möglich, mit denen zu Marken in einer näheren Umgebung (-126 bis +129 Byte) um die Befehlsadresse verzweigt werden kann. Im Quellprogramm ist dabei zwar die absolute Adresse der Marke anzugeben, im Befehlscode aber erscheint nur die relative Verschiebung zum momentanen Befehlszählerstand. Das Maschinenprogramm wird damit unabhängig von seiner Lage im Speicher. Bei bedingten Sprüngen sind Flag-Bedingungen als Operanden anzugeben (s. Abschn. 3.3.), und es werden die entsprechenden Flag-Bits getestet. In Abhängigkeit von diesem Test wird der Sprungbefehl entweder ausgeführt oder ignoriert. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! JP nn !10! Unbedingter Sprung nach Adresse nn, in- !------ ! ! dem der Befehlzzähler PC mit nn geladen ! ! ! wird ! ! ! ! JP NZ,nn !10! Sprung nach Adresse nn, wenn das Z-Flag !------ ! ! gleich 0 ist ! ! ! ! JP Z,nn !10! Sprung nach Adresse nn, wenn das Z-Flag !------ ! ! gleich 1 ist ! ! ! ! JP NC,nn !10! Sprung nach Adresse nn, wenn das C-Flag !------ ! ! gleich 0 ist ! ! ! ! JP C,nn !10! Sprung nach Adresse nn, wenn das C-Flag !------ ! ! gleich 1 ist ! ! ! ! JP PO,nn !10! Sprung nach Adresse nn, wenn das P/V- !------ ! ! Flag gleich 0 ist ! ! ! ! JP PE,nn !10! Sprung nach Adresse nn, wenn das P/V- !------ ! ! Flag gleich 1 ist ! ! ! ! JP P,nn !10! Sprung nach Adresse nn, wenn das S-Flag !------ ! ! gleich 0 ist ! ! ! ! JP M,nn !10! Sprung nach Adresse nn, wenn das S-Flag !------ ! ! gleich 1 ist ! ! ! ! JR nn !12! Unbedingter relativer Sprung nach Adres-!------ ! ! se nn ! ! ! ! JR NZ,nn !12! Relativer Sprung nach Adresse nn, wenn !------ ! 7! das Z-Flag gleich 0 ist ! ! ! ! JR Z,nn !12! Relativer Sprung nach Adresse nn, wenn !------ ! 7! das Z-Flag gleich 1 ist ! ! ! ! JR NC,nn !12! Relativer Sprung nach Adresse nn, wenn !------ ! 7! das C-Flag gleich 0 ist ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================= ! ! ! JR C,nn !12! Relativer Sprung nach Adresse nn, wenn !------ ! 7! das C-Flag gleich 1 ist ! ! ! ! JP (HL) ! 4! Unbedingter Sprung zur Adresse, die im !------ ! ! Doppelregister HL steht ! ! ! ! JP (IX) ! 8! Unbedingter Sprung zur Adresse, die im !------ JP (IY) ! 8! Indexregister IX (bzw. IY) steht !------ ! ! ! DJNZ nn !13! Der Inhalt des Registers B wird um 1 !------ ! 8! vermindert. Bedingter relativer Sprung ! ! ! zur Adresse nn, wenn der Inhalt des Re- ! ! ! gisters B ungleich 0 ist. ! ! ! ! 3.7.8. Unterprogrammbefehle --------------------------- Es ist wie bei Sprungbefehlen zwischen bedingten und unbedingten Befehlen zu unterscheiden. Der Unterprogrammaufruf geschieht mit einem CALL-Befehl, bei dem, zusätzlich zum Programmsprung, die dem CALL-Befehl im Speicher folgende Adresse (Rückkehradresse) in den Kellerspeicher (Stack) gerettet wird. Wird nun das Unter- programm mit einem RET-Befehl abgeschlossen, so wird diese Rückkehradresse in den Befehlszähler aus dem Stack zurückgeladen, und das Programm wird an der alten Stelle fortgesetzt. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! CALL nn !17! Unbedingter Unterprogrammaufruf zur !------ ! ! Adresse nn. Die nach dem CALL-Befehl ! ! ! folgende Speicheradresse wird wie bei ! ! ! einem PUSH-Befehl in den Stack gerettet ! ! ! (Rückkehradresse). Danach erfolgt ein ! ! ! unbedingter Sprung zur Adresse nn, indem! ! ! der Befehlzzähler PC mit nn geladen ! ! ! wird ! ! ! ! CALL NZ,nn!17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das Z-Flag gleich 0 ist ! ! ! ! CALL Z,nn !17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das Z-Flag gleich 1 ist ! ! ! ! CALL NC,nn!17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das C-Flag gleich 0 ist ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! CALL C,nn !17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das C-Flag gleich 1 ist ! ! ! ! CALL PO,nn!17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das P/V-Flag gleich 0 ist ! ! ! ! CALL PE,nn!17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das P/V-Flag gleich 1 ist ! ! ! ! CALL P,nn !17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das S-Flag gleich 0 ist ! ! ! ! CALL M,nn !17! Unterprogrammaufruf zur Adresse nn, wenn!------ !10! das S-Flag gleich 1 ist ! ! ! ! RST p !11! Der RST-Befehl ist ein spezieller Unter-!------ ! ! programmaufruf. Es sind folgende 8 Re- ! ! ! start-Adressen zugelassen: ! ! ! p = #00,#08,#10,#18,#20,#28,#30,#38 ! ! ! Der höherwertige Adreßteil ist dabei ! ! ! stets 0. Der RST-Befehl entspricht in ! ! ! seiner weiteren Wirkung dem unbedingten ! ! ! Unterprogrammaufruf. ! ! ! ! RET !10! Unbedingter Unterprogrammrücksprung. !------ ! ! Die Ausführung erfolgt, indem die ! ! ! Rückkehradresse wie bei einem POP-Be- ! ! ! fehl aus dem Stack geholt und in den Be-! ! ! fehlszähler PC geladen wird. ! ! ! ! RET NZ !11! Unterprogrammrücksprung, wenn das Z- !------ ! 5! Flag gleich 0 ist ! ! ! ! RET Z !11! Unterprogrammrücksprung, wenn das Z- !------ ! 5! Flag gleich 1 ist ! ! ! ! RET NC !11! Unterprogrammrücksprung, wenn das C- !------ ! 5! Flag gleich 0 ist ! ! ! ! RET C !11! Unterprogrammrücksprung, wenn das C- !------ ! 5! Flag gleich 1 ist ! ! ! ! RET PO !11! Unterprogrammrücksprung, wenn das P/V- !------ ! 5! Flag gleich 0 ist ! ! ! ! RET PE !11! Unterprogrammrücksprung, wenn das P/V- !------ ! 5! Flag gleich 1 ist ! ! ! ! RET P !11! Unterprogrammrücksprung, wenn das S- !------ ! 5! Flag gleich 0 ist ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! RET M !11! Unterprogrammrücksprung, wenn das S- !------ ! 5! Flag gleich 1 ist ! ! ! ! RETI !14! Es erfolgt ein Rücksprung aus einer In- !------ ! ! terruptbehandlungsroutine, die durch ei-! ! ! nen maskierbaren Interrupt ausgelöst ! ! ! wurde. Dem peripheren Baustein, der den ! ! ! Interrupt auslöste, wird das Ende sei- ! ! ! nes Programms mitgeteilt. Der Baustein ! ! ! gibt daraufhin die von ihm blockierte ! ! ! Interrupt-Kette wieder frei und ermög- ! ! ! licht damit die Abarbeitung niederwerti-! ! ! ger Interrupts. ! ! ! Durch die RETI-Anweisung wird der mas- ! ! ! kierbare Interrupt nicht freigegeben. Es! ! ! sollte deshalb vor jeder RETI-Anweisung ! ! ! ein EI-Befehl stehen, der die Annahme ! ! ! später folgender Interruptanforderungen ! ! ! ermöglicht. ! ! ! ! RETN !14! Es erfolgt ein Rücksprung aus einer In- !------ ! ! terruptbehandlungsroutine, die durch ei-! ! ! nen nichtmaskierbaren Interrupt (NMI) ! ! ! ausgelöst wurde. Die Anweisung wirkt ! ! ! zunächst wie ein RET-Anweisung. Zu- ! ! ! sätzlich wird der Inhalt von IFF2 nach ! ! ! IFF1 übertragen, so daß die Abarbei- ! ! ! tung maskierbarer Interrupts unmittelbar! ! ! nach Ausführung des RETN-Befehls frei- ! ! ! gegeben ist, falls sie vor der NMI-An- ! ! ! forderung freigegeben war. ! 3.7.9. Rotations- und Verschiebebefehle --------------------------------------- Durch diese Befehle wird die Möglichkeit gegeben, im Akkumulator (Register A), in einem anderen Register oder in einem Speicher- platz Daten einfach zyklisch (bitweise) zu verschieben. Das aus dem Byte herausgeschobene Bit wird dabei im Carry-Flag abgelegt. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! RLCA ! 4! Linksrotation des Akkumulatorinhalts. !--0-0* ! ! Der Inhalt des Akkumulators wird um eine! ! ! Bitposition nach links verschoben. Das ! ! ! höchstwertige Bit 7 wird zum Inhalt des ! ! ! Bits 0 und des Carry-Flags. ! ! ! ! ! ! -----------> ! ! ! ! ! ! ! ! CY ----B7 ----B0 - ! ! ! ! RRCA ! 4! Rechtsrotation des Akkumulatorinhalts. !--0-0* ! ! Der Inhalt des Akkumulators wird um eine! ! ! Bitposition nach rechts verschoben. Das ! ! ! niederwertige Bit 0 wird zum Inhalt des ! ! ! Bits 7 und des Carry-Flags. ! ! ! ! ! ! ----------- ! ! ! ! ! ! ! ! ->B7---->B0---->CY ! ! ! ! RLA ! 4! Linksrotation des Akkumulatorinhalts !--0-0* ! ! durch das Carry-Flag. Der Inhalt des Ak-! ! ! kumulators wird um eine Bitposition nach! ! ! links verschoben. Das höchstwertige Bit ! ! ! 7 ersetzt das Carry-Flag, während das ! ! ! Carry-Flag das Bit 0 des Akkumulators ! ! ! ersetzt. ! ! ! ! ! ! -----------------> ! ! ! ! ! ! ! ! -CY ----B7 ----B0- ! ! ! ! RRA ! 4! Rechtsrotation des Akkumulatorinhalts !--0-0* ! ! durch das Carry-Flag. Der Inhalt des Ak-! ! ! kumulators wird um eine Bitposition nach! ! ! rechts verschoben. Das niederwertigste ! ! ! Bit 0 ersetzt das Carry-Flag, während ! ! ! das Carry-Flag das Bit 7 des Akkumula- ! ! ! tors ersetzt. ! ! ! ! ! ! ----------------- ! ! ! ! ! ! ! ! -B7---->B0---->CY- ! ! ! ! RLC r ! 8! Linksrotation eines Registers oder !**0P0* RLC (HL) !15! Speicherbytes analog dem Befehl RLCA !**0P0* RLC (IX+d)!23! !**0P0* RLC (IY+d)!23! !**0P0* Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! ! ! ! RRC r ! 8! Rechtsrotation eines Registers oder !**0P0* RRC (HL) !15! Speicherbytes analog dem Befehl RRCA !**0P0* RRC (IX+d)!23! !**0P0* RRC (IY+d)!23! !**0P0* ! ! ! RL r ! 8! Linksrotation eines Registers oder !**0P0* RL (HL) !15! Speicherbytes durch das Carry-Flag !**0P0* RL (IX+d) !23! analog dem Befehl RLA !**0P0* RL (IY+d) !23! !**0P0* ! ! ! RR r ! 8! Rechtsrotation eines Registers oder !**0P0* RR (HL) !15! Speicherbytes durch das Carry-Flag !**0P0* RR (IX+d) !23! analog dem Befehl RRA !**0P0* RR (IY+d) !23! !**0P0* ! ! ! SRA r ! 8! Rechtsverschiebung eines Registers oder !**0P0* SRA (HL) !15! Speicherbytes um ein Bit durch das !**0P0* SRA (IX+d)!23! Carry-Flag. Der Inhalt des höchstwerti- !**0P0* SRA (IY+d)!23! gen Bit 7 bleibt erhalten. !**0P0* ! ! ! ! ! --> ! ! ! ! ! ! ! ! -B7---->B0---->CY ! ! ! ! SLA r ! 8! Linksverschiebung eines Registers oder !**0P0* SLA (HL) !15! Speicherbytes um ein Bit durch das !**0P0* SLA (IX+d)!23! Carry-Flag. Das niederwertige Bit 0 !**0P0* SLA (IY+d)!23! wird 0. !**0P0* ! ! ! ! ! CY ----B7 ----B0 ----0 ! ! ! ! SRL r ! 8! Rechtsverschiebung eines Registers oder !**0P0* SRL (HL) !15! Speicherbytes um ein Bit durch das !**0P0* SRL (IX+d)!23! Carry-Flag. Das höchstwertige Bit 7 !**0P0* SRL (IY+d)!23! wird 0. !**0P0* ! ! ! ! ! 0---->B7---->B0---->CY ! ! ! ! RLD !18! Zyklische Verschiebung nach links zwi- !**0P0- ! ! schen dem Akkumulator und dem Inhalt des! ! ! durch HL adressierten Speicherplatzes. ! ! ! Die unteren 4 Bit des durch HL adres- ! ! ! sierten Speicherplatzes werden in die ! ! ! oberen 4 Bitstellen übertragen und ! ! ! diese ihrerseits in die unteren 4 Bit- ! ! ! stellen des Akkumulators. Die unteren 4 ! ! ! Bits des Akkumulators werden in die un- ! ! ! teren 4 Bitstellen der Speicherstelle ! ! ! transportiert. Die oberen 4 Bits des Ak-! ! ! kumulators bleiben unberührt. ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! RRD !18! Zyklische Verschiebung nach rechts zwi- !**0P0- ! ! schen dem Akkumulator und dem Inhalt des! ! ! durch HL adressierten Speicherplatzes. ! ! ! Die unteren 4 Bit des durch HL adres- ! ! ! sierten Speicherplatzes werden in die ! ! ! unteren 4 Bitstellen des Akkumulators ! ! ! übertragen und diese in die oberen der ! ! ! durch HL adressierten Speicherstelle. ! ! ! Die oberen 4 Bits der durch HL adres- ! ! ! sierten Speicherstelle werden in die un-! ! ! teren 4 Bitstellen transportiert. Die ! ! ! oberen 4 Bits des Akkumulators bleiben ! ! ! unberührt. ! ! ! ! 3.7.10. Einzelbitbefehle ------------------------ Diese Befehle erlauben es, einzelne Bits in Registern oder auf Speicherplätzen zu testen, zu setzen oder zu löschen. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! BIT b,r ! 8! Die durch b gekennzeichnete Bitposition !x*1x0- ! ! wird in dem Register r getestet. Das ! ! ! Komplement des zu testenden Bits wird in! ! ! das Z-Flag geladen. ! ! ! ! BIT b,(HL) !12! Die durch b gekennzeichnete Bitposition !x*1x0- ! ! wird in der Speicherstelle getestet, die! ! ! durch das Register HL adressiert ist. ! ! ! Das Komplement des zu testenden Bits ! ! ! wird in das Z-Flag geladen. ! ! ! ! BIT b,(IX+d)!20! Die durch b gekennzeichnete Bitposition !x*1x0- BIT b,(IY+d)!20! wird in der Speicherstelle getestet, die!x*1x0- ! ! durch das Indexregister IX (bzw. IY) ! ! ! plus Verschiebung d adressiert ist. Das ! ! ! Komplement des zu testenden Bits wird in! ! ! das Z-Flag geladen. ! ! ! ! SET b,r ! 8! Die durch b gekennzeichnete Bitposition !------ ! ! wird in dem Register r gesetzt (auf 1) ! ! ! ! SET b,(HL) !15! Die durch b gekennzeichnete Bitposition !------ ! ! wird in der Speicherstelle gesetzt, die ! ! ! durch das Register HL adressiert ist ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! SET b,(IX+d)!23! Die durch b gekennzeichnete Bitposition !------ SET b,(IY+d)!23! wird in der Speicherstelle gesetzt, die !------ ! ! durch das Indexregister IX (bzw. IY) ! ! ! plus Verschiebung d adressiert ist ! ! ! ! RES b,r ! 8! Die durch b gekennzeichnete Bitposition !------ ! ! wird in dem Register r gelöscht (Null) ! ! ! ! RES b,(HL) !15! Die durch b gekennzeichnete Bitposition !------ ! ! wird in der Speicherstelle gelöscht, ! ! ! die durch das Register HL adressiert ist! ! ! ! RES b,(IX+d)!23! Die durch b gekennzeichnete Bitposition !------ RES b,(IY+d)!23! wird in der Speicherstelle gelöscht, !------ ! ! die durch das Indexregister IX (bzw. IY)! ! ! plus Verschiebung d adressiert ist ! ! ! ! 3.7.11. CPU-Steuerbefehle ------------------------- Diese Befehle dienen zur Steuerung des Interruptsystems der CPU. Der Interruptmodus ist im KC compact auf IM 2 eingestellt. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! NOP ! 4! Die CPU führt keine Operation aus. Es !------ ! ! werden aber Refresh-Zyklen erzeugt. ! ! ! ! HALT ! 4! Die CPU führt solange eine Folge von !------ ! ! NOP-Befehlen aus, bis ein Interrupt oder! ! ! der RESET-Eingang an der CPU aktiv wird.! ! ! Es werden Refresh-Zyklen erzeugt. ! ! ! ! DI ! 4! Der maskierbare Interrupt wird durch !------ ! ! Rücksetzen der Interrupt-Freigabe-Flip- ! ! ! Flops IFF1 und IFF2 der CPU gesperrt. ! ! ! Nichtmaskierbare Interrupts werden aner-! ! ! kannt. ! ! ! ! EI ! 4! Der maskierbare Interrupt wird durch !------ ! ! Setzen der Interrupt-Freigabe-Flip-Flops! ! ! IFF1 und IFF2 der CPU freigegeben. ! ! ! Während der Ausführung des Befehls ! ! ! akzeptiert die CPU keine Interruptanfor-! ! ! derungen. ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! IM 0 ! 8! Der Befehl bringt die CPU in den !------ ! ! Interruptmodus 0 ! ! ! ! IM 1 ! 8! Der Befehl bringt die CPU in den !------ ! ! Interruptmodus 1 ! ! ! ! IM 2 ! 8! Der Befehl bringt die CPU in den !------ ! ! Interruptmodus 2 ! ! ! ! 3.7.12. Ein- und Ausgabebefehle ------------------------------- Mit diesen Befehlen können Datenbytes zwischen Registern oder Speicheradressen und externen Bausteinen ausgetauscht werden. Der externe Baustein wird dabei über eine sog. Portadresse (8-Bit- Wert) angesprochen. Diese Portadresse wird je nach Befehl entweder direkt angegeben (als Konstante) oder muß im Register C zur Verfügung stehen. Ähnlich den Blocktransferbefehlen existie- ren auch hier Befehle für die Daten-Ein- und -Ausgabe ganzer Speicherbereiche. Diese können beim KC compact nicht verwendet werden, da nicht wie üblich im Register C sondern im Register B die Kanaladresse bereitgestellt werden muß (siehe /1/). Bei den Befehlen INI, INIR, IND, INDR, OUTI, OTIR, OUTD und OTDR wird außerdem B als Zählregister verwendet, und die Kanaladresse würde damit nach jedem IN/OUT um 1 dekrementiert. Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! IN A,(n) !11! Die Eingabekanaladresse wird mittels der!------ ! ! Konstanten n eingestellt. Zielregister ! ! ! ist der Akkumulator. ! ! ! (n) --> A ! ! ! ! IN r,(C) !12! Die Eingabekanaladresse wird indirekt !**0P0- ! ! über das Register C eingestellt. Ziel- ! ! ! register ist r. ! ! ! (C) --> r ! ! ! ! INI !16! Die Eingabekanaladresse wird indirekt !x*xx1- ! ! über das Register C eingestellt. Ziel- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B kann als Bytezähler ! ! ! arbeiten. ! ! ! B wird um 1 vermindert, HL um 1 erhöht. ! ! ! (C) --> (HL) ! ! ! B-1 --> B ! ! ! HL+1 --> HL ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! INIR !21! Die Eingabekanaladresse wird indirekt !x1xx1- !16! über das Register C eingestellt. Ziel- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B arbeitet als Bytezähler! ! ! B wird um 1 vermindert, HL um 1 erhöht. ! ! ! Es wird eine Blockübertragung durchge- ! ! ! führt bis B = 0 ist. ! ! ! (C) --> (HL) ! ! ! B-1 --> B ! ! ! HL+1 --> HL ! ! ! Wiederholen bis B = 0 ! ! ! ! IND !16! Die Eingabekanaladresse wird indirekt !x*xx1- ! ! über das Register C eingestellt. Ziel- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B kann als Bytezähler ! ! ! arbeiten. ! ! ! B und HL werden um 1 vermindert. ! ! ! (C) --> (HL) ! ! ! B-1 --> B ! ! ! HL-1 --> HL ! ! ! ! INDR !21! Die Eingabekanaladresse wird indirekt !x1xx1- !16! über das Register C eingestellt. Ziel- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B arbeitet als Bytezähler! ! ! B und HL werden um 1 vermindert. ! ! ! Es wird eine Blockübertragung durchge- ! ! ! führt bis B = 0 ist. ! ! ! (C) --> (HL) ! ! ! B-1 --> B ! ! ! HL-1 --> HL ! ! ! Wiederholen bis B = 0 ! ! ! ! OUT (n),A !11! Die Ausgabekanaladresse wird mittels der!------ ! ! Konstanten n eingestellt. Quellregister ! ! ! ist der Akkumulator. ! ! ! A --> (n) ! ! ! ! OUT (C),r !12! Die Ausgabekanaladresse wird indirekt !------ ! ! über das Register C eingestellt. Quell- ! ! ! register ist r. ! ! ! r --> (C) ! ! ! ! Mnemonik ! T! Wirkungsweise des Befehls !SZHPNC ! ! ! V ================================================================ ! ! ! OUTI !16! Die Ausgabekanaladresse wird indirekt !x*xx1- ! ! über das Register C eingestellt. Quell- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B kann als Bytezähler ! ! ! arbeiten. ! ! ! B wird um 1 vermindert, HL um 1 erhöht. ! ! ! (HL) --> (C) ! ! ! B-1 --> B ! ! ! HL+1 --> HL ! ! ! ! OTIR !21! Die Ausgabekanaladresse wird indirekt !x1xx1- !16! über das Register C eingestellt. Quell- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B arbeitet als Bytezähler! ! ! B wird um 1 vermindert, HL um 1 erhöht. ! ! ! Es wird eine Blockübertragung durchge- ! ! ! führt bis B = 0 ist. ! ! ! (HL) --> (C) ! ! ! B-1 --> B ! ! ! HL+1 --> HL ! ! ! Wiederholen bis B = 0 ! ! ! ! OUTD !16! Die Ausgabekanaladresse wird indirekt !x*xx1- ! ! über das Register C eingestellt. Quell- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B kann als Bytezähler ! ! ! arbeiten. ! ! ! B und HL werden um 1 vermindert. ! ! ! (HL) --> (C) ! ! ! B-1 --> B ! ! ! HL-1 --> HL ! ! ! ! OTDR !21! Die Ausgabekanaladresse wird indirekt !x1xx1- !16! über das Register C eingestellt. Quell- ! ! ! adresse ist der durch HL adressierte ! ! ! Speicherplatz. B arbeitet als Bytezähler! ! ! arbeiten. ! ! ! B und HL werden um 1 vermindert. ! ! ! Es wird eine Blockübertragung durchge- ! ! ! führt bis B = 0 ist. ! ! ! (HL) --> (C) ! ! ! B-1 --> B ! ! ! HL-1 --> HL ! ! ! Wiederholen bis B = 0 ! ! ! ! 3.8. Abarbeitung des Assemblers Der Assembler wird mit 'A' im Editor gestartet. Als erstes wird die, für die Markentabelle zu reservierende, Speichergröße abge- fragt. In der Regel reicht hier die Betätigung der ^RETURN_- Taste. Damit wird nämlich ein von der Länge des Quelltextes abhängiger Durchschnittswert verwendet. Wird aber mit der 'include'-Option (Assembler-Kommando '*F') gearbeitet, reicht dieser Wert in der Regel nicht aus, und es muß bei 'Table size:' ein größerer Wert angegeben werden. Als zweites wird nach Assembler-Optionen gefragt. 3.8.1. Assembler-Optionen ------------------------- Es ist die gewünschte Optionsnummer einzugeben. Sollen mehrere Optionen gesetzt werden, sind deren Nummern zu addieren. Soll z.B. nur die Markentabelle auf dem Drucker ausgegeben werden, wird die Option 15 (1+2+4+8) angegeben. Folgende Optionen sind möglich: Options-Nummer ! Bedeutung ----------------------------------------------------------------- 1 ! Markentabelle am Ende des 2. Passes ausgeben 2 ! Objektcodegenerierung unterdrücken 4 ! Assemblerlistenausgabe unterdrücken 8 ! Ausgabe der Assemblerliste auf den Drucker 16 ! Objektcode hinter der Markentabelle ablegen, ! auch wenn mit 'ORG' ein anderer Bereich ! festgelegt wird, so daß der Code zwar in einem ! Speicherbereich abgelegt wird aber nur auf ! einem anderem lauffähig ist ('ENT' wird außer ! Kraft gesetzt) . 32 ! nicht prüfen, wo der Objektcode abgelegt wird ! --> Beschleunigung der Assemblierung 3.8.2. Fehlermeldungen ---------------------- Neben der Markentabellenerstellung wird im ersten Assemblerlauf auf Fehler geprüft. Bei einer Fehlererkennung wird die Fehler- zeile und die Fehlernummer (siehe Anhang D) ausgegeben. Hier kann mit ^ESC_ in den Editor zurückgekehrt oder mit jeder anderen Taste die Assemblierung fortgesetzt werden. Nach Beenden des ersten Passes erfolgt die Meldung: Pass 1 errors: nn 3.8.3. Assemblerliste --------------------- Während des zweiten Assemblerpasses kann neben der Objektcode- generierung eine Assemblerliste ausgegeben werden. Form der Liste: Spalte 1 Spalte 2 Spalte 3 Spalte 4 Spalte 5 Spalte 6 (Stelle 1)(Stelle 6)(Stelle 15)(Stelle 21)(Stelle 28)(Stelle 33) z.B. 2800 C5 130 LOOP: PUSH BC Bedeutung der Spalten: Spalte ! Bedeutung ----------------------------------------------------------------- 1 ! Wert des Befehlszählers, außer bei ORG, ENT und EQU, ! wo der Operandenwert in Spalte 1 ausgegeben wird 2 ! generierter Objektcode (bis zu acht Zeichen = 4 Bytes) 3 ! Zeilennummer 4 ! Name, falls vorhanden 5 ! Assemblerbefehl 6 ! Operanden und Kommentare Durch beliebige Tastenbetätigung kann die Auflistung unterbrochen werden. Mit ^ESC_ kann in den Editor zurückgekehrt und mit jeder anderen Taste die Auflistung fortgesetzt werden. Am Ende wird ausgegeben: Pass 2 errors: nn Markentabelle (wenn Option 1 gesetzt war) Table used: xxxxx from yyyyy Executes: nnnnn 'Table used:' gibt die gebrauchte und die reservierte Speichergröße der Markentabelle an. 'Executes:' zeigt dezimal den Befehlszählerstand für das Startkommando 'R' des Editors an. ASSMON # 4. Disassembler / Debugger 4. D i s a s s e m b l e r / D e b u g g e r 4.1. Einführung Mit ASSMON2 werden dem Assemblerprogrammierer ein Disassembler und viele notwendige Debuggerfunktionen bereitgestellt. Die Bedienung des Programms erfolgt über die Eingabe von Kommando- Buchstaben. Nach jedem Kommando werden alle Bildschirmausgaben aktualisiert. Einige Kommandos verlangen die Eingabe einer hexadezimalen Zahl. Werden hier mehr als 4 Ziffern eingegeben, werden nur die vier zuletzt eingegebenen Ziffern beachtet. 4.2. Bildschirmausgaben Nach dem Laden des Programms und der ersten Ausschrift wird das folgende Bild aufgebaut: X+00 yyyyyyyy zzzzzzzzzzzzzzzz PC AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 SP AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 IY AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 IX AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 HL AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 DE AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 BC AAAA a1 a2 a3 a4 a5 a6 a7 a8 a9 AF AAAA ffffffff IR AAAA X-12 xx X-04 xx X+04 xx X+12 xx X-11 xx X-03 xx X+05 xx X+13 xx X-10 xx X-02 xx X+06 xx X+14 xx X-09 xx X-01 xx X+07 xx X+15 xx X-08 xx >X+00 xx X+08 xx X+16 xx X-07 xx X+01 xx X+09 xx X+17 xx X-06 xx X+02 xx X+10 xx X+18 xx X-05 xx X+03 xx X+11 xx X+19 xx > Erklärungen: X+00 - Adresse, auf die der Speicherzeiger weist xx - Inhalt der Adresse links daneben y...y - aktuelle Befehlsbytes (1-4) z...z - Mnemonik des aktuellen Befehls AAAA - Inhalt des links daneben stehenden Registerpaars a1-a9 - Inhalt der Adresse AAAA links daneben, sowie Inhalte der folgenden Adressen f...f - gesetzte Flags 4.3. Kommandos 4.3.1. Disassembler ------------------- ^CTRL_-^A_ Mit diesem Kommando wird eine Seite ab der aktuellen Speicher- zeigeradresse disassembliert. Mit jeder weiteren Tastenbetätigung wird weiterdisassembliert. In den Kommandomodus gelangt man mit ^CTRL_-^A_ zurück. T Mit 'T' kann ein Maschinencodeblock disassembliert und als Listing auf dem Bildschirm, dem Drucker und/oder als Quelltext im Speicher abgelegt werden. Dazu sind als erstes die Anfangsadresse (First:) und die Endadresse (Last:) des zu übersetzenden Blockes einzugeben. Wird die sich anschließende Frage nach der Drucker- ausgabe (Printer?) mit 'Y' beantwortet, wird das Listing auf den Drucker ausgegeben. Alle anderen Zeichen bewirken die Ausgabe auf den Bildschirm. Anschließend ist die Anfangsadresse für das ent- stehende Quelltextprogramm anzugeben (Text:). Soll keine Datei erstellt werden, ist an dieser Stelle nur ^RETURN_ einzugeben. Wenn die Datei mit ASSMON1 bearbeitet werden soll, muß deren Anfangsadresse für Quelltexte in ASSMON1 übereinstimmen (siehe Kommando 'X' in Abschn. 2.4.) bzw. die Datei muß dorthin ver- schoben werden. Weiterhin ist die Textendeadresse, die der Dis- assembler zum Schluß ausgibt, an ASSMON1 zu übergeben. In ASSMON1 stehen dazu zwei Arbeitszellen bereit, in die diese Endadresse mittels 'POKE' gespeichert werden muß. Die Arbeitszellen sind: XXXX+7 - Low-Teil der Textendeadresse XXXX+8 - High-Teil der Textendeadresse XXXX - Ladeadresse von ASSMON1 Soll eine Textdatei erstellt werden, ist noch eine Anfangsadresse (Workspace:) für die entstehende Markentabelle einzugeben. Für jede erkannte Marke werden 2 Bytes benötigt. Liegt eine Marke innerhalb des zu übersetzenden Bereichs, wird die Marke in der Form 'Lnnnn' (nnnn-Hexadezimalwert der Marke) ausgegeben. Liegt die Marke außerhalb, wird nur der Hexadezimalwert eingetragen. Als letztes vor dem Disassemblerstart können noch Datenbereiche innerhalb des zu übersetzenden Blocks angegeben werden, die mit 'DEFB' übersetzt werden. Dazu ist jeweils deren Anfangsadresse (First:) und Endadresse (Last:) anzugeben. Sollen keine bzw. keine weiteren Datenbereiche mehr eingegeben werden, ist bei 'First:' und 'Last:' nur ^RETURN_ einzugeben. Nach dem Disassemblerstart wird der Bildschirm gelöscht und die Markentabelle erstellt. Anschließend wird dann die Disassemblerliste auf den Bildschirm oder Drucker ausgegeben. Mit beliebiger Tastenbetätigung kann das Listen gestoppt und auch wieder fortgesetzt werden. Mit ^ESC_ nach dem Stoppen wird in den Kommandomodus zurückgekehrt. Ungültige Codes werden mit 'NOP' übersetzt, und nach dem Code wird ein '*' im Listing ausgegeben. Beispiel: Die ersten 256 Bytes von ASSMON1 sollen zurückübersetzt werden. Dazu folgende Vorgehensweise als Vorschlag: - Laden von ASSMON2 auf die Adresse 30000 - Verlassen von ASSMON2 mit ^CTRL_-^X_ - Laden von ASSMON1 auf die Adresse 1000 - Textanfangsadresse mit 'X' ausgeben lassen (9501=#251D) - Sprung in ASSMON2 mit ^CTRL_-^J_ - Aufruf 'T' - Eingabe First: 3E8 (=1000) - Eingabe Last: 4E8 - Eingabe Printer? ^RETURN_ - Eingabe Text: 251D (siehe 'X'-Kommando von ASSMON1) - Eingabe Workspace: 7000 - Eingabe First: ^RETURN_ - Eingabe Last: ^RETURN_ - Disassemblierung läuft; es folgt die Ausschrift: Text end = #2B19 - Verlassen von ASSMON2 mit ^CTRL_-^X_ - POKE 1007,&19:POKE 1008,&2B ^RETURN_ - Sprung in ASSMON1 mit CALL 1004 - Bearbeitung des rückübersetzten Quelltextes 4.3.2. Speicherzeigerkommandos ------------------------------ Cursor rechts Der Speicherzeiger wird um eins erhöht. Cursor links Der Speicherzeiger wird um eins verringert. Cursor runter Der Speicherzeiger wird um acht erhöht. Cursor hoch Der Speicherzeiger wird um acht verringert. M 'M' setzt den Speicherzeiger auf die nach dem erscheinenden Doppelpunkt einzugebende Adresse. O 'O' verändert den Speicherzeiger relativ um den Wert, der in der Speicherzelle, auf den der Speicherzeiger momentan zeigt, steht. Das entspricht einem relativen Sprung (JR xx). Zu beachten ist, daß Werte, die größer als #7F sind, den Speicherzeiger verringern. U 'U' setzt den Speicherzeiger wieder auf den Wert, der vor einem 'O'-Kommando eingestellt war. 'U' kann also nur nach einem 'O' verwendet werden. Zu beachten ist, daß nur jeweils ein Rücksprung möglich ist, falls mehrere 'O'-Kommandos nacheinander eingegeben wurden. X 'X' setzt den Speicherzeiger auf die Adresse, deren Wert sich aus der Speicherzelle, auf die der Zeiger momentan weist, und der folgenden Zelle ergibt. Beispiel: Der Zeiger steht auf einem CALL-Befehl (CD xx yy) und der Zeiger soll auf die Anfangsadresse des dort gerufenen Unterprogramms gestellt werden. Dazu ist der Zeiger mit Cursor rechts auf den Low-Teil der Adresse zu verschieben und anschließend 'X' einzugeben. V 'V' setzt den Speicherzeiger wieder auf den Wert, der vor einem 'X'-Kommando bestanden hat. 'V' kann also nur nach einem 'X' verwendet werden. Wie bei 'U' ist auch mit 'V' jeweils nur ein Rücksprung bei mehreren hintereinander eingegebenen 'X'-Kommandos möglich. S Der Speicherzeiger wird auf die Adresse gesetzt, die sich gerade im Stack befindet (z.B. eine Rücksprungadresse aus einem gerufenen Unterprogramm). 4.3.3. Abarbeiten von Code -------------------------- ^CTRL_-^S_ Es wird der Befehl ausgeführt, der auf der Adresse steht, auf die der Speicherzeiger zeigt (Einzelschritt). Zu beachten ist, daß auch der Befehlszähler (PC) vorher auf diese Adresse zu setzen ist. J Es ist eine Adresse einzugeben, ab der der Maschinencode in Echtzeit ausgeführt werden soll. Soll noch einmal in den Kommandomodus zurückgekehrt werden, müssen im Maschinencode Unterbrechungspunkte gesetzt werden ('!'-Kommando). ^CTRL_-^C_ Der Maschinencode wird ab der Adresse, die im Befehlszähler (PC) steht, in Echtzeit ausgeführt. Soll noch einmal in den Kommandomodus zurückgekehrt werden, müssen Unterbrechungspunkte gesetzt werden. ! Auf der Adresse, auf die der Speicherzeiger weist, wird ein Unterbrechungspunkt gesetzt. D.h., es wird ein CALL-Befehl auf eine Routine in ASSMON2 eingetragen. Diese Routine bewirkt die Unterbrechung. Die ursprünglichen drei Bytes werden gesichert und nach der Unterbrechung zurückgeschrieben. > '>' setzt einen Unterbrechungspunkt nach dem laufenden Befehl und ruft anschließend ^CTRL_-^C_ auf. Das ist z.B. bei Unterprogramm- aufrufen (CALL) sinnvoll. 4.3.4. Speicher- und Registeränderungen --------------------------------------- I Mit 'I' wird ein Speicherblock an einen anderen Platz kopiert. Dazu wird die Anfangs- (First:), die End- (Last:) und die Zieladresse (To:) eingegeben. Ist die Endadresse kleiner als die Anfangsadresse, wird das Kommando abgebrochen. P Mit 'P' kann ein Speicherblock mit einem anzugebenden Byte gefüllt werden. Dazu ist die Anfangs- (First:), die Endadresse (Last:) und das Füllbyte (With:) anzugeben. Speicheränderung Der Inhalt der Adresse, auf die der Speicherzeiger weist, kann dadurch geändert werden, in dem einfach eine Hexadezimalzahl (es werden immer die 2 niederwertigsten Stellen genommen) gefolgt von einem Beendigungszeichen (nicht 0-9 oder A-F) eingegeben wird. Wird nur eine Ziffer eingegeben, wird die Zahl links mit Null ergänzt. Ist das Beendigungszeichen ein gültiges Kommando, wird die Zahl gespeichert und anschließend das Kommando ausgeführt. Stellt das Beendigungszeichen kein gültiges Kommando dar, wird es ignoriert. . (Registeränderung) Oben links auf dem Bildschirm stehen die Register und deren Inhalt. Ein Pfeil '>' zeigt auf ein Registerpaar (Registerzeiger). Der Registerzeiger kann mit Punkt '.' auf das nächste Registerpaar verschoben werden usw. Soll der Inhalt eines Registerpaares geändert werden, ist der Zeiger auf dieses Registerpaar zu verschieben und der neue Registerinhalt (Hexadezimalzahl) gefolgt von einem Punkt '.' einzugeben. 4.3.5. Lade- und Rette-Kommandos -------------------------------- R Mit 'R' kann eine Datei von Band eingelesen werden. Dazu ist der Name der Datei (wird nur ^RETURN_ eingegeben, wird die erste gefundene Datei geladen) und die Adresse, ab der die Datei abge- legt werden soll, einzugeben. W Mit 'W' kann ein Speicherblock auf Band gerettet werden. Dazu ist ein Name für die Datei sowie die Anfangs- und Endadresse einzugeben. 4.3.6. Weitere Kommandos ------------------------ G Es kann mit 'G' nach einer Zeichenkette gesucht werden. Die Zeichenkette ist byteweise einzugeben (immer ein Byte nach ':' und ^RETURN_ eingeben). Ist die Kette vollständig eingegeben, wird nach dem Doppelpunkt nur ^RETURN_ eingegeben, und die Suche nach dem ersten Auftreten der Kette beginnt. Wird die Kette im Speicher gefunden, weist der Speicherzeiger auf das erste Zeichen der gefundenen Zeichenkette. N 'N' sucht das nächste Auftreten der Zeichenkette, die mit 'G' eingegeben wurde. L 'L' löscht den Bildschirm und gibt einen 160 Bytes langen Speicherbereich ab der Adresse, auf die der Speicherzeiger weist, auf dem Bildschirm aus. Es werden die Adressen und deren Inhalt hexadezimal und im ASCII-Zeichenformat dargestellt (20 Zeilen mit jeweils 8 Bytes). Für die ASCII-Zeichendarstellung wird für Werte >#7F der Wert #80 abgezogen, und die Werte 0 bis #1F werden mit '.' dargestellt. Danach kann mit ^ESC_ in den Kommandomodus zurückgekehrt oder mit jeder anderen Taste ein weiterer 160 Bytes langer Bereich ge- listet werden. ^CTRL_-^L_ Dieses Kommando entspricht 'L'. Die Ausgabe erfolgt jedoch auf dem Drucker. H Eine Dezimalzahl wird in ihr hexadezimales Äquivalent umgewandelt. Dazu ist nach dem Doppelpunkt die dezimale Zahl einzugeben. Beendet wird die Eingabe mit einem nicht-numerischen Zeichen (außer 0-9). Danach erscheint ein '=' und das hexadezimale Äquivalent. Y Mit 'Y' kann eine ASCII-Zeichenkette eingegeben werden, die ab der Adresse abgelegt wird, auf die der Speicherzeiger verweist. Die Kette wird mit ^ESC_ abgeschlossen und mit ^DEL_ kann jeweils ein Zeichen gelöscht werden. ^CTRL_-^X_ Mit diesem Kommando kehrt man in den BASIC-Interpreter zurück. Mit CALL x+2 (x=Ladeadresse von ASSMON2) kann ASSMON2 von BASIC aus wieder gestartet werden. ^CTRL_-^J_ Mit diesem Kommando wird in das Programm ASSMON1 gesprungen, falls dieses geladen ist. ASSMON # 5. Programmbeispiel 5. P r o g r a m m b e i s p i e l Da der KCc sehr gute Grafikmöglichkeiten bietet, ist als Beispiel ein Sprite-Programm (Sprite=Grafikfigur, die über den Bildschirm bewegt werden kann, ohne dessen Inhalt zu zerstören) ausgewählt worden. Das Programm arbeitet im Bildschirmmodus 0. Als erstes ist das im folgenden abgebildete Programm mit 'I' einzugeben (jede Zeile mit ^RETURN_ abschließen): 1 ;******************************** 2 ;* UEBUNGSPROGRAMM FUER ASSMON1 * 3 ;* * 4 ;* SPRITE-PROGRAMM 'STIEFEL' * 5 ;* * 6 ;* VEB MIKROELEKTRONIK * 7 ;* 'WILHELM PIECK' MUEHLHAUSEN * 8 ;******************************** 9 10 ;VEREINBARUNGEN: 11 12 DOTPOS: EQU #BC1D ;BILDSCHIRMADRESSE AUS POSITION 13 NEXTLI: EQU #BC26 ;NAECHSTE ZEILENADRESSE 14 MODUS: EQU #BC0E ;BILDSCHIRMMODUS FESTLEGEN UND CLS 15 SPALTE: EQU #BB6F ;CURSOR IN SPALTE SETZEN 16 ZEILE: EQU #BB72 ;CURSOR AUF ZEILE SETZEN 17 TEXTOU: EQU #BB5A ;ASCII-ZEICHEN AUF BILDSCHIRM 18 PEN: EQU #BB90 ;SCHREIBSTIFT EINSTELLEN 19 WAITFL: EQU #BD19 ;WARTEN AUF STRAHLRUECKLAUF 20 21 ;********************************* 22 ; SPRITESETZROUTINE 23 24 SETSP: CALL DOTPOS ;ADRESSE BILDSPEICHER 25 PUSH HL ;MERKE ADRESSE 26 LD DE,SPEICH ;RETTESPEICHER 27 LD B,16 ;16 * 16 PIXEL 28 LOOP: PUSH BC ;AUS BILDSPEICHER 29 PUSH HL ;IN FREIEN 30 LD BC,8 ;RAM-BEREICH 31 LDIR ;RETTEN 32 POP HL 33 CALL NEXTLI ;ADRESSE DARUNTER 34 POP BC 35 DJNZ LOOP 36 37 ;AUSGABE SPRITE 38 39 LD C,16 40 LD DE,SPRITE 41 POP HL 42 LOOP3: PUSH HL 43 PUSH BC 44 LD B,8 45 LOOP2: LD A,(DE) ;PIXEL, 46 LD C,A ;DIE IM SPRITE 47 OR (HL) ;GESETZT SIND, 48 SUB C ;AUF DEM 'BILDSCHIRM' 49 LD C,A ;LOESCHEN UND 50 INC DE ;MIT NEUER 51 LD A,(DE) ;FARBE 52 AND C ;VOM SPRITE 53 LD (HL),A ;SETZEN 54 INC HL 55 INC DE 56 DJNZ LOOP2 57 POP BC 58 POP HL 59 CALL NEXTLI 60 DEC C 61 JR NZ,LOOP3 62 RET 63 ;************************************** 64 ;START DES DEMO-PROGRAMMS 65 66 ENT $ ;STARTPUNKT FUER 'R'-KOMMANDO 67 XOR A 68 CALL MODUS ;MODE 0 69 ;TEXTAUSGABE 70 LD A,1 71 CALL SPALTE 72 LD A,14 73 CALL ZEILE 74 LD DE,TEXT ;ZEIGER FUER TEXTAUSGABE 75 LD B,19 76 STRING: LD A,(DE) 77 CALL TEXTOU 78 LD A,B 79 INC DE 80 CALL PEN 81 DJNZ STRING 82 83 ;STIEFEL UEBER TEXT BEWEGEN 84 85 LD B,160-16 ;X=RECHTER RAND MINUS SPRITEBREITE 86 LOOP: LD H,0 87 LD L,100 88 LD D,H 89 LD E,B 90 PUSH BC 91 CALL SETSP ;SPRITE SETZEN 92 93 ;KURZE WARTESCHLEIFE 94 95 LD HL,95 ;WERTE VON 1-#FFFF MOEGLICH 96 PAUSE: DEC HL 97 LD A,H 98 OR L 99 JR NZ,PAUSE 100 101 POP BC 102 PUSH BC 103 LD H,0 104 LD L,100 105 LD D,H 106 LD E,B 107 CALL LOESCH ;SPRITE LOESCHEN 108 POP BC 109 DEC B 110 DJNZ LOOP4 111 RET 112 113 TEXT: DEFM "TEST SPRITEPROGRAMM" 114 115 ;*************************************** 116 ;SPRITE LOESCHEN 117 118 LOESCH: CALL DOTPOS 119 LD DE,SPEICH 120 LD B,16 121 CALL WAITFL 122 LOOP5: PUSH BC ;ALTEN 123 PUSH HL ;BILDINHALT 124 EX HL,DE ;AUS DEM 125 LD BC,8 ;PUFFER 126 LDIR ;ZURUECKSCHREIBEN 127 EX DE,HL 128 POP HL 129 CALL NEXTLI 130 PIP BC 131 DJNZ LOOP5 132 RET 133 ;******************************** 134 ;PIXELMASKEN UND -FARBEN FUER 135 ;DEN STIEFEL 136 137 SPRITE: 138 DEFB 0,0,0,0,0,0,0,0 139 DEFB #55,#44,#FF,#DC,0,0,0,0 140 DEFB 0,0,0,0,0,0,#FF,#CC 141 DEFB #FF,#CC,#FF,#DC,#AA,#A8,0,0 142 DEFB 0,0,#55,#44,#FF,#CC,#FF,#CC 143 DEFB #FF,#CC,#FF,#FC,#FF,#FC,0,0 144 DEFB 0,0,#FF,#CC,#FF,#CC,#FF,#CC 145 DEFB #FF,#DC,#FF,#A9,#AA,2,0,0 146 DEFB 0,0,#55,#44,#FF,#CC,#FF,#F3 147 DEFB #FF,#F3,#FF,3,#AA,2,0,0 148 DEFB 0,0,0,0,#FF,#F3,#FF,#F3 149 DEFB #FF,#F3,#FF,#A3,#AA,2,0,0 150 DEFB 0,0,0,0,#55,#51,#FF,#B3 151 DEFB #FF,#F3,#FF,#F3,#AA,2,0,0 152 DEFB 0,0,0,0,0,0,#FF,#F3 153 DEFB #FF,#73,#FF,#F3,#FF,3,0,0 154 DEFB 0,0,0,0,0,0,#55,#51 155 DEFB #FF,#73,#FF,#F3,#FF,#A3,#AA,2 156 DEFB 0,0,0,0,0,0,#FF,#F3 157 DEFB #FF,#F3,#FF,#F3,#FF,#F3,#FF,3 158 DEFB 0,0,#FF,#F3,#FF,#F3,#FF,#F3 159 DEFB #FF,#F3,#FF,#F3,#FF,#A3,#FF,3 160 DEFB #55,#51,#FF,#B3,#FF,#F3,#FF,#F3 161 DEFB #FF,#F3,#FF,#F3,#FF,#B3,#FF,#C0 162 DEFB #FF,#F3,#FF,#73,#FF,#F3,#FF,#F3 163 DEFB #FF,#F3,#FF,#F3,#FF,#E2,#AA,#80 164 DEFB #FF,#F3,#FF,#73,#FF,#F3,#FF,#F3 165 DEFB #FF,#F3,0,0,#FF,#C0,0,0 166 DEFB #FF,#F3,#FF,#F3,#FF,#F3,#FF,#E2 167 DEFB 0,0,0,0,0,0,0,0 168 DEFB #55,#40,#FF,#C0,#FF,#C0,#AA,#80 169 DEFB 0,0,0,0,0,0,0,0 170 171 ;RESERVIERUNG DES PUFFERS ZUM RETTEN 172 ;DES BILDINHALTS 173 SPEICH: DEFS 16*8 174 175 ;********************************* 176 ; ENDE DES PROGRAMMS Als nächsten Schritt kann das Programm auf syntaktische Fehler überprüft werden. Dazu ist am einfachsten der Assembler mit 'A' und der Option 4 (Unterdrücken des Listens) aufzurufen. Wenn das Listing ordentlich eingegeben, wurde müßten folgende Fehler ange- zeigt werden: *ERROR* 04 in Zeile 86 (Marke mehrfach definiert) (Beseitigung: Aufruf 'E86' und Korrektur der Marke in 'LOOP4:') *ERROR* 01 in Zeile 124 (Aufbau der Zeile falsch) (Beseitigung: Aufruf 'E124' und Korrektur der Operandensyntax in 'EX DE,HL') *ERROR* 02 in Zeile 130 (Befehl wurde nicht erkannt) (Beseitigung: Aufruf 'E130' und Korrektur der Syntax in 'POP BC') *WARNING* LOOP4 absend (LOOP4 konnte wegen der falschen Marke in Zeile 86 nicht gefunden werden) (Beseitigung: ergibt sich aus Korrektur der Zeile 86) Wenn alle syntaktischen Fehler beseitigt sind, sollte die Datei mit 'P1,176,STIEFEL' auf Band gerettet werden. Nach dem Retten und einem erneuten Assemblerlauf (nach der Fehlerbeseitigung) kann das Programm mit 'R' gestartet werden. Zu sehen ist, daß das Programm noch logische Fehler enthält, denn an den Stellen auf dem Bild, wo der Sprite dargestellt werden soll, wird nur eine rechteckige Fläche gelöscht. Der Fehler liegt in der Zeile 52. Hier wurde an Stelle eines OR oder XOR ein AND verwendet. Dieser Fehler ist mit 'E' oder Zeilenneueingabe zu beseitigen. Nach der Beendigung der Routine ist MODE 0 einge- stellt. Mit 'W' kann auf MODE 0 oder 1 zurückgestellt werden. Es wäre denkbar, nach kleineren Änderungen die Spritesetz- und - löschroutine als RSX-Kommandos auch für die Nutzung von BASIC aus nutzbar zu machen. ASSMON # 6. Literatur 6. L i t e r a t u r h i n w e i s e /1/ Systemhandbuch KC compact. VEB Mikroelektronik "Wilhelm Pieck" Mühlhausen /2/ Classen, L.: Programmierung des Mikroprozessorsystems U880- K1520. Reihe Automatisierungstechnik. VEB Verlag TEchnik, Berlin 1982 /3/ Schwarze, W.; Meyer, G.; Eckard, D: Mikrorechner. Wirkungs- weise Programmierung, Applikation. VEB Verlag Technik, Berlin 1980 /4/ Robotron-Systemdokumentation MOS K1520. SCPX 1526, Anleitung für den Programmierer Teil II. VEB Robotron Buchungs- maschinenwerk, Karl-Marx-Stadt 1984. /5/ Lampe, D.; Jorke, G.; Wengel,N.: Algorithmen der Mikro- rechentechnik. VEB Verlag Technik, Berlin 1983. /6/ Z80-Assemblersprache. Benutzerhandbuch in deutscher Sprache. ZILOG, 1977. /7/ Klein, M.; Klein, R.-D.: Z80-Applikationsbuch. Franzisverlag GmbH. München 1983. /8/ Osborn, A.: Einführung in die Mikrocomputer-Technik. te-wi Verlag GmbH, München 1982. /9/ Barthold, H.; Bäurich, H.: Mikroprozessoren- Mikroelektro- nische Schaltkreise und ihre Anwendung. Reihe electronica Bde 186/188 oder 202/204 bzw. Nachauflagen. Berlin: Militär- verlag der DDR. /10/ Befehlsbeschreibung U880D. VEB Mikroelektronik "Karl- Marx" Erfurt, Stammbetrieb. /11/ Mikroprozessorsystem der II. Leistungsklasse. VEB Mikroelek- tronik "Karl Marx" Erfurt /12/ Kieser, H.; Meder M.: Mikroprozessortechnik. VEB Verlag Technik, Berlin 1985 ASSMON # Anhang A A n h a n g A Befehlscode-Tabelle ------------------- 8-Bit-Ladebefehle ----------------- A B C D E H L (HL) (BC) (DE) (nn) n LD A,. 7F 78 79 7A 7B 7C 7D 7E 0A 1A 3AXXXX 3EXX LD B,. 47 40 41 42 43 44 45 46 06XX LD C,. 4F 48 49 4A 4B 4C 4D 4E 0EXX LD D,. 57 50 51 52 53 55 55 56 16XX LD E,. 5F 58 59 5A 5B 5C 5D 5E 1EXX LD H,. 67 60 61 62 63 66 65 66 26XX LD L,. 6F 68 69 6A 6B 6C 6D 6E 2EXX LD (HL),. 77 70 71 72 73 77 75 36XX LD (BC),. 02 LD (DE),. 12 LD (nn),. 32XXXX A B C D E H L LD .,(IX+d) DD7EXX DD46XX DD4EXX DD56XX DD5EXX DD66XX DD6EXX LD .,(IY+d) FD7EXX FD46XX FD4EXX FD56XX FD5EXX FD66XX FD6EXX LD (IX+d),. DD77XX DD70XX DD71XX DD72XX DD73XX DD74XX DD75XX LD (IY+d),. FD77XX FD70XX FD71XX FD72XX FD73XX FD74XX FD75XX LD (IX+d),n DD36XXXX LD (IY+d),n FD36XXXX S Z H P/V N C LD A,I ED57 * * 0 F 0 - LD A,R ED5F * * 0 F 0 - LD I,A ED47 - - - - - - LD R,A ED4F - - - - - - 16-Bit-Ladebefehle ------------------ BC DE HL SP IX IY LD ..,nn 01XXXX 11XXXX 21XXXX 31XXXX DD21XXXX FD21XXXX LD ..,(nn) ED4BXXXX ED5BXXXX 2AXXXX ED7BXXXX DD2AXXXX FD2AXXXX LD (nn),.. ED43XXXX ED53XXXX 22XXXX ED73XXXX DD22XXXX FD22XXXX LD SP F9 DDF9 FDF9 BC DE HL AF IX IY PUSH .. C5 D5 E5 F5 DDE5 FDE5 POP .. C1 D1 E1 F1 DDE1 FDE1 Registeraustauschbefehle ------------------------ EX (SP),HL E3 EX DE,HL EB EX (SP),IX DDE3 EX AF,AF' 08 EX (SP),IY FDE3 EXX D9 BC-BC' DE-DE' HL-HL' Blocktransfer- und -suchbefehle ------------------------------- S Z H P/V N C LDI EDA0 - - 0 * 0 - LD(DE),(HL);INC HL;INC DE;DEC BC LDIR EDB0 - - 0 0 0 - wie LDI, wiederholen bis BC=0 LDD EDA8 - - 0 * 0 - LD(DE),(HL);DEC HL;DEC DE;DEC BC LDDR EDB8 - - 0 0 0 - wie LDD, wiederholen bis BC=0 CPI EDA1 * * * * 1 - CP A,(HL);INC HL;DEC BC CPIR EDB1 * * * * 1 - wie CPI,wiederh.b.BC=0 od.A=(HL) CPD EDA9 * * * * 1 - CP A,(HL);DEC HL;DEC BC CPDR EDB9 * * * * 1 - wie CPD,wiederh.b.BC=0 od.A=(HL) 8-Bit-Arithmetik- und -Logikbefehle ----------------------------------- B C D E H L (HL)A n (IX+d) (IY+d) S Z H P/V N C ADD . 80 81 82 83 84 85 86 87 C6XX DD86XX FD86XX * * * V 0 * ADC . 88 89 8A 8B 8C 8D 8E 8F CEXX DD8EXX FD8EXX * * * V 0 * SUB . 90 91 92 93 94 95 96 97 D6XX DD96XX FD96XX * * * V 1 * SBC . 98 99 9A 9B 9C 9D 9E 9F DEXX DD9EXX FD9EXX * * * V 1 * AND . A0 A1 A2 A3 A4 A5 A6 A7 E6XX DDA6XX FDA6XX * * 1 P 0 0 XOR . A8 A9 AA AB AC AD AE AF EEXX DDAEXX FDAEXX * * 1 P 0 0 OR . B0 B1 B2 B3 B4 B5 B6 B7 F6XX DDB6XX FDB6XX * * 1 P 0 0 CP . B8 B9 BA BB BC BD BE BF FEXX DDBEXX FDBEXX * * * V 1 * INC . 04 0C 14 1C 24 2C 34 3C DD34XX FD34XX * * * V 0 - DEC . 05 0D 15 1D 25 2D 35 3D DD35XX FD35XX * * * V 1 - S Z H P/V N C DAA 27 * * * P - * BCD-Korrektur im Akku CPL 2F - - 1 - 1 - Komplementiere Akku (1er-Komplement) SCF 37 - - 0 - 0 1 Setze Carry-Flag CCF 3F - - x - 0 * Komplementiere Carry-Flag NEG ED44 * * * V 1 * Komplementiere Akku (2er-Komplement) 16-Bit-Arithmetikbefehle ------------------------ BC DE HL SP IX IY S Z H P/V N C ADD HL,.. 09 19 29 39 - - x - 0 * ADC HL,.. ED4A ED5A ED6A ED7A * * x V 0 * SBC HL,.. ED42 ED52 ED62 ED72 * * x V 1 * ADD IX,.. DD09 DD19 DD39 DD29 - - x - 0 * ADD IY,.. FD09 FD19 FD39 FD29 - - x - 0 * INC .. 03 13 23 33 DD23 FD23 - - - - - - DEC .. 0B 1B 2B 3B DD2B FD2B - - - - - - Sprung- und Unterprogrammbefehle -------------------------------- Z NZ C NC PE PO M P JP CAXXXX C2XXXX DAXXXX D2XXXX EAXXXX E2XXXX FAXXXX F2XXXX CALL CCXXXX C4XXXX DCXXXX D4XXXX ECXXXX E4XXXX FCXXXX F4XXXX RET C8 C0 D8 D0 E8 E0 F8 F0 JR 28XX 20XX 38XX 30XX unbedingt (HL) (IX) (IY) RST 00 08 10 18 20 28 30 38 JP C3XXXX E9 DDE9 FDE9 C7 CF D7 DF E7 EF F7 FF CALL CDXXXX JR 18XX DJNZ 10XX DEC B;JR NZ,nn RETI ED4D zurück vom Interrupt RETN ED45 zurück vom nicht maskierbaren Interrupt Rotations- und Verschiebebefehle -------------------------------- S Z H P/V N C RLCA 07 - - 0 - 0 * Rotiere Akku links RRCA 0F - - 0 - 0 * Rotiere Akku rechts RLA 17 - - 0 - 0 * Rotiere Akku links durch Carry RRA 1F - - 0 - 0 * Rotiere Akku rechts durch Carry RLD ED6F * * 0 P 0 - Rot.Ziffern links zw. Akku und (HL) RRD ED67 * * 0 P 0 - Rot.Ziffern rechts zw.Akku und (HL) B C D E H L (HL) A (IX+d) (IY+d) RLC CB00 CB01 CB02 CB03 CB04 CB05 CB06 CB07 DDCBXX06 FDCBXX06 RRC CB08 CB09 CB0A CB0B CB0C CB0D CB0E CB0F DDCBXX0E FDCBXX0E RL CB10 CB11 CB12 CB13 CB14 CB15 CB16 CB17 DDCBXX16 FDCBXX16 RR CB18 CB19 CB1A CB1B CB1C CB1D CB1E CB1F DDCBXX1E FDCBXX1E SLA CB20 CB21 CB22 CB23 CB24 CB25 CB26 CB27 DDCBXX26 FDCBXX26 SRA CB28 CB29 CB2A CB2B CB2C CB2D CB2E CB2F DDCBXX2E FDCBXX2E SRL CB38 CB39 CB3A CB3B CB3C CB3D CB3E CB3F DDCBXX3E FDCBXX3E S Z H P/V N C RLC/RRC * * 0 P 0 * Rotiere Register links/rechts RL/RR * * 0 P 0 * Rotiere Register links/rechts durch Carry SLA/SRA * * 0 P 0 * Schiebe Register links/rechts arithm. SRL * * 0 P 0 * Schiebe Register rechts logisch Einzelbitbefehle ---------------- B C D E H L (HL) A (IX+d) (IY+d) BIT 0 CB40 CB41 CB42 CB43 CB44 CB45 CB46 CB47 DDCBXX46 FDCBXX46 BIT 1 CB48 CB49 CB4A CB4B CB4C CB4D CB4E CB4F DDCBXX4E FDCBXX4E BIT 2 CB50 CB51 CB52 CB53 CB54 CB55 CB56 CB57 DDCBXX56 FDCBXX56 BIT 3 CB58 CB59 CB5A CB5B CB5C CB5D CB5E CB5F DDCBXX5E FDCBXX5E BIT 4 CB60 CB61 CB62 CB63 CB64 CB65 CB66 CB67 DDCBXX66 FDCBXX66 BIT 5 CB68 CB69 CB6A CB6B CB6C CB6D CB6E CB6F DDCBXX6E FDCBXX6E BIT 6 CB70 CB71 CB72 CB73 CB74 CB75 CB76 CB77 DDCBXX76 FDCBXX76 BIT 7 CB78 CB79 CB7A CB7B CB7C CB7D CB7E CB7F DDCBXX7E FDCBXX7E RES 0 CB80 CB81 CB82 CB83 CB84 CB85 CB86 CB87 DDCBXX86 FDCBXX86 RES 1 CB88 CB89 CB8A CB8B CB8C CB8D CB8E CB8F DDCBXX8E FDCBXX8E RES 2 CB90 CB91 CB92 CB93 CB94 CB95 CB96 CB97 DDCBXX96 FDCBXX96 RES 3 CB98 CB99 CB9A CB9B CB9C CB9D CB9E CB9F DDCBXX9E FDCBXX9E RES 4 CBA0 CBA1 CBA2 CBA3 CBA4 CBA5 CBA6 CBA7 DDCBXXA6 FDCBXXA6 RES 5 CBA8 CBA9 CBAA CBAB CBAC CBAD CBAE CBAF DDCBXXAE FDCBXXAE RES 6 CBB0 CBB1 CBB2 CBB3 CBB4 CBB5 CBB6 CBB7 DDCBXXB6 FDCBXXB6 RES 7 CBB8 CBB9 CBBA CBBB CBBC CBBD CBBE CBBF DDCBXXBE FDCBXXBE SET 0 CBC0 CBC1 CBC2 CBC3 CBC4 CBC5 CBC6 CBC7 DDCBXXC6 FDCBXXC6 SET 1 CBC8 CBC9 CBCA CBCB CBCC CBCD CBCE CBCF DDCBXXCE FDCBXXCE SET 2 CBD0 CBD1 CBD2 CBD3 CBD4 CBD5 CBD6 CBD7 DDCBXXD6 FDCBXXD6 SET 3 CBD8 CBD9 CBDA CBDB CBDC CBDD CBDE CBDF DDCBXXDE FDCBXXDE SET 4 CBE0 CBE1 CBE2 CBE3 CBE4 CBE5 CBE6 CBE7 DDCBXXE6 FDCBXXE6 SET 5 CBE8 CBE9 CBEA CBEB CBEC CBED CBEE CBEF DDCBXXEE FDCBXXEE SET 6 CBF0 CBF1 CBF2 CBF3 CBF4 CBF5 CBF6 CBF7 DDCBXXF6 FDCBXXF6 SET 7 CBF8 CBF9 CBFA CBFB CBFC CBFD CBFE CBFF DDCBXXFE FDCBXXFE Flagbeeinflussung: S Z H P/V N C BIT x * 1 x 0 - Komplement des Bits in Z RES - - - - - - 0 in Bit SET - - - - - - 1 in Bit CPU-Steuerbefehle ----------------- S Z H P/V N C NOP 00 - - - - - - Leerbefehl HALT 76 - - - - - - NOP bis RESET oder Interrupt DI F3 - - - - - - Interrupts sperren EI FB - - - - - - Interrupts freigeben IM 0 ED46 - - - - - - Interrupt-Modus 0 IM 1 ED56 - - - - - - Interrupt-Modus 1 IM 2 ED5E - - - - - - Interrupt-Modus 2 Ein- und Ausgabebefehle ----------------------- A B C D E H L S Z H P/V N C IN .,(C) ED78 ED40 ED48 ED50 ED58 ED60 ED68 * * * P 0 - OUT (C),. ED79 ED41 ED49 ED51 ED59 ED61 ED69 - - - - - - S Z H P/V N C IN A,(n) DBXX - - - - - - OUT (n),A D3XX - - - - - - INI EDA2 x * x x 1 - IN (HL),(C);INC HL;DEC B INIR EDB2 x 1 x x 1 - wie INI,wiederholen solange B >0 IND EDAA x * x x 1 - IN (HL),(C);DEC HL;DEC B INDR EDBA x 1 x x 1 - wie IND,wiederholen solange B >0 OUTI EDA3 x * x x 1 - OUT (C),(HL);INC HL;DEC B OTIR EDB3 x 1 x x 1 - wie OUTI,wiederholen solange B >0 OUTD EDAB x * x x 1 - OUT (C),(HL);DEC HL;DEC B OTDR EDBB x 1 x x 1 - wie OUTD,wiederholen solange B >0 Flag-Register ------------- Bit 7 6 5 4 3 2 1 0 S Z X H X P/V N C gesetzt nicht gesetzt wird bei C Carry-Flag C NC Übertrag von Bit 7 N Add-/Subtract-Flag Subtraktion P/V Parity-/Overflow-Flag PE PO gerader Parität H Half-Carry-Flag Übertrag von Bit 3 Z Zero-Flag Z NZ Ergebnis 0 S Sign-Flag M P negatives Ergebnis X nicht verwendet Beeinflussung: - unverändert 1 gesetzt 0 zurückgesetzt * entsprechend dem Ergebnis der Operation (gesetzt wenn erfüllt zurückgesetzt wenn nicht erfüllt) x unbestimmt V Overflow-Funktion P Parity-Funktion F Inhalt des Interrupt-Flip-Flops IFF2 ASSMON # Anhang B A n h a n g B Pseudobefehle des Assemblers: ----------------------------- ORG nn - Adreßzählerzuordnung Marke: EQU nn - Wertzuweisung für Marke DEFB n - Legt n auf die nächste Speicherstelle DEFW nn - Legt nn auf die nächsten zwei Speicher- stellen (dabei zuerst niederwertiger, dann höherwertiger Teil) DEFM "Text" - Legt auf die nächsten Speicherstellen die ASCII-Werte der Zeichen des Textes DEFS nn - reserviert nn Speicherplätze und be- schreibt diese mit Nullen ENT - legt Startadresse für 'R' fest Dabei sind: n - 8-Bit-Konstante nn - 16-Bit-Konstante bedingte Pseudobefehle: ----------------------- IF ausdruck - in Abhängigkeit von 'ausdruck' wird folgender Quelltext bis END bzw. ELSE assembliert oder nicht ELSE - in Abhängigkeit von 'ausdruck' nach IF wird nachfolgender Quelltext bis END assembliert oder nicht END - Beenden der bedingten Assemblierung Assemblerkommandos ------------------ *L- - Auflistung unterdrücken *L+ - Auflistung starten *D+ - Befehlszähler dezimal ausgeben *D- - Befehlszähler hexadezimal ausgeben *E - Ausgabe drei Leerzeilen bzw. Blattvorschub *Hs - String s wird als Kopfzeile definiert *S - Stoppen der Assemblerliste *T+s - Objektcode auf Band ausgeben *T- - Beenden der Bandausgabe *F s - Quelltext vom Band assemblieren ASSMON # Anhang C A n h a n g C Übersicht ASSMON1 und ASSMON2 ASSMON1 ------- Assemble - Aufruf des Assemblers Bye - Rücksprung zum BASIC Current state - Ausgabe der aktuellen Argumente Delete - Löschen von Quelltextzeilen Edit - Aufruf des Editors Find - Durchsuchen von Quelltext nach einer Zei- chenkette Get text - Quelltext von Band einlesen Help - Aufruf des Hilfsmenüs Insert - Eingabe von Quelltext CTRL/J -> ASSMON2 - Sprung in ASSMON2 List - Auflisten von Quelltext Move - Kopieren von Quelltextzeileninhalten reNumber - Neunummerierung von Quelltextzeilen Objekt - assemblierten Objektcode auf Band retten Put text - Quelltext auf Band retten Q put ASCII - Quelltext als reine ASCII-Datei auf Band retten Run - Start eines assemblierten Objektcodes Separator - Eingabe eines neuen Trennzeichen für die Argumenteingabe Tape speed - Umschalten zwischen 1000 und 2000 Baud Übertragungsrate bei der Bandausgabe Upper line - Ausgabe der Nummer der letzten verwendeten Quelltextzeile Verify - Überprüfung der Bandaufzeichnung Width - Umschalten zwischen 40 und 80 Zeichen pro Zeile teXt info - dezimale Anzeige des Quelltextanfanges- und -endadresse Y print lenght - Festlegen der Zeilenzahl pro Seite bei Druckerausgabe Z print text - Ausgabe von Quelltext auf dem Drucker ASSMON2 ------- Cursor rechts - SZ um eins erhöhen Cursor links - SZ um eins vermindern Cursor runter - SZ um acht erhöhen Cursor hoch - SZ um acht vermindern G - Suchen nach Zeichenkette H - Umwandlung Dezimalzahl in Hexadezimalzahl I - Kopieren eines Speicherblocks J - Ausführung von Objektcode in Echtzeit L - Hex-Dump auf Bildschirm ausgeben M - SZ setzen N - Fortsetzen der Suche nach der mit 'G' einge- gebenen Zeichenkette O - SZ = SZ + (SZ) P - Füllen eines Speicherblocks mit Byte R - Objektcode von Band lesen S - SZ = Adresse die im Stack liegt T - Speicherblock disassemblieren U - SZ wieder auf den Wert vor Aufruf 'O' bringen V - SZ wieder auf den Wert vor Aufruf 'X' bringen W - Ausgabe eines Speicherblocks auf Magnetband X - SZ = (SZ) + (SZ+1) Y - Eingabe einer ASCII-Zeichenkette > - Unterbrechungspunkt nach laufenden Befehl setzen und '^CTRL_-C' aufrufen ! - Unterbrechungspunkt bei SZ setzen . - Registerzeiger bzw. Registerinhalt ändern ^CTRL_-^A_ - eine Seite disassemblieren ^CTRL_-^C_ - Fortsetzung der Programmausführung ^CTRL_-^J_ - Sprung in ASSMON1 ^CTRL_-^L_ - Hex-Dump auf Drucker ausgeben ^CTRL_-^S_ - Einzelschritt ^CTRL_-^X_ - Rücksprung zu BASIC Erklärung: SZ = Speicherzeigeradresse (SZ) = Inhalt der Speicherzeigeradresse ASSMON # Anhang D A n h a n g D Fehlermeldungen --------------- *ERROR* 1 Aufbau der Zeile ist fehlerhaft *ERROR* 2 unbekannte Mnemonik *ERROR* 3 Statement schlecht geformt *ERROR* 4 Name mehrfach definiert *ERROR* 5 Zeile enthält ein unerlaubtes Zeichen *ERROR* 6 ein Operand in dieser Zeile ist nicht erlaubt *ERROR* 7 Name ist ein reserviertes Wort *ERROR* 8 falsche Registerbenutzung *ERROR* 9 zu viele Register in der Zeile *ERROR* 10 der WERT eines Ausdrucks ist unzulässig groß (8-Bit-Wort ist maximal zulässig) *ERROR* 11 die Befehle JP (IX+n) und JP (IY+n) sind nicht erlaubt *ERROR* 12 Fehler bei der Anwendung einer Assembleranweisung *ERROR* 13 unzulässige Vorwärtsreferenz, z.B. wenn in einem EQU-Befehl eine Marke als Operand auftritt, die vor- her nicht definiert wurde *ERROR* 14 Division durch Null *ERROR* 15 Überlauf in einer Multiplikationsoperation *ERROR* 19 verschachteltes, bedingtes Statement Bad ORG! Eine ORG-Anweisung würde mit der zugewiesenen Adresse ASSMON1, sein Textfile oder die Markentabel- le überschreiben. Die Kontrolle geht an den Editor zurück. Out of Table space Tritt während des 1. Laufes auf, wenn der reservierte Platz für die Markentabelle nicht ausreicht. Die Kontrolle geht an den Editor zurück. Bad Memory! Es ist kein Platz für weiteren Quelltext vorhanden. In diesem Fall sollte die gesamte Textdatei oder ein Teil davon auf Band gerettet werden Warnungen: ** File closed ** während mit 'T+' code auf Band ausge- geben wird tritt eine ORG-Anweisung auf *WARNING* label absend Name nicht definiert ASSMON # Anhang E A n h a n g E Reservierte Wörter und gültige Befehls-Mnemonik ----------------------------------------------- Reservierte Wörter dürfen Teil eines Namens, nicht aber selber Namen sein. A B C D E H L I R $ AF AF' BC DE HL IX IY SP NC Z NZ M P PE PO gültige Mnemonik: ADC ADD AND BIT CALL CCF CP CPD CPDR CPI CPIR CPL DAA DEC DI DJNZ EI EX EXX HALT IM IN INC IND INDR INI INIR JP JR LD LDD LDDR LDI LDIR NEG NOP OR OTDR OTIR OUT OUTD OUTI POP PUSH RES RET RETI RETN RL RLA RLC RLCA RLD RR RRA RRC RRCA RRD RST SBC SCF SET SLA SRA SRL SUB XOR DEFB DEFM DEFS DEFW ELSE END ENT EQU IF ORG 5. Programmbeispiel An dieser Stelle folgt ein kleines Beispielprogramm, welches mit ASSMON1 erstellt wurde. Da der KCc sehr gute Grafikmöglichkeiten bietet, ist als Beispiel ein Sprite-Programm (Sprite=Grafikfigur, die über den Bildschirm bewegt werden kann, ohne dessen Inhalt zu zerstören) ausgewählt worden. Das Programm arbeitet im Bildschirmmodus 0. Als erstes ist das im folgenden abgebildete Programm mit 'I' einzugeben (jede Zeile mit <ENTER> abschließen): 1 ;******************************** 2 ;* UEBUNGSPROGRAMM FUER ASSMON1 * 3 ;* * 4 ;* SPRITE-PROGRAMM 'STIEFEL' * 5 ;* * 6 ;* VEB MIKROELEKTRONIK * 7 ;* 'WILHELM PIECK' MUEHLHAUSEN * 8 ;******************************** 9 10 ;VEREINBARUNGEN: 11 12 DOTPOS: EQU #BC1D ;BILDSCHIRMADRESSE AUS POSITION 13 NEXTLI: EQU #BC26 ;NAECHSTE ZEILENADRESSE 14 MODUS: EQU #BC0E ;BILDSCHIRMMODUS FESTLEGEN UND CLS 15 SPALTE: EQU #BB6F ;CURSOR IN SPALTE SETZEN 16 ZEILE: EQU #BB72 ;CURSOR AUF ZEILE SETZEN 17 TEXTOU: EQU #BB5A ;ASCII-ZEICHEN AUF BILDSCHIRM 18 PEN: EQU #BB90 ;SCHREIBSTIFT EINSTELLEN 19 WAITFL: EQU #BD19 ;WARTEN AUF STRAHLRUECKLAU 20 21 ;********************************* 22 ; SPRITESETZROUTINE 23 24 SETSP: CALL DOTPOS ;ADRESSE BILDSPEICHER 25 PUSH HL ;MERKE ADRESSE 26 LD DE,SPEICH ;RETTESPEICHER 27 LD B,16 ;16 * 16 PIXEL 28 LOOP: PUSH BC ;AUS BILDSPEICHER 29 PUSH HL ;IN FREIEN 30 LD BC,8 ;RAM-BEREICH 31 LDIR ;RETTEN 32 POP HL 33 CALL NEXTLI ;ADRESSE DARUNTER 34 POP BC 35 DJNZ LOOP 36 37 ;AUSGABE SPRITE 38 39 LD C,16 40 LD DE,SPRITE 41 POP HL 42 LOOP3: PUSH HL 43 PUSH BC 44 LD B,8 45 LOOP2: LD A,(DE) ;PIXEL, 46 LD C,A ;DIE IM SPRITE 47 OR (HL) ;GESETZT SIND, 48 SUB C ;AUF DEM 'BILDSCHIRM' 49 LD C,A ;LOESCHEN UND 50 INC DE ;MIT NEUER 51 LD A,(DE) ;FARBE 52 OR C ;VOM SPRITE 53 LD (HL),A ;SETZEN 54 INC HL 55 INC DE 56 DJNZ LOOP2 57 POP BC 58 POP HL 59 CALL NEXTLI 60 DEC C 61 JR NZ,LOOP3 62 RET 63 ;************************************** 64 ;START DES DEMO-PROGRAMMS 65 66 ENT $ ;STARTPUNKT FUER 'R'-KOMMANDO 67 XOR A 68 CALL MODUS ;MODE 0 69 ;TEXTAUSGABE 70 LD A,1 71 CALL SPALTE 72 LD A,14 73 CALL ZEILE 74 LD DE,TEXT ;ZEIGER FUER TEXTAUSGABE 75 LD B,19 76 STRING: LD A,(DE) 77 CALL TEXTOU 78 LD A,B 79 INC DE 80 CALL PEN 81 DJNZ STRING 82 83 ;STIEFEL UEBER TEXT BEWEGEN 84 85 LD B,160-16 ;X=RECHTER RAND MINUS SPRITEBREITE 86 LOOP4: LD H,0 87 LD L,100 88 LD D,H 89 LD E,B 90 PUSH BC 91 CALL SETSP ;SPRITE SETZEN 92 93 ;KURZE WARTESCHLEIFE 94 95 LD HL,95 ;WERTE VON 1-#FFFF MOEGLICH 96 PAUSE: DEC HL 97 LD A,H 98 OR L 99 JR NZ,PAUSE 100 101 POP BC 102 PUSH BC 103 LD H,0 104 LD L,100 105 LD D,H 106 LD E,B 107 CALL LOESCH ;SPRITE LOESCHEN 108 POP BC 109 DEC B 110 DJNZ LOOP4 111 RET 112 113 TEXT: DEFM "TEST SPRITEPROGRAMM" 114 115 ;*************************************** 116 ;SPRITE LOESCHEN 117 118 LOESCH: CALL DOTPOS 119 LD DE,SPEICH 120 LD B,16 121 CALL WAITFL 122 LOOP5: PUSH BC ;ALTEN 123 PUSH HL ;BILDINHALT 124 EX DE,HL ;AUS DEM 125 LD BC,8 ;PUFFER 126 LDIR ;ZURUECKSCHREIBEN 127 EX DE,HL 128 POP HL 129 CALL NEXTLI 130 POP BC 131 DJNZ LOOP5 132 RET 133 ;******************************** 134 ;PIXELMASKEN UND -FARBEN FUER 135 ;DEN STIEFEL 136 137 SRITE: 138 DEFB 0,0,0,0,0,0,0,0 139 DEFB #55,#44,#FF,#DC,0,0,0,0 140 DEFB 0,0,0,0,0,0,#FF,#CC 141 DEFB #FF,#CC,#FF,#DC,#AA,#A8,0,0 142 DEFB 0,0,#55,#44,#FF,#CC,#FF,#CC 143 DEFB #FF,#CC,#FF,#FC,#FF,#FC,0,0 144 DEFB 0,0,#FF,#CC,#FF,#CC,#FF,#CC 145 DEFB #FF,#DC,#FF,#A9,#AA,2,0,0 146 DEFB 0,0,#55,#44,#FF,#CC,#FF,#F3 147 DEFB #FF,#F3,#FF,3,#AA,2,0,0 148 DEFB 0,0,0,0,#FF,#F3,#FF,#F3 149 DEFB #FF,#F3,#FF,#A3,#AA,2,0,0 150 DEFB 0,0,0,0,#55,#51,#FF,#B3 151 DEFB #FF,#F3,#FF,#F3,#AA,2,0,0 152 DEFB 0,0,0,0,0,0,#FF,#F3 153 DEFB #FF,#73,#FF,#F3,#FF,3,0,0 154 DEFB 0,0,0,0,0,0,#55,#51 155 DEFB #FF,#73,#FF,#F3,#FF,#A3,#AA,2 156 DEFB 0,0,0,0,0,0,#FF,#F3 157 DEFB #FF,#F3,#FF,#F3,#FF,#F3,#FF,3 158 DEFB 0,0,#FF,#F3,#FF,#F3,#FF,#F3 159 DEFB #FF,#F3,#FF,#F3,#FF,#A3,#FF,3 160 DEFB #55,#51,#FF,#B3,#FF,#F3,#FF,#F3 161 DEFB #FF,#F3,#FF,#F3,#FF,#B3,#FF,#C0 162 DEFB #FF,#F3,#FF,#73,#FF,#F3,#FF,#F3 163 DEFB #FF,#F3,#FF,#F3,#FF,#E2,#AA,#80 164 DEFB #FF,#F3,#FF,#73,#FF,#F3,#FF,#F3 165 DEFB #FF,#F3,0,0,#FF,#C0,0,0 166 DEFB #FF,#F3,#FF,#F3,#FF,#F3,#FF,#E2 167 DEFB 0,0,0,0,0,0,0,0 168 DEFB #55,#40,#FF,#C0,#FF,#C0,#AA,#80 169 DEFB 0,0,0,0,0,0,0,0 170 171 ;RESERVIERUNG DES PUFFERS ZUM RETTEN 172 ;DES BILDINHALTS 173 SPEICH: DEFS 16*8 174 175 ;********************************* 176 ; ENDE DES PROGRAMMS Als nächsten Schritt kann das Programm auf syntaktische Fehler überprüft werden. Dazu ist am einfachsten der Assembler mit 'A' und der Option 4 (Unterdrücken des Listens) aufzurufen. Wenn das Listing ordentlich eingegeben wurde müßten folgende Fehler angezeigt werden: *ERROR* 04 in Zeile 86 (Marke mehrfach definiert) (Beseitigung: Aufruf 'E86' und Korrektur der Marke in 'LOOP4:') *ERROR* 01 in Zeile 124 (Aufbau der Zeile falsch) (Beseitigung: Aufruf 'E124' und Korrektur der Operandensyntax in 'EX DE,HL') *ERROR* 02 in Zeile 130 (Befehl wurde nicht erkannt) (Beseitigung: Aufruf 'E130' und Korrektur der Syntax in 'POP BC') *WARNING* LOOP4 absend (LOOP4 konnte wegen der falschen Marke in Zeile 86 nicht gefunden werden) (Beseitigung: ergibt sich aus Korrektur der Zeile 86) Wenn alle syntaktischen Fehler beseitigt sind, sollte die Datei mit 'P1,176' auf Band gerettet werden. Nach dem Retten und einem erneuten Assemblerlauf (nach der Fehlerbeseitigung) kann das Programm mit 'R' gestartet werden. Zu sehen ist, daß das Programm noch logische Fehler enthält, denn an den Stellen auf dem Bild, wo der Sprite dargestellt werden soll, wird nur eine rechteckige Fläche gelöscht. Der Fehler liegt in der Zeile 52. Hier wurde an Stelle eines OR oder XOR ein AND verwendet. Dieser Fehler ist mit 'E' oder Zeilenneueingabe zu besetigen. Nach der Beendigung der Routine ist MODE 0 eingestellt. Mit 'W' kann auf MODE 0 oder 1 zurückgestellt werden. Es wäre denkbar, nach kleineren Änderungen die Spritesetz- und - löschroutine als RSX-Kommandos auch für die Nutzung von BASIC aus nutzbar zu machen.
 



Goto Top
CPC-POWER/CPCSOFTS, programming by Kukulcan © 2007-2024 all rights reserved.
Reproduction forbidden without any express authorization. All the game titles used belong to their respective owners.
Hébergement Web, Mail et serveurs de jeux haute performance