tuts_gba
Thread Id: 10535
Thread Name: GBA | Scripting | [THUMB MODE]Mini Tutorial: Cómo ejecutar scripts a través de ASM
#0
Sonicarvalho 17082
Buenas!

Mientras no termino el BIG UPDATE al Safari, voy posteando aquí unas cosas.

Hoy será ejecutar scripts a través de ASM. Este método solo funciona en OverWorld, claro. No en Bag, no en batallas, solo en OverWorld.

Requisitos mínimos:


Entonces, sigan el tutorial de ~Javs antes de empezaren este pues el de ~Javs vos da los basicos de ASM.
Pero mismo así, vos voy a explicar cada comando y hacer una analogía con el Scripting, para que perciban mejor.

El comando Ldr sirve para cargar números en los registros y acceder a la RAM. Pero aquí en este tutorial solo vamos a utilizar 'cargar numeros'. Este comando es una especie de loadpointer en el sentido literal. Carga un numero 32bit a la Memoria (en este caso, los registros)

El comando Bl es como en scripting el comando 'call', que llama una subrutina (en scripting, un subscript, como el 'CallStd'). Para que funcione correctamente, la Subrutina llamada tiene que terminar en Pop {pc} (puede dar Pop a mas registros, pero el Registro PC (R15) TIENE que estar presente!). Ese pop {pc} es como el comando 'Return' en scripting: Vuelta al función que le ha llamado.

El comando Bx rX tiene que ser usado con el ldr rX, pues ese comando pone el processador a ejecutar las instrucciones de código en el offset de el registro rX. Es como el comando 'Goto' en scripting. No tiene retorno. Por eso vamos a usar ese dentro de un Bl (buen truco, no? ;))
---------------------------------------------

Después de los básicos, vos voy a presentar una rutina hecha para que puedan llamar scripts en rutinas.
ATENCION: YO NO USO GOLDROAD COMO COMPILADOR. ESTE CODIGO ES PARA DEVKITARM y EL ENSAMBLADOR QUE VIENE CON MID2AGB (as.exe y objcopy.exe)
Ejemplo FIRERED:

.thumb
.align 2
push {lr}
ldr r0, SCRIPT_ADRESS
bl SCRIPT_ROUTINE //subrutina que va a ejecutar los scripts
pop {pc}

SCRIPT_ROUTINE:
ldr r1, SCRIPT_EXECUTER
Bx r1

.align 2
SCRIPT_ADRESS: .word 0x081624F5 //Aquí definen vuestro script offset
SCRIPT_EXECUTER: .word 0x08069AE5 //Esta es la rutina que ejecuta los scripts. Offset +1


Ahora deben ter reparado en algo.
Porque no he push'ado los registros r0 y r1? ¿:.
La verdad es, cuando no damos push a registros y llamamos un Bl, significa que estamos pasando argumentos a la rutina que estamos llamando. Asi que en este caso especifico, NO DEBEMOS dar push {r0-r1, lr}, solo push {lr}.
Los argumentos son:
r0= Script offset (un script que quieran)
r1= Script executer (el offset de la rutina que hace con que los scripts sean ejecutados!)

Los offsets de el Script Ejecuter para las versiones Ruby, Firered y Emerald son(no vos olvidéis de poner el offset + 1!Es necesario para que funcione correctamente):
Ruby:080655B8
FireRed:08069AE4
Emerald:08098EF8

Por ahora es todo. Espero tener ayudado!
-------------------------------------
Tutorial made by Sonicarvalho AKA Dark Rayquaza

PD: Como en este forum todos usan GOLDROAD, entonces pido a alguien que adapte la rutina para GOLDROAD. Gracias.
#1
Hackun 12904
Gracias nuevamente, tus tutoriales son algo especial ^^
Con esto la gente se familiarizará más con el lenguaje ensamblador más básico :B
Saludos.
#2
Gut_Bro 14808
Juuu! Siempre supe que con un script normal se puede llamar una rutina ASM (callasm). Pero siempre me pregunté cómo hacer para que desde una Rutina ASM se ejecutara un Script, y ahora... ¡ya lo se!

xD

Me voy a poner a practicar un rato con el devkit joo a ver que logro :P

Muchisisisimas gracias ^^
#3
Gershel 12314
¡Gran aporte!
Al igual que Gut, muchas veces me preguntaba como llamar a msgbox, o cosas parecidas y bueno, ahora ya sé como hacerlo de una forma simple y sencilla :D
Como siempre, un genial aporte, muy bien explicado, se entiende muy bien siempre y cuando se hayan leído tutoriales más básicos como el de Javs o Pey!.
Muchísimas gracias por colaborar tanto con Wah!
Saludos!
#4
JV Works 12391
¡Que buen tutorial!

