archivo

Archivos Mensuales: junio 2009

twitter-birdYa habĺé por aquí en su momento de Facebook, y ahora le toca el turno a Twitter e Identi.ca, dos servicios de microblogging parecidos que sólo salvan las distancias por el hecho de que el primero es propietario y el segundo es libre.

Siguiendo pues la filosofía de la “larga cola“, voy polinizando lo que puedo aquí y allá con la semilla del QL 😉 , conociendo a gente de otros países con formas de ver el QL distintas, y de paso haciendo publicidad de nuestra web.

Por eso hace aproximadamente un mes añadí al menú lateral un RSS de los twitts o mensajes que los usuarios de Twitter dejan relacionados con el QL, y ahora añado otro RSS relacionado con el grupo sobre QL en Identi.ca que he creado. Esta es otra ventaja de Identi.ca frente a Twitter, la de poder crear grupos de interés a donde dirigir tus mensajes sin tener que hacer búsquedas o seguir a nadie. Bien es cierto que Twitter permite guardar las búsquedas que desees (bajo registro) para consultarlas cuando quieras, pero no es lo mismo.

Hoy por hoy son pocos los usuarios que hablan sobre QL en ellos, pero es bueno tenerlos en cuenta a medida que estos servicios se popularizan.

Si eres usuario de Twitter pero te gustaría publicar algo en el grupo de QL de Identi.ca lo tienes fácil, pues este servicio permite la comunicación con Twitter pudiendo publicar automáticamente desde Identi.ca en los dos servicios.

Es una lástima que Google no permita aún seguir mediante RSS los comentarios sobre QL de los grupos, si bien uno puede estar al tanto de las entradas que hablen sobre QL en los blogs desde su servicio de noticias. Puedes seguir esas entradas también desde nuestro menú lateral.

¿Alguien está en Tuenti, Myspace o Tumblr y puede darnos un informe de la situación en esas redes?

Turbo fue el segundo de los compiladores SuperBASIC publicado por Digital Precision Limited (el primero fue Supercharge). Originalmente, el compilador Turbo fue obra de Simon N. Goodwin, acompañado de un equipo de personas como Freddy Vachha (MD de Digital Precision), Chas Dillon, Dave Newell y Gerry Jackson. Recientemente Turbo ha pasado a ser freeware (lo que significa que se puede copiar y obtener copias de forma gratuita) respaldado por George Gwilt, un experimentado programador QL cuyo trabajo incluye el desarrollo del ensamblador GWASS y GWASS Lite (Gwasl).

¿Por qué usar un compilador BASIC?

Un compilador SuperBASIC toma un programa BASIC y lo convierte en un programa que puedes ejecutar con EXEC. Normalmente el resultado es que el programa se ejecuta muchísimo más rápido, un programa varias veces más pequeño, un programa en el que el usuario no tiene porqué ver el código fuente SuperBASIC y un programa mucho más seguro ya que el programador puede beneficiarse de mejores mecanismos para el tratamiento de errores disponible en programas compilados. Los programas compilados, a menudo corrigen bugs derivados de versiones antiguas del BASIC como pueden ser las versiones de la ROM JM y JS, y asegura que el programa se ejecute de una forma consistente en todas las versiones de ROMS donde ciertos comandos podrían no trabajar completamente igual a las versiones más tempranas de la ROM del QL.

Un programa compilado no tiene que ser interpretado cuando se ejecuta, por lo que generalmente se ejecutará más rápido que el programa original. Turbo pretende convertir el programa original en un programa equivalente en código máquina. Hay dos tipos de compiladores, los que compilan a un código intermedio (por ejemplo el compilador Q-Liberator) y aquellos que compilan a código máquina (o lo más cerca posible). Esto creó una gran discusión en los primeros días sobre cuál era el mejor compilador para el usuario QL, pero la conclusión era que ambos tenían características destacables y que la elección dependía de lo que se pretendiese hacer. Turbo siempre tuvo la ventaja de la velocidad, pero tiende a ser estricto con aspectos de la sintaxis y tiene reglas ligeramente diferentes con respecto al paso de parámetros por referencia a y desde procedimientos y funciones. Por otro lado Q-Liberator siempre fue preferido por aquellos que trataban de compilar programas que hacían uso de “Pointer Environment” (PE, el entorno de ventanas para QDOS).

En estos días, los argumentos tienden a diferenciarse menos. En los rápidos sistemas QL-compatibles de hoy en día, el argumento de la velocidad es menos importante. Turbo es un proyecto libre y todavía mantenido con nueva versiones que aparecen de vez en cuando. Q-Liberator sigue siendo un programa comercial, y aunque no se producen nuevas versiones, sigue siendo hasta la fecha, sorprendentemente compatible con los sistemas modernos.

Siempre he sido un fan de ambos compiladores y pensé que sería el momento de echar una nueva mirada a Turbo ya que ahora es gratuito y ofrece un montón de nuevas facilidades que se han actualizado.

Turbo siempre se ofreció con un pequeño toolkit que contenía extensiones muy útiles al BASIC, algunas de ellas eran específicas para Turbo (otras son de uso general). Estas incluyen por ejemplo un “capturador” de errores para funciones INPUT. Más recientemente, Turbo Toolkit ha sido actualizado por David Gilham y George Gwilt

Este artículo está basado en las siguientes versiones del compilador Turbo y Turbo Toolkit:

Compilador Turbo (parser) versión 4.20
Turbo Toolkit versión 3.34

¿Dónde puedo conseguir el compilador Turbo?

El compilador Turbo y su Toolkit se puede obtener desde la mayoría de las librerías de dominio público del QL y de varios sitios Web. La fuente principal es el sitio Web del grupo escocés de usuarios QL de John Sadler:
http://www.jms1.supanet.com

También del sitio Web de Dilwyn Jones, en:
http://www.dilwyn.me.uk/turbo/index.html

Los manuales de Turbo son de acceso libre y puedes obtener también los fuentes si estás interesado en el diseño del compilador, aunque estos no son necesarios para el uso general de compilador.

Merece la pena obtener los nuevos manuales, incluso si tienes los originales de Digital Precision, ya que gente como Timothy Swenson han puesto gran esfuerzo en la actualización del contenido.

Puede que valga la pena conseguir los “Programas de Asociados”, un conjunto programas adicionales que aunque no sean indispensables para el uso de Turbo son muy útiles.

¿Cómo instalar Turbo?

Si has descargado los paquetes de Turbo desde los sitios Web que hemos comentado, habrás obtenido archivos en formato zip. Estos archivos deben ser descomprimidos con la versión QL del programa Unzip. No intentes descomprimirlo la versión Unzip de PC o de otro sistema, lo más probable es que pierdas las cabeceras de los ficheros ejecutables y no funcionen.

Una vez que hayas descomprimido los ficheros obtendrás los siguientes ficheros.

Turbo:
PARSER_TASK   - esta es el 'parser', que lee y comprueba
                el programa original SuperBASIC.
CODEGEN_TASK  - este es el generador de código, que
                produce el programa compilado final.
