Mis años adolescentes: El compilador de Pascal para transputer

Transputer homebrew board
Erase una vez, cuando era adolescente, escribí un compilador de Pascal casi completo para transputer (el tipo FILE nunca se completó). El lenguaje Pascal fue diseñado en 1971 por Niklaus Wirth, como una versión educativa del lenguaje Algol, que data de 1960. Alcanzó su máxima popularidad con Turbo Pascal y Delphi de Borland. Borland fue fundada por Philippe Kahn, quien estudió Pascal con Wirth.
El año 1993 fue la convergencia de varias cosas que estaba aprendiendo: Pascal (a través de The BYTE Book of Pascal), generación de código (Compiladores: Principios, Técnicas y Herramientas), y programación de transputer.
Fue una época en la que el INMOS transputer prometía computación paralela para todos, pero era demasiado caro. Hicieron algunas cosas buenas, como el procesamiento de 32 bits y un transputer T805 muy rápido con 64 bits de coma flotante antes de que el Intel 486DX2 fuera popular.

Y en el comienzo era un transputer

Transputer homebrew board
Mi padre consiguió un par de chips transputer y los chips de interfaz requeridos. Era 1992, y el precio de un transputer era de $500,000 pesos mexicanos. Como referencia el dólar americano se cotizaba a $380 pesos, un coprocesador matemático Intel 8087 se vendía a $297,000 pesos, un litro de leche costaba $2,300 pesos, y un kilo de tortilla de maíz costaba $1,000 pesos.
Hizo esquemas y mi deber era rehacerlos usando mi software de dibujo de diagramas electrónicos. También escribió largas páginas a mano explicando como funcionaba, y yo tecleaba todo y sacaba los documentos en limpio.
Mi padre escribía pequeños programas de prueba, y se lanzaba a una plática de como el algoritmo de Fibonacci más rápido demostraría algo, y formaría la base para algoritmos de más alto nivel. Estaba entusiasta intentando algoritmos y optimizando por días enteros, también dijo que este procesador era el más rápido del mundo.
El año 1993 llegó rápido, yo era un adolescente de 14 años y estaba aburrido. Pensé que si el procesador era tan rápido debía haber una forma de probar su potencial. Mientras él probaba nuevas instrucciones del procesador, yo leía el manual a escondidas, intentando encontrar una manera en mi mente de iniciar algo, y haciendo una comparación mental con mi conocimiento de Z80 y 8086 contra el extraño procesador transputer basado en pila.
También estudié algo de FORTH (nombrado como el heraldo de la cuarta generación de lenguajes, pero el sistema operativo de su desarrollador solo permitía cinco letras para el nombre), pero nunca pude entender como el compilador armaba su conjunto de palabras.

¡Era muy rápido!

Libro Transputer Assembly Language Programming (frente)
En una casualidad completa, estaba leyendo The BYTE Book of Pascal que discutía bastante acerca de la notación polaca inversa (otro nombre para cálculos hechos en una pila), y recientemente había obtenido el libro de Compiladores: Principios, Técnicas y Herramientas, que estaba teniendo dificultades para entender.
Comencé mi exploración en tierras desconocidas con un bucle. Un bucle simple para ver que tan rápido era el procesador. Escribí el código para el bucle, lo hice contar un millón de veces (bueno, 1048576 veces), y me quedé sorprendido al ver que de hecho el procesador era más rápido que cualquier cosa que hubiera visto. El procesador Z280 podía correr un bucle de 65536 veces en menos de un segundo, pero el transputer estaba contando un millón en menos de un segundo.
El tablero del transputer era esencialmente el procesador T805 rodeado por 32K de memoria RAM de alta velocidad, y solo podía enviar y recibir datos seriales a través de un tranceptor. Sin pantalla, sin teclado, sin sonido. La computadora basada en Z280 desarrollada previamente servía como anfitrión o host.
Por supuesto, me quedé picado de hacer algo más complejo, y mi primer proyecto fue escribir un ensamblador para el T805. De esta forma podía hacer proyectos más complicados para probar.
Libro Transputer Assembly Language Programming (detalle contraportada)
Este transputer tenía la rareza de que sus instrucciones básicas eran de diferentes tamaños. Cargar una constante de 0 a 15 se lograba con una instrucción de un solo byte, pero cada 4 bits extras requerían otro byte. Cargar una constante completa de 32 bits requería 8 bytes. Implementar un ensamblador para esta bestia requería repensar por completo mi enfoque de ensambladores. Me tomó varios meses del año 1993 hacerlo funcionar.
El primer ensamblador estaba escrito en código máquina Z280. Tomaba el código fuente de un archivo, lo ensamblaba, y expandía las instrucciones del transputer como era necesario hasta que llegaba a una estabilidad de cero cambios.
El procesador Z280 tiene la habilidad de correr como un Z80 normal leyendo datos y código de $0000-$ffff, y poner un área de MMU de 64K para systema y otros 64K para usuario. Utilicé las instrucciones extendidas para obtener un buffer de texto de 64K para mi editor de texto, y para construir los datos requeridos por el ensamblador.
Una vez que tuve un ensamblador funcional, construí facilmente un monitor de sistema para desarrollar programas. Era un nuevo mundo para mí, ya que nunca había desarrollado para un procesador de 32 bits.
Mi éxito con el ensamblador me dirigió a otro objetivo: Portabilidad de P-code. Ya había adaptado el compilador de Tiny Pascal escrito en BASIC que apareció en The Byte Book of Pascal para correr en la máquina Z280, no fue mucho esfuerzo ya que el compilador original corría en una máquina 8080, que es muy compatible con Z80. Generaba P-code (un pseudocódigo) que era interpretado para correr los programas de Pascal compilados.
¿Pero qué tal si en lugar de un intérprete de P-code pudiera escribir un convertidor de P-code a ensamblador de transputer? Me puse a trabajar e hice una versión rápida y sin pulir de un convertidor de P-code a transputer, y estuve muy feliz aunque el compilador corriendo en lenguaje BASIC era increíblemente lento.
También el código generado era increíblemente ineficiente.

