Nach unten und zurück

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

CBM prg StudioUnterprogramme

Zuletzt haben wir eine Zahl binär auf dem BS ausgegeben. Nun möchten wir zusätzlich den Hexwert anzeigen, den Text frei positionieren und unsere Routinen für eine Wiederverwendbarkeit in Unterprogramme packen. Außerdem soll ein eingegebenes Zeichen als Basis für die Ausgabe dienen. Das klingt erstmal nach einer Menge Arbeit, aber durch die ‚Zerschlagung‚ in einzelne Probleme/Aufgaben wird alles wieder einfacher.

Programmstruktur

Beginnen wir damit unsere ‚Probleme‚ aufzulisten:

  • Zeichen vom BS lesen
  • BS löschen
  • Textausgabe
  • Binärausgabe
  • Hexausgabe

Durch die neue Möglichkeit der Unterprogramme, werden wir das Programm in Etappen entwickeln. Beginnen wir mit dem Hauptprogramm, das zunächst nur die Basis für weitere Ergänzungen bietet. Das Programm wird nach jedem Schritt lauffähig sein, so dass ihr den Fortschritt direkt ausprobieren könnt.

 

Hey, ho, let‘s go…

Zuerst legen wir drei Variablen für die von uns benötigten Adressen fest. Unser Programm wird für die Eingabe ein Zeichen von einer festen BS Position lesen, diese Position steht in SCREENPOS.
Außerdem wollen wir ja Systemroutinen verwenden. Wir werden die Routinen zur Ausgabe von Zeichen (CHROUT = $FFD2) und zum Setzen und Lesen der Cursorposition (SETCURSOR = $FFF0) verwenden. Die beiden Variablen (CHROUT & SETCURSOR) enthalten die jeweilige Einsprungadresse auf der Jump-Table.

Die Jump-Table
Am Ende unseres Speichers, von Adresse $FF81 bis $FFF5, haben die C64 Entwickler eine Jump-Table (Sprungtabelle) zu 39 Kernalfunktionen hinterlegt. Dies ist einfach eine Liste von 39 JMP-Befehlen. Sinn dieser Tabelle war, dass man über feste Einsprungadressen immer zur gewünschten Funktion gelangt, egal wo die sich im Speicher befindet. Damit sollte sichergestellt werden, dass Programme auch dann noch funktionieren, falls die Entwickler mal die Kernalfunktionen verschieben. Wir ‘springen‚ also in die Jump-Table und diese springt weiter zur Kernalfunktion. Es gibt allerdings viel mehr als nur 39 interessante Funktionen, so dass man, wenn man eine der anderen Funktionen verwenden wollte, nur das Risiko eingehen konnte diese direkt anzuspringen. Hätten sich die Entwickler dazu entschlossen diese Funktionen zu verschieben, dann wären die Programme natürlich nicht mehr lauffähig gewesen. Aber glücklicherweise haben sich die Adressen nicht verändert, es wurden im Laufe der Zeit nur Kleinigkeiten im internen Aufbau der Funktionen geändert.

Die BASIC-Zeile ist identisch zu allen bisherigen. Zu Beginn des Assemblerprogramms laden wir das Zeichen (genauer gesagt die Nr. des Zeichens im Char-ROM) in den Akku. Diesen Wert wollen wir später binär bzw. hexadezimal ausgeben. Da sich der Akku aber gleich ändert, merken wir uns diesen auf dem Stack. Wir laden das PETSCII-Zeichen #$93 in den Akku, um es gleich auszugeben. Dies entspricht der euch evtl. bekannten Basic-Anweisung „PRINT CHR$(147)„, wodurch der Bildschirm gelöscht wird.

JSR : Jump to SubRoutine (springe zum Unterprogramm)
JSR absolut ($20, 3B, 6T, <keine>)

Der JSR-Befehl springt zur absolut angegebenen Adresse, aber im Gegensatz zum JMP speichert er zusätzlich die Adresse für den Rücksprung auf dem Stack. Man benutzt ihn also um häufiger verwendete Programmteile auszuführen. Er ist somit mit einem GOSUB
unter BASIC vergleichbar.

Der genaue Ablauf des JSR sieht so aus:

  • PC (ProgramCounter) +2  |  Der PC zeigt also aufs MSB der angegebenen Adresse des JSR-Befehls (hier aufs $FF von $FFD2, da im Speicher bekanntlich erst das LSB und danach das MSB gespeichert wird)
  • MSB des PC auf den Stack (bei uns $FF)
  • LSB des PC auf den Stack (hier $D2), da der Stapel von oben nach unten gefüllt wird, liegt unsere Rücksprungadresse also wieder wie gewohnt als LSB MSB im Speicher.
  • PC auf das Sprungziel des JSR setzen

