SITRE

© 1989-2016 por Víctor Parada G.

Introducción

Algunos años atrás, los amigos de Atariware, Retrogames y Retronia me pidieron que liberara un copiador de juegos desde disco a cinta que desarrollé hace muchos años para la plataforma Atari 8-bits. Habiendo accedido a la petición, comencé a revisar mis diskettes (tanto los físicos como los que ya había traspasado a ATR) buscando información al respecto, lo cual no fue fácil, por lo que de a poco fue quedando como tarea pendiente.

Hace un año, en Retronia comenzaron a discutir cómo modificar otro de los copiadores contemporáneos al mío para que fuera capaz de copiar juegos de más de 64K en computadores con ampliación de memoria de 256K, ya que en los años '80 y '90 lo normal era utilizar la memoria extra de los 130XE como buffer para la copia.

La conversación se tornó interesante y me motivó a retomar el tema de la liberación de SITRE, pero con el adicional de dale un segundo aire y modificarlo para poder copiar juegos de más de 64K en computadores Atari 800XL con ampliación de memoria.

Lo que viene a continuación es un resumen de lo publicado en el foro de la comunidad Retronia.

Un Poco de Historia

SITRE es un copiador de juegos de disco a cassette para Atari 8-bits que desarrollé durante el verano de 1989 a pedido de SYFCOM, un negocio de venta de juegos piratas en Viña del Mar. Lo que buscaba era combinar en un único copiador:

Este desarrollo tomó algunas semanas y la paga recibida fue la cassetera XC11 utilizada para el desarrollo y pruebas, y acceso libre a los juegos y demás software existente en el local. Después que desapareció SYFCOM de Viña, le entregué una copia a otro local similar: VCC (Video Compu Club), a cambio de una interface 850 con su módem para teléfono de gancho, un modem XM310, y obviamente acceso libre a los juegos que pasaran por el local.

SITRESYF
SITRE utilizado por SYFCOM
SITREVCC
SITRE utilizado por Video Compu Club

SITRE o S.I.T.R.E. quiere decir "Sistema Inteligente Turbo con Recuperación de Errores", pero en su fase inicial se llamó C.A.T.C.I. o "Cargador Automático Turbo Cassette Inteligente". Era muy feo el nombre original, y lo cambié por otro peor!!!

El desarrollo de SITRE lo realicé en mi 800XL estándar, sin memoria expandida, por lo que la primera versión sólo permitía copiar juegos de unos 24K. Con eso pude hacer todas las pruebas necesarias para poner las pausas de los pitos lentos y ajustar la velocidad máxima de grabación que permitiera hacer cargas sin fallos, y cuando forzaba los errores (por ejemplo presionando suavemente la tecla de pausa en la cassetera), podía retomar la carga retrocediendo la cinta un par de vueltas. Para ajustar los parámetros de grabación, era necesario modificar el S.O. en la ROM del Atari... ¡¿En la ROM?!

La arquitectura de los Atari XL/XE tiene un registro en memoria denominado PORTB, mediante el cual cambiando algunos bits se pueden activar o desactivar algunas ROM y RAM del sistema, haciendo que se pueda acceder a algunos de ellos mediante direcciones de memoria preestablecidas. De esta forma se puede activar y desactivar el lenguaje BASIC, la ROM del S.O., el Self Test, y los distintos bancos de memoria extendida.

Por lo tanto, para modificar el S.O. hay que copiarlo desde la ROM hacia la RAM accesible en el mismo rango de memoria, y luego se retocan los parámetros o rutinas necesarias.

Una vez que el copiador estuvo estabilizado, el siguiente paso fue permitir el uso de bancos de memoria extendida que poseen los 130XE, con lo cual se podían obtener los 64K adicionales, usando el mismo registro PORTB. Después de las pruebas correspondientes, el programa resultante en esta segunda versión fue el que le entregué a SYFCOM.

Todas las rutinas de carga de SITRE estaban programadas en Assembler 6502, ya que es lo requerido para cargar juegos desde cassette (sin BASIC, es decir, con la tecla OPTION presionada además de la tecla START). Sin embargo, el grabador (copiador) estaba escrito en BASIC, ya que ahí es bastante simple controlar el flujo del programa, efectuar la interacción con el usuario, y acceder a DOS para la manipulación de los XEX.

