Einfach mal nichts tun…

Ein Dreizeiler

C64 Studio, AMCE & TASM

Fügen wir unserem Sprachschatz, mit einem Klassiker der C64 Beispiele, drei weitere Befehle hinzu.

Bevor ihr euch langweilt, weil wir den obigen Teil bereits kennen, kommen wir zum eigentlichen Programm. Es besteht nur aus drei Befehlen, aber die haben wir noch nicht verwendet.

 

INC: INCrement (Byte an der angegebenen Speicherstelle um 1 erhöhen)
INC absolut ($EE, 3B, 6T, NZ)
Der INC-Befehl stellt das Gegenstück zum DEC-Befehl dar. Er erhöht einfach das Byte, das an der angegebenen absoluten Adresse liegt um eins. Hat ein Byte den Wert $FF, dann führt ein INC dazu, dass es wieder bei $00 beginnt. Dies trifft auch auf die unten erwähnten Befehle INX und INY zu.
Hier erhöhen wir die Rahmenfarbe (die ist an der Speicherstelle $d020 gespeichert) um eins. Es sind ja nur 16 Farben möglich, wir schalten also einfach alle Farben laufend durch, da wir mit der übernächsten Zeile eine Endlosschleife programmiert haben.

 

NOP: No OPeration (keine Anweisung)
NOP implizit ($EA, 1B, 2T, <keine>)
Das kann doch wohl nicht wahr sein, gibt es wirklich einen Befehl, der nichts macht? Der Befehl hat natürlich Auswirkungen auf das System. Er benötigt ein Byte im Speicher, dadurch wird natürlich auch der Programmcounter (PC / Programmzähler) erhöht und er verlangsamt unsere Programmausführung um zwei Taktzyklen. Der NOP-Befehl kann z. B. als Platzhalter oder zur gewollten Verzögerung eingesetzt werden.

 

JMP: JuMP to (springe zur angegebenen Adresse)
JMP absolut ($4C, 3B, 3T, <keine>)
Der JMP-Befehl springt immer direkt zur angegebenen absoluten Adresse, er ist also, im Gegensatz zu den Branch-Befehlen (Verzweigung / bedingter Sprung, siehe BNE), von keiner Bedingung abhängig. Ein weiterer Unterschied zu den Bedingten-Sprüngen ist, dass die Sprungweite keiner Beschränkung unterliegt, wir können also an jede beliebe Speicherstelle springen. Wie bereits beim BNE erklärt, bedeutet springen nichts anderes, als den PC auf die angegebene Adresse zu setzen. Wir benutzen JMP hier, um zurück zum INC zuspringen und in einer Endlosschleife unablässig die Rahmenfarbe zu ändern.

Und schon ist unser Programm fertig. Da wir eine Endlosschleife programmiert haben, verzichten wir dieses Mal auf ein RTS. Das Programm läßt sich nur durch drücken von RUN/STOP + RESTORE bzw. einen RESET beenden.

Nachdem ihr das Programm gestartet habt, achtet auf das Muster im Rahmen. Entfernt anschließend den NOP-Befehl und vergleicht wie sich das Muster verändert.

Ändern der Rahmenfarbe mal mit und mal ohne NOP-Befehl.

Da der NOP-Befehl die Zeit bis zum nächsten INC verlängert hatte, blieb die Rahmenfarbe auch länger erhalten. Sobald wir NOP entfernen, wird die Farbe schneller gewechselt und wir bekommen ein anderes Muster.

Die restlichen Adressierungsarten

Wie eben im Intermezzo angekündigt, folgen nun die weiteren Adressierungsarten für die eben vorgestellten Befehle. Weiter unten gibt es dann doch noch eine Änderung des Beispiels, um eine neue Adressierungsart zu erklären.

Der INC-Befehl bietet die selben Adressierungsart wie der DEC-Befehl. Hier also die oben nicht aufgeführten Adressierungsarten.

INC absolut X-indiziert ($FE, 3B, 7T, NZ)
Erhöht das Byte an der angegebenen Adresse+X-Register.

 

INC Zero-Page ($E6, 2B, 5T, NZ)
Erhöht das Byte an der angegebenen Zero-Page-Adresse.

 

INC Zero-Page X-indiziert ($F6, 2B, 6T, NZ)
Erhöht das Byte an der angegebenen Zero-Page-Adresse+X-Register.

 

Da wir schon DEX und DEY verwendet haben, schauen wir uns doch direkt noch die folgenden beiden Befehle an:

INX: INcrement X-Register (Inhalt des X-Registers um 1 erhöhen)
INX implizit ($E8, 1B, 2T, NZ)
Wie INC, nur dass hier das X-Register erhöht wird.

 

INY: INcrement Y-Register (Inhalt des Y-Registers um 1 erhöhen)
INY implizit ($C8, 1B, 2T, NZ)
Wie INX, allerdings wird hier das Y-Register erhöht.


