Beiträge von Vernunftmensch im Thema „Sid -> C64“

    Zitat

    Die Information welcher grösste, zusammenhängende Speicherbereich nicht von der Playerroutine verwendet wird, ist sicher auch eine nützliche Information für Dein Programm. Dort kann dann Deine Abspielroutine liegen. Und wenn der Bereich gross genug für das Hauptprogramm ist, könnte man das auch dort hin verschieben und am Ende wieder zurück verschieben, statt es neu zu laden.

    Mein Player spielt aktuell (fast) alle SIDs ab. Ich erkläre mir das so: Zunächst lädt er brav ein ausgewähltes SID in Bereiche, die egal sind. Je nachdem lädt er einen anderen Player nach, dem nur die abzuspielende Datei übergeben wird und am Anfang des Speichers steht. Dann scheint die Init-Routine scheins noch nicht viel zu machen. Und ausbreitend oder nicht scheint er dann meine Abspielroutinen nicht anzurühren, sobald ich sie mit allen Interrupts freigebe, d.h. Interrupt mit Flackern und die Variablenänderung (quasiparallel laufend).

    Trotzdem möchte ich gerne wissen, wie man den größten zusammenhängenden unberührten Bereich ermittelt, vielleicht könnte man dann sogar einen SID-Wechsel realisieren, während der eine noch läuft. Scheins geht das nicht immer, weil SIDPLAYER64 je nachdem nur noch einen schwarzen Bildschirm zeigt?

    Ich habe zwar eine Möglichkeit, Dateien mit Link anzusetzen, aber kann man nicht hier das auch irgendwie (immerhin reden wir von c64er-Dateien) ?

    Bitte melde dich an, um diesen Link zu sehen.
    - Quellcode
    - PRG-Dateien
    - BeispielSIDs (eine mit Playadresse $0000, die SIDPLAY64 nicht kann.)

    Wo finde ich SIDPLAYER64-source-dateien?

    Zitat

    Vernunftmensch: Du hast die Unterbrechungsbehandlung offensichtlich ohne sie zu verstehen übernommen. Du brauchst ja gar keine zwei verschiedenen Rasterzeilen für die Unterbrechung und das mit dem `zaehler` ist ein hässlicher Hack, weil die Unterbrechungsbehandlung für die Timer-Unterbrechung und zweimal pro Frame für durch eine Rasterzeile ausgeführt wird. Du rufst die Abspielroutine an der falschen Stelle auf.

    Ja, ich klaue mir alles zusammen. Manchmal denke ich nur nach, wenn es nicht funtioniert. Hier z.B. nicht. Kannst Du mir bitte die einfachere Routine posten, die Du meinst?

    Zitat

    Und das mit `MEM` könnte gefährlich werden.

    Wie wir Kölner sagen: Es hätt noch immer jutgegangen. :smile:

    Zitat

    A) Ich bin mir ziemlich sicher Du verwendest das Wort ”rekursiv” falsch. Und solche Lader gibt es sehr wahrscheinlich nicht. Wie willst Du zuverlässig Code und Daten trennen? Insbesondere wenn der Code sich selbst modifiziert und dadurch im Grunde beides ist. Und in den Daten, die sowohl als Operanden von Befehlen, als auch ”frei” in den reinen Datenbereichen vorkommen können, müsstest Du dann die Adressen identifizieren können, die angepasst werden müssen. Wobei die auch erst durch Berechnungen mit Werten entstehen könnten.

    Wunder verbringen die alle nicht. Aber vieles wird genau richtig disassembliert. Aber vieles auch nicht, hast Du auch Recht.

    Zitat


    Wenn Du einen allgemeinen SID-Player wie Sidplay 64 schreiben möchtest, und dafür C einsetzen willst, würde ich eher das Hauptprogramm in C schreiben und dann einen Lader+Player in Assembler für mehrere Positionen im RAM oder besser noch frei in 256-Byte-Schritten verschiebbar, der am Ende das Hauptprogramm wieder nachläd falls das von den Musikdaten oder beim Abspielen überschrieben worden sein sollte. Es gibt SIDs die wirklich viel Speicher benötigen, weil sie zum Beispiel Sampledaten enthalten oder die Initialisierungsroutine die Playerroutine und die Daten erst einmal quer über den ganzen Speicher verteilt. So ein Song muss nicht in dem Bereich bleiben, in den er geladen wurde!

    Sidplay 64 runtergeladen als .d64, seltsam, aber da sind keine SID-Dateien bei, nur PRG-Dateien. Seltsam.

    Ok, also bei cc65 ist ein Programm namens overlaydemo.c bei und die zugehörige*.cfg. Es wird gezeigt, wie man Segmente mehrfach beschreibt in c und wie man in der cfg erklärt, daß er alle Versionen in eigende Dateien beim Linken schreibt. Im Programm lädt er dann drei versch. Versionen ein und desselben Segments nach und ruft jeweils daraus eine Beispielprozedur. Da könnte man was von machen.

    Wenn ich höre, daß manche SIDs unkontrolliert Speicher benutzen außerhalb der Grenzen wird mir gruselig. :-S

    Zitat


    B) Man muss den Ladecode ausserhalb des Bereichs ablegen der durch das neue Programm belegt wird [1]_. Und dann kann man einfach laden und den geladenen Code mit den entsprechenden Aufrufen starten. Also entweder eine Assemblersequenz, die ein RUN ”nachbaut” oder direkt an die Startadresse springen, falls das nachgeladene Programm kein BASIC-Programm ist und die Startadresse bekannt ist.

    Für diesen Fall jetzt wahrscheinlich nicht so wichtig, aber man kann mit cc65 auch ”overlays” schreiben, in dem man in der Linker-Konfiguration mehrere Speicherbereiche mit den selben Adressen definiert und diese in verschiedene Dateien schreiben lässt und mit ``Bitte melde dich an, um diesen Link zu sehen.``-Anweisungen dann Funktionen und Daten gezielt in für diese Bereiche definierte Segmente platziert. Auf diese Weise kann man nachladbare Teilprogramme realisieren.

    .. [1] Das ist nicht ganz korrekt: Man könnte auch die Startadresse - 1 des nachzuladenen Maschinespracheprogramms auf dem (Hardware)Stack ablegen wenn die eigentliche Laderoutine tatsächlich der allerletzte Aufruf aus dem Code ist, der durch das Laden überschrieben wird.

    Ich habe da schon eine Idee. Die Programmversion, die bis auf die Startinitialisierung mit Code am Ende ist, die kann ja den Anfang mit dem zweiten Programm laden, das am Anfang allen Code hat. Das könnte wie Du sagst schief gehen, aber ich ziele sowieso nur auf die gutartigen SIDs ab...


    Zitat

    C) Ja natürlich. Beispielsweise die Lade-, Initialisierungs-, und Abspieladressen und die Quelle des Timings (Rasterzeile, CIA-Timer, Init macht was eigenes).

    Ich meinte die hier ganz unteren ab flags....

    cbm_load ("fire",8,NULL); (um in irgendsoein Beispielsprogramm zu springen)
    //__asm__ ("jmp $07ff");
    //__asm__ ("jmp $0801");
    __asm__ ("jmp $????");

    Wie bekomme ich leicht raus, wo die main-Funktion beginnt?

    Also einfacher als das:
    __asm__ ("jmp $c00a");
    rausgeholt durch anfrage in fire.c:

    Sehe gerade, daß das zu Problemen führen könnte, weil wohl aus START_UP erst nach Säuberungen in main gesprungen wird.....

    Ohne Interrupt völlig in c mit Schnelllader:


    Mit Interrupt völlig in c mit Schnelllader:

    Das spielt schon manche richtigen SID-Files ab:

    A@BlackJack:
    (rekursive Lader, die über Eingabeadresse Code und Data trennen und danach rel. verschieben, gibt es, dauern aber bei einem C64 unpraktisch zu lange. besser: zwei programme, bei denen der Code entweder am Anfang oder am Ende ist und ein kleines Programm, das aussucht, welches gebraucht wird.)

    B Beim C64er kann man doch in Basic komplett in ein neues Programm rüberspringen. Wie sieht das gleiche in C aus?

    C Sind im SID-Header wichtige Informationen, die das Abspielen betreffen?

    mit Startadresse noch drinnen:

    Klappt.

    Meine nächste Fragen:
    A Was gibt es beim C64 für Interrupts und wie kann man die ändern?
    B Welche Format haben die SID-Dateien?
    C Gibt es schon irgendwo eine Routine, mit der man immer ab $1000 schreiben kann, aber die Routine die JSR JMP BNE BEQ und soweiter alle anpaßt?

    Das Hauptprogramm:

    Die Linker.cfg:

    Immerhin startet der C64 das Hauptprogramm, welches folgendes macht, besser nicht macht. :sad:

    1. Mozart.dat einbeziehen mit Erfolgsmeldung (Vielleicht Programmfehler?)
    2. Abstürzen mit leerem READY.-Bildschirm bei lda #0 und jsr $1000, obwohl Sidplay das als Initialisierung angibt
    3. Zum eigentlichen Abspielen kommt er nicht.

    Woran liegts diesmal?

    Meine C-Datei:


    Meine Linker-Konfiguration:

    StartUp im LOWRAM: Warum schreibt der Computer nicht einmal mein printf ?

    Hier steht zwar veraltet und erledigt, aber ich habe mir alles durchgelesen und noch eine Frage:

    Wie spiele ich ein SID auf dem C64 mit CC65 ab? Ich habe schon mir von einem Vivaldi-SID mit Sidplay die .Dat erstellt und die Daten Initialisierungszeiger und Spielroutinezeiger aus den Eigenschaften herausgelesen. Jetzt möchte ich die Datei mit C nicht direkt einbinden. Wie ich die Datei an die Stelle $1000 byteweise oder blockweise schreibe weiß ich. In der Makefile kann man auch die Startadresse des eigentlichen Programmes angeben.
    @$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^ $(CLIB) Wie aber sorge ich dafür, daß cc65 den platz ab $1000 bis zum Ende der SID-Code-Datei freihält?

    Helmut