Cómo Encontrar Pokes


Utilizando el programa en C que podeis descargar aquí y el emulador de Gerton Lunter Z80, incluso su versión share, no habrá juego que se os resista. Si encontrais alguno que no esté en la lista o teneis alguna duda, no dudeis en escribirme:

fraile@teleline.es

con el subject "Spectrum Pokes". En el fichero .zip se encuentra el mismo texto de esta página, el fuente en C y el compilado con el gcc GNU. ¡A pokear se ha dicho!

Descarga
(49,1 KB)

Cómo buscar POKES

Con el emulador de Spectrum Z80 u otro que lo permita, por ejemplo, el X128, hay que salvar el contenido de la memoria desde la posición 23296 (#5B00) que es donde acaba la memoria de video, hasta el final, longitud 42239 (#A4FF).

Con el emulador Z80 son las teclas: F10, X, S, M, S5B00, LA4FF.

Con el X128 son: F6, cursor hasta Start, 23296, cursor hasta Length, 42239.

Los ficheros se deben llamar POKE0000, POKE0001, POKE0002,etc. y deben estar en el mismo directorio que el programa POKES. En cada una de esas imágenes de la memoria el valor que estamos buscando debe haber cambiado. Con el programa "POKES.EXE" encontraremos la dirección en que se encuentran las vidas, la energía, etc. Normalmente será una dirección cuyo contenido haya ido decreciendo (se encontrará con la opcion POKES -d. Con la opción POKES -Ddireccion verificaremos que los valores que ha ido tomando corresponden al valor de las vidas, por ejemplo). Si especificamos un valor, por ejemplo POKES -d5 nos dara las direcciones que han ido decreciendo empezando en 5.

Si el emulador permite pokear directamente en el transcurso de una partida, por ejemplo con el Multiface 128, podemos parar aquí y meter en esa dirección un valor muy alto (máximo 255) para las vidas.

En caso contrario, para tener un POKE que funcionara en un Spectrum real escribiéndolo en el cargador BASIC antes del RANDOMIZE USR, debemos usar el SAMRAM (esta característica sí es exclusiva del Z80) para buscar la instruccion que modifica esa direccion de memoria. Los comandos del SAMRAM que nos sirven para esto son:

#: cambia de Hexadecimal a Decimal

f: busca el número (la direccion de memoria)

n: continúa la busqueda

m: va a la dirección indicada

b: inserta un byte en la dirección actual

 

Lo que haremos ahora es buscar las instrucciones que modifican la dirección donde estan las vidas. Para ello buscamos la dirección obtenida con el programa POKES en la memoria del Spectrum (f: dirección). Usualmente, la primera vez que aparece es la rutina de inicialización, donde se da el valor inicial a las vidas. Suele ser algo así:

23299 LD A, 005 /* Pone 5 en el registro A */

24301 LD (64393), A /* Mete el valor de A (5) en la dirección 64393, donde estan las vidas */

Si cambiamos ese 5 por un 255 obtendremos 255 vidas al empezar cada partida. Hemos encontrado el POKE para variar el número de vidas:

POKE 23300, 255. (255 vidas)

Buscar el POKE de vidas infinitas no es mucho mas complicado. Seguimos buscando la dirección en el código del programa (con n). Aparecera varias veces. El lugar donde se decrementa el numero de vidas suele tener este aspecto:

36538 LD A, (64393) /* carga el número de vidas en el registro A */

36541 DEC A /* decrementa el registro A */

36542 LD (64393), A /* introduce el nuevo valor de las vidas en memoria */

El POKE de vidas infinitas sería, en este caso:

POKE 36541,0.

El cero corresponde a la instrucción NOP (No operación) que no hace nada. De este modo las vidas no se decrementan.

En ocasiones se comprueba si las vidas son cero justo después de decrementarlas. En ese caso el POKE puede no funcionar correctamente. Para ello, en lugar de cambiar el DEC hay que cambiar la instruccion en que se actualiza la direccion de memoria. Por ejemplo:

36538 LD A, (64393) /* carga el numero de vidas en el registro A */

36541 DEC A /* decrementa el registro A */

36542 JR Z, 36590 /* salta a la direccion 36590 si es cero */

36545 LD (64393), A /* introduce el nuevo valor de las vidas en memoria */

Si el código es de esta forma, podemos cambiar la ultima linea para que el valor nuevo no se meta donde debería, sino en una posicion de memoria de la ROM (lo que no producirá ningún efecto, pues la ROM no puede ser sobreescrita). El POKE sería:

POKE 36547,0 que cambiaría el código de la última línea a LD (00137),A

Otras instrucciones ademas de DEC que podemos encontrar son INC (que incrementa), ADD (suma) y SUB (resta).

 

EJEMPLO PRÁCTICO: BUSCAR LAS VIDAS INFINITAS EN EL MANIC MINER

(Para este ejemplo he supuesto que se utiliza el emulador Z80 de Gerton Lunter).

1. Buscar la direccion que guarda el numero de vidas.

Ponemos el juego y empezamos una partida. Inmediatamente lo salvamos con 2 vidas (pulsamos F10, X, S y ajustamos los valores M, S5B00, LA4FF). Como nombre ponemos POKE0000. Matamos una vez al minero Willy y lo volvemos a grabar con el nombre POKE0001. De nuevo perdemos otra vida y lo salvamos como POKE0002. Salimos del emulador y ejecutamos el programa POKES. Obtenemos muchas direcciones. Escribimos "POKES -d". Ahora tenemos menos pero siguen siendo demasiadas. Sin embargo, el último valor que tuvieron sólo es cero para la última, la 33879. Escribimos POKES -D33879 y comprobamos que los valores que ha tenido esta direccion han sido 2, 1 y 0, que coincide con el numero de vidas que teniamos al salvar. Escribiendo directamente POKES -d2 podemos obtener la dirección correcta con una sola operación. Ya conocemos la dirección en que se guardan las vidas: la 33879.

Si no queremos complicarnos mas la vida, podemos POKEar con el emulador de Multiface 128 que incorporan el Z80 o el X128 con un valor alto (por ejemplo 10) para tener ese numero de vidas. Si nos acercamos peligrosamente a las cero vidas, podemos POKEar de nuevo con ese valor. Para acceder al Multiface con el Z80 es necesario tenerlo activado en la configuracion del Hardware (F9) y provocar una NMI con F5. Con el X128 se utiliza F2. En ambos casos, una vez con el menu del Multiface en la zona inferior de la pantalla se pulsa: t, espacio, direccion, valor, ENTER, q, r. Algunos emuladores (por ejemplo el ZX32) permiten la opcion de POKEs con cerrojo ("lock") de forma que mantienen fijo un valor en esa direccion. De esa forma no hay que POKEar continuamente. Para los perfeccionistas que quieran un POKE que funcione en un Spectrum real sin periféricos adicionales y con cualquier emulador que no los soporte, no les queda mas remedio que pasar al punto 2.

2. Buscar el código que modifica el valor de las vidas.

Volvemos a poner el emulador con la SAMRAM y el juego. Provocamos una NMI con F5 y entramos en la SAMRAM. Pulsamos D para entrar en el desensamblador. Con '#' cambiamos la notacion de hexadecimal a decimal, que nos sera mas comoda. Ahora con 'f:33879' buscamos las instrucciones que operan sobre esa direccion de memoria y hallamos:

34271

Subimos 3 veces (Q/A es subir/bajar) y vemos:

34268 LD A, 002

34270 LD (33879),A

Esto mete un 2 en la dirección de las vidas. Es la inicialización.

Si cambiamos el 2 por otro número, por ejemplo un 5, en la dirección 34269 (con la B), empezaremos siempre con 5 vidas. Hemos encontrado el POKE de número de vidas:

POKE 34269, n (0 <= n <= 255, numero de vidas).

34575

No vemos ninguna instrucción que modifique el valor de las vidas. Seguimos buscando.

35129

Subimos una vez (Q) y vemos:

35128 LD HL, 33879

35131 LD A, (HL)

35132 OR A

35133 JP Z, 35140

35136 DEC (HL)

Este código pone en HL la direccion de las vidas, el numero de vidas en el registro A, hace una comparacion para saltar o no y decrementa el contenido de la direccion apuntada por HL. Es esa linea la que tenemos que cambiar, la que decrementa. Poniendo en la 35136 un 0 (B:0) cambiamos la instruccion de decremento por un NOP que no hace nada.

Hemos encontrado las vidas infinitas:

POKE 35136,0

37112,37116

Vemos que se leen las vidas, se incrementan y se escriben en la dirección correspondiente. Probablemente sea por llegar a cierta cantidad de puntos.


principio