Spectrum Pokes

Basic Information

Using my hexsearch tool it is possible to identify byte seqences in snapshots files used by many Spectrum Emulators. For simplicity we can use the .sna snapshot file format.
Some emulators do not allow memory to be searched but some allow the memory to be changed by the poke command.

The problem is translating a virtual address as an offset in the .sna file to a physical memory address. A lot of games store their variables if the 48k region, so that in 48k and 128k mode they will be at the same address.

The specification for the .sna format says:

   Offset   Size   Description
   ------------------------------------------------------------------------
   0        27     bytes  SNA header (see above)
   27       16Kb   bytes  RAM bank 5 \
   16411    16Kb   bytes  RAM bank 2  } - as standard 48Kb SNA file

So for a quick calculation to calculate the physical address within the 48k RAM area the equation is:
address = (file_offset - 27) + 16384

For quickness it's a good idea to put this formula into an Excel spreadsheet.

Reference: WOS


Examples

180 by Mastertronic
Chuckie Egg

180 by Mastertronic

Set Score

Start the game with 501 points. Take a snapshot. 501 in hex is 0x1f5. In little endian format this is 0xf501

D:\games\emu\spectrum\Spin>hexsearch f501 180_1.sna
Found at offset
23243 (0x5acb)
23245 (0x5acd)
23354 (0x5b3a)
26921 (0x6929)
27394 (0x6b02)
27457 (0x6b41)
28516 (0x6f64)
29733 (0x7425)

Continue the game. Score 20 so the score is now 481. Take a snapshot. 481 in hex is 0x1e1. In little endian format this is 0xe101
This gives us an address comparison to find addresses where the score may be stored.


D:\games\emu\spectrum\Spin>hexsearch e101 180_2.sna
Found at offset
23354 (0x5b3a)
24184 (0x5e78)
25807 (0x64cf)
25857 (0x6501)
25923 (0x6543)
25959 (0x6567)
26405 (0x6725)
26478 (0x676e)
26527 (0x679f)

By checking the 2 snapshot we can see that offset 23354 contains the values we are looking for in both cases. This is probably where the score is held. To convert the snapshot offset to a real address we must recalculate it.

address = (file_offset - 27) + 16384
(23354 - 27) + 16384 = 39711
since this is a 16-bit word we poke 39711 and 39712.

In the game 180 we should:
poke 39711, 2
poke 39712, 0
to be able to end the game in double 1.


This makes the final very easy!

Tune up

Save a snapshot with 20 on the board,
Save a snapshot with 19 on the board,
Use file compare to diff the 2 files 20 (0x14), 19 (0x13).

D:\games\emu\spectrum\Spin>fc /B 180_1.sna 180_2.sna > m.txt
D:\games\emu\spectrum\Spin>grep ": 14 13" m.txt
File M.TXT:
00005B48: 14 13
00006F64: 14 13

Just for testing we convert 0x5b48 to a real address:
poke 39725,1


Hit 1. It works!


Chuckie Egg

255 lives

Save a snapshot with 5 lives (4 yellow dashes shown at the top),
Save a snapshot with 4 lives (3 yellow dashes shown at the top).


D:\games\emu\spectrum\Spin>fc /B a.sna b.sna > m.txt
D:\games\emu\spectrum\Spin>grep ": 05 04" m.txt
File M.TXT:
00002F0B: 05 04

Just for testing we convert 0x2f0b to a real address:

0x2f0b=12043
12043->28400
poke 28400,255

On futher investigation this is actually the player 1 lives counter, players 2-4 are in 28401, 28402 and 28303. A nicer poke is actually to do a ret (0xc9, 201) before it decrements the counter.


Back to index.