sábado, 5 de marzo de 2022

Conexión MIDI de un teclado Toshiba HX-MU901

Hace relativamente poco conseguí un teclado Toshiba HX-MU901 en muy buen estado, con su cartucho HX-MU900. Aunque no soy músico, de siempre me ha gustado la cuestión de las tecnologías musicales electrónicas. De hecho, en su día realicé el programa Simphony para MSX-1, y hacía mis pinitos con el Amiga 2000.

El HX-MU900 es un cartucho MSX-AUDIO que permite reproducir notas de un banco de instrumentos que lleva. Es muy sencillo, pero funciona bastante bien. No tiene sensibilidad de pulsación de tecla, pero para mi nivel no lo necesito :-). Tengo un sintetizador Kawai XS-1 y me pareció interesante estudiar si era posible conectar este teclado mediante MIDI. Y el resultado es el que relato en esta entrada del blog.

Además del HX-MU900, tengo el Philips NMS 1205 (conocido como el Philips Music Module) que también es MSX-AUDIO, al que se le puede conectar un teclado similar de Philips, que no tengo.  El conector es también  de tipo (IDC-20), pero el conexionado es distinto al del Toshiba. El Music Module tiene conexiones MIDI IN y OUT, aunque el programa que contiene su ROM no utiliza el MIDI IN. Me dejo pendientes dos manualidades: a) hacer un adaptador de un conector de teclado a otro (esto es trivial), b) hacer un programa MSX que utilice el MIDI IN del Music Module (esto es relativamente sencillo, ya que se puede deshabilitar el arranque del programa de la ROM del módulo, pero requiere decodificar los mensajes MIDI). En algún momento me gustaría poder conectar el teclado al programa Simphony.

El dispositivo

Los componente son sencillos y fáciles de encontrar. El trabajo de montaje es relativamente simple. La lista de componentes (BOM) es la siguiente:

  • Adafruit Feather M0
  • Adafruit Featherwing MIDI
  • Adafruit Feather Quad 2x2
  • Placa de prototipo PCB
  • Tira de pines / Conector IDC-20 macho

Como mi objetivo es la funcionalidad, no me ha importado el coste ni el hacerlo compacto. Obviamente, para fabricar en serie habría utilizado otro procesador (aunque basado en el Cortex M0) y el resto iría en una PCB específica.

La única cuestión delicada es el conexionado. Lo mas complicado has sido encontrar precisamente el patinaje del conector. Tras muchos tumbos di con un documento (realizado por Ton Valkenburgh) con el esquema. El teclado es básicamente una matriz de filas y columnas, con 8 filas de entradas (IN0-IN7) y 10 columnas de salidas (OUT0-OUT9). Total 18 líneas. Por fortuna el Feather M0 tiene precisamente 18 pines libres que podemos usar como E/S, ya que tenemos que dejar 2 para el puerto serie necesario para la comunicación MIDI. La forma de leer este tipo de matrices es utilizando resistencias de pull-up en las entradas, por lo que he utilizado pines con pull-up interno para las líneas IN (y así me ahorro soldar resistencias). El conexionado final es el siguiente:


NOTA: El GPIO#13, en las placas Feather M0 lleva conectado un LED rojo. Esto produce pulsaciones de tecla "fantasma" al escanear las teclas correspondientes a OUT5. Para evitarlo es necesario quitar este LED o su resistencia. En esta operación lo normal es que dicho componente se estropee, pero no tiene ningún efecto secundario.

Con una PCB de prototipado y con paciencia se monta un placa que haga estas conexiones del IDC-20 macho a los puertos correspondientes del Feather M0. Como no tenía a mano ningún conector IDC-20 he utilizado directamente unas tiras de pines. El resultado se puede ver a continuación. Ni os molestéis en criticar el resultado, ya que soy poco manitas. Y me funciona, que es lo que importa.


El montaje final es muy simple ya que sólo hay que montar el Feather M0, el interfaz MIDI y la placa de conexionado en la placa Quad. Aquí hay poco que comentar. El resultado es el siguiente.


