Disassemble Blog: Ihatovo Monogatari

Sprachbarrieren halten Dich vom Spielen Deines Herzchenspiels ab? Du willst eines Deiner Herzchenspiele Mal ganz neu erleben? Dann bist Du hier genau richtig.

Moderatoren: ikari_01, d4s, Redscorpion

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 3. Dezember 2012, 20:26

Dieses Board hat zu wenig Thread-Leichen. Also noch eine. Noch ein viel zu enthusiastisches Projekt. Ich nehme mal "Ihatovo Monogatari" komplett auseinander, aber komplett, ey.

Und werde nach jeder Arbeitsstunde einen Bericht schreiben. Einfach so, weil ich so gerne schreibe, und von euch beweihräuchert werde.

Darum starte ich auch ein Projekt, was ich nur machen werde, wenn ich Lust dazu habe. Und wenn ich keine Lust mehr habe, höre ich einfach auf.

Einfach so.

Tja, ja.

Also.

Vorarbeit
Ich habe mir auf superfamicom.org angeschaut, was es für interessante Infos es über das Spiel gibt. Es ist... 8MBit groß, hieß es dort. Also nur zwei Drittel von SoM. Außerdem ist es LoROM. Das ist einmal gut zu wissen, und ein zweites Mal gut, weil ich mit HiROM noch nie gearbeitet habe.

Also bezog ich mir daheim die ROM und war erstaunt: Sie ist nur 600kb groß!
Im Hexeditor angeschaut, sah ich, dass der Letzte Byte bei $000F.FFFF liegt. Das heißt, das Dingens hat 32 Bänke (weil 0 bis F = 16, und 16 mal 2, weil $1.0000 = zwei Bänke).

Meine Güte, das ist ja... ich bin so arrogant zu sagen: Überschaubar.

Desweiteren habe ich schonmal auf den Reset-Vektor geschielt und sehe ein "00 80". Also: Das Spiel fängt am Anfang der ROM an. Okay. Schon. Chic. Fangen wir an.

Stunde 1
Disassembled: 143 / 1.048.576 Bytes (0,013%)
Gehört: Wamdue Project - Resource Toolbox, Volume One

Der erste Byte, den ich nicht verstehe, ist der Dreizehnte. Da steht

Code: Alles auswählen

LDY #0000.w
PHY
[u][b]STY $EF[/b][/u]
PLD
Also: Die Direct-Page wird erst mit PLD gesetzt, das heißt, man weiß nicht, wo er das jetzt hinschreibt, weil ja noch sonstwas im Direct Page Register stehen könnte. Deshalb vermute ich mal, das "STY $EF" ist einfach nur, um die Zeit totzuschlagen...?
~~~
Okay, es wird in den Native Mode geswitcht, der Stack Pointer gesetzt, das Direct Page Register gesetzt, Interrupts disabled ($4200), DMA/HDMA ausgeschaltet und in die vier APU-Register geSTZtet. Danach wird eine Subroutine auf Bank 10 ($A) aufgerufen. Interessanterweise geht es nach dem JSL $0A8000 auf Bank 0 gleich weiter mit... "SEI CLC XCE". Komisch. "Alternativer Anfang"?
~~~
Auf Bank $0A werde ich zweimal herumgeschubbst (bzw.: herumgesprungen) und lande schlussendlich vor der SPC-Ini. Ich kann immer noch kein Stück SPC-Programmierung und habe davor immer noch einen Heiden-Respekt, dementsprechend verstehe ihc, worauf es hinausläuft, wenn ich ein "LDX #$BBAA" sehe, und mein Selbstvertrauen in Bezug auf dieses Projekt wechselt dementsprechend sofort den Aggregatzustand. ;)
Glücklicherweise werde ich gleich mit einem "RTS" danach erlöst. ;)
~~~
Puh, this stuff is serious. Reichlich verwirrend, mit vielem gebranche und Gehobse. Und dabei ist das noch die Init! ;)
~~~
Um das Ganze noch komplizierter zu machen, wird jetzt gerade noch ein LDA-Befehl benutzt, den ich vorher nicht kannte. "Indirect Long Indexed, Y". Also... es wird Y als Direct-Page-Offset genutzt, und ein Byte als Adresse auf dieser Direct Page übergeben. Wenn jemand etwas so flexibel schreibt, mag er es entweder unnötig kompliziert, oder wird diese Funktion noch für jeden erdenklichen Mist nutzen. Help.