Sin embargo, muchas de las actividades necesarias habrían sido lentas y requerido bastante código en BASIC (ocupando además la escasa memoria disponible), por lo que varias de las acciones fueron programadas en Assembler en modalidad de código relocalizable, y accediéndolas mediante la funcion USR de AtariBASIC. Entre esas rutinas estaban la copia de la ROM hacia la RAM, la lectura del XEX hacia los bancos de memoria y la grabación del XEX en los bloques de cinta, usando los parámetros precalculados como los IRG para pitos lentos.

La primera versión de SITRE para 800XL estándar fue la 1.01 con fecha de cierre en marzo de 1989, y que podía copiar hasta 24K aproximadamente. La versión modificada para trabajar con los bancos del 130XE la denominé 2.01 y tiene fecha de abril del mismo año. Posteriormente hice un esfuerzo para copiar hasta 64K el 800XL pero por etapas, es decir, cargaba un trozo del XEX, grababa en cinta el cargador seguido del trozo de XEX, luego detenía la cinta y cargaba otro trozo en memoria, para luego encender la cinta otra vez y continuar la grabación. Hasta donde recuerdo, no tuve problemas con la grabación, pero durante la carga, al llegar al corte, siempre fallaba la carga debido a basura que quedaba en el GAP. Esa versión fue la 1.11 con fecha de junio del mismo año 1989.

La Versión 2.01 de 1989

Después de 26 años tuve que buscar y revisar de los códigos fuentes de cada componente entre mis viejos diskettes o sus respaldos que alguna vez pasé a PC usando SIO2PC o 1050-2-PC, y encontré la última versión 2 estable de SITRE en BASIC y gran parte de los fuentes de las rutinas en Assembler (MAC/65) incluyendo para la carga desde cinta (empotradas en el copiador en forma de strings). Posteriormente encontré los fuentes de la rutina en assembler que grababa a cinta los bloques del XEX, e incluía los comentarios.

El siguiente es el listado del copiador SITRE 2.01, es decir, la versión para 130XE, y que se usó de base para este proyecto de renovación.

SITRE201.BAS-1
SITRE201.BAS-2

La explicación de qué hace el código y para qué sirve cada variable es:

Cualquier otra variable no descrita es de uso local en la rutina donde aparezca, y puede ser reciclada por otras rutinas.

Como se puede apreciar, las rutinas en assembler son varias y el código en BASIC no es tanto, pero se usa para administrar las USR.

Debo recalcar que ésta era la versión limpia y para uso personal, pues las versiones que entregué a SYFCOM y posteriormente a VCC incluían un poco de código extra para evitar el pirateo del copiador.

Pensando en una Nueva Versión

Han pasado muchos años y la tecnología ha cambiado, pero no solo se ha renovado sino que ha permitido potenciar los "viejos" computadores Atari. También se han visto nuevas versiones de juegos para estos computadores y los románticos de la época vieron que éstos ya ocupaban más de 64K, y que ningún copiador de los que habían recolectado por años les permitía pasar a cinta esos juegos... y SITRE no sería la excepción.

La amena discusión de cómo modificar uno de los copiadores ya liberado me inspiró para modificar SITRE por mi cuenta y permitir usarlo en computadoras con más de 128K.

Para evaluar el cambio, fue necesario tomar en cuenta el diseño de SITRE. Éste se basó en las siguienes definiciones:

El cargador de SITRE consta de 4 bloques que se graban a cinta antes que el XEX:

  1. Boot record: Es un registro de formato estándar que no tiene código a ejecutar, sino que sólo se usa para cargar en memoria los vectores de ejecución de SITRE. Si alguien lee la cinta usando un copiador en BASIC, lo que verá es sólo un mensaje de relleno indicando que se trata de SITRE. Pude haber puesto ahí también el nombre del juego grabado, pero ya no fue.
  2. Registro EOF (falso): En cassette se requiere un bloque extra al final de la grabación. Normalmente ese bloque está vacío, pero en el caso de SITRE va la rutina de inicialización, la cual queda en el buffer de cassette estándar en memoria. Esta rutina realiza la carga de la primera etapa turbo y le pasa el control.
  3. Primera etapa de carga turbo: Este bloque carga en página 6 y ahí está contenida la pantalla de característica de SITRE. Si el XEX que se cargue tiene su propia pantalla de presentación (usualmente son los juegos que requieren pitos lentos), la de SITRE será reemplazada, incluso si carga en la misma página 6. Este bloque tiene además la rutina que carga bloque principal de SITRE.
  4. Segunda etapa turbo: Este bloque entra en página 7 y contiene el cargador de SITRE. Aquí está el código para la carga del XEX, incluyendo las rutinas de carga de bloques, de su validación y reintentos. También contiene la pantalla de reintentos en caso de error y el mensaje "quedan XXX bloques" que se muestra además en la pantalla cargada en la primera etapa; el mensaje va aquí por seguridad, pues si un XEX carga código en página 6, SITRE podría corromper código válido al decrementar el contador.