El programa

    El concepto del programa es muy simple. Comprobamos periódicamente el estado de las distintas teclas. Si detectamos algún cambio enviamos un mensaje MIDI noteOn (pulsamos tecla) o noteOff (soltamos tecla) con la nota correspondiente a la tecla. Y repetimos. De esta forma podemos registrar la pulsación simultánea de todas las teclas del teclado (otra cosa es que después el equipo que reciba pueda gestionar todas esas notas de forma simultánea). El código completo para el entorno Arduino está disponible en GitHub:

    https://github.com/humbertomb/mymsx/blob/master/midi/FeatherMidiToshiba.ino

    Las cuestiones más relevantes a cómo funciona el mismo las describo a continuación. Comenzamos con las estructuras de datos más importantes.

    Los arrays in y out corresponden al patillaje de las entradas y salidas respectivamente. El array keys contiene los valores lógicos de la matriz de teclado (0 pulsado, 1 sin pulsar). El array de booleanos chan tiene a true aquellas teclas que han cambiado de valor.  Por último el array notes contiene la correspondencia entre cada tecla pulsada y la nota o acción MIDI correspondiente. En este caso las 8 primeras columnas corresponden a las teclas del teclado (blancas y negras) y las últimas 2 columnas corresponden a las teclas del multi-sensor (pads coloreados sensibles al tacto).

    El procedimiento de lectura de la matriz de teclas es genérico para este tipo de circuitos. La idea es ir activando secuencialmente las salidas, y para cada una hacer la lectura de las diferentes entradas, también de forma secuencial. La activación de cada salida se realiza configurando el puerto correspondiente como salidas y estableciéndola a nivel bajo. La lectura de cada entrada se realiza configurando el puerto correspondiente como entradas y habilitando su resistencias interna de pull-up. Posteriormente hay que hacer una espera de 0.05ms para permitir que la línea se estabilice, y posteriormente se realiza una lectura digital de dicho puerto. Con el valor de la lectura se actualizan las celdas correspondientes de los arrays chan y keys. Una vez realizada la lectura de una entrada se deshabilita su resistencia interna de pull-up. Cuando se termina de utilizar una salida, esta se configura como puerto de entrada. 


    El procedimiento de envío de los valores MIDI correspondientes es muy sencillo. Para ello utilizo la fantástica librería Arduino MIDI, de Forty Seven Effects. Hay que distinguir dos casos: a) el envío de las notas por pulsación de las teclas, b) envío de comandos de control por pulsación del multi-sensor. En el primer caso sólo hay que verificar qué teclas han cambiado de valor y enviar un noteOn o noteOff en función del valor del estado de la matriz de teclas. Como el teclado no tiene sensibilidad se envía el valor de presión fijo a 127 (máximo) y se utiliza el canal MIDI 1.


    En el segundo caso sólo hay que verificar qué pads del multi-sensor han cambiado de valor y enviar los comandos MIDI correspondientes. En este caso sólo se utiliza el Program Change, que habitualmente sirve para cambiar el instrumento que se utiliza para reproducir el sonido. Se utiliza una variable global program que contiene el valor del programa seleccionado. Si se pulsa el pad amarillo, el valor de program se reduce 5 unidades. Si se pulsa el pad verde, el valor de program se reduce 1 unidad. Si se pulsa el pad azul, el valor de program se incrementa 1 unidad. Si se pulsa el pad violeta, el valor de program se incrementa 5 unidades.


    El resultado

      Considero que el objetivo se cumple razonablemente bien, con materiales que no son excesivamente caros, en torno a unos 40€. A continuación un sencillo vídeo de prueba.








      miércoles, 23 de febrero de 2022

      Dimens10. Submission to the 2022 10-Liner Contest


      Last year I presented a program to the 10th Edition of BASIC 10 Liner Contest, and the experience was very interesting and encouraging. The main idea is that you develop a game in BASIC with no more than 10 lines of code for 8 bit legacy computers. There are different categories depending on the maximum number of characters per line allowed. After I got notice of the announcement of the 11th Edition of BASIC 10 Liner Contest, I decided to participate, this time with a challenging and technically difficult game (at least for me :-). In this post I will describe my submission to the EXTREME-256 category for this year edition (2022), which I have named Dimens10.


      The idea

      Some time ago I found part of the code of a fast scrolling game I wrote ins the 80's. It was very simple and used some machine code for the scrolling part, which unfortunately I did not found. It was named Cuarta Dimensión (4th Dimension). Not so long ago I started writing a program to automatically generate BASIC code for maze-scrolling programs, which I call aMazeing. With this editor I coded a simple mockup re-incarnation of the game.

      For this submission I wanted to make something similar, which is a challenge because the maze is rather large and needs a lot of code to program it. The base game consisted in roughly 100 lines of code and occupied 14 kB. I only needed to reduce it to 10 lines of code which must not exceed 2.56 kB (that is 256 bytes per line of code, including line numbers). Not so simple.

      In a game you typically start with an idea, gameplay, some graphics and then start coding. In this case I started coding the technical parts, then creating a gameplay which could fit the available space. Just the opposite, although I believe that is not that uncommon.

      I have implemented the game for a MSX-2 machine in SCREEN 1 mode, that is, a semi-graphics mode: you can combine text and sprites, with several coloring constraints. The characters table can be modified so that standard ASCII chars have a different look. The graphics are created by modifying the characters table and locating then was desired on the screen. The only thing that prevents this program to be a pure MSX-1 is the extra VRAM memory needed (more than the basic 16 kB of MSX-1).

      Because moving the characters on screen for scrolling in BASIC is quite slow, I decided to give MSX BASIC Kun a try. BASIC Kun (a.k.a X-BASIC) is a BASIC compiler which is almost a de facto standard. The rules of the contest allow using compiled code. Although it is not strictly necessary (the developed game runs fine without the compiler), the non-compiled experience is quite bad.

      The methodology

      I use aMazeing both for defining the graphics and for generating the code. aMazeing is a program developed in Java which allows the automatic generation of BASIC code (currently only MSX SCREEN 1) for vertical and horizontal scrolling games. The process is as follows (well, actually it is not, it is in fact an iterative process, you know, but you get the idea).

      You start modifying the characters table creating patterns that will make part of the graphics of the game, and the sprites table, both their pixmaps and their colors. I have modified 15 8x8 characters and created a single16x16 sprite.


      The next step is the creation of the maze, which is coded as a bidimensional array of characters/patterns. I have created a 125x13 array and filled it with the modified characters from the characters table.


      The last step is filling the screen with characters, those which will not scroll (the base screen).


      Now here it comes the funny part: coding. I have implemented a specific module for generating BASIC code for the 10-liner contest, in addition to the standard BASIC coding. Because coding a 10-liner is a highly iterative process in which you move pieces of code so that they fit the number of lines (10) and the maximum characters per line (256), this module includes a line counter and a character counter. This is very handy in order to know how much space is available per line. Below appears the count for Dimens10.

      0 chars=255

      1 chars=255

      2 chars=224

      3 chars=247

      4 chars=247

      5 chars=253

      6 chars=245

      7 chars=212

      8 chars=240

      9 chars=221

      -------------------

      Total lines=10     

      Total chars=2399   

      Last, but not least, code generation is quite tricky. For standard BASIC, it is straightforward: you generate DATA lines with all the definitions (patterns, sprites, maze, screen, etc) and then code to read all of them and modifying the corresponding graphical memory (VRAM in MSX parlance). For the 10-liner we need exactly the same, but everything squeezed in ten lines of code. Which is not straightforward at all. In this case, instead of generating a template of BASIC code and then manually coding the game logic, I in-lined the code for the logic with the code for generating the 10-liner. What makes the "wow" is that the BASIC code is parametrised with Java code, as in:

      lunes, 22 de marzo de 2021

      ¿Programación de juegos de 8 bits en 2020?

      ¿Alguna vez te has preguntado cómo se desarrollaban videojuegos en los años 80? Los ordenadores de la época eran muy diferentes a los que tenemos hoy en día, ¿cómo se harían juegos similares en la actualidad? Acompáñanos en este viaje a los 80 donde trataremos los ordenadores MSX y los lenguajes BASIC y ensamblador del Z-80, además de repasar las limitaciones técnicas de aquel entonces a la hora de desarrollar videojuegos. 

      Charla impartida el 18 de diciembre de 2020, en la Facultad de Informática de Murcia y organizada por el Club GameDev. Si te la perdisteis ahora tienes la oportunidad de verla.




      domingo, 7 de marzo de 2021

      Archer10 (Apple II). Submission to the 2021 10-Liner Contest

      Some weeks ago I had notice of a retro programming contest, yes through one of these wasap groups, the 10th Edition of BASIC 10 Liner Contest. The main idea is that you develop a game in BASIC with no more than 10 lines of code for 8 bit legacy computers. There are different categories depending on the maximum number of characters per line allowed. Simple, isn't it? I decided to go for a try, and made a MSX-1 program which I submitted to the contest. You can find a detailed description of the program in Archer 10 (MSX). Submission to the 2021 10-Liner Contest. After I finished, I asked myself: why not an Apple II port? Although I developed some programs in the 80s for Apple II, those were mostly CP/M with the Microsoft BASIC. You can find an example in Recuperación de código MBASIC para Apple II desde listados (it is in Spanish, but you can get the idea from the many pictures. Google translate might also be of some help). Anyway, it is never late for learning. And I had the appropriate material for getting into the job:

      • D. Finningan (2012) The New Apple II User's Guide. Mac GUI, Lincoln, IL (book)
      • M.L. Callerey, R. Schwarz (1984) Apple Graphics Tools and Techniques. Prentice-Hall (PDF)
      I decided to mimic as much as possible the MSX-1 program mentioned above and develop an AppleSoft BASIC one. I had a gameplay and a sample 10-liner source code. That should be more than enough. I wanted to keep high resolution graphics, colors and sounds, even if those for the MSX were a little bit weird (disclaimer: I am very bad at gaming, coloring and music. The perfect combination :-).


      The programming

      The first thing I learned is that double high resolution graphics is not available to BASIC. And standard resolution graphics is crazy on coloring, not to mention the small available palette. Anyway, this did not prevented me to going ahead. Because of the small program size, complex sounds are also out of the game. Well, let's go for a simpler and less visually attractive version, but with the same gameplay I decided for the MSX-1 version.

      I started to code right from the beginning thinking on a 10 lines program, with the experience of the MSX version. But because there were less graphical possibilities, I tried to enter the PUR-120 category. No way.  I had to reduce even more the visual aspects, and I wanted to support a minimum of them. Thus I ended up in the EXTREME-256 category. In addition to only ten lines of code, each line must not contain more than 256 characters. Overall, the code can not be larger than 2.5 Kb !!! To squeeze the code in this size you play the very old tricks. The BASIC interpreter uses a lexical analyzer that is based on keyword detection and not in delimiters. This basically means that you can write the code without white spaces. Who cares about readability !!! Then you use one-letter variables and single-digit line numbers (after all, remember, you can not use more than 10 :-). 

      This was standard stuff in 10-liners. When you have to actually code the gameplay, all of a sudden, you get the headaches. First thing is AppleSoft BASIC does not have ELSE statements. The typical strategy is to leave conditionals at the end of lines, and use ELSEs to better manage decisions (in term of program space and lines usage). Soooo ... you have to decompose decisions and break them apart into different lines. Tricky, isn't it? Let's see.

      The code

      Lines 0 to 3 initialize the program and do all graphics background drawing and shapes definition. The order in which instructions are performed are related to the available line space. I tried different combinations. One interesting and important thing is that only line 3 is needed to replay, so you can GOTO 3 when the game is finished to start a new one.

      Line 9 performs the text updating. It is coded in the form of a subroutine which is called at game initialization and whenever there is a hit or a fail.

      Lines 4 to 8 implement the gameplay. They manage arrow and target movement, user input and scoring. The hit or fail of the arrow is checked in lines 6 (hit) and 7 (fail). Line 8 just closes the game loop. Should ELSE statements are available, this single-statement line would not be needed. Line 7 plays a nice trick. When the game is over, the game loop continues but arrow throwing is disabled. Until you press the space key and the game is re-initialized.

      Lines 8 to 9 contain DATA definitions for the graphic shapes coded in decimal. These statements are put at the end of actual code, so we can make benefit of characters available in those lines. I tried to get rid of any character which is not ASCII standard. As I develop both on my Mac and on my Apple IIe, doing otherwise would produce me many headaches trying to preserve character coding.

      The state of the game is coded using the following variables:
      • Y (Float): vertical position of the target in pixels. Varies in the 34 .. 125 range
      • S (Float): amount in pixels which is added/substracted to Y at each time step. It controls the velocity of the target. Its initial value is 1.0. Each time a hit occurs it is increased by 0.25 
      • X (Integer): horizontal position of the arrow in pixels. Varies in the 200 .. 32 range
      • D (Integer): linear distance between the arrow y position and the target y position
      • G (Integer): total score achieved
      • F (Integer): number of fails
      • H (Integer): score of the last hit, derived from D
      • B (Integer): state variable representing whether the arrow is moving (B=1) or not (B=0)
      • Q (Integer): state variable representing whether the game is active (Q=0) or not (Q=1)
      I finally had a code of 1.7 Kb, in 10 lines of BASIC, with standard ASCII character coding. Nice. Goal achieved. You can find the code, a simulator disk file (DSK) and some multimedia materials here:


      Instructions

      You are a top-notch archer in the "Outdoor Archery World Series. Moving Target". You throw an arrow by pressing the space bar, and cannot throw a new one until it either makes a hit or a fail. The target moves so you have to carefully synchronize the arrow throwing with the target movement. The target speed gets increasing with each hit. You get points for each hit depending of how close the arrow gets to the target center. You are allowed a maximum of 3 failures, in which case the competition finishes and you get your final score. To start a new game press the space bar.



      Are you ready? Can you make more than one hundred points? Let's try it.

      Download the file archer10.dsk from GitHub and drag&drop it on the Drive 1 icon on the Virtual II emulator (a fantastic application by Gerard Putter, which is worth the price of the paid version). Once the disk is loaded, type the following command in the console and then press INTRO:

      RUN ARCHER10.BAS

      The game has sound, so remember to enable audio in your computer.

      Enjoy playing!!



      miércoles, 3 de marzo de 2021

      Archer 10. Participación en el 2021 10-liner Contest


      Hace algunas semanas tuve noticia de un concurso de programación retro, si, a través de uno de esos grupos de wasap, el 10th Edition of BASIC 10 Liner Contest. La idea principal es que tienes que desarrollar un juego en BASIC que no ocupe más de 10 líneas de código para cualquier ordenador original de 8 bits. Hay diferentes categorías dependiendo del número máximo de caracteres por línea permitidos. Sencillo, ¿verdad?. Decidí darle un tiento. Pensé "vamos, si son sólo 10 líneas de código, esto no puede ser muy complicado". No podía estar más equivocado. En este artículo explicaré qué y cómo he desarrollado mi participación en la edición de este año (2021), que he llamado Archer10.

      El juego

      Puesto que era la máquina con la que aprendí, decidí ir a por un programa MSX-1. Llamémosle nostalgia. Claro que, además, es la máquina que mejor conozco. Una vez decidido el equipo, la siguiente cuestión es pensar en un juego. Como no soy bueno en los juegos, decidí plagiarme yo mismo. Comencé con algunas ideas prestadas de Barcelona 92, un programa en BASIC que desarrollé cuando tenía 15 años y fue publicado en la revista MSX Club de Programas nº 3-4 (1985).

      Después de algunas reflexiones-no-muy-profundas acabé con una idea sencilla de mecánica de juego: un blanco a la izquierda se mueve hacia arriba y hacia abajo. Controlas un arquero en la derecha que lanza flechas que se mueven de derecha a izquierda. Si impactas el blanco consigues puntos dependiendo de cómo cerca del centro lo haga. Tienes permitido un número máximo de fallos, tras los cuales el programa finaliza. Cuanto mayor sea la puntuación, mejor. Bien, bastante sencillo, pero un juego al fin y al cabo. Y presenta varias posibilidades que puedo explotar. Algo que no me gusta de muchos juegos es que son difíciles desde el principio. Como soy muy malo en los juegos, esto no facilita el que los pruebe. Así que decidí que el juego fuera sencillo al principio (el blanco se mueve muy despacio). Pero según se progresa, la dificultad se va incrementando poco a poco (al principio no se aprecia) de forma que tras algunos aciertos se torna realmente difícil. Y la restricción en el número de fallos hace que quieras repetir de nuevo e intentar superarte.

      Estupendo. Ya tengo una idea de juego. Ahora a por la parte visual. Quería mostrar algunas de la estupendas características de los ordenadores MSX-1, por lo que decidí incluir gráficos en alta resolución (lo que se conoce como SCREEN 2 en el mundillo MSX), sprites por hardware, y sonido. Con profusión de colores, por supuesto (descargo de responsabilidad: no soy daltónico, pero definitivamente no soy bueno coloreando). Y, cómo no, también sonidos (descargo de responsabilidad: soy tan bueno con la música como con los colores).

      La programación

      Comencé programando una maqueta del programa sin restricciones, con un montón de líneas, para tenerlo funcionando. Quería asegurarme de que se pudiera jugar como yo quería. Después trabajé los gráficos para evitar la colisión de atributos de color (típico del procesador de vídeo de los MSX) y a la vez mostrar la mayor parte de la paleta de colores disponible. Básicamente tenía unas cien líneas de código y unas 3 Kb de espacio de programa. Definitivamente demasiado para un 10-liner.

      Debido a los gráficos tenía claro que requeriría bastante espacio de programa. Además, mostrar texto en una pantalla gráfica requiere de muchas instrucciones que ocupan bastante espacio de programa. Y definitivamente quería texto. Sin compromisos.

      De esta forma decidí participar en la categoría EXTREME-256. Además de sólo diez líneas de código, cada línea no debe de contener mas de 256 caracteres. De forma global ¡¡ el programa no puede ocupar más de 2.5 Kb !!. Para encajar el código en este tamaño hay que utilizar todos los viejos trucos. El intérprete BASIC utiliza un analizador léxico que está basado en la detección de palabras clave y no en los delimitadores. Esto significa que puedes escribir todo el código sin espacios. ¡¡¡ A quien le importa la legibilidad !!! Además, hay que usar variables con una sola letra y números de línea de un sólo dígito (después de todo, recordad, no puedes usar mas de diez :-).

      Con esto consigues un código BASIC muy compacto, con la menor cantidad de espacio de almacenamiento posible. Esta es la parte fácil. Pero aún hay más, ya que hay que implementar la mecánica del juego que involucra acciones y decisiones. Cuando se programa tendemos a pensar en secuencias lógicas (o al menos eso deberíamos hacer) que acaban plasmándose en el uso de sentencias GOTO, y con el objetivo de mejorar la claridad, también GOSUB. El problema aquí es que debido al reducido número de líneas el uso de GOTOs y GOSUBs es muy limitado. Así que, en lugar de pensar en secuencias lógicas, donde tienes decisiones y acciones claramente aisladas, tienes que intercalar estas en el poco espacio disponible, incluyendo la mayor cantidad posible en una línea de código. Es un ejercicio de programación muy interesante que habitualmente no se practica.

      El juego

      Si digo que al final acabé con diez líneas de código, esto no debería ser una sorpresa. No hay spoiler. Las líneas 0 a 3 inicializan el programa y hacen todo el pintado del fondo gráfico y la definición de los sprites hardware. El orden en el que se realizan las instrucciones esta relacionado con el espacio disponible en las distintas líneas de código, paro lo que probé distintas combinaciones. Una cuestión interesante es que sólo se necesita la línea 3 para reiniciar el juego, de forma que se puede hacer un GOTO 3 cuando se acaba la partida.

      Las líneas 4 a 7 implementan la mecánica del juego. Gestionan el movimiento del blanco y de la flecha, la interacción con el usuario y el puntaje. Tuve bastante suerte y pude implementar una subrutina en la línea 7, que se llama mediante un GOSUB 7 cada vez que la flecha llega a la parte izquierda de la pantalla (ya sea un acierto o un fallo). La línea 6 utiliza un truco muy interesante. Comprueba tanto el final de la partida como la reinicalización del juego (después de pulsar la barra espaciadora). Lo último mediante una llamada a GOTO 6. Esto produce una corrupción del estado del juego, pero como ya ha finalizado, ¡a quien le importa!. Cuando posteriormente se hace un GOTO 3 el estado del juego se inicia correctamente.

      Las líneas 8 a 9 contienen las definiciones DATA para los sprites hardware codificados en hexadecimal. Debo señalar que esta NO es la forma más eficiente de almacenar esta información. Se pueden utilizar cadenas de caracteres, pero he sacrificado un poco de almacenamiento de programa (que al final no necesité) por la codificación de caracteres. Puesto que habitualmente desarrollo tanto en mi Mac como en mi Sony HB-F700S la copia entre estos preservando la codificación de caracteres es muchísimo mas simple así.

      El estado del juego se codifica por medio de las siguientes variables:
      • Y (Float): posición vertical del blanco en pixeles. Varía en el rango 30 .. 135
      • S (Float): cantidad de pixeles que se le añaden/sustraen en pixeles a la Y en cada instante de tiempo. El valor uncial es 1,0. Cada vez que s produce un acierto se incrementa en 0,25.
      • X (Integer): posición horizontal de la flecha en pixeles. Varía en el rango 200 .. 22
      • G (Integer): puntuación total conseguida
      • F (Integer): número de fallos
      • H (Integer): puntuación del último acierto. Calculada como la distancia lineal entre la posición y de la flecha y la posición y del blanco. 
      • B (Integer): variable de estado que representa si la flecha está en movimiento (B=1) o no (B=0)
      Finalmente conseguí un código de 2.1 Kb, en 10 líneas de código BASIC, y codificación de caracteres en ASCII estándar. ¡¡ Estupendo!!. Objetivo conseguido. Puedes descargar el código, un archivo de disco para simulador (DSK) y diverso material multimedia desde:


      Instrucciones

      Eres un arquero de alto nivel en la "Liga Mundial de Tiro con Arco al Aire Libre. Blanco Móvil". Lanzas flechas pulsando la barra espaciadora, y no puedes volver a lanzar hasta que aciertas el blanco o fallas. El blanco se mueve por lo que tines que sincronizar con cuidado el lanzamiento de la flecha con el movimiento del blanco. La velocidad del blanco se va incrementando con cada acierto. Consigues puntos según lo cerca que queda la flecha con respecto al centro del blanco. Tienes permitido un máximo de 3 fallos, en cuyo caso la competición finaliza y obtines tu puntuación final. Para iniciar un nuevo juego pulsa la barra espaciadora durante más de un segundo.

      Estás listo? Puedes conseguir más de cien puntos? Vamos a ello.

      Descarga el archivo archer10.dsk de GitHub y arrástralo a la consola azul de WebMSX (una aplicación estupenda de Paulo Augusto Peccin). Aparece una ventana emergente y entonces selecciona Drive A. A partir de ahí el simulador carga la imagen de disco y se queda a la espera de recibir comandos. Teclea el siguiente comando y después pulsa INTRO:

      RUN "ARCHER10.BAS"

      ¿Demasiado complejo?

      He preparado una página web que automáticamente carga y ejecuta el programa en WebMSX. Sigue este enlace para jugar en línea.

      El juego tiene sonido, así que recuerda habilitar el audio en el ordenador.

      ¡¡¡ Disfruta jugándolo !!!




      sábado, 27 de febrero de 2021

      Archer10. Submission to the 2021 10-Liner Contest



      Some weeks ago I had notice of a retro programming contest, yes through one of these wasap groups, the 10th Edition of BASIC 10 Liner Contest. The main idea is that you develop a game in BASIC with no more than 10 lines of code for 8 bit legacy computers. There are different categories depending on the maximum number of characters per line allowed. Simple, isn't it? I decided to go for a try. I though "come on, it is only 10 lines of code, it can not be of much pain". I could not have been more wrong. In this post I will explain what and how I developed my submission for this year edition (2021), which I have named Archer10.

      The gameplay

      Being the machine I learned with I decided to go for a MSX-1 program. Let's call it nostalgia. Well, and it is the machine that I actually know more of. Once the machine is settled, next thing is thinking on a gameplay. I am not good at all with games, so I decided to perform some plagiarism of myself. I started with some ideas borrowed from Barcelona 92, a BASIC program I developed when I was 15 years old and was published in the magazine MSX Club de Programas nº 3-4 (1985).

      After some not-too-deep-thinking I came up with a very simple gameplay: a target on the left moves up and down. You control an archer on the right who throws arrows from right to left. If you hit the target you get points depending on how close to the center the arrow impacts. You are allowed a maximum number of fails. Then the program finishes. The larger the final score, the better. Well, quite simple, but definitively a game. And it has some nice features I can exploit. Something I dislike of many games is that they are very hard from the beginning. Being very bad at gaming, this disallows me from trying them. So I decided the game at the beginning was to be very easy (the target moves very slowly). But then, the difficulty gets increasing little by little (you hardly notice the difference at first) so that after some throws it gets really difficult. And the constraint in the number of fails makes you to try again to increase your score.

      Good. I had a gameplay. Now the visual part. I wanted to expose some of the very-nice-features of the MSX-1 machines, so I decided to include high resolution graphics (known as SCREEN 2 in MSX jargon), hardware sprites, and sound. With plenty of colors, of course (disclaimer: I am not color impaired, but definitively I am not good at coloring). And weird sounds as well (disclaimer: I am as good at music as I am at coloring).

      The programming

      I started coding a mock up of the program without constraints, with many lines, to get it up and running. I wanted to make sure the gameplay was as I intended. Then I worked the graphics so to avoid the color attribute clash (typical of the MSX-1 video processor), but at the same time displaying most of the available color palette. I roughly had over a hundred lines of code with some 3 Kb of program space. Definitively too much for a 10-liner.

      Because of the graphics I was sure I needed quite a lot program space. In addition having text in a graphics screen is quite a lot program space consuming. And I definitively wanted some text. No compromises allowed. 

      Thus I decided to enter the EXTREME-256 category. In addition to only ten lines of code, each line must not contain more than 256 characters. Overall, the code can not be larger than 2.5 Kb !!! To squeeze the code in this size you play the very old tricks. The BASIC interpreter uses a lexical analyzer that is based on keyword detection and not in delimiters. This basically means that you can write the code without white spaces. Who cares about readability !!! Then you use one-letter variables and single-digit line numbers (after all, remember, you can not use more than 10 :-). 

      Now you get a very compact BASIC code with the minimum of program storage needed. This is the simple stuff. But there is more than this, you have to actually code the gameplay, which involves actions and decisions. When programming we tend to think on logical sequences (at least, we should do that) which end up coded using control structures with GOTOs and, for the sake of clarity, with GOSUBs. The problem here is that with the reduced number of lines available GOTOs and GOSUBs are of very limited use. So instead thinking on logical sequences, where you have actions and decisions clearly isolated, you have to interleave all of them, fitting as much as posible in a single line of code. It is a very interesting programming exercise that you do not typically practice.

      The code

      If I say I finished up with 10 lines of code, this should not be of great surprise. No spoiler here. Lines 0 to 3 initialize the program and do all the text and graphics background drawing and hardware sprites definition. The order in which instructions are performed are related to the available line space. I tried different combinations. One interesting thing is that only line 3 is needed to replay, so you can GOTO 3 when the game is finished to start a new one.

      Lines 4 to 7 implement the gameplay. They manage arrow and target movement, user input and scoring. I was lucky enough to implement a single subroutine in line 7, with is called as GOSUB 7 each time the arrow reaches the left part of the screen (being it a hit or a fail). Line 6 plays a very nice trick. If checks for both the end of the game and the reinitialization of it (after pressing the space bar). The later issuing a GOTO 6. This corrupts the state of the game, but as it has finished, who cares!!!. When you do GOTO 3 the game state is correctly initialized.

      Lines 8 to 9 contain DATA definitions for the hardware sprites coded in hexadecimal. I must say this is NOT the most efficient way of storing this information. You can use string literals, but I sacrificed some program storage (with I finally did not need) for character coding. These literals might (and do) contain characters which are not ASCII standard. As I develop both on my Mac and on my Sony HB-F700S it produced me many headaches while copying to and from and trying to preserve character coding.

      The state of the game is coded using the following variables:
      • Y (Float): vertical position of the target in pixels. Varies in the 30 .. 135 range
      • S (Float): amount in pixels which is added/substracted to Y at each time step. It controls the velocity of the target. Its initial value is 1.0. Each time a hit occurs it is increased by 0.25 
      • X (Integer): horizontal position of the arrow in pixels. Varies in the 200 .. 22 range
      • G (Integer): total score achieved
      • F (Integer): number of fails
      • H (Integer): score of the last hit. Computed as a linear distance between the arrow y position and the target y position
      • B (Integer): state variable representing whether the arrow is moving (B=1) or not (B=0)
      I finally had a code of 2.1 Kb, in 10 lines of BASIC, with standard ASCII character coding. Nice. Goal achieved. You can find the code, a simulator disk file (DSK) and some multimedia materials here:


      Instructions

      You are a top-notch archer in the "Outdoor Archery World Series. Moving Target". You throw an arrow by pressing the space bar, and cannot throw a new one until it either makes a hit or a fail. The target moves so you have to carefully synchronize the arrow throwing with the target movement. The target speed gets increasing with each hit. You get points for each hit depending of how close the arrow gets to the target center. You are allowed a maximum of 3 failures, in which case the competition finishes and you get your final score. To start a new game hold the space bar for more than one second.

      Are you ready? Can you make more than one hundred points? Let's try it.

      Download the file archer10.dsk from GitHub and drag&drop it on the blue console of WebMSX (a nice application by Paulo Augusto Peccin). A pop up window appears and select Drive A. Then the simulator loads the disk and it is ready to accept commands. Type the following command in the console and then press INTRO:

      RUN "ARCHER10.BAS"

      Too complex? 

      I have prepared a web page which automatically loads and executes the program in WebMSX. Follow this link to play online

      The game has sound, so remember to enable audio in your computer.

      Enjoy playing!!




      domingo, 20 de diciembre de 2020

      Reparación del cabezal del plotter SONY PRN C-41

      De siempre me ha gustado este fantástico plotter, el SONY PRN C-41, y me hacía ilusión conseguir uno. En su día no pude tener uno (se me iba de presupuesto), aunque si que pude hacer alguna cosa a través de conocidos. Uno de mis primeros trabajos era dar clases de CAD, y me encantaban los plotters.

      Lo he adquirido recientemente junto con un juego de plumillas originales, con la tinta en perfecto estado, lo cual tiene mérito después de tantos años. Al ponerlo en marcha verifico que todo funcione, y eso parece. Sin embargo al cargarlo con las plumillas estas no llegan al papel, por lo que no pintan. Descargo manuales, observo la cabeza y ... el martillo que baja la plumilla está roto. Es una pieza muy pequeña y el plástico después de tanto años se ha rigidizado en exceso.

      Estudio el asunto y decido fabricar uno parecido mediante impresión 3D. Lo primero tomar medidas, darle vueltas en el CAD, imprimir, probar, verificar y vuelta a empezar. A continuación se pueden ver algunos de los intentos.

      Después de numerosas pruebas llego a un diseño que es poco práctico, pero es lo mejor que he podido hacer. 

      El problema de este diseño es el ajuste con el resto del cabezal: no tengo posibilidad sencilla de hacer un pasador de 0.05 mm de diámetro, ni forma fácil de conseguirlo. Lo soluciono mediante una pequeña chapucilla: pego el martillo al cabezal mediante una notita de cianocrilato, con cuidado de que no rebose y pueda pegar algún elemento del cabezal. El resultado del montaje se muestra a continuación.

      ¿Y cómo ha funcionado? Pues razonablemente bien. Para probarlo he hecho un sencillo programa en BASIC para probarlo. A continuación se muestra un vídeo del plotter haciendo una prueba de impresión.

      Por último, una imagen del resultado en el papel.


      El modelo 3D del martillo de la plumilla está disponible de forma gratuita en:

      Thingiverse: https://www.thingiverse.com/thing:4691872

      domingo, 22 de noviembre de 2020

      Recopilación de juegos BASIC en cartucho.

      Tras terminar de rescatar todos los listados de programas en BASIC para ordenadores MSX que conservo de los años 80, que son sólo una parte de los que hice, me he planteado hacer una recopilación en cartucho. Esto, que en su día era impensable de forma artesanal, en la actualidad es bastante sencillo y barato debido a las herramientas software y hardware disponibles. Vamos a hacer un repaso de cuales son y cómo funcionan. Lo primero es seleccionar los programas que tenemos disponibles, que están descritos en diversas entradas de este blog:

      La idea fundamental es crear un disco con los programas y a partir de él generar una ROM que se almacenará en un cartucho con una FlashRAM. Y ya está. Sencillo, no? Como dijo Jack el Destripador, vamos por partes.

      Creación del disco

      Necesitamos crear un disco MSX-DOS en el que cargaremos los archivos necesarios para arrancar el sistema operativo, para ejecutar nuestros programas, y, obviamente, los programas que queremos almacenar. 

      Comenzamos formateando un disco físico de 3.5" en el propio ordenador MSX, en este caso 2DD (doble cara y doble densidad). Grabamos los archivos de sistema necesarios para que el disco sea autoejecutable:

      • COMMAND.COM
      • MSXDOS.SYS
      • AUTOEXEC.BAT

      En este último escribimos el nombre del programa que queremos que se ejecute. En el caso, como el que nos ocupa, de que este programa esté escrito en BASIC el contenido de este archivo será:

      BASIC nombre.BAS

      Por último grabamos todos los programas y archivos que hemos desarrollado y queremos incluir en nuestra recopilación. Comprobamos que el disco arranca correctamente y que todo funciona bien. En mi caso, he preparado una etiqueta para darle un aire semi-profesional. Este es el aspecto:


      Una vez que este paso está superado, copiamos todos los archivos a nuestro ordenador y creamos una imagen de disco. Para ello podemos utilizar una imagen que previamente tengamos (podemos borrar todos los archivos), podemos utilizar un emulador de MSX, o podemos utilizar la herramienta DiskMgr, de Rudolf Lechleitner. Con cualquiera de estos métodos creamos un archivo que llamaremos recopila.dsk.

      Una vez creada la imagen de disco, vamos a utilizar la herramienta dsktool, de Ricardo Bittencourt, que es capaz de trabajar con archivos de imagen de disco en formato FAT12. Aunque se podrá hacer también con DiskMgr, yo prefiero esta porque es de línea de comandos y puedo automatizar algunos procesos mediante shell-scripts. Para añadir el primer de los archivos haremos:

      dsktool a recopila.dsk COMMAND.COM

      Y después repetimos con el resto de los archivos de nuestro disco físico. Llegados a este punto ya tendremos la primera etapa terminada. Para verificar que todo está correcto vemos el contenido de la imagen:

      dsktool l recopila.dsk

      que nos muestra la siguiente salida por pantalla:

      DskTool v1.30 (C) 1998 by Ricardo Bittencourt

      Utility to manage MSX DOS 1.0 diskette images (3.5"360/720Kb).

      (2010) Updated by Tony Cruise

      (2017) Updated by NataliaPC

      This file is under GNU GPL, read COPYING for details


      Disk image size:  720Kb

      Standard format


      Name of volume:   SNYJX101


      COMMAND.COM      6656 14/10/2020  7:23:04 ----

      MSXDOS.SYS       2432 14/10/2020  7:23:04 ----

      AUTOEXEC.BAT       21 15/11/2020 12:51:36 ----

      EXAMEN.BAS       3775 22/11/2020 11:19:44 ----

      LECCION.BAS     22432 22/11/2020 11:23:02 ----

      PRESENT.BAS      2044 22/11/2020 11:19:14 ----

      BCN92.BAS       11182 21/11/2020 21:57:24 ----

      CRAZYP.BAS      14736 22/11/2020 11:26:00 ----

      SKRAM.BAS        9175 22/11/2020 11:52:18 ----

      RECOPILA.BAS     1087 22/11/2020 11:24:00 ----


      652288 bytes free


      Ya solo nos queda probar la imagen en un emulador. Yo utilizo OpenMSX que es el que más me gusta. Con esto nos aseguramos que hemos creado la imagen correctamente, y que en el emulador tenemos lo mismo que en el ordenador real. Y con esto terminamos esta etapa.

      Creación de un cartucho

      Comenzaremos con crear un archivo de imagen ROM a partir de nuestra imagen de disco. Para ello utilizaremos el programa dsk2rom, de Vincent van Dam. El funcionamiento es muy ingenioso. Este programa crea una ROM con un driver virtual para acceder al sistema de ficheros de la imagen un disco almacenado en memoria. Como el tamaño de la imagen de disco es mayor que la memoria máxima direccionable por el Z-80, el propio programa incluye diferentes mappers para esta operación. Además, permite utilizar el compresor Pletter para reducir el tamaño de la imagen.

      El funcionamento es muy sencillo. Simplemente lo invocamos con los parámetros adecuados. En este caso utilizaremos el mapper ASCII de 8 bits y el nivel de compresión 2 para Pletter. Estas opciones nos valdrán para la mayoría de casos. Lo invocamos de la forma:

      dsk2rom -asfc 2 recopila.dsk RECOPILA.ROM

      Lo siguiente es probar la imagen de la ROM en un emulador. La cargamos en el OpenMSX y tras el proceso de arranque de la máquina se muestra la pantalla de inicio del programa. Probamos todas las opciones y comprobamos que la ROM es correcta.


      Ya solo nos queda la operación más delicada de todo el proceso, la grabación del cartucho. Esta operación hay que hacerla en el propio ordenador MSX. Debemos de tener algún dispositivo de almacenamiento que nos permita tener tanto el programa de carga como nuestra imagen ROM. Debido al tamaño necesitaremos utilizar por lo menos un disco de 3.5".

      Existen diferente modelos y tipos en el mercado, con más o menos memoria, mappers, etc. En general son dispositivos con una FlashRAM donde se almacena la imagen de la ROM, y una electrónica para comunicarse a través del puerto de expiación del MSX. En este caso he optado por un cartucho multimapper de 2Mb distribuido por Carmeloco. Junto con el cartucho nos proporciona el programa cargador de la flash.


      Como se puede observar la placa tiene una serie de jumpers. Estos son fundamentales para las distintas operaciones. Comenzaremos cargando la flash. Para ello hay que abrir el puente PRG y cerrar el puente A16. Introducimos el cartucho con el ordenador apagado y lo encendemos. Cuando cargue el dispositivo de almacenamiento donde tenemos la imagen, utilizamos el comando:

      FL16 RECOPILA.ROM

      El proceso dura unos minutos. La salida del mismo es la siguiente:

      Tras los cuales apagamos el ordenador, cerramos el puente PRG, quitamos el puente A16 y cerramos el puente A8. Metemos la placa dentro de la carcasa del cartucho, y lo volvemos a insertar en el ordenador, este apagado.  En mi caso le he añadido una etiqueta y me ha quedado semi-profesional.

      Ya solo resta encender y ... voilà, a disfrutar de un cartucho personalizado.



      El código fuente y las imágenes de disco y ROM están disponibles en GitHub:

      https://github.com/humbertomb/mymsx/tree/master/recopila

      domingo, 15 de noviembre de 2020

      Anatomía del Aparato Digestivo. Programa didáctico

      Este programa escrito en BASIC para ordenadores MSX1 (1985), con una extensión considerable,  Anatomía del Aparato Digestivo, es un programa didáctico con lecciones y test. Lo escribí conjuntamente con dos compañeros de instituto Antonio Alcántara Lapaz y Julian Alcántara Lapaz y fue nuestra participación en el I Concurso de Programas MSX (1985), organizado por Sony España, y cuyo premio se falló en 1986.

      Aunque era una buena idea, no teníamos las herramientas (ni probablemente conocimientos) para  hacerlo suficientemente sólido. El problema fundamental que nos encontramos era su extensión. Para poder encajar los diferentes diagramas del aparato digestivo y sus textos explicativos tuvimos que utilizar las 28k disponibles en MSX BASIC. Para ello hubo que simplificar excesivamente la mecánica y, además, no incluir una instrucciones de uso en el programa (que no eran muy evidentes). Dicho lo cual, creo que fue un programa faraónico, con la dificultad de hacerlo por trozos y entre varias personas, y haciendo los gráficos en papel y su posterior digitalización a mano. En mi caso, además, mi ordenador Sony HB-55P sólo tenia 16k de memoria, y me dejaba unas 12k en MSX BASIC, por lo que sólo podía trabajar con fragmentos pequeños. Para poder realizar la integración del programa acomplejo me tuvieron que dejar una ampliación de memoria de 64K.

      Como el resto de los programas de la época, no lo conservo en forma digital. Sólo disponía de un listado apergaminado. Al contrario del resto de entradas de este blog, y teniendo en cuanta la extensión del listado, he utilizado una estrategia más profesional. Siguiendo el modelo descrito en Recuperación de código MBASIC he digitalizado y pasado por OCR el listado completo. Una vez en el editor de texto innumerables iteraciones de corrección de código y ejecución, sobre todo dejándome los ojos en los comandos DRAW de los listados. Como no me apetecía recorrer el camino de almacenar el programa en cinta, lo he fragmentado para poder ser ejecutado desde diskette, ya que el MSX DISK BASIC solo deja 24k de memoria libre. Aprovechando esto, he añadido una fundamental pantalla de instrucciones, que es la única diferencia con respecto al programa original. Y ya de paso le he preparado una etiqueta, que le da un aire casi profesional.




      Pasemos a hablar del programa. Es un programa didáctico básico, muy sencillo y sobrio de aspecto, pero con una cantidad de información bastante elevada (por ello su tamaño en BASIC). Técnicamente no es muy complejo (no hay ensamblador ni manejo directo del VDP), su gran dificultad el modo en que se desarrolló y su tamaño. El programa está organizado en lecciones sobre la anatomía y funcionamiento del aparato digestivo:
      • Cuerpo entero
      • Boca
      • Dientes
      • Esófago-Estómago
      • Hígado-Páncreas
      • Pared Intestinal
      • Intestino
      Al usuario se le presenta la opción de seguir en continuo todas las lecciones de forma secuencia o de forma individual. En cada lección se presenta un diagrama de la parte estudiada, con referencias a las distintas partes de la anatomía, y una o varias pantallas con textos explicativos de las funcionalidades de los elementos. Una vez revisados todos los contenidos, el usuario puede realizar una evaluación tipo test para comprobar su conocimiento de los contenidos. Las preguntas de este test no son nada triviales, y no es fácil superarlo si antes no se han leído bastante bien las explicaciones de las lecciones.






      El código está disponible en GitHub:

      lunes, 19 de octubre de 2020

      Recuperación de código MBASIC para Apple II desde listados

      Suele ocurrir que hayamos perdido el material en soporte magnético (ya sean cintas o disquetes) de programas desarrollados en los años 80. Si entonces fuimos algo cuidadosos (cosa habitual, porque era fácil  tener problemas con los soportes y los lectores de la época) es posible que conservemos el código en formato papel, más parecido al pergamino que otra cosa. Llegados a este caso, y si queremos recuperar esas joyas de la historia (o que simplemente les tengamos cierto cariño), no tenemos más remedio que optar por una de dos opciones: a) ponernos como locos a copiar código (tarea nada agradecida, sobre todo con presbicia, que sin duda tendremos si el código de los 80 es nuestro), b) echar mano de la tecnología para automatizar en lo posible el proceso. 

      Cuando empece a recuperar el material de los 80 para MSX seguí el camino "a", no por falta de usar tecnología, sino porque en su día no di con la combinación adecuada y de forma fiable. Ahora sí lo he conseguido con la "b", de forma bastante fiable, robusta y práctica. Lo que no quita para que el proceso no sea ni mucho menos automático, pero sí mucho más productivo que la otra opción. 

      Para ilustrar el proceso vamos a partir del programa de matriculación de alumnos del I.B. Jiménez de la Espada que desarrollé sobre 1985-1986 en lenguaje MBASIC para el ordenador Apple IIe con sistema operativo CP/M. Fue el primer programa de matriculación que se utilizó en el instituto, y yo debería de tener unos 16 años. De entonces conservo un tocho de papeles que son los listados de los programas, que intuyo que son versiones finales, y lo sabré cuando finalice al 100% el proceso de recuperación. El aspecto de los mismos es el siguiente:


      Pues bien, en esta entrega voy a describir el proceso que he seguido para recuperar dichos códigos. Aunque en este ejemplo utilizo código BASIC de un Apple II, el proceso es aplicable a otros sistemas de la época, y lo estoy utilizando también tanto para BASIC y ensamblador Z80 de MSX.

      Como se puede observar en la imagen anterior, se trata de una impresión matricial, donde el papel está amarronado (en este caso habiendo estado muy bien conservado, sin que le diera la luz), y con la tinta bastante descolorida. Lo primero antes de nada es tratarlo digitalmente para conseguir un mayor contraste. Para este trabajo he utilizado la herramienta Graphic Converter, que es una especie de Photoshop en pequeño, y cuya herramienta "Niveles Automáticos" produce el siguiente resultado:


      El siguiente paso es utilizar un programa OCR para extraer el texto de la imagen. En la actualidad hay OCRs a patadas, muchos de ellos gratuitos y con una calidad de reconocimiento bastante aceptable. El problema que presentan la mayoría es que no están preparados para reconocer este tipo de caracteres, y producen resultados tan malos que no sirven para nada. Y en esas estaba atascado hasta que por casualidad  leí que Google tenía un OCR gratuito integrado en su herramienta. Me pongo a ello. Subo la imagen a una carpeta de mi Drive de Google. La selecciono y la abro con la herramienta Google Docs. Esta detecta automáticamente que es una imagen y extrae de la misma todo el texto en bruto, sin saltos de línea y dejando un único espacio en blanco, produciendo el siguiente resultado:


      Ooooooh !!! Pues no es un código directamente ejecutable, pero el texto tiene bastante información para ahorrarnos un trabajado tremendo. Como se puede observar, se han cambiado algunos símbolos, han desaparecido otros, y de vez en cuando alguna letra o número se han alterado. La confusión del cero "0" y la letra "O" es un clásico. También el uno "1" y la letra "I". Llegados a este punto, usar una herramienta simple y adecuada para la edición de código es muy interesante. En este caso utilizo el editor de programación Geany, que incluye coloreado de sintaxis para una gran cantidad de lenguajes de programación. En concreto incluye BASIC, lo que nos va a hacer la tarea más sencilla indicándonos visualmente muchos errores de transcripción. Las palabras clave de BASIC las colorea, por lo que si alguna no sale en color, es que hay un error. Así se cazan las alteraciones de GOTO, por ejemplo, donde una de las letras es un número. Es un BASIC genérico, y no lleva colorización de comandos específicos de MBASIC o AppleSoft BASIC, como VTAB y HTAB, que serán un porcentaje muy pequeño del total de comandos que se usarán. 

      Copiamos el texto de Google Docs a Geany, e introducimos un salto de línea antes de cada número de línea de código. Algo que se hace muy rápida y sencillamente a mano. El resultado es el siguiente:


      Ya solo nos queda trabajarlo un poquito, verificando con el listado en papel. El trabajo requiere un poco de dedicación, pero la productividad es muy grande. Una vez verificado, el resultado es el siguiente:


      Con todo y con eso, todavía tendremos algunos errores, pocos, que se nos habrán escapado, y, además, tenemos que pasarlo a un formato que nos permita cargarlo en un ordenador de esa época. Para esto tenemos alguna alternativa muy tediosa, que incluye tener que hacer toda la depuración en al Apple II, cuyo editor de BASIC es más bien pedestre, o bien utilizar un emulador de la máquina en sí. En este caso decidí usar el emulador Virtual II que es una maravilla. Aunque se puede utilizar de forma gratuita con ciertas limitaciones, la versión completa de pago es fundamental para este trabajo. Sólo con la facilidad y esfuerzo que nos ahorramos se paga sólo. Entre otras opciones permite emular la tarjeta Microsoft SoftCard CP/M, que es necesaria para ejecutar el código MBASIC. El proceso de trabajo es muy sencillo. Cargamos una imagen de disco 5 1/4" con el Sistema Operativo CP/M y el intérprete de MBASIC. Hay un montón de webs para descargar las imágenes. Entre ellas la Apple II CP/M Library y la Apple II Asimov. Aparte de la imagen que necesitamos hay literalmente cientos de imágenes. Ejecutamos el emulador y cargamos la imagen de CP/M. Al arrancar entramos en el intérprete de MBASIC, como se muestra en las siguientes capturas de pantalla del Virtual II:


      Tan solo nos queda hacer copia y pega del código desde Geany hasta Virtual II. El pegado se hace simulando la entrada desde teclado, por lo que es equivalente a teclear el mismo código en la interfaz del MBASIC. Este lo entiendo, a todos los efectos, como si lo estuviéramos tecleando. Esto es mu conveniente por dos razones. Por un lado podemos pasar todo el texto de Geany al intérprete de MBASIC de una tacada. Ya solo esto es fundamental, tal y como podemos ver en la siguiente captura:


      Pero una vez que lo tenemos copiado, donde verdaderamente podemos alcanzar unas cotas bastante altas de productividad es cuando ejecutamos y depuramos. En lugar de editar en el emulador, editamos en Geany cada vez que detectemos un error, y hacemos copia y pega solamente de las líneas que acabamos de modificar. Verdaderamente cómodo. Después de sucesivas iteraciones con el OCR, con el editor y con el emulador conseguimos recuperar el código sin problemas. ¿Que cómo queda el resultado? Pues un programa de gestión no es muy agradecido, pero bueno, aquí van un par de capturas de pantalla: