Die Akku-Ladebefehle

Auf gehts zur Erkundung der restlichen Akku Ladebefehle
(ein / zwei weitere Befehle sind auch noch dabei)

C64 Studio, AMCE & TASM

Für ein wenig Abwechslung, ändern wir unser Testprogramm, so dass wir unsere -Symbole nachträglich einfärben. Um die Farbe in den Akkumulator zu laden, werden wir nacheinander einmal alle möglichen Adressierungsarten für den Akkumulator verwenden. Als Basis dient das Abschluß-Listing vom letzten Beitrag: Der erste Schritt.

Beginnen wir mit der Aufnahme von zwei weiteren Variablen, die wir einfach hinter CHAR einfügen.

Die Variable FARBRAM enthält die Startadresse des Farb-RAMs, in dem die Zeichenfarben hinterlegt sind.
In FARBNR merken wir uns die gewünschte Farbe.

Entfernt dann bitte den RTS Befehl:

Ergänzt das Programm abschließend mit den folgenden Zeilen:

Diese Zeilen sollten für euch kein Problem darstellen. Sie machen fast das Gleiche, wie unser erstes Programm (bzw. jetzt der obige Teil), nur dass der Inhalt des Akkus hier ins Farb-RAM, statt in den Bildschirmspeicher geschrieben wird.

  1. lda #FARBNR : Akku mit der FARBNR laden
  2. ldx #$ff : X-Register mit der gewünschten Schleifenanzahl laden
  3. farbloop : neues Label für die Farb-Schleife
  4. sta FARBRAM-1,x : Akkuinhalt an die Adresse FARBRAM-1+x schreiben
  5. dex : X-Register um eins verringern
  6. bne farbloop : Wenn das X-Register > 0 ist zu farbloop springen (s. Punkt 3)
  7. rts : Sobald das X-Register = 0 ist, zurück zum Aufrufer (hier ins BASIC)

Das gesamte Programm sollte nun wiefolgt aussehen:

Nach dem Start seht ihr jetzt lauter schwarze -Symbole.

Bildschirmausgabe des 2. Beispiels.

Beim Turbo Assembler solltet ihr eine andere Farbe wählen, da dort die Hintergrundfarbe ebenfalls schwarz ist! Wer mag, kann ja mit der Variablen FARBNR experimentieren. FARBNR = $05 führt z. B. zu grünen -Symbolen.

Aber kommen wir zum eigentlichen Thema, die restlichen Ladebefehle für den Akkumulator.

Um uns die absolute Adressierung einmal anzuschauen, müssen wir unser Programm etwas überarbeiten.

Fügt zunächst ans Ende ein neues Label farbadr hinzu, in die nächste Zeile kommt dann die bekannte !byte-Anweisung (kennt ihr von unserer BASIC-Zeile für den Start), gefolgt von unserer Variablen FARBNR. Wie ihr seht, kann man hier ebenfalls problemlos eine Variable verwenden.

Kommen wir jetzt zu unserem neuen Befehl ersetzt den bisherigen LDA-Befehl durch:

LDA absolut ($AD, 3B, 4T, NZ)
Dieses Mal verwenden wir die absolute Adressierung. Bei der absoluten Adressierung wird der Inhalt für den Akku aus der angegebenen Speicherstelle (hier also $0824) geholt. Da Adressen 16-Bit lang sind, benötigt der Befehl also drei Bytes im Speicher. Eins für den OpCode $AD und zwei weitere, für die Adresse. Die Adresse $0824 sieht sehr willkürlich aus. Sie entspricht aber der Position unseres neuen Labes farbadr (jedenfalls, wenn ihr alles wie oben beschrieben geändert habt).
Die verwendete Adresse $0824 könntet ihr natürlich selbst errechnen z. B. indem ihr zur Startadresse $0801 alle Bytes bis zur Zeile !byte FARBNR hinzuzählt. Ändert ihr aber etwas an eurem Programm, so verschiebt sich auch die Adresse und wir erhalten eher zufällig unsere Farbe (halt abhängig davon was nun an unserer festen Speicherstelle steht). Das ist also nicht der Weisheit letzter Schluss. Wir haben beim STA ja schon eine Variable FARBRAM für die Adresse verwendet. Nur macht es hier wenig Sinn eine Variable mit unserer Adresse anzulegen, aber wir können statt $0824 auch einfach das Label farbadr beim LDA verwenden. Der Assembler ersetzt dann bei der Programmerstellung farbadr automatisch mit der zum Zeitpunkt der Erstellung gültigen Adresse und unser Programm funktioniert immer, egal ob wir Zeilen einfügen oder entfernen.