Stunde um, Resümee:
Ich bin gerade an das Ende einer weiteren Subroutine gekommen, die sich noch um die Initialisierung des SPC kümmert (es werden fleißig die Register $2140 bis $2143 bedient). Bisher verstehe ich das ganze nicht im Detail, und es kommen einige Befehle, die für mich keinen Sinn machen, wo ich nicht weiß, ob mein Disassembler wieder spinnt, oder ob da wirklich Nonsense getrieben wurde, um Prozessor-Cycles vergehen zu lassen (man hätte auch NOP nutzen können, aber es gibt sicherlich andere Befehle, die innerhalb derselben Menge an Speicherplatz, die diese Befehle einnehmen, mehr Cycles verschwendet haben).

Es ist eigentlich egal. Der klare Vorteil, den man hat, wenn man ein Programm disassembled, ist, man kann es beim Neu-Assemblen in der Größe verändern. Dementsprechend ist es auch egal, wenn ich den gesamten SPC-Teil nicht verstehe; Hauptsache, ich tippe ihn richtig ab, dass beim Re-Assemblen alles beim Alten bleibt, und der relevante Teil wird der sein, von dem ich mehr verstehe - die Grafiken.

Mal schauen. :)

EDIT: Um mich vollends lächerlich zu machen, habe ich mal die Datei nach meinem jetzigen Stand angehängt, sodass alle Super-Programmierer hier sehen können, dass ich so gut wie gar nichts innerhalb einer Stunde disassembled habe! :D

EDIT 2: Für einen etwaigen Foren-Umzug habe ich hier den Beitrag editiert.
Dateianhänge

[Die Dateierweiterung txt wurde deaktiviert und kann nicht länger angezeigt werden.]

Zuletzt geändert von lytron am 4. Dezember 2012, 18:33, insgesamt 3-mal geändert.
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
ChronoMoogle
snesfreaks.com-Team
snesfreaks.com-Team
Beiträge: 9895
Registriert: 26. Februar 2007, 14:56
+Positive Tradingpoints+: 98 von 98
Wohnort: Nippon
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von ChronoMoogle » 3. Dezember 2012, 20:32

Du tust es wirklich! Respekt! :D
Mach reichlich Notizen fuer Romhacker, dieses Spiel ist noch nicht uebersetzt worden :)
Bild
| Mein YT Channel | Mein Twitter | Ich suche | Ich verkaufe | Foren SuFu |
...weil Terranigma einfach das Größte ist!

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 4. Dezember 2012, 08:30

Kleiner, statistischer "Big Fun":

Ich habe 143 Bytes disassembled.
Die ROM ist 1.048.576 Bytes groß.

Das sind 0,013% Prozent. Wenn ich jede Stunde so viele Bytes disassemblen würde, dauert das 7.332 Stunden, das sind 305,5 24-Stunden-Tage.

Werde ich aber nicht, allein eine einzelne bildschirmfüllende Tilemap würde diese Bytezahl um ein vielfaches erhöhen. Und soetwas muss man ja nicht disassemblen.
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 4. Dezember 2012, 19:45

Stunde 2
Disassembled: 189 / 1.048.576 Bytes (0,018%)
Gehört: Kante - Zombi


Da ich gestern so wahnsinnig viel disassembled habe und damit in Bezug auf auseinandergenommene Datenmenge supergut im Zeitplan liege (ich kneife gerade nur so das eine Auge zu, ist entspannter für mich, so), habe ich beschlossen, mich vorerst mal um die "Qualitätssicherung" zu kümmern.
Ich werde eine Assembler-Datei soweit vorbereiten, dass ich den disassembleten Kram assemblen kann und dann im Abgleich sehen kann, ob ich das alles richtig auseinandergepflückt habe.
Danach gehts dann locker-flockig weiter.