A continuación van los bloques de XEX, los cuales tienen la siguiente estructura:

Finalmente, en la cinta se graba el registro EOF real, a velocidad normal (no turbo) y que fue simulado en el segundo bloque al grabar. Este bloque no es leído por SITRE, pues la cinta es detenida justo antes para pasarle el control al XEX.

Dado lo anterior, se observa que todos los contadores necesarios son de 8 bits (1 byte), y pueden ser utilizados sin problema en los registros X e Y de la CPU para acceder la memoria (buffers y tablas) en forma indexada.

A primera vista parecía muy simple hacer el cambio, pero observando estas definiciones de diseño, me encuentro con bastante trabajo, principalmente porque los contadores ya no serían de 1 byte, sino que de 2, ya que se requiere utilizar 10 bits para manejar hasta 1024 bloques de 256 bytes (256K). Como se puede apreciar, el impacto es grande... los registros X e Y de la CPU no serán capaces de acceder a tablas completas en forma directa (las tablas ya están a su máxima capacidad y habría que hacerlas crecer) y la manipulación de contadores también requieren al menos el doble de instrucciones en ASM. ¡Y eso está en todos lados!

Viendo las variables que controlo, me di cuenta que nunca se pasa como parámetro el número total de bytes a copiar a las rutinas USR, por lo que no estaría limitado a 64K. Es más, la rutina de grabación tampoco maneja los bancos de memoria, sino que en BASIC se selecciona cada banco y se itera con la llamada a la rutina que lo graba. Los parámetros corresponden a números de bloques y el número de bytes del último bloque de ese tramo. También va la tabla de pitos lentos completa cada vez, pero que fácilmente se puede restringir al segmento asociado a ese banco. De esta forma se puede manejar tablas de más de 256 bytes, pero en segmentos de a 64.

Lo que sí noté es que el copiador está muy ajustado en el uso de la memoria. Cabe justo entre el DOS y el área de memoria de acceso a los bancos, lo que me complicaría un poco agregarle algunos chiches, por lo que pensé en mover algunas cosas a la memoria que está entre los bancos y la pantalla. Ahí hay unos 6K totalmente disponibles para buffers, el loader y demases.

Revisé bastante el código de SITRE, y vi que hay muchas cosas ahora que habría hecho de otra forma. Igual me sorprendí de algunas optimizaciones realizadasy de la forma que resolví problemas.

Entre las cosas curiosas, observé que la lista de bloques con pitos lentos está en orden inverso, para ir de la mano con el contador que se almacenaba en cada bloque. Obvio, si el bloque cero es el último en grabarse. Eso explicaba tanta fórmula en el programa en BASIC. Pero por lo mismo, también me di cuenta que en cada bloque hay un byte que indica el tamaño del bloque, siendo que es constante excepto en el bloque cero, y en la práctica se estaba perdiendo un byte en cada bloque de cinta.

Hasta ese momento, para hacer una versión de 256K había identificado los siguientes cambios:

Renovando SITRE

Dado todo lo anterior, se puede observar que hay una restricción en el tamaño máximo del XEX: 256 bloques por 256 bytes permiten 65.536 bytes (64K). Por lo tanto, para poder cargar XEX de mayor tamaño, se requerió modificar el loader. Pensé en incorporar 1 byte adicional para el contador de bloques en la data del XEX o en reemplazar la funcionalidad del byte del tamaño del bloque (como sólo es relevante en el último bloque, se podíra almacenar por separado junto al loader), pero como quería tocar lo menos posible el código original, me aproveché de las características del álgebra binaria en complemento a 2 y no fue necesario modificar los bloques del XEX. Simplemente comparé un registro de 8 bits con el LSB de uno de 16 bits. Este cambio agregó unos pocos bytes al 4to segmento, pero eso impactó al 3ro, pues se corrieron algunos vectores, lo que de paso afectó al 2do. El 1ro no se salvó porque ahí iba la fecha de la versión de SITRE que tenía el bug Y2K, así que la cambié por la fecha de hoy.