Wenn ihr mit dem C64 Studio arbeitet, dann könnt ihr nach dem Erstellen, einfach mal den Mauszeiger auf das Label farbadr stellen. Euch wird dann die dazu gehörige Speicherstelle angezeigt.

farbadr liegt an Adresse $0824

Die Angabe einer Adresse als Hex-Zahl kann natürlich durchaus Sinn machen, z. B. wenn ihr auf eine feste Systemadresse zugreift. Aber auch dort kann es die Lesbarkeit des Programmes erhöhen, wenn ihr diese in eine Variable packt, deren Name direkt auf den Inhalt schließen lässt. So wie wir es z. B. mit FARBRAM für den STA-Befehl gemacht haben.


Die nächste Adressierung haben wir schon beim STA gesehen, nur dass wir sie hier zum Laden des Akkus verwenden werden. Es handelt sich um die absolute Adressierung mit X-Indizierung.

Auch hierfür muss das Programm wieder geringfügig geändert werden.

Der LDX-Befehl lädt für unseren Test, in das X-Register die Position der gewünschten Farbe. Die verlängerte !byte-Zeile enthält unterschiedliche Farbwerte, auf die wir durch Änderung des X-Registers zugreifen können. Wie ihr seht, kann unsere Variable FARBNR auch hier verwendet werden.

LDA absolut X-indiziert ($BD, 3B, 4-5T, NZ)
Beim Laden des Akkumulators mit einer absoluten Adresse und X-Indizierung, wird der Inhalt der angegebenen Speicherstelle + X-Register in den Akku übernommen. Wir verwenden hier wieder, wie eben, unser Label farbadr (statt einer festen Hex-Zahl) als absolute Adresse. Das Label farbadr wird jetzt übrigens an der Adresse $0826 liegen. Steht im X-Register nun (wie oben angegeben) eine #$02, dann wird in den Akku also der Inhalt der Speicherstelle $0826+$02 = $0828 geladen, hier wieder #$00 für Schwarz, aus der Variablen FARBNR.
Ändert ihr den Befehl ldx #$02 mal in ldx #$01, erhaltet ihr hellblaue Pik-Symbole, da nun der Inhalt von $0826+$01 = $0827 genommen wird. An der Stelle steht #$0e und das ergibt Hellblau. Mit ldx #$03 erhaltet ihr weiße Pik-Symbole. Wie ihr seht, könnt ihr direkt in der !byte-Zeile ablesen, welche Farbe genommen wird ( ldx #$00 = erste Angabe, #$01 = zweite usw.).
Der Befehl benötigt (ähnlich wie beim BNE) unterschiedlich lange für die Ausführung. Normalerweise werden 4 Taktzyklen benötigt, bei einer Überschreitung der Page(Seiten)-Grenze, kommt ein weiterer hinzu, dann sind es also 5 Taktzyklen.

Neben der Verwendung des X-Registers, gibt es die gleiche Adressierung auch mit dem Y-Register.

LDY: LoaD Y-Register (lade / setze einen Wert im Y-Register / Indexregister-Y)
LDY unmittelbar ($A0, 2B, 2T, NZ)
Dieser Befehl macht exakt dasselbe, wie der LDX-Befehl, nur das hier eben das Y-Register gefüllt wird.

LDA absolut Y-indiziert ($B9, 3B, 4-5T, NZ)
Außer dem anderen OpCode und der Verwendung des Y-Registers gibt es keinen Unterschied zu eben.


Die letzten vier LDA-Befehle arbeiten immer mit der Zero-Page zusammen. Diese liegt, wie ihr wisst, an den ersten 256 Bytes des C64 Speichers. Auf der Zero-Page finden sich viele Register, die für die Programmierung wichtig sind, daher muss man häufiger mal etwas von dort laden und kontrollieren.

Für den ersten Test verwenden wir die Adresse $01 auf der Zero-Page. Dort lassen sich bekanntlich die ROM-Bereiche ein- / ausblenden und man kann zwei Status der Datasette abfragen. Das Register sollte direkt nachdem Start des C64 mit dem Wert $37 gefüllt sein. Bei Einsatz der Turbo Assemblers, erhaltet ihr übrigens eine andere Farbe, da dort der Inhalt der Adresse $01 verändert wird!

Ändern wir also mal wieder das Programm:

LDA Zero-Page ($A5, 2B, 3T, NZ)
Ihr solltet darauf achten, dass ihr für die Adressierung der Zero-Page, wirklich nur zweistellige Adressen, wie hier $01, verwendet. Sonst kann es euch bei $0001 passieren, dass wieder die absolute Adressierung mit dem OpCode $ad von oben verwendet wird. Das Programm funktioniert dann natürlich immer noch wie bei der Zero-Page Adressierung, allerdings benötigt ihr dann ein Byte Speicher und einen Taktzyklus mehr!

