Asteroids: presentación de números en decimal – coordenadas X e Y

La coordenada Y ocupa un byte y puede tomar los valores 0 a 255, aunque no todos caen dentro de la zona visible de la pantalla. La coordenada X ocupa dos bytes, aunque sólo se usan 9 bits. Por tanto, puede tomar los valores 0 a 511, aunque tampoco todos caen dentro de la zona visible de la pantalla.

En este caso, al superarse el intervalo 0 – 9, podríamos plantearnos dejar de usar la codificación binaria y pasar a usar la codificación y la aritmética BCD, todo con el objeto de facilitar la presentación de estas variables en pantalla en formato decimal.

Sin embargo, hay un problema. El VIC requiere que las coordenadas X e Y que se informan a los registros SP0X, SP0Y y siguientes ($d000 – $d00f) estén codificados en binario, no en BCD.

Por tanto, tenemos que seguir usando la codificación y la aritmética binarias. Podemos convertir a BCD antes de pintar en pantalla o desarrollar alguna rutina que, directamente desde la codificación binaria, imprima los números en decimal.

Y esto es lo que vamos a hacer: una rutina que partiendo de un byte en codificación binaria nos dé el número equivalente en codificación BCD. Y luego imprimiremos ese segundo número BCD en decimal.

Un byte puede tomar los valores decimales 0 – 255. Por tanto, para la codificación BCD necesitamos al menos tres nibbles o tres dígitos decimales (para almacenar el 2, el 5 y el otro 5). Y como en el C64 la unidad de memoria mínima que se puede asignar o reservar es el byte, reservaremos para el retorno de la rutina dos bytes o, lo que es lo mismo, cuatro nibbles o cuatro dígitos decimales. Por tanto, nos sobrará un nibble o dígito decimal.

Empecemos por lo sencillo: el nibble bajo del byte codificado en binario. El nibble bajo puede tomar los valores %0000 – %1111, que en decimal son los valores 0 – 15. El 0 sólo tiene un dígito decimal; por tanto, nos llegaría con un nibble BCD. Sin embargo, el 15 tiene dos dígitos decimales; por tanto, necesitamos dos nibbles BCD para codificarlo (un nibble para el 1 y otro nibble para el 5).

La conversión de lo primero (los 16 posibles valores del nibble bajo) a lo segundo (los nibbles o dígitos BCD) es fácil de conseguir mediante una tabla de conversión:

Nibble bajo Valor decimal Byte BCD Hi Byte BCD Lo
%0000 0 00 00
%0001 1 00 01
%0010 2 00 02
%0011 3 00 03
%0100 4 00 04
%0101 5 00 05
%0110 6 00 06
%0111 7 00 07
%1000 8 00 08
%1001 9 00 09
%1010 10 00 10
%1011 11 00 11
%1100 12 00 12
%1101 13 00 13
%1110 14 00 14
%1111 15 00 15

En definitiva, si el valor del nibble bajo lo pasamos al registro X o Y, y usamos ese registro como índice para acceder a la tabla, obtenemos fácilmente los nibbles o dígitos en BCD.

La conversión de binario a BCD ha sido más fácil de lo que cabía esperar. De hecho, me declaro un absoluto forofo de las tablas de datos. Son mucho más fáciles de usar, y seguro que incluso más rápidas, que las fórmulas matemáticas, que son un horror para implementar en ensamblador en cuanto tienen algo más complejo que sumas, restas, multiplicaciones por dos o divisiones por dos.

La versión en rutina del algoritmo anterior es así de fácil:

Asteroids - Rutina nibble0ToBCD.PNG

El problema es que el byte codificado en binario no sólo tiene el nibble bajo, también tiene el nibble alto. Y con él hay que hacer lo propio. Pero, cuidado, porque ahora el nibble alto “pesa” más que el nibble bajo. Es decir, la tabla de conversión es así:

Nibble alto Valor decimal Byte BCD Hi Byte BCD Lo
%0000 0 x 16 = 0 00 00
%0001 1 x 16 = 16 00 16
%0010 2 x 16 = 32 00 32
%0011 3 x 16 = 48 00 48
%0100 4 x 16 = 64 00 64
%0101 5 x 16 = 80 00 80
%0110 6 x 16 = 96 00 96
%0111 7 x 16 = 112 01 12
%1000 8 x 16 = 128 01 28
%1001 9 x 19 = 144 01 44
%1010 10 x 16 = 160 01 60
%1011 11 x 16 = 176 01 76
%1100 12 x 16 = 192 01 92
%1101 13 x 16 = 208 02 08
%1110 14 x 16 = 224 02 24
%1111 15 x 16 = 240 02 40

Nuevamente, la versión en rutina del algoritmo anterior es así (sólo cambian las tablas de datos):

Asteroids - Rutina nibble1ToBCD

Ahora, llamando a las dos rutinas anteriores y sumando sus resultados (suma decimal con “sed”), ya somos capaces de pasar de un byte codificado en binario (con su nibble bajo y su nibble alto) a dos bytes equivalentes con la codificación BCD:

Asteroids - Rutina byteToBCD

Y los dos bytes BCD resultantes ya se pueden imprimir en formato XXXX (cuatro dígitos decimales) con la rutina “pintaBCD”. Por ejemplo, para la coordenada Y:

Asteroids - Pinta Y en BCD

Por tanto, ya hemos resuelto el problema de imprimir en decimal (no en binario, ni en hexadecimal) un byte que contiene un número en codificación binaria.

Si alguna variable, como la coordenada X, no ocupa un byte, sino que ocupa dos bytes, es posible extender el razonamiento anterior tanto como sea necesario.

El resultado podemos verlo en la versión 23 del proyecto y aquí. Obsérvese cómo las coordenadas X e Y ya aparecen en decimal:

Asteroids - XY en decimal.PNG


Código del proyecto: Asteroids23

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s