Bancos direccionados por el VIC

Todo lo que hemos visto en la entrada anterior tiene que ver con los mapas de memoria direccionados por el microprocesador 6510. Como hemos visto, se pueden direccionar bancos de ROM o sustituirlos por la RAM que está “debajo”.

Por si esto fuera poco, el VIC también admite diferentes configuraciones de memoria. Para empezar, el VIC es capaz de direccionar 16K y, como el C64 direcciona 64K, eso significa que admite cuatro configuraciones básicas o cuatro bancos.

Pero es que, además, para cada uno de los cuatro bancos posibles, es posible recolocar los juegos de caracteres personalizados, los bitmaps, la RAM de pantalla, los sprites, etc. No ocurre lo mismo con la RAM de color, que siempre tiene que estar en el rango $d800 – $dbe7.

Bancos del VIC:

La forma de seleccionar el banco de 16K direccionado por el VIC es actuando sobre los bits 0 y 1 del registro CI2PRA = $dd00 del CIA2:

  • %00: $c000 – $ffff
  • %01: $8000 – $bfff
  • %10: $4000 – $7fff
  • %11: $0000 – $3fff (valor por defecto)

Bancos VIC

Juegos de caracteres personalizados:

La forma de ubicar los juegos de caracteres personalizados, como ya vimos en su momento, es actuando sobre los bits 1, 2 y 3 del registro VMCSB = $d018. Esto da lugar a 2^3 = 8 posibles valores o ubicaciones.

Estas ocho posibles ubicaciones, lógicamente, son relativas al comienzo del banco de 16K que esté direccionando el VIC:

Juegos caracteres

Bitmaps:

La forma de ubicar los bitmaps, como también vimos en su momento, es actuando sobre el bit 3 del registro VMCSB = $d018. Esto da lugar a dos posibles valores o ubicaciones.

Estas dos posibles ubicaciones, nuevamente, son relativas al comienzo del banco de 16K que esté direccionando el VIC:

Bitmaps

RAM de pantalla y punteros de sprites:

La forma de ubicar la RAM de pantalla es actuando sobre los bits 4, 5, 6 y 7 del registro VMCSB = $d018. Esto da lugar a 2^4 = 16 posibles valores o ubicaciones:

  • %0000: $0000 – $03ff
  • %0001: $0400 – $07ff (valor por defecto)
  • %0010: $0800 – $0bff
  • %1111: $3c00 – $3fff

Estas dieciséis posibles ubicaciones, una vez más, son relativas al comienzo del banco de 16K que esté direccionando el VIC:

RAM pantalla

La RAM de pantalla, en realidad, no ocupa 1K = 1.024 bytes, sino que sólo ocupa 1.000 bytes (25 filas x 40 columnas). Por tanto, sobran 24 bytes. Entre esos 24 bytes están los ocho punteros a los sprites. Más concretamente, los punteros a los sprites son los últimos ocho bytes de los 1.024 configurados en VMCSB.

Definición de los sprites:

No sólo es posible reubicar los punteros de los sprites dentro de los 16K direccionados por el VIC, cambiando la ubicación de la RAM de pantalla.

Por supuesto, también es posible reubicar la propia definición gráfica de los sprites (64 bytes por sprite). Esto es posible, precisamente, porque esa definición no ocupa una posición fija, sino que ocupa una posición variable (siempre dentro de los 16K direccionados por el VIC) que viene indicada o especificada por los punteros de los sprites.

En definitiva, entre las posibilidades de configuración de la memoria del 6510 y las del VIC, la flexibilidad es casi absoluta, como hemos visto.

Otros mapas de memoria avanzados

En una de las primeras entradas del blog describimos el mapa de memoria estándar del C64. Este mapa de memoria es así:

Memoria

Es decir, consta de:

  • La página 0, que contiene muchas variables o posiciones que se usan desde el intérprete de BASIC y desde el Kernal.
  • La página 1, que se usa para la pila de llamadas a subrutinas.
  • 40K de RAM, que incluyen la RAM de pantalla en su ubicación estándar ($0400-$07e7) y 38K de RAM para programas en BASIC ($0801-$9fff).
  • El intérprete de BASIC en ROM.
  • 4K de RAM donde, de forma muy habitual, se han ubicado los programas en código máquina, al menos, los programas pequeños.
  • Los chips especiales para vídeo, sonido y entrada / salida. También la RAM de color.
  • El Kernal en ROM.