~~~
Interessante Sache. Wenn ich alles von der Bank 0 bis zum JSL (inklusive) einfüge, und danach das einfach kompiliere, taucht hinter der JSL-Adresse ein "$40" (RTI) auf.
Interessant, interessant...
~~~
Nachdem ich für meine Tutorials endlich den Sinn der ".ORG"-Angabe mir angelesen habe, kann ich es hier endlich nutzen. In der "echten" ROM springt man ja kreuz und quer durch den dichtbepackten Sourcecode, ich kann mittels ".ORG" (in Verbindung mit "FORCE") einzelne Segmente an dieselben Stellen in der ROM legen. Damit stimmen dann wenigstens schonmal die Adressen, auch wenn das reichlich beknackt aussieht, Sourcecode in der ROM mit einer Häufigkeit wie Planeten im Weltall zu finden.
~~~
Okay, es sind gut vierzig meiner sechzig Minuten vorbei, ich habe alles kompiliert... und es ging. Also, es ist alles chic. Woozah, damit habe ich nicht gerechnet, dass ich bisher keinen Fehler beim Disassemblen gemacht habe.
Ja, liebe Leserschaft: Manchmal vergesse selbst ich, wie großartig ich bin. 8)
~~~
Hihi, lustig.
Gestern habe ich irgendwas disassembled und war plötzlich an einen "BRA" gekommen, ein "Branch always", also gleichzusetzen mit einem "Jump". Das führte mich offensichtlich in derselben Subroutine gut 100 Bytes weiter. "Wozu die Lücke?" fragte ich mich. Jetzt scheine ich verstanden zu haben. Am Ende dieses zweiten Teils steht ein "Branch if Overflow Set", ein BVS, der genau an den Anfang dieser Lücke springt.
Es scheint alles so richtig zu sein, es scheint auch irgendwie so etwas in der Art von sinnhaft zu sein, aber bisher vollends ausgefreakt. "BVS" ist noch so ein Befehl, von dem ich nie gedacht hätte, dass er wirklich irgendwo gebraucht wird, wo es nicht ums Rechnen mit komplizierten Formeln geht. Mai, man lernt nie aus. Und all dieser Quark für eine Init? Weeeiiird, bro.

Stunde um, Resümee:
Ich habe jetzt diese reine TXT-Datei der ersten Stunde in eine "richtige" ASM-File umgebogen und schon kompiliert. Getestet habe ich sie nicht, das muss ich ja auch nicht - es gibt nichts zu sehen, aber vieles, was einem um die Ohren fliegen würde. ;)
Desweiteren habe ich jetzt viele Vergleiche mit den APU-Registern gesehen und dazwischen viele seltsame, seltsame Befehle. Langsam kommt es mir so vor, als ob das vielleicht eine Art von Kopierschutz ist. "Lasst uns ganz viel krankes Zeug in den Anfang unserer ROM schreiben, dass es keiner wagt, unseren Sourcecode zu klauen." Hm. Okay.

Übrigens kam mir der lustige Gedanke: Was, wenn das Spiel irgendetwas enthält, was es überhaupt unübersetzbar macht, und somit diese Arbeit hinfällig ist...?

Ich will da nicht drüber nachdenken. ;)
Dateianhänge
Stunde 2.rar
(2.18 KiB) 218-mal heruntergeladen
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
Svambo
Hardcore SNES-Freak
Hardcore SNES-Freak
Beiträge: 571
Registriert: 14. September 2009, 19:09
+Positive Tradingpoints+: 13 von 13

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von Svambo » 4. Dezember 2012, 23:25

Um mal eine ganz dumme Noob-Frage zu stellen:

Wie disassemblierst du das eigentlich? Ich hab bei meinen wenigen Versuchen mit sowas immer den Geiger-Debugger genommen und eine log-Datei erstellt. Geht rasend schnell und man findet doch tatsächlich vieles (und versteht in meinem Fall weniges davon).
Welche Tools nutzt du?

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 5. Dezember 2012, 05:24

Svambo hat geschrieben:Um mal eine ganz dumme Noob-Frage zu stellen:

Wie disassemblierst du das eigentlich? Ich hab bei meinen wenigen Versuchen mit sowas immer den Geiger-Debugger genommen und eine log-Datei erstellt. Geht rasend schnell und man findet doch tatsächlich vieles (und versteht in meinem Fall weniges davon).
Welche Tools nutzt du?
Den Geiger-Debugger hatte ich auch mal versucht, auf Grund der Empfehlung von ikari_01. Lief bei mir nicht, ich bekam nur Fehlermeldungen.
Nachdem mein Vertrauen in Dispel erschüttert wurde, weil es damals diese Dwarf-ROM nicht gefressen hat ("Die ROM ist zu klein"), nutze ich diesen JavaScript-Disassembler, der wohl der schlechteste vom Schlechtesten ist. Aber mittlerweile weiß ich, wo seine Bugs sind, und zumindest mir hilft es, so genaue Kontrolle darüber zu haben, was ich als nächstes auseinandernehmen will. Außerdem kann ich für mich selbst schneller sehen, was falsch auseinandergenommen wurde, und es notfalls neu auseinandernehmen, statt "blind" es in ein Kommandozeilenprogramm zu nehmen. Bei sowas wäre ich im großen Zweifel gewesen, ob dieser SPC-Kram, den ich bis jetzt auseinandergenommen habe, nicht doch vielleicht Grafikdaten sind. ;)
Und da du allgemein nach Tools fragst: Der Rest der Programme, die ich nutze, ist Standardware. WLA DX zum Assemblen, HxD als Hexeditor und irgendein Texteditor, der mir Assemblercode schön farbig darstellt, damit ich in dem Wust nicht komplett die Übersicht verliere.
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
ikari_01
snesfreaks.com-Team
snesfreaks.com-Team
Beiträge: 441
Registriert: 15. Juni 2010, 23:19
+Positive Tradingpoints+: 6 von 6
Wohnort: Wunstorf

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von ikari_01 » 5. Dezember 2012, 08:33

Code: Alles auswählen

	STA $2142.w
	SEP #$20
	CPX #0001.w	; Waste of Time?
	LDA #$00.b
	ROL a		; Waste of Time?
	STA $2141.w
Keine Waste of Time ;) CPX setzt das Negative-, Zero- und Carryflag, LDA nur Negative und Zero. Mit ROL wird dann also das Carryflag als Ergebnis des CPX ins LSB vom Akku geschoben.
D.h. wenn X >= #$0001, dann wird A = #$01, ansonsten #$00. Der Wert kommt dann nach $2141. Anschließend:

Code: Alles auswählen

	ADC #$7F.b	; !?!?
	PLA			; !?!?
	STA $2140.w
	RepeatingLoop1:
	CMP $2140.w
	BNE RepeatingLoop1
	BVS SPCIntro4	; $0005:1F8B
ADC #$7F addiert #$7F zum letzten A-Wert (#$00 oder #$01), da das Carry-Flag durch das ROL an der Stelle immer 0 ist.
War A = #$01, ist das Ergebnis #$80; dadurch wird das Overflow-Bit gesetzt, das durch PLA und CMP nicht beeinflusst wird, also bis zum BVS in der letzten Zeile durchschlägt.
Sieht insgesamt nach einer ziemlich elegant programmierten verschachtelten fußgesteuerten Schleife aus, mit datenabhängigem Wiederholungskriterium für die äußere Schleife. Hübscher Code. :)
sd2snes news: https://sd2snes.de

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 5. Dezember 2012, 15:15

Zuerst einmal einen ganz lieben Dank für die Unterstützung, ikari_01! :)

Die Flags waren bei mir vollkommen hinten runtergefallen, an die hatte ich überhaupt nicht gedacht. Ich muss gestehen, dass ich recht schnell mich damit zufrieden gegeben habe, dass das "halt irgendsoein SPC-Zeug" ist, und habe deshalb da nicht viel Hirnschmalz drauf gegeben... :oops:

Und darum danke für die Hilfe.

Was mich etwas verwundert hat, war das "PLA" an einer Stelle (du zitierst es ebenfalls). Ich habe dort nicht genau draufgeschaut, aber ich meine, es gibt kein zugehöriges "PHA" o. ä. zu Beginn der Subroutine wird gePHPt, aber am Ende folgt das dazugehörige "PLP" (meine ich; ich sage das gerade aus dem Kopf, kann gerade nicht nachschauen), und somit gehört dieses wohl zu jenem.

