Erstellt: 17. März 2013 (zuletzt geändert: 3. Juli 2024)

Der Rest

Das Ende ist nah!

C64 Studio, AMCE & TASM

Wir haben es fast geschafft, es sind (mit Ausnahme der undokumentierten OpCodes) nur noch acht Befehle übrig, die wir bisher nicht behandelt haben. Da es sich bei diesen Befehlen (mit Außnahme von einem) nur um Abwandlungen bereits bekannter Befehle handelt, werde ich mich dieses Mal etwas kürzer fassen.

Das Carry-Flag prüfen

Schauen wir uns als Erstes einen weiteren bedingten Sprungbefehl an:

 BCS $0822

BCS: Branch on Carry Set (springe, wenn das C-Flag gesetzt ist)
BCS relativ ($B0, 2B, 2-4T, <keine>)
Mit dem BCS-Befehl verzweigen wir, sobald das Carry-Flag gesetzt wurde. Wie bei allen bedingten Sprüngen, benötigt der Befehl 2TZ, wenn nicht gesprungen wird, 3TZ bei einem Sprung und wieder 4TZ, falls beim Sprung die Page-Grenze überschritten wird.

Einen Einsatz für BCS können wir z. B. bei folgender Aufgabenstellung finden. Ihr erinnert euch bestimmt, dass wir mit ASL eine Multiplikation mit 2 vornehmen können. Wenn wir dies mit einer größeren Zahl (z. B. 16- oder 32-Bit) machen wollen, müssen wir unser Bit, das links „herausfällt“, ja fürs nächste Byte beachten. Da dieses Bit im Carry-Flag landet, können wir mit BCS darauf prüfen und entsprechend reagieren.

;*** Eine 16-Bit Zahl nach links 'shiften'
asl_16
 asl asl_16_Word         ;LSB shiften
 bcs asl_16_carryset     ;bei Übertrag Sprung zu asl_16_carryset
 asl asl_16_Word+1       ;sonst einfach MSB shiften
 rts                     ;zurück zum Aufrufer
asl_16_carryset          ;gab es einen Übertrag, diesen beachten
 asl asl_16_Word+1       ;MSB shiften
 inc asl_16_Word+1       ;und um 1 erhöhen, für den Übertrag!
 rts                     ;zurück zum Aufrufer
asl_16_Word              ;Platzhalter für die 16-Bit Zahl
 !byte $00, $00          ;LSB, MSB

Brrrr, ist das gruselig! Bitte vergesst den Codeschnipsel ganz schnell wieder!
Er soll nur den Einsatz von BCS zeigen, ich hoffe die Kommentare reichen als Erklärung aus.

Wer es dennoch nicht lassen kann, findet hier ein komplettes Beispiel, inkl. einer geänderten Ausgabe für Binärzahlen, damit auch 16-Bit Zahlen angezeigt werden können.

CHROUT    = $ffd2        ;Jump-Table Adr.: Zeichenausgabe
SETCURSOR = $fff0        ;Jump-Table Adr.: get/set cursor pos

;*** Startadresse BASIC-Zeile
*=$0801
 !byte $0c,$08,$e2,$07,$9e,$20,$32,$30,$36,$32,$00,$00,$00

;*** Start des Programms
 lda #147                ;BS löschen
 jsr CHROUT

;*** LSB für 16-Bit shift
 lda #$81
 sta asl_16_Word

;*** MSB für 16-Bit shift
 lda #$40
 sta asl_16_Word+1

;*** erst das MSB ausgeben
 lda asl_16_Word+1
 ldx #$04
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen

;*** dann das LSB
 lda asl_16_Word
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 jsr asl_16              ;16-Bit Zahl 'shiften'

;*** erst das MSB ausgeben
 lda asl_16_Word+1
 ldx #$05
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen

;*** dann das LSB
 lda asl_16_Word
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 rts                     ;Zurück zum BASIC

 
;************************************************************
;*** Eine 16-Bit Zahl nach links 'shiften'
;************************************************************
;*** Übergabe: asl_16_Word: = die 16-Bit Zahl (LSB/MSB)
;************************************************************
;*** Rückgabe: in asl_16_Word: steht das Ergebnis
;************************************************************
;*** ändert:   SR
;************************************************************
asl_16
 asl asl_16_Word         ;LSB shiften
 bcs asl_16_carryset     ;bei Übertrag Sprung zu asl_16_carryset
 asl asl_16_Word+1       ;sonst einfach MSB shiften
 rts                     ;zurück zum Aufrufer
 
