Mi propio procesador de textos en ZX Sinclair BASIC
Baltasar García Perez-Schofield

Baltasar García Perez-Schofield @baltasarq

About: Lecturer in programming since 1998

Location:
Spain
Joined:
Apr 14, 2019

Mi propio procesador de textos en ZX Sinclair BASIC

Publish Date: Sep 17 '25
5 13

Cuando era un tierno preadolescente, me dedicaba a jugar con mi Investrónica/Sinclair Spectrum 128k, perpetrando mis propios juegos y mis propias aventuras conversacionales o juegos de texto, algo que como puedes ver en el anterior enlace, no he dejado en la actualidad.

El caso es que, ya como adolescente, me hubiera venido muy bien un ordenador como el Amstrad CPC 6128, con su diskettera de 3", su software de procesamiento de textos, Tassword y su CP/M. Pero por aquel entonces... ¡jamás lo hubiera admitido!

Tasword para el Speccy

También lo había para Speccy, pero desde luego era mucho mejor si tenías unidad de disco. Aparecería con el tiempo para el Sinclair +3, claro.

Disco de Tasword para Amstrad 6128

Les pedí a mis padres una impresora, recibiendo por reyes una impresora Investrónica de matriz de puntos. Esta impresora estaba pensada para un PC, con su modo estándar de 80 columnas. Se conectaba al Spectrum mediante un puerto serie RS232, solo el 128 tenía este puerto (aunque el enchufe físico no era el estándar) a un conversor a paralelo (pensado para el Sinclair QL), y entonces, una vez que tenías el texto a imprimir en una cadena de caracteres, por ejemplo, mediante el editor de textos integrado en ROM:

edit t$
Enter fullscreen mode Exit fullscreen mode

Solo tenías que hacer un lprint.

lprint t$
Enter fullscreen mode Exit fullscreen mode

¡Y el texto mágicamente pasaba al papel! Solo había un pequeño, pequeñísimo problema: el Spectrum solo tenía 32 columnas, de forma que el texto impreso quedaba... digamos que con un gran margen por la derecha.

         1         2         3         4         5         6         7         8
---------0---------0---------0---------0---------0---------0---------0---------0
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor
incididunt ut labore et dolore
magna aliqua. Ut enim ad minim
veniam, quis nostrud
exercitation ullamco laboris
nisi ut aliquip ex ea commodo
consequat. Duis aute irure
dolor in reprehenderit in
voluptate velit esse cillum
dolore eu fugiat nulla
pariatur. Excepteur sint
occaecat cupidatat non
proident, sunt in culpa qui
officia deserunt mollit anim id
est laborum.
Enter fullscreen mode Exit fullscreen mode

Quizás te estés preguntando cómo era posible tener un texto de una gran longitud en una sola cadena de caracteres. Este manejo de string era una de las potencias de Sinclair BASIC.

Hice un pequeñísimo programa que permitía introducir un texto a base de párrafos let t$ = t$ + p$, y tenía una opción para imprimir, que solo hacía lprint t$.

1. Nuevo párrafo
2. Ver texto
3. Imprimir texto
4. Borrar texto

Opción:
Enter fullscreen mode Exit fullscreen mode

¿Has visto la opción 4? No, no preguntaba si estabas seguro de querer borrar todo el texto. En la siguiente versión, sí, te preguntaba si estabas realmente seguro de querer borrar el texto. No me preguntes por qué incluí esa pregunta de seguridad.

Mi primera aproximación al problema era no hacer absolutamente nada: ya sería mala suerte que una palabra quedase cortada por el borde derecho, ¿no?

         1         2         3         4         5         6         7         8
---------0---------0---------0---------0---------0---------0---------0---------0
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
cididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru
 exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aut
 irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat n
lla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
Enter fullscreen mode Exit fullscreen mode

Esta estrategia no funciona (sorprendente, ¿eh?). En el ejemplo, vemos como solo algunas líneas aparecen correctamente; la mayoría están cortadas por la mitad de la última palabra. Además, cuando el corte toca en un fin de palabra, el primer carácter de la siguiente línea es un espacio.

