Gestern gabs ganz schön viel Stuff zu lernen! Daher werde ich heute den Kurs etwas kürzer gestalten, es soll nicht gleich zu einem Brain-Overkill kommen. Sicher gibt es noch einige Code-Brocken von gestern zu verdauen.
Aber erstmal schnell zur Auflösung der gestriegen Aufgabe. Neefi und Pohli lagen mit ihrer Umsetzung zu 100% richtig! Applaus!
Hier nochmal das ganze:
* = 4096
LDA # 1
LDX # 0
loop STA 1024,X
INX
CPX #40
BNE loop
RTS
Die sache ist also erledigt! Wenden wir uns neuen Aufregenden 6502 Befehlen zu.
Für unsere geplante Scrollroutine, fehlen noch drei Befehle, die ich heute zum erlernen Anbiete. Der erste ist sehr leicht zu Handhaben. Es handelt sich dabei um den "JMP". Das Kürzel bedeutet soviel wie: "JUMP". Man kann es schon erraten, das es sich hier im einen Sprungbefehl handelt, der IMMER springt, egal wie die Flags gesetzt oder gelöscht sind. Wenn man ihn mit einem Basic Befehl vergleichen möchte, zieht man dazu das GOTO heran! Die Funktion ist identisch.
Testen wir das doch schonmal aus:
* = 4096
LDX #0 ;in X eine 0, um mit farbe schwarz zu starten.
loop STX 53280 ;den Wert in X als Rahmenfarbe nutzen
INX ;X um 1 erhöhen.
JMP loop ;Und nach "loop" springen.
Nachdem die kleine Routine gestartet wurde, staunt man über einen kunterbunten Rahmen. Unser Programm hat dummerweise keine Abbruchbedingung, und ist in einer Endlosschleife gefangen. Trotzdem können wir es abbrechen, zwar nicht mit Run/Stop allein, aber mit Run/Stop + Restore. Falls der Turbo Ass vorher aktiviert war, reicht auch ein druck auf Restore, und wir sind wieder im Editor. Der JMP Befehl ist so Kinderleicht, das er keine weiteren Erklärungen benötigt.
Fackeln wir nicht lange und gehen zum nächsten Befehl über. In dem gerade vorrangegeangenem Beispiel, zählen wir mit hilfe des X Registers, die Adresse 53280 (Rahmenfarbe) in jedem Durchlauf im einen Wert nach oben. Das können wir auch etwas kürzen, in dem wir wiedermal einen neuen Befehl lernen. Es ist möglich, Speicherzellen im Ram, direkt um 1 zu erhöhen, ohne den Akku, X-Reg oder Y-Reg zu benutzen. Ich spreche von dem Befehl "INC". Das Kürzel steht einfach für "INCREMENT", also Erhöhe! Das kennen wir doch schon irgendwoher? Genau! Das hatten wir gestern bei dem "INX" & "INY". Der unterschied ist, das man hinter dem INC, einfach die Speicherzelle angibt, die erhöht werden soll, welches bei INX & INY nicht möglich ist, da diese sich nur auf das X & Y Register auswirken.
Schreiben wir doch mal das kleine Programm von vorhin um.
* = 4096
loop inc 53280 ; erhöhen 53280 um 1
jmp loop ; springe zurück zum label: loop
Wie man sieht, erscheinen wieder viele bunte Rahmenfarben. Also tut sich etwas in der Adresse 53280, aber erhöht sich der Wert wirklich immer um 1? Testen wirs doch mal anders. Daher schlage ich dieses kleine Programm vor, das die Funktion, für das Auge verfolgbar, demonstriert.
* = 4096
inc 1024 ;erhöhe 1024 im 1
rts
Nun startet das ganze einmal. Es erscheint oben links im Textschirm ein "!" Ausrufezeichen. Gehen wir diesmal nicht gleich wieder in den Turbo Assembler zurück, sondern tippern schnell ein SYS 64738 ein. Dieser eben genannte SYS bewirkt einen Softreset, aber keine Angst, unser Source und das assemblierte Programm, sind immer noch im Speicher. Diesen Reset machen wir nur zur Absturzvorbeugung des Basicinterpreters. Durch den Reset, bekommen wir wieder eine 100%tig lauffähige Basic Console. Der Turbo Assembler verändert einige Zeropageadressen (das sind die, die von $0000 bis $00ff gehen), die der Basicinterpreter zum normalen Arbeiten benutzt. Da diese Werte verändert worden sind, kann es passieren, das ein normaler PRINT Befehl schon einen Absturz verursacht. Daher Resetten wir (ein Resetschalter tuts auch), und tippen in die dritte Text Zeile:
SYS 4096 : PRINT PEEK(1024)
...Und drücken Return
Wie wir sehen, erscheint wieder ein "!" Zeichen, und der Peek teilt uns mit, das in der Adresse 1024 jetzt der Wert 33 gespeichert ist. Fahren wir mit den Cursor nochmals auf die Höhe unserer Basic Zeile, und drücken wieder Return. Diesmal bekommen wir ein >"< Anführungszeichen zu sehen, mit dem gepeekten Wert von 34.
Der INC Befehl macht also genau das, wie wir es erwartet haben. Mit einen SYS 36864 landen wir im Turbo Ass und sehen unseren Source Code.
Denken wir mal weiter. Was passiert, wenn wir so oft die Basic Zeile gestartet hätten, bis wir uns auf den Wert 255 genähert hätten? Bei der nächsten Wiederholung, würde die 256 ins Haus stehen, doch die passt nicht mehr in eine 8 Bit breite Speicherzelle! Bekommen wir einen Illegal Quantity Error zu sehen? Nein, natürlich nicht, denn die Zelle fällt zurück auf den Wert 0. Genauso verhält es sich auch mit INX & INY. Das Witzige ist nun, wenn die Werte vom 255 auf 0 zurückfallen, wird in diesem Moment, auch die ZERO Fahne gehoben, ganz ohne einen Compare Befehl zu benutzen. Der nächste INC Befehl, der von 0 auf 1 weiter hochzählt, löscht das ZERO flag wieder. Dies sei aber nur am Rande erwähnt. Da wir gerade so schön beim hochzählen sind, warum zählen wir dann nicht auch mal herunter? Es gibt natürlich auch die umgekehrte Methode:
INX - Increment X (überschlägt sich X von 255 auf 0, dann ZERO Flag = gesetzt)
DEX - Decrement X (überschlägt sich X von 1 auf 0, dann ZERO Flag = gesetzt)
INY - Increment Y (... nur mit Y)
DEY - Decrement Y (... nur mit Y)
INC - Increment Speicherzelle (...nur mit einer Speicherzelle)
DEC - Decrement Speicherzelle (...nur mit einer Speicherzelle)
Aber das Wissen, über die ganzen DEX, DEY & DEC´s, sowie das diese auch Flags setzen können, brauchen wir für unsere Scrollroutine nicht. Es kann aber nicht schaden, davon schonmal etwas erfahren zu haben.
Uns fehlt jetzt nur noch EIN (!!!) einziger Befehl, um eine anständige Scrollroutine zu schreiben. Um genau zu sein, der AND Befehl. Mit jenem welchem ist es möglich, einzelne Bits in einem Byte zu löschen! Hört sich schwierig an, oder? Ist aber nicht so dramatisch. Fragen wir uns doch erstmal, warum in eine Speicherzelle gerade dieser dumme Wert 255, die Höchstgrenze ist. Eine Runde Zahl wäre doch viel schöner gewesen. Nun das ganze stark mit den BITS zusammen. Wir wissen auch als Basic Coder, das 1 Byte ganze 8Bits enthält. Nicht mehr, nicht weniger! Jedes BIT in einem Byte, hat einen genau festgelegten Wert, der immer gleich ist. Schauen wir uns die Wertigkeit der 8 BITs mal an.
BIT 0 = Wert 1
BIT 1 = Wert +2
BIT 2 = Wert +4
BIT 3 = Wert +8
BIT 4 = Wert +16
BIT 5 = Wert +32
BIT 6 = Wert +64
BIT 7 = Wert +128
-----------------
1 BYTE = #255
Es sieht so aus, als steckt da ein System hinter. Die Wertigkeit von BIT 0 bis zu BIT 7, steigt immer in Zweierpotenzen auf. Rechnen wir schnell mit einem Taschenrechner: 1+2+4+8+16+32+64+128 ! Unser Ergebniss ist eine 255. So ergibt sich diese Zahl. Wir haben also ein Byte ausgerechnet, in dem alle BITs gesetzt sind, um den maximal mit 8BIT erreichbaren Wert zu bekommen.
Ich weiß es ist ein ätzender und trockener Stoff, aber da müssen wir schnell durch. Diesmal nehmen wir ein Byte, in dem nicht alle BITs gesetzt sind.
Mein Beispiel-Byte sieht folgendermassen aus.
7 6 5 4 3 2 1 0 : Die 8 Bits von rechts nach links (!!!)
0 1 0 0 1 1 0 1 : Ist das Bit gesetzt=1 (addieren wir es) gelöscht=0, lassen wir es aus.
Schauen wir uns BIT0 an. Das BIT ist gesetzt und hat eine Wertigkeit von 1. Das merken wir uns!
BIT 1 gelöscht- also Ignorieren wir es
BIT 2 gesetzt - Wertigkeit von 4, die wir zu unserer 1 dazu addieren = 5
BIT 3 gesetzt - Wertigkeit von 8. Die addieren wir auf unsere 5 = 13
BIT 4 gelöscht - wieder Ignorieren
BIT 5 gelöscht - wieder Ignorieren
BIT 6 Wertigkeit von 64. Die addieren wir auf unsere 13 = 77
BIT 7 gelöscht - wieder Ignorieren
Unser Byte, hat bei diesen gesetzten BITs, eine Wertigkeit von insgesamt 77 ! Was wir jetzt hier gemacht haben, ist schlicht und einfach eine Umwandlung einer Binärzahl, in eine Dezimalzahl per Brainpower.
Überprüfen wirs doch schnell an einem Beispiel, ob das System bestand hat:
* = 4096
LDA #%00000000 ; (= einem LDA #0)
STA 1024
RTS
Man staunt nicht schlecht, denn der Turboass kann sogar BITweise eingegebene Werte verarbeiten. Man bereitet ihn mit einem "%" Prozentzeichen darauf vor, das ein Wert in Binär folgt. Nach dem Start dieses Programms, sehen wir oben links im Textfeld einen Klammeraffen, welcher den Screencode #0 besitzt. Testen wir weiter.
* = 4096
LDA #%00000001 ; (= einem LDA #1)
STA 1024
RTS
Welches Zeichen werden wir wohl sehen? Es wird ein "A" nach dem starten erscheinen, da es den Screencode 1 hat. Warum? BIT0 ist gesetzt und hat die Wertigkeit 1. Alle anderen sind BITs sind gelöscht, daher bleibt es bei der 1.
* = 4096
LDA #%10000000 ; (= einem LDA #128)
STA 1024
RTS
Wir können ein reversen Klammeraffen erspähen = Screencode 128!
Es sieht also danach aus, das alles seine Richtigkeit hat. Doch was hat das alles mit unserem AND Befehl zu tun, den ich gaaaaanz weit oben erwähnt habe? Es wurde schon gesagt, das dieser Befehl, einzelne BITS löschen kann.
Nehmen wir einfach mal ein Byte, in dem alle BITs gesetzt sind und löschen danach die Bits 7, 6, 5, 4 mit einem AND!
7 6 5 4 3 2 1 0 : (BITS)
---------------
1 1 1 1 1 1 1 1 : Anfangswert #255
0 0 0 0 1 1 1 1 : AND (0=löscht das BIT. 1=lässt es wie es war.)
===============
0 0 0 0 1 1 1 1 : Ist unser Ergebniss #15
Wie man sieht, gibt man beim AND Befehl die jenigen BITs mit 0 an, die gelöscht werden sollen. Wo eine 1 steht, bleiben die BITs unangestastet. Verrückt, nicht war? Dann einfach nochmal lesen. Ich führe noch schnell ein weiteres Beispiel auf, an dem ihr testen könnt, ob es verstanden wurde.
Im nächsten Posting gehts weiter.
This post has been edited 4 times, last edit by "biguser" (May 25th 2003, 9:55am)