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.
search for audio clips, good porn, tanned ass pussy, lesbians in the shower, paris hilton smoking, free xxx long movies, bondage sex toys, forced birth control, petite ass, studs masturbating, girls squirting while fucking sex machines, moms fucking son, national zoo panda cam, throat, puss in boots costume, bestiality dvds, circle jerk videos, celeb fake galleries, gay trans, cheerleader skirts, free handjob stories, amateur allure elizabeth, anal fisting fisting, gay escorts, bikini nude babes, gay male galleries, lesbian dildo domination, milf anal sex hot swallow slut, housewife rape, holy melon dog mad at foot, anal redheads, jenna haze facial, hairy female armpits, ebony shemales, big dildo penetrations, big boobs, chubby masturbate, nude gay office men, ashton-drake little bo peep, nude final fantasy, blonde lesbian, celebs missing their panties, japanese schoolgirl nudes, football youth cams for 00, celebrety nude movies, new movie clips, free, children naked, latin teen pics, free private voyeur pics, face jizz shower, white spots on throat, small secretary desk, sex on the beach drink, animal xxx, adult stars, logo retro, women fucking men with dildos, hot tanned girls naked, blowjob videos, free stocking porn, black cumshots, ebony young girls, boob implants, porn stars ebony porn, teen outdoors, huge female nipples, double penetration wmv, spanking online, wet blondes, soft speculum, mouth cock, hot black bitches, wife sucking cock, lesbian housewives dildos, my friends hot mom mrs. devine, lesbian toon porn, pyrex sex toys, mature sluts, vietnamese gang, dirt bike boots, sexy legs, sapphic erotica passwords, zits vagina, ultimate zoo, bbw registry, faye valentine hentai, boob sex, jizz lovers, scat sluts, extreme film, rape me- nirvana, doctor nude office, naked military men, fox-trot uniform charlie kilo bloodhound gang, adult xxx dvd, cock enormous free pic, reality porn finder, quit smoking drugs, polish tits, bdsm slave collars, free online retro game, cum anal ffm, home sex toy party, duct tape bondage, hot mom naked, oral cancer, spanking personals, outdoor swing, hardcore cheerleaders, large cock trans, bubble butts male, horny teen, hardcore brunette, secretary fucks, fat gaining chicks, dad raping daughter, bisexual swinger couple orgy, male orgasm techniques, hidden camera upskirt, puss in boots costume, open speculum, hot showers, peeing in public, erotic youth, teen peep show, teen twink, fuck wife, monsters of cock, tara reid nipple, teens wearing thongs, big saint sylvia, xxx dvds, deep dog penetrations, teen outdoor stripping, hot brunette slut, mentor silicone breast implant, paparazzi image, young russian lingerie models, chubby big tits, second hand smoking, honda crx engine swap, shemale erection, anal fucking, 15 weeks pregnant, movie password rimjob, pornstar stockings, teen face, voyeur mpeg, cd extreme, dad sucking son, blonde girls, brazil teens, schoolgirl asians, beach boobs, free scat sex, vagina preg, multiple orgasm, spanking bench, giving oral, celeb lesbian kiss, pornstars, nude toon, shaved nuts, live and let die, skinny, pregnant babes, ebony orgy, asain youth gangs, bbw spanking, wholesale cz stud earrings, pissing and fisting hardcore dvd or vhs for sale, hot moms in lingerie, chubby ladies, ethniorn stars, zoo sex free, celebrety cruses, bikini shave, teens in uniform, asshole rimming, facial shots, legs pantyhose, brazilian chicks, adult party favors, bang bus gang, links extreme game, long sexy boots, girl masturbation instructions, young virgins girls virgin girls, double anal triple penetration, spanking women, schoolgirls nude, quit smoking hypnosis houston, nine inch nail canadian concerts dates, mean bitch, mature masturbation, blowjob secretary, free teen gallery, ass galleries, woman having a orgasm, cum on her face tina, gay latin, gay military boys, silicone dick, asian nude, hot asian maids, extreme life styles, shemales asshole stretched lubricated moaned, vagina look normal, asians in nylons pantyhose, free incest message boards, gay cartoon porn, schoolgirl anime, big boys toys, gigantic breasted toons, free amateur voyeur galleries, perfect tits contest, free dirty housewives, men having sex with animals, hairy ass, private amateur videos, nipple clips, sexy halloween costumes, anime fuck, massive dick, heidi klum naked, free sex video, brazil xxx twins, huge clit pics, free horse cock dildo penetration videos, picture of hand painted nail art, indian butt, closeup blowjob, ebony hentai, local dating, cum on clothes, bikini fuck, paris hilton porn video, flexible sluts, butt pictures
| BLIT_MENU: |
| 87A5 | call CLEAR_SCREEN | |
| ld hl, 0EB00h | |
| ld de, 0EB01h | |
| ld bc, 2FFh | |
| ld (hl), l | |
| ldir | |
| call DIBUJA_LOGO | |
| jp ESCRIBIR_TEXTOS_MENU | |
| |
| ESCRIBIR_TEXTOS_MENU: |
| 87F2 | ld de, TEXTO_KEYS | |
| call ESCRIBIR_CADENA | ; Escribe texto teclado |
| ld de, TEXTO_KEMPSTON | |
| call ESCRIBIR_CADENA | ; Escribe texto kempston |
| ld de, TEXTO_DEFINE | |
| call ESCRIBIR_CADENA | ; Escribe texto redefinir |
| ld de, TEXTO_COLOR | |
| call ESCRIBIR_CADENA | ; Escribe texto color on-off |
| ld de, TEXTO_START | |
| call ESCRIBIR_CADENA | ; Escribe texto start |
| ld de, TEXTO_CREDITS_1 | |
| call ESCRIBIR_CADENA | ; Escribe primera línea de créditos |
| ld de, TEXTO_CREDITS_2 | |
| call ESCRIBIR_CADENA | ; Escribe segunda línea de créditos |
| ld de, TEXTO_CREDITS_3 | |
| call ESCRIBIR_CADENA | ; Escribe tercera línea de créditos |
| ld de, TEXTO_CREDITS_4 | |
| call ESCRIBIR_CADENA | ; Escribe cuarta línea de créditos |
| ld de, TEXTO_CREDITS_5 | |
| call ESCRIBIR_CADENA | ; Escribe quinta línea de créditos |
| ld hl, 4C09h | |
| ld a, 5Dh | |
| ld c, 0 | |
| call DIBUJAR_CARACTER_TEXTO_8X8 | |
| ld hl, 44C9h | |
| ld a, 5Dh | |
| ld c, 0 | |
| call DIBUJAR_CARACTER_TEXTO_8X8 | |
| ld hl, 4489h | |
| ld a, 5Dh | |
| ld c, 0 | |
| call DIBUJAR_CARACTER_TEXTO_8X8 | |
| ei | |
| halt | |
| ld hl, 0EB00h | |
| ld de, 5800h | |
| ld bc, 300h | |
| ldir | |
| ld a, 1Ah | |
| ld (CONTADOR_BLINK), a | |
| ld a, 1 | |
| ld (EMPEZAR), a | |
| xor a | |
| ld (ALTERAR_ESTADO_COLOR), a | |
| call ACTUALIZAR_FLECHA | |
| ESPERA_TECLA_MENU: |
| 886A | xor a | |
| ei | |
| in a, (0FEh) | ; Leemos combinado de todas las semifilas |
| cpl | Negar los bits |
| and 1Fh | |
| jp nz, ESPERA_TECLA_MENU | |
| COMPRUEBA_TECLAS_MENU: |
| 8874 | ld a, 0EFh | |
| ei | |
| in a, (0FEh) | ; Comprobar semifila 6-0 |
| rra | |
| jp nc, EMPEZAR_PARTIDA | ; Comprobar 0 pulsado |
| ld a, 0F7h | |
| ei | |
| in a, (0FEh) | ; Comprobar semifila 5-1 |
| and 0Fh | |
| cp 0Eh | |
| call z, SELECT_KEYBOARD | ; Comprobar 1 pulsado |
| ld a, 0F7h | |
| ei | |
| in a, (0FEh) | ; Comprobar semifila 5-1 |
| and 0Fh | |
| cp 0Dh | |
| call z, SELECT_KEMPSTON | ; Comprobar 2 pulsado |
| ld a, 0F7h | |
| ei | |
| in a, (0FEh) | ; Comprobar semifila 5-1 |
| and 0Fh | |
| cp 0Bh | |
| call z, REDEFINE_KEYBOARD | ; Comprobar 3 pulsado |
| ld a, (ALTERAR_ESTADO_COLOR) | |
| and a | |
| jp nz, ALTERNAR_COLOR_ON_OFF | |
| ld a, 0F7h | |
| ei | |
| in a, (0FEh) | ; Comprobar semifila 5-1 |
| and 0Fh | |
| cp 7 | |
| jp nz, COMPRUEBA_TECLAS_MENU | ; Comprobar 4 NO pulsado |
| ld a, 1 | |
| ld (ALTERAR_ESTADO_COLOR), a | ; Marcar para alternar estado color prox. vuelta |
| jp COMPRUEBA_TECLAS_MENU | ; Comprobar 3 pulsado |
| |
Comentarios
Esta función está dividida en varios bloques no contiguos a los que se accede mediante saltos largos.
Para mayor comodidad en su análisis la veremos como un solo bloque. Esta función se ocupa de pintar
y de manejar los eventos que se producen en el menu de opciones del juego.
Los textos no se mapean como ASCII y por tanto la transcripción del IDA no es exacta, basta decir que
realmente se mapean contra el mapa de caracteres interno del juego.
La rutina dibuja el logo, escribe los textos y entra en un bucle de comprobación del teclado que termina
cuando se inica la partida al pulsar el 0. Durante este estado la rutina de interrupción en 8080h se ocupa
de generar un efecto de borde multiculor en la zona superior e inferior de la pantalla y de controlar el
parpadeo del texto ON o OFF de la activación del color.
| CLEAR_SCREEN: |
| 842E | ei | ; Habilitar interrupciones |
| halt | ; Esperar retrazo vertical |
| xor a | |
| out (0FEh), a | ; Borde a negro |
| ld hl, 5800h | |
| ld de, 5801h | |
| ld bc, 2FFh | |
| ld (hl), l | |
| ldir | ; Borrado de atributos |
| ld hl, 4000h | |
| ld de, 4001h | |
| ld bc, 17FFh | |
| ld (hl), l | |
| ldir | ; Borrado de pantalla |
| ret | |
Comentarios
Función auxiliar que realiza un borrado completo de la pantalla borrando primero atributos (todo a negro) y
luego el contenido real de la pantalla. Se hace así porque si se borrase primero pantalla y luego atributos
podrian verse cuadros de colores debidos a los colores de "papaer" de algunos carácteres.
| DIBUJA_LOGO: |
| 87BA | ld hl, 400Ch | ; DESTINO Logo del menu |
| ld de, 0B592h | ; ORIGEN Logo del menu |
| ld b, 18h | ; 24 lineas |
| DIBUJA_LINEA_LOGO: |
| 87C2 | ld c, 8 | ; 8 BYTES por línea |
| VUELCA_BYTE_LOGO: |
| 87C4 | ld a, (de) | |
| ld (hl), a | |
| inc l | |
| inc de | |
| dec c | |
| jp nz, VUELCA_BYTE_LOGO | |
| ld a, l | |
| sub 8 | |
| ld l, a | |
| ld a, b | |
| and 7 | |
| call z, VUELCA_ATRIBUTOS | ; Volcar atributos cada 8 lineas |
| call INCREMENTAR_LINEA | ; Cambiar a la siguiente linea de pantalla |
| djnz DIBUJA_LINEA_LOGO | ; Cambiar a la siguiente linea de pantalla |
| ret | |
Comentarios
Esta función vuelca el gráfico del logo que aparece en el menú de opciones a partir de su localización
en memoria. Usa un conjunto de rutinas auxiliares que se van utilizando a lo largo del volcado de gráficos
por todo el juego.
| ESCRIBIR_CADENA: |
| 87CF | ld a, (de) | |
| ld l, a | |
| inc de | |
| ld a, (de) | |
| ld h, a | ; Tenemos en HL dir destino en pantalla |
| inc de | |
| ld a, (de) | |
| ld c, a | ; Tenemos en C el color |
| inc de | |
| ESCRIBIR_LETRA: |
| 8768 | ld a, (de) | |
| push hl | |
| push de | |
| call DIBUJAR_CARACTER_TEXTO_8X8 | |
| pop de | |
| pop hl | |
| inc l | |
| inc de | ; Siguiente carácter |
| ld a, (de) | |
| cp 0FFh | ; Comparar con final de cadena |
| ret z | ; Retornar si 0xFF leído |
| jp ESCRIBIR_LETRA | |
Comentarios
Esta función recupera la direccion donde se volcará el texto en pantalla, el color y
entra en un bucle del que sale al leer 0xFF, indicador de final de cadena. En cada
vuelta del bucle se dibuja un carácter de 8x8 en pantalla volcándolo desde el mapa gráfico
de la fuente en memoria.
| EMPEZAR_PARTIDA: |
| 88D5 | xor a | |
| ld (EMPEZAR), a | ; EMPEZAR valdrá 0 |
| ret | ; Salimos de la rutina BLIT_MENU |
Comentarios
Esta función se ocupa de salir del menú de oipciones y de avisar a la
rutina de interrupción para que deje de ejecutar todo el proceso de pantalla que
hace.
LOS DATOS
En este apartado ire añadiendo los bloques de datos y la explicación de sus formatos
quedando enlazados con el codigo para facilitar su navegación.
| TEXTO_KEYS: |
| 8A8C | .db 8Bh, 44h, 44h |
| .text "1>KEYS///" |
| .db 0FFh ; |
| TEXTO_KEMPSTON: |
| 8A99 | .db 0CBh, 44h, 44h |
| .text "2>KEMPSTON" |
| .db 0FFh ; |
| TEXTO_DEFINE: |
| 8AA7 | .db 0Bh, 4Ch, 44h |
| .text "3>DEFINE/" |
| .db 0FFh ; |
| TEXTO_COLOR: |
| 8AB4 | .db 4Bh, 4Ch, 44h |
| .text "4>COLOR/ON>OFF" |
| .db 0FFh ; |
| TEXTO_START: |
| 8AC6 | .db 8Bh, 4Ch, 44h |
| .text "0>START" |
| .db 0FFh ; |
| TEXTO_CREDITS_1: |
| 8AD1 | .db 0C4h, 4Ch, 45h |
| .text "Program/:/Ricardo/Puerto" |
| .db 0FFh ; |
| TEXTO_CREDITS_2: |
| 8AED | .db 6, 54h, 45h |
| .text "Graphics:/Raul/Lopez" |
| .db 0FFh ; |
| TEXTO_CREDITS_3: |
| 8B05 | .db 45h, 54h, 45h |
| .text "Music/:/Roman/Hergueta" |
| .db 0FFh ; |
| TEXTO_CREDITS_4: |
| 8B1F | .db 86h, 54h, 42h |
| .text "?/Zeus/Software/1987" |
| .db 0FFh ; |
| TEXTO_CREDITS_5: |
| 8B37 | .db 0C6h, 54h, 42h |
| .text "?/Dinamic/Soft1987" |
| .db 0FFh ; |
| TEXTO_GAMEOVER: |
| 8B4F | .db 0E3h, 44h, 42h |
| .text "//THE/MISSION/HAS/FAILED//" |
| .db 0FFh ; |
| TEXTO_GAMEOVER2: |
| 8B6D | .db 2Ah, 4Ch, 42h |
| .text "/IS/THE/END/" |
| .db 0FFh ; |
Cadenas de texto:
NOTA: Estoy desensamblando desde la versión inglesa, cambiaré esta parte con los datos de la española más adelante
Los textos se escriben en pantalla en medio de dos "cuadros" de 8x8 para poder ser escritos en tres colores
de forma simultánea. La parte superior es blanca y la inferior de un color arbitrario. Las cadenas de texto se guardan con el siguiente formato:
DW direccion de pantalla donde empiezan a dibujarse en pantalla (LB-HB)
B color arbitrario para el texto
B[] array de bytes que indica la letra en el mapa de caracteres del juego acabado en 0xFF
| ATT_CALAVERA: |
| 9E5C | db 6, 7, 6 db 7, 7, 7 db 47h, 47h, 47h |
| ATT_GEMA_APAGADA: |
| 9E5C | db 41h, 41h, 41h db 41h, 41h, 41h db 41h, 41h, 41h |
| ATT_GEMA_ENCENDIDA: |
| 9E65 | db 6, 45h, 47h db 45h, 45h, 47h db 45h, 45h, 47h |
| GFX_CORAZON: |
| EE00 | .db [800h],<...> |
| ATT_CORAZON: |
| F600 | .db [100h],<...> |
Gráficos:
No añadiré el volcado integro de los gráficos, pero si sus "puntos" de origen y tamaños. Usaré una sintaxis
incorrecta para definirlos (similar a la de DUP) pero que servira para dejar claras las cosas... la idea es
.db [longitud],<...> que indica un array de bytes consecutivos de la longitud indicada y con un contenido
que a efectos practicos no necesitamos saber aqui. Los datos reales estarán en el desensablado global unificado.
En algunos casos puede que si coloque el volcado (p.e. blit de atributos sueltos).
|
|