Aber eigentlich kann ich auch mit einem "Is halt so" mich auch ganz gut arrangieren. ;)
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
ikari_01
snesfreaks.com-Team
snesfreaks.com-Team
Beiträge: 441
Registriert: 15. Juni 2010, 23:19
+Positive Tradingpoints+: 6 von 6
Wohnort: Wunstorf

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von ikari_01 » 5. Dezember 2012, 15:37

Code: Alles auswählen

	SPCIntro3:
	PHA
:D
sd2snes news: https://sd2snes.de

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 5. Dezember 2012, 17:58

ikari_01 hat geschrieben:

Code: Alles auswählen

	SPCIntro3:
	PHA
:D
Hm. Dass du lügst und es hier nachträglich eingefügt hast, ist offensichtlich. Aber wie hast du das "PHA" auch in die Datei gekriegt, die bei mir auf dem Desktop liegt? o_O
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
ChronoMoogle
snesfreaks.com-Team
snesfreaks.com-Team
Beiträge: 9895
Registriert: 26. Februar 2007, 14:56
+Positive Tradingpoints+: 98 von 98
Wohnort: Nippon
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von ChronoMoogle » 5. Dezember 2012, 18:07

Ich finde du solltest dich wirklich in den Aufbau von Musikengines reinlesen, dass koennen von den aktiven Homebrewern nur sehr wenige, wenn ich mich nicht irre. Vielleicht hat er ja noch einen kleinen Tipp fuer dich auf Lager um die besser zu verstehen.

Weiter so und gib dein Bestes Bro! :D
Bild
| Mein YT Channel | Mein Twitter | Ich suche | Ich verkaufe | Foren SuFu |
...weil Terranigma einfach das Größte ist!

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 5. Dezember 2012, 19:31

ChronoMoogle hat geschrieben:Ich finde du solltest dich wirklich in den Aufbau von Musikengines reinlesen
Ich habe zwischen den Feiertagen Urlaub. Mal schauen. ;)

Stunde 3
Disassembled: 434 / 1.048.576 Bytes (0,041%)
Gehört: Invalids - Eunoia; Reno Dakota - You scalded me, Bravo! (2x)


ChronoMoogle wies mich auf die Notizen für ROM-Hacker hin, und das erinnerte mich daran, dass ich schon gestern eine "ROM Map" erstellen wollte. Oder, was ich mich darunter vorstelle.
Ansonsten konnte ich heute morgen schon einen kleinen Lunz in den Quellcode lunzen und dort erlunzen, dass es auf Bank 0, auf die ich jetzt nach dem SPC-Kram gestern endlich zurückkehre, erstmal mit einer halbwegs normalen Register-Init weitergeht. Heute kann ich was an Bytes reißen, woohoo!
~~~
Also, Init, immer noch Init, auch 100 Bytes weiter. Mir geistert ikaris "elegant programmiert" immer noch im Kopf herum. Das Gute ist zu wissen, dass man demnach weiß, woran man ist - wenn ich in Zukunft vor einer Sache stehe, die ich nicht verstehe, muss ich mir nicht die Frage stellen: "Bin ich zu dämlich oder zu sachkundig, um das vollkommen unsinnig zu finden?". Die Frage erübrigt sich damit nämlich.
Jetzt gerade habe ich einen großen Teil der, wie es so schön heißt, BUS-B-Register ($21xx) absolviert und jetzt gerade stehe ich vorm Clearen einiger Direct-Page-Register (sprich: Variablen). Und hier werden gerne 16-Bit-Nullen in diese Register gespeichert. Damit sind dann zwei Variablen auf einen Streich gecleart (was mit STZ nicht klappen würde).
Elegant programmiert, wie gesagt.
Und dennoch einfältig genug, dass ich es verstehen kann. :D ;)
~~~
Okay, da lobe ich die Programmierer, und in der -ungelogen- nächsten Zeile gehen sie zu STZ bei vier aufeinander folgenden Registern über.
Und dadurch habe ich auch etwas gelernt.
Über mich.
Ich sollte schlicht aufhören, andere Menschen für intelligenter als mich zu halten. 8)
~~~
@ikari_01: Wegen meiner PM von heute morgen: Es wird #$FF in dieses WIO-Latch-Register-Schingeling gespeichert.
~~~
"Elegant programmiert", die zweite (bzw. dritte):
Die DMA-Register werden per Schleife gecleart. Jedes Register aller Channels in je einem Schleifendurchlauf. Das lustige ist: Es wird rückwärts gemacht, also der Counter wird auf $000A gesetzt und dann per STZ $4300, X; STZ $4310, X;... auf alle Channels angewandt und dekrementiert.
Würde man es andersrum, "richtig herum", machen, müsste man am Ende X nochmal leeren. ;)
~~~
Oh, und bei dieser Schleife wieder einen neuen ASM-Befehl gelernt.
BPL. Branch if Plus.
~~~
Öh...
Äh...
Es gibt WRAM-Register!? O_O :D :D :D
Coole Sache. Sind die Register $2180 bis $2183 zum "einfachen Kommunizieren" mit Bank $7D/$7E?
~~~
Ich glaube, die Frage nach den WRAM-Registern hat sich erledigt, weil wieder ein sehr tricky-ger Loop geschrieben wurde, der ganz offensichtlich den RAM cleart:

Code: Alles auswählen

LDX #$0000.w
LDY #$0000.w
STY $2181.w
STZ $2183.w
WRAMRegClearLoop:
STZ $2180.w
DEX
BNE WRAMRegClearLoop
Finde ich cool gemacht mit dem LDX #$0000.w, DEX, BNE. Damit ist ganz einfach sichergestellt, dass es "mal eben, easy," 32.000mal durchläuft. ;)

Stunde um, Resümee:
Mensch, das sind schon schlaue Hunde, woll?
Ich habe gerade noch einmal abschließend meine ROM kompiliert und mit der Original-ROM verglichen. Es gab einige Abweichungen, z. B. weil ich zwei Rauten vergaß und statt Bytewerte DP-Register ausgelesen habe, außerdem hatte ich ein, zwei Loops falsch gesetzt.
Am erstaunlichsten fand ich, dass in oben beschriebener DMA-Channel-Clear-Schleife Channel 7 nicht gecleart wird. Ich hatte ihn automatisch mit hineingenommen, und erst beim Vergleich der ROMs und anschließenen Betrachten der Disassembler-Daten gesehen, dass dort kein "STZ 4370, X" in der Reihe steht. Vielleicht wird der Channel ja gleich im Anschluss genutzt...?

Vielleicht mache ich auch gleich nochmal ne Stunde weiter. ^.^
Dateianhänge
Stunde 3.rar
(2.91 KiB) 210-mal heruntergeladen
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 5. Dezember 2012, 21:28

Stunde 4
Disassembled: 530 / 1.048.576 Bytes (0,051%)
Gehört: Wamdue Project - Resource Toolbox, Volume One


