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:

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):

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:

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:

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:

Código del proyecto: Asteroids23