T_CONFIG_DATA - junto con T_CONFIG_LOAD establece el bloque
                Confing estándar en los programas.
UTILITY_TASK  - permite configurar Turbo Toolkit, etc.
CHANGES_TXT   - un fichero de texto que detalla los cambios
                recientes aplicados a Turbo.

Turbo Toolkit:
TURBO_TK_CODE - el Turbo Toolkit completo,
                para uso general
TURBO_SMS_CODE- una versión de Turbo Toolkit ligeramente
                más pequeña para usuarios de SMSQ/E.
TURBO_REM_CODE- un suboconjunto de Turbo para la inclusión
                en programas compilados.
TURBOBASE_ASM - código fuente en ensamblador del toolkit.

Turbo Manuals:
TURBOTOC_TXT  - Tabla de contenidos del manual.
TURBOS1_TXT  a
TURBOS4_TXT   - manual de Turbo en cuatro secciones.
UTILITY_TXT   - manual de las utilidades
T_CONFIG_TXT  - manual de T_CONFIG_DATA y T_CONFIG_LOAD
TASCOM_TXT    - manual para Task Commander, una utilidad
                que ayuda a convertir un porgrama compilado
                en una extensión del BASIC (es decir, un
                fichero que puede ser cargado con
                LRESPR en lugar de EXEC)
TURBODEM_TXT  - describe el contenido de los ficheros de
                demostración de Turbo Toolkit suministrado
                en el paquete de "Programas Asociados"

Adicionalmente, estos documentos de referencia también están
disponibles, pero realmente no los necesitas al principio

TURBOREF_TXT  - fichero de referencias. Listado de mensajes de
                error y comandos del Turbo Toolkit en orden
                alfabético
LINKLOAD_TXT  - ejemplos de cómo usar LINK_LOAD
INTFILE_TXT   - explicaciones de Simon Goodwin sobre la generación
                de código intermedio producido por el "parser"
                para el generador de código.
TURBOREP_TXT  - un artículo de Simon Goodwin acerca del diseño
                de Turbo.

Programas asociados:
TASCOM        - Task Commander transforma un ejecutable en un
                comando SuperBASIC.
DATASPACE_TASK- un programa que cambia el área de datos
                de una tarea.
LIBRARY_MANAGER-un programa que extra rutinas
TURBO_TK_DEMOS- un conjunto de programas de demotración con
                procedimientos y funciones útiles.
MAKE_MODULES  - una utilidad para partir un programa
                SuperBASIC en módulos más pequeños.

Descomprime todos los ficheros que piensas que vas a necesitar y ponlos todos juntos en un disquete o en un directorio de tu disco duro. Si intentas usar Turbo Toolkit deberás cargarlo primero mediante RESPR o LRESPR.

LRESPR FLP1_TURBO_TK_CODE

Existen tres versiones diferentes de Turbo Toolkit. Turbo_TK_Code es la apuesta más segura en el sentido de que funcionará bien en todos los sistemas. Turbo_SMS_Code sólo funcionará en sistemas SMSQ/E, y tiene la ventaja que es ligeramente más pequeño (si estás usando SMSQ/E Turbo_SMS_Code es la versión que debes usar, ya que se añade soporte a algunas características avanzadas de SMSQ/E). La tercera versión, Turbo_REM_code, es más reciente y adaptada a las nuevas versiones de Turbo, donde puedes incrustar el toolkit dentro de un programa compilado, en lugar de tener que cargarlo previamente con LRESPR. Para ver cómo “incluir” o “adjuntar” esta facilidad tendrás que mirar en el fichero CHANGES_TXT el uso de la directiva REMark %%:

REMark %%<filename>,a,b

El nombre de fichero a incluir está indicado por y puede llevar dos parámetros, a y b:

a es el desplazamiento al código de inicialización en el fichero, o 0 si no hay rutina de inicialización.

b es el desplazamiento a la tabla de inicialización.

La línea con REMark %% pude estar en cualquier lugar dentro del programa SuperBASIC. Ésta es una característica avanzada y por ahora no necesitas saber nada más sobre esto.

Turbo_Rem_Code es una versión especial de Turbo Toolkit diseñada para la inclusión en el programa compilado, y utiliza la directiva

REMark %%flp1_turbo_rem_code,6,10

Una vez que has cargado Turbo Toolkit, puedes cargar tu programa SuperBASIC y listar o editar algunas líneas para garantizar que es un programa listo para ser compilado.

Ahora debemos asegurarnos que el valor predeterminado de PROG_USE está apuntando a la unidad de disco o subdirectorio que contiene los programas PARSER_TASK y CODEGEN_TASK. Si se está apuntando a otro lugar, el comando CHARGE que se utiliza para iniciar el compilador no encontrará los programas necesarios. Así, suponiendo que el compilador está en FLP1_ el comando PROG_USE FLP1_ hara que Turbo esté lista para empezar a compilar. Introduce ahora el comando CHARGE y deberás ver la aparición del panel principal de configuración del compilador (ver figura 1).

Turbo, Panel principal

Turbo, Panel principal

Si por alguna razón el comando CHARGE no funciona, puedes también iniciar el proceso de compilación con los comandos EXEC_W o EW:

EW PARSER_TASK:EW CODEGEN_TASK

que esencialmente es lo que hace el comando CHARGE.

Este panel frontal te permite establecer una serie de opciones para configurar el proceso de compilación. En la línea superior se muestra una serie de información general y si se han detectado errores o no.

En la tercera línea hacia abajo, en el primer cuadro te permite elegir entre las opciones FREEFORM o STRUCTURED. Esto establece el nivel de comprobación para programas que estén correctamente estructurados o no. Para activar esas opciones usa las teclas del cursor y activa o desactiva la opción con la tecla ESPACIO. El siguiente cuadro de elección selecciona si deseamos utilizar código de 16-bit o no. Si el programa compilado es corto (menos de 64 kilobytes) Turbo intentará usar código de 16 bits para generar un programa más pequeño y más rápido.

La siguiente opción permite establecer si deseamos incluir número de línea en el programa compilado. Esto tiene incidencias en el tamaño del programa compilado, pero por supuesto hace que sea más fácil depurar programas porque los mensajes de error nos indicarán el número de línea donde se produjo dicho error. La siguiente opción te permite elegir las opciones BREVE, FAST y REMs, y por último en esta misma línea en la caja de selección del extremos derecho podremos configurar cuantas ventanas con copiadas desde el BASIC al programa compilado (con cuantas ventanas abiertas comenzará el programa).

En la cuarta línea especificaremos el nombre del fichero del programa compilado. Hay un valor por defecto o RAM1_TEST_TASK cuando lo ejecutas por primera vez. Puedes cambiar esto si lo deseas usando el Config estándar o el programa MenuConfig para configurar los valores por defecto incluidos en PARSER_TASK. No hay bloques de configuración en CODEGEN_TASK o Turbo Toolkit.

En la quinta línea puedes especificar los objetos de datos (el espacio para datos del programa compilado, que por defecto son 2 kilobytes) en el cuadro de la izquierda (este valor se puede cambiar más adelante por medio de un programa llamado DATASPACE_TASK). En la caja de parte derecha de esta línea, puedes especificar cuanta memoria se reserva para el buffer del compilador, que tiene influencia en la velocidad de compilación. Los sistemas QL modernos tienen un montón de memoria, así que no hay necesidad de escatimar en este apartado.

En el cuadro de informe (Report) se puede especificar el nombre de un fichero al cual se enviará los detalles de la compilación. Esto ayudará en el análisis de los errores generados. También en el nombre del TASK podemos especificar el nombre de la tarea para el programa compilado, este es el nombre que verás cuando se usa el comando JOBS para ver la lista de programas en ejecución.

En la línea inferior se pueden establecer una cadena de opciones para la compilación de programas (ver el manual para más detalle). Por último, en la línea inferior se encuentra las opciones para salir (Quit) del panel.

Una vez establecidas las opciones deseadas debemos desplazarnos al cuadro del centro y pulsar ENTER para comenzar la compilación (cuadro COMPILE). El proceso de compilación comenzará, tomándose algún tiempo dependiendo el tamaño del programa a compilar. Si se producen errores serios, aparecerá un mensaje y el analizador (Parser) parará su ejecución, ya que en otro caso se producirán resultados inesperadas en la fase de generación de código.

Si todo ha ido bien y no se han producido errores, tendrás un bonito programa compilado listo para ejecutar con EXEC. Por supuesto, recuerda que si has generado el programa en un RamDisk, necesitas grabar el programa a disco antes de apagar o reiniciar tu QL, en caso contrario lo perderás. La compilación a un disco RAM puede ser mucho más rápida que compilar a un disco flexible, especialmente útil en las compilaciones de prueba.

Hay algunas otras opciones disponibles con el comando CHARGE, que ayudarán a automatizar el proceso de compilación en cierta manera:

CHARGE ‘nombrefichero’ especifica el nombre de fichero para el programa compilado.

El comando CHARGE \ con la barra invertida a continuación, compilará automáticamente el programa usando la configuración por defecto y saltando el panel principal. Esto es de muy útil si quieres compilar rápidamente un programa para uso propio o para pruebas sin molestarte demasiado sobre los ajustes del compilador.

Para complicarte un poco la vida (más fácil una vez que te acostumbras, especialmente en la elaboración de programas más complejos) existen una serie de directivas para especificar al compilador muchas de las opciones establecidas en el panel principal. Por ejemplo, el comando TURBO_model 1 fuerza al compilar a crear programas como si se hubiera especificado el “<64” en el panel frontal. TURBO_objdat ’50 ‘ asignará 50 KB al espacio de datos en el programa compilado. Si estas desarrollando varios programas complejos, puedes incluir esas directivas en tu programa para estandarizar de forma consistente el proceso de compilación cada vez que cambias algo.

¿Cuánto de compatible es el compilador Turbo?

La respuesta no es inmediata. Necesitas leer extensos ficheros de documentación suministrados con el compilador para encontrar exactamente qué se compilará y qué cosas no se compilarán correctamente. Para un uso general, sólo necesitas algunas directrices simples para conseguir que pequeños programas se compilen sin ningún problema.

Para programas más complejos, necesitarías leer los manuales con más detalle, pero te acostumbrarías rápidamente a los cambios. Las principales novedades que fueron para mi más destacables son las facilidades de manejo de errores (Turbo tiene su propio sistema de captura de errores WHEN_ERROR 1 Y WHEN_ERROR 2 a diferencia el del comando WHEN ERRor de SuperBASIC/SBASIC), el uso del paso de parámetros por referencia (para usar parámetros por referencia se debe emplear el comando REFERENCE en la definición de la lista de parámetros), y la necesidad del uso cuidadoso de la dimensión de los string en comparación a la declaración de string del BASIC ordinario.

Se han hecho varios cambios en el compilador desde la popularización de SMSQ/E. El comportamiento de las ventanas se ha mejorado mucho cuando Pointer Environment (PE) está presente, por ejemplo.

George Gwilt ha desarrollado algunas utilidades para el uso del Compilador Turbo. La más destacable es TurboPTR, una utilidad bien pensada para escribir y compilar programas bajo PE. En cierto modo se puede comparar al toolkit QPTR de Tony Tebby, pero TurboPTR está específicamente orientado al uso de Turbo.

Las utilidades Turbo-config o T-Config te permiten incluir bloques de configuración para el uso de programas compilados.

Los ‘Associated Programs’ son versiones actualizadas incluidas con la versión original de Turbo, actualizadas para trabajar mejor en los sistemas recientes y para aprovechar mejor las facilidades disponibles en los sistemas QL recientes.

Resumen

El compilador y el Toolkit han tenido una importante remodelación en los últimos tiempos y merece la pena obtener una copia actualizada. Si tu única experiencia con Turbo ha sido con versiones anteriores correspondientes a la primera década del QL, o simplemente has leído algo de la versión original de Digital Precision deberías descargarte la nueva versión y probarlo. Es un paquete bastante complejo, y por supuesto, la gran cantidad de documentación puede hacer desistir a muchas personas a intentar aprenderlo.

Una serie de nuevos comandos y variaciones en otros se han añadido a Turbo Toolkit y al Compilador Turbo en los últimos años, especialmente destinados a facilitar la tarea a los usuarios de SMSQ/E y GD2, en estos casos bien merece la pena la actualización a las últimas versiones.

Hay muchas más cosas que decir sobre Turbo pero no caben en un artículo corto como éste. Espero que este breve recorrido te ayude a comenzar con él y te anime a utilizar el Turbo Toolkit y el Compilador Turbo después de todo el trabajo realizado por gente como George Gwilt y David Gilham para poner día este fantástico compilador.


Autor: David Denham
(Traducción y adaptación: afx)

Uno de los primeros programas con los que jugué cuando compré mi primer QL fue el copiador que acompañaba al software de PSION. Con este programa uno puede aprender varios conceptos básicos acerca de las facilidades del QL y del SuperBASIC, uso de ficheros, canales… y de paso el programa ayudó a salvar más de un cartucho de microdrive, al menos hasta la llegada de las extensiones TK2 (Toolkit II) de Tony Tebby, con sus “wildcards” o facilidades de copia salvaje. Respecto a esto, tengo que hacer mención al artículo de Salvador Merino titulado “Un resumen de la historia de un copión llamado trumpcopy2” que os recomiendo que no dejéis de leer pues tiene su gracia a la vez que es muy aprovechable si se dispone de TK2.

Hablaba del programa copiador de microdrives. Esto es lo que veremos en este artículo dedicado obviamente a los que empiezan con el QL. Es muy cortito. Veamos su listado y que hace en cada línea:

100 REMark copia de mdv2_ a mdv1_
110 OPEN_NEW #3,mdv1_dir
120 DIR #3,mdv2_
130 OPEN_IN #3,mdv1_dir
140 INPUT #3,a$;a$
150 REPeat copia
160   IF EOF(#3): EXIT copia
170   INPUT #3,a$
180   PRINT "Copiando mdv1_";a$
190   COPY mdv2_ & a$ TO mdv1_ & a$
200 END REPeat copia
210 CLOSE #3
220 DELETE mdv1_dir
230 PRINT "Copia completada."

La línea 100 muestra un comentario. Nada nuevo bajo el sol. Sólo decir que cuando se renumeran automáticamente las líneas (RENUM) en el QL, la primera línea por defecto es la 100.

El programa, a grandes rasgos, va a abrir un fichero en mdv1_ (unidad de microdrive 1), luego listará en ese fichero el nombre de los ficheros que hay en mdv2_ y por último copiará uno por uno cada fichero de mdv2_ a mdv1_.

En la línea 110 abrimos (OPEN) un canal nuevo de comunicación (#3) que va a ser un fichero en mdv1_ llamado “dir”. Cualquier dispositivo de entrada o salida, ficheros, puertos serie, etc… se abrirá como un canal numerado “#n”.

En la línea 120 hacemos DIR para mostrare el contenido de mdv2_ y este contenido se mostrará por el canal 3 (#3). Si #3 se hubiese abierto como un puerto serie en vez de como un fichero, estaríamos mandando el listado a la impresora por ejemplo directamente.

El siguiente paso será poder acceder al canal en modo lectura. Usamos pues OPEN_IN en la línea 130.

Ya podemos leer del #3. Las dos primeras cadenas de texto del fichero mdv1_dir corresponden al nombre del microdrive y al número de sectores disponibles (información que proporcionó DIR). Esta información no es necesaria para realizar la copia, así que la desechamos.

En la línea 140 leemos en a$ las dos primeras cadenas de texto (a$;a$) del fichero “dir”. El punto y coma pues es un separador. El SuperBASIC tiene estas facilidades que nos permiten leer varias cadenas a la vez con un INPUT.

Entre las líneas 150 y 200 se produce la magia. Estamos en un bucle llamado “copia” cuya condición de salida podemos ver en la línea 160: Si hemos llegado al final del canal (EOF) entonces salimos del bucle “copia” y segimos desde la línea posterior a END REPeat copia.

En la línea 170 leemos a$, que contendrá una cadena con un nombre de fichero del listado de mdv2_.

En la línea 180 indicamos por pantalla que vamos a copiar ese fichero. Volvemos a usar “;” como separador. Existen varios tipos de separadores en SuperBASIC que descubrirás en el manual.

En la línea 190, por fin, se realiza la copia de un fichero desde mdv2_ a mdv1_ Analicemos esta línea.

La orden COPY  necesita saber desde donde hacia donde vamos a copiar. Sabemos que el fichero a copiar está en a$, y que vamos a copiar desde mdv2_ a mdv1_, ahora sólo tenemos que escribir correctamente la sentencia.

el separador “&” consigue unir cadenas de texto. En este caso la cadena de texto es mdv2_ o mdv1_ y el contenido de a$, que será igual para ambas unidades de microdrive, puesto que el fichero que copiaremos se va a llamar igual en el origen y en el destino.

Pongamos que tenemos un fichero llamado programa_bas en mdv2_. La orden sería:

COPY mdv2_programa_bas TO mdv1_ programa_bas

Podríamos tener, como sucede en el listado, el nombre del fichero en una variable:

fichero$="programa_bas"
COPY mdv2_ & fichero$ TO mdv1_ & fichero$

y funcionaría igual.

Esto puede ser de mucha utilidad cuando escribimos programas que van a acceder a datos en microdrive o en discos, pues de esta forma podemos sustituir el nombre del dispositivo guardado en una variable sin tener que cambiar cada línea del listado donde se use ese dispositivo. Por ejemplo:

..
500 DIR mdv1_
600 RUN mdv1_programa_bas
..

Si este programa lo salvamos en flp1_ (floppy 1) por poner un ejemplo y en el copiamos también el fichero programa_bas tendremos que cambiar las líneas 500 y 600 y cualquiera otra que apunte a algún archivo en mdv1_ que ahora esté en flp1_

Con el siguiente programa la cosa sería más sencilla.

100 disp$="mdv1_"
..
500 DIR disp$
600 RUN disp$ & programa_bas
..

En este ejemplo sólo tendremos que cambiar la línea 100 por:

100 disp$="flp1_"

Útil ¿verdad?

Seguimos pues. Como ya hemos salido del bucle, y copiado todos los ficheros, que era nuestro objetivo, en la línea 210 cerramos el canal 3 (#3) definitivamente.

En la línea 220 borramos el fichero “dir” en mdv1_, pues ya no lo necesitamos, y en la línea 230 avisamos que la tarea está realizada.

Ha llegado la hora de usar el programa. Debemos poner el microdrive que queramos copiar en mdv2_ y un cartucho en blanco formateado en mdv1_ y ejecutar el programa.

Si salvamos el programa en mdv2_ antes de ejecutarlo, este se clonará a si mismo en la copia que realicemos. 😉

Con lo expuesto aquí, uno ya puede abrir ficheros para escribir y leer de ellos o copiar en ellos información proveniente de otros canales. Puedes probar a crear un pequeño fichero al que añadas mediante INPUTs cadenas de texto que introduzcas por teclado y luego muestres lo escrito por pantalla, o abrir un canal dirijido al puerto serie y escribir directamente líneas en la impresora. Todo sea por enredar.

Tirando de la hebra en un post de ql-user he encontrado una utilidad muy práctica que transforma código fuente SuperBASIC en Html.

La página de referencia es está aquí (sección Programs->Utilities).

He traído aquí la demo que pone la página. Como veis, se colorea el código SuperBASIC, pero lo más útil es que incluye href’s (enlaces) a los procedimientos y funciones. Si probáis en el este código veréis que al pulsar sobre “CrossHair” o “Disp” en la rutina Main os lleva directamente a la definición de esos procedimientos o funciones.

Me parece una utilidad muy práctica a la hora de “leer” y trazar programas SuperBASIC, especialmente los que sean muy largos. Puede venirnos muy bien si queremos exponer código fuente en nuestro Blog, o en cualquier otro sitio en internet.

La demo que os comento:

Demo sb2htm (CrossHairs)


Xhair

100 REMark $$stak=384
110 REMark $$heap=384
120 REMark $$chan=3
130 :
140 REMark       CrossHairs
150 REMark ©PWitte March 26th 2000
160 REMark         V 0.00
170 REMark        Freeware
180 :
190 REMark
200 :
210 REMark For details of use click here
220 c = FOPEN("con"): ERT c
230 xs% = SCR_XLIM(#c): ys% = SCR_YLIM(#c)
240 WINDOW#c; xs%, ys%, 0, 0
250 OVER#c; -1: INK#c; 7
260 :
270 RPTR#c; lx%, ly%, 9, s%, xr%, yr%, k$
280 CrossHairs lx%, ly%
290 toggle% = 0
300 :
310 REPeat main
320  RPTR#c; xp%, yp%, 9, s%, xr%, yr%, k$
330  k% = CODE(k$): IF k% = 27 OR k% = 2: EXIT main
340  CrossHairs lx%, ly%
350  CrossHairs xp%, yp%
360  lx% = xp%: ly% = yp%
370 :
380  IF k% = 1 THEN
390   IF toggle% = 0 THEN
400    toggle% = 1
410    dx% = xp%: dy% = yp%
420    Displ dx%, dy%, xp%, yp%
430    nx% = xp%: ny% = yp%
440   ELSE
450    toggle% = 0
460    Displ dx%, dy%, nx%, ny%
470   END IF
480  ELSE
490   IF toggle% = 1 THEN
500    Displ dx%, dy%, nx%, ny%
510    Displ dx%, dy%, xp%, yp%
520    nx% = xp%: ny% = yp%
530   END IF
540  END IF
550 END REPeat main
560 :
570 DEFine PROCedure  CrossHairs(x%, y%)
580 BLOCK#c; xs%, 1, 0, y%, 7
590 BLOCK#c; 1, ys%, x%, 0, 7
600 END DEFine CrossHairs
610 :
620 DEFine PROCedure  Displ(px%, py%, nx%, ny%)
630 LOCal x%, y%, l%, s$
640 s$ = ' ' & nx% & '/' & ny% & ' ': l% = LEN(s$) * 6
650 IF (px% + l%) > xs%: x% = px% - l%: ELSE : x% = px%
660 IF (py% - 12) < 0: y% = py% + 2: ELSE : y% = py% - 12
670 BLOCK#c; l% - 8, 10, x% + 4, y%, 7
680 CURSOR#c; x%, y%: PRINT#c; s$;
690 END DEFine Displ
700 :

Top of Page

Generated with sb2htm

XGraceHopper


Grace Hopper fue una gran impulsora de los lenguajes de alto nivel, y a ella se debe la identificación del primer “bug”.

Suele pensarse que la ciencia de la informática por lo general es un club “sólo de hombres”. Pero las mujeres van ocupando cada vez más posiciones junto a los hombres, en pie de igualdad, en el desarrollo y la aplicación de los ordenadores. Una de las pioneras de la informática fue Grace Hopper, cuya aportación más trascendente revolucionó el campo del software: fue la autora del primer compilador y colaboró de manera destacada en la elaboración y la puesta a punto del lenguaje COBOL. También fue la primera persona que aisló un “bug” en un ordenador y logró “depurarlo”.

Después de hacer un trabajo de posgrado en Yale, Grace Hopper regresó a su universidad de origen, Vassar, como miembro de la facultad de matemáticas. Allí permaneció hasta la edad de 39 años, cuando fue llamada para el servicio de guerra en la Naval Ordinance Computation Project. En 1945 se le ordenó que fuera a la Universidad de Harvard para ayudar al físico Howard Aiken en la construcción de un ordenador. En 1937 Aiken había propuesto a la IBM la idea de construir un ordenador utilizando equipos de tabulación adaptados. Su primer ordenador, aunque de diseño mecánico, tuvo el éxito suficiente como para animar a IBM a invertir en un modelo mejorado que pudieran emplear relés electromecánicos. Así se construyó una máquina que se denominó Harvard Mark II.

En aquellos primeros días las máquinas habían de programarse volviendo a tender sus cables cada nueva tarea. De modo que, en el caluroso verano de 1945, Grace Hopper se encontró literalmente atrapada entre los cables del ordenador. Las necesidades de la guerra exigían con toda urgencia el procesamiento de datos balísticos, y el comandante Aiken solía irrumpir en la sala para preguntarle: “¿Por qué no está usted haciendo números, Hopper?” Una avería del ordenador lo impedía. Cuando finalmente se descubrió que el fallo se debía a una enorme polilla que había penetrado por las ventanas abiertas y que había quedado atrapada en el interruptor de un relé, Grace le replicó sucintamente: “¡Estamos desinsectando la máquina!” Este primer “bug” del que se tiene constancia se extrajo con sumo cuidado del relé con un par de pinzas y se conserva en el Museo Naval de Virginia en el cuaderno de bitácora del Harvard Mark II. Está pegado con cola junto a la entrada de las 15.45 del 9 de septiembre de 1945.

Primer Bug

Primer Bug

Aquel mismo año dos ingenieros, John Mauchly y Presper Eckert, estaban construyendo otro ordenador, el ENIAC. Finalizada la guerra, los dos hombres crearon su propia empresa para fabricar una versión comercial de la máquina, e invitaron a Grace a unirse al equipo. La ayuda más valiosa que aportó al desarrollo de este ordenador, denominado UNIVAC (UNIversal ACcounting Machine) la constituyó la creación de software para el mismo. Y fue mientras intentaba construir programas de aplicaciones empresariales en el UNIVAC cuando Grace buscó por primera vez un atajo para ahorrarse la necesidad de volver a escribir ciertas subrutinas que se repetían una y otra vez. Valiéndose de lo que entonces se tuvo como brillante estratagema, la de que un ordenador podía escribir sus propios programas. Grace creó el primer lenguaje de programación, junto con el compilador necesario para traducirlo a código de lenguaje máquina. Se le dio el nombre de “A-0”. Cuando este compilador fue presentado en público por primera vez suscitó la incredulidad entre los profesionales de la informática, quienes pensaban que las máquinas sólo podían realizar operaciones aritméticas y manipular símbolos. Se quedaban atónitos viendo cómo un ordenador saltaba a una subrutina de su biblioteca al encontrarse con un verbo en imperativo al comienzo de lo que era casi una sencilla locución en inglés.

En mayo de 1959 la capitana Hopper fue invitada al Pentágono para formar parte de una comisión de trabajo que estaba intentando crear y estandarizar un lenguaje para ordenadores de uso comercial. En menos de un año la comisión dio a luz la primera versión del Common Business Oriented Language (COBOL). Grace colaboró valiosamente en los esfuerzos de la comisión por aunar los mejores logros de cada uno de los lenguajes existentes y, por consiguiente, crear un lenguaje óptimo para las empresas en virtud de su calidad. Prueba del éxito que consiguió la comisión es que COBOL continúa siendo hoy en día uno de los lenguajes más ampliamente utilizados.

(Fuente: Enciclopedia Mi Computer, fascículo 22. Editorial Delta, 1984.)

Seguramente muchos de vosotros os habéis imaginado alguna vez cómo sería un QL en la actualidad si la empresa Sinclair no hubiera quebrado y la plataforma QL-QDOS hubiera seguido evolucionando hasta nuestros días.

Lo más probable es que dicha evolución hubiera sido en la misma línea que la plataforma MAC. Esto es:

– Las primeras etapas deberían haber girado en torno al procesador 68000, tales como el 68030, 68040 y finalmente el 68060.

– La siguiente evolución habría girado en torno al procesador Power PC, a imagen y semejanza del MAC (o Amiga) ya que fue en su momento la apuesta de futuro de Motorola (quedando bastante abandonado la evolución de la línea de procesadores 68000). Tal vez se hubieran fabricado dos generaciones de máquinas con ese procesador.

– Y por último, como el gran “rodillo” que todo lo pisa, esa hipotética plataforma habría recalado en los chips de Intel, tal como ha sucedido en los MAC. Ya se sabe, lo que más se vende al final produce mayor inversión, mayor innovación, abaratamiento de costes, …

Expuesto este preámbulo, si se hubiera dado esta evolución, hoy en día tendríamos un Super QL con una placa base como la p5QL.

Una placa como esta:

Placa p5QL

Placa p5QL

Algunas características:
– Soporte para procesador Intel Core 2 Quad.
– Hasta 16 GB de memoria.
– 6 Serial ATA.
– 12 x USB.
– PCI 2.0
– …

Portada del manual:

Portada manual placa p5QL

Portada manual placa p5QL

Esto, en el terreno hardware. En cuanto al Software, seguramente tendríamos un hipotético SMSQ/E versión 10.5 (ya multiusuario) con entorno gráfico tipo KDE por ejemplo (una especie de PE evolucionado), SuperBASIC versión ZKA con orientación a objetos, … Tendríamos también FireFox para SMSQ/E, Java, Open Office, PC Four versión 12.0 (de la casa Psion), …

¡Bueno! … todo esto viene a cuento porque esta semana he estado sustituyendo el hardware de mi PC. He tenido unos problemas tremendos a los que no le encontraba explicación alguna (… la historia es larga y no merece la pena detallar). La cosa es que al final decidí comprar una nueva placa base, una carcasa nueva y aprovechar algo de hardware que ya tenía (HD, DVD, teclado, monitor, …). Estas piezas las he comprado en “la tienda de la esquina” (de un amigo por cierto).

El dilema en principio era elegir una buena placa base (robusta, rápida, …) y como el ser humano muchas veces no toma las decisiones por razones lógicas u objetivas sino por razones “emocionales” yo elegí la placa p5QL de Asus. ¿Adivináis por qué elegí esa placa? … pues simplemente porque ¡¡tenía las letras QL en el nombre!!

Pues eso … ya tengo mi nuevo PC, mi sistema vuelve a funcionar y por un ratito he soñado cómo sería un QL hoy en día si la “suerte” hubiera sido otra. Por ahora tengo mis dos QL ampliados y mi p5QL donde puedo ejecutar todo el software actual y unos muy buenos emuladores QL (Q-emulator o QPC -por ahora versión demo-), … ¡que ya es bastante!

Estaba revisando algunos de los materiales elaborados sobre el QL estos últimos años y he topado con estos dos vídeos.

El primero es un anuncio un tanto gamberro que pretendía principalmente llamar la atención y que se hizo a petición de la organización de la MadriSX & Retro en el 2005 (ahora RetroMadrid), año en el que celebramos el 20 aniversario de la versión MGE del QL (la versión de QL vendida en España con ROM española) y pusimos un stand en la feria patrocinado por Radastan.

Aquí podéis verlo en todo su esplendor. Aviso, no apto para escrupulosos:

El segundo vídeo es una composición de las pantallas de presentación de stand:

En cada diapositiva se hablaba de:

  1. Presentación de sinclairql.es (entonces sinclairql.info)
  2. El QL
  3. Webs de QL en España (QReino Retropágina y Programas Sinclair QL y ZX 81)
  4. Programas de QL que llevábamos a la feria
  5. Actividades de copia de microdrive
  6. Muestra de hardware
  7. Badasetas (así renombró la gente a la tirada de camisetas Sinclair que hicimos para el evento)
  8. Material de información disponible (revista 20 aniversario y folleto)
  9. “Visita nuestra web”…tenemos de todo
  10. Agradecimiento

En otra ocasión os contaré como nos fue. Os adelanto unas fotos de Zerover.

Las músicas que se escuchan son mods que podéis descargar aquí (vídeo 1) y aquí (vídeo 2).

En el artículo “Copiando ficheros desde el QL al PC (y viceversa)” se muestra un enlace a las instrucciones  que tenemos que seguir si queremos transferir ficheros entre ambas máquinas. Esto abre las puertas a muchas posibilidades, pero es importante destacar algunas cosas a tener en cuenta:

  1. Los microdrives son caros en lo que respecta a su capacidad de almacenamiento y difíciles de obtener.
  2. Los programas pues, en general, ocuparán demasiado espacio en los microdrives, pero lo peor es la escasa cantidad de memoria de que dispondremos para ejecutarlos en el QL.
  3. Algunos ejecutables requieren extensiones del sistema como el Toolkit II, que si bien hoy día están disponibles gratuitamente, limitan aún más el espacio de memoria para programas.
  4. Los ficheros ejecutables tienen una cabecera que hay que preservar cuando transferimos archivos.
  5. Los programas que obtendremos por Internet generalmente están disponibles comprimidos en formato zip.

…todo esto sin hablar de que necesitaremos saber cómo instalar y usar un emulador y cuales son los comandos necesarios para copiar ficheros.

Es evidente que tratar con el QL no es lo mismo que hacerlo con sus otros hermanos Sinclair, y su metodología de uso se asemeja más a la de MS/DOS o cualquier OS de línea de comandos. Vamos a ver cuales son las distintas soluciones a estos problemas que seguro se os presentarán si os estáis iniciando en el mundo del QL con una máquina básica.

Los puntos 1 al 3 tienen una única solución: ampliar. Necesitaremos una controladora de discos y una ampliación de memoria para nuestro QL. Ambas pueden ser tarjetas independientes o una sola tarjeta que incluya ambas cosas. La más recomendable por precio y prestaciones es la TrumpCard de Miracle Systems, pero hay muchas otras posibilidades. Una búsqueda entre los enlaces a las páginas comerciales de QL o en Ebay nos dará algunas opciones.

Claro que si tenemos una controladora de discos necesitaremos un lector de discos. Buenas noticias. Las disqueteras de hoy sirven perfectamente. En este artículo se explica cómo adaptarlas.

Para solucionar el problema del punto 4 es necesario que la manipulación de los ficheros ejecutables se haga siempre desde un sistema QL que soporte el formato de ficheros del S.O. QDOS, es decir, desde el propio QL, un emulador de QL que pueda acceder a ficheros en una partición FAT, NTFS, etc… (casi todos lo hacen) pero nunca, NUNCA, manipular esos ficheros desde Windows, Linux u otros sistemas. Si copiamos un ejecutable mediante “copiar y pegar” por ejemplo, habremos perdido la cabecera de ese fichero y ya no funcionará en el QL. Los que tengan Macs saben de que hablo. Afortunadamente, los ficheros no ejecutables no tienen este problema, pudiendo, por ejemplo, editar un fichero de texto con el bloc de notas y luego usarlo en el QL o en el emulador sin más (podemos pues editar nuestros programas SuperBASIC en nuestro cómodo editor de textos…)

Por ultimo, para solucionar el problema planteado por el punto 5 debemos usar los programas zip y unzip para QL. No podemos, por la razón descrita, descomprimir los zip fuera de el emulador o el QL. Aquí tienes una descripción de cómo usarlos (mismo modo que en otros sistemas) y dónde conseguir unzip. Lee el leeme.txt.

Si lo que queremos es pasar nuestros viejos programas SuperBASIC al PC para hacer una copia de respaldo, todo esto no será necesario, pero enseguida querremos sacarle más partido al QL, y estas anotaciones te serán entonces imprescindibles.

jav_ql_mdvHe leído un hilo muy bueno en ql-user de cómo transferir ficheros desde un QL básico (sólo con unidades microdrives sin ningún tipo de ampliación de disqueteras) a un PC empleando simplemente un cable RS232.

El usuario que inicia la experiencia (aupf82), pone como último post (http://www.mail-archive.com/ql-users@lists.q-v-d.com/msg06162.html) el resumen de todos los pasos a dar para quien lo pueda necesitar. En este resumen explica con todo lujo de detalles los pasos para realizar dicha transferencia con éxito y en ambos sentidos (QL a PC y PC a QL).

jav_ql_serLa idea básica es emplear un cable estándar RS232, para hacer la transferencia al PC por medio de Q-emulator (un emulador QL en el PC) y no vía MS-DOS. (Para emplear este cable se necesita un adaptador en el QL, -se puede conseguir en “Sinclair Shop”-)

Hay dos partes en el proceso:

1) Lograr transferir desde el Q-emulator a un microdrive del QL, una utilidad que viene con el propio Q-emulator llamada MdvToWin. Ejecutando esta utilidad en el QL podemos transferir ficheros EXEcutables sin perder las cabeceras. El problema de este primer paso es que se necesita un mecanismo para que el propio MdvToWIN (que es un ejecutable QDOS) no pierda las cabeceras al pasarlo al QL real. Bien, el artículo mencionado explica cómo hacerlo.

2) Una vez hayamos transferido la utilidad MdvToWin a una unidad Microdrive del QL, el resto es mucho más sencillo. El propio MdvToWin nos guía en el proceso para lograr transferir cualquier tipo de fichero respetando las dichosas cabeceras de los ejecutables QDOS.

Bueno, lo dicho, un artículo muy útil para aquellos que sólo dispongan de un QL básico con algunos cartuchos microdrives y quieran disfrutar de la máquina real copiando ficheros desde el PC. O bien para aquellos que tengan programas en microdrives y deseen pasarlo al PC para ser usados en un emulador.

En esta última parte vamos a estudiar de una forma más atenta los Things en tu sistema, cómo se organizan en la memoria y la forma en la que están vinculados.

Te mostraré un programa SBASIC bastante corto al final de éste artículo (listado 1), que puedes teclear o copiar, y que te mostrará algunos detalles de los Thing en tu sistema. Cuando lo ejecutes, probablemente listará todos los Things que tienes actualmente disponibles. A modo de ejemplo, puedes ver en la tabla 2 los Things cargados en mi sistema.

Debería mencionar en primer lugar, que el “hacking” a través de una lista como la de los Things (u otra lista, como la de los controladores de dispositivos etc.) debería hacerse en ensamblador mientras el programa se está ejecutando en modo Supervisor. Esto asegura, que otros jobs no pueden enlazar o des-enlazar Things mientras nosotros examinamos la lista. Esto no lo podemos hacer en SBASIC, pero siempre y cuando tú no añadas y quietes Thigs durante la ejecución del propio programa no pasará nada. Además, dudo que estés continuamente añadiendo o eliminando Things mientras estás probando esto.

Los Things se guardan en una lista enlazada y los nuevos Things se añaden en la parte superior de esta lista. Una variable de sistema

sys_thgl equ $b8

apunta a la primera entrada en la lista. El extraño PEEK_L con los dos signos de exclamación lee una palabra larga desde las variables del sistema en un desplazamiento B8 en hexadecimal desde el inicio de dichas variables del sistema.

En lugar de eso puedes escribir en QDOS “ordinario” lo siguiente:

PEEK_L(HEX("280B8"))

La dirección leída desde esta variable es un puntero al primer Thing en la lista de Things. Cada uno de ellos apunta al siguiente, así que es muy fácil rastrear la lista de arriba abajo. La lista termina cuando el siguiente puntero no apunta a un sitio válido, en este caso contiene un 0. Si observas la tabla 1 que está más abajo, verás una explicación de la estructura a la que estos punteros apuntan.

Las tres direcciones siguientes serán llenadas por: la rutina que vincula el Thing en la lista, de esta manera no necesitas preocuparte de ellos cuando se crea un Thing, un puntero que apunta a una lista enlazada de todos los jobs que están usando este Thing en un momento dado, y otro puntero a rutinas que no debería ser tocadas en absoluto. El puntero al Thing en si mismo necesita contener un valor, pero nadie sabe exactamente donde está realmente situado el Thing.

Las siguientes cuatro punteros apuntan a rutinas deben ser suministradas por ti para que hagas lo que quieras cuando el job intenta usarlo, liberarlo o eliminar este Thing específico. Además se puede suministrar una rutina de limpieza (por ejemplo para des-enlazar drivers o eliminar rutinas desde una lista de interrupciones, etc.).

Si el Thing puede solamente ser usado por un job al mismo tiempo, entonces deberías establecer el bit superior de un flag que indica no-compartido (marcado con un “-” en el listado de salida de nuestro programa BASIC).

La omisión de la comprobación del byte se hace para ejecutar una comparación de nombre más rápida. Sin embargo, el ID de la versión (o lista de características) debería ser llenada por el programador.

El programa BASIC lee unos bits muy interesantes de cada una de las entradas de los Thing. En mi ejemplo (tabla 2 otra vez), puedes ver que el último Thing que ha sido añadido al Sistema es “Calculator” (está especificado el último en mi definición HOTKEY en mi programa BOOT). Es interesante ver que “Calculator” no tiene número de versión. QD, que está más abajo, ha sido cargado con LRESPR anteriormente, pero después de QPAC2 (que aparece como un montón de Things likados desde “Button Frame” hasta “Things” …)

Todo lo que está por debajo hasta “HOTKEY” es linkado por el sistema operativo SMSQ/E, esto explica el orden.

En la parte más inferior puedes encontrar un thing especial llamado “THING” que define la entrada al sistema Things, pero esto ya lo he explicado. Verás cómo usarlo en el futuro.

La tabla que muestra la salida de mi sistema después de ejecutar el programa BASIC, en mi caso, el sistema de variables Thing apunta a $C3810, que apunta a $91E30, que apunta a $917C0 … y así hasta $56C10, que apunta a “0”.

Nosotros tenemos también el número de versión de cada Thing. Se corresponde con lo que el programador defina como etiqueta de versión – la mayoría de la gente lo llena con cuatro caracteres ASCII que define la versión-. SBASIC, por ejemplo, tiene como número de versión etiquetas como “HBA”.

También es posible ver en los 4 caracteres que ocupan 32 bits, especifican “características” soportadas por el Thing. Esto significa que no puedes ver realmente una secuencia de caracteres sino una serie de patrones o caracteres extraños. En el ejemplo de la lista de Things de mi sistema lo podrás ver en el Thing llamadao “FileInfo”.

El nombre del thing se reduce a 20 caracteres en caso de ser más largo. Tienes que especificar el nombre correcto del Thing si quieres usarlo o eliminarlo.

Seguramente has notado que la estructura de las lista enlazada de los Things contienen menos información de la que hemos listado, por ejemplo el nombre del Thing no está almacenado en la estructura sino en el Thing en sí mismo (th_thing que apunta al Thing). Hemos hecho alguna trampa por ahora pero léelo desde ahí.

Para terminar el tema, echemos un vistazo a las diversas estructuras para varios tipos posible de Things en las siguientes Tablas. También te muestro el listado del programa Basic que hemos comentado en el artículo y la salida producida en mi sistema.

TABLA 1
-------

; Thing linkage block

th_nxtth  equ $00 ; long link to NeXT THing
th_usage  equ $04 ; long thing' s USAGE list
th_frfre  equ $08 ; long address of "close" routine for FoRced FREe
th_frzap  equ $0c ; long address of "close" routine for FoRced ZAP
th_thing  equ $10 ; long pointer to THING itself
th_use    equ $14 ; long code to USE a thing
th_free   equ $18 ; long code to FREE a thing
th_ffree  equ $1c ; long code to Force FREE a thing
th_remov  equ $20 ; long code to tidy before REMOVing thing
th_nshar  equ $24 ; byte Non-SHAReable Thing if top bit set
th_check  equ $25 ; byte CHECK byte --- set by LTHG
th_verid  equ $26 ; long version ID
th_name   equ $2a ; string name of thing
th.len    equ $2c ;        basic length of thing linkage_

TABLA 2
-------

LINK      VERS S ADDRESS  TYPE NAME
--------  ---- - -------- ---- ---------------------
000C381O       + 000C386E EXEC Calculator
00091E30  2.25 + 00091E62 EXEC Sernet
000917C0  1.30 + 00100BB4 EXEC Pic Viewer
00091760  3.31 + 00100B80 EXEC FileInfo II thread
00091700  3.31 + 0010091C EXTN FileInfo II extensio
000916A0  3.31 + 001008FE DATA FileInfo II history
00091640  FIv3 + 001008E0 DATA FileInfo II database
000915E0  ###0 + 001008BA UTIL FileInfo
00090FE0  1.00 - 000FC2D2 DATA DATAdesign mutex
00091890  3.14 + 000918CE EXTN DATAdesign.engine
0008B970  A.05 + 000E6D22 EXEC QD
0008B920  1.13 + 000DB5B6 EXTN Scrap Extensions
0008B8D0  7.57 + 000D8B1A EXTN Menus
00091320  1.03 + 00091360 UTIL Button Frame
000911F0  1.03 + 000CC6C2 EXTN Button Extensions
000911A0  1.04 + 000CF1BE EXEC Button_Sleep
00091150  1.02 + 000CF168 EXEC Button_Pick
00091100  1.01 + 000CF0B0 EXEC Hotjobs
000910B0  1.01 + 000CF098 EXEC Hotkeys
00091060  1.04 + 000CEE78 EXEC Channels
0008E7D0  1.02 + 000CEA44 EXEC Jobs
0008E780  1.25 + 000CCDB2 EXEC Files
0008E730  1.05 + 000CCAFC EXEC Sysdef
0008E6E0  1.02 + 000CCA26 EXEC Rjob
0008BBD0  1.02 + 000CC928 EXEC Pick
0008BB80  1.02 + 000CC7E6 EXEC Wake
0008BAA0  1.02 + 000CC7CE EXEC Exec
0008BA50  1.02 + 000CC2C6 EXEC Button
0008BA00  1.01 + 000CC068 EXEC Things
000580C0  2.15 + 000B8AD2 EXTN Jmon
0008A910  2.29 + 0008A948 UTIL HOTKEY
0008B4B0  2.05 + 007EAEAE EXTN DEV
0008A1A0  3.00 + 007EAC14 EXTN WIN Control
0008A050  3.08 + 0008A050 UTIL DV3
00089920  2.00 + 007F64E8 EXTN QVME
000898D0  2.09 + 0000AA6E EXTN Ser_Par_Prt
000581F0  2.11 + 0000A91E EXTN KBD
00059250  HBA  + 007F9E9E UTIL SBAS/QD
000591B0  HBA  + 007F9D5C EXEC SBASIC
00056C10  0.05 + 00056C42 VECT THING
  TH_ENTRY 00002FDA
  TH_EXEC  00002F40_

Programa SuperBASIC
-------------------
100 REMark List Things
110 :
120 listptr = PEEK_L( !! $B8)
130 chan = 3 : OPEN #chan, con
140 PRINT #chan;LINK     VERS S ADDRESS  TYPE NAME"
150 REPeat loop
160   IF listptr = 0 THEN EXIT loop
17O   cr_thgaddr = PEEK_L(listptr+$10)
18O   PRINT #chan;HEX$(listptr,32)!
190   IF PEEK_L(listptr+$26)  O
200     PRINT #chan; ! PEEK$(listptr+$26,4)!
210   ELSE
215     PRINT #chan;'     ';
220   END IF
230   PRINT #chan; ! "+-"((PEEK(listptr+$24) > $7F)+1)!
240   PRINT #chan; !HEX$(cr_thgaddr,32);" ";
250   cr_thgtyp = PEEK_L(cr_thgaddr+$4)
260   th_nam$ = PEEK$(listptr+$2C, PEEK_W(listptr+$2A)) : namlen = LEN(th_nam$)
280   IF namlen 2O THEN th_nam$=tt_nam$( TO 20)
320   END IF
330   SELect ON cr_thgtyp
340     =0:PRINT #chan;'UTIL'!th_nam$!
350     =1:PRINT #chan;'EXEC'!tt_nam$!
360     =2:PRINT #chan;'DATA'!th_nam$!
370     =$1000003 : PRINT #chan;'EXTN'!th_nam$!
380     =$1000004 : PRINT #chan;'EXTS'!th_nam$!
390     =-1:PRINT#chan;'VECT'!th_nam$_TH_ENTRY'!HEX$(PEEK_L(cr_thgaddr+$8),32)_TH_EXEC'!HEX$(PEEK_L(cr_thgaddr+$C),32)!
400     =REMAINDER:PRINT #chan;'    ';th_nam$!'UNKNOWN TYPE('!HEX$(cr_thgtyp,32)!') '
410   END SELect
420   PRINT #chan
430   listptr = PEEK_L(listptr)
440 END REPeat loop
450 CLOSE #chan


Artículo reproducido en “The Dilwyn Jones Sinclair QL Pages” con permiso de QL Today Volúmen 4, número 5.
Autor: Jochen Merz.
Traducción y adaptación: afx.