asl_16_carryset          ;gab es einen Übertrag, diesen beachten
 asl asl_16_Word+1       ;MSB shiften
 inc asl_16_Word+1       ;und um 1 erhöhen, für den Übertrag!
 rts                     ;zurück zum Aufrufer
asl_16_Word              ;Platzhalter für die 16-Bit Zahl
 !byte $00,$00           ;LSB, MSB

 
;************************************************************
;*** Den Inhalt des Akkus als Binärzahl auf dem BS ausgeben
;************************************************************
;*** Übergabe: A = Zahl, die ausgegeben wird
;***           X = Zeile in der die Ausgabe beginnt
;***           Y = Spalte in der die Ausgabe beginnt
;************************************************************
;*** Rückgabe: -
;************************************************************
;*** ändert:   X,Y,SR
;************************************************************
;*** Bei 'Folge-Bits' z. B. für 16- oder 32-Bit-Zahlen, muss
;*** zum Label binaryout_nextbyte gesprungen werden.
;*** Dann werden die nächsten 8-Bit aus dem Akku OHNE % 
;*** direkt ab der letzten Cursor-Position ausgegeben.
;************************************************************
binaryout
 pha                     ;Akku auf dem Stack merken (wg. SETCURSOR)
 clc                     ;C=0 für set / C=1 für get Cursor
 jsr SETCURSOR           ;Jump-Table: get/set cursor
 lda #"%"                ;Prozent-Zeichen in den Akku
 jsr CHROUT              ;und ausgeben
 pla                     ;Akku wieder vom Stack holen
binaryout_nextbyte       ;wenn KEIN % benötigt wird, steigen wir hier ein!
 pha                     ;und direkt nochmal merken (bis zum Rücksprung)
 ldy #$07                ;Schleife bei 7 beginnen (rückwärts Bit 7-0)
binoutloop
 ldx #"0"                ;Zeichen "0" ins X-Register
 asl                     ;Akku nach <-links verschieben
 bcc out                 ;Wenn es eine 0 ist, direkt zur Ausgabe,
 inx                     ;sonst erhöhen, damit wir eine 1 haben.
out                      ;Sprungziel, wenn wir eine 0 haben
 pha                     ;Akku merken, da er gleich überschrieben wird (CHROUT)
 txa                     ;X -> Akku; Zeichen in den Akku
 jsr CHROUT              ;Jump-Table: Zeichenausgeben
 pla                     ;Akku fürs nächste Bit wiederholen
 dey                     ;Schleife runterzählen
 bpl binoutloop          ;bis 8-Bit verarbetet sind, springe nach oben
 pla                     ;sonst, den 'alten' Akku-Zustand wiederherstellen
 rts                     ;und zurück zum Aufrufer

Denkt hier und bei den folgenden Beispielen, beim Turbo Assembler, wieder an die üblichen Probleme: max. Labellänge, keine Unterstriche, nur Kleinschreibung usw.

Rotieren

Das Problem von eben lässt sich viel eleganter lösen, dazu brauchen wir nur einen neuen Befehl:

 ROL $0822

ROL: ROtate Left (rotiere nach links)
ROL absolut ($2E, 3B, 6T, NZC)
Der ROL-Befehl ähnelt sehr dem ASL. Auch hier wird bitweise nach links verschoben, allerdings wird jetzt von rechts nicht einfach mit einer Null aufgefüllt, sondern mit dem Inhalt des Carry-Flags. Das links herausfallende Bit landet zum Schluß wieder, wie beim ASL, im C-Flag.

ROtate Left
ROtate Left

Wie kann das nun unser 16-Bit shiften vereinfachen? Werft dazu einfach einen Blick auf unser neues Unterprogramm asl_16 .

asl_16
 asl asl_16_Word         ;LSB shiften
 rol asl_16_Word+1       ;MSB 'rollen'
 rts                     ;zurück zum Aufrufer
asl_16_Word              ;Platzhalter für die 16-Bit Zahl
 !byte $00,$00           ;LSB, MSB

Na, hab ich zuviel versprochen? Jetzt ist die Funktion doch sehr übersichtlich geworden. Hier nochmal im Detail, wie sie funktioniert:

asl_16_Word   asl_16_Word+1
    LSB            MSB
 %10010001      %01010101

Als erstes, ASL auf das LSB:
LSB = %10010001
ASL = %00100010 <- 0 hinein
Das linke Bit vom LSB ist im Carry gelandet, daher C=1

