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:
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.
Lo primero es insertar está rutina para FR en la ROM, una vez compilada:
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:
Ahora en vez de hacer checkflag 0x(flag) haremos lo siguente:
Despues del callasm en la variable 0x800D tendremos un 1 si esa flag está activada, y un 0 en caso contrario.
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.
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.
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:
Cabe mencionar que todos los valores están en hexadecimal, pero me daba pereza andar poniendo un 0x en todos.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
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}
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
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)
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: