Mantransfer en ROM

Emuladores y aplicaciones que ayudarán a la perpetuación del Spectrum y su software en el futuro

Moderador: Sir Cilve Sinclair

Responder
zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Mantransfer en ROM

Mensaje por zup » Vie Abr 27, 2018 3:34 pm

Al hilo de una discusión con chernandezba, me ha picado la curiosidad de ver cómo de fácil sería adaptar su mantransfer a la ROM del Spectrum. La respuesta es que ha sido bastante fácil, y he creado tres ROMs experimentales que pueden servir para dotar a un Spectrum cualquiera de transfer. No estoy seguro de que me funcionen correctamente el 100% de las ocasiones, pero ahí van:

Las ROMs son las siguientes:
  • mantransfer_v3 - La versión "casi" original. Conserva todas la peculiaridades de mantransfer (como que solo sirve para juegos que usen IM 1, uso de pila y de pantalla, esas cosas).
  • mantransfer_v3i - Esta versión permite transferir juegos independientemente del IM en el que estén y corrige algún bug.
  • mantransfer_v3z - La versión "zuperior". Aquí he mangoneado a mi gusto en la rutina para reducir el uso de la pila y de la pantalla, y creo haber corregido los posibles bugs. Esta es la versión que recomiendo.
Requerimientos de hardware:
- Estas ROMs deberían funcionar en cualquier Spectrum de 48k (incluído el Harlequin).
- El pulsador que dispare la NMI deberá tener algún tipo de antirrebotes.

Instrucciones:
Lo que dice al iniciar el Spectrum: Pulsa NMI y se grabará un snapshot.

Posibles incompatibilidades:
- La rutina está graba a partir de la dirección $3900 de la ROM. Los programas que usen I=$39 para las interrupciones no funcionarán bien (es el mismo problema que dan algunos juegos no compatibles con +2A y +3).
- Al haber modificado la ROM, aquellos juegos que la usen para desencriptar o hagan algún tipo de checksum que incluya la ROM no funcionarán (Ghost'n'goblins o 3 weeks in Paradise 128k lo hacen, pero no he comprobado si fallan).
- En los modelos de 128k no existe el "hueco" que se aprovecha para meter nuestro transfer. Quizás pueda aplicarse el parche (quitando el mensaje de copyright) en las del +2A o +3, pero no estoy seguro.

Cómo conseguir las ROMs:
Puedes descargarlas de este enlace a mediafire. En el paquete se incluyen las tres rutinas en ensamblador para ZX Spin y las tres ROMs ya ensambladas.
Última edición por zup el Jue May 03, 2018 7:32 pm, editado 1 vez en total.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
chernandezba
Sabreman
Mensajes: 408
Registrado: Mié Oct 17, 2007 5:26 pm

Re: Mantransfer en ROM

Mensaje por chernandezba » Jue May 03, 2018 2:06 pm

Gracias por el trabajo que te has pegado y corrigiendo bugs!

He probado las 3 roms, me gusta que aparezca el mensaje de copyright cada uno con un color diferente :)

Ahora podrías mejorarlo mas y hacer que soporte snaps de 128k ;)

Saludos
César
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Mantransfer en ROM

Mensaje por zup » Jue May 03, 2018 7:58 pm

chernandezba escribió:Ahora podrías mejorarlo mas y hacer que soporte snaps de 128k ;)
Imposible sin hardware adicional (o meterme en un embolao gordo).

Me explico... en la ROM del Spectrum de 48k hay un trozo bastante gordo (más de 1K) sin utilizar que está relleno de bytes a 0xFF y ahí es donde he escondido la rutina principal del mantransfer. En los modelos de 128k han metido ahí rutinas para leer el teclado auxiliar y las que ejecutan los comandos SPECTRUM y PLAY (o, como mínimo, la parte que identifica los tokens). En los +2A y +3 parecen haber desaparecido parte de esas rutinas (presumiblemente las del teclado auxiliar) y hay dos huecos que sumarán unos 500 bytes entre los dos.