Pero para poder llevar el cargador a cinta, fue necesario modificar el copiador. Mi intensión era modificar lo menos posible y mantener la concepción origina de SITRE, pero creo que debo haber cambiado como un tercio del programa BASIC. Si bien no modifiqué la estructura y conserve el orden, los nombres de las variables y hasta los números de línea, varias cosas debieron ser cambiadas radicalmente.

Detalles técnicos del por qué son los siguientes:

La memoria de un 130XE o un 800XL ampliado tiene más o menos la siguiente estructura:

  1. $0000 - $06FF: casi 2K para registros del HW, de BASIC y de DOS. Algunos bytes en página cero y la página 6 completa pueden ser usados por los programas como SITRE.
  2. $0700 - $1FFF: Poco más 6K utilizados por el DOS. El límite superior es variable y depende de la versión del DOS de turno. Es importante señalar que SITRE es incompatible con cualquier RAMDISK.
  3. $2000 - $3FFF: 8K disponibles para programas en BASIC.
  4. $4000 - $7FFF: Ventana de 16K para acceder a los bancos de memoria extendida. Si el programa en BASIC no va a utilizar directamente los bancos, están completamente disponibles para él.
  5. $8000 - $9FFF: 8K disponibles para programas en BASIC, pero que incluyen la memoria de la pantalla en la parte finaldependiendo del modo gráfico utilizado. En modo de texto se reserva poco más de 1K.
  6. $A000 - $BFFF: 8K correspondientes a la ROM de BASIC.
  7. $C000 - $FFFF: 16K con la ROM del sistema operativo y algunos registros para el control del hardware.

Si no se usan los bancos, un programa BASIC tiene disponibles aproximadamente 8K+16K+8K-1K=31K de memoria contigua.

Un programa en BASIC se estructura de la siguiente forma:

  1. Nombres de las variables.
  2. Valores de las variables numéricas y punteros a los arreglos y cadenas.
  3. Instrucciones del programa (en formato de token).
  4. Valores de las cadenas y los arreglos, dispuestos según el orden de las instrucciones DIM.

Se puede decir que las 3 primeras partes ocupan una cantidad fija de memoria, como por ejemplo cuando el programa se graba en disco, y el área de cadenas (strings) y arreglos y matrices numéricas se asignan dinámicamente cuando el programa se ejecuta, y posteriormente se le asignan valores.

El programa original de SITRE en BASIC incluía todas las rutinas en lenguaje de máquina como asignaciones a cadenas empotradas en el código, incluyendo las 4 etapas del cargador, con la consecuencia que cuando el programa iniciaba, todas ellas quedaban duplicadas en memoria (en el área de código y en el área de valores).

Así, la cantidad de memoria total que utilizaba SITRE era muy cercano al límite de 8K. Para poder grabar más de 64K (256 bloques), era necesario hacer crecer algunos buffers, en particular la tabla para marcar los pitos lentos (64 bytes por cada banco extra), y no era posible crecer sin chocar con la zona para el acceso a los bancos de memoria.

Por lo tanto, el primer paso fue cambiar la forma en que se accedían a las rutinas USR: en lugar de asignarlas a variables de tipo cadena, se cambiaron a variables numéricas, y se les asignó como valor la dirección de la cadena directamente en el área de instrucciones. Es decir:

10 DIM RUTINA$(47)
20 RUTINA$="CARACTERES ATASCII REPRESENTANDO CODIGO BINARIO"
30 U=USR(ADR(RUTINA$),1,2,3)

se cambió por:

20 RUTINA=ADR("CARACTERES ATASCII REPRESENTANDO CODIGO BINARIO")
30 U=USR(RUTINA,1,2,3)

El segundo paso fue mover los buffers que estaban en otras variables de tipo cadena hacia el área de memoria disponible sobre la zona de acceso a los bancos. Ahí hay sobre 6K disponibles para todos ellos, y a la tabla de pitos lentos le asigné tranquilamente 2K.

