Posts by WebFritzi

    Neptun und atomcode: Danke für eure Ausführungen. Das macht einiges klarer. Jetzt raffe ich erst, dass ich dann in meinem Spielchen auch einfachen Text im HiRes-Mode darstellen kann.


    Frage bleibt für mich: Warum benutzt das Farb-RAM nur halbe Bytes? Wofür wird das obere Nibble genutzt? Man hätte ja auch das siebte Bit für die Umschaltung HiRes-MC verwenden können.

    Ist ein bisschen wie bei Master Mind. :) Ja, die Restriktionen sind hart. Da staunt man manchmal, wie farbenfroh die Spiele im Char-Mode werden können.

    Perfekt zusammengefasst. Ich mache auch gerade ein kleines Spielchen und habe mich anfangs geärgert, dass alles so doof aussah, bis ich auf diese zusätzliche Restriktion gestoßen bin. Weißt du vielleicht, warum das so ist -- also, dass man für die Zeichenfarbe nur 0-7 wählen darf?

    Dafür hast Du doch "lda $d019, bmi doRasterIrq" eingebaut?

    Wenn Du vor den 2 Befehlen was gemacht hättest, dann würde sich die Geschwindigkeit ändern.

    Da hast du recht. War mir gar nicht mehr bewusst. Nachdem ich die CIA-IRQs gekillt hatte, hatte ich nämlich auch diesen Code gelöscht. War ja nicht mehr nötig.

    Grasnarbe (braun, grün, schwarz, blau) und dann diese Rahmensteine (grau, weiß, schwarz). Wie soll das gehen?

    Es ist halt kein blau, sondern grau (Steine im Erdreich). Sonst hättest du Recht. Weiß und grün (01 und 05) sind bei diesen Chars die variablen Farben.

    Aha! Got it! Also, schwarz ist Hintergrund. Dann ist grau eine MC-Farbe. Die andere ist entweder braun oder grün. Bei den Rahmensteinen ist weiß die Zeichenfarbe, bei der Grasnarbe entweder grün oder braun.


    Squidward Verstehe ich nicht. Was genau meinst du? Was ich weiß, ist, dass man für die Zeichenfarbe nur eine der ersten acht Farben wählen kann (allerdings muss man 8 dazu addieren, sonst wird's murks).

    Was mir vorher gar nicht klar war: wenn ich den CIA-IRQ nicht ausschalte, läuft mein Ball mit doppelter Beschleunigung.

    Ich bezog mich darauf und nicht wie oft der IRQ-Handler aufgerufen wird.

    Naja, aber wenn der IRQ-Handler nun zweimal pro Bildschirm-Frame aufgerufen wird, dann läuft der Ball eben mit doppelter Beschleunigung, weil x zweimal vergrößert wird, bevor der Sprite gezeichnet wird.

    Hallo mal wieder! Ich beziehe mich auch auf Endurions Spiel -- und zwar auf das Bild in Beitrag No. 8 auf Project J - Wir schreiben ein C64 Spiel in mehreren Schritten. So wie ich das verstanden habe, benutzt Endurion für sein Spiel kein HiRes, sondern ein eigenes Character Set. Wahrscheinlich im MultiColor-Mode. Aber wie kriegt er so viele Farben auf den Bildschirm? Fest sind immer die Hintergrundfarbe und die zwei MultiColor-Farben. Das sind drei unveränderbare Farben (die man natürlich verändern kann, aber dann werden sie für den ganzen Bildschirm verändert -- es sei denn, man benutzt einen gerissenen stabilen Raster-IRQ). Es bleibt eine zusätzliche Farbe für jedes Zeichen. Schauen wir uns zwei verschiedene Charaktere im Bild an. Da haben wir einmal eine Grasnarbe (braun, grün, schwarz, blau) und dann diese Rahmensteine (grau, weiß, schwarz). Wie soll das gehen? Wo ist der Trick?

    Jo, so wie ich das verstehe, ändere ich in Zeile 79 den Pointer, der in 314/315 steht -- und zwar zeigt der dann auf meine Raster-IRQ-Routine, die in Zeile 28 beginnt. Das bleibt während der kompletten Laufzeit meines Programms so. D.h., auch bei Auslösen eines CIA-IRQs springt der Prozessor in meine Zeile 28. Somit wird mein Code öfter durchgeführt als 50 mal pro Sekunde (in der Regel zweimal, vielleicht sogar dreimal).


    Vorher dachte ich, dass CIA-IRQs einfach immer nur direkt in $ea31 springen. Aber das ist wohl nicht so. Auch sie nehmen den "Umweg" über den Pointer in 314/315.

    Das dürfte eigentlich nicht der Fall sein, da ja nur in die Routine verzweigt wird, wenn ein Raster-IRQ anliegt.

    Hmm, auf https://www.c64-wiki.de/wiki/IRQ#ISR_des_KERNAL steht aber, dass der normale IRQ den Code ausführt, auf den $314/$315 verzweigt. Das ist normalerweise $ea31. Nun steht da aber die Adresse meines Handlers drin. Also müsste doch der CIA-IRQ auch dahin springen, oder nicht?


    Da ist bei mir noch etwas merkwürdig. Wenn ich einen Zähler mitlaufen lasse, der bei jedem Raster-IRQ-Aufruf um eins erhöht wird und der Handler erst ausgeführt wird, wenn der Zähler bei 10 ist, dann müsste mein Ball sich ja jede 1/6 Sekunde bewegen. Tut er aber nicht. Es ist ungefähr jede 1/4 Sekunde... (Ich habe den CIA-IRQ ausgeschaltet.)

    Nochmal vielen Dank für eure Antworten, Leute! Toll, dass es noch deutschsprachige C64 ASM-Profis gibt. Könnte gut sein, dass ich euch demnächst mal wieder belämmere. Ich habe einige Erfahrung mit C/C++ und tue mich doch ein wenig schwer mit Assembler. Wenn ich eine neue Routine schreibe, habe ich eigentlich immer mondestens einen Fehler drin. Den entdecke ich durch ausprobieren, wodurch der C64 des Öfteren auch mal abstürzt. Kein Problem mit C64-Studio + VICE, aber früher muss das ein Pain in the Ass gewesen sein. Hut ab vor den Leuten, die in den 80ern ASM gelernt haben und dann so tolle (funktionierende!) Spiele geschrieben haben.


    Was mir vorher gar nicht klar war: wenn ich den CIA-IRQ nicht ausschalte, läuft mein Ball mit doppelter Beschleunigung. Ich dachte vorher, der CIA-IRQ läuft unabhängig von meinem und löst nur die Standard-Prozedur in $ea31 aus. Aber der geht offenbar auch in die Prozedur, auf die in $314/$315 verwiesen wird -- also meinen Handler. Deshalb wird der Ball viel häufiger bewegt und ist somit schneller. Aufgrund der unterschiedlichen Trigger-Zeiten (1/60 vs 1/50 sec) müsste der Ball eigentlich auch unterschiedliche Geschwindigkeiten haben. Ich werde mal drauf achten.

    Das Problem das ich sehe ist eher, dass Du zwei IRQ-Trigger laufen lässt, einer vom VIC mit 50Hz und einer vom CIA mit 60Hz. Die können sich hie und da in die Quere kommen, wenn sie annähernd gleichzeitig getriggert werden.

    OK, also mal allgemein gefragt: wie ist das eigentlich mit den IRQs? Sagen wir, ich schalte den CIA-IRQ nicht ab (habe ich jetzt allerdings) und sagen wir weiterhin, dass meine Routine gerade läuft, wenn der CIA-IRQ getriggert wird. Was hat dann Priorität - mein IRQ-Handler oder der CIA-IRQ? Springt dann der Prozessor kurzzeitig aus meiner Routine raus, um nach dem Abarbeiten des CIA-IRQs wieder neu einzuspringen? Oder wartet er auf mein RTI?

    Eventuell befindet sich im Konfigurationsmenü des Monitors die Möglichkeit, eine Overdrive-Funktion einzuschalten, wodurch die Schlieren reduziert werden.

    Dass das nichts mit VICE zu tun hat, kann man auch hier unter "Reaktionszeit" nachvollziehen: https://www.eizo.de/monitortest/

    Aha, interessant. Sogar bei minimaler Geschwindigkeit zeigen sich im Test Schlieren "hinter" dem weißen Rechteck. Mein Laptop-Monitor läuft mit 60 Hz. Würde sich das mit den Schlieren ändern, wenn ich ihn auf 50 Hz drosseln könnte?

    Leider weiß ich nicht, was Overdrive ist und kann es im Konfigurationsmenü der Grafikkarte auch nicht finden.

    Herzlichen Dank für eure Beiträge, Leute!

    Du behandelst den CIA-IRQ noch extra, ich würde ihn in Deinem Fall eher ausschalten (sonst könnte es auch zu vereizelten Rucklern kommen, wenn Du zur gefragten Rasterzeilte gerade in der ROM-Routine bist). Das erreichst Du in Deiner set_irq Routine mit


    Code
    1. lda #%01111111 ; disable CIA irq: Bit 7 sets the value, Bit 0...4 selects the bits to be set
    2. sta $dc0d
    3. lda $dc0d ; acknowledge any pending CIA irq

    Ok, verstehe. Danke dir. Aber dann habe ich z.B. auch kein Cursor-Blinken mehr, nicht wahr? Vielleicht könnte ich auch am Ende meines IRQ-Handlers zur Standard-CIA-Prozedur jumpen? Das wären dann zwar 50 statt 60 Hz, aber was soll's...


    EDIT: Habe ich jetzt gemacht, und es läuft. Allerdings nicht wirklich besser. Ist auch irgendwie klar, weil sich mein Ball in der vertikalen Mitte des Bildschirms befindet und der IRQ in Rasterzeile 0 ausgelöst wird. Die paar Ticks, die für die Aktualisierung der x-Koordinate nötig sind, sollten spätestens in Zeile 2 durchgeführt sein. Oder habe ich etwas übersehen?

    Hi Neptun!

    Schlieren sollte es eigentlich nicht geben. Verwendest du einen Emulator?

    Ja, WinVICE 2.2. Ich werde es gleich nochmal auf meinem TheC64 ausprobieren. Aber da das genauso ein Emulator ist, fürchte ich denselben Effekt. Er ist nicht stark. Es sieht halt bissl so aus als ob der Ball einen dünnen Schweif hinter sich herzieht.


    >> zu 2: Zeile 54 vor einer Subtraktion mußt du das Carry-Bit setzen. Da gehört ein Sec hin.

    Autsch! Vielen Dank. Das war es! Das hatte ich nicht auf dem Schirm. Gucke mir gleich nochmal SBC genauer an.



    >> Noch was: Der Code, der in den Zeilen 68 bis 73 steht, befindet sich auch im ROM. Du kannst die Zeilen also weglassen und statt jmp exitirq, jmp $febc schreiben.

    Oh, das ist gut, danke. Hab gerade nochmal in der Beschreibung des Kernels nachgeschaut. Es stimmt: bei Adresse $FEBC steht "Interrupt-Ende (holt Register Y, X, A vom Stack und RTI)".


    BTW: Wie kann ich hier mehrfach schön zitieren anstatt den ">>"?

    Hallo!


    Gleich vorweg: ich bin ein totaler Neuling auf Assembler-Gebiet. Nun wollte ich mal anfangen mit einem einfachen Programm, das einen kleinen Sprite-Ball von links nach rechts (X=255) und wieder zurück usw. springen lässt. Alles mit konstantem Y-Wert. Das habe ich auch geschafft, aber es gibt Probleme. Damit das Ganze mit dem Bildschirm einigermaßen synchronisiert wird, habe ich einen einfachen Raster-IRQ eingesetzt, der bei Bildschirmzeile Null in meine Routine geht. Die Probleme sind:


    1. Der Bildschirm refresht 50 mal pro Sekunde. Wenn ich also einfach $d000 um eins erhöhe, sind das ca. 50 Pixel pro Sekunde und damit zu langsam. Aber einigermaßen smooth. Also bin ich zu einer Addition von #$04 übergegangen. Das ist zwar das Tempo, das ich mir vorgestellt habe, zieht aber Schlieren. Kann man das irgendwie vermeiden?
    2. Wenn der Ball nach links geht, läuft er schneller, obwohl ich genauso #$04 abziehe. Das verstehe ich nicht. Hat jemand eine Erklärung dafür?

    Hier mein gesamter Code:

    Wow, BIF. Vielen Dank! Daraus habe ich einiges gelernt. Wusste gar nicht, dass man den Grafikspeicher verlegen kann. Aber warum ist das hier nötig? Das sehe ich noch nicht so.


    Und auch der Doppelpunkt bei IF war mir neu. Normalerweise bewirkt IF bla THEN bla1:bla2, dass wenn bla stimmt, dann bla1 UND bla2 ausgeführt werden. Ich verstehe, dass jetzt so, dass IF bla THEN :bla1:bla2 bewirkt, dass NUR bla1 ausgeführt wird, wenn bla stimmt. bla2 wird in jedem Fall ausgeführt (wie eine neue Zeile). Stimmt das so?

    Der VIC sieht die Adressen nur innerhalb seines aktiven 16kB-Blocks. D.h., wenn der auf $c000 bis $ffff steht, dann gelten die Sprite-Pointer-Werte ab $c000.

    Und was mache ich, damit der "auf $c000 steht"? Wenn ich POKE2040,13 schreibe, dann ist die Referenz Null, und es wird in den Kassettenpuffer geschrieben. Wie stelle ich die Referenz also auf z.B. 49152?

    Ei, Neptun,. ich bin ja so ein Blödmann. Habe gerade gemerkt, dass ich meine Sprite-Definitionen ab 12800 habe und der kopierte Zeichensatz vom c64-wiki-Beispiel bei 12288 anfängt. Jetzt wird mir einiges klar... Tausend Dank, dass du mich darauf aufmerksam gemacht hast.


    Du schlägst also vor, den Zeichensatz direkt vor den VIC zu legen. Da liegt also 2k frei belegbarer Speicher? Ich folge einfach deinem Vorschlag... EDIT: Nur wie? In 2040, 2041, usw. lege ich ja die Sprite-Pointer fest. Ich habe dort zur Zeit POKE2040,200 stehen, d.h. mein erster Sprite ist an Adresse 200*64 = 12800 gespeichert. Will ich den nun an Adresse 49152 = 768 * 64 speichern, müsste ich ja POKE2040,768 schreiben, aber der Wert geht ja nur bis 255. Wie legt man denn Sprites ab Speicherstellen >=256 * 64 = 16348 ab?

    Hi nackteule. Vielen Dank! Das geht ja einfacher als ich dachte. Ich habe die Version mit Maschinencode von deinem Link genommen. Allerdings habe ich jetzt ein Problem. Ich verwende nämlich Sprites. Zuerst hatte ich es so, dass ich zuerst die Sprites geladen habe und dann den Zeichensatz geändert. Das hat die Sprites dann total verfälscht. Liegt wohl irgendwie an dieser Doppelbelegung von den VIC-Registern (habe davon keine Ahnung!). Dann habe ich die Änderung des Zeichensatzes an den Anfang meines Programms gestellt und die Sprites danach geladen. Die Sprites sehen jetzt gut aus, aber der Zeichensatz ist nicht korrekt kopiert. Die normalen Buchstaben A-Z sind ok, aber z.B. SHIFT+E ist jetzt einfach leer (die inverse Version ist korrekt kopiert). Woran könnte das liegen?


    [Den Code habe ich korrekt übernommen. Das sehe ich daran, dass SHIFT+E vollkommen ok ist, wenn ich das Programm nach dem Ändern des Zeichensatzes per END stoppe.]