Espiando transfers
Publicado: Sab Feb 04, 2017 4:48 pm
He estado echando una ojeada a algunos juegos copiados con transfer (había unos cuantos en los tzx de ralphy), con vistas de hacer una utilidad que convierta snapshots a tap (¿para qué inventar el proceso de carga si puedo copiarlo?). Por el camino, he encontrado cosas curiosas.
Los que he mirado son:
Algunas características:
Corrupción de pantalla: Transtape corrompe tres líneas de la pantalla, pero como lo hace en líneas contiguas el efecto son tres rayas bastante visibles. Phoenix es más discreto, corrompiendo solo las dos líneas superiores y su primo Dynamid se cepilla tanto las dos líneas superiores como las inferiores. El Pokeador es más "cacharrero", corrompiendo líneas por todas partes. En cuanto al Multiface... no dudo que sea un buen transfer, pero es que corrompe todo un tercio de la pantalla. Specmate se aparta de la tónica general ya que es muy flexible: nos deja elegir qué zona de la pantalla corromper (podemos elegir una que se refresque frecuentemente y así no tener basurilla en pantalla) y además podemos elegir entre incorporar la pantalla de carga original, utilizar solo la del snapshot o no incluir ninguna (pensándolo bien, esta última opción es la más destrozona de todas).
Gestión de interrupciones: El menos respetuoso es el Pokeador. Si I=63, pone el modo IM1 y si es cualquier otro valor el modo IM2. Esto podría llevar a algunas incompatiblidades. Transtape guarda IM y el estado de las interrupciones en un byte, y tiene una rutina para descifrarlo (solo preserva IM1/IM2), mientras que Phoenix/Dinamid 3/LMA y Specmate meten el IM y la habilitación como instrucciones (en vez de almacenarlo en un byte y decodificarlo como Pokeador y Transtape). Esto es más compacto y ocupa menos en pantalla, y además hace que puedan preservar algo tan raro como IM0 (dudo mucho que el hardware original detecte IM0 o que esto sea de utilidad en un juego).
La pila: Excepto el Specmate (que necesita 12 bytes de la pila en todos sus modos), los demás interfaces sólo necesitan 2 bytes de la pila para hacer su trabajo.
Borde: Me ha parecido curioso que el único transfer que guarda el borde explícitamente (y probablemente podría guardar todo el estado del puerto 254) es el Transtape. Ninguno de los demás incluye instrucciones para restaurar el borde, lo que me lleva a pensar que confían en que el valor de BORDCR sea el correcto.
Carga y compresión: Transtape y Pokeador automático guardan el programa al completo (ojo: el programa original del Pokeador Automático no guarda el último byte de la memoria). Phoenix/Dinamid 3 "recortan" el final de uno de los bloques, de manera que si la RAM está llena de ceros (porque el programa no llene toda la RAM) pueden ahorrar cinta (LMA además puede recortarlo por el principio). Multiface 1 parece necesitar menos espacio, pero no sé si comprime datos, los recorta o qué hace exactamente. Specmate puede tanto ahorrar cinta (si no incorporas ninguna pantalla) como desperdiciarlas (si incorporas la pantalla de carga original).
Formatos de carga:
Transtape:
- Bloque BASIC.
- Bloque CODE 16384,75 (rutina para cargar el programa y restaurar los registros).
- Bloque sin cabecera, inicio en 16484 y longitud 49052. Los primeros bytes son el estado de la máquina. Se carga con la rutina de la ROM.
Phoenix:
- Bloque BASIC.
- Bloque CODE 64000,354 (contiene el cargador, creo que tiene rutinas de carga a velocidad estándar y turbo).
- Bloque headerless, inicio en 16384 y longitud 9216. Creo que puede ser turbo.
- Bloque headerless, inicio en 25600 y longitud máxima 38400. El bloque puede "recortarse" si la RAM contiene ceros. La longitud de este bloque está en la dirección 16644, y creo que también podría ser turbo.
- Bloque headerless, inicio en 64000 y longitud 1536. Carga con la rutina de la ROM.
Dynamid 3:
- Bloque BASIC.
- Bloque SCREEN$.
- Bloque headerless, inicio en 23296 y longitud 9216. Carga con la rutina de la ROM.
- Bloque headerless, inicio en 25600 y longitud máxima 38400. El bloque puede "recortarse" si la RAM contiene ceros. La longitud de este bloque está en la dirección 16644. Carga con la rutina de la ROM.
- Bloque headerless, inicio en 64000 y longitud 1536. Carga con la rutina de la ROM.
(NOTA: La descripción de los dos últimos bloques es muy similar a la del Phoenix, aunque debido a que Dynamid NO usa el área a partir de 64000, podría cargar esos dos últimos bloques en uno solo)
Pokeador automático (Transfer, MH144):
- Bloque BASIC.
- Bloque SCREEN$.
- Bloque headerless, inicio en 23296 y longitud 42239 (o 42240 si usa la versión corregida).
Pokeador automático (Transpoke, MH179):
- Bloque BASIC
- Bloque headerless, inicio en 16384 y longitud 24576
- Bloque headerless, inicio en 40959 y longitud 24577 (si la primera versión tenía un bug que no guardaba toda la memoria, esta versión guarda un byte dos veces)
Specmate (sin pantallas):
- Bloque BASIC.
- Bloque headerless, inicio 18432 y longitud 288 (rutina cargador y de arranque)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 23296 y longitud 1704
Specmate (con una pantalla pantalla):
- Bloque BASIC.
- Bloque headerless, inicio 16384 y longitud 6916 (pantalla del snapshot)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 23296 y longitud 1704
Specmate (con dos pantallas):
- Bloque BASIC.
- Bloque headerless, inicio 16384 y longitud 6912 (pantalla de carga original)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 16384 y longitud 6916 (pantalla de carga del snapshot)
- Bloque headerless, inicio 23296 y longitud 1704
Disciple (en realidad, esto viene de una utilidad publicada en MH167 que permite pasar snapshots de Disciple a cinta):
- Bloque BASIC
- Bloque headerless, inicio 16384 y longitud 15300
- Bloque headerless, inicio 31864 y longitud 33852
He recopilado todos estos datos en una hoja de cálculo que se puede consultar aquí.
Los que he mirado son:
- Transtape
- Phoenix
- Dinamid 3
- "La máquina alucinante" (a partir de aquí, LMA)
- Pokeador automático (Transfer publicado en MH144 y corregido en 147). Hay otros dos programas de transfer para el pokeador automático (Transpoke, MH179 y Transfer para +3, MH191) que no he probado.
- Specmate
- Multiface 1 (este no lo he mirado demasiado)
Algunas características:
Corrupción de pantalla: Transtape corrompe tres líneas de la pantalla, pero como lo hace en líneas contiguas el efecto son tres rayas bastante visibles. Phoenix es más discreto, corrompiendo solo las dos líneas superiores y su primo Dynamid se cepilla tanto las dos líneas superiores como las inferiores. El Pokeador es más "cacharrero", corrompiendo líneas por todas partes. En cuanto al Multiface... no dudo que sea un buen transfer, pero es que corrompe todo un tercio de la pantalla. Specmate se aparta de la tónica general ya que es muy flexible: nos deja elegir qué zona de la pantalla corromper (podemos elegir una que se refresque frecuentemente y así no tener basurilla en pantalla) y además podemos elegir entre incorporar la pantalla de carga original, utilizar solo la del snapshot o no incluir ninguna (pensándolo bien, esta última opción es la más destrozona de todas).
Gestión de interrupciones: El menos respetuoso es el Pokeador. Si I=63, pone el modo IM1 y si es cualquier otro valor el modo IM2. Esto podría llevar a algunas incompatiblidades. Transtape guarda IM y el estado de las interrupciones en un byte, y tiene una rutina para descifrarlo (solo preserva IM1/IM2), mientras que Phoenix/Dinamid 3/LMA y Specmate meten el IM y la habilitación como instrucciones (en vez de almacenarlo en un byte y decodificarlo como Pokeador y Transtape). Esto es más compacto y ocupa menos en pantalla, y además hace que puedan preservar algo tan raro como IM0 (dudo mucho que el hardware original detecte IM0 o que esto sea de utilidad en un juego).
La pila: Excepto el Specmate (que necesita 12 bytes de la pila en todos sus modos), los demás interfaces sólo necesitan 2 bytes de la pila para hacer su trabajo.
Borde: Me ha parecido curioso que el único transfer que guarda el borde explícitamente (y probablemente podría guardar todo el estado del puerto 254) es el Transtape. Ninguno de los demás incluye instrucciones para restaurar el borde, lo que me lleva a pensar que confían en que el valor de BORDCR sea el correcto.
Carga y compresión: Transtape y Pokeador automático guardan el programa al completo (ojo: el programa original del Pokeador Automático no guarda el último byte de la memoria). Phoenix/Dinamid 3 "recortan" el final de uno de los bloques, de manera que si la RAM está llena de ceros (porque el programa no llene toda la RAM) pueden ahorrar cinta (LMA además puede recortarlo por el principio). Multiface 1 parece necesitar menos espacio, pero no sé si comprime datos, los recorta o qué hace exactamente. Specmate puede tanto ahorrar cinta (si no incorporas ninguna pantalla) como desperdiciarlas (si incorporas la pantalla de carga original).
Formatos de carga:
Transtape:
- Bloque BASIC.
- Bloque CODE 16384,75 (rutina para cargar el programa y restaurar los registros).
- Bloque sin cabecera, inicio en 16484 y longitud 49052. Los primeros bytes son el estado de la máquina. Se carga con la rutina de la ROM.
Phoenix:
- Bloque BASIC.
- Bloque CODE 64000,354 (contiene el cargador, creo que tiene rutinas de carga a velocidad estándar y turbo).
- Bloque headerless, inicio en 16384 y longitud 9216. Creo que puede ser turbo.
- Bloque headerless, inicio en 25600 y longitud máxima 38400. El bloque puede "recortarse" si la RAM contiene ceros. La longitud de este bloque está en la dirección 16644, y creo que también podría ser turbo.
- Bloque headerless, inicio en 64000 y longitud 1536. Carga con la rutina de la ROM.
Dynamid 3:
- Bloque BASIC.
- Bloque SCREEN$.
- Bloque headerless, inicio en 23296 y longitud 9216. Carga con la rutina de la ROM.
- Bloque headerless, inicio en 25600 y longitud máxima 38400. El bloque puede "recortarse" si la RAM contiene ceros. La longitud de este bloque está en la dirección 16644. Carga con la rutina de la ROM.
- Bloque headerless, inicio en 64000 y longitud 1536. Carga con la rutina de la ROM.
(NOTA: La descripción de los dos últimos bloques es muy similar a la del Phoenix, aunque debido a que Dynamid NO usa el área a partir de 64000, podría cargar esos dos últimos bloques en uno solo)
Pokeador automático (Transfer, MH144):
- Bloque BASIC.
- Bloque SCREEN$.
- Bloque headerless, inicio en 23296 y longitud 42239 (o 42240 si usa la versión corregida).
Pokeador automático (Transpoke, MH179):
- Bloque BASIC
- Bloque headerless, inicio en 16384 y longitud 24576
- Bloque headerless, inicio en 40959 y longitud 24577 (si la primera versión tenía un bug que no guardaba toda la memoria, esta versión guarda un byte dos veces)
Specmate (sin pantallas):
- Bloque BASIC.
- Bloque headerless, inicio 18432 y longitud 288 (rutina cargador y de arranque)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 23296 y longitud 1704
Specmate (con una pantalla pantalla):
- Bloque BASIC.
- Bloque headerless, inicio 16384 y longitud 6916 (pantalla del snapshot)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 23296 y longitud 1704
Specmate (con dos pantallas):
- Bloque BASIC.
- Bloque headerless, inicio 16384 y longitud 6912 (pantalla de carga original)
- Bloque headerless, inicio 25000 y longitud 20000
- Bloque headerless, inicio 45000 y longitud 20536
- Bloque headerless, inicio 16384 y longitud 6916 (pantalla de carga del snapshot)
- Bloque headerless, inicio 23296 y longitud 1704
Disciple (en realidad, esto viene de una utilidad publicada en MH167 que permite pasar snapshots de Disciple a cinta):
- Bloque BASIC
- Bloque headerless, inicio 16384 y longitud 15300
- Bloque headerless, inicio 31864 y longitud 33852
He recopilado todos estos datos en una hoja de cálculo que se puede consultar aquí.