Jetzt wird unser Unterprogramm solange ausgeführt, bis es auf den bekannten RTS-Befehl trifft. Bisher haben wir RTS nur benutzt, um zurück ins BASIC zu springen.
Beim RTS wird zunächst das LSB und dann das MSB vom Stack geholt. Der PC wird dann auf diese Adresse gesetzt und abschließen wird der PC um 1 erhöht, damit wir mit dem nächsten Befehl weitermachen.

Da wir jetzt das Zusammenspiel von JSR / RTS komplett kennen, möchte ich die Gelegenheit nutzen um nochmal auf einen häufig gemachten Fehler hinzuweisen.
Wir haben ja bereits weitere Stack-Befehle kennengelernt. Euch sollte nun klar sein, wie wichtig es ist jeden auf den Stack gelegten Wert (z. B. mit PHA) vor dem RTS auch wieder vom Stack zu holen (z. B. mit PLA). Anderenfalls springt euer Programm zu einer nicht gewollten Adresse. Im günstigsten Fall landet ihr wieder im BASIC, habt ihr weniger Glück ist ein RESET oder gar Aus-/Anschalten fällig.

Wir verwenden hier die Adresse $FFD2 von der Jump-Table, um die Kernalfunktion CharOut aufzurufen. CharOut kann dazu verwendet werden PETSCII-Zeichen auf unterschiedlichen Geräten (Bildschirm, Drucker, Floppy usw.) auszugeben. Wir verlassen uns hier einfach darauf, dass alles wie von uns gewünscht für eine Ausgabe auf den BS vorbereitet ist (das ist bei einem frisch gestarteten C64 immer der Fall). Eigentlich müssten wir eine ganze Reihe von Kernalfunktionen aufrufen, um sicher zu gehen, dass unsere Ausgabe wirklich auf dem BS stattfindet.
CharOut gibt an der aktuellen Cursorposition das im Akku befindliche Zeichen aus. Da wir zum BS-Löschen #$93 in den Akku geladen haben ist uns hier die Cursorposition erstmal egal.

 

Die Kommentare wie gleich der erste ;<Aufruf: Textausgabe> dienen als Platzhalter. Ich werde euch gleich nach und nach bitten den jeweiligen Kommentar durch neue Programmzeilen zu ersetzen.
Aber unseren Programmablauf können wir jetzt schon bis zum Schluß durchgehen. Wir werden also als erstes unsere Infozeile über einen Aufruf der Textausgabe vornehmen. Dann holen wir unser Zeichen vom Programmstart wieder in den Akku und schreiben es direkt in den BS-Speicher an unsere geplante Eingabestelle SCREENPOS. Anschließend geben wir hinter unserer Infozeile die Binär- und Hexzahl des eingegebenen Zeichens im Akku aus. Zum Schluß geht es per RTS wieder zurück zum BASIC. Hinter dem RTS seht ihr die Platzhalter für unsere Unterprogramme, die wir gleich entwickeln.

Der Rumpf für unser Programm ist jetzt erstmal fertig:

Wer mag kann das Programm jetzt starten. Auf den ersten Blick geschieht nicht viel, es wird nur der BS gelöscht.
Geht doch mal in die 13. Zeile und gebt RUN:ABC+<RETURN> ein. Unser Programm startet und wir sehen, dass trotz des BS-Löschens das Zeichen B auf dem BS stehen bleibt. Wie ihr euch erinnert, wollen wir ja eine Eingabe ermöglichen und hier ist sie. Wir lesen unser Zeichen von der Stelle an der das B steht und geben es nach dem Löschen auch wieder dort aus.

Bildschirmeingabe
Unsere „Bildschirmeingabe„


Ersetzt den Kommentar ;<Aufruf: Textausgabe> mit:

Wir werden für diese und die beiden anderen Funktionen das X– (Zeile) und Y-Register (Spalte) verwenden, um unsere Cursorposition für die Ausgaben zu bestimmen. Die Zählung beginnt jeweils bei 0!
Dann springen wir in unser Unterprogramm runtextout: um unsere Info-/Startzeile auszugeben.

Mach wir bei ;<SUB: Textausgabe> weiter:

Wenn man sich z. B. eine Sammlung an Hilfsroutinen anlegt, ist es keine schlechte Idee die Funktionen mit Kommentaren einzuleiten. Es sollte ersichtlich sein, was die Routine macht, welche Werte übergeben werden müssen, was evtl. zurückgeliefert wird und welche Register von der Funktion verändert werden und außen dann evtl. andere Werte zu erwarten sind.

CLC : CLear Carry (Carry-Flag löschen)
CLC implizit ($18, 1B, 2T, C)

Mit CLC löschen wir das Carry-Flag, wir setzen es hier also auf 0. Wichtig wird das C-Flag in Verbindung mit der Addition und Subtraktion, die werden wir in einem der nächsten Beiträge kennenlernen.
Hier benötigen wir das Carry-Flag, da die Kernalfunktion Get-/SetCursor daran festmacht, ob die Cursorposition gesetzt (C = 0) oder gelesen (C = 1) werden soll.

Nachdem wir das Carry-Flag gelöscht haben, springen wir zur Kernelfunktion SETCURSOR. Diese setzt den Cursor (da C = 0 ist) auf die im X– & Y-Register angegebene Position. Danach setzen wir X auf 0. Wir verwenden das X-Register jetzt, um unser aktuelles Zeichen zu finden. Da wir einen beliebig langen Text ausgeben wollen, fügen wir das Label runtextcharin: ein um eine Schleife zu bilden. Dahinter holen wir unseren ersten Buchstaben in den Akku, den Text werden wir gleich hinter dem Label runtext: ablegen. Das Textende kennzeichnen wir durch ein $00. Wir werden solange Textausgeben, bis wir auf dieses $00 treffen.

BEQ : Branch on EQual (springe wenn gleich)
BEQ relativ ($F0, 2B, 2-4T, <keine>)

Der BEQ-Befehl prüft ob das Zero-Flag auf 1 gesetzt ist, also ob die letzte Operation (z. B. ein Vergleich) eine Null geliefert hat. Wenn das Ergebnis also Null war (Z = 1), dann springen wir hier zum Label done:, da wir fertig sind.
Wir kennen ja bereits den BNE-Befehl, der verzweigt bekanntlich, wenn das Ergebnis ungleich Null ist (also bei Z = 0). Hier gelten die gleichen Besonderheiten was die Taktzyklen betrifft: 2T wenn nicht gesprungen wird, 3T beim Sprung, 4T falls der Sprung über die Page-Grenze hinaus geht.
Wir verwenden BEQ um festzustellen, ob wir unser Textende ($00) erreicht haben. Da LDA bereits die Flags setzt, benötigen wir keinen Vergleichsbefehl mehr. Sobald eine $00 in den Akku geladen wird, setzt der Computer die Z-Flagge auf 1 und wir springen dann direkt zu done:.

Wenn wir beim BEQ nicht gesprungen sind, springen wir direkt zur Kernalfunktion CHROUT. Diese gibt, wie oben bereits erwähnt, das Zeichen im Akku an der aktuellen Cursorposition aus. Außerdem wird der Cursor automatisch um ein Zeichen nach rechts verschoben. Wir müssen uns also für die weiteren Zeichen nicht um die Cursor-Positionierung kümmern. Wenn wir wieder zurück in unserem Programm sind, erhöhen wir das X-Register, damit wir auf unser nächstes Zeichen im Text zeigen. Dahinter springen wir einfach wieder zum Label runtextchain: um das nächste Zeichen in den Akku zu laden. Wenn BEQ zum Label done: gesprungen ist, finden wir dort als letztes den RTS-Befehl und landen dann wieder im Hauptprogramm (also hinter jsr runtextout:)
Zum Schluß legen wir hinter dem Label runtext: noch unseren Text fest und kennzeichen das Ende mit $00. Der Text erinnert an unser Beispiel von oben.

Damit ist auch dieser Schritt beendet, wenn ihr das Programm jetzt startet, sollte das Programm zu folgender Ausgabe führen:

Unsere Eingabe findet zwischen den Klammern statt.
Unsere Eingabe findet zwischen den Klammern statt.

Wir können jetzt zwischen den Klammern „( )„ unser Zeichen für die Ausgabe eintragen und direkt <RETURN> drücken. Das Programm startet dann sofort wieder, löscht den BS und gibt dann die Info-/Startzeile mit dem eingegebenen Zeichen erneut aus.

 

Kommen wir zu ;<Aufruf: Binärausgabe>:

Nachdem wir von runtextout: zurück ins Hauptprogramm gekommen sind, haben wir ja den Akku vom Stack geholt und zwischen den Klammern ausgegeben. Anschließend legen wir im X– & Y-Register unsere Cursorpostion fest und geben den Akku-Inhalt mit unserem Unterprogramm binaryout: auf dem BS aus.

 

Kümmern wir uns daher jetzt um ;<SUB: Binärausgabe>:

Zu Beginn merken wir uns den Akku auf dem Stack. Unsere Funktion soll den Akku unverändert lassen, damit wir den außen weiterverwenden können. Wir positionieren dann den Cursor und geben das Prozentzeichen „%„ als Kennzeichen für die Binärzahl aus. Da der Akku verändert wurde holen wir ihn vom Stack und speichern ihn dort auch gleich wieder, damit wir vorm Rücksprung den original Akku-Inhalt wiederherstellen können. Im Y-Register merken wir uns die Bitposition, die wir aktuell prüfen. Wir gehen die Bits 7 bis 0 rückwärts durch.

Wer die eigentliche Binärausgabe ab dem Label binoutloop: mit der aus dem letzten Beitrag vergleicht, wird feststellen, dass diese etwas anders funktioniert. Zu Übungszwecken und damit ihr seht dass man unterschiedliche Lösungswege gehen kann habe ich die Funktion etwas umgebaut.
Wir laden zunächst das Zeichen „1„ in den Akku.
Wenn ihr unsere bisherigen Sourcen aufmerksam verfolgt habt, wundert ihr euch evtl. warum mal einfache Anführungszeichen ‚1‚ und ein anderes mal doppelte Anführungszeichen z. B. „%„ verwendet wurden. Benutzt ihr die einfachen Anführungszeichen , dann nimmt das CBM prg Studio den gewünschten Wert für das Zeichen aus dem Char-ROM. Bei doppelten Anführungszeichen wird der Code aus der PETSCII-Tabelle genommen. So liefert ‚A‚ z. B. ein $01 und „A„ ein $41. Den Unterschied könnt ihr durch einen Vergleich der beiden Tabellen unter ‚Schlag mal nach…‚ kontrollieren.

ASL: Arithmetic Shift Left (bitweises verschieben nach links)
ASL Akku ($0A, 1B, 2T, NZC)

Den Befehl hatten wir am Ende des letzten Beitrags bereits, aber hier nochmal die Funktionsweise. Er ist das Gegenstück zum LSR, nur das hier die Bits nach links verschoben werden. Dabei wird von rechts mit Nullen aufgefüllt und das herausfallende Bit landet im Carry-Flag.

ASL
ASL

Da das Bit, dass links herausfällt, im Carry-Flag landet, können wir daran festmachen, ob wir eine 0 oder 1 haben.

BCC : Branch on Carry Clear (springe, falls das Carry-Flag gelöscht ist | C = 0)
BCC relativ ($90, 2B, 2-4T, <keine>)

Der BCC-Befehl prüft, ob das Carry-Flag auf 0 steht und springt, falls das der Fall ist, zur angegebenen Adresse. Auch hier ist die Ausführungszeit wie bei allen Branch-Befehlen wieder variabel (vgl. BNE).
Wir testen hier, ob unser letztes Bit eine 0 war, fall ja behalten wir den Wert im X-Register und springen direkt zur Ausgabe beim Label out:.

Haben wir aber eine 1, dann geht es nach dem BCC direkt mit dem nächsten Befehl weiter. Dort erhöhen wir den Inhalt des X-Registers und machen so aus unserer „0„ eine „1„. Unsere Ausgabe beginnt hinter out: damit, dass wir uns den Akku wieder auf dem Stack merken. Das ist wie wir bereits erfahren haben notwendig, da wir gleich unser Zeichen aus dem X-Register in den Akku kopieren, um es über die Kernalfunktion an der aktuellen Cursorposition auszugeben. Kommen wir von der Kernalfunktion zurück, dann holen wir den Akku auch wieder vom Stack. Wir verringern danach unsere Schleifenvariable im Y-Register um eins.

BPL : Branch on PLus (springe wenn positiv)
BPL relativ ($10, 2B, 2-4T, <keine>)

