lunes, 28 de noviembre de 2011

Imaginemos la situación, tenemos un bonito MSX2 y al intentar ejecutar SCREEN 8 obtenemos un curioso mensaje de error: ILLEGAL FUNCTION CALL.

¿Cómo? ¿Que no es posible? Pues lo cierto es que sí lo es. Y no sólo SCREEN 8, también sucedería lo mismo con SCREEN 7. Mirad este vídeo si no os lo creéis.
Todos estamos acostumbrados a trabajar con MSX2 que tengan, al menos, 128Kb de VRAM (digo al menos, porque se puede aumentar la memoria de vídeo hasta los 192Kb, pero eso es otra historia). Sin embargo, existen varios modelos de MSX2 con tan solo 64Kb de VRAM. Según la lista de hardware de la MSX faq, dichos modelos son:
Bien, en todos estos modelos cualquier intento de usar tanto SCREEN 7 como SCREEN 8 va a resultar en un bonito error. ¿Por qué? La respuesta la encontramos indagando un poco en la documentación técnica disponible (os recomiendo PORTAR).

Resulta que estos dos modos utilizan un total de 256 bytes por cada línea horizontal y por razones de velocidad la VRAM está direccionada de diferente forma: los 64K inferiores almacenan las direcciones pares y los 64K superiores almacenan las direcciones impares. De esta forma el controlador de vídeo puede incrementar las líneas de dirección inferiores a la misma velocidad de reloj que en los modos de 128 bytes por línea horizontal (como pudiera ser SCREEN 5).

Lo divertido del caso es que esto se hace de forma totalmente transparente para el programador. Todo el cambio de direcciones se realiza por hardware, sin que nosotros tengamos necesidad de saber ese comportamiento. Bien. Con esta pequeña explicación, habréis deducido que si sólo tenemos 64Kb de VRAM, por mucho que el hardware intente entrelazar la imagen, todos los bytes impares no podrán escribirse, con lo que el VDP debería leer $FF y tendríamos una bonita pantalla llena de líneas verticales en blanco entrelazadas con nuestra imagen.

El BASIC, que es más inteligente de lo que parece, chequea una variable que la BIOS ha calculado para comprobar cuanta VRAM hay. Si sólo hay 64Kb de VRAM no permite activar ninguno de estos modos, por lo que en un MSX2 con 64Kb de VRAM sólo tenemos los modos de vídeo del 0 al 6.

Las preguntas que surgen ahora son, ¿qué pasaría si le decimos al VDP que construya una imagen tomando los datos de la VRAM que no existe? ¿Lee 255 y nos muestra una imagen en blanco? Pues lo que sucede es, ni más ni menos que lo que se puede ver en este vídeo:
¡Flipante! El VDP se arma un lío tremendo y nos muestra una imagen que va cambiando de forma constante. Aunque tiene algunos patrones, no hemos podido averiguar por qué sale eso en concreto. No cambia ni aunque haya una imagen en la página 0, sólo alguno de los colores, que lo toma del segundo parámetro que utilicemos en la instrucción COLOR.

Es hora de probarlo

Pues nada, sólo tenéis que coger vuestro MSX2 con 64Kb de VRAM y prob... ¿qué? ¿Que no tenéis un MSX2 con sólo 64Kb de VRAM? Bueno, pues caben dos opciones: quitarle los chips de VRAM de los 64Kb superiores o bien usar un emulador... ¿O no? Probemos con los dos emuladores más populares: BlueMSX y OpenMSX. Crearemos una máquina MSX2 con sólo 64Kb de VRAM y veremos si al ejecutar SCREEN 8 obtenemos un bonito ILLEGAL FUNCTION CALL.

¡Vamos a por BlueMSX!

Probemos primero con BlueMSX. ¡Anda! ¡Pero si me deja ejecutar SCREEN 8! No, no os he estado engañando. Si volvemos a arrancar la máquina, lo primero que nos llama la atención es que en el arranque del MSX2, bajo el logo, veremos perfectamente que la máquina tiene 128Kb de VRAM, cuando en realidad le hemos dicho que debe tener 64Kb.

¿Por qué? Resulta que el BlueMSX emula los 64Kb de VRAM haciendo mirroring de los 64Kb inferiores en los superiores. Esto significa que si escribimos en cualquiera de esos dos bancos, en realidad estamos escribiendo en ambos a la vez. Por este motivo la BIOS se cree que hay 128Kb de VRAM y así actualiza sus variables, pero esos 64Kb superiores simplemente son una copia de los inferiores.

Sí, podemos usar SCREEN 8, pero es algo totalmente ilegible. Para poder comprobarlo utilizad el siguiente código en BASIC:

10 COLOR 15,0,0:SCREEN 8
20 OPEN "GRP:" AS#1
30 COLOR 255
40 PSET (0,0),0
50 PRINT#1,"HELLO WORLD!"
60 GOTO 60

Mientras que en un ordenador real con 64Kb de VRAM este código no funciona porque nos da un error en la línea 10 (al intentar ejecutar SCREEN 8), en el BlueMSX sí que funciona, aunque el resultado no es legible. Probad el mismo listado con SCREEN 7 (cambiando la línea 30 por "COLOR 15", obviamente) y veréis que sucede algo similar. En un MSX2 (o superior) con 128Kb de VRAM este programa funciona como se supone debe hacer.

Y ahora Open MSX

Probemos en Open MSX 0.8.1 (la última versión disponible). Nos creamos una máquina con 64Kb de VRAM y ¡maravilla! ¡En el arranque se detectan sólo 64Kb de VRAM! Tecleamos SCREEN 7 y obtenemos el error. Con SCREEN 8 nos pasa lo mismo. Nunca un error del BASIC había originado tantas alegrías.

Resumiendo: existen (al menos) cinco modelos de MSX2 con sólo 64Kb de VRAM. En dichos modelos no podemos contar ni con SCREEN 7 ni con SCREEN 8. Si estamos realizando algún juego que vaya a usar esos screens, o que requiera 128Kb de VRAM, deberemos tener en cuenta su existencia y si queremos ser puristas, en caso de que no haya VRAM suficiente adaptarse (como hace QBIQS) o mostrar un mensaje de error.

También hay que tener en cuenta que BlueMSX está emulando de forma incorrecta los 64Kb de VRAM, ya que, como hemos comprobado, cuando intentamos visualizar el contenido de los 64Kb superiores en el Hitachi MB-H3, obtenemos una imagen bastante extraña. Eso nos permite concluir que este modelo no hace un mirroring completo de los 64Kb inferiores en los superiores.

Nuevamente quiero agradecer a BiFiMSX su ayuda sobre este tema. También a él le debemos que C-BIOS realice correctamente la detección de los 64Kb de VRAM, algo que hizo tras una charla que mantuvimos al descubrir que el QBIQS en C-BIOS con 64Kb de VRAM no funcionaba como es debido. También he de agradecer a JLTurSan que me haya prestado su flamante Hitachi MB-H3 para hacer las pruebas sobre la máquina real.