Ya con memoria suficiente para trabajar en las cosas nuevas, introduje la nueva forma de operar con los bancos. Originalmente utilizaba el mecanismo de usar un valor base para asignar al registro PORTB y a ese sumarle el número del banco a seleccionar, pero ahora utiliza el esquema de valores predefinidos de acuerdo a lo siguiente:

El acceso a la memoria extendida del 130XE y del 800XL modificado se realiza a través de bancos de memoria de 16K cada uno, accesibles a través de una zona fija de memoria ($4000-$7FFF) que es reemplazada por el banco. Para activar un banco específico, se debe modificar algunos bits en el registro de hardware denominado PORTB (dirección de memoria 54017). La combinación de bits requerida para cada banco es la siguiente:

       | POKE  | Banco real | D=0     V=0 E=0         B=0 R=1
 Banco | 54017 | 130XE 256K |  7   6   5   4   3   2   1   0
-------|-------|------------|---------------------------------
   0   |  177  |  RAM   RAM |  1   0   1   1   0   0   0   1
   1   |  161  |   0     4  |  1   0   1   0   0   0   0   1
   2   |  165  |   1     5  |  1   0   1   0   0   1   0   1
   3   |  169  |   2     6  |  1   0   1   0   1   0   0   1
   4   |  173  |   3     7  |  1   0   1   0   1   1   0   1
   5   |  193  |         8  |  1   1   0   0   0   0   0   1
   6   |  197  |         9  |  1   1   0   0   0   1   0   1
   7   |  201  |        10  |  1   1   0   0   1   0   0   1
   8   |  205  |        11  |  1   1   0   0   1   1   0   1
   9   |  225  |        12  |  1   1   1   0   0   0   0   1
  10   |  229  |        13  |  1   1   1   0   0   1   0   1
  11   |  233  |        14  |  1   1   1   0   1   0   0   1
  12   |  237  |        15  |  1   1   1   0   1   1   0   1
-------|-------|------------|---------------------------------
  13   |  129  |         0  |  1   0   0   0   0   0   0   1
  14   |  133  |         1  |  1   0   0   0   0   1   0   1
  15   |  137  |         2  |  1   0   0   0   1   0   0   1
  16   |  141  |         3  |  1   0   0   0   1   1   0   1

En la tabla puse los bancos ordenados de forma que sean compatibles un 130XE y un 800XL con el mod de Claus Bushholz o RAMBO (XL o 320K), en que el banco 0 representa la memoria real, los bancos 1 al 4 a los bancos del 130XE, los 5 al 12 al 800XL con mod, y del 13 al 16 los de RAMBO-320K. Esto se puede extender a 16 valores más para un mod de 512K, en que se repiten los valores anteriores, pero con el bit 7 en cero (se resta 128 a los valores de los bancos 1 al 16 para habilitar del 17 al 32).

Para acceder a cada banco en forma simple, basta asignar un arreglo con los valores establecidos, y usar esos valores para modificar PORTB. En BASIC, sería de la siguiente forma:

1 M=16:DIM B(M+1):FOR I=0 TO M:READ X:B(I)=X:NEXT I
2 DATA 177,161,165,169,173,193,197,201,205,225,229,233,237,129,133,137,141

La variable M indica cuántos bancos se podrían utilizar. El arreglo B tiene los M+1 valores posibles, partiendo de 0 para memoria real hasta el máximo banco M.

Para determinar en forma dinámica cuánta memoria extra dispone el programa, es decir, cuantos bancos están disponibles dependiendo del tipo de computador o modificación, se puede usar el siguiente código que ajusta M al máximo posible:

3 FOR I=M TO 1 STEP -1:POKE 54017,B(I):POKE 16384,B(I):NEXT I
4 FOR I=1 TO M:POKE 54017,B(I):IF PEEK(16384)=B(I) THEN NEXT I
5 IF I<=M THEN M=I-1:POP
6 PRINT M