Entonces la clave esta en el bx, espera, ¿El bx es el que ordena a la Gba que lea los comandos script?, hay me perdi, pero el punto es que entendi el tuto y me parece muy bien poder ejecutar scripts desde rutinas, pero hasta que no sepamos como modificar el menu o los objetos, no creo que sirva de mucho ya que para llamar el script desde una rutina, mejor continuo en el script en el que se ejecuto la rutina, ¿no?, ya que asi me ahorro espacio.

De todas formas es un gran aporte, ¡Sigamos asi!, ¡Wah se convertira en la web mas avanzada en rom hacking gracias a la investigacion!

¡Y pronto prometo yo tambien traer un tuto, INVESTIGACION EN ALTO!! :furia:
#5
Sonicarvalho 17082
Pues MarioFan, no te confundas bro. Yo nunca he dicho eso. Ni tampoco ASM tiene que ver con Scripts. Scripting fue una lenguaje creada por nintendo con base en ASM para poder contratar programadores por precios mas bajos que no saben ASM(?) :XD:.

O sea, nadie que ver con Scripts. Scripting tiene algunas relaciones con ASM porque los Core Engine Programmers hicieran esa lenguaje teniendo en cuenta sus conocimientos en ASM, pues scripting no es menos que pura Lógica sin la complejidad de ASM.

Al respecto de Bx, no digas tal cosa. Especialmente siendo tu, un de los mejores ASMers de Wah, si no el mejor!
Bx rX simplemente pon el procesador a leer la rutina localizada en el offset presente en el rX.

Si yo quiero ejecutar una rutina en 08064580 entonces pongo por ejemplo
ldr r0, =0x0864581
bx r0


Las rutinas que están en el Primer post simplemente son las rutinas que el juego tiene para ejecutar scripts.

'See? Not that hard!' ;)

Si, sigamos con las investigaciones!!! La verdad es que yo tiengo mas de 400mb en Bases de dados con investigaciones Ruby/Firered/Emerald, pero cuasi todo es complejo, entonces no sé como explicar a la comunidad de una forma simples. Pero me arreglare una manera de lo hacer ;)

Saludos
#6
eing 12479
Hum.. grandisimo aporte darkrayquaza.
Con esto, podríamos llamar un script -codigo rubikon- desde una rutina asm.

Segun yo, he entendido esto.
Cargariamos en r0 la direccion donde esté ubicado nuestro script -codigo rubikon-, luego iremos al ejecutor de scripts (r1) y ahí se ejecutará nuestro script, y luego volverá a la rutina asm, para dar por finalizado. ¿no?

Entonces con esto, si la intro es con ASM, podriamos ir al principio de dicha rutina, y colocarle esa rutina, y ¿ejecutariamos un script en vez de la intro?

Saludos y eres grande men!
#7
Sonicarvalho 17082
Iniciado por eing

Hum.. grandisimo aporte darkrayquaza.
Con esto, podríamos llamar un script -codigo rubikon- desde una rutina asm.

Segun yo, he entendido esto.
Cargariamos en r0 la direccion donde esté ubicado nuestro script -codigo rubikon-, luego iremos al ejecutor de scripts (r1) y ahí se ejecutará nuestro script, y luego volverá a la rutina asm, para dar por finalizado. ¿no?

Entonces con esto, si la intro es con ASM, podriamos ir al principio de dicha rutina, y colocarle esa rutina, y ¿ejecutariamos un script en vez de la intro?

Saludos y eres grande men!


Has percibido cuasi todo, pero esa parte de irmos a la rutina nos es asi que se hace.

PERO, yo conozco el Offset de la rutina de la opción New Game en FR y E, y percibo mas o menos como aquello funciona.

Hay una rutina para que que hace el Warp para el mapa inicial del juego (en FR, tu casa, en Emerald, el TrucK). Y luego despues de esa rutina esta una otra que es el "Script_Executer2", que sirve para llamar Map Scripts 03(scripts de gatillo 03). Pero esas dos rutinas solo son llamadas después de la intro. Asi que removeríamos las rutinas de la intro y hariamos un script que SETVAR 0xVAR 0x1 para que cuando llegues al primer mapa se active un script gatillo 02 por esa VAR con tu "supuesta intro 'coded in rubikon' script".

Pero para que trabajase bien, tenias que separar las rutinas de Naming de [PLAYER] y de [rival].

Es posible, pero es necesario mas búsqueda en esas rutinas.

Saludos,
~Sonicarvalho
Aka D.ray