Llega el dragón

Era el mes de julio cuando comprendí finalmente la utilidad de la generación de árboles para expresiones. La función gencódigo del libro del dragón (sección 9.10, figura 9.25) fue una inspiración completa.
Hasta ese momento, todos mis compiladores sufrían de un exceso de instrucciones push y pop innecesarias junto con optimización de mirilla muy básica, porque no sabía como optimizar adecuadamente. Ahora, el número de registros en el transputer era 3 (A, B y C), y solo con ordenar el árbol podía optimizar en una forma sorprendente y el código generado era muy compacto.
Aún así el lenguaje BASIC era demasiado lento para programas mayores, más cuando comencé a figurarme que el compilador de Pascal podía ser escrito en Pascal. Decidí codificarlo usando Turbo Pascal en MS-DOS.
El 27 de septiembre de 1993 comencé a portar el compilador a Pascal. Me tomó dos días completar el compilador básico, y estuve muy feliz de verlo funcionar. Para mi mayor decepción, excedía los 32K de memoria que tenía disponible en el tablero del transputer.
Necesitaba 25K de RAM para ejecutar el compilador, y si iba a auto-compilarse necesitaba otros 25K para los datos. Intente todas las formas posibles para optimizarlo, sin lograrlo, hasta que dos días después mi padre me sorprendió poniendo 128K de RAM en el tablero, y fui capaz de cargarlo.
Volví a la máquina Z280 donde use mi editor de texto para seguir desarrollando el compilador. Hice un programa "driver" que alimentaba el código fuente al transputer, y obtenía de regreso el código compilado para guardarlo en la unidad de disco. El código ensamblador resultante todavía era ensamblado en la máquina Z280.
Encontré unos pocos errores en el compilador y el ensamblador, y mi compilador de Pascal estaba funcionando y corriendo. Quedé maravillado después de lograr que mi compilador de Pascal se autocompilara en el tablero del transputer.
También estaba aprendiendo que existían normas. Niklaus Wirth hizo un trabajo asombroso especificando el lenguaje Pascal, y fui muy afortunado de tener varios libros de Pascal a la mano.
Pronto tuve mi primer objetivo: un compilador completo de Pascal. ¿No era más de adolescentes perder el tiempo en las arcades? De cualquier forma, trabajé paso a paso en mejorar el compilador de Pascal, y cada pequeño logro me ponía muy contento. Fue un enorme logro llegar a implementar el punto flotante, aunque facilitado por que el transputer ejecutaba directamente el punto flotante. Algunas optimizaciones lograron 100% extra de velocidad para programas compilados.
Al final me tomó poco más de un mes crear un compilador casi completo de Pascal. Nunca terminé la parte final del tipo FILE, más que nada porque no comprendía como funcionaba. También dividí el compilador en varias piezas (cada uno menor a 64K) para que pudiera seguir editando el compilador con mi propio editor de texto.
Tenía un libro de Ray Tracing y porté el código a Pascal, y todo el mes de noviembre de 1993 estuve depurando mi compilador de Pascal y mejorando la optimización para generar imagenes con ray tracing. Estaba muy feliz, y actualizaré este artículo si encuentro el código fuente e imágenes.
Estaba muy seguro de que Pascal era el futuro, hasta que empecé a sentirme incómodo con los tipos estrictos de Pascal, ya que era muy limitante para hacer programación de sistemas.
Incremente mi confianza con este compilador de Pascal y me sirvió como una buena experiencia para mi siguiente logro: un compilador de C para transputer. Pero esa será otra historia.

32 años después

No puedo creer que ahora es el año 2025. Mi compilador de Pascal hoy permanece como una curiosidad y un testamento a mi esfuerzo. Un compilador de Pascal casi completo escrito por un adolescente muy versado en técnica. Nunca se me ocurrió que pude haberlo vendido. En esa época cada utilidad de desarollo de software tenía un precio muy alto, aún más para el transputer.
Para este artículo extraje la versión final de mi compilador de Pascal, y dado que no tenemos la computadora Z280 como anfitrión, tuve que escribir el software de soporte en lenguaje C moderno. En principio el emulador para el transputer, y el ensamblador.
El código fuente esta disponible en https://github.com/nanochess/transputer
¡Que lo disfrutes!

Ligas relacionadas:

Última actualización: 04-feb-2025