El compilador de Basic de Hisoft para el Sinclair ZX Spectrum de 48K, apareció por primera vez en 1986.

Fue escrito por Cameron Hayne, quien estima que empleó en el desarrollo un año hombre, lo cual sería hoy en día un esfuerzo minúsculo para desarrollar un compilador.

Estaba totalmente programado en código máquina del Z80, apenas ocupaba 12 Kb de memoria. Ésta pequeña maravilla era capaz de compilar la mayoría de programas Basic sin ningún cambio. A diferencia de otras herramientas, soportaba totalmente los números en coma flotante.

Posteriormente se fueron corrigiendo errores, y añadiendo nuevas funcionalidades, hasta llegar a la versión 1.2 de 1987. Se hicieron diferentes versiones para los nuevos Spectrum de 128K, con más memoria; Spectrum +2, que añadía un chip de sonido multicanal; y para el Spectrum +3, que sumaba a todo lo anterior una unidad de disco de 3 pulgadas.

Debemos tener en cuenta que el hardware del Spectrum, era muy limitado, un procesador de 8 bits corriendo a 3,5 Mhz, y 128 Kb de memoria paginada en 2 bloques de 64 Kb en el mejor de los casos. Con estos recursos tenía que ser capaz de interpretar el código Basic de nuestros programas, y ejecutarlos, por lo que no es de extrañar que el rendimiento del lenguaje fuera bajísimo, y solamente apto para aprendizaje.

En aquella época, la mayoría de programas y juegos, se desarrollaban en código máquina, o en ensamblador. Solamente algunos aplicativos de gestión podían permitirse el lujo de estar escritos en un lenguaje de mayor nivel (C, Pascal, Basic, Forth, …) y posteriormente compilados.

Por aquellos años, mis conocimientos de ensamblador no eran suficientes para escribir un programa entero, así que me conformé con el Basic interpretado. Hasta que el compilador de Hisoft, me cambió la vida.

Me permitía mejorar tremendamente el rendimiento de mis pequeños juegos, tan solo compilando, al mismo tiempo que las rutinas sencillas y críticas en tiempo, las podía programar en ensamblador. La calidad final, no se asemejaba ni de lejos a los desarrollos comerciales, pero a mi me bastaba.

A continuación os pongo una pequeña demostración con la que he estado jugueteando. Los pantallazos son de un Spectrum +3 emulado con Spectaculator.

Cargamos el compilador de la unidad de disco. El binario son 14 Kb, por lo que en menos de 2 segundos lo tenemos operativo.

Desde el propio editor de Basic, escribimos el programa en cuestión. Este de aquí, se encarga de ir poniendo todos los píxeles de la pantalla en color negro.

Ahora procederemos a compilarlo, para ello, debemos utilizar las extensiones de Hisoft que le indican al compilador desde donde hasta donde se genera código compilado del fuente. Agregamos las lineas 5 y 65, que engloban todo el código.

Por compatibilidad con el Basic interpretado, el compilador está asumiendo que todas las variables, en este caso f, son en coma flotante. En efecto esto no es demasiado eficiente, ya que estás instrucciones se emulan (los comprocesadores matemáquicos se popularizaron bastantes años después).
Para evitar esto, insertamos la linea 5, que indica al Hisoft Basic que f es una variable de tipo natural (unsigned int de 16 bits).

Finalmente compilamos nuestro programa. El tamaño del código generado es de tan solo 96 bytes, con todas las funciones necesarias incluídas (el enlazado incremental, también fue una técnica que se popularizó bastantes años después).

Para acabar, solamente nos queda mirar la velocidad de ejecución de este programa de ejemplo:

Entorno Tiempo de ejecución (segundos)
Sinclair Basic (interpretado) 44
Hisoft Basic (compilado) 4
Hisoft Basic (compilado optimizando a números naturales) 1

Solamente recompilando, hemos obtenido una mejora de un 1100%. Posteriormente, cuando hemos aplicado la conversión a enteros, y hemos vuelto a compilar, la ganancia ha sido de un 4400%.

Los resultados son increíbles, no tanto por la mejora de rendimiento obtenida, sino por la calidad del código generado por un compilador que ocupa 14 Kb de memoria con runtimes incluídos.

Por último, aunque pueda parecer que el tiempo de 1 segundo, es insuperable, en ensamblador se podría reducir como mínimo a 0,25 segundos con el mismo algoritmo, y su ejecución sería casi inmediata usando LDIR. Refrescándome un poco la memoria, iría así:


ld a, 255
ld hl, 16384
ld (hl), a
ld de, 16385
ld bc, 6140
ldir
ret