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:
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
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:
Und der Prozessor verarbeitet es so:
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:
db, dw und dl:
Und hier ist z.B. ein Hex Edit:
Platziert eine gelbe Münze auf einen ?-Block, sammelt die Münze nicht ein, aktiviert den Block und prüft was da passiert .
Ans eingemachte
Und jetzt muss All.log ins Spiel kommen. Ihr sucht eine Routine, die ihr "entführt" und schreibt bei einen Xkas Patch:
Bei Asar:
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.
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:
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:
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:
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:
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:
Dasselbe Ergebnis würde man mit folgenden Tabellen erreichen (auch bei Tabellen stehen die niederwertigeren Bytes immer vorne):
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".
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:) -->
Ich kann einige (ASM)-Codes fixen. <!-- s:) -->:)<!-- s:) -->