Wenn ihr das Programm nun startet, sollten gelbe Pik-Symbole erscheinen. Dies liegt daran, dass vom Wert $37 an der Adresse $01 nur das untere Nibble (also $7) verwendet wird und das steht für die Farbe Gelb.

Auch die Zero-Page kann mit Hilfe des X-Register adressiert werden.

LDA absolut Zero-Page X-indiziert ($B5, 2B, 4T, NZ)
Hier wird wieder zur angegebenen Adresse (dieses Mal $00) der Inhalt des X-Registers hinzugezählt. Da wir das mit #$01 füllen, landen wir wieder bei der Adresse $01 und erhalten weiterhin gelbe Symbole.

Achtung: Die Zero-Page kann durch eine Addition mit dem Registerinhalt nicht verlassen werden kann!!
Gebt ihr als Zero-Page-Adresse z. B. $fe an und im X-Register steht $3, dann würde das ja die Adresse $fe+$3 = $0101 ergeben. Da die Adresse bei dieser Adressierungsart aber nur ein Byte lang ist, wird nur das LSB betrachtet und wir erhalten $01!
Werft ggf. einen Blick auf die Adressierungsarten, um zu kontrollieren, wann dies zu beachten ist.

Im Gegensatz zur absoluten Adressierung, gibt es für absolut Zero-Page keine Variante mit dem Y-Register.

Die nächsten beiden Befehle sind etwas komplizierter. Sie ermöglichen die indirekte Adressierung, d. h. ihr gebt eine Zero-Page Adresse an, an der eine Adresse steht von der der Wert geladen wird. :mrgreen:

Treffen wir zunächst mal wieder unsere Vorbereitungen und lernen dabei noch einen STA-Befehl kennen.

Der LDA-Befehl sieht etwas merkwürdig aus, oder? Er ist aber eigentlich nichts Neues für uns. Es wird einfach ein Byte mittels unmittelbarer Adressierung in den Akku geladen. Neu ist nur die spezielle Anweisung für den Assembler. Mit #<farbadr wird das LSB der Adresse unseres Labels farbadr ermittelt und durch die Raute # „direkt“ in den Akku geladen.
Dieses Byte legen wir und dann in einen freien Bereich auf der Zero-Page, fügt den folgenden neuen Befehl hinzu.

STA absolut Zero-Page ($85, 2B, 3T, <keine>)
So wie beim LDA-Befehl, gibt es auch beim STore Akkumulator, eine spezielle Fassung für die Zero-Page. Wir speichern hier den Inhalt des Akkus in der angegebenen Adresse der Zero-Page. Auch hier ist für den Assembler wieder die Schreibweise entscheidend ( $fb = Zero-Page; $00fb = absolute Adressierung).

