Patches erstellen

geschrieben am 29.05.2013 18:32:05
zuletzt bearbeitet von MarioFanGamer am 30.05.2013 6:48:24.
( Link )
Anmerkung: Es ist mein erstes Tutorial. Also hoffe ich, dass ihr es so gut wie es versteht. Verbesserungsvorschläge sind erwünscht .

Hallo und das ist mein erstes Tutorial und ich zeige wie man
HIJACKT UND PATCHES ERSTELLT!!! (ja übertrieben )

Nötige Sachen
Einen Wissen, wie man Patches einfügt
Einen Assembler (Xkas oder [besser] Asar)
Notepad
Free Space Logger (oder früher nötig: HxD Hex Editor und SNEStuff)
Hex2ASM (Hex Edits)
All.log
ASM Grundwissen
Eine Rom und einen Backup der Rom

Erste Schritte
Bevor man erstmals einen Patch erstellt, sollte man das am Anfang haben:
Code
lorom         ; Tausche zu hirom aus, wenn die Rom eine sogenannte HiRom ist.
header ; Ist die Rom eine .sfc Datei, dann lösche es.

Nun kopiert es in eine neue .asm Datei und schon habt ihr eine Nutzlose .asm Datei .

Assembler sind SNES-Hex Editoren
Stimmt wirklich, denn erinnert ihr euch an das Tutorial von RPG
Zitat von RPGHacker:
LEKTION 7: INDEXING

Kommen wir nun zu einer der, wie ich finde, nützlichsten Funktionen in ASM, wenn man denn in er Lage ist sie zu meistern. Ich rede vom Indexing.

Ziemlich am Anfang habt ihr den Akkumulator (oder "A") als ein Register kennengelernt, mit dem man verschiedene Rechnungen durchführen und noch viel mehr anstellen kann. Nun möchte ich euch zwei Register vorstellen, die dem Akkumulator sehr ähnlich sind, jedoch noch ein paar Zusatzfunktionen haben und dafür ein paar Dinge nicht können, die der Akkumulator kann. Ich rede von den X- und Y Registern, auch "Index Register" genannt.

Viele der Befehle, die es für den Akkumulator gibt, gibt es auch für die X- und Y Register. Z.B. gibt es LDX und LDY zum laden von Werten und Adressen, STX und STY zum Speichern der Werte in Adressen, INX und INY bzw. DEX und DEY zum erhöhen bzw. verringern der Register, CPX und CPY zum Vergleichen der Register mit einer Zahl und sogar noch viele mehr. Das alles ist aber nur nebensächlich. Was diese Register viel interessanter macht ist das so genannte Indexing.

Stellt euch vor ihr wolltet einen Block machen, der abhängig von eurem Powerup verschiedene Routinen ausführt. Sagen wir einfach mal er soll eure Münzen um eine je nach Powerup variierende Anzahl erhöhen:

Small Mario - 10 Münzen
Super Mario - 25 Münzen
Cape Mario - 35 Münzen
Feuer Mario - 50 Münzen

Nach unserem bisherigen Wissen sollte das in etwa so aussehen:

Code
LDA $19
CMP #$00 ; Powerup nicht 0? Mario nicht klein!
BNE Nichtklein
LDA #$10
BRA Addieren

Nichtklein:
CMP #$01 ; Powerup nicht 1? Mario nicht Super Mario!
BNE NichtSuperMario
LDA #$25
BRA Addieren

NichtSuperMario:
CMP #$02 ; Powerup nicht 2? Mario nicht Cape Mario!
BNE NichtCapeMario
LDA #$35
BRA Addieren

NichtCapeMario: ; Dann kann Mario höchstens noch Feuer Mario sein
LDA #$50

Addieren:
CLC
ADC $0DBF
STA $0DBF


Wie ihr seht, ist das schon ganz schön viel Schreibarbeit. Nun stellt euch mal vor ihr hättet nicht 4 verschiedene Werte, sondern 100. Da sähe die Sache nochmal ganz anders aus. Weil das wohl auch den Programmierern von damals zu blöd war, erfand irgendeiner schlauer Kopf das Indexing, das einem eine Menge Arbeit erspart. Hier nun der obige Code nochmal, bloß mit Indexing:

Code
LDX $19
LDA MuenzTabelle,x
CLC
ADC $0DBF
STA $0DBF

MuenzTabelle:
db $10,$25,$35,$50


