Adressen nur noch hexadezimal schreiben!
Echt? Mach ich heut noch nicht immer. Manche Adressen weiß ich eher in Hex auswendig, aber manche Zahlen liegen mir irgendwie eher in Dezimal.
Du bist in Begriff, Forum64 zu verlassen, um auf die folgende Adresse weitergeleitet zu werden:
Bitte beachte, dass wir für den Inhalt der Zielseite nicht verantwortlich sind und unsere Datenschutzbestimmungen dort keine Anwendung finden.
letzter Beitrag von Hexworx am
Adressen nur noch hexadezimal schreiben!
Echt? Mach ich heut noch nicht immer. Manche Adressen weiß ich eher in Hex auswendig, aber manche Zahlen liegen mir irgendwie eher in Dezimal.
Ok, peinlich, aber ich scheitere schon am Anfang. Ich will die Farben des Bildschirms ändern. Aber es tut sich nichts...
Und zwei Fragen:
1) die erste Zeile gibt die Startadresse an, richtig? Woher weiß ich wo ich eigentlich starten darf? Und was macht z.B.:
^^das verstehe ich überhaupt nicht. Trotz Internet...
2) was genau sind diese Labels? Einfach nur sowas wie Post-ITs zur besseren Lesbarkeit?
Viele Größe
Es tut sich nichts? Also wenn Du das so assemblierst, das resultierende File lädst und per SYS49152 startest, dann sollte der Bildschirm schwarz werden. Was danach passiert, ist offen, da das RTS fehlt.
Und zwei Fragen:
1) die erste Zeile gibt die Startadresse an, richtig? Woher weiß ich wo ich eigentlich starten darf?
Aus dem C64-Speicherschema. Du darfst eigentlich überall von $0801 bis $9fff (Basicbereich) und von $c000 bis $cfff (ungenutzter Bereich) starten, aber sinnvollerweise nimmt man den Anfang eines der beiden Bereiche. Und wenn man bei $0801 startet, ist eine vor das Programm gehängte Basic-SYS-Zeile sinnvoll, damit man das Programm nach dem Laden ganz normal per RUN starten kann, anstatt SYS<Startadresse> eingeben zu müssen.
Das ist eben genau die besagte Basic-Startzeile, die eine SYS-Anweisung direkt hinter diese Zeile enthält. Wenn Du diesen Teil assemblierst, lädst und LISTest, kommt: "2013 SYS 2062".
$0b $08 => Zeilenlink, bekommt man bei LIST nicht zu sehen
$dd $07 => Zeilennummer 2013 in Low/High
$9e => SYS als Basic-Token
$20 => Leerzeichen in PetSCII
$32 => 2 in PetSCII
$30 => 0 in PetSCII
$36 => 6 in PetSCII
$32 => 2 in PetSCII
$00 => markiert das Ende der Basic-Zeile
$00 $00 => markiert das Ende des Basic-Programms
was genau sind diese Labels? Einfach nur sowas wie Post-ITs zur besseren Lesbarkeit?
Zum einen das, und zum anderen werden ihre Werte vom Assembler verwaltet und automatisch angepasst, wenn man z.B. irgendwo einen Befehl einfügt oder löscht.
Das erste Listing übersetzt ein Maschinenprogramm an der Adresse $C000 , also dezimal 49152.
Der Akku A wird mit 0 geladen und dann schreibst du diesen Wert für die Rahmenfarbe in $D020 und Hintergrundfarbe $D021. Also mit 0: Schwarz auf Schwarz.
Was noch fehlt: ein RTS am Ende. Damit beim Ende des Programms auch am richtigen Ort zurückgekehrt wird.
Wenn du das erste Listing übersetzt als PRG und mit LOAD"TEST",8,1 lädst, kannst du es mit SYS49152 starten und mit dem RTS kommst du zurück ins BASIC (aber schwarz auf schwarz).
Das zweite Listing erstellt einen BASIC Starter. Das ist am richtigen Ort (an der BASIC Startadresse $0801) ein kleines BASIC-Listing in der folgenden Form erstellt:
10 SYS 49152
(Nur ein Beispiel, ist nicht deins)
<Edit>Mac war natürlich schneller und gründlicher
damit passiert wirklich nichts. Auch nach SYS 49152:
damit genauso:
damit wird alles - bis auf die Schrift - schwarz:
damit wird alles - bis auf die Schrift - schwarz:
Das RTS scheint wohl wichtig zu sein. Danke!
"Du darfst eigentlich überall von $0801 bis $9fff (Basicbereich) und von $c000 bis $cfff (ungenutzter Bereich) starten, aber sinnvollerweise nimmt man den Anfang eines der beiden Bereiche. Und wenn man bei $0801 startet, ist eine vor das Programm gehängte Basic-SYS-Zeile sinnvoll, damit man das Programm nach dem Laden ganz normal per RUN starten kann, anstatt SYS<Startadresse> eingeben zu müssen."
Frage: was ist sinnvoller/schöner/sauberer? Oder sind beide Varianten "gleich" und ihr würfelt immer?
Der Prozessor des C64 kennt kein fertig, oder nichts tun. Der ackert einen Befehl nach dem anderen ab.
D.h. nachdem deine Farben gesetzt sind, macht der Prozessor an der nächsten Speicherstelle weiter. Was immer da liegt, ist relativ undefiniert. In deinem Fall hat es zu einem Soft-Reset geführt, was auch die Farben wieder zurücksetzt
"Schöner" ist natürlich ein BASIC-Start, du willst dir (und deinen Benutzern) ja nicht zumuten, irgendeine Sys-Adresse zu wissen und aufzurufen.
Das mit dem BASIC Start hat auch den folgenden Hintergrund:
Willst Du mit LOAD"TEST",8 oder LOAD"TEST",8,1 laden? Mit BASIC-Start: Es ist egal.
Siehe auch hier: Welches Programm wird mit "*" gestartet
"Schöner" ist natürlich ein BASIC-Start, du willst dir (und deinen Benutzern) ja nicht zumuten, irgendeine Sys-Adresse zu wissen und aufzurufen.
Klar, das macht Sinn! Danke!
Das mit dem BASIC Start hat auch den folgenden Hintergrund:
Willst Du mit LOAD"TEST",8 oder LOAD"TEST",8,1 laden? Mit BASIC-Start: Es ist egal.
Siehe auch hier: Welches Programm wird mit "*" gestartet
Super Beitrag. Danke auch!
Es war eine sehr schwere Geburt (ca. 5,5 Stunden), aber ich habe 3 Sprites am Bildschirm und verstehe auch was ich da gemacht habe
Bei deinem Code fehlt stets das achte Sprite (Spritepointer_7), hat das einen Grund?
PS: Bei so Sachen wie den Sprite-Farben oder Pointern mach ich es meist eher so: Definiere SpriteColor = $d027, und dann im Code schreibe ich nur noch sta SpriteColor + 0 (für Sprite 0) bzw. +1 für Sprite 1 usw. Das spart Schreibarbeit
Squidward: Ja, ich habe nur 7 Sprites (0 - 6), deswegen fehlt das achte Sprite.
Hier der fertige Code.
Was noch fehlt:
1) etwas "Musik"
2) den Reset der Animation später ausführen (statt 255 Frames nach ca. 2550 Frames) -> weiß hier jemand einen Rat?
2) den Reset der Animation später ausführen (statt 255 Frames nach ca. 2550 Frames) -> weiß hier jemand einen Rat?
Mach doch noch 'ne Schleife mit Y drumrum.
Die meisten der 'ldx/dex/stx/cpx/beq'-Orgien kann man auch mit 'dec SPRITE/beq' erschlagen (außer beim cpx #70, da müsste das 'cpx' bleiben und halt ein 'ldx SPRITE...' davor.
So, nachdem es jetzt eigentlich fertig war, bin ich vor 3 Stunden auf die tolle Idee gekommen den kompletten Bildschirminhalt auszunutzen. (ich weiß gar nicht mehr wie ich darauf kam...)
D.h. den Rand nicht nur schwarz färben, sonder oben und unten ausschalten. Das hat dann zu "Geisterbildern" geführt und ich habe mich dann weiter mit dem Rasterzeileninterrupt beschäftigt.
Ich habe folgende Links versucht zu kombinieren, aber es will nicht so recht.
http://www.retro-programming.d…eren-unteren-rand-offnen/
http://www.retro-programming.d…er-rasterzeileninterrupt/
Probleme:
1) der Rand ist immer noch da!
2) Die Sprites flackern 2 mal (links unten)
Das ist mein Code:
Kann sich das bitte jemand anschauen und mir sagen wo ich den Fehler / die Fehler mache? Ich komme einfach nicht drauf.
cmp SET24ROWS -> cmp #SET24ROWS !!
oh man.... Danke!!!
Aber das flackern bleibt. Ich habe das mal etwas zerlegt. Und der Rasterzeileninterrupt scheint viel zu oft zuzuschlagen.
Code:
was läuft hier falsch?
Du must den Interrupt bestätigen (lda $d019: sta $d019), sonst bleibt das Signal die ganze Zeit aktiv. Statt LDA/STA gehen auch read-modify-write-Befehle wie z.B. ASL oder DEC, aber das versagt dann auf SuperCPU und Konsorten.
EDIT: Als Beispiel:
-Du stellst Dir einen Wecker (Interrupt einrichten).
-Du tust irgendwas (Hauptprogramm).
-Der Wecker klingelt (Interrupt wird aktiv).
-Du reagierst darauf (Interrupt wird abgearbeitet).
-Du schaltest das Klingeln ab (Interrupt wird bestätigt). Genau dieser Schritt fehlt.
stimmt, das hat gefehlt. Aber was läuft das hier falsch. Die Sprites flackern...
In Zeile 205 und 206 ist die Bestätigung.
So, nach eine längeren Pause bin ich wieder dabei das Ding fertig zu bekommen.
Die Grafik/Animation ist fertig.
Heute habe ich mein USB2IEC unter Win10 zum laufen gebracht und den Code auf einem echten C64 getestet. Läuft 1A.
Jetzt die neue Herausforderung: Wie bekomme ich am einfachsten Sound rein? Es muss erstmal nicht viel sein. Einfach 4-5 unterschiedliche Töne in einer Schleife. Mit Pause zwischen den einzelnen Tönen.
Kann mir jemand helfen?
Einfach 4-5 unterschiedliche Töne in einer Schleife. Mit Pause zwischen den einzelnen Tönen.
Zunächst ein genereller Ratschlag: Was Du beschreibst, sieht danach aus, als möchtest Du eine Warteschleife programmieren, die jeweils wartet, bis ein Ton ausgeklungen ist, um dann den nächsten Ton zu erzeugen oder am Ende zum eigentlichen Programm zurückzuspringen. Das wäre die typische Art und Weise, wie man z. B. auf dem AppleII programmieren würde. Beim C64 gibt es dafür jedoch die viel elegantere Möglichkeit, für solche Zwecke den Interrupt zu verwenden. Mache Dich bitte mit dem Gedanken vertraut, die Interruptprogrammierung zu erlernen. Am C64 geht letzten Endes ohnehin kein Weg daran vorbei.
Hier mal ein Beispiel (ohne Interrupt) für eine Sounderzeugung aus einem realen (Adventure-)Spiel für den Soundeffekt: "Leiter raufgehen":
Hier eine Routine, die eine einstimmige Melodie spielt:
Achtung: Das ist sehr schlechter Stil! Das liegt daran, daß der Programmierer hier den Soundcode vom AppleII direkt auf den C64 übertragen hat. Zwar kann man beim C64 davon ausgehen, daß die Geschwindigkeit der Warteschleife immer gleich ausgeführt wird, da der Original-C64 stets mit 1Mhz läuft. Aber bei einer Erweiterung wie der 65816-Turbokarte oder dem TC64 (im beschleunigten Modus) gibt es hier arge Probleme. Nun kann (und sollte) man natürlich die Warteschleife ähnlich mit Zugriff auf $d011 und $D012 programmieren, wie Du es bereits bei der Animation gemacht hast. Dennoch wäre dies nur eine halbe Lösung. Meine dringende Empfehlung daher nochmal an Dich: Bitte lerne zunächst mal die Interruptprogrammierung, am besten gleich den Rasterinterrupt mit dem VIC. (Den anderen mit dem CIA wirst Du wahrscheinlich sowieso nicht brauchen.)