Diese beiden Zeilen laden zuächst das MSB unserer Adresse farbadr (beachtet das nun ein #>verwendet wird) per unmittelbarer Adressierung in den Akku und speichert diese dann wieder in der Zero-Page. Das MSB legen wir direkt hinter unserem LSB an der Adresse $fc ab.

Jetzt noch das X-Register setzen:

So, endlich sind die Vorbereitungen abgeschlossen, kommen wir zum LDA-Befehl, den wir uns eigentlich ansehen wollen.

Fügt hinter die Zeilen von eben noch die folgende ein:

LDA indirekt X-indiziert ($A1, 2B, 6T, NZ)
Das müssen wir uns jetzt mal ganz genau ansehen. Zunächst wird zur angegebenen Zero-Page Adresse (hier $fa) der Inhalt des X-Registers (das haben wir mit #$01 gefüllt) addiert. Somit kommen wir also auf $fb, dann wird die dort hinterlegte Adresse ausgewertet. Wenn ihr euch die Vorbereitung noch mal anseht, dann haben wir ja an $fb das LSB und an $fc das MSB unseres Labels farbadr abgelegt. Der Akku wird dann mit dem Byte, das an der so ermittelten Adresse zufinden ist geladen. Bei uns ist das $0f = Hellgrau. Um zu überprüfen, dass wir wirklich dieses Byte auslesen, überschreibt in der !byte-Zeile am Programmende $0f einfach mal mit $07 für Gelb und startet das Programm erneut.

Von diesem Befehl gibt es keine Fassung mit dem Y-Register.

Hier nochmal das komplette Programm:

 

Kommen wir zum letzten LDA-Befehl.

LDA indirekt Y-nach-indiziert ($B1, 2B, 5-6T, NZ)
Hier wird zunächst die Adresse, die auf der Zero-Page unter $fb zufinden ist (hier $082d) herausgesucht und dann dazu der Inhalt des Y-Registers addiert. Wir bekommen so die Farbe Gelb $07 für unser Pik-Symbol ( $082d + $5 = $0832). Auch hier kommt ein zusätzlicher Taktzyklus hinzu, sobald die Page-Grenze überschritten wird.
Wenn ihr die Werte fürs Y-Register ändert, werden andere Farben angezeigt, z. B. führt ein #$01 im Y-Register zur Farbe Hellblau $0e .
Diesen Befehl gibt es nicht als X-Register Version.


So, dass war es erstmal.
Lasst das Gelernte ein Wenig auf euch wirken und spielt etwas damit rum. Als nächstes werden wir uns die restlichen Ladebefehle fürs X- und Y-Register ansehen.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (20 Bewertungen | Ø 4,65 von 5 | 93,00%)

Loading...


ZurückWeiter

7 Gedanken zu „Die Akku-Ladebefehle“

  1. Hi Jörn,

    nur ein kleiner Rechtschreibfehler:

    „Ändert ihr den Befehl ldx #$02 mal in ldx #$01, erhaltet ihr hellblaue Pik-Symbole, da nun der Inhalt von $0826+$01 = $0829 genommen wird.“

    $0826+$01 = $0827 und nicht $0829.

    Ich wollte nicht kleinlich sein, dachte jedoch, daß ich es Dir dennoch mitteile. 🙂

    Viele Grüße,
    Achim

    1. Hallo Achim,
      man das ist mir ja mal wieder peinlich!

      Das ist übrigens nicht kleinlich, es ist einfach nur korrekt und darauf kommt es beim Programmieren an.
      Ich habe es eben korrigiert.

      Danke für den Hinweis,
      Jörn

  2. Hallo Jörn,

    ich hätte eine Frage zu deinem ersten Assembly Dump auf dieser Seite.
    In Zeile 22 (0818) steht das LDA FARBADR. Nun wundere ich mich, dass
    an dieser Stelle 4 Byte verbraucht werden. Laut deiner Tabelle benötigt
    das absolute LDA nur 3 Byte.

    Gruß Mike

  3. Hallo (wie sollen dich die Leute denn ansprechen?),
    Glückwunsch zu den gekonnten Seiten zur Assemblerprogrammierung auf dem C64. Ich bin vor Wochen durch Zufall auf das CBM Program Studio gestossen und hab einige Sachen damit veranstaltet. Nun bin ich seit ein paar Tagen auf deinen Seiten und muss sagen das mir diese sehr gtu gefallen. Mach weiter so.
    Nun zum Grund meiner Anmeldung:
    In Schritt 1 erklärst du die Basiczeile, OK.
    Wo wird den festgelegt das dieses Program ab 2062 abgelegt wird?
    Das ist mir nicht klar.

    Grüße,
    Goldbug

    1. Willkommen Goldbug,
      erstmal danke fürs Lob, nenn mich einfach bei meinem Vornamen: Jörn.
      Ich sollte den wohl etwas deutlicher platzieren, zur Zeit findet man den nur im Impressum.

      Direkt festgelegt wird der Start bei 2062 bzw. $080E nicht, er ergibt sich rechnerisch.

      Mit *=$0801 wird ja die Start- / Ladeadresse für das Programm festgelegt bzw. für die nächsten Anweisungen bestimmt.

      Das Programm beginnt mit folgender BYTE-Zeile:
      BYTE $0B,$08,$DD,$07,$9E,$20,$32,$30,$36,$32,$00,$00,$00
      Diese sorgt für die BASIC-Zeile „2013 SYS2062“.

      Schaut man sich die Speicherstellen für jedes Byte der BASIC-Zeile mal an

      $0801,$0802,$0803,$0804,$0805,$0806,$0807
        $0B,  $08,  $DD,  $07,  $9E,  $20,  $32
      $0808,$0809,$080A,$080B,$080C,$080D
        $30,  $36,  $32,  $00,  $00,  $00

      dann sieht man, dass der erste Assembler-Befehl des Programmes (der ja direkt auf die obige BYTE-Zeile folgt) an $080E steht.

      $080E entspricht der Dezimalzahl 2062.
      Da BASIC mit Hex-Zahlen nicht umgehen kann, muss man dem SYS-Befehl die Startadresse
      als Dezimalzahl übergeben.

      Also kann man hier den Start des eigentlichen Assemblerprogramms auch einfach ausrechnen:
      Startadresse des Programms $0801 + 13 BYTEs = $080E = dezimal 2062.

      Gruß,
      Jörn

Schreibe einen Kommentar

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

Protected by WP Anti Spam