Woah! Das sieht doch schon mal wesentlich besser aus, nicht wahr? Nun mal zu Erläuterung. Als erstes mal sollte man alle in Frage kommenden Werte in einer Tabelle festhalten. In ASM gibt es verschiedene Formen von Tabellen, in diesem Beispiel wird die Tabelle durch "db" eingeleitet. Dahinter stehen die einzelnen Werte der Tabelle, die jeweils mit Kommata abgetrennt sind. Bitte merkt euch diesen Aufbau genau. Zuerst der Tabellentyp (hier "db"), dann ein Leerzeichen, dann die einzelnen Werte, jeweils durch Kommata abgetrennt. Hinter den Kommata dürfen keine Leerzeichen stehen und hinter dem letzten Wert darf kein Komma stehen. Andere Tabellentypen sind zum Beispiel:

Code
16BitTabelle:
dw $0000,$0002,$3456,$7895,$AAFF

24BitTabelle:
dl $700360,$700366,$70036A


In diesen Beispielen haben die Werte einfach nur verschiedene Längen. Ihr braucht euch aber nur "db" zu merken. Im Grunde genommen sind db, dw und dl sowieso alle genau gleich und sollen den Programmcode nur übersichtlicher machen. Werden solche Tabellen in eine ROM eingefügt, werden einfach nur die einzelnen Bytes in der selben Reihenfolge in die ROM eingefügt. Also nehmen wir einfach mal diese Tabelle:

Code
TestTabelle1:
db $00,$01,$02,$03,$04,$05


Fügen wir diesen Code in einer ROM an einer bestimmten Stelle ein (zum Beispiel mit xkas), so würde an dieser Stelle dann in Hex stehen:

Code
...00 01 02 03 04 05...


Dasselbe Ergebnis würde man mit folgenden Tabellen erreichen (auch bei Tabellen stehen die niederwertigeren Bytes immer vorne):

Code
TestTabelle2:
dw $0100,$0302,$0504

TestTabelle3:
dl $020100,$050403


Bei manchen Assemblern, wie zum Beispiel Trasm, welcher von sprite tool benutzt wird, weichen die Tabellenbezeichnungen geringfügig ab. So verwendet man z.B. statt "db" in Trasm "dcb" oder statt "dw" dann "dcw".

Merkt euch auch, dass wenn man von der Rom lädt, die Zahl, die in der Adresse normalerweise ist, geladen wird. Deshalb gilt beim Indexing immer:

Code
LDX/Y ZahlOderAdresse
LDA Adresse,X/Y ;Rom oder Ram
STA RamAdresse,Y/X


Und der Prozessor verarbeitet es so:
Code
LDA,X/Y Adresse        ; = Lädt Adresse + Zahl des Registers am ende
STA,Y/X Adresse ; = Speichert in die Ram Adresse + Zahl des Registers am ende
Beispiel:
LDX $19 ;Lädt Powerup in X
LDY $0DA0 ;Lädt momentaner Spieler in Y
LDA $00F8E8,x ;Lädt aus der Rom aus der Adresse $00F8E8 in A
STA $0DB6,y ;Speichert in Marios oder Luigis Münzen

Aber ich will euch kein ASM beibringen (oder den 65c816 Prozessor erklären).

Nun aber wirklich Ontopic: "org" und "db" sind z.B. Assembler-Befehle (d.h. sie gibt es ohne Xkas, etc. eigentlich nicht). Und die Funktionieren so:
org:
Zitat von WYE:
sagt dem Assembler, wo er anfangen soll zu schreiben

db, dw und dl:
Zitat von WYE:
schreiben Daten

Und hier ist z.B. ein Hex Edit:
Code
header : lorom
org $029347
db $20,$E2,$FF ;Welches gleich ist wie JSR $FFE2

org $02FFE2
db $A9,$02,$4C,BA,$91 ;In ASM: LDA #$02 : JSR $91BA

Platziert eine gelbe Münze auf einen ?-Block, sammelt die Münze nicht ein, aktiviert den Block und prüft was da passiert .
Antwort anzeigen
Es passiert nichts, außer die Münze wird gesammelt. Es entsteht sogar keinen unsichtbaren Block oder so.


Ans eingemachte
Und jetzt muss All.log ins Spiel kommen. Ihr sucht eine Routine, die ihr "entführt" und schreibt bei einen Xkas Patch:
Code
header : lorom

!Freespace = $xxxxxx ;Freie Adresse

org $xxxxxx
JSL Start ;Oder !Freespace+$08

org !Freespace
!CodeSize = End-Start ; <- RATS Tag define.
db "STAR"
dw !CodeSize-$01
dw !CodeSize-$01^$FFFF
Start: ;<- Beginning of RATS Tag, and bytes to protect.
(Code den ihr schreiben wollt)
End: ; <- End of RATS Tag and number of bytes to protect.


Bei Asar:
Code
header : lorom

