Registrarse

[ASM] Si necesitas más flags, usa variables

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
En este tutorial voy a explicar como usar una variable como si fuera un conjunto de hasta un máximo de 16 flags, claro está que también se pueden usar menos. Antes de explicar nada más haremos un breve repaso de lo que es cada cosa.

Una flag es una dirección de la RAM capaz de almacenar un dato de un bit, es decir, cero o uno. Su uso es muy límitado por razones evidentes. Una variable es una dirección de la RAM capaz de almacenar un valor de dos bytes, o una half word. Es decir, una variable está constituida por 16 bits.

El objetivo será usar cada uno de los bits de la variable como si fueran flags independientes unas de otras.

Quiero hacer un breve inciso en esto, pues más tarde, si bien no es necesario para llevar a cabo el objetivo del tutorial, usaremos de una forma indiricta un decodificador. En este caso será un decodificador de 4 a 16. En resumen, un decodificador toma como parametro un valor cualquiera (en nuestro caso de un valor máximo de cuatro bits, es decir, de cero a quince) y nos devuelve un valor que en binario todos sus bits son cero excepto el bit de la posicion indicada por el parametro de entrada, que será un uno. El decodificador para un parametro de entrada de cuatro bits será el siguiente:

0 → 1
1→ 2
2 → 4
3 → 8
4 → 10
5 → 20
6 → 40
7 → 80
8 → 100
9 → 200
A → 400
B → 800
C → 1000
D → 2000
E → 4000
F → 8000
Cabe mencionar que todos los valores están en hexadecimal, pero me daba pereza andar poniendo un 0x en todos.

Si aun asi no os ha quedado claro os dejo un link a Wikipedia de un decodificador, aunque no es de estas dimensiones es tres cuartos de lo mismo.

>>LINK<<

Una vez explicado esto vamos a proceder a desarrollar el código que cumplirá la función de checkflag, setflag y clearflag. Para lo primero no he visto más remedio que hacer una rutina ASM pero los demás no son más que puro scripting.

Primero quiero explicar la arquitectura que va a tener nuestra variable. Para nosotros la variable será un bloque de datos que contiene 16 bits. Cada uno de esos bits tendrá un ID. El bit de más a la derecha, el que menos vale, trendrá la posición cero. La de su izquierda la posicion uno...

Siempre que vayamos a interactuar sobre una de esas flags vamos a necesitar la variable en la que están almacenadas y su número de ID.

CHECKFLAG

Lo primero es insertar está rutina para FR en la ROM, una vez compilada:

Código:
.text
.align 2
.thumb

main:
	push {r0-r1, lr}
	ldr r0, =0x20370D0	//variable 0x800D
	ldrh r0, [r0]
	ldr r1, =0x20370B8	//variable 0x8000
	ldrh r1, [r1]
	and r0, r1
	ldr r1, =0x20370D0
	cmp r0, #0x0
	beq not
	mov r0, #0x1
	strh r0, [r1]
	b end

not:
	strh r0, [r1]

end:
	pop {r0-r1, pc}
Para otras ROMs simplemente sustituid esos offsets por sus equivalentes en dicha ROM.

Como se que sois muy vagos aquí dejo la rutina compilada para FR:

Código:
03 B5 06 48 00 88 06 49 09 88 08 40 03 49 00 28 02 D0 01 20 08 80 00 E0 08 80 03 BD D0 70 03 02 B8 70 03 02
Ahora en vez de hacer checkflag 0x(flag) haremos lo siguente:

Código:
copyvar 0x800D 0x(variable que se usa como BD)
setvar 0x8000 0x(valor decodificado del ID de la flag que queramos checkear)
callasm 0x(offset de la rutina +1)
Despues del callasm en la variable 0x800D tendremos un 1 si esa flag está activada, y un 0 en caso contrario.

SETFLAG

Antes de nada tenemos que comprobar que la flag esté desactivada, para eso usaremos lo que he explicado en el paso anterior. En caso de que esté activada no haremos nada más, puesto que ya está seteada. En caso de que esa flag esté desactivada seguiremos los siguientes pasos.

En este caso simplemente con un addvar ya nos vale.

Código:
addvar 0x(variable que sirve como BD) 0x(valor decodificado del ID de la flag a setear)
CLEARFLAG

De la misma forma comprobaremos primero si la flag está activada o no, en caso de estar desactivada no haremos nada. En caso de estar activada vamos a usar un subvar.

Código:
subvar 0x(variable que sirve como BD) 0x( valor decodificado del ID de la flag a desactivar)
 
Última edición:

Gold

Porrero a tiempo parcial
Miembro insignia
Respuesta: ¿Necesitas más mas flags? Usa variables

Buen aporte. Aunque teniendo en cuenta que hay mucho menos flags que variables pues como que no es el método más factible para tener más flags.
 

Nachoius

Caminante del cielo
Re: ¿Necesitas más flags? Usa variables

Gracias bro, bue aporte. Y genial idea para el ancient, qyedó guapisimo el evento. Ojalá lo puedan usar los demás!! Sigue así
 
Arriba