Este es el mapa estándar, es decir, el que ofrece el C64 recién arrancado. Ahora bien, una de las características clave del C64 es que soporta diferentes mapas de memoria en función de las necesidades de la aplicación. De hecho, el microprocesador 6510 es esencialmente un 6502, con el mismo juego de instrucciones, pero con capacidad para gestionar diferentes mapas de memoria.

De esta gestión se encargan los registros:

  • D6510 = $0000.
  • R6510 = $0001.

El primero es un DDR o registro de dirección de datos. Es decir, sus bits sirven para configurar si los bits de un IOP o puerto de entrada / salida asociado, en este caso el puerto R6510 = $0001, son de entrada o salida. Su valor por defecto es 47 = %00101111, lo que significa que todos los bits del puerto R6510 son de salida (1), salvo el 4, que es de entrada (0); los bits 6 y 7 no se usan.

Por su lado, el registro R6510 = $0001 es el puerto de entrada / salida propiamente dicho. En este caso, en función de los valores 0 o 1 que se configuren en sus bits, se consigue que el microprocesador 6510 direccione unos u otros bancos de memoria, en particular, bancos de ROM (lo normal) o RAM (opcional).

En particular, los bits del puerto R6510 = $0001 son:

Bit Nombre bit Si vale 0 Si vale 1
0 LORAM Las direcciones $a000 – $bfff direccionan RAM Las direcciones $a000 – $bfff direccionan la ROM con el intérprete de BASIC
1 HIRAM Las direcciones $e000 – $ffff direccionan RAM Las direcciones $e000 – $ffff direccionan la ROM con el Kernal
2 CHAREN Las direcciones $d000 – $dfff direccionan la ROM con el mapa de caracteres Las direcciones $d000 – $dfff direccionan los chips especiales y la RAM de color

El registro R6510 tiene más bits (3, 4 y 5), pero tienen que ver con el datasette, y no con los mapas de memoria. Los bits 6 y 7 no se utilizan.

Extensiones de RAM:

Total, configurando un 0 en el bit 0 de R6510 podemos eliminar el intérprete de BASIC y ganar 8K de RAM adicionales. Igualmente, configurando un 0 en el bit 1 de R6510 podemos eliminar el Kernal y ganar otros 8K de RAM adicionales.

Podemos eliminar sólo el BASIC o BASIC y Kernal. Lo que no podemos hacer es mantener el BASIC y quitar el Kernal, puesto que el BASIC se apoya en éste.

De este modo, si tenemos un programa en ensamblador / código máquina que es muy grande, podemos adaptar el mapa de memoria a nuestras necesidades:

Memoria - sin BASIC

Memoria - sin BASIC ni Kernal

Y si aun así sigue sin caber en RAM, tendremos que organizar el programa en varios “trozos” (por ejemplo, pantallas 1 – 10, pantallas 11 – 20, etc.) de modo que en cada momento tengamos cargada en RAM sólo la parte que estamos usando y, mediante cargas sucesivas, ir cambiando de parte.

Todos estos mapas de memoria, y otras posibilidades que hay si tenemos en cuenta los cartuchos de expansión, se describen en las páginas 260 y siguientes del “Programmer’s Reference Guide”.

Modelo de “RAM bajo ROM”:

Al modelo de memoria del C64 se le llama de “RAM bajo ROM”. Esto no sólo significa que haya bloques de RAM que están ocultos detrás de otros bloques de ROM y que, desactivando la ROM, se pueda usar la RAM.

Es que, además, y de forma sorprendente, se pueden usar los bloques de ROM y RAM a la vez. Veamos cómo:

RAM bajo ROM.PNG

Supongamos que tenemos los bloques de ROM activos (bits 0 y 1 de R6510 con valor 1). En esta situación, si leemos la posición $a000, puesto que la ROM está activa, estamos leyendo la ROM:

Lectura ROM

Pero si escribimos en la posición $a000, puesto que la ROM está activa, y la ROM es de sólo lectura, no tendría sentido escribir en la ROM. De hecho, es físicamente imposible escribir en la ROM. Por ello, lo que ocurre en realidad es que estamos escribiendo en la RAM que está “por debajo”:

Escritura RAM.PNG

De este modo, es perfectamente posible hacer cosas como:

  • Copiar el intérprete de BASIC de ROM a RAM.
  • Modificar el intérprete de BASIC ya copiado en RAM.
  • Desactivar la ROM de BASIC, activando la RAM.
  • Y usar el intérprete modificado en RAM.

Y los mismo con las rutinas del Kernal.

Por ejemplo, podemos modificar el “prompt” de BASIC de “READY.” a “C:/>” de este modo: (versión en ensamblador)

  • Copiamos el intérprete de BASIC de ROM a RAM:

Copia BASIC

  • Cambiamos el “prompt” en RAM (posiciones 41848 a 41853):

Cambia prompt.PNG

  • Desactivamos la ROM de BASIC, dando paso a la RAM:

Desactiva BASIC

A partir de ese momento, el “prompt” deja de ser “READY.” y pasa a ser “C:/>”. Esto es así porque se está ejecutando la versión modificada de RAM. Igualmente, podríamos modificar comandos de BASIC o añadir otros nuevos.

Mapa de caracteres en ROM:

Sin actuar sobre el registro R6510, el mapa de caracteres en ROM no está accesible. Es decir, sí está accesible para el VIC para pintar los caracteres en pantalla, pero no está accesible para el 6510 o, lo que es lo mismo, no está accesible para los programas que se ejecutan en él.

Esto es fácil de comprobar si tenemos en cuenta que el primer carácter del juego de caracteres es la @:

Arroba

Si el mapa de caracteres en ROM fuera direccionable, al leer la primera posición (la $d000 = 53.248) deberíamos leer el valor %00111100 = 60, ya que la fila superior de la @ tiene activados los bits 2 – 5. Sin embargo, leemos 0:

Mapa de caracteres no direccionable.PNG

Esto es así porque, en realidad, tras la dirección $d000 lo que estamos leyendo es el registro SP0X del VIC, es decir, la coordenada X del sprite 0.

De hecho, podemos cambiar el valor de SP0X = $d000, lo que viene a confirmar nuevamente que no estamos direccionando ROM, porque la ROM no se puede modificar:

SP0X.PNG

Total, el mapa de caracteres no está inicialmente disponible para el 6510 (ojo, sí para el VIC). Sin embargo, configurando un 0 en el bit 2 de R6510 podemos dejar de direccionar los chips especiales (VIC, SID y CIAs) y pasar a direccionar la ROM con el mapa de caracteres.

Esto puede ser útil, por ejemplo, para copiar ese mapa de caracteres de ROM a RAM, y luego adaptar los caracteres que sean de interés, a modo de juego de caracteres personalizados.

Sin embargo, este activar el mapa de caracteres no es inocuo, porque va acompañado de desactivar la entrada / salida. Por tanto, si se hace, hay que hacerlo con cuidado. Previamente habrá que desactivar las posibles interrupciones generadas por la entrada / salida (ver registro CIAICR) porque, caso de no desactivarlas, si se produjera una interrupción de este tipo durante el proceso, ésta no podría ser identificada ni tratada correctamente.

Total, casi merece más la pena diseñar un juego de caracteres personalizados completo, pero tomando como base de partida los caracteres estándar (como hace el editor de caracteres de CBM prg Studio). Te evitas andar copiando los caracteres estándar de ROM a RAM y, sobre todo, te evitas problemas con las interrupciones.

En todo caso, han pasado 30 años y no dejan de sorprenderme las capacidades del C64. Y eso que no hemos hablado de cartuchos de expansión…


Programa de ejemplo: Prog61

Enlaces de descarga del código

Algunos lectores me están pidiendo que habilite enlaces para facilitar la descarga del código ensamblador, tanto de los proyectos del volumen I como de los proyectos del volumen II.

Ningún problema, ahí van:

  • Enlace para descarga del código ensamblador de los proyectos del volumen I, incluyendo las librerías: volumen I
  • Enlace para descarga del ensamblador de los proyectos del volumen II (Asteroids), incluyendo las librerías mejoradas: volumen II

Espero que con esta medida resulte más fácil descargar, revisar y probar el código.

¡¡Feliz 2020!!

Otro blog interesante

Al comienzo del blog tenéis una selección importante de referencias sobre C64. Las tenéis de muchos tipos: generalistas, sobre emulación, sobre programación, sobre libros, sobre juegos, sobre música, etc.

Posteriormente, con el desarrollo del blog, hemos ido completando esas referencias. Era imposible tenerlas todas claras al comienzo. En Internet hay muchísimo material sobre C64, aunque suele estar en inglés y un tanto disperso.

Hace unos meses pude conocer otro blog que me pareció interesante: «A C64 game in several steps (lots of them)». Todavía no lo he revisado completo, pero sí las primeras entradas.

El blog me parece interesante porque describe cómo programar en ensamblador un juego para C64. Ahora bien, ya en la primera entrada se mete directamente (y sin mayor explicación ni preámbulo) en temas como sprites, caracteres personalizados, bancos del VIC o el ráster.

Además los ejemplos están programados para ACME, aunque con pequeñas adaptaciones son perfectamente válidos para CBM prg Studio.