Jetzt ROL aufs MSB, dabei wird das C-Flag automatisch von rechts eingefügt.
MSB %01010101
ROL %10101011 <- Carry war 1, daher wird von rechts eine 1 eingefügt!
                 Zum Schluß ist die 0 vom MSB im Carry gelandet.

 

Wer die neue Funktion testen möchte, der kann jetzt mal den Source aufklappen:

CHROUT    = $ffd2        ;Jump-Table Adr.: Zeichenausgabe
SETCURSOR = $fff0        ;Jump-Table Adr.: get/set cursor pos

;*** Startadresse BASIC-Zeile
*=$0801
 !byte $0c,$08,$e2,$07,$9e,$20,$32,$30,$36,$32,$00,$00,$00

;*** Start des Programms
 lda #147                ;BS löschen
 jsr CHROUT

;*** LSB für 16-Bit shift
 lda #$81
 sta asl_16_Word

;*** MSB für 16-Bit shift
 lda #$40
 sta asl_16_Word+1

;*** erst das MSB ausgeben
 lda asl_16_Word+1
 ldx #$04
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen

;*** dann das LSB
 lda asl_16_Word
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 jsr asl_16              ;16-Bit Zahl 'shiften'

;*** erst das MSB ausgeben
 lda asl_16_Word+1
 ldx #$05
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen

;*** dann das LSB
 lda asl_16_Word
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 rts                     ;zurück zum Aufrufer

 
;************************************************************
;*** Eine 16-Bit Zahl nach links 'shiften'
;************************************************************
;*** Übergabe: asl_16_Word: = die 16-Bit Zahl (LSB/MSB)
;************************************************************
;*** Rückgabe: in asl_16_Word: steht das Ergebnis
;************************************************************
;*** ändert:   SR
;************************************************************
asl_16
 asl asl_16_Word         ;LSB shiften
 rol asl_16_Word+1       ;MSB 'rollen'
 rts                     ;zurück zum Aufrufer
asl_16_Word              ;Platzhalter für die 16-Bit Zahl
 !byte $00,$00           ;LSB, MSB

 
;************************************************************
;*** Den Inhalt des Akkus als Binärzahl auf dem BS ausgeben
;************************************************************
;*** Übergabe: A = Zahl, die ausgegeben wird
;***           X = Zeile in der die Ausgabe beginnt
;***           Y = Spalte in der die Ausgabe beginnt
;************************************************************
;*** Rückgabe: -
;************************************************************
;*** ändert:   X,Y,SR
;************************************************************
;*** Bei 'Folge-Bits' z. B. für 16- oder 32-Bit-Zahlen, muss
;*** zum Label binaryout_nextbyte gesprungen werden.
;*** Dann werden die nächsten 8-Bit aus dem Akku OHNE % 
;*** direkt ab der letzten Cursor-Position ausgegeben.
;************************************************************
binaryout
 pha                     ;Akku auf dem Stack merken (wg. SETCURSOR)
 clc                     ;C=0 für set / C=1 für get Cursor
 jsr SETCURSOR           ;Jump-Table: get/set cursor
 lda #"%"                ;Prozent-Zeichen in den Akku
 jsr CHROUT              ;und ausgeben
 pla                     ;Akku wieder vom Stack holen
binaryout_nextbyte       ;wenn KEIN % benötigt wird, steigen wir hier ein!
 pha                     ;und direkt nochmal merken (bis zum Rücksprung)
 ldy #$07                ;Schleife bei 7 beginnen (rückwärts Bit 7-0)
binoutloop
 ldx #"0"                ;Zeichen "0" ins X-Register
 asl                     ;Akku nach <-links verschieben
 bcc out                 ;Wenn es eine 0 ist, direkt zur Ausgabe,
 inx                     ;sonst erhöhen, damit wir eine 1 haben.
out                      ;Sprungziel, wenn wir eine 0 haben
 pha                     ;Akku merken, da er gleich überschrieben wird (CHROUT)
 txa                     ;X -> Akku; Zeichen in den Akku
 jsr CHROUT              ;Jump-Table: Zeichenausgeben
 pla                     ;Akku fürs nächste Bit wiederholen
 dey                     ;Schleife runterzählen
 bpl binoutloop          ;bis 8-Bit verarbetet sind, springe nach oben
 pla                     ;sonst, den 'alten' Akku-Zustand wiederherstellen
 rts                     ;und zurück zum Aufrufe