Der nächste bedingte Sprungbefehl prüft ob das Negativ-Flag gelöscht ist (also ob eine positive Zahl vorliegt) und verzweigt, solange N = 0 ist, zur angegebenen Adresse. Mit der Ausführungszeit verhält es sich wie bei allen Branch-Befehlen (s. BNE). Die Mathematiker unter euch werden den Namen des Befehls bemängeln, da hier auch Null als positive Zahl gewertet wird (wir wissen ja, dass die 0 in der Mathematik vorzeichenlos ist). Das Verhalten ist allerdings korrekt, da hier wie gesagt auf N = 0 geprüft wird und die 0 halt auch nicht negativ ist, verzeigt der Befehl eben auch dann zur angegebenen Adresse.
Wir wollen hier unsere Schleife solange durchlaufen, bis alle Bits geprüft wurden. Wenn der aktuelle Inhalt des Y-Registers $00 beträgt, dann führt ein DEY bekanntlich dazu, dass nun $FF im Y-Register steht und dies setzt die N-Flagge.

Wenn alle Bits ausgegeben wurden, dann müssen wir nur noch unseren original Akku-Inhalt vom Stack holen und kehren mit RTS zurück ins Hauptprogramm (jsr binout:).

Unser Programm nähert sich langsam aber sicher seinem Ende. Wenn ihr das Programm jetzt startet könnt ihr euch schon die Nr. des gewünschten Zeichens im Char-ROM binär auf dem BS ausgeben lassen.

Binärzahl der Nummer des Zeichen 'A' im Char-ROM.
Binärzahl der Nummer des Zeichen ‚A‚ im Char-ROM.

Das wir die Nummer aus dem Char-ROM und nicht die aus der PETSCII-Tabelle anzeigen, könnt ihr ganz einfach durch die Eingabe von ‚A‚ zwischen den Klammern ( ) und anschließendem <RETURN> kontrollieren. Im Char-ROM hat ‚A‚ die Nr. $01 im PETSCII $41.

Lasst uns das Programm zu Ende führen. Kommen wir im Hauptprogramm zum Kommentar ;<Aufruf: Hexausgabe>

Nach der Rückkehr von binaout: steht unsere Zahl für die Ausgabe ja wieder im Akku, daher können wir einfach im X– und Y-Register unsere neue Cursorposition eintragen und zur neuen Funktion hexout: springen. Sobald wir von dort zurückkommen wird unser Programm durchs anschließende RTS beendet und wir landen wieder im BASIC.

 

Ersetzt nun den letzten Kommentar

;<SUB: Hexausgabe>

Das Unterprogramm hexout: beginnt, wie bereits binout: damit, dass wir unseren Akku-Inhalt auf dem Stack speichern. Als nächstes setzen wir den Cursor an die gewünschte Position und geben wieder das Kennzeichen für die kommende Zahl (diesmal ein Dollar $) aus. Da der Akku verändert wurde holen wir den gespeicherten Wert vom Stack und merken uns den sofort wieder auf dem Stack. Einmal fürs Ende der SubRoutine und einmal für die Ausgabe. Wir verwenden anschließend vier LSR-Befehle, um das obere Nibble ins untere zu verschieben. Dadurch erhalten wir eine Zahl zwischen $0 und $F, von links werden bekanntlich Nullen eingeschoben, im Akku. Danach kopieren wir den Akku-Inhalt ins X-Register um unser Zeichen für die Ausgabe vom Label possiblehexchars:. Dort sind einfach alle möglichen Hexzeichen von „0„ bis „F„ hinterlegt. Über das X-Register greifen wir per absoluter X-indizierter Adressierung auf das dazugehörige Zeichen zu. Dieses landet im Akku und wird wieder per Kernalfunktion CharOut auf dem BS ausgegeben. Sobald wir aus der Kernalfunktion zurückkehren holen wir uns den original Akku-Inhalt vom Stack. Jetzt blenden wir per AND das obere Nibble aus und geben somit das untere wie eben aus. Zum Schluß holen wir den Akkuwert wieder vom Stack und springen per RTS zurück ins Hauptprogramm (jsr hexout:)

So das wars auch schon. Da uns immer mehr Befehle bekannt sind, konnten wir den Block schnell abhandeln.

Unser komplettes Programm:

Starten wir das Programm und wir erhalten endlich die von uns gewünschte Ausgabe.

Unser fertiges Programm...
Unser fertiges Programm…