Als Letztes gibt es noch eine neue Adressierungsart, die es nur beim JMP-Befehl gibt. Ändert dafür unser Programm hinter der NOP-Anweisung.

JMP indirekt ($6C, 3B, 5T, <keine>)
Hier wird das Sprungziel von der hinter JMP in den Klammern stehenden Adresse gelesen. Oben schauen wir also nach, welche Adresse an der Stelle jmptable im Speicher steht und springen dann zu dieser.

In unserem Fall werden wir dort das LSB und MSB des Lables loop ablegen…

Achtung: Bei der indirekten Adressierung gibt es eine böse Falle!
Würde unser Label jmptable an einer Pagegrenze, z. B. bei $c0ff beginnen, dann ginge der Sprung gehörig schief!
Eine genaue Erklärung für diesen und weitere Fehler des 6510 findet ihr unter Systemfehler!

Das war es auch schon. Ein Programmstart führt wieder zur bereits gesehenen Ausgabe. Da dieser JMP-Befehl 2 Taktzyklen mehr als der normale JMP benötigt, sieht das Muster wie bei der ersten Version mit NOP aus.

Schon haben wir das Ende dieses Beitrages erreicht.
Im nächsten geht es wieder in die Vollen: Wir werden Binär- und Hex-Zahlen auf dem Bildschirm ausgeben und indirekt Eingaben vom BS auslesen.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (11 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


ZurückWeiter

7 Gedanken zu „Einfach mal nichts tun…“

  1. Hallo Jörn, zunächst mal Danke und ein riesen Lob für diese tolle Website.

    Ich habe vor kurzer Zeit den C64 für mich wieder entdeckt und wollte mich mal mit der Materie hinter den Kulissen befassen. Dabei hilft deine Seite ungemein.

    Ich habe mal eine Frage zum Erhöhen der Rahmenfarbe. Die Farbe wird über den INC-Befehl (inc $d020 ;Rahmenfarbe um eins erhöhen) erhöht. Soweit ist alles klar…mir stellt sich allerdings die Frage, was die CPU in der Endlosschleife mit den Bits anstellt!? Wird durch den Überlauf die Bitfolge wieder auf 0000 gestellt oder wie kommt dieses Verhalten zustande?

    Durchlauf | Bitfolge
    1 | 0000
    2 |0001
    3 |0010

    16 | 1111
    ….
    17 | 0000
    18 | 0001

    Ist meine Annahme korrekt?

    Danke für deine Antwort.

    PS: Ich muss dazu sagen, dass ich ein völliger Anfänger in der Assember-Programmierung bin. Ich arbeite hauptsächlich im Java-Umfeld und habe ganz schön Probleme mich in dieser Welt zurecht zufinden. Hast Du eventuell auch noch einen Tipp für mich, wie man den Kopf von Java auf Assembler umgestellt bekommt?! 😉

    1. Hallo Mario,
      deine Annahme ist teilweise korrekt.

      Da in $D020 ein Byte steht, werden allerdings auch alle 8-Bit erhöht. Sobald das Byte den Wert %11111111 hat, beginnt die Zählung mit dem nächsten INC dann wieder bei Null.

      Durchläufe…
      1: %00000000
      2: %00000001
      3: %00000010
      ...
      16: %00001111
      17: %00010000
      18: %00010001
      ...
      255: %11111110
      256: %11111111
      ...
      257: %00000000
      258: %00000001

      Da für die Farbe aber nur das untere Nibble beachtet wird, wird aus dieser Sicht dann auch immer nur von nur 0 bis 15 gezählt.

      Tipps zum „Umstieg“ von Java zu Assembler habe ich leider keine. Ich denke, der beste Weg ist es, sich mit der Technik des Rechners zu beschäftigen.

  2. Hallo,
    Funktioniert der Befehl „jmp (jmptable:)“ auch immer noch unter CBM Prog Studio 2.8?
    Ich bekomme immer ein „Invalid operand, label or variable“ -Error für diese Zeile, sogar nach einem Copy/Paste von deinem Source.
    Danke!

    1. So, ich habe mir das Beispiel jetzt nochmal in Ruhe angesehen und es klappt tatsächlich nicht, weder mit 2.8.0 noch mit der 2.9.0 BETA!!!

      —-

      OK, sobald ein Label vor dem jmp (jmptable:) kommt, wirft das CBM prg Studio einen Fehler beim Erstellen.
      Mal sehen, was Arthur dazu sagt.

    2. Ich habe eben eine neue BETA erhalten. Dort wurde der Fehler behoben. Den Dank von Arthur geben ich hiermit gerne weiter.

      Das CBM prg Studio 2.9.0 wird voraussichtlich nächste Woche (passend zum Bericht in der neuen Retro) veröffentlicht.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Protected by WP Anti Spam