Wollt ihr größere Zahlen mit zwei multiplizieren, dann braucht ihr hinter dem ersten ROL, nur weitere für jedes Byte einfügen. Auch die binaryout-Funktion lässt sich jetzt für größere Zahlen (24- / 32-Bit) verwenden. Ihr müsst nur, wie im obigen Beispiel, für das erste Byte zu binaryout springen und für alle folgenden zu binaryout_nextbyte.

 

Auch für den ROL gibt es ein Gegenstück:

 ROR $0822

ROR: ROtate Right (rotiere nach rechts)
ROR absolut ($6E, 3B, 6T, NZC)
Der ROR-Befehl ähnelt sehr dem LSR. Es findet eine bitweise Verschiebung nach rechts statt, aber auch hier wird diesmal von links nicht mit 0, sondern mit dem C-Flag aufgefüllt. Das rechts herausfallende Bit landet zum Schluß wieder im Carry-Flag.

ROtate Right
ROtate Right

 

Durch eine Kombination von LSR und ROR könnt ihr somit auch größere Zahlen durch zwei Teilen. Ihr müsst hier halt nur beim höchsten Byte beginnen und euch zum niedrigsten durcharbeiten.

CHROUT    = $ffd2        ;Jump-Table Adr.: Zeichenausgabe
SETCURSOR = $fff0        ;Jump-Table Adr.: get/set cursor pos

;*** Startadresse BASIC-Zeile
*=$0801
 !byte $0c,$08,$e2,$07,$9e,$20,$32,$30,$36,$32,$00,$00,$00

;*** Start des Programms
 lda #147                ;BS löschen
 jsr CHROUT

;*** LSB des LSW für 32-Bit shift
 lda #$84
 sta DWord_32

;*** MSB des LSW für 32-Bit shift
 lda #$44
 sta DWord_32+1

;*** LSB des MSW für 32-Bit shift
 lda #$24
 sta DWord_32+2

;*** MSB des MSW für 32-Bit shift
 lda #$14
 sta DWord_32+3

;*** erst das MSB des MSW ausgeben
 lda DWord_32+3
 ldx #$04
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 jsr lsr_32              ;32-Bit Zahl 'shiften'

;*** erst das MSB des MSW ausgeben
 lda DWord_32+3
 ldx #$05
 ldy #$00
 jsr binaryout           ;inkl. %-Zeichen
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition
;*** dann das LSB
 lda DWord_32+2
 jsr binaryout_nextbyte  ;OHNE %-Zeichen direkt an der letzten Cursorposition

 rts                     ;Zurück zum BASIC

 
;************************************************************
;*** Eine 32-Bit Zahl nach rechtss 'shiften'
;************************************************************
;*** Übergabe: DWord_32: = die 32-Bit Zahl LSW (LSB/MSB)
;***                                       MSW (LSB/MSB)
;************************************************************
;*** Rückgabe: in DWord_32: steht das Ergebnis
;************************************************************
;*** ändert:   SR
;************************************************************
lsr_32
 lsr DWord_32+3          ;MSB des MSW shiften
 ror DWord_32+2          ;LSB des MSW 'rollen'
 ror DWord_32+1          ;MSB des LSW 'rollen'
 ror DWord_32            ;LSB des LSW 'rollen'
 rts                     ;zurück zum Aufrufer
DWord_32                 ;Platzhalter für die 32-Bit Zahl
 !WORD $0000,$0000 	 ;LSW (LSB, MSB), MSW (LSB, MSB)

 
;************************************************************
;*** Den Inhalt des Akkus als Binärzahl auf dem BS ausgeben
;************************************************************
;*** Übergabe: A = Zahl, die ausgegeben wird
;***           X = Zeile in der die Ausgabe beginnt
;***           Y = Spalte in der die Ausgabe beginnt
;************************************************************
;*** Rückgabe: -
;************************************************************
;*** ändert:   X,Y,SR
;************************************************************
;*** Bei 'Folge-Bits' z. B. für 16- oder 32-Bit-Zahlen, muss
;*** zum Label binaryout_nextbyte gesprungen werden.
;*** Dann werden die nächsten 8-Bit aus dem Akku OHNE % 
;*** direkt ab der letzten Cursor-Position ausgegeben.
;************************************************************
binaryout
 pha                     ;Akku auf dem Stack merken (wg. SETCURSOR)
 clc                     ;C=0 für set / C=1 für get Cursor
 jsr SETCURSOR           ;Jump-Table: get/set cursor
 lda #"%"                ;Prozent-Zeichen in den Akku
 jsr CHROUT              ;und ausgeben
 pla                     ;Akku wieder vom Stack holen
