Vampire Savior/Hacks

From Mizuumi Wiki
Jump to navigation Jump to search

Information about how to edit the colors and RAM can be found here.



R.A.M. Manipulation - Tools & Workflows


I’m VMP_KyleW, an enthused VSAV competitor with an interest in VSAV related hobbies. Since the summer of 2018, I experimented & documented R.A.M. manipulation for Vampire Savior. This page of Mizuumi Wiki has been reformatted to include the workflow & findings of my R.A.M. project in a format intended to be read as an article. The project was ambitious and challenging as I had very little knowledge on the subject. Truthfully, there is very little I did on my own. The majority of my effort was learning new content, new tools and collating information developed by others.

My project objectives:

  • Further explain bugs
  • Understand how the CPU can execute moves in situations the player cannot
  • Find hidden content like moves, taunts, animations
  • Unlock hidden content like Colors, Characters, Stages, & the Debug menu



This person has been the largest influence to the project. Felineki is truly a knowledgeable expert with a wealth of data. Please check out The Cutting Room Floor‘s Darkstalker titles located here:
Most, if not all of these Darkstalker contributions are from Felineki. Here are other examples of technical skills;
Additionally, They were kind enough to mentor me through some concepts as well as provided me with access to their work in progress Memory Map, including notes. SUPER THANK YOU Felineki!

Jed (Possum, MountainMan, Hudson)

Jed is a legend for his ability to meaningfully contribute & mod/hack most fighting games. Here are his VSAV videos which speak to his efforts;
Similarly to Felineki, he was very active in forum communities in the early 2000’s. Try google searching esoteric data about CPS-II, emulators or game music & their legacy is easily spotted. To further cite VSAV, Jed is responsible for creating a (.LUA) script which replicates most features of a “Training Mode” within VSAV on MAME.
Lastly, Jed’s VSAV color modding/hacking parameters are all public data on the Mizuumi wiki.
Jed, you are incredible, thanks for your hard work!


Goose is a PWN VSAV competitor, a friend of mine who plays an amazing Bulleta and excels at other hobbies including programming. Goose took on a modding project to create a custom “Benwa” portrait in the character select screen. He succeeded!
Playing on native CPS-II using a DarkSoft.
Lastly, Goose provided me with his notes on that project. Although it was entirely focused on graphics, I definitely learned valuable lessons/concepts for how VSAV game data is sorted, referenced & computed. If I do venture into a graphics modding project, the foundation is already set. Cheers to Goose!


SF2_Platnium has been wonderful to me. I was introduced to his efforts from this article during the summer of 2017;
He linked me to this valuable resource:
I could easily see the overlap between his project & my goals. Since then, we had numerous email exchanges discussing basic workflows for disassembly & data recreation. Overall, he helped me know what tools to use immediately & what tools to defer until after I understood more about MAME’s intermediate features. SF2_Platnium is my biggest inspiration as I take my project further. Thank You Thank You SF2_Platnium!


Although I’ve never corresponded with Dammit, It’s important to recognize this person’s efforts in creating the first generation of (.LUA) Scripts for CSP-II games. This individual is largely responsible for the Hit, Hurt & Push-Box visibility feature as well as the input display options. Dammit, you did a tremendous effort for the CPS-II community, we are indebted to you!

Pugsy’s Cheats Forum
Since the infancy of emulators, activist were interested in having “cheats” available to enhance gameplay; infinite health, infinite lives, etc. The earliest source I found for crediting these efforts is Pugsy’s Cheats. This is a forum which users would explore R.A.M. values and report them to Pugsy, who would collate the “cheats” into Mame’s PROGRAM INPUT LANGUAGE and provide a master “cheat” file for all game. This site is a testament to a grass root community effort from 2000-2010. Besides Pugsy himself, some active members focusing on VSAV were Mike_Haggar, KelvSYC & D9x. Thank You for establishing the “Cheats” files for MAME!

Jais & Alphakami

Jais & Tad are a support network, allowing a platform for theory-crafting, learning computer science concepts & most importantly, engaging with me as the project developed. Jais also reviewed the document. I was only able to complete this with your help. Thanks guys!


Jordyn is a friend of mine from back in the Cincy days. He reviewed this article as a knowledgeable source for Computer Science, Fighting Games, Reverse Engineering & competing with Demitri. Thanks Jordyn, you are awesome!

Surround yourself with supporting, knowledgeable & encouraging people

Updating & Sharing Thesis

This article will be as workflow-transparent as possible. Secondly, I am taking the effort to prove the findings so readers have a better understanding of concepts. I am sharing this in a wiki format largely at the request of the community, but also to offer a responsive platform for updating the document. I have a very basic understanding of these concepts from a non-formal learning perspective. I presume corrections need to be made after publication. Please feel empowered to notify me on Twitter @VMP_KyleW with errors, I am happy to correct them! I strive to only share accurate information.

My largest challenge was finding information for what tools to use as well as how and when to use them. I plan to mitigate these hurdles for people outside of the Computer Science Industry. The brilliant people before me tend to keep their tools & workflows internal. It is not clear as to why, we can only speculate. Some hypotheses are:

Results vs Process - Similar to scientist publishing public papers; to the public eye, there is a greater emphasis on the results of an experiment. Some amazing logic and problem solving would go into a hypothesis, to ultimately not be shared due to unfavorable or incomplete results.
Internal work without public intent - Some projects were designed only for an internal workflow. Sharing workflows and developmental data as OpenSource was never the desire. OpenSource publication takes a higher level testing, transparency and maintenance. For personal projects, this slows down production.

Legal Disclaimer

I personally own (3) separate copies of VSAV; Darkstalkers 3 for PS1, DS:Resurrection for XBox 360 & a JP-VSAV B-Board on CPS-II. Anyone interested in obtaining VSAV(.ZIP) should purchase a legal copy first! I will not specify how to obtain VSAV(.ZIP). I’m publishing this up on a good faith effort that Capcom will not award me a cease and desist.


  • Provide a framework for others to explore R.A.M. addresses in CPS-II games.
  • Influence others to join in a communal Disassembly activity
  • Share a collective understanding of VSAV’s R.A.M. with a diverse audience.

Getting Started

What I will not explain

Learn these before proceeding:

  • What Operating System you are running
  • How to install programs on your own Operating System
  • Basic Operating System (Windows)
Commands like copy, paste, find, replace
Navigation of directories
Accessing RUN(Window’s) command
Accessing COMMAND PROMPT(Window’s)
  • Mapping the controller in MAME;
TAB key > input (This game)
  • Creating SAVE STATES in MAME;
TAB key > Input (general) > user interface
TAB key > Input (general) > user interface
  • You should enable Windows to display file type extensions

My Environment

  • MAME default settings. Non custom configurations
  • Windows 10 Pro - Home edition; 64 bit operating system
Version 1809
OS Build 17763.615


These definitions are very basic, but essential to beginning the project.

  • R.O.M. - READ ONLY MEMORY. R.O.M. refers to all the data inside the game which is static & does not change. Some examples of R.O.M. are graphics, audio & program data. Often times, a file needed to play on an emulator is referenced as the games “ROM” file. This file is actually the “game data file” which is a combination of data and language needed to interface the processor. This file allocates all addresses for R.O.M. & R.A.M values.
  • R.A.M. - RANDOM ACCESS MEMORY. R.A.M. is allocated memory addresses that manage dynamic variables in a program. This includes variables like, which character is playing, how much life the player has & how much meter a player has. All of these values are dynamically stored in dedicated Memory addresses. R.A.M. is a location which temporary data is stored.
  • Dip Switch - Early arcade games do not offer a “Menu” to interface game options because it required too much memory. The solution to changing basic options like game difficulty was managed by physical switches on the Printed Circuit Board. These switches have a map key or legend provided with the installation manual of each title. Because these Dip Switches were used to manage basic options of games, the industry adopted the name “Dip Switch” to discuss the act of changing these settings, even for future games where the physical switches do not exist, Ha! One example of this is Darkstalkers: The Vampire Collection for Playstation 2 which offers unspecified “Dip Switch” options for custom game balancing. This term is known as generic trademark. Think of it like the “save” icon on most windows programs, the icon of a floppy disk is still used today, while physical floppy were announced dead, around 2007
  • Service Menu - VSAV does not have physical switches to manage game options. CPS-II’s B-Board offers a single button, called the “SERVICE BUTTON” which places the game into the “SERVICE MENU”. This Service Menu is where basic settings (input test, clock speed, round count, etc.) are managed.
  • Decimal, base10 - Standard counting uses our traditional method whereas any digit position could hold up to one of ten different symbols; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 that each represent a value in respect to which symbols are in which positions.
  • Hexadecimal, base16 - Hexadecimal counting uses a different method whereas any digit position could hold up to one of sixteen different symbols; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F that each represent a value in respect to which symbols are in which positions. All memory addresses and values within the R.O.M. and R.A.M. address are Base16 hexadecimal. Usually, but not always, Base16 hexadecimal format is identified with the prefix 0x. Nine units in Base16 hexadecimal is written as 0x9. Ten units is written as 0xA. Twenty Six units in Base16 hexadecimal is written as 0x1A.
  • Program Input Language - The arrangement of characters and commands to be read by a program.

Obtain MAME-RR


Extract the (.ZIP) file such that the final product is a folder called “MAME-RR_v0139_vsav_train” which includes numerous data files, folders & an executable called MAME(.EXE). Rename this folder to be called “MAME”.

I placed this MAME folder on my Desktop. You could place it there or directly into your “C: Drive”

I am running version You can verify your version by Right Mouse Click on “Mame.Exe” > Properties > Details > File Version.

Obtain VSAV(.ZIP) for Emulator

Try searching google for the filename - Once you obtain VSAV(.ZIP), place it into the directory of MAME > roms.

Pugsy’s Cheats Analysis

Obtain Pugsy’s Cheats


1. click on the column header titled “MAME Cheat Files”.
2. Download the link from the top of the list, titled as “XML CHEAT Collection for MAME”.
3. This (.ZIP) folder is a compressed folder that needs to be “unzipped”. Windows 10 allowed me to complete this by by Left Mouse Clicking once on the (.ZIP) file then Right Mouse Clicking & selecting Extract All…
4. This will recreate the data as an interactable folder within the same directory. You can delete cheat0206(.ZIP), after extraction.
5. Within your new folder, there is a file named Cheat.7z. This a compressed (.7z) file which needs a unique program to unzip it.

Obtain 7-zip


1. download the executable compatible with your operating system. For me, this was the 64-bit installer for Windows 10.
2. Install the program.
3. Right Mouse Click on Cheat(.7z) and hover the Mouse Over 7-zip > Extract files....
4. The next dialogue defaults to placing a newly unzipped copy in the same directory.
5. Click OK.
6. Look inside your newly created folder called Cheats to find the file VSAV(.XML)
7. Right Mouse Click > Copy
8. Go to your MAME directory, and PASTE VSAV(.XML) into your subfolder called cheats.
Yes, the file already exist there, but I needed you to understand where VSAV(.XML) originated. It’s important to cite the sources of previous projects. Congrats, now you have all the tools to run VSAV on MAME as well as access the CHEATS feature within MAME.


I prefer to edit in NOTEPAD, so I did this - Within the directory of MAME > Cheats, Right Mouse Click on VSAV(.XML) > Open With > Notepad.

Explore VSAV(.XML)

This cheat file already contains some addresses and values. Basic MAME Cheats can only change R.A.M. Values. Changing R.O.M. values is best with a different tool. Here is a walk-through of their first example: Description, Address (in Base16 hexadecimal), Value (in Base16 hexadecimal), Program Input Language

<cheat desc="Infinite Time">
   <script state="run">

0x63 = 99 in Base10 decimal.

This cheat forces the clock to constantly read as 99.

Here is the totality of what Pugsy’s Cheats tells us for VSAV’s R.A.M. (omitting Program Input Language).

Infinite Time FF8109 63
Finish this Round Now! FF8109 0
Select Background FF8101 param
Soul Keeper 'ON' FF87BC FF
Soul Keeper 'OFF' FF87BC 0
Maximum POW PL1 FF8509 63
Infinite Energy PL1 FF8450 1200120
Drain All Energy Now! PL1 FF8450 0
Infinite Dark Force Time PL1 FF8577 70
Select Character PL1 FF8782 param
Soul Keeper 'ON' PL2 FF8BBC FF
Soul Keeper 'OFF' PL2 FF8BBC 0
Maximum POW PL2 FF8909 63
Infinite Energy PL2 FF8850 1200120
Drain All Energy Now! PL2 FF8850 0
Infinite Dark Force Time PL2 FF8977 70
Select Character PL2 FF8B82 param
No Background Music F026 0
Hide Background This one is complicated
Select Region FF8091 param
Select Title FF8089 param
Sound Test This one is complicated
Sound Test Timer Stop FF800B FF

Lots to learn!

Notice how almost all Address are 6-digits. That’s important information. We can easily assume that the total Address range of Program Space Memory is 000000 to FFFFFF.

Notice how the Address for No Background Music is only (4) digits. This is because Base16 hexadecimal format allows us to assume the leftmost values are 0’s. We can write the Base16 hexadecimal number 0xF026 as 00F026.

Regarding the value of param. This is a command for the CHEATS program that allows us to specify different values at the same address all within one CHEAT operation. These are for Select Character, Select Background, Select Region and Select Title.

Notice that addresses expect values with consistent formats:

  • Number that converts to binary representing systems like health or clock. This can be increasing or decreasing; INCREMENTING or DECREMENTING.
  • 00 or FF - This type of value is a FLAG.The condition is binary, which only allows two options. Flags are coded to verify an expected value. It can also be said that a FLAG of FF is looking for FF or anything not FF. Any value not FF will trigger the change.
  • Param values directly reference additional variables. This is called a POINTER.

Notice how PL1 (Player One) & PL2 (Player Two) have separate entries. Let’s get a better understanding of their relationship; here is a proof of concept confirming there is a consistent 0x400 address difference.

Select Character PL1 subtract Select Character PL2 =
FF8782 subtract FF8B82 = -0x400
Maximum POW PL1 subtract Maximum POW PL2 =
FF8509 subtract FF8909 = -0x400

We can confidently say that the design of R.A.M. addresses have a 0x400 gap between PL2 & PL1. Felineki told me this specifically, thanks for the tip!

Lastly, Let’s try to understand the ranges of R.A.M. for similar descriptions. I’ll note the lowest & highest findings from above.

  • Game R.A.M. Data; FF800B to FF8091
  • Match R.A.M. Data; FF8101 to FF8109
  • PL1 R.A.M. Data; FF8450 to FF87BC
  • PL2 R.A.M. Data; FF8850 to FF8BBC

Unanswered questions from this analysis:

  • What is the total range of R.A.M. addresses?
  • Where does R.A.M. delineate between game, match & player data?
  • Why are some values greater than two digits?

Cheats Script & Commands

The four basic commands inside of CHEATS are ON, OFF, CHANGE & RUN. This defines how or when the action will be executed. In an example of RUN, the script state is always enabled, running each frame. If you are interested in all of these details, I recommend you read pages 7 & 8 from PUGSY’S endorsed guide called HOLY CHEAT!, located here:

By copy and pasting program input language inside VSAV(.XML), you can now create your own cheats.

MAME & R.A.M. Exercises

Time to load MAME & get into VSAV! Double Click the file MAME(.EXE) > Double-Click VSAV’s “Game Data” file. While running VSAV on this emulator, press the “TAB” button on your keyboard to open a sub-menu. Now Double-Click the option CHEAT. Here is where you activate the CHEATS we analyzed. Most of this tool is intuitive, but there a few interactions worth an explanation.

Exercise #1: Overflow

GOAL: Learn about memory overflow

Let’s analyze the Infinite Time cheat again.

<cheat desc="Infinite Time">
   <script state="run">

The specific command within this CHEAT program is the “run” command. You will notice that changing this cheat to “ON” will tell VSAV to constantly WRITE the value of 0x63 (remember that the prefix 0x signifies this as a Base 16 Hexidecimal number) for the entire time the cheat is “ON”. This command succeeds with no issues because the Address 0xFF8190 is expecting a DECREMENTING value. VSAV is not programmed to have a clock value greater than 0x63 or a combo-counter value greater than 0x63. Adding a cheat to go above the designed value will cause unintended graphics to load. This condition is called a MEMORY OVERFLOW or OVERFLOW.

The overflow in the above case is actually a type of memory overflow. It’s highly likely that there's an address table somewhere that looks up the graphics for the timer, and when the value exceeds 0x63, it is grabbing other graphics outside of that specific address table. It is also possible that the graphics engine can grab non-graphics data and represent it as a graphic.

Exercise #2: Pointers, Read & Write Operations

GOAL: Learn about pointers, read & write commands

Let’s analyze the Select Character cheat.

1. Go to VSAV’s Select Character screen
2. Active the Select Character cheat
3. Cycle through the options and choose “Jon Talbain”.
4. Notice how the character select graphics will change while you cycle through characters.
5. While playing as your CHEAT Jon Talbain, begin the battle
6. Activate the Select Character cheat
7. Cycle through the options and choose “Lord Raptor”.
8. Make Lord Raptor walk & you’ll see “Wild MISSINGNO appeared!”

In programming, a POINTER is a value that directly references another location.

This exercise demonstrates a lesson on when values are READ. POINTERS are dependent on when the Processor READS and WRITES data. Changing the Select Character value during the character select menu functioned normally. Changing the Select Character value during the battle caused graphical errors - MissingNo.

In this example, the Program Data told the Processor to READ & WRITE the primary character value and all nested value (Character specific graphics, hit-boxes, audio, etc.) during character selection. While in a battle, the Processor only READS these value. We are playing as “Lord Raptor” but all of the character’s graphics are still directed to “Jon Talbain” because they are WRITTEN at character selection.

Value can be WRITTEN & READ at different times. Consider this as you experiment.

Exercise #3: R.A.M. Versatility

GOAL: Learn about the versatility of R.A.M.

Add the following Cheat into your VSAV(.XML) file.

<cheat desc="0xFF800D Config Menu Options" <comment>Also activates match HUD announcements</comment>
	<item value="0x00">System 00</item>
	<item value="0x02">Game 02</item>
	<item value="0x04">Default 04</item>
	<item value="0x06">Save then Exit 06</item>
	<item value="0x08">Hidden Regions 08</item>
        <script state="run">

Service Menu Function example

0xFF800D is the address for manipulating a sub-menu called 7-CONFIGURATION MENU within the SERVICE MENU. Changing values inside the sub-menu forces the cursor to move to specific sub-options; SYSTEM, GAME, DEFAULT, or SAVE THEN EXIT.

Battle Function example

0xFF800D is also the address for manipulating the H.U.D. Announcements during battle. READY, FIGHT, K.O., LOSE, PERFECT Etc. The Program Data tells the Processor to READ & WRITE values and all referenced values during battle too.

It’s overwhelming to realize that an address of memory can be used for numerous tasks. That flexibility is the exact purpose of R.A.M. It’s RANDOM ACCESS MEMORY - Exercise #3 unveils that R.A.M. is relative to the current operation. Think of it as different game states, called FUNCTIONS. It’s know that developers deliberately assigned memory, each function has a repeatable way of interacting with available R.A.M., we have these discrete functions where R.A.M. could be unique:

  • Service Menu
  • Game Intro & Ending animations
  • Character Select
  • Battle
  • Story Mode Transitions

Unanswered questions from these exercises:

  • Where are memory overflow values coming from?
  • Is there R.A.M. values that remain during different functions?
  • How to determine if an address is a POINTER, FLAG, INCREMENT or DECREMENT format?
  • How best to document R.A.M. addresses with respect to each function?

Training Mode (.LUA) Analysis

The next tool to discover is a Lua program. These are often called lua scripts, it is an additional program that can be executed simultaneously alongside MAME to allow modifications. MAME allows lua scripts! Some brilliant people were able to produce these tools:

  • CPS-II real time hit-box/throw-box graphics
  • CPS-II Frame Data
  • MAME input display
  • VSAV exclusive - Training Mode

This exercise will explore the Training Mode (.LUA) created by Jed

Mizuumi’s VSAV wiki explains the custom training mode here:

You will notice these files are already downloaded when obtaining MAME-RR. I prefer to explore in NOTEPAD, so I chose to do this- - open the MAME directory & locate vsavscriptv2(.LUA) then Right Mouse Click > Open With > Notepad.

There is too much relevant data to list in this article. but know that numerous more addresses and values for R.A.M. manipulation are documented in this script. Using best practices, Jed wrote all Base-16 hexadecimal numbers with a prefix of 0x. Using the Windows FIND (CTRL+F) command, If you search for “0x”, you easily find adjacent corresponding descriptions. the second result informs us: Projectile On-Screen is @0xFF84AC. This check is obviously a BOOLEAN because there are only (2) answers; projectile is on-screen & projectile is not on-screen. A BOOLEAN FLAG can also be referred as a FLAG, BOOLEAN, or BOOL.

Additionally, we previously learned that PL2 has a repeatable +0x400 relationship to the PL1 address. So it’s safe to assume PL2 Projectile On-Screen is @0xFF88AC.

Continue your Windows FIND (CTRL+F) command of “0x” to find a few hundred more results for addresses and descriptions. Combining this information with Pugsy’s Cheat’s provides tremendous insight into VSAV’s memory.

MAME Debugger

MAME’s Debugger tool is fantastic. It is the most useful option to explore live memory.

Open the Debugger

MAME'S Debugger tool does not have a (.EXE) file. I started by accessing the Window’s RUN command. I prefer to use the keyboard shortcut of (WinKey + R) > type cmd > OK

We have to manually boot the program using the Window’s COMMAND PROMPT. My MAME directory is located on the Desktop. I have to specify this within the COMMAND PROMPT. To navigate to the Desktop, I have to “Change Directories”. I enter this into the COMMAND PROMPT; cd Desktop\MAME

The directory being referenced is now the desktop. If your MAME folder is located in your C: Drive, the required command is; cd C:\MAME

To load the Debugger Use the command; mame vsav -debug

The Debugger & the emulator will load. The Debugger needs a RUN command to initiate. To achieve the RUN command, I chose this workflow; select the window of the Debugger then press the “F5 key”.

Super congrats, you are in!

Exercise #1 Basic Flow of Data

GOAL: Obtain a basic understanding of the CPS-II’s data-flow.

At a very basic level - The Program Data tells the Processor which game state is enabled as well as how to execute every command to facilitate that state (character select, battle, etc.) . The Processor will process data, using MACHINE CODE. CPS-II uses a Motorola 68K processor, all of the MACHINE CODE commands are unique to this Motorola 68K processor. The Processor reads R.O.M. data (Graphics, Audio & Program Data), does manipulations to WRITE & READ R.A.M. values as required. The Audio & Graphics are simultaneously reading data from memory to display and generate sound. The Program Data & R.A.M are simultaneously WRITING & READING data to allow controller inputs.

Vsav CPS-II Basic Data Flow.png

Exercise #2 Debugger Tour

GOAL: Be introduced to the Debugger tool

I noted each pane in Orange.
  • Command Line & History - A panel to give commands & read output history of commands.
  • Machine Code - Also called “Machine Language”, this is the literal machine code commands given by the Motorola 68K.
  • Registers - Address Registers is a unique type of R.A.M. used as a temporary storage for values, exclusively for process calculations. The existence of address registers greatly improves the overall performance time.

Vsav MAME Debugger Overview.png

Exercise #3 Cheatinit + Save States

GOAL: Learn the Debugger command; Cheatinit

This Cheatinit command is very useful to discover addresses based on your own conditions, It searches the entirety of memory so results could be R.A.M. or R.O.M. data. The Cheatinit command compares the entirety of memory at (2) user-specified points in time. By setting your own conditions, you can search for the corresponding differences in value.

Let’s work through the Cheatinit command to locate the counter for “PLAYER ONE START INPUTS” at the character select screen. We know the game stores this value because five total inputs are required to select a Shadow Character in VSAV.

First, go to the character select screen and press PL1 START a total of nine times. Now SAVE STATE 1. Secondly, restart the Debugger (or the emulator), go to the character select screen and press PL1 START a total of six times. Create a SAVE STATE 2. Comparing the values of nine & six is easiest because their values are the same in Base10 decimal counting as well as Base16 hexadecimal counting because we’re not going above 0x9 and into 0xA.

Here is my preferred workflow to restart MAME & the Debugger while actively running the program;

1. In the Debugger menu, go to Debug > Hard Reset. This resets the emulator & Debugger. The emulator starts in a PAUSED mode.
2. Select the emulator window then press the “P Key” to unpause it. Now the Debugger begins and needs another RUN command.
3. Select the Debugger window and press the “F5 Key”. Now VSAV is running again.

Here is my preferred workflow for comparing the (2) SAVE STATES with the Cheatinit command;

Active the emulator window, press the “P Key” to PAUSE the emulator, LOAD STATE 1. activate the Debugger, enter the command Cheatinit. Once you press “Enter” it appears that nothing has happened! This is because the emulator is not running. Now, select the emulator & while it remains PAUSED, LOAD STATE 2 then press the “Tilde Key” also referred to as the “~ Key”. The “Tilde key” advances the emulator by (1) frame of animation. You now have a confirmation from the Debugger that it is tracking 81940 memory addresses for CHEATS. Issue the command; Cheatnext de, 3. Select the emulator and advance the emulator by (1) more frame & see the results on the Debugger: (36) cheats found. If the results were just a few hits, they would be listed out as history. This example found (36) results but it wants to know HOW we desire to receive the data. This command is called Cheatlist. It defaults to the history pane, but we actually want to create a (.TXT) file of the results. Give the Debugger this command; Cheatlist StartCompare.txt then advance the emulator by (1) frame to process the command. The Debugger now reads >Cheatlist startcompare(.TXT). The Debugger will create a (.TXT) file using the name we specified. The location of the newly created file is in our MAME directory.

Let’s discuss a few properties of the Cheatnext command before we analyze the (36) results. We provided the command Cheatnext de, 3. de represents a decreasing value while 3 represents 0x3. We compared nine start inputs against six start inputs, that’s a difference of 3, so a de of 3 was an input to Cheatnext.

While learning and experimenting with the Cheatinit command, it’s important to make an educated guess about the anticipated format of data. Would your custom condition be in FLAG, POINTER, INCREMENT or DECREMENT format? Your SAVE STATES & Cheatnext command should format accordingly.

Exercise #4 Cheatlist(.TXT) Analysis

GOAL: Analyze Cheatlist(.TXT)

Open the file StartCompare(.TXT). You will quickly notice the syntax is identical to VSAV(.XML). This is because the Cheatinit tool is used to generate CHEATS. You can copy & paste these results into your (.XML) file to enable CHEATS within MAME!

Before we begin that process, it’s important to realize the Cheatinit command returns all addresses of memory, meaning it gives addresses in R.O.M. & R.A.M. that meet the condition we set in CheatInit. We cannot use MAME cheats to manipulate R.O.M. During our Pugsy’s Cheats Exploring we documented R.A.M. address ranges for similar descriptions. It’s safe to assume that our answer for the number of Player One Start Inputs is within the address range FF800B to FF8BBC, because it’s R.A.M. Data!

  • Game R.A.M. Data; FF800B to FF8091
  • Match R.A.M. Data; FF8101 to FF8109
  • PL1 R.A.M. Data; FF8450 to FF87BC
  • PL2 R.A.M. Data; FF8850 to FF8BBC

Finally, look at all (36) addresses within the file StartCompare(.TXT). Only one result is within the range FF800B to FF8BBC.

<cheat desc="Possibility 36 : FF8444 (06)">
   <script state="run">

We found it! Player One’s quantity of Start inputs during the character select menu is at FF8444. Therefore, Player Two quantifies Start inputs during the character select menu at FF8844.

We can demonstrate this by creating a CHEAT to change the number of start inputs to always be at value 05. The cheat enables easy selection of a Shadow Character. Here is the script;

<cheat desc="Easy PL1 Shadow Character"> <comment>Choose Random Character</comment>
   <script state="run">

Exercise #5 Visualizing Memory

GOAL: Learn to visualize memory in real-time

Debugger > Debug > New Memory Window.

This new window is amazing. It is real time visualization into values of memory at every address.

While viewing addresses, remember that all numbers are in Base16 hexadecimal! This data reads left-to-right then top-to-bottom. Every pair of characters represent the current value stored in the position’s address. Starting at the top of the table, address 0x000000 equals 0x23 & address 0x000001 equals 0xDF. By default, the address listed at the beginning of the row is the first address in the sequence. By default, the address at the end of the row will always be the address listed at the beginning with a final digit of F. 0x00000F equals 0xD0.

Vsav Memeory Window Example.png

Use the open field to specify an address. This will jump the table to that address. I recommend you only search for addresses which have the last digit as 0x0. Doing so will keep the default formatting described above.

We can now answer one of our previous questions: What is the finite range for Program Space memory? By scrolling to the bottom of this window we see that all possible Program Space Memory addresses are implemented in definitively 6-digits; 0x000000 to 0xFFFFFF.

Exercise #6 Real Time R.A.M. Manipulation

GOAL: Learn to manipulate R.A.M. in real-time

MAME’s Debugger allows real time manipulation of R.A.M. inside this memory window. Only R.A.M. manipulation is allowed. In comparison to CHEATS, these changes do not continuously update the value. This tool allows us to test an address and confirm if it is R.O.M. or R.A.M., if you can change the value, it’s R.A.M.!

Exercise #7 Size of Values

GOAL: Learn about the size of values

From the Debugger’s New Memory Window, search for the address 0xFF8060. Go to the emulator and begin the game. As you press Player One Start, 0xFF8060 & 0xFF8061 simultaneously update to the value of 0x01. This is because the value of 0x01010101 is written to address 0xFF8060.

It is detailed at the beginning of the operator's manual for the Motorola 68k that a BYTE is 8 bits, a WORD is 16 bits and a DOUBLE WORD or DWORD is 32 bits. Please know that a BYTE is (2) digits in Base16 hexadecimal (0x00 to 0xFF), a WORD is (4) digits in Base16 hexadecimal (0x0000 to 0xFFFF) & a DWORD is (8) digits in Hex (0x00000000 to 0xFFFFFFFF).

You cannot use the Debugger’s New Memory Window to manipulate R.A.M. In real time when it is looking for a WORD or DWORD. There is simply too many digits to enter in the given time. Manipulating these addresses is best using CHEATS.

This answers our previous question; Why are some values greater than two digits?

Definition Length of Bits Number of Digits Hex Ranges
BIT 1 Not Applicable Not Applicable
BYTE 8 2 0x00 to 0xFF
WORD 16 4 0x0000 to 0xFFFF
DWORD 32 8 0x00000000 to 0xFFFFFFFF

We now have the tool & knowledge to answer another previous questions; Where does R.A.M. delineate between game, match & player data? Our previous notes show:

  • Game R.A.M. Data; FF800B to FF8091
  • Match R.A.M. Data; FF8101 to FF8109
  • PL1 R.A.M. Data; FF8450 to FF87BC
  • PL2 R.A.M. Data; FF8850 to FF8BBC

Let’s open a New Memory Window to visualize where changes occur. First, search for the address 0xFF8000, then scroll up a little to see a wider range of addresses, let the lowest visible address be 0xFF7F10.

Now, inside the emulator, hold the “ENTER key” and watch the memory as the game is sped up during Game Intro Mode. Notice how values from 0xFF7FA0 to 0XFF7FF0 are constantly changing at a rate significantly different then the values across line 0xFF8000. Notice how 0xFF8001 changes values every time the game transitions to a new game state. This is the delineation of R.A.M. during the game state.

Next let’s try to delineate Match Data. Search 0xFF8100 and scroll up to analyse the demo-mode similarly. Notice how address 0xFF8101 only updates when the Battle-Demo is active. It’s safe to assume that Match Data begins here.

Next, let’s analyze PL1 Data. Search 0xFF8450 and scroll up and review the Game Intro mode similarly. Notice that during the battle demo-mode, only values load starting at 0xFF8400. This is the delineation. We can assume PL2 R.A.M. addresses start at 0xFF8800. Lastly, we know the range of PL1 is 0xFF8400 to 0xFF87FF. We can assume the PL2 range is 0xFF8800 to 0xFFBFF.

Here are the results;
  • Game R.A.M. Data; FF8000 to FF80FF
  • Match R.A.M. Data; FF8100 to FF83FF
  • PL1 R.A.M. Data; FF8400 to FF87FF
  • PL2 R.A.M. Data; FF8800 to FF8BFF

Exercise #8 -ListXML_VSAV

GOAL: Learn about the Debugger command; -ListXML

I learned about this tool from a Youtube channel owned by Thank you for the demonstration!

Mame has a tool to list out the memory uses of each Game Data File. The MAME Debugger command is ListXML. We execute the command from the Window’s Command Prompt. Open the Command Prompt then change the directory to the MAME folder. Give this command: mame vsav -listxml > vsavDATA.xml. This creates a (.XML) file in your MAME directory. Open this file with NOTEPAD then scroll to the bottom.

Here is the last portion of information;

<mame build="0.139[RR] (Aug  8 2010)" debug="no" mameconfig="10">
   <game name="vsav" sourcefile="cps2.c">
  	 <description>Vampire Savior: The Lord of Vampire (Euro 970519)</description>
  	 <rom names="vm3e.03d" size="524288" crc="f5962a8c" sha1="e37d48b78186c7c097894d6c17faf7c9333f61eb" region="maincpu" offset="0"/>
  	 <rom names="vm3e.04d" size="524288" crc="21b40ea2" sha1="6790fa3e618850f518cbd470f44434a71be6f29f" region="maincpu" offset="80000"/>
  	 <rom names="vm3.05a" size="524288" crc="4118e00f" sha1="94ce8abc5ff547667f4c6022d84d0ed4cd062d7e" region="maincpu" offset="100000"/>
  	 <rom names="vm3.06a" size="524288" crc="2f4fd3a9" sha1="48549ff0121312ea4a18d0fa167a32f905c14c9f" region="maincpu" offset="180000"/>
  	 <rom names="vm3.07b" size="524288" crc="cbda91b8" sha1="31b20aa92422384b1d7a4706ad4c01ea2bd0e0d1" region="maincpu" offset="200000"/>
  	 <rom names="vm3.08a" size="524288" crc="6ca47259" sha1="485d8f3a132ccb3f7930cae74de8662d2d44e412" region="maincpu" offset="280000"/>
  	 <rom names="vm3.09b" size="524288" crc="f4a339e3" sha1="abd101a55f7d9ddb8aba04fe8d3f0f5d2006c925" region="maincpu" offset="300000"/>
  	 <rom names="vm3.10b" size="524288" crc="fffbb5b8" sha1="38aecb820bd1cbd17287848c3ffb013e1d464ddf" region="maincpu" offset="380000"/>
  	 <rom names="vm3.13m" size="4194304" crc="fd8a11eb" sha1="21b9773959e17976ff46b75a6a405042836b2c5f" region="gfx" offset="0"/>
  	 <rom names="vm3.15m" size="4194304" crc="dd1e7d4e" sha1="30476e061cdebdb1838b83f4ebd5efae12b7dbfb" region="gfx" offset="2"/>
  	 <rom names="vm3.17m" size="4194304" crc="6b89445e" sha1="2abd489839d143c46e25f4fc3db476b70607dc03" region="gfx" offset="4"/>
  	 <rom names="vm3.19m" size="4194304" crc="3830fdc7" sha1="ebd3f559c254d349e256c9feb3477f1ed7518206" region="gfx" offset="6"/>
  	 <rom names="vm3.14m" size="4194304" crc="c1a28e6c" sha1="012803af33174c0602649d2a2d84f6ee79f54ad2" region="gfx" offset="1000000"/>
  	 <rom names="vm3.16m" size="4194304" crc="194a7304" sha1="a19a9a6fb829953b054dc5c3b0dc017f60d37928" region="gfx" offset="1000002"/>
  	 <rom names="vm3.18m" size="4194304" crc="df9a9f47" sha1="ce29ff00cf4b6fdd9b3b1ed87823534f1d364eab" region="gfx" offset="1000004"/>
  	 <rom names="vm3.20m" size="4194304" crc="c22fc3d9" sha1="df7538c05b03a4ad94d369f8083799979e6fac42" region="gfx" offset="1000006"/>
  	 <rom names="vm3.01" size="131072" crc="f778769b" sha1="788ce1ad8a322179f634df9e62a31ad776b96762" region="audiocpu" offset="0"/>
  	 <rom names="vm3.02" size="131072" crc="cc09faa1" sha1="2962ef0ceaf7e7279de3c421ea998763330eb43e" region="audiocpu" offset="28000"/>
  	 <rom names="vm3.11m" size="4194304" crc="e80e956e" sha1="74181fca4b764fb3c56ceef2cb4c6fd6c18ec4b6" region="qsound" offset="0"/>
  	 <rom names="vm3.12m" size="4194304" crc="9cd71557" sha1="7059db25698a0b286314c5961c618f6d2e6f24a1" region="audiocpu" offset="400000"/>
  	 <chip type="cpu" tag="maincpu" name="68000" clock="16000000"/>
  	 <chip type="cpu" tag="audiocpu" name="Z80" clock="8000000"/>
  	 <chip type="audio" tag="qsound" name="Q-Sound" clock="4000000"/>
  	 <display type="raster" rotate="0" width="384" height="224" refresh="59.629403" pixclock="8000000" htotal="518" hbend="64" hbstart="448" vtotal="259" vbend="16" vbstart="240" />
  	 <sound channels="2"/>
  	 <input players="2" buttons="6" coins="2" service="yes">
  		 <control type="joy8way"/>

I highlighted the rom names & memory uses accordingly. We now have a basic understanding of which type of data is in each file;

I shared a few examples of MAME’s extremely powerful commands. There is so much more it can do, like watchpoint & step over. MAME’s official documentation is here;

VSAV(.ZIP) Analysis

GOAL: Assess data

We are going to unzip the Game Files. I chose to navigate to the MAME > roms directory. Now Right Mouse Click & Extract All… then open the new folder.

These (22) files represent the entirely of bytes needed to run the game. Notice how the file names of “vm3” match the (20) file names listed within the -listxml exercise. These are encrypted binary files. This data is in 'BINARY FORMAT.

Here is a table for reference:

File Name Memory Use File Size Memory Range Encryption
vm3e.03d Main C.P.U. 524288 Bytes 0x000000 - 0x07FFFF Byte Swap 12 34 = 21 43
vm3e.04d Main C.P.U. 524288 Bytes 0x080000 - 0x0FFFFF Byte Swap 12 34 = 21 43
vm3.05a Main C.P.U. 524288 Bytes 0x100000 - 0x17FFFF Byte Swap 12 34 = 21 43
vm3.06a Main C.P.U. 524288 Bytes 0x180000 - 0x1FFFFF Byte Swap 12 34 = 21 43
vm3.07b Main C.P.U. 524288 Bytes 0x200000 - 0x27FFFF Byte Swap 12 34 = 21 43
vm3.08a Main C.P.U. 524288 Bytes 0x280000 - 0x2FFFFF Byte Swap 12 34 = 21 43
vm3.09b Main C.P.U. 524288 Bytes 0x300000 - 0x37FFFF Byte Swap 12 34 = 21 43
vm3.10b Main C.P.U. 524288 Bytes 0x380000 - 0x3FFFFF Byte Swap 12 34 = 21 43
vm3.10b 0x0139DB extra space Not Applicable 0x3EC624 - 0x3FFFFF Byte Swap 12 34 = 21 43
vm3.13m Graphics
vm3.15m Graphics
vm3.17m Graphics
vm3.19m Graphics
vm3.14m Graphics
vm3.16m Graphics
vm3.18m Graphics
vm3.20m Graphics
vm3.01 Audio C.P.U.
vm3.02 Audio C.P.U.
vm3.11m Qsound
vm3.12m Qsound
qsound.bin Emulator required data
vsav.key Emulator required data

Shared R.A.M. Bug

While investigating a well documented Alter-Ego Reduction Bug, I noticed all of the interactions were using moves and move properties unique to their character.

Character Applicable Moves
Lei-Lei Chuukadan, Tenraiha
Bulleta ES-Pursuit (Apple Explosion)
Lilith D.F. Deactivation
Felicia D.F. Helper (Leaving the screen)

While investigating the R.A.M., I had no findings in PL1 R.A.M. Data & PL2 R.A.M. Data ranges;

  • PL1 R.A.M. Data; FF8400 to FF87FF
  • PL2 R.A.M. Data; FF8800 to FF8BFF

All of these unique moves had to be documented somewhere else! The logical place for Unique Player Data is directly after Standard Player Data ranges. By observing values in a New Memory Window, I confirmed that the theory is correct. The allocated ranges are now:

  • Game R.A.M. Data; FF8000 to FF80FF
  • Match R.A.M. Data; FF8100 to FF83FF
  • PL1 R.A.M. Data; FF8400 to FF87FF
  • PL2 R.A.M. Data; FF8800 to FF8BFF
  • Unique Player R.A.M. Data; FF8C000 to ??????

Lastly, by visualizing memory beginning at FF8C000 & doing all of the moves listed with the bug, it is revealed that all moves interact in the same address range of R.A.M.; 0xFF9400 to 0xFF94FF. My results were tweeted here;

Memory Map

A MEMORY MAP is a table which lists all addresses and their uses. As of the time I am writing this, the collective understanding of VSAV’s MEMORY MAP is available across numerous platforms:

  • Pugsy’s Cheat file
  • Pugsy’s Cheat Forums
  • Felineki’s notes
Thanks for sharing with me!
The Cutting Room Floor:
  • VSAV Training Mode script
  • ChooseaGoose’s notes
Thanks for sharing with me!
  • A custom cheat file shared by VMP_KyleW
  • XenoBlip’s Notes (Data is not verified!)

There is an opportunity to centralize this data, making it publicly available & publicly enabled to contribute. I’m interested in enabling the task, but do not know the optimal platform. This platform should offer the versatility of noting each “game state” as well as being user-friendly to the Japanese. I will do some research & hopefully have a solution…. does anyone have industry experience with this type of public data platform?

Review Goals & Questions

Now that the lessons & workflows are complete, let’s do a final review of my project's goals & the outstanding questions.


Find hidden content
Unlock hidden content; Characters, Stages, Moves, Colors, Debug Menu
Further Explain Bugs
Understand how the CPU can do special moves in situations a player cannot
  • This concept was proven by understanding the POINTERS needed to command characters to do special moves. Once I knew these POINTERS, I was able to visualize the memory and confirm a CPU controlled opponent activates special moves by directly changing these POINTER values, rather then giving necessary controller inputs to execute special moves. Forcing these POINTERS causes unique results, such as removing restrictions of when specials can be executed as well as not requiring the meter necessary to complete an ES-Move.


Where are OVERFLOW values coming from?
  • This is unique per instance, The Program Data needs to be evaluated to understand each answer. A full Disassembly of the MACHINE CODE is needed.
Is there R.A.M. values that remain during unique game “modes”?
  • Open up the Debugger’s New Memory Window to visualize where these changes occur. Some values, such as which character you are using & what conditions are met to fight the Mid-Boss and Oboro are stored between matches.
How to determine if the address is in POINTER, FLAG, INCREMENT or DECREMENT format?
  • We can assess each case individually by manipulating R.A.M. and verifying results. However, the MACHINE CODE specifies the length of values per operation, a full Disassembly of the MACHINE CODE is needed to develop this answer.
How do you centralize documentation of a Memory Map?
  • I don’t have an answer yet. I will continue to investigate but remain open to recommendations.


To achieve a portion of my initial goals, the 'Disassembly of the MACHINE CODE is required. The output of this task is the total information of:

  • Where values are READ
  • Where values are WRITE
  • When values are READ
  • When values are WRITE
  • What values are READ
  • What values are WRITE

It’s not easy! All operations are listed in unique code directly relating to the PROCESSOR; the Motorola 68K. Each operation is a sequence of numerous calculations. When this is done, we obtain all of the MACHINE CODE instruction. We can begin to assume the actual PROGRAM SOURCE CODE. I’ve read in some forums that the CPS-II is believed to be written in Donald Knuth’s C Programming Language.

Just recently a freeware disassembler, developed by the NSA, called GHIDRA, became open-source as of March 2019. This Disassembler software is compatible with the Motorola 68K. (Thanks for the recommendation Zinac!)

One of my next projects is to begin the DISASSEMBLY task. Luckily,’s Youtube channel has some recent videos on the tool. I have lots to learn! If It gets enough interest, it would be great to allow public contribution too.

R.A.M. Manipulation - Findings

  • RAM Manipulation to access colors 0x08 & 0x09
  • RAM Manipulation to access unlisted Color Palettes
The RAM location for allocating P1 or P2's color is the last (2) digits of a hexadecimal number, so there are 256 possible variables; most of which are horrendous, but some real gold exist!
  • RAM Manipulation to access unintended stages
Black & DF-Enabled
Character Select
  • RAM Manipulation to access Mid-Boss variant stages
Iron Horse Iron Terror
Fetus of God
  • RAM Manipulation to access a hidden title screen
  • RAM Manipulation to play as D.F. Zabel
  • RAM Manipulation - Versus Screen Transitions Mid-Fight
  • RAM manipulation to force Character Intros
  • RAM & Win-Lose Checks
  • RAM & Hidden Menu Option
  • RAM & Special Boss Requirements
ES-Finished -
Lose a Bat -
  • RAM & Variables at Character Select Screen
  • RAM & PL1 MO/LI Remove Projectile Restrictions
  • RAM & CPU Special Moves as Instruction
  • RAM Manipulation - Verify Dizzy Bug Setups
  • RAM Manipulation - Stage assets & Wheels at Iron Horse Iron Terror
  • RAM Manipulation - Victor's Unused Functional Special Moves
  • RAM Manipulation - Anakaris's unlisted Special Moves
  • RAM Manipulation - Special Move Graphical Pointer Oddities
  • RAM Manipulation - Special Move Pointers
  • RAM Manipulation - Verify All Win-Poses
Jedah & Lilith
Lei-Lei & Q-Bee
Bishamon & Felicia
Gallon & Victor
Bulleta & Demitri
  • RAM Manipulation - Verify custom Intros
Jedah & Felicia
  • RAM Manipulation - Verify missing throw commands
  • RAM Manipulation - Enable a CARD system for collecting carnival style tickets
  • RAM Manipulation - Instantly fight Oboro with special ending conditions
  • RAM Manipulation - D.F. Details
  • RAM Manipulation - Shared RAM address details

R.O.M. Manipulation - General Overview

A few notes about what I understand:

  • R.O.M. includes Graphics, Audio, Program Data & Input/Output functions
  • R.O.M. is not easily manipulated with Mame’s CHEATS
  • R.O.M. manipulation requires another tool called a “Hexadecimal Editor”. Hex editors have to compile data back into a native (encrypted) format so it can run on an emulator.
  • Graphic, Audio & Program Data is managed separately

This resource is amazing at describing M68K instruction:

It would be awesome if others were interested in adding to this wiki with their tools & workflows for R.O.M. manipulation.

Here are some ROM findings of "Data":

  • High Score Values
  • Character Names nested with the Debug Menu
  • Service Menus
  • Staff Credits
  • Service Menu - Submenus

R.O.M. Manipulation - Binary Files & Decryption

Super THANK YOU to for mentoring me through this tasks!

The MAME Debugger tool has (2) exports we need to reference.

  • Within Mame's Debugger, run VSAV, then enter the following command.
DUMP VSAV-Word-Ascii.dmp,0,1000000,4,1
This command will create a (.DMP) within your MAME directory. This file is text enabled, you can read it with any notepad, wordpad, etc. Most importantly, this text file is the authoritative document for all of the bytes which are Data. This include ASCII text & reference tables. Although all byte values are represented, most are actually OpCode (Operation Code) which are further manipulated prior to feeding the M68K.
  • Within Mame's Debugger, run VSAV, then enter the following command.
DASM VSAV.asm,0,1000000
This command will create a (.ASM) within your MAME directory. This file is text enabled, you can read it with any notepad, wordpad, etc. Most importantly, this text file is the authoritative document for all of the bytes which are OpCode. This includes all instruction for the M68K. Although all byte values are represented, some are actually Data.

With these (2) references in hand, our next objective is to validate what is Data & what is OpCode. The following table depicts values of vm3e.03d. I chose these addresses because it's a combination of OpCode & Data, the Data is legible ASCII within the DUMP file, the OpCode is not legible ASCII.

Source vm3e.03d 0x000000 (OpCode) 0x000790 (ASCII Data) 0x07FFF0 (OpCode) Validation
Encrypted ROM DF23 746F 5542 2053 E53C 06A2 Encrypted
MAME DUMP 23DF 6F74 4255 5320 3CE5 A206 Data values are correct
MAME DASM 00FF 8000 7EBE 0483 0076 542E OpCode values are Correct

With the aid of , we found (4) tools which claim to decrypt CPS2 ROMS. I tested each tool, the results are presented in the table below.

Source vm3e.03d 0x000000 (OpCode) 0x000790 (ASCII Data) 0x07FFF0 (OpCode) Download Page Comment
X.C.O.P.Y. 00FF 8000 7EBE 0483 0076 542E Correct OpCode, Wrong Data
vsavdi FF00 0080 5542 2053 7600 2E54 Wrong Data, Wrong Opcode
CPS2dec FF00 0080 5542 2053 7600 2E54 Wrong Data, Wrong Opcode
SwapEndian 23DF 6F74 4255 5320 3CE5 A206 Correct Data, Wrong OpCode

While carefully reviewing both tables, nothing is an exact match, but, CPS2dec & vsavdi are both close! They need to be Byte-Swapped to completion. Luckily, the tool SwapEndian does the byte-swap function needed to complete the decryption. Use SwapEndian on the vsavdi file or after the CPS2dec tool & the decryption is complete!

Source vm3e.03d 0x000000 (OpCode) 0x000790 (ASCII Data) 0x07FFF0 (OpCode) Comment
(vsavdi or cps2dec) then SwapEndian 00FF 8000 4255 5320 0076 542E values are correct!

Now that we have a workflow for the decryption, it's time to decrypt the first (8) files, then concatenate (add together linearly) each file in a HexEditor program to create a single binary file of decrypted bytes.

Here is a download link, of the completed file, for your convenience.

This file will properly load into a disassembler program like IDA-PRO or Ghidra.

R.O.M. Manipulation - Color Palettes


Do not use color hacks online; make sure you have a backup.

The locations below are ROM locations, which can be accessed to manipulate the base color palettes of sprites. It's a lot of work, but is the opportunity for a full custom color hack.

Bulleta (BB Hood)


LP Location 0000C1AC
MP Location 0000C22C
HP Location 0000C2AC
LK Location 0000C32C
MK Location 0000C3AC
HK Location 0000C42C
3P Location 0000C4AC 
3K Location 0000C52C
AP Location 0000C5AC
AK Location 0000C62C

Versus Screen/Character Select Portraits

LP 0002BF0C
MP 0002C10C
HP 0002C30C
LK 0002C50C
MK 0002C70C
HL 0002C90C
3P 0002CB0C
3K 0002CD0C
AP Location
AK Location

Character Select Icon


Demitri Maximov


LP Location Frame 1 0000C6AC
LP Location Frame 2 0001ACCC

MP Location Frame 1 0000C72C
MP Location Frame 2 0001ACEC

HP Location Frame 1 0000C7AC
HP Location Frame 2 0001AD0C

LK Location Frame 1 0000C82C
LK Location Frame 2 0001AD2C

MK Location Frame 1 0000C8AC
MK Location Frame 2 0001AD4C

HK Location Frame 1 0000C92C
HK Location Frame 2 0001AD6C

3P Location Frame 1 0000C9AC
3P Location Frame 2 0001AD8C

3K Location Frame 1 0000CA2C
3K Location Frame 2 0001ADAC

AP Location Frame 1
AP Location Frame 2

AK Location Frame 1
AK Location Frame 2

Versus Screen/Character Select Portraits

LP 0002BF2C
MP 0002C12C
HP 0002C32C
LK 0002C52C
MK 0002C72C
HK 0002C92C
3P 0002CB2C
3K 0002CD2C

Character Select Icon


Gallon (Jon Talbain)


LP Location 0000CBAC
MP Location 0000CC2C
HP Location 0000CCAC
LK Location 0000CD2C
MK Location 0000CDAC
HK Location 0000CE2C
3P Location 0000CEAC
3K Location 0000CF2C
AP Location 0000CFAC
AK Location 0000D02C

Versus Screen/Character Select Portraits

LP 0002BF4C
MP 0002C14C
HP 0002C34C
LK 0002C54C
MK 0002C74C
HK 0002C94C
3P 0002CB4C
3K 0002CD4C

Character Select Icon


Victor von Geldenheim


LP Location 0000D0AC
MP Location 0000D12C
HP Location 0000D1AC
LK Location 0000D22C
MK Location 0000D2AC
HK Location 0000D32C
3P Location 0000D3AC
3K Location 0000D42C
AP Location 0000D4AC
AK Location 0000D52C

Versus Screen/Character Select Portraits

LP 0002BF6C
MP 0002C16C
HP 0002C36C
LK 0002C56C
MK 0002C76C
HK 0002C96C
3P 0002CB6C
3K 0002CD6C 
AP Location
AK Location

Character Select Icon


Zabel Zarock(Lord Raptor)


LP Location 0000D5AC
MP Location 0000D62C
HP Location 0000D6AC
LK Location 0000D72C
MK Location 0000D7AC
HK Location 0000D82C
3P Location 0000D8AC
3K Location 0000D92C
AP Location 0000D9AC
AK Location 0000DA2C

Versus Screen/Character Select Portraits

LP 0002BF8C
MP 0002C18C
HP 0002C38C
LK 0002C58C
MK 0002C78C
HK 0002C98C
3P 0002CB8C
3K 0002CD8C 
AP Location
AK Location

Character Select Icon


Morrigan Aensland


LP Location 0000DAAC
MP Location 0000DB2C
HP Location 0000DBAC
LK Location 0000DC2C
MK Location 0000DCAC
HK Location 0000DD2C
3P Location 0000DDAC
3K Location 0000DE2C
AP Location 0000DEAC
AK Location 0000DF2C

Versus Screen/Character Select Portraits

MP 0002C1AC
HP 0002C3AC
LK 0002C5AC
MK 0002C7AC
HK 0002C9AC
3P 0002CBAC
3K 0002CDAC 
AP Location
AK Location

Character Select Icon


Victory Portraits

LP 0002D92C - 0002D9C9
AP Location
AK Location



LP Location 0000DFAC
MP Location 0000E02C
HP Location 0000E0AC
LK Location 0000E12C
MK Location 0000E1AC
HK Location 0000E22C
3P Location 0000E2AC
3K Location 0000E32C 
AP Location 0000E3AC
AK Location 0000E42C

Versus Screen/Character Select Portraits

MP 0002C1CC
HP 0002C3CC
LK 0002C5CC
MK 0002C7CC
HK 0002C9CC
3P 0002CBCC
3K 0002CDCC 
AP Location
AK Location

Character Select Icon




LP Location 0000E4AC
MP Location 0000E52C
HP Location 0000E5AC
LK Location 0000E62C
MK Location 0000E6AC
HK Location 0000E72C
3P Location 0000E7AC
3K Location 0000E82C 
AP Location 0000E8AC
AK Location 0000E92C

Versus Screen/Character Select Portraits

MP 0002C1EC
HP 0002C3EC
LK 0002C5EC
MK 0002C7EC
HK 0002C9EC
3P 0002CBEC
3K 0002CDEC  
AP Location
AK Location

Character Select Icon




LP Location 0000E9AC
MP Location 0000EA2C
HP Location 0000EAAC
LK Location 0000EB2C
MK Location 0000EBAC
HK Location 0000EC2C
3P Location 0000ECAC
3K Location 0000ED2C  
AP Location 0000EEAC
AK Location 0000EF2C

Versus Screen/Character Select Portraits

LP 0002C00C
MP 0002C20C
HP 0002C40C
LK 0002C60C
MK 0002C80C
HK 0002CA0C
3P 0002CC0C
3K 0002CE0C  
AP Location
AK Location

Character Select Icon


Aulbath (Rikuo)


LP Location 0000EEAC
MP Location 0000EF2C
HP Location 0000EFAC
LK Location 0000F02C
MK Location 0000F0AC
HK Location 0000F12C
3P Location 0000F1AC
3K Location 0000F22C
AP Location 0000F2AC
AK Location 0000F32C

Versus Screen/Character Select Portraits

LP 0002C02C
MP 0002C22C
HP 0002C42C
LK 0002C62C
MK 0002C82C
HK 0002CA2C
3P 0002CC2C
3K 0002CE2C  
AP Location
AK Location

Character Select Icon




LP Location 0000F3AC
MP Location 0000F42C
HP Location 0000F4AC
LK Location 0000F52C
MK Location 0000F5AC
HK Location 0000F62C
3P Location 0000F6AC
3K Location 0000F72C
AP Location 0000F7AC
AK Location 0000F82C

Versus Screen/Character Select Portraits

LP 0002C04C
MP 0002C24C
HP 0002C44C
LK 0002C64C
MK 0002C84C
HK 0002CA4C
3P 0002CC4C
3K 0002CE4C  
AP Location
AK Location

Character Select Icon




LP Location 0000FCAC
MP Location 0000FD2C
HP Location 0000FDAC
LK Location 0000FE2C
MK Location 0000FEAC
HK Location 0000FF2C
3P Location 0000FFAC
3K Location 0001002C
AP Location 000100AC
AK Location 0001012C

Versus Screen/Character Select Portraits

LP 0002C08C
MP 0002C28C
HP 0002C48C
LK 0002C68C
MK 0002C88C
HK 0002CA8C
3P 0002CC8C
3K 0002CE8C  
AP Location
AK Location

Character Select Icon


Lei Lei (Hsien-Ko)


LP Location 000101AC
MP Location 0001022C
HP Location 000102AC
LK Location 0001032C
MK Location 000103AC
HK Location 0001042C
3P Location 000104AC
3K Location 0001052C
AP Location 000105AC
AK Location 0001062C

Versus Screen/Character Select Portraits

LP 0002C0AC
MP 0002C2AC
HP 0002C4AC
LK 0002C6AC
MK 0002C8AC
3P 0002CCAC
3K 0002CEAC  
AP Location
AK Location

Character Select Icon




LP Location 000106AC
MP Location 0001072C
HP Location 000107AC
LK Location 0001082C
MK Location 000108AC
HK Location 0001092C
3P Location 000109AC
3K Location 00010A2C
AP Location 00010AAC
AK Location 00010B2C

Versus Screen/Character Select Portraits

LP 0002C0CC
MP 0002C2CC
HP 0002C4CC
LK 0002C6CC
MK 0002C8CC
3P 0002CCCC
3K 0002CECC  
AP Location
AK Location

Character Select Icon




LP Location 00010BAC
MP Location 00010C2C
HP Location 00010CAC
LK Location 00010D2C
MK Location 00010DAC
HK Location 00010E2C
3P Location 00010EAC
3K Location 00010F2C
AP Location 00010FAC
AK Location 0001102C

Blood shared with all of Jedah's palettes

Versus Screen/Character Select Portraits

LP 0002C0EC
MP 0002C2EC
HP 0002C4EC
LK 0002C6EC
MK 0002C8EC
3P 0002CCEC
3K 0002CEEC  
AP Location
AK Location

Character Select Icon



Character Select

NOTE This still does not get all the pink around the character portraits.

Start 0005189C
End   00051A5B

Misc. Locations


Lifebar and super meter


Life bar blending

Note: You only need to edit the one color on each line.


Combo Number/Wincounter/Combo Text


Flash Combo Counter/Timer/Fight Logo


Published Works

Let’s recognize the publication of projects.


  • Leverage DarkSoft hardware to rewrite the binary files and play a graphics modifications on native CPS-II hardware.
  • Created & shared tools for interfacing graphics.


  • Published a custom CHEATS file representing R.A.M. manipulation efforts.
  • Explained the Alter-Ego Reduction Bug & clarified it as a Shared Ram Bug
  • Found a hidden move for Victor, from Night Warriors - Jed documented another attack in 2014.


  • Custom burnt an EPROM, essentially creating a “Software Patch” to emulate training mode on CPS-II hardware
  • Published a custom (.LUA) scripts for VSAV Training Mode
  • Provides addresses for character color manipulation


  • Documented hidden, unfinished and cut content on T.C.R.F.
  • Explained the infamous Dizzy Bug as an improper underflowing conditions
Vampire Savior
General FAQHUDControlsTraining ModesCommunity Info/Find Players!GlossaryLinks
Characters AnakarisAulbath (Rikuo)BishamonBulleta (BB Hood)DemitriFeliciaGallon (Talbain)JedahLei-Lei (Hsien-ko)LilithMorriganQ-BeeSasquatchVictorZabel (Lord Raptor)
Mechanics EsotericsDark ForceCommand SupersRenda BonusTutorialSecrets
Other Extra CharactersJapanese Test MenuVampire Savior 2 ChangesVampire Chronicle ChangesPlayersHacksReverse Engineering