La línea 3 marca cada banco con un valor individual, y las líneas 4 y 5 determinan cuál es el mayor banco utilizable.
Como consecuencia del cambio para manipular bancos, tuve que cambiar el proceso de carga del XEX, el de análisis para descubrir dónde aplicar pitos lentos y la rutina de grabación de bloques en cinta. Sin embargo, me impresionó lo simple que quedó con el arreglo de valores predefinidos para PORTB. Pero debo hacer notar algo relevante: los valores del arreglo habilitan los respectivos bancos, pero suponen que el bit 1 del registro está encendido, es decir, que está presente la ROM del S.O., lo cual no es siempre cierto en SITRE; cuando se graba en modalidad turbo, se están usando las rutinas modificadas de SIO, por lo que la ROM debe estar desactivada, y en ese caso los bancos se activan con:

POKE 54017,B(I)-1

Como consecuencia del nuevo tamaño de la tabla de pitos lentos, decidí que la rutina utilizara sólo el rango asignado a los bloques de la página que se está grabando, por lo que las marcas ya no se están almacenando en orden invertido como comenté en un post anterior.

En la pasada se fueron a la basura:

Lo que fue quedando pendiente:

Las Pruebas

Al igual que el desarrollo de esta actualización, la mayor parte de las pruebas fueron realizadas utilizando emuladores sobre ambiente Windows. Durante el período de cambios y pruebas, a SITRE le asigné temporalmente el número de versión 2.02.

En el foro me recomendaron probar con Commando, el cual tuve que buscarlo en la red. El primero que encontré es el Commando original, pero es en formato cartucho ROM de 128K... Luego encontré un ATR con el Commando+256K en formato ATR, que si bien contiene un XEX, no está en formato DOS, así que tuve que extraer el XEX... pero me llamó la atención que está modificado respecto del original. Busqué otras alternativas y encontré 2 XEX más, uno para Atari con ampliación de 192K y otro para 320K. Este último es el mismo que el XEX extraído, en tanto que el para 192K se ve idéntico al ROM. Como todos los XEX eran similares en contenido y pesaban casi los mismos 128K, y además tenían los mismos créditos, opté por hacer la prueba con el que era más parecido al ROM. Sin embargo, noté que no pasaría la frontera de los 128K, sino que sólo usaría 506 bloques, por lo que cambié de opción y me pasé al que extraje del ATR, porque ocuparía más de 512 bloques.

Pero como lo necesitaba dentro de un ATR formateado con algún DOS para poder leerlo con SITRE en el emulador atari800-a8cas con ampliación 320K-RAMBO, tuve que crear uno de doble densidad con MyDOS y poner ahí el XEX. Debo mencionar que a la fecha, de estas pruebas, atari800-a8cas era el unico emulador capaz de grabar WAV y CAS.

Esto me sirvió además para probar que SITRE funciona OK en otro DOS (sólo lo había usado en DOS 2.5). Un cambio que hice en SITRE es que ahora valida que no se choque el programa BASIC con la ventana para el acceso a los bancos de memoria extendida, haciéndolo un poco más independiente del DOS o de las extensiones que éste tenga y que le quiten un poco de memoria a BASIC.

El resultado fue el siguiente: SITRE cargó en memoria los 131.588 bytes y realizó el análisis en busca de las pausas para pitos lentos y detectar posibles bloqueos durante la carga. Pasó OK la prueba y encontró varios bloques que requerían pitos lentos (aproximadamente cada 16K, es decir, pareciera ser que carga tramos de 16K directamente en cada banco). En total, se necesitaron 515 bloques en cinta y poco más de media hora de grabación:

SITRE-Commando+256K-01

Inicié el CAS generado en Altirra con ampliación 320-RAMBO, y apareció SITRE:

SITRE-Commando+256K-02

Este era el momento de hacer pruebas con el control de errores en la carga. Como se está utilizando un contador de 8 bits, el número máximo de bloque representado es el 255, por lo tanto existía la posibilidad que mi teroría de complemento a 2 fallara por comparar sólo los LSB (bytes de menor relevancia) en la frontera de los bloques múltiplos de 256, donde se incluye el 512. Así que apenas comenzó la carga, forcé una caída adelantando y retrocediendo repetidamente la cinta en el emulador. Pude comprobar que todo operó bien antes de 512, en los 512 y después de los 512:

SITRE-Commando+256K-03-err1
(antes)
SITRE-Commando+256K-03-err2
(durante)
SITRE-Commando+256K-03-err3
(después)

Mirando esas 3 pantallas, se puede apreciar lo siguiente: entre las pruebas del control de errores hubo un pito lento, y apareció la pantalla de presentación propia del XEX. Como esta rutina cambia el modo gráfico de 40 a 32 caracteres (20 a 16 caracteres en modo 1 y 2), y esa característica no es alterada por SITRE, se provocó el corrimiento de los mensajes. También se ve que el texto cambió de color por el mismo motivo.

La pantalla de carga propia es la siguiente:
SITRE-Commando+256K-04
Transcurridos cerca de los 3 minutos, en otro pito lento, algo hace el loader internamente con lo que va cargado hasta el momento:
SITRE-Commando+256K-05
Después de media hora, el mensaje de la pantalla cambió:
SITRE-Commando+256K-06
Prersionando una tecla comienza el juego:
SITRE-Commando+256K-07
Pantalla de presentación del juego (modificada respecto de la que muestra la ROM):
SITRE-Commando+256K-08
Comienza la acción:
SITRE-Commando+256K-09
No hay caso, para mí es inmanejable sin un joystick... No puedo probar que no esté corrupto intentando pasar niveles:
SITRE-Commando+256K-10
Repetí la prueba, pero emulando un 130XE. Apareció un mensaje diciendo que no había suficiente memoria extendida:
SITRE-Commando+256K-11

Pero no me quedé tranquilo, e hice la prueba con el XEX parq equipos con 192K. También funcionó en forma muy similar (hartos pitos lentos repartidos y un rutina de inicialización con los créditos similares). Pero la pantalla de presentación del juego es la misma del cartucho:

SITRE-Commando-09
"Commando"

No sé si sólo modificaron la imagen y la música de la presentación o si hay algo más, pero se me ocurre que no, ya que en ambos casos los créditos son de Fandal. En la sección de descargas están ambas versiones en formato .CAS con SITRE.

Otra prueba fue grabar el Goonies-130XE de 72.670 bytes en un .CAS usando SITRE modificado en el emulador Atari800-a8cas con 128K de RAM y posteriormente lo cargué en Altirra con 320K. La gracia es que éste puede ser grabado con SITRE en un 130XE, pues de buffer sólo requiere 5 bancos (4 de memoria extendida y 1 de memoria real totalizando 81.920 bytes). Éstos son 18 minutos de grabación y de carga!!!

Grabando:
SITRE-Graba-Goonies130XE
Cargando:
SITRE-Carga-Goonies130XE-1
Después del pito lento, se instala la presentación propia:
SITRE-Carga-Goonies130XE-2
Forzando un error moviendo el control del .CAS un poco más adelante de donde iba:
SITRE-Carga-Goonies130XE-3
Después de rebobinar, la carga finaliza y se inicia el juego:
SITRE-Carga-Goonies130XE-4

En la sección de descargas está el resultado de esta prueba en formato .CAS con SITRE.

Quise hacer una prueba extrema: usar todos los bancos para grabar un XEX. Anteriormente había dicho que restringiría el número máximo de bancos a 13 (lo disponible en los mod de Buchholz y Newell), pero como en el emulador puedo usar 17 bancos (simulando piggyback de memorias con RAMBO-320K), quité la restricción, lo cual me permite grabar hasta 1088 bloques en cinta... eso es 272K de XEX!!! Esto me introdujo 2 problemas ya mencionados: el contador necesita un dígito más, y además necesito encontrar un XEX de más de 256K.

Para el contador utilicé una solución más simple: mantuve los 3 dígitos, pero si hay más de 999 bloques, al primer dígito le pone ":" (dos puntos) representando 2 dígitos... Así, cuando el contador llegue a ":00", bajará a "999" y todo seguirá normal.

En lugar de buscar un XEX tan grande, me hice uno: simplemente tomé el juego Pole Position de 16K y concatené varias veces la data de la ROM y sus punteros, 16 en total, por lo que la data extra y la rutina final de inicialización hacen que se llene parcialmente el 17vo banco. De esta forma, SITRE cargará 16 veces la misma información en el mismo lugar, pero lo que interesa es que parta, ¿no? Eso además me obligó a crear un disco ATR bastante grande usando MYDOS...

Así se ve el copiador de SITRE en el emulador atari800-a8cas:

sitre-pole256k-0

En el .CAS se grabaron 262.493 bytes (1026 bloques) y efectivamente tomó más de una hora grabarlo (no se puede usar el SIO-Patch porque anula las modificaciones que hace SITRE en la ROM).

Al darle el doble clic al archivo resultante, Altirra responde así:
sitre-pole256k-1
En la captura anterior ya había avanzado un poco la carga, y un momento después, cuando bajó de 1000 bloques, se vió así:
sitre-pole256k-2

Cuando quedaban 2 bloques, se activó la rutina de inicialización que apagó la pantalla y cuando SITRE terminó de cargar, apareció el juego:

sitre-pole256k-3
sitre-pole256k-4

En la sección de descargas está el .CAS de esta prueba.

También hice una versión del XEX de 192K + adicionales (sólo 12 copias del juego) para probar los 13 bancos en el Atari real con la expansión Newell original:

Imagen

Como se puede ver, el XEX pesaba 196.933 bytes, y en cassette serían 770 bloques, con un tiempo de grabación de 47 minutos y medio... ¡¡¡Auch!!! Busqué entre mis cassettes, y sólo encontré un par de 90 minutos (45 minutos por lado), y los demás eran de 60 minutos (30 por lado):

Imagen

En esas condiciones no quise probar si cabía en una de las cintas de 45 por lado... 2 minutos y medio extra creo que son muchos y tenía altas posibilidades de quedar truncado y por lo tanto fallar. Sin embargo dejé que SITRE grabara algunos bloques en el aire sólo para escuchar los pitos reales por el parlante de la tele y con eso di por cerradas las pruebas relativas al manejo de bancos.

Durante estas pruebas se fueron completando los pendientes, y eso incluyó la transformación de la rutina para identificar bancos disponibles desde BASIC a Assembler, la incorporación de una rutina en assembler para inicializar memoria (usado para limpiar la tabla de pitos lentos y rellenar el último bloque con el saldo del XEX), y la posibilidad de utilizar varias disketeras y además desplegar su contenido.

La versión final 3.02 de 2015

Después de todo lo discutido en Retronia durante 5 semanas y aquí expuesto, al 29 de marzo de 2015, SITRE evolucionó para soportar más de 4 bancos de 16K, permitiendo grabar desde 1 hasta 17 bancos dependiendo del tipo de expansión de memoria reconocido entre 130XE, 800XL con Buchholz, Rambo/XL, Rambo320K, Newell, Newell modificado e incluso ninguna. Esto es, desde 16K hasta 208K!!!

Esta nueva versión del copiador SITRE es la 3.02, y se ve así:

SITRE302.BAS-1
SITRE302.BAS-2
SITRE302.BAS-3

La explicación de qué hace el código y para qué sirve cada variable es:

Al igual que en la verión 2.01, cualquier otra variable no descrita es de uso local en la rutina donde aparezca, y puede ser reciclada por otras rutinas.

Si se comparan las descripciones, no hay mucha diferencia en la estructura del programa BASIC entre las versiones 2.01 y 3.02. Los mayores cambios que se pueden apreciar son:

Descargas

SITRE es © Copyright de Víctor Parada, y puede ser utilizado libremente, pero no redistribuido si es que es modificado de alguna forma.

SITRE201.BAS
SITRE versión 2.01 de 1989 para 130XE (128K).
SITRE302.BAS
SITRE versión 3.02 de 2015 para 130XE y 800XL (de 64K a 320K).
SITRE.ATR
Disco con MyDOS y ambas versiones de SITRE listas para usar.
commando256k.cas
Imagen .CAS de Commando+256K para ser jugado en computadores con 256K de RAM.
commando.cas
Imagen .CAS de Commando para computadores con 192K.
goonies.cas
Imagen .CAS del juego Goonies para 130XE.
pole256k.cas
Imagen .CAS de juego Pole Position de 16K concatenado 16 veces.

Debo hacer notar que SITRE debe ser utilizado con AtariBASIC, es decir, con el BASIC que traen los computadores Atari XL y XE. No se debe utilizar en TurboBASIC XL, ya que la disposición de la memoria será distinta a la esperada al momento de iniciar SITRE. La RAM bajo la ROM es utilizada por este intérprete de BASIC, la que será destruída por SITRE cuando copie la ROM para ser modificada y alterar parámetros de grabación.


© 2016 por Víctor Parada G. (++Vitoco) - 2016-02-22