Und weiter geht's mit unserem fröhlichen Disassemblen der Init-Prozedur!
~~~
Auch ohne ein Tutorial bzgl. der WRAM-Register gelesen zu haben, scheint es mir doch klar zu sein, wie sie funktionieren, wenn er jetzt noch einmal denselben Loop durchführen lässt, aber vorher in das Bank-Adressregister eine 01 statt 00 schreibt.
~~~
Woohoo, jetzt schreibt er was in $2115! Gleich schreibt er in $2116 und $2118! Ich bin ja so aufgeregt! ^.^
~~~
Hm. Jein. Er schreibt in $2116, und macht dann ein JSL. Allerdings führt das zu einer Subroutine, die auf derselben Bank liegt. Warum JSL? Vielleicht prophylaktisch, weil der/die Programmierer noch nicht wussten, auf welche Bank sie am Ende die Subroutine verschieben würden.
~~~
Hm. WLA DX sagt: "Do not try to change the bank". Wobei, oh, ich glaube, ich weiß woran das liegt.
~~~
Aaah; äh, oh...
"Do not try to change the bank" ist WLA DX' Art zu sagen: "Du hast ein '.ENDS' vergessen".
~~~
Ich habe alles kompiliert, und muss leider feststellen: Nein, du hast keinen Fehler gemacht, die...
OH! ICH VERSTEHE!
ICH VERSTEHE, warum man einen JSL macht, auch wenn die Subroutine auf derselben Bank liegt:
Sie muss ja nicht bei jedem Aufruf auf derselben Bank liegen. Und man muss sich halt vorher entscheiden, ob man ans Ende "RTS" oder "RTL" setzt.
Was ich vorher sagen wollte: Ich habe keinen Fehler gemacht, augenscheinlich führt der Jump-Befehl wirklich dahin. Wie doof, das sieht schon wieder so kompliziert aus... >_<
Die Subroutine sieht so aus, als wäre es eine allgemeine DMA-SR. In Verbindung mit meinem spontanen Geistesblitz bzgl. "RTS" und "RTI" wohl eine, die für *jedes* Mal, in der ein DMA benötigt wird, herangezogen wird. Holla, die Waldfee. Aber vielleicht kann ich damit schon die Bedeutung einiger DP-Variablen festsetzen. ;)
~~~
Okay, jetzt ist schon wieder der Punkt erreicht, wo ich ikari_01 anbetteln würde, dass er sich das anguckt. :D
Es wird eine DMA-Subroutine aufgerufen, die den Stackpointer in X überträgt und dann Variablen lädt und auf den ersten Direct-Page-Registern ablegt. Danach führt es im zweiten Teil der Subroutine eine Bestückung der DMA-Register in Abhängigkeit von diesen Variablen ab. Ich vermute fast, dass man diesen zweiten Teil auch unabhängig vom ersten Teil nutzen kann.
Ferner habe ich in der Original-ROM gesehen, dass die nächste Subroutine wieder ein DMA ist. Allerdings werden dort mit festen Werten gearbeitet. Und da zunächst in Register $2102 gespeichert wird, gehe ich mal davon aus, dass es ein Sprite-DMA ist.
Hm. Ich überlege, ich überlege...
Wenn ich den Stack Pointer nehme, und ich gehe gerade davon aus, dass das Ding bei $01FF steht, und LDA $03, X und LDA $01, X, heißt das, dass ich die ersten Variablen jenseits des Stacks ($0202 und $0200) aus dem RAM nehme. Aber die müssten doch eigentlich leer (ich meine = $00) sein, oder?

Stunde um, Resümee:
It leaves me bewildered. So wirklich steige ich durch die DMA-Funktion noch nicht durch. In jedem Falle finde ich dieses Ding doch sehr reizvoll. Und wirklich weiterkommen werde ich ohne auch nicht. Es ist davon auszugehen, dass hier die ersten Grafikdaten übertragen werden (die Register, die vorbereitet wurden, bevor diese Subroutine aufgerufen wurde, lassen das nahe liegen), allerdings kann ich diese nicht lokalisieren, solange ich die Funktionsweise speziell des ersten Teils der DMA-Subroutine nicht checke.
In jedem Fall: Sehr interessant, das Ganze.
Dateianhänge
Stunde 4.rar
(3.22 KiB) 238-mal heruntergeladen
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Benutzeravatar
ikari_01
snesfreaks.com-Team
snesfreaks.com-Team
Beiträge: 441
Registriert: 15. Juni 2010, 23:19
+Positive Tradingpoints+: 6 von 6
Wohnort: Wunstorf

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von ikari_01 » 5. Dezember 2012, 23:27

Nun, "JSL DMA" legt drei Bytes auf dem Stack ab, nämlich Bank und Offset der Rücksprungadresse minus 1. RTL zieht die wieder vom Stack und die CPU weiß dann, wo es nach dem JSL weitergeht. Auf dem Stack liegt also die Adresse des Codes DIREKT nach der JSL-Instruction.

Der Stackpointer ist nach dem JSL ein Byte "vor" der Rücksprungadresse, also liegt die Rücksprungadresse bei SP+1 bis SP+3. Diese Adresse wird nach DP $00-$02 kopiert:

Code: Alles auswählen

	TSX			; Stackpointer --> X
	LDA $03, X
	STA $02
	REP #$20.b		; A = 16
	LDA $01, X
	STA $00
Danach wird der Stack manipuliert: Die Rücksprungadresse wird um #$0008 erhöht:

Code: Alles auswählen

	LDA $01, X
	CLC
	ADC #$0008.w
	STA $01, X
Das bedeutet, dass das RTL nicht direkt hinterm JSL weitermacht, sondern 8 Bytes weiter hinten.

