Voy a hacer un spoiler aquí: el parche es una chapuza. Es mi primer experimento y tengo ideas para mejorarlo, pero de momento funciona y así se queda.
Empecemos un poco con los datos básicos sobre el juego. Voy a usar la versión publicada en Microhobby (hay una en WOS algo diferente).
El juego carga en la dirección 28657, y durante su ejecución vemos que el stack anda por debajo de la dirección 28000. Eso nos deja mucha memoria libre para meter rutinas de carga y grabación a disco. Ejecutamos el juego y empezamos a buscar 1366 (punto de entrada a LOAD, otra variante popular es 1378) por toda la memoria. Mala suerte, no están ninguna de las dos.
Probemos con 1218... vale, está en la dirección 30731. Si subimos algo más arriba, vemos que la rutina de grabación de datos empieza en la dirección 30722, y que graba 544 bytes a partir de la dirección 34144. Ya tenemos la rutina de grabación localizada. ¿Cómo localizamos la de carga?
Pues bueno, ya sabemos dónde debería cargar y cuántos datos debería cargar... así que buscamos 34144 ( o podríamos buscar 544, a veces los juegos primero cargan los datos en otra parte y luego los mueven). Después de unos cuantos saltos, aterrizamos en 30764. Poco más abajo hay un call 2050 (que a su vez hace un call 1366, la rutina de carga de la ROM), y si subimos vemos que la rutina de carga empieza a cargar registros en 30761.
Así que mi parche me ha quedado algo así...
Código: Seleccionar todo
dos_open equ 262
dos_close equ 265
dos_abandon equ 268
dos_read equ 274
dos_write equ 277
dos_set1346 equ 319
dos_free_space equ 289
BANK678 equ 23399
BANKM equ 23388
; estas definiciones pueden usarse en otras rutinas
rutload equ 27000
rutsave equ 27100
saveini equ 34144
savelen equ 544
loadini equ 34144
loadlen equ 544
; inicio
org rutload
; paginar DOS
ld a,$07
call paginar ; poner ROM2/RAM7 (configuración para +3DOS)
; abrir fichero
ld bc,$0503
ld de,$0002
ld hl,fichero
call dos_open
jr nc,salir
ld bc,$500
ld hl,loadini
ld de,loadlen
call dos_read ; se lee el bloque
jr nc,salir
cerrar:
ld b,5
call dos_close ; se cierra el fichero
jr nc,salir
salir:
; paginar ROM BASIC
ld a,$10
call paginar
; retornar al BASIC
ccf ;cuidado: en la rutina de disco y en la de cinta, el acarreo significa lo contrario
ret
; rutina de paginación
; necesita la página a establecer en a
paginar:
di
ld bc,32765
ld (BANKM),a ; actualizamos BANKM
out (c),a ; paginamos
ei
ret
; variables
fichero:
; es el nombre del fichero con los datos
db 'FIRFURCI.SAV',$ff
org rutsave
; paginar DOS
ld a,$07
call paginar ; poner ROM2/RAM7 (configuración para +3DOS)
; abrir fichero
ld bc,$0503
ld de,$0203
ld hl,fichero
call dos_open
jr nc,salir2
ld bc,$500
ld hl,saveini
ld de,savelen
call dos_write ; se lee el bloque
jr nc,salir2
ld b,5
call dos_close ; se cierra el fichero
jr nc,salir2
salir2:
; paginar ROM BASIC
ld a,$10
call paginar
; retornar al BASIC
ccf
ret
;parches
org 30722
db 0,0,0,0
db 0,0,0
db 0,0
call rutsave
org 30761
db 0,0
db 0
db 0,0,0,0
db 0,0,0
call rutload
El parche consiste en una rutina de carga y otra de grabación. La de carga abre un fichero y lo carga en las direcciones que hemos averiguado antes. La de grabación crea un fichero (si no existe) y graba los datos. Si hubiera ya un savegame, se renombra a .BAK y graba el nuevo save.
Como tengo memoria de sobra, he puesto una rutina a partir de la dirección 27000 y la otra a partir de la 27100. Una vez parcheado el juego, deberíamos grabar todo a partir de la dirección 27000, y en el cargador BASIC poner un CLEAR en 26999.
Chapuzas/mejoras:
Este parche está hecho como experimento, admite muchas mejoras. Entre ellas:
- Las rutinas de SAVE y LOAD tienen muchos puntos en común, podrían fusionarse entre ellas o poner algunas porciones como subrutinas.
- Queda un hueco bastante gordo entre 27200 y el inicio del CODE, podía haber puesto las rutinas bastante más adelante.
- Hablando de lo cual, una forma elegante (solo para juegos que admitan ejecutarse en modo USR0) de esconder parte del código sería ponerlo en la página 7.
Pensamientos aleatorios:
- Cuando hice mi propia conversión a disco de la Aventura original y Don Quijote, pensé que eran algo chapuceras porque no cargaban o guardaban a disco. Hace poco pegué un repaso y resulta que las versiones que publicó Dinamic en disco tampoco lo hacen.
- He encontrado juegos (Mercenary) que graban y cargan con turbo... a saber cómo lo convierto a algo utilizable.
- Y todavía me falta por encontrar las rutinas de grabación y carga de otras aventuras de Dinamic... pero esto es más fácil.