Back to XM6 Pro-68k

This page contains tutorials for using the Dynamic Memory Search feature for cheating purposes.

General Advice

Read the manual.

Press '?' or 'H' to enter a help mode that lists the most common commands.

When inputting values into dialogs, hexadecimal numbers start with $ or 0x and decimal numbers start with #. The default radix used for ambiguous entries can change; consult the manual for details.

Dynamic Memory Search is implemented as a special mode of the usual memory viewer. You can switch modes at any time with the 'M' key.

The search window must be active before you can input any commands, so remember to click on it or use a keyboard shortcut to activate it at the appropriate time. A consequence of this is that Pop-up Window Style must be enabled in the options under the Miscellaneous tab.

For international keyboards, a few keys won't map properly. The num-pad keys are generally more reliable than their equivalents in the main area. Some commands have alternate keys that can be used as noted in the manual.

Generic Game Guide

Start playing the game.

Open the Dynamic Memory Search (DMS) window. If it is already open, press backspace to reset things.

Play the game until the value you are interested in (e.g. lives, health, money) has changed. Then perform a search in the DMS window:

  • If the value decreased by 1 (e.g. you lost a life), press '-'. If it increased by 1, press '+'.
  • If the value changed by more than 1, and you know the exact amount, press 'Y' and enter a negative number if it decreased or a positive number if it increased. For example, if you lost 5 HP, enter -5. If you picked up 10 gold pieces, enter +10 or just 10.
  • If you are uncertain how much something changed, press 'D' if it decreased or 'I' if it increased. These commands are usually more reliable but they also tend to take longer to filter out spurious addresses.
  • If you are uncertain how a variable changed (i.e. a game "flag") but you can recognize when it did or did not change state, use 'C' or 'S' respectively.
  • If you made a mistake (i.e. all the addresses disappear) press 'Z' to revert the previous search. This feature has some caveats, which are noted in the manual.

    Repeat the previous step until there is only one address remaining in the DMS window.

    TIP: Press the space bar to repeat the previous search.

    TIP: Sometimes you may need to go through several game sessions to isolate the address of interest. When starting a new session you may need to use 'I' to indicate that the value went up. For example, if you ran out of lives and had to start a new game, the lives counter would have been reset, so the value appeared to increase. Alternatively, you can press 'U' to simply update the previously stored values without needing to know what the relative difference was.

    NOTE: In certain circumstances there may be two or three variables that track each other. In such cases you will have to experimentally determine which one(s) need to be modified.

    Double-click on the line and change the value to whatever you like. The game may not reflect your change immediately. You may have to take some action (such as losing another life) before it will be noticed.

    Assuming everything went well and you found the address you were interested in, you can copy it to the clipboard by typing 'A'. You can also add it to the history by pressing 'G' followed by Enter. You can reuse this address in the regular memory window (type Alt-V, P, M in the frame window) at any time. Just type 'G' and enter the address to select, then press Enter to modify the value at that address. NOTE: The standard memory window always assumes hexadecimal input, so you may need to prepend '#' to the number if you are inputting a decimal value.

    There are many other search strategies. For example, it is possible to search for exact values or quantities within a specified range. This tutorial describes the simplest and most reliable method, if not necessarily the most efficient, and is applicable to many common situations.

    More in-depth tutorials follow.

    Thunder Force II

    Start a new game and pause emulation (Alt-F12 or Alt-Pause).

    Open the Dynamic Memory Search window.

    Resume the game and get killed, then pause and click on the DMS window. Now press '-' to indicate that the value we are interested in (lives in this case) decreased by 1.

    Repeat the previous step. Note that you can pause/unpause the game while the DMS window is active.

    Hopefully by this time you should have reduced the search space to a single address. It should look something like this:

    00704F: 00 (==) (B/W) 0

    This indicates that the current value at address 704F is 0. The current value is always displayed in both hexadecimal and decimal formats.

    The part in parentheses is the previous value, which is was stored after the last search. The equals signs indicate that it is equal to the current value. Note that if you had examined it prior to performing the search it would NOT have been equal; immediately prior to pressing '-' it would have been the current value plus one.

    Lastly, B/W indicates that this value could be interpreted as either a byte or a word. If you switch the units to view word-sized locations (press 'W') you should see the following:

    00704E: 0000 ( == ) 0

    Note that this is the same address minus 1. There is a good chance that the lives counter is word-sized. We'll investigate that in a minute. For now, switch back to byte-sized (press 'B').

    Double click on the address (or press enter) to change the value. We'll start with a small value like 8.

    Resume emulation. Note that the number of lives did not appear to increase, but this is probably because the game was not expecting the value to change suddenly like that. Commit suicide and you'll then see a large number of lives.

    Next try changing the value to $7F. There won't be any indication that you have that many lives, but you can watch the value in the memory window and it decrements fine every time you die.

    The rest of this tutorial is optional. If you are content with having $7F (127 decimal) lives (or whatever) then you don't need to bother checking the size of the variable.

    Now let's see if it is really a 16-bit (word-sized) value. Switch back to word-sized units ('W') and change the value to $101. Die a few times and you'll see that you still have a bunch of lives. Therefore it must be a 16-bit quantity. If the value were 8-bit then you'd run out of lives almost immediately because setting 00704E to $0101 is equivalent to setting 00704F to 01 - one life in stock.

    At this point you can simply set 00704E to $7FFF for effectively unlimited lives and be done with it. But let's investigate a little bit more.

    Set the value to $FFFF. This is either the largest possible unsigned word value or it is -1 if the variable is interpreted as signed. You'll notice that negative numbers ($8000 - $FFFF) work, but your life stock disappears. So it's probably being treated as a signed variable, at least in certain cases.

    Xenon 2

    This is an advanced tutorial where a variable of interest is 32-bit: the amount of so-called "REALCASH". DMS does not support 32-bit quantities due to a variety of complications. However, it is still possible to work with such values, as we will see below.

    Another wrinkle is that the cash you have is not displayed during normal gameplay so it isn't obvious when it has increased or by how much.

    Play the game until you reach the first shop, then open the DMS window. You can now see how much cash you have acquired towards the bottom of the screen.

    Note that the cash display is 7 digits. Recall that 16-bit quantities cannot hold numbers larger than 65535 (decimal) or $FFFF (hexadecimal). Therefore, 7 digits suggests that this variable might be larger than 16 bits.

    Another possibility is that one or more of the low-order zeros being displayed are not actually part of the variable. This technique was often used historically to compress score values, particularly on systems with limited register sizes. For example, 100 points could be stored as the value 1, with two zeros displayed in the score field. I'll tell you ahead of time that that's not the case here, but it is something to be aware of.

    Press 'E' or '=' and enter the exact amount of cash. Chances are there will only be a few matches. Make any transaction and you should be able to determine the correct address: 05897A. This is actually the address of the lower 16 bits.

    But what if you have more cash than will fit into a 16-bit variable?

    This can cause problems in some situations, but it doesn't matter when searching for an exact quantity; just enter the full number and it will be automatically masked to fit within 16 bits. It may find multiple addresses, and some of them may not match the full 32-bit value, but this is only a minor complication.

    It becomes a bigger issue when performing relative searches: they may not work as intended. Even if the total 32-bit value decreased, the value of the lower 16 bits may have increased, and vice versa. Therefore, you might not want to perform relative searches for numbers greater than 65535 unless you understand the mathematics. Below 65536, any kind of search is safe.

    Moving on, let's confirm that this is indeed a 32-bit quantity. On big-endian systems, higher-order bytes are at lower addresses. So to calculate the start of the hypothetical 32-bit variable, we need to subtract 2 bytes from the address of the lower 16 bits: 05897A - 2 == 058978.

    Press 'M' to switch out of DMS mode and into the standard memory view. Press 'W' to switch to the word-sized view, if not already there. Next press 'G' and enter the address we calculated above. We can see that the value at that address is 0000, which is consistent with this being a 32-bit quantity. Press Enter or double click on that value to change it. I recommend a small number like 2. (Remember that we are modifying the upper-order 16 bits here.)

    Finally, buy an item and verify that your cash went up by a large amount.

    You can experiment further. You'll see that excessively large values (e.g. $7FFFFFFF) won't display correctly, although they still work. This variable is interpreted as signed in the shop, so values of $80000000 or more will be treated as negative. Outside of the shop it is unsigned, so excessively high amounts risk rolling over into negative territory and thus being useless. The largest amount of cash that will display properly is #9999999.

    TIP: You can switch to longword view to modify all 32 bits at once; however you won't be able to double-click on unaligned 32-bit variables (i.e. addresses that aren't a multiple of 4).

    Back to XM6 Pro-68k