Die unmodifizierte "Originalrücksprungadresse" liegt ja nun bei DP:$00-$02. Jetzt passiert etwas total Tolles:

Code: Alles auswählen

	LDY #$0001.w
	LDA [$00], Y
	INY
	STA $4300.w, X
	LDA [$00], Y
	INY
	STA $4301.w, X
usw.
Hier wird per long indirect indexed load ([$00],Y) die Adresse bei DP:$00-$02 als 24-Bit-Pointer genutzt, anschließend wird Y addiert (=1) und dann von der so errechneten 24-Bit-Adresse ein Wert gelesen.
Doch halt - die 24-Bit-Adresse müsste doch die Rücksprungadresse sein, direkt nach dem JSL?! Richtig! Und das ist genau das Geniale an dieser Funktion: Direkt nach dem "JSL DMA" kommt gar kein Code, sondern DATEN! Nämlich die DMA-Parameter, die hier nun einfach nacheinander in die DMA-Register kopiert werden.
Darum wird die "echte" Rücksprungadresse fürs RTL um 8 Bytes erhöht - um die Daten zu überspringen.

Es wird hier also einfach der "Codebereich" hinterm JSL DMA genutzt, um die DMA-Parameter unterzubringen. Wenn du an der Stelle mal ins ROM schaust, solltest du Werte finden, die als DMA-Registerinhalte sinnvoll sind.
sd2snes news: https://sd2snes.de

Benutzeravatar
lytron
Code Bro
Code Bro
Beiträge: 2664
Registriert: 12. August 2012, 20:18
+Positive Tradingpoints+: 12 von 12
Wohnort: ハノーファー区
Kontaktdaten:

Re: Disassemble Blog: Ihatovo Monogatari

Beitrag von lytron » 6. Dezember 2012, 07:24

Öhm...

... du bringst mich ein wenig in Verlegenheit, ich weiß nicht, was ich sagen soll...

... auch wenn ich geschrieben habe, dass ich da nicht weiterkomme und dich diesbezüglich um Hilfe bitten wollte, möchte ich dich dennoch wissen lassen, dass ich es alles andere als selbstverständlich ansehe, dass du mir hierbei zur Seite stehst.

Vielen lieben Dank, ikari!

Ich schätze, ich hätte mehrere Stunden gebraucht, um diese Funktion zu knacken, wenn ich mir bewusst gewesen wäre, dass JSL den Stack beeinflusst. Und ob ich darauf gekommen wäre, ist fraglich. Und ohne diese DMA-Subroutine und die "anhängenden" Grafikdaten hätte das alles hier ein ganz schnelles Ende gefunden.

Folglich hast du dieses Vorhaben direkt vorm Scheitern bewahrt. Danke, ikari! :)

Gestern war mir auch aufgefallen, dass direkt nach dem JSL wieder "komischer Code" steht; es fing mit einem "ORA" an, was für mich wenig Sinn machte, wenn man direkt aus der DMA-Vorbereitung und -Einleitung kommt. Jetzt weiß ich den Kram zu interpretieren und werde dann heute, morgen oder übermorgen wissen, wie ich weiterzumachen habe. :)

Ein drittes Mal "Danke", dieses Vorhaben hat dafür gesorgt, dass in meinem Kopf gar nicht erst der Gedanke aufkommt, dass ich jetzt automatisch alles verstehen kann, was im 65816-Assembler geschrieben ist; es sind nicht nur 256 Befehle, sondern auch eine gute Kenntnis der "Umgebung" wie der Funktionsweise des Stacks und die Auswirkung von Befehlen auf das Statusregister von nöten. Eigentlich hätte ich nicht gedacht, so überzeugt von meinen Fähigkeiten zu sein, aber dass ich mit diesem Thread angefangen habe, zeigt ja, dass ich davon ausgegangen war, nicht so früh überfordert zu werden. :D
pantalytron: ルトロンはくそのディスアセンブラだよ!
Perikles hat geschrieben:Man muss sich das mal reinziehen: die Idee ist scheiße, die theoretische Ausarbeitung ist scheiße, die praktische Umsetzung ist scheiße und der so entstehende Anspruch noch beschissener.

Antworten