DESENSAMBLADO
Para intentar reproducir de forma fiel el funcionamiento del juego intentaré reproducir la ejecución
en el mismo orden y timing que el original de spectrum. Para ello he comenzado el proceso de desensamblado
del original de spectrum y estoy analizando el codigo para sacar toda la información posible de él.
Estoy usando el IDA free 4.1 para este cometido y de momento llevo un 30-40% del programa analizado con bastantes
buenos resultados.
En breve añadiré a la web el código desensamblado para aquellos que tengan interés e iré comentando el proceso de
desensamblado (que puede ser mejor o peor... pero que a mi ya me sirve) que he seguido.
EL CARGADOR BASIC
El cargador BASIC es el bloque PROGRAM de una carga, para obetenerlo podemos parar la
carga con un BREAK de usuario tras cargar el primer bloque. El del HUNDRA es el siguiente:
10 BORDER NOT PI; PAPER NOT PI ; POKE 23624,NOT PI ; CLEAR 24398
15 PRINT AT 21,NOT PI; INK 7; PAPER 2; "DINAMIC PRESENTA.........."; FLASH 1; "HUNDRA"
20 PRINT AT NOT PI,NOT PI; LOAD "" SCREEN$; BORDER 6
30 LET a = PEEK 23633 + 256 * PEEK 23634; LET b = PEEK a; POKE a,111
40 LOAD "" CODE
50 POKE a,b: PRINT USR 65436
Del cargador BASIC podemos obener siempre información importante... En nuestro caso
nos interesa saber que el codigo va a situarse a partir de 24398 y que nuestro
punto de entrada está en 65436 una vez terminada la carga. El pokeado en la
direccion apuntada por 23634/33 se ocupa de modificar la rutina de OUTPUT del canal
de datos actual, en este caso se usa para deshabilitar el echo en pantalla... se cambia
la dirección de la rutina de ROM PRINT-OUT (09F4) por un punto de entrada en la rom con
un RET (096F). Al acabar la carga se rehabilita la direccion correcta... así se evita
que el texto de carga del bloque "machaque" la pantalla de carga.
EL CODIGO BLOQUE A BLOQUE
A partir de este punto ire añadiendo cada bloque de código y comentandolo para que
sirva como referencia a cualquiera que le pueda interesa... adicionalmente, cuando
el desensamblado esté terminado, añadire un fichero para descarga con todo el código
de una pieza.
ENTRY_POINT : |
FF9C | di | ; Deshabilitar interrupciones |
| ld sp, 0FFFFh | ; Vaciar la pila |
| ld hl, 8B7Dh | |
| push hl | ; Guardamos una direccion en la pila |
| ld a, (unk_0_5B10) | ; 04h |
| dec a | |
| jp z, CARGAR | |
| ld hl, 1B8h | |
| ld (unk_0_84DE), hl | |
| ld hl, 76Eh | |
| ld (loc_0_8506+1), hl | |
| xor a | |
| ld (unk_0_84FA), a | |
| ld (unk_0_8521), a | |
CARGAR: |
FFBE | ld hl, 5F4Fh | |
| ld de, 5B00h | ; Buffer de impresora |
| ld bc, 0A04Ch | |
| ldir | |
| ret | ; RET: Coge el valor de la cima de la pila y salta |
Comentarios
Bueno, este es el punto de entrada del juego... inicialmente se vacia la pila, se guarda la dirección 8b7dh que
usaremos como punto de retorno para esta función y se hacen algunas operaciones básicas... en las uqe estoy trabajando para
ver exactamente que hacen (me huele a que el byte que se lee en 5b10 identifica el tipo de spectrum o la existencia de algun
periférico concreto como el microdrive/interface I ... lo unico que tengo claro es que
cae en la zona de las rutinas de paginación de la impresora en la rom del Sp. 128...
Después se vuelca sobre la zona de memoria del buffer de impresora (5B00) un bloque de 2ks que aun no se que contiene. :/
INTRO: |
8B7D | di | |
| call sub_0_F700 | |
ESPERA_TECLA: |
8B81 | di | |
| call sub_0_F747 | ; Controlando la m£sica |
| xor a | |
| di | |
| in a, (0FEh) | ; Comprobar cualquier tecla |
| cpl | |
| and 1Fh | |
| jp z, ESPERA_TECLA | ; No hay teclas pulsadas |
Comentarios
Esta es la intro del juego... el borde se queda en amarillo, se reproduce en un bucle infinito la música y
se espera una pulsación de tecla. Para ello se hace una lectura combinada de todas las semifilas: para ello
ponemos A a 0 y leemos el puerto de teclado 0FEh. si alguna tecla de alguna semifila esta pulsada uno de los
5 bits de menor peso estará a 0... se hace el complemento (CPL) para negar todos los bits, enmascaramos a los
bits de interés y si A es 0 es que no se ha pulsado ninguna tecla.
Comentarios
Esta rutina se ocupa de renderizar el menú de opciones y gestionarlo... todo el control
interno se hace desde la rutina BLIT_MENU y la rutina de interrupcion en modo IM2.
CREA_TABLA_DIRECCIONES_IM2: |
83F1 | ld a, 0FEh | |
| ld i, a | ; Inicializar vector de interrupción |
| ld bc, 100h | ; La tabla tendra 127 valores |
| ld h, a | |
| ld l, c | HL -> FE00 |
| ld d, a | |
| ld e, b | DE -> FE01 |
| ld (hl), 80h | Valor a copiar 80h |
| ldir | |
| im 2 | Activar USER INTERRUPT MODE |
| ret | |
Comentarios
Esta función genera la tabla de 127 entradas que permite asegurar que la direcci¢n
del Vector de Interrupci¢n (apuntado por I) es correcta, en este caso se usa
la direcci¢n 8080 (múltiplo de 127). Esta necesidad deriva de que algunos dispositivos
no cogen la dirección de I*256+FF para guardar la dirección de la rutina de interrupciones y
por tanto se asegura que cayendo en el byte que caiga la lectura la dirección es la misma, en
nuestro caso 8080h.
|
|