Noch eine Anmerkung zu den Kernalfunktionen.
Die Kernalfunktionen erlauben es uns schnell und einfach unser Programm aufzubauen. Aber man sollte auch immer bedenken, dass sie nicht unbedingt die schnellsten sind. Bei zeitkritischen Aufgaben sollten wir uns überlegen, ob wir nicht lieber eine eigene Funktion schreiben.
Einige Kernalfunktionen können übrigens fehlschlagen. Diese zeigen durch ein gesetztes Carry-Flag einen aufgetretenen Fehler an. Im Akku steht dann eine Fehler-Nr., die wir auswerten sollten. Dies ist aber ein Thema, das ich hier bei den Grundlagen nicht vertiefen möchte.


Kommen wir zu den Befehlsvarianten.

SEC : SEt Carry (Carry-Flag setzen)
SEC implizit ($38, 1B, 2T, C)

Mit SEC setzen wir das Carry-Flag auf 1. Wenn wir mit SETCURSOR z. B. die aktuelle Position lesen wollen. Wie oben bereits erwähnt wird das Carry-Flag und die beiden Befehle um dieses zu setzen / löschen, hauptsächlich bei der Addition und Subtraktion benötigt.


ASL bietet neben der Akku-Adressierung noch die selben vier Adressierungsarten wie LSR.

ASL absolut ($0E, 3B, 6T, NZC)
Das Byte an der angegebenen absoluten Adresse bitweise nach links verschieben.

ASL absolut X-indiziert ($1E, 3B, 7T, NZC)
Das Byte an der angegebenen absoluten Adresse + X-Register bitweise nach links verschieben.

ASL Zero-Page ($06, 2B, 5T, NZC)
Verschiebe das Byte an der angegebenen Zero-Page-Adresse bitweise nach links.

ASL Zero-Page X-indiziert ($16, 2B, 6T, NZC)
Bitweises verschieben des Bytes, das an der angegebenen Zero-Page-Adresse + X-Register zu finden ist.


Als nächstes nutzen wir unsere hier entwickelten Routinen und schauen uns endlich die Rechenmöglichkeiten an.


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

Loading...


<<<zurück | weiter>>>

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

6 Gedanken zu „Nach unten und zurück“

  1. Hallo Jörn,

    zuerst mal vielen Dank für das Tutorial im Ganzen (ich wünschte, so etwas hätte es vor gut 30 Jahren gegeben).

    Allerdings fällt mein CBM prg Studio (3.10.0) hier auf die Nase:

    [Error ] Line 79:Invalid operand, label or variable „lda „%“ ;Prozent-Zeichen in den Akku“ – S:\store\CBM\CBM prg Studio\test2\test-7.asm
    [Error ] Line 87:Invalid operand, label or variable „ldx „0“ ;Zeichen „0“ ins X-Register“ – S:\store\CBM\CBM prg Studio\test2\test-7.asm
    [Error ] Line 116:Invalid operand, label or variable „lda „$“ ;Dollar-Zeichen in den Akku“ – S:\store\CBM\CBM prg Studio\test2\test-7.asm

    Woran liegt’s?

    Grüsse,
    Chris

    1. Hallo Chris,
      das liegt daran, dass Arthur laufend die Kompatibilität zerstört und ich einfach keine Lust mehr habe, alles zu überarbeiten.
      Daher empfehle ich mittlerweile auch das C64 Studio von Endurion. Eigentlich müssten mal sämtliche Beispiele auf das C64 Studio umgestellt werden, aber dazu fehlt mir einfach die Zeit.

      Schreib einfach
      lda #"%"
      ldx #"0"
      lda #"$"
      (beachte die Raute #) und das „RUN ( )“ in Kleinbuchstaben „run ( )“, dann sollte es wieder klappen.

        1. Denk daran, dass du dann auch die Sourcen ändern musst.

          Ich finde es für Einsteiger allerdings suboptimal, wenn die auch noch die Beispiele anpassen müssen. Die Beispiele sollten direkt laufen. Daher denke ich gerade aktiv darüber nach, wie ich die Überarbeitung am besten auf die Reihe kriege.

          1. Hallo Jörn,

            ich „arbeite“ gerade ebenfalls gerade sämtliche Deiner Tutorials ab und kann Dir sagen, dass ich den gleichen Fehler, wie Chris, hatte. Es war allerdings bis dahin auch der erste und einzige. Von daher kann man, zumindest bis hier hin, auch noch ganz gut beim CBM prg Studio bleiben. Ich denke, ich werde den Umstieg aufs C64 Studio erst dann vornehmen, wenn es in Deinen Tutorials auch geschieht.

            Vielen Dank für diese wunderbare Seite. Sie sucht – vergeblich – ihresgleichen.

            Grüße Carsten

Schreibe einen Kommentar

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

Protected by WP Anti Spam