Opciones:
- Encontrar la manera de desactivar SPECTRUM, PLAY y el teclado auxiliar para hacerme un hueco gordo. El parche funcionaría en todos los modelos de 128k, pero se pierden funcionalidades.
- Hacer solo un parche para las ROMs de los +2A y +3. Aunque hay de sobra en las ROMs adicionales, usarlo es algo más complejo y probablemente requiera corromper más la pantalla.

Si esto fuera hardware real, la respuesta sería paginar nuestra propia ROM sobre la del 128k de manera que no necesitemos empotrar la rutina en la ROM del Spectrum (bueno, salvo quizás unos pocos bytes en la 0x66).

Pensando un poco sobre cómo me gustaría que funcionara la rutina:
- Al pulsar NMI, salva los registros.
- Espera una tecla (1, 4 o 5).
- Si la tecla es 4, graba un snapshot de 48k.
- Si la tecla es 1, debe identificar qué página está ubicada en 0xC000 (para poder restaurarla luego) y grabar toda la memoria.
- Si la tecla es 5, salimos sin grabar nada.

Además de todo ese código, necesitamos espacio para almacenar el cargador (tengo una idea para que sea casi común)... y si puede ser meter todo eso en los 500 bytes para no corromper más la pantalla :shock:

La verdad es que da una pereza...
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
chernandezba
Sabreman
Mensajes: 408
Registrado: Mié Oct 17, 2007 5:26 pm

Re: Mantransfer en ROM

Mensaje por chernandezba » Vie May 04, 2018 9:42 am

Es verdad, no recordaba que ese espacio libre en la rom de 48k no está en los modelos de 128k...
Aunque no imposible, sí que da un perezón absoluto, juasss

Por otra parte, se me ocurre una idea de cómo identificar qué página está mapeada en C000h, ya que el puerto 32765 no es de lectura, sin utilizar hardware adicional, y sin leer la variable de systema 23388 (que no tiene por qué estar actualizada).
El método seria obtener una hash (por ejemplo md5) de la zona mapeada en ese momento C000H-FFFFH, y luego sacar 8 hashes, de las 8 posibles páginas de RAM. Comparando hashes, puedes saber que página estaba mapeada. Lógicamente el método fallará si tienes dos páginas idénticas (por ejemplo conteniendo ceros) pero en ese caso no supondría ningún problema, acabarias mapeando una ram que no era la que estaba, pero el contenido sí que era el mismo. Ahí lo dejo... ;)
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Mantransfer en ROM

Mensaje por zup » Sab May 05, 2018 7:23 pm

Como en muchas otras cosas, MicroHobby también nos puede dar un curso de programación de transfers. En este caso, el que nos interesa es el artículo sobre el Transfer para +3 que modifica el pokeador automático para que funcione en +2A/+3 y además incluye un programa de transfer para 128k (el enlace es a la primera página del artículo, la 42).

En cuanto a los problemas propios de un 128k el principal es "adivinar" la página que está metida. En este caso, el autor hace (más o menos) lo que tú dices: primero suma todos los bytes de la página actual y luego va sumando una por una todas las páginas hasta encontrar una suma que le coincida. La rutina va desde la línea 2480 hasta la 2680, usando la subrutina DETEC (página 44, desde la línea 70 a la 210) para la suma. La suma de 16 bits es más segura, pero también se podría usar una de 8 bits o un XOR para ahorrar algún byte. Aún así, quedan fuera los casos "raros" (modos allram de los +2A/+3).

(Como decías, una forma mejor sería usar una función hash o un CRC... pero creo que complicaría bastante el código además de que la ejecución sería más lenta)

Una vez que sabemos cuál es la página, ya solo nos queda elegir un formato y escribir las rutinas de carga y grabación. En mi caso, usaría un formato parecido a esto:

- BASIC
- CODE de casi todo el loader
- SCREEN$ (incluye última rutina de carga y la de restauración)
- 7 bloques de 16384 bytes con las páginas 0, 1, 2, 3, 4, 6 y 7.
- Bloque de 9472 bytes que incluye las direcciones 23296 a 32767.