org $xxxxxx
autoclean JSL CustomCode

freespace
CustomCode:


Wichtig ist: Bei Patches ist es wichtig, immer einen Rats-Tag zu haben, weil die bytes sonst von den meisten Tools überschritten werden. Also könnte die Rom früher oder später crashen. Auch müsst ihr den ersetzten Code immer zu "recovern".
Aber: Aser ist einer der neuen Assembler und fügt einen Rats-Tag immer (zumindest wenn ihr freespace oben eingegeben hat) automatisch hinzu (Alcaro ist ein Genie). Also solltet ihr (wenn ihr einen Patch erstellt) immer in Aser-Format erstellen.

Noch was: Wenn ihr "LDA $19" oder "LDA $0019" schreibt, dann ist es nicht gleich: "LDA $7E0019", sondern: "LDA (DB des Freespaces)0019". Also ist die Freespace-Adresse z.B. $108000, dann ist ihr "LDA $19 gleich: "$100019". Deshalb sollten Freespace-Adressen immer eine DB von $10 bis $3F haben, weil die Ram-Adressen sonst keinen Mirror (also Spiegel) haben. Dies gilt aber nur in Adressen von $00 bis $1FFF. Darüber sind es Ram-Adressen der SNES (also DMA, HDMA und weiteres) und hat immer die gleiche Bedeutung. Danke WYE

Bei Fragen postet in den ASM-Hilfen-Thread (ich kann nicht immer helfen).

F.A.Q.
F: Meine Rom crasht:
A: Immer einen Backup haben. Wenn nicht, dann versuche die Ressourcen (Level, GFX, Patches) der Rom auf eine andere Rom zu übertragen außer, bei dem der Crash entstand. Prüfe ob
der Patch mit einen RTL endet (wegen JSL),
die Freespace-Adresse einen DB von $10 bis $3F hat,
du "header : lorom" vergessen hast,
die Rom eine HiRom ist "lorom" zu "hirom",
die Rom eine .sfc Datei ist und der "header" weg muss,
du den Rats vergessen hast.
den Code prüfen (Schwierigkeiten? Poste in den ASM-Frage Thread)
oder ob du die Richtige Rom nutzt.

F: Bei der Rom passiert nichts (kein Crash)
A: Für Xkas braucht man eine .bat Datei, und zwar so:
Xkas.exe (Patch).asm (Rom)(Endung)
Asar hat einen GUI und weitere Schwierigkeiten zu haben, hat man hier nicht.
Funktioniert es trotzdem, dann hast du
"JSL !Freespace" oder "JSL CustomCode" vergessen
oder .
Funktioniert das auch nicht, nutzt du vielleicht die falsche Rom .

Edit: WYE, WYE, WYE.
Du kannst auch gerne zu mir MFG659 sagen (ich heiße übrigens in CreepTD wegen dem limitierten Platz wirklich MFG659)
Ich kann einige (ASM)-Codes fixen. <!-- s:) -->:)<!-- s:) -->
geschrieben am 29.05.2013 19:13:27
( Link )
Zitat von MarioFanGamer659:
org: Verändert die Rom Adresse per ASM-Befehle, "db"s, "dw"s und "dl"s oder Befehle
db: Tauscht eine 8-bit Zahl der Adresse in eine Andere

Seltsam erklärt. org sagt dem Assembler, wo er anfangen soll zu schreiben, und db etc. schreiben Daten, das isses.

Zitat von MarioFanGamer659:
lorom ; Tausche zu hirom aus, wenn die Rom eine sogenannte HiRom ist.

Schön, dass jeder weiß, was das ist.

Zitat von MarioFanGamer659:
db $20,$E2,$FF ;Welches gleich ist wie JSR $FFE2

Warum schreibst du den Code in assemblierter Form?

Zitat von MarioFanGamer659:
JSL !Freespace
org !Freespace
dw "STAR"

Na, wenn das mal nicht crasht.

Ansonsten war schon viel Schönes dabei.
geschrieben am 29.05.2013 19:59:00
( Link )
Zitat von WYE:
Zitat von MarioFanGamer659:
org: Verändert die Rom Adresse per ASM-Befehle, "db"s, "dw"s und "dl"s oder Befehle
db: Tauscht eine 8-bit Zahl der Adresse in eine Andere

Seltsam erklärt. org sagt dem Assembler, wo er anfangen soll zu schreiben, und db etc. schreiben Daten, das isses.

Verbessert!

Zitat von WYE:
Zitat von MarioFanGamer659:
lorom ; Tausche zu hirom aus, wenn die Rom eine sogenannte HiRom ist.

Schön, dass jeder weiß, was das ist.