Así que, para mi procesador de textos, la simple impresión mediante lprint t$ no funcionaba. Era necesario un algoritmo que evitara esas palabras cortadas. Una forma de hacerlo sería introducir saltos de línea, es decir \n antes de la palabra que puede quedarse cortada. En Sinclair BASIC, estamos hablando de chr$(13).

Un código completo en Python, cuyas primeras líneas permiten jugar con el texto, el número de columnas, y si se quiere o no enrollado de palabra, es el siguiente:

t = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

COL = 32
WORD_WRAP = False

i = COL
l = list(t)
while i < len(t):
    if WORD_WRAP:
        while i > 0 and l[i] != ' ':
            i = i - 1
        ...
        if i == 0:
            break
        ...
    ...

    l[i] = '\n'        
    i += COL
...

print("         1         2         3         4         5         6         7         8")
print("---------0---------0---------0---------0---------0---------0---------0---------0")
print(str.join("", l))
Enter fullscreen mode Exit fullscreen mode

Es necesario convertir el texto a una lista para poder modificar aquellos caracteres que van a albergar los cambios de línea. Para poder pasar el texto a lista, utilizamos l = list(t), para el proceso contrario, utilizamos str.join("", l). El resultado es esperanzador:

         1         2         3         4         5         6         7         8
---------0---------0---------0---------0---------0---------0---------0---------0
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
Enter fullscreen mode Exit fullscreen mode

Solo tenemos que pasar este algoritmo a Sinclair BASIC. He incluido algunos espacios para hacer más fácil la lectura, aunque en Sinclair BASIC serían ignorados.

8000 REM Print text
8010 let COL = 80
8020 let i = COL
8030 if i >= len(t$) then goto 8110
8040     if i <= 1 or t$(i) = " " then goto 8070
8050         let i = i - 1
8060     goto 8040
8070     if i = 0 then goto 8110
8080     let t$(i) = chr$(13)
8090     let i = i + COL
8100 goto 8030
8110 lprint t$
Enter fullscreen mode Exit fullscreen mode

Y así, pude obtener mis textos (apuntes y trabajos), correctamente formateados en la impresora. Desde luego, no era WYSIWYG, ya que en la pantalla no se veía ni remotamente lo mismo que se obtenía en la impresora (por el distinto número de columnas), pero a mi me llegaba.

¿Alineación justificada? ¿Qué es eso?

Comments 13 total

  • Cesar Aguirre
    Cesar AguirreSep 17, 2025

    Se sintio un poco raro, seguir el ejemplo en BASIC con los gotos. Supongo que despues de escribir y leer BASIC a diario, uno se acostumbra.

    • Baltasar García Perez-Schofield
      Baltasar García Perez-SchofieldSep 18, 2025

      Es cierto, estamos tan acostumbrados a estructuras de iteración como while, que se hace muy raro. Pero es que, al fin y al cabo, Sinclair BASIC seguía la especificación de Mini BASIC estándar, y lo más avanzado de este en ese aspecto era GOSUB... RETURN (pero sin muchas características necesarias, como variables locales; todas eran globales).

      En el Sinclair QL (el último de Sinclair al mando de la compañía), Super BASIC sí que soportaba procedimientos y funciones, de manera similar a MS Visual BASIC.

      Por un lado es un poco molesto. Por el otro, en realidad sabes que cuando un bucle while es compilado, no acaba siendo otra cosa que un goto (jmp, en ensamblador Intel), a una condición (probablemente con cmp, en ensamblador Intel).

  • hsicilia
    hsiciliaSep 19, 2025

    Qué buena la historia, Baltasar.

    Con tu permiso la voy a pasar al grupo de Telegram de Boriel Basic ;)

  • Leanware
    LeanwareSep 21, 2025

    Nice post!

  • Leanware
    LeanwareSep 21, 2025

    Thank you!

  • Golam Rabby
    Golam RabbySep 21, 2025

    Uffs,, ভাই রে ভাই সেইরকম একটা ভিডিও ছিল🥵🥵, ভিডিওটি না দেখলে পুরাই মিস করবেন💥
    ⬇️ ভিডিওটির লিংক দিয়ে দিলাম⬇
    📎👇👇👇 read moed

Add comment