El bloque CODE puede ir en cualquier dirección a partir de 24576, siempre que no llegue a 32768 (porque lo sobreescribiríamos al leer la página 2). Este bloque debería cargar el SCREEN$ y los 7 bloques de 32768 (¡siempre con las interrupciones deshabilitadas!*). Al terminar, metemos la página que queremos y saltamos a la rutina de restaurar registros.

En caso de hacer un mantransfer v4, esta rutina sería casi la misma que la del mantransfer v3... simplemente cambiamos el bloque a cargar (desde 23296, con 9472 bytes de longitud) y el resto sigue igual... salvo que quieras enfrentarte al siguiente problema específico de los 128k: los registros del AY.

(En este caso, creo que los registros del AY sí que son de lectura/escritura por lo que incluir una rutina que los grabe y otra que los restaure no es demasiado complicado)

Hacer el programa del transfer no es demasiado complicado, lo jodido es hacerle sitio en la ROM.

La opción más válida es usar un dispositivo que pagine su propia ROM, siendo lo más deseable que se pueda desactivar esa paginación para no comprometer las funciones del spectrum**.

O, si estamos programando un emulador y queremos que suelte snapshots en formato tap, la siguiente opción sería hacer trampa a lo bestia y simular el comportamiento del transfer desde el emulador. Tenemos la ventaja de que conocemos el estado exacto de la CPU, puertos del Spectrum y registros del AY... no tenemos que hacer operaciones raras para averiguar de modo indirecto algo que ya sabemos :) ***

* La rutina de interrupción del Spectrum +3 decrementa un contador en la página 7. Si mal no recuerdo, esto provocó que tuvieran que retocar el cargador del Ninjajar!.

** Si nos ponemos a diseñar hardware, podríamos poner esto en la lista de deseos:
- Que el hardware almacene los últimos bytes enviados a determinados puertos ($FE, $1FFD y $7FFD). Así no hay que hacer el gambas para poder averiguar cómo está la paginación (y podemos soportar los modos all-ram y el color del borde).
- Que el hardware pueda activar/desactivar la paginación de la ROM a voluntad (p.ej.: paginar cuando se pulse NMI y despaginar al hacer un out a un determinado puerto).
- Ponerle algo de RAM que posibilite hacer snapshots sin corromper la pantalla.

*** O también podemos coger el diseño que he descrito antes e incorporarlo al emulador como algo virtual. De nuevo, podemos hacer todas las trampas que queramos... sabemos exactamente el estado de la CPU.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

zx81
Freddy Hardest
Mensajes: 619
Registrado: Vie Dic 28, 2007 2:14 pm
Ubicación: Valencia
Contactar:

Re: Mantransfer en ROM

Mensaje por zx81 » Mié May 09, 2018 4:31 pm

zup escribió: ** Si nos ponemos a diseñar hardware, podríamos poner esto en la lista de deseos:
- Que el hardware almacene los últimos bytes enviados a determinados puertos ($FE, $1FFD y $7FFD). Así no hay que hacer el gambas para poder averiguar cómo está la paginación (y podemos soportar los modos all-ram y el color del borde).
- Que el hardware pueda activar/desactivar la paginación de la ROM a voluntad (p.ej.: paginar cuando se pulse NMI y despaginar al hacer un out a un determinado puerto).
- Ponerle algo de RAM que posibilite hacer snapshots sin corromper la pantalla.
Olvídate de soportar los modos all-ram en la máquina real, eso no lo hace ni el transfer más sofisticado que conozco, el Multiface +3. De hecho, los otros dos puntos que comentas los hace el MF+3, que lleva una ROM de 8K y una RAM de 8K (todos los Multiface tienen eso, salvo el primer modelo de Multiface para el 48k, que no lleva interruptor de desactivación y creo que solo llevaba 2K de RAM).

Por eso, los muy cucos de Opera Soft sacaron las versiones de 128k de algunos de sus juegos usando el modo all-ram, eran imposibles de piratear de esa forma. :D
Debido al fallo de un mecanismo, el lanzagranadas M203 se te podía disparar cuando menos lo esperaras, lo que te habría hecho bastante impopular entre lo que quedara de tu unidad.
Revista del ejército EE.UU. PS, agosto 1993.

Emulador JSpeccy
ZXBaremulator

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 4 invitados