IRQ-Problem

Es gibt 19 Antworten in diesem Thema, welches 4.110 mal aufgerufen wurde. Der letzte Beitrag (13. April 2010 um 20:25) ist von domspitze.

  • Hallo,

    ich habe gerade den Einstieg in Crossassembler mit ACME gemacht. Ich versuche ein kleines Intro zu basteln. Habe dafür viel im Thread von TheRyk gelsen und viel gelernt. Scolltext, Rasterbar und Sprites sind mit drin, aber für diese Frage mal rausgenommen.

    Mein Code erstellt einen Rasterinterrupt. Der läuft auch prima. Nur nach meinem Verständnis müsste er nach abarbeiten der Routine und sprung zur ursprünglichne irq-routine JMP$EA31 doch wieder im Hauptprogramm "main" landen. Dort will ich eine Taste abfragen und dementsprechend das Intro beenden.

    Also die Frage: Warum erreicht mein Code nicht mehr das Hauptprogramm "main"?

    Code ist als TXT im Anhang. Würde gerne ihn einfach posten, weiß aber nicht wie.

  • mmmh, schwer zu sagen was da wirklich bei Dir passiert.
    Poste am besten mal den Code, bzw. die relevanten Stellen ;)

    Gruß

    Wenn einer, der mit Mühe kaum, geklettert ist auf einen Baum, schon meint, daß er ein Vogel wär, so irrt sich der.

    Wilhelm Busch

  • Du warst einfach schneller als ich mit dem Code hochladen :wink:

    64er-Zeitschriften gesucht:
    1984: 9 in gutem Zustand

    Ansonsten 64er 1984-1994 sind komplett wieder da. :D

  • Ja, inc $d019 muss noch in die IRQ-Routine. Ausserdem steht im Initialisierungsteil:

    Code
    lda #$00			;Rasterzeile $00 als
    sta $d012			;IRQ-Auslöser festlegen

    und in der IRQ-Routine dann

    Code
    lda #$ff 		; Bis Rasterzeile FF warten
    cmp $d012
    bne *-3		;warten damit wirklich die soundroutine alle 1/60 sekunden aufgerufen wird

    Die IRQ-Routine wird dann zwar in der ersten Rasterzeile ausgelöst, wartet aber beinahe den gesamten Frame ab, bis endlich die Musik abgespielt wird. Bei einer eher lahmen Musikroutine bleibt da nicht mehr viel Zeit für das Hauptprogramm übrig. Besser du entfernst die 3 Zeilen aus der IRQ-Routine.

  • Der Inc $d019 führt zu einem AcKnowlegde, d.h. ab dort weiß der Prozessor, das der IRQ einmal ausgeführt wurde.
    Gehört immer an das Ende einer IRQ-Routine.
    Nur zum Verständniss.
    Gruß

    Wenn einer, der mit Mühe kaum, geklettert ist auf einen Baum, schon meint, daß er ein Vogel wär, so irrt sich der.

    Wilhelm Busch

  • Nochmal zum "Zeitmanagement": Nachdem du den Fehler mit dem Einfügen von INC $D019 in den Interrupt behoben hast, würde ich mich darum kümmern. Denn derzeit verschwendest du mit deiner Routine knapp 255 Rasterzeilen vom IRQ-Auslösen bis zur ersten "sinnvollen" Interruptaktion. Das sind knapp 82 Prozent der Gesamtrechenzeit, die dir nicht mehr zur Verfügung stehen! Nicht gerade ökonomisch, oder? ;) (Wobei, bei deinem derzeitigen Code macht das nicht viel aus, aber wenn du später komplexere Sachen machst, musst du mit Zeit sparsam und sinnvoll umgehen, denn die ist wertvoll! :D)

    Entweder machst du es so wie Colt sagte, dann wird die Musik ab Rasterzeile $00 gespielt. Soll sie wirklich erst bei $FF gespielt werden, würde ich in der Initialisierung halt auch $FF in $D012 schreiben und den Warteteil ebenfalls weglassen, dann verschenkt man keine Zeit.

    BTW: Bei PAL-Maschinen wird der Raster-IRQ alle 1/50-Sekunden ausgelöst und nicht 1/60 wie bei NTSC und in deinen Kommentaren. ;)


    Aber nicht verzagen, weitermachen und probieren und dann wird alles gut, schließlich hat ja jeder mal so angefangen.

  • Hallo und danke für die vielen Antworten!

    Das hat mir echt weitergeholfen!

    Das ursprünglich hier abgebildete Programm (Code) läuft.

    Ich habe das dann in meine alte Intro-Routine eingebunden und nach einer Änderung läuft es (mit Einschränkung) auch da.
    Die Einschränkung ist: Am Anfang des Programms werden 3 Zeilen mit 120 <SPACE>-Zeichen vollgerschrieben (Routine siehe unten), um den Scrolltext sauber hinzustellen.
    Gebe ich dort die korrekte Anzahl von 120 ein blockiert er anscheinend die Rückkehr ins Hauptprogramm. Erst wenn ich den Wert heruntersetze funktioniert die Rückkehr wieder. Dafür werden nicht alle Zeilen von vorher sich dort im Speicher befindenden Zeichen befreit. Meine Vermutung, ich schreibe irgendwo was ungewollt in die falsche Speicherstelle. Blicke es leider aber nicht.

    Was ist der Fehler?

    Hier die Routine. Der gesamte Code (code002) befindet sich im Anhang.

    ;textzeilen löschen
    .zeilenlöschen
    ;Hier gibt es noch ein Problem
    lda #$20 ; Spaces in Scrollzeilen
    sta $0770,x
    lda #$01 ; Schriftfarbe in Scrollzeilen
    sta $d800+$398,x
    inx
    cpx Bitte melde dich an, um diesen Link zu sehen. ;früher $78 = 120
    bne .zeilenlöschen

    Ansonsten habe ich natürlich noch tausend fragen zur Intro und Demoprogrammierung.

  • Edit: Alles Quatsch was ich geschrieben hab, Kopfrechenprobleme :)

  • $d800+$389,x
    macht sicher nicht das was Du moechtest bei X > $0400-$398 = $68

    Bitte melde dich an, um diesen Link zu sehen.
    Bitte melde dich an, um diesen Link zu sehen.
    Bitte melde dich an, um diesen Link zu sehen.

  • Hi domspitze,

    der Fehler ist, dass Du mit dem

    sta $d800+$398,x (+ $77)

    voll in den CIA 1-Bereich (> $DC00) reinknallst. Dort wird dann u.a. das IRQ-Timing etwas durcheinander gebracht, deswegen der 'Absturz'.

    Richtig wäre:
    ---------------------
    sta $d800+$370,x

  • Hallo enthusi, hallo Camigo,

    Camigo hatte mit der Veränderung von $398 auf $370 vollkommen Recht. Ich habe eine Zeile zu spät angefangen und dann natürlich voll drüber geballert. Das hat den IRQ zum Absturz gebracht.

    Enthuis hat mich aber auf ne Idee gebracht. Ich schreibe meine 3 Zeilen mit <SPACE> in den Farbspeicher. Das klappt. Er schlägt vor direkt in den Bildschirmspeicher zu schreiben. Ich hab das als Routine umgesetzt.

    Farbram

    Code
    ;Alte Routine textzeilen löschen, setzt im Farbram
    .zeilenlöschen
    	    	lda #$20      ; Spaces in Scrollzeilen
             	sta $0770,x
             	lda #$01  	; Schriftfarbe in Scrollzeilen
             	sta $d800 + $370,x
             	inx
             	cpx #$78
    		bne .zeilenlöschen

    Bildschirmspeicher

    Code
    zeilenlöschen			;neue Routine textzeilen löschen, setzt im Bildschirmspeicher
    		lda #$20		;Space in Akku
    		sta $0400 +$370,x	;Space ab Zeile 23-Anfang in den Bildschirmspeicher
    		inx			; x um 1 erhöhen
    		cpx #$78		;ist x = 120 (3 Zeilen), dann ende
    		bne zeilenlöschen	;ansonsten zurück zu zeilenlöschen

    Frage: Gibt es da eine, die zu bevorzugen ist? Die Bildschirmspeicher-Lösung ist kürzer.

    Ansonsten wäre ich sehr an Infos rund um Demoprogrammierung interessiert. Ich kenne bereits Codebase64 -bin aber nicht so begeistert davon.
    Hab Fragen wie:
    1) Rasterbar über einer Bitmap
    2) Rasterbar unter Scrolltext
    3) Farbiger 1x1 Scrolltext - ich vermute, dass das auch mit Rasterbar klappt. Es geht hier nicht um einen Multicolor-Font.

    und tausend andere Dinge. Aber das würde den Thread sprengen.

    Genau so eine Thread fänd ich aber klasse. Vielleicht als Unterforum zu ASM. Also "Intro-Programmierung in ASM"

    Auf jeden Fall malwieder danke für die Hilfe!

    64er-Zeitschriften gesucht:
    1984: 9 in gutem Zustand

    Ansonsten 64er 1984-1994 sind komplett wieder da. :D

  • Das mit dem farbigen Text hab ich übrigens gerade hinbekommen. Blödsinn dafür Rasterbars zu nutzen. Der Farbram ist dafür auch super :smile:

    64er-Zeitschriften gesucht:
    1984: 9 in gutem Zustand

    Ansonsten 64er 1984-1994 sind komplett wieder da. :D

  • Jau, zu Fragen 1 und 2:
    Was sich im "Hintergrund" abspielen soll macht man idR mit d020/d021 und Chars/Bitmap und was sich im "Vordergrund" abspielen soll mit Sprites. Hintergrund ist meistens easy.
    Rasterbars über Chars/Bitmap mit Sprites ist etwas tricky, weil die Sprites einiges an Rastertime "klauen" ...

  • Zu deiner Frage, welche zu bevorzugen ist: Ich selbst würde die Bildschirmramroutine nutzen, die ist kürzer und braucht weniger lange. Um die zu Optimieren natürlich das lda #$20 VOR das label zeilenlöschen schieben, weil sich der Akku ja in der Routine nicht verändert, du ihn also nicht für jedes Zeichen neu laden brauchst (sind jedes mal 2 Zyklen (afair) *120 = 240).

    Zu deinen anderen Fragen von wegen
    1) Rasterbar über einer Bitmap
    2) Rasterbar unter Scrolltext
    Das wird meist einfach über einen RasterIRQ gelöst, der an der entsprechenden Zeile den Grafikmodus umschaltet, so kannst du verschiedene Bildschirmmodi zusammen anzeigen. Nur bei Sprites würde ich mich da jetzt nicht zu weit raushängen wollen wie das mit der Zeit ist, siehe spider-j's Post.

  • Hallo spider-j, hallo thasti,

    nette Ideen. Und ja, der lda-Befehl muss natürlich vor die Schleife verlegt werden. Schlamperei von mir!

    Das mit den Bildschirmmodi ändern durch den Raster-irq mach ich bereits bei meinem Intro, da ich im oberen Teil eine Bitmap und in den letzten 3 Zeilen einen Textscroll habe. Flackert beim Übergang etwas.

    Was ich nicht so ganz verstehe ist, wie man mit Sprites Rasterbars ÜBER einer Bitmap darstellen kann? Dumm gefragt, tun die Sprites so, als wenn sie Rasterbars wären - wohl eher nicht, da nur 3 Farben möglich sind. Oder werden die Rasterbars über die Sprites gelegt? Also das blicke ich nicht? Vielleicht findet ihr dafür noch ein paar erläuternde Worte. Danke!

    Vielleicht poste ich mal meinen Code zu meinem farbig -"schimmernden" Scrolltext. Ist vielleicht ne "Inspiration" für andere. Noch ist das allerdings zu umständlich programmiert. Auch wenn es funktioniert. :smile:

    64er-Zeitschriften gesucht:
    1984: 9 in gutem Zustand

    Ansonsten 64er 1984-1994 sind komplett wieder da. :D

  • Was ich nicht so ganz verstehe ist, wie man mit Sprites Rasterbars ÜBER einer Bitmap darstellen kann? Dumm gefragt, tun die Sprites so, als wenn sie Rasterbars wären - wohl eher nicht, da nur 3 Farben möglich sind. Oder werden die Rasterbars über die Sprites gelegt? Also das blicke ich nicht? Vielleicht findet ihr dafür noch ein paar erläuternde Worte. Danke!

    du meinst wohl den effekt der zb in vielen crackintros benutzt wird...rasterbars die sich mal vor und mal hinter einem logo bewegen?

    das prinzip ist simpel... zwei denkbare wege hast du schon genannt: im klassischen fairlight intro zb ist dieser "rasterbar" garkeiner, sondern besteht einfach aus sprites. das ist natürlich total einfach, aber man kann eben nur 3 farben benutzen. dann könnte man auch in der tat einen statischen spritelayer nehmen, und da durch umschalten einer multicolorfarbe rasterbalken reinmachen (die dann auch vor der bitmap sein würden). das hat aber vielerlei nachteile, wird timing kritisch (bin mir grad nichtmal sicher ob das bei voller breite überhaupt sauber geht) und allgemein unhandlich :)

    der klassische ansatz ist dieser:

    - die grafik als zeichensatz anzeigen
    - in der rasterroutine ausser d020/21 für die farben auch d018 jede line umschalten
    - die d018 tabelle manipuliert man dann beim bewegen der rasterbars so das da wo diese "vor" der grafik sein sollen auf einen zeichensatz geschaltet wird der keine grafikdaten enthält, und ansonsten eben auf den charset mit den grafikdaten

    (auch ausprobierenswert an der stelle: statt d018 mal d016 zusätzlich jede line umschalten, und da wo rasterbars sind irgendwelche andren werte reinschreiben. so lassen sich auch ein paar aus diversen intros bekannte effekte erzielen)

  • Dumm gefragt, tun die Sprites so, als wenn sie Rasterbars wären - wohl eher nicht, da nur 3 Farben möglich sind. Oder werden die Rasterbars über die Sprites gelegt? Also das blicke ich nicht? Vielleicht findet ihr dafür noch ein paar erläuternde Worte. Danke!

    Vergiss es einfach wieder. Die d018-Methode ist für Rasterbars schon besser. Hatte das aus irgendeinem Grund mal mit Sprites getestet, aber schon wieder vergessen warum :(
    Man ändert dann eben zusätzlich zu $d020 noch die Spritefarbe:
    Bitte melde dich an, um diesen Anhang zu sehen.


  • das prinzip ist simpel... zwei denkbare wege hast du schon genannt: im klassischen fairlight intro zb ist dieser "rasterbar" garkeiner, sondern besteht einfach aus sprites. das ist natürlich total einfach, aber man kann eben nur 3 farben benutzen.


    Ausserdem gibt es bei dieser Methode noch ein Problem mit den Sprite-Prioritäten, denn nur 2 der 3 Vordergrundfarben sind wirklich im Vordergrund, wenn die Spritepriorität nach "hinten" geschaltet ist.

  • Ersteinmal danke an alle, die mir bisher geholfen haben. Ich bin inzwischen etwas weiter vorgedrungen und beschäftigte mich mit der Sprite-Programmierung (auf dem Bild übrigens das C64 Logo). den Stand der Dinge könnt ihr im Bild sehen. Alles noch ganz am Anfang.
    Wo ich nochmal dran muss ist die Rasterbar-Routine. Da flackert es noch. Aber ich lese gerade den IRQ-Kurs aus der Magic Disk.

    Über Programmiertipps zu allen möglichen Effekten freue ich mich sehr. Gerne auch als Mail.

    Bitte melde dich an, um diesen Anhang zu sehen.

    64er-Zeitschriften gesucht:
    1984: 9 in gutem Zustand

    Ansonsten 64er 1984-1994 sind komplett wieder da. :D