binaryout_nextbyte       ;wenn KEIN % benötigt wird, steigen wir hier ein!
 pha                     ;und direkt nochmal merken (bis zum Rücksprung)
 ldy #$07                ;Schleife bei 7 beginnen (rückwärts Bit 7-0)
binoutloop
 ldx #"0"                ;Zeichen "0" ins X-Register
 asl                     ;Akku nach <-links verschieben
 bcc out                 ;Wenn es eine 0 ist, direkt zur Ausgabe,
 inx                     ;sonst erhöhen, damit wir eine 1 haben.
out                      ;Sprungziel, wenn wir eine 0 haben
 pha                     ;Akku merken, da er gleich überschrieben wird (CHROUT)
 txa                     ;X -> Akku; Zeichen in den Akku
 jsr CHROUT              ;Jump-Table: Zeichenausgeben
 pla                     ;Akku fürs nächste Bit wiederholen
 dey                     ;Schleife runterzählen
 bpl binoutloop          ;bis 8-Bit verarbetet sind, springe nach oben
 pla                     ;sonst, den 'alten' Akku-Zustand wiederherstellen
 rts                     ;und zurück zum Aufrufer

Ist euch die bisher nicht verwendete Assemblerdirektive aufgefallen? Wir verwenden hier !word, um bei DWord_32 die benötigten vier Bytes, für unsere 32-Bit-Zahl, zu reservieren. Ihr könntet natürlich auch wieder mit !byte den Platz reservieren. Eine Besonderheit noch: !word legt die 16-Bit im gewohnten LSB/MSB-Format ab. Nach !word $1234, findet ihr im Speicher also $34 $12! Damit lassen sich sehr leicht Adressen im Speicher ablegen.

Da waren es nur noch vier

Kümmern wir uns zunächst um die letzen beiden bedingten Sprünge, die wir noch verwenden können.

 BVC $082f

BVC: Branch on oVerflow Clear (verzweige, wenn das V-Flag gelöscht ist)
BVC relativ ($50, 2B, 2-4T, <keine>)
Der BVC-Befehl, springt zur angegebenen Adresse, wenn das OVerflow-Flag gelöscht, also 0 ist. Für die Taktzyklen gilt wieder dasselbe, wie bei den anderen bedingten Sprüngen.

 BVS $082f

BVS: Branch on oVerflow Set (verzweige, wenn das V-Flag gesetzt ist)
BVS relativ ($70, 2B, 2-4T, <keine>)
Hier wird gesprungen, wenn das V-Flag gesetzt, also gleich 1 ist. Taktzyklen, wie gehabt.

 

Da wir gerade beim V-Flag sind, es gibt noch einen Befehl zum Löschen des Flags.

 CLV

CLV: CLear OVerflow-Flag (V-Flag löschen, auf Null setzen)
CLV implizit ($B8, 1B, 2T, V=0)
Wir können mit CLV das OVerflow-Flag löschen, also auf Null setzen. Aber im Gegensatz zu den anderen Flag-Befehlen, gibt es keinen Befehl zum Setzten des V-Flags! Wenn ihr es dennoch setzen müsst / wollt, bleibt euch nichts Anderes übrig, als entweder eine Rechenoperation auszulösen, die einen Overflow verursacht oder ihr benutzt die bekannten Stackbefehle:

;*** V-Flag setzen
setVFlag
 php                     ;Statusregister auf den Stack
 pla                     ;Stack in den Akku
 ora #%01000000          ;V-Flag setzen (steht in Bit-6)
 pha                     ;Akku auf den Stack
 plp                     ;Stack ins Statusregister
 rts                     ;zurück zum Aufrufer

 

Endlich sind wir beim letzten offiziellen Befehl des 6502/6510 angelangt.

Have a break, have an OpCode… 😉

 BRK

