Documentos de Académico
Documentos de Profesional
Documentos de Cultura
V 1.1
13 Mayo 2004
NOTA: Esta es una modificación SENCILLA usando algo de asm, no esperen salir haciendo
modificaciones a su gusto, ya que falta para eso. Recomiendo leer los documentos que están
en la página de Magno para los que quieres saber mucho más.
Índice:
Introducción:...............................................................................................................................2
Encontrando la Rutina.................................................................................................................2
Empezando..............................................................................................................................3
En Memoria.............................................................................................................................4
Entendiendo cada línea:...........................................................................................................5
Editar el Puntero: Tres Métodos Probados................................................................................11
Agradecimientos........................................................................................................................18
2
Introducción:
Este documento lo hice hace tiempo, pero debía primero mostrar los fundamentos con los
capítulos 1 2 y 3.
Ya estamos capacitados para ver algún código y entender algo. En este capitulo se verá un
caso concreto, modificar un puntero de una rom conocida usando algo de asm y herramientas,
hablo del FF6. Dada una rutina la analizaremos completamente, descubriremos que es una
rutina que carga los punteros y la modificaremos las usando herramientas necesarias.
Encontrando la Rutina
Lo primero que haremos será encontrar la rutina que deseamos cambiar para usaré como
ejemplo el rom de Final Fantasy 6 (J), aunque con la versión US igual se puede. Lo abrimos
con el snes9x1.42 que hace Trace, también puede ser con el clásico Trace de Lord Tech, y
cuando este a punto de empezar el Intro (cuando uno no presiona ningún botón) presionamos
la tecla DIVISION (/) del teclado numérico, apenas se acabe la frase, presiónalo de nuevo ya
que solo nos interés esta primera frase. Ahora ve a ver el archivo que se generó (un .log) en el
directorio donde tienes el juego.
Lo abrimos con el EDITPAD y tenemos muchos códigos, dentro de todo ellos, el trozo de
código que nos interesa está aquí:
Si quieres lo compruebas con tu archivo, puede que no lo encuentres a la primera, busca por
“LDA #$CD” y deberá aparecer. Muchos se preguntarán como yo sé que esta rutina nos sirve,
3
y la verdad es que este trozo de código yo no la descubrí, en una guía en francés que bajé
solo daban la rutina y decían que aquí se cargaban los punteros, yo la investigue y pregunté a
Magno y a otros por mail y foro, al final la entendí casi completamente he hice esta guía.
Empezando
Primero que todo debes saber donde está el texto. El texto del intro está en localizado en la
posición D0200 (lo vi en una guía en Internet). Es Obvio que si lo vez con un editor no verás
nada ya que no tenemos una tabla:
Ahora debemos convertir la dirección Hexadecimal del Intro (D0200) en Dirección de SNES,
para esto usamos el programa Hex2Snes, escogemos Hi-Rom, ya que FF6 es Hi-Rom, escribe
0D0200 (6 dígitos) y dale a Convert!, te debería salir $CD:0000
Ocupando el Hex2Snes
4
El texto entonces está en el “Banco” CD, pero ¿que es un banco?. Banco es una zona de
memoria de la Snes. En los Hi-Rom el banco comienza siempre en C0, y en 80 en las Lo-
Rom.
En Memoria
Como cualquier lenguaje asm, las rutinas se pueden representar en la memoria misma, así
cada instrucción y operandos ocupan ciertos “casillas” de memoria en cierta dirección. El
trace.log que genera el Snes9X_Trace indica todo lo necesario para representarla
gráficamente:
¿Por qué el mapa de memoria no guarda Opcodes (LDA,REP, etc)? Ya que la maquina solo
trabaja con hexadecimales y no caracteres. Un LDA es A9, STA es 85 y así, cada opcode tiene
su equivalente en hex.
Si quieres saber mas acerca del mapa de memoria de una Hi-rom y una Lo-rom lee mi
próxima guía que haré solo acerca del mapa de memoria.
No es necesario que entiendas cada línea, pero es necesario para que ya te acostumbres a las
instrucciones de asm de la snes. Si ya conoces las instrucciones y quieres saber de que sirve
tener la rutina que di mas arriba, ve más abajo donde dice “Editando el Puntero”
1. LDA #$CD
Transferimos el banco del texto al acumulador A. Este es el banco del comienzo del texto.
3. REP $20
Con REP $20 hacemos que el acumulador esté en modo de 16 bits aunque por ahora solo
almacene un valor de 8 bits (#$CD).
antes. Recuerda en la RAM solo hay DATOS y en la ROM está la instrucción LDA $D0 que
la accede.
5. ASL A
Se multiplica A=06 por 2, quedando A=C, ya que cada puntero es de 2 bytes. Ya veras para
que se hace esto.
6. TAX
Este nuevo valor se pone en X para…
12. TDC
Entonces seguimos y ejecutamos TDC - Transfer Direct Page to Accumulator, es decir se
transfiere lo que estaba en un registro llamado Direct Page (DP) al acumulador. Ve mi guía de
Referencia para saber más del DP. Al terminar esta instrucción A vale 0, lo que quiere decir
que los que estaba en DP es 0.
16. RTS
Vuelve de la subrutina al código que la llamó y ejecuta la instrucción siguiente a la subrutina.
Recuerda que casi siempre una instrucción de salto (como JSR) llama a una subrutina. Pero
queda una duda:
10
¿Qué pasa si un salto JSR que llamó a toda esta rutina de los 16 pasos, y ese JSR era la ultima
instrucción de otra subrutina? Ejemplo:
Hay 3 formas de editar una instrucción asm (por lo menos las que conozco yo):
Para empezar supongo que ya tienes el log. Ahora modificaremos la instrucción del paso
4:
Esta instrucción carga en A el numero del puntero a mostrar por pantalla, ese numero esta
guardado en la dirección D0, no se carga en A el puntero en si. Con ese número se accede
a la Tabla de puntero en los pasos siguientes y se saca. Recuerda que cada instrucción
(LDA, BCC, TXA, etc..) tiene un equivalente en bytes, así LDA es A5, entonces LDA
$D0 es el par A5 D0. Recuerdalo.
Lo primero es apuntar la dirección snes donde se ejecuta LDA $D0, es decir $C0:F7C5,
esta dirección la usamos en el Hex2snes, marcamos Hi-Rom como se muestra abajo y le
damos a Convert!
12
Nos entregó el Offset 008C5, recuérdala ya que tenemos ahora que buscarla en el Editor
Hexadecimal.
Abrimos el Translhextion y vamos donde dice Offset->Jump To y adentro escribimos
x81c5 (la ‘x’ porque accederemos a una dirección hexadecimal):
y mira lo que encontró…cha chan! A5 D0, o sea que allí hace LDA $DO, es decir que allí
carga el numero del puntero a mostrar por pantalla. Te dije que lo recordarás! Entonces es
fácil darse cuenta que 0A es ASL A, y así sucesivamente.
Ahora editemos ese valor (que esta en la posición 0x81C5), pongámosle en vez de A5 D0,
A5 00. Quedaría así:
Antes Ahora
¡¡¡Bravo!!!, merezco un aplauso ¿no? El puntero que se cargo fue el otro por lo que mostró
otro en pantalla. Bueno, con esto ya pueden aprender más por cuenta suya y experimentar
con otras roms.
Ahora veremos una forma mas profesional de hacerlo, es decir ocupando el compilador
X86.
14
Requerimientos:
-Un editor Hexadecimal, yo usaré el Translhextion 1.6c.
-El programa Bin Inserter 1.0 (encuéntralo en la pagina de Los Sayans) es para insertar
bytes en una rom dado una dirección.
-El compilador X86 para hacer nuestro archivo.bin, para luego insertarlo en la rom.
-El Hex2snes 1.3 para convertir direcciones de Snes a Offset para verlos en el Editor
Hexadecimal.
-Emulador y fabricador de log, el Snes9x_trace.
Lo primero que haremos será crear nuestro archivo.bin, para esto abrimo un editor de texto
(usaré el EditPad) y escribimos lo que queremos insertar: LDA $00, lo salvamos como
ej1.asm:
Le sacamos el tick que dice “cerrar al salir” para ver la información una vez compilado el
archivo. Lo ejecutamos y mostrará:
A5 y 00, ¿los recuerdas? Son los valores del Opcode LDA y del operando 05 pero su
equivalente en bytes. La raya __ es que es el fin del archivo según Translhextion. Ciérralo.
Ahora toca convertir la dirección de Snes que teníamos ($C0:7FC5) a dirección Offset,
dándonos 81C5, ahora tomamos el Bin Insert y lo ejecutamos.
Escribimos primero el archivo donde se insertaran los bytes, luego el archivo.bin que
creamos y finalmente la dirección en DECIMAL (mira en el editor hex y te das cuenta que
81C5 es 33221 decimal):
Aceptamos y listo, reemplazó los bytes que teníamos en la dirección 81C5 los del binario.
Para comprobarlo solo abre el editor hex y comprueba que así sea:
Ahora solo carga el juego en el emulador y verás lo mismo que con el método anterior:
Antes Ahora
Esta instrucción carga en A el numero del puntero a mostrar por pantalla, ese numero esta
guardado en la dirección D0, no se carga en A el puntero en si. Luego abrimos Snes
Profesional ASM Development Kit y nos sale una ventana asi:
Vamos a File->New Proyect y escogemos la rom FF6(US).smc. Luego se nos abre una
ventana chica donde aparece la Rom, haces clic en el signo + para que se expanda y
aparece Code y Data.
Ahora ve a la dirección $C0/7FC5 (la puse al principio) y aparecerá INX (ver imagen) ahora
SUBE 2 BYTES arriba y esta la dirección $C0/7FC3, y aquí nos encontramos con LDA
$DO.
Les suena esta instrucción? Ahora solo la modificamos haciendo un clic sobre ella (ver
imagen de arriba) y escribimos LDA $00.
Ve a guardar y carga el juego en el emulador y verás lo mismo que con los 2 métodos
anteriores:
Antes Ahora
KIAAA!!! Funciono ;)
Agradecimientos
26 Junio 2004