Ich wollte es nur erklären.

Zitat von WYE:
Zitat von MarioFanGamer659:
db $20,$E2,$FF ;Welches gleich ist wie JSR $FFE2

Warum schreibst du den Code in assemblierter Form?

Ich wollte es nur anmerken . Man könnte auch "JSR $FFE2" schreiben.
Aber:
Wie du weißt, ist die Reinfolge, die man schreibt, in ASM immer BankByteHighBiteLowByte, in Hex aber LowByteHighBiteBankByte.

Zitat von WYE:
Zitat von MarioFanGamer659:
JSL !Freespace
org !Freespace
dw "STAR"

Na, wenn das mal nicht crasht.

Super-Admin ich habe selbst einen Patch erstellt, mit der ich Probleme habe. Aber es crasht nicht. Hier mal der Xkas-Code:
Code
header
lorom

!freespace = $128000 ; Free space. Only freespace. Asar do... oh I made Asar Patch
!Rama = $58 ; Remember: it MUST be cleared by overworld but NOT by level load.

org $008E51
JSL !freespace ; Xkas doesn't need a "Label" to this.

org $008E57
NOP : NOP

org !freespace


Und der Asar-Code:
Code
header
lorom

!Rama = $58 ; Remember: it MUST be cleared by overworld but NOT by level load.

org $008E51
autoclean JSL Fixing

org $008E51
NOP : NOP

freecode
Fixing:


Eigenständig getestet .
Du kannst auch gerne zu mir MFG659 sagen (ich heiße übrigens in CreepTD wegen dem limitierten Platz wirklich MFG659)
Ich kann einige (ASM)-Codes fixen. <!-- s:) -->:)<!-- s:) -->
geschrieben am 29.05.2013 20:51:13
( Link )
Zitat von MarioFanGamer659:
Super-Admin ich habe selbst einen Patch erstellt, mit der ich Probleme habe. Aber es crasht nicht. Hier mal der Xkas-Code:
Code
[...]
org !freespace

Interessant ist doch erst, was danach kommt. Wenn du zu !freespace JSLst, aber bei !freespace keinen echten Code stehen hast, sondern ein dw "STAR" (das im Übrigen db heißen müsste?), dann führt er diese Bytes als Code aus. Zugegeben, der Code crasht überraschenderweise nicht (EOR ($54,s),y : EOR ($52,x)), tut aber auch nichts Erwünschtes. Guter Stil ist das jedenfalls keinesfalls.
geschrieben am 29.05.2013 21:01:21
( Link )
Zitat von WYE:
Zitat von MarioFanGamer659:
Super-Admin ich habe selbst einen Patch erstellt, mit der ich Probleme habe. Aber es crasht nicht. Hier mal der Xkas-Code:
Code
[...]
org !freespace

Interessant ist doch erst, was danach kommt. Wenn du zu !freespace JSLst, aber bei !freespace keinen echten Code stehen hast, sondern ein dw "STAR" (das im Übrigen db heißen müsste?), dann führt er diese Bytes als Code aus. Zugegeben, der Code crasht überraschenderweise nicht (EOR ($54,s),y : EOR ($52,x)), tut aber auch nichts Erwünschtes. Guter Stil ist das jedenfalls keinesfalls.


*Facepalm* Ich weiß, ich bei wiiqwertyuiop (wie kann man de Namen den merken!) nachgeschaut, aber das mit den Rat-Tag war ein Fail. Ich muss es jedenfalls verbessern. Ich habe bei meinen eigenen Patch den Rat-Tag vergessen *Double-Facepalm*. Noch was: Ein Rat_Tag nimmt doch immer 8 Bytes weg, oder? Man könnte also auch schreiben: JSL !Freespace+$08, nicht?
Du kannst auch gerne zu mir MFG659 sagen (ich heiße übrigens in CreepTD wegen dem limitierten Platz wirklich MFG659)
Ich kann einige (ASM)-Codes fixen. <!-- s:) -->:)<!-- s:) -->
geschrieben am 29.05.2013 21:03:11
( Link )
Zitat von MarioFanGamer659:
Man könnte also auch schreiben: JSL !Freespace+$08, nicht?

Klar, durchaus. Ich würde allerdings gleich ein Label da hin schreiben.
geschrieben am 29.05.2013 21:06:55
( Link )
Ersetzte "JSL !Freespace+$08" durch "JSL Start ;Oder !Freespace+$08"
Du kannst auch gerne zu mir MFG659 sagen (ich heiße übrigens in CreepTD wegen dem limitierten Platz wirklich MFG659)
Ich kann einige (ASM)-Codes fixen. <!-- s:) -->:)<!-- s:) -->