BRK: BReaK (Abbruch / abbrechen, löst einen Software-Interrupt aus)
BRK implizit ($00, 1B, 7T, BI)
Trifft unser Programm auf den BRK-Befehl, wird ein Interrupt ausgelöst. Das ist dem einen oder anderen bestimmt schon mal passiert. Geht z. B. ein RTS daneben, weil der Stack nicht passt, friert entweder der Rechner ein oder man hat Glück und die CPU trifft früher oder später auf ein $00. Dann finden wir einen leeren BS mit der READY.-Meldung links oben, gefolgt von unserem Cursor, vor.
Einfach gesehen, legt BRK den um zwei erhöhten Programmcounter (PC) auf dem Stack ab, setzt das Break-Flag, sichert das Statusregister (SR) auf dem Stack, setzt das Interrupt-Flag und springt zur Adresse, die an $FFFE/$FFFF (IRQ-Vector) zufinden ist.

Im Detail passiert folgendes:

CPU holt BRK -> PC+1
CPU holt nächsten Befehl -> PC+1 und verwirft diesen
MSB auf den Stack -> SP-1
Break-Flag setzen
LSB auf den Stack -> SP-1
Statusregister (SR) auf den Stack -> SP-1
I-Flag setzen
Inhalt von $FFFE in PC (LSB)
Inhalt von $FFFF in PC (MSB)

Im PC befindet sich jetzt normalerweise $FF48 = der IRQ-(BRK-)Vektor
Wenn das B-Flag gesetzt ist, wird zur Adresse gesprungen,
die an $0314/$0315 gespeichert ist. Die zeigt wiederum auf den Warmstart
vom BASIC ($FE66)

Wenn man BRK für eigene Zwecke, z. B. zum Testen von Programmen nutzen möchte, kann man den Vektor an $0314/$0315 verbiegen. Will man nach dem BRK sein Programm fortsetzen, muss man beachten, dass der PC auf dem Stack um zwei erhöht wurde und somit nicht direkt auf den nächsten Befehl nach dem BRK zeigt! Hier muss man also eine Korrektur vornehmen oder hinter dem BRK ein NOP einfügen. Maschinenmonitorprogramme und Assembler für den C64 nutzen dies häufig, z. B. zeigt SMON nach einem BRK automatisch die Register an. Auch beim Turbo Assembler müsst ihr mit dem Break vorsichtig sein.

Adressierungsarten

Kommen wir zu den letzten Adressierungsarten. Einzig ROL und ROR müssen wir uns jetzt noch mal ansehen. Da die sehr ähnlich sind und wir jetzt am Ende angelangt sind, nur eine kompakte Übersicht:

 ROL
 ROR

ROL Akku ($2A, 1B, 2T, NZC)
ROR Akku ($6A, 1B, 2T, NZC)

 ROL $0822,x
 ROR $0823,x

ROL absolut X-indiziert ($3E, 3B, 7T, NZC)
ROR absolut X-indiziert ($7E, 3B, 7T, NZC)

 ROL $fb
 ROR $fc

ROL Zero-Page ($26, 2B, 5T, NZC)
ROR Zero-Page ($66, 2B, 5T, NZC)

 ROL $fb,x
 ROR $fc,x

ROL Zero-Page X-indiziert ($36, 2B, 6T, NZC)
ROR Zero-Page X-indiziert ($76, 2B, 6T, NZC)

Das Ende, ist erst der Anfang

So, das wars!
Jetzt kennen wir alle Befehle, die der 6502/6510 laut Hersteller beherrscht. Lassen wir die unterschiedlichen Adressierungsarten weg, kommen wir auf nur 56 Befehle. Ihr könnt mit diesen paar Anweisungen also sämtliche Programme, die ihr bisher auf dem C64 gesehen habt, erstellen. Das eine oder andere Programm mag zwar Illigale OpCodes verwenden, aber das sind keine wirklich neuen Befehle, sondern die bewirken in der Regel, dass mehrere Befehle mit einem OpCode ausgelöst werden.

Dies war auch der letzte Beitrag, der auf den Turbo Assembler Rücksicht genommen hat!
Ab jetzt wird nur noch mit dem C64 Studio und ACME entwickelt. Natürlich sind die anderen Beispiele auf diesen Seiten, auch mit dem Turbo Assembler realisierbar. Ich weise aber nicht mehr auf Probleme hin!


Schrott!!Naja...Geht so...Ganz gut...SUPER! (10 Bewertungen | Ø 4,60 von 5 | 92,00%)

Loading...


ZurückWeiter

Ein Gedanke zu „Der Rest“

  1. Hi,
    du schreibst hier jetzt überall “OVerlay-Flag”, aber es ist doch das “OVerflow-Flag”, oder?
    Ansonsten danke für diesen tollen Kurs!

    Grüße

Schreibe einen Kommentar

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

Protected by WP Anti Spam