Por tanto, hace falta un poco de base para meterle mano. Yo recomendaría al menos tener revisado y claro el material del primer libro.

¡¡Felices Fiestas!!

Reacciones al nuevo volumen II

Hace casi una semana que se publico el nuevo libro, y ya podemos comentar algunas de las reacciones.

El nuevo volumen II ha llegado a estar en el puesto número 6 de su categoría en Amazon, y el puesto 256 del ranking global de Amazon:

Número 6 educación.PNG

Por otro lado, empiezan a verse las primeras valoraciones de algunos lectores que, de momento, son muy buenas:

Opiniones 11

Muchas gracias a todos por el interés 🙂

Nuevo libro: Programación Retro del Commodore 64 Volumen II

Como os anunciaba hace unos días, acaba de publicarse en Amazon el nuevo libro «Programación Retro del Commodore 64 Volumen II»:

Portada ppal Volumen II

Son 230 páginas con el contenido que hemos tratado en el blog durante los últimos meses (de agosto a noviembre), es decir:

  • El enfoque de desarrollo incremental.
  • El uso de herramientas y librerías de desarrollo actuales.
  • La estructura del proyecto.
  • El diseño y movimiento de sprites.
  • Los caracteres personalizados.
  • Los bitmaps.
  • La lectura del joystick y el teclado.
  • El bucle de juego, con sus inicializaciones y actualizaciones.
  • La nave, los asteroides y los disparos.
  • La detección de colisiones y la animación de explosiones.
  • Los niveles de dificultad progresivos.
  • Las pantallas de inicio, de juego, y de fin.
  • El sonido con el SID.
  • La presentación de números en decimal.

Y todo con la idea de inspirar y ayudar a quien quiera animarse a hacer sus propios proyectos con esa maravillosa máquina que es el C64.

El libro está disponible en los principales portales de Amazon:

Espero que al menos guste tanto como el primer volumen 🙂 .

Un par de películas interesantes

Me pregunta un lector cómo hacían los chavales de los 80 para aprender a programar el C64 y desarrollar aquellos juegos.

Ya comentaba al comienzo del blog que, al menos en la España de los 80, circulaba poca información. Había algunos libros y algunas revistas. De los primeros, me gustaban los libros blancos y rojos de Data Becker, y de las segundas «Commodore World» y «Commodore Magazine». Por supuesto, no existía Internet, aunque empezaba a haber algunos servicios en línea (las famosas BBS’s).

Información 80.PNG

En Estados Unidos, Reino Unido y Alemania sí había más información. Si buscáis en Archive.org encontraréis bastantes libros en inglés de aquella época. Aun así, la informática, o al menos la informática personal, estaba en sus comienzos también allí.

Entonces… ¿cómo aprendían los chavales? Pues básicamente eran autodidactas. Suplían la falta de formación e información con muchas ganas, mucho ingenio y muchas horas de dedicación.

Hay un documental que describe este proceso en el caso del Reino Unido: «From bedrooms to billions» (2014). No he conseguido localizarla en las plataformas de streaming habituales (Netflix, Amazon, Movistar, etc.), pero sí he localizado una página web que parece específica de la película:

https://frombedroomstobillions.com/

También relacionada con el C64, aunque no específicamente con el tema de los jóvenes programadores, hay otra película que me gusta: «The Commodore Story» (2018). Se trata de otro documental que revisa la historia de Commodore en general. Incluye muchas entrevistas a los protagonistas de aquella época, incluyendo al hijo de Jack Tramiel y los ingenieros que diseñaron muchos de sus equipos.

Nuevamente, no la he encontrado en las plataformas de streaming habituales, pero sí he localizado esta página:

https://thecommodorestory.com/

¡¡Que las disfrutéis!!

Documentales.PNG

Futuro

En su momento hablamos de desarrollar varios juegos con enfoques diferentes, complejidades crecientes, etc. Pero después de más de 50 entradas, 23 versiones del proyecto, y 200 páginas de contenido, se hacen aconsejables una parada y reflexión.

Hay un autor canadiense llamado Alexander K. Dewdney que en los 80 escribía en Scientific American sobre informática y matemáticas. Sus artículos me gustaban mucho, porque tenían un planteamiento abstracto y, en general, no acababa de resolver completamente los problemas que planteaba, dejando ese reto al lector.

En su día –y habrán pasado más de 30 años– leí un artículo suyo sobre cómo desarrollar un juego de damas, o juegos de tablero en general, que me dejó muy prendado. Quién sabe, quizás me anime con el reto 30 años después y con un C64…

HVSW.