fafling
Gear Supporter
It doesn't appear to have been found already. There was a report recently on Kronos Discord by user WhiteySnakey that the nightmare difficulty could be unlocked in the PSX version of Doom, and he thought that since the Saturn version shares some similarities with the PSX one, that difficulty level could also be hidden inside.
So I gave it a shot with Kronos Cheat search feature and Yabause debugger, and got lucky.
But first thing first, to avoid screen flickers that can occur in Doom if many cheat codes are enabled (such as those ones for the US version), as well as reduce the CPU cycles used by the Action replay handler, I recommend to use a different master code than the default one. There's a specific master code to use for each region of Saturn Doom (the part that changes from the default code is in bold) :
Here is how the main menu looks in the Japanese version with the cheat enabled :

In game, monster placement is the same as in Ultra Violence, but they move faster, shoot at a faster rate and their projectiles move faster. Contrary to the PC version, monsters don't respawn (thankfully, it's hard enough).
I don't know if the game can be completed in that mode, I've only been through 4 levels before I got toasted.
Also note that when continuing a game with a password without the cheat, the difficulty is set by the password, however a password obtained with the cheat enabled and input with the cheat disabled will set the difficulty as "I am a wimp". So a password obtained in the nightmare difficulty must be input with the cheat enabled in order to continue the game with the same difficulty. And a password obtained in an easier difficulty can be used with the cheat enabled to continue the game in nightmare mode.
The cheat codes work in Kronos emulator without needing the master code. They should be input after the Sega logo, in Tools > Cheat Lists.
A tutorial on how to use the Cheat search in Kronos, made by @Benjamin Siskoo :
An Action replay code is obtained from the address found in Kronos Cheat search that way :
The FXXXXXXX part of the master code that is changed replaces the value at address 0XXXXXXX with 0xC305 which is a "TRAPA #0x5" instruction that triggers the AR handler. The value at 0XXXXXXX must meet the following criteria :
So I gave it a shot with Kronos Cheat search feature and Yabause debugger, and got lucky.
But first thing first, to avoid screen flickers that can occur in Doom if many cheat codes are enabled (such as those ones for the US version), as well as reduce the CPU cycles used by the Action replay handler, I recommend to use a different master code than the default one. There's a specific master code to use for each region of Saturn Doom (the part that changes from the default code is in bold) :
- US version master code :
F603CD70 C305
B6002800 0000 - Japanese version master code :
F603CDCC C305
B6002800 0000 - European version master code :
F603CC2C C305
B6002800 0000
- US version cheat code :
1604A2AA 0004
16026F52 0009
1602712A 61D0
160286E8 E104 - Japanese version cheat code :
1604A306 0004
16026F6E 0009
160271A6 622C
16028754 E104 - European version cheat code :
1604A166 0004
16026E1E 0009
16027056 6084
16028664 E104
Here is how the main menu looks in the Japanese version with the cheat enabled :

In game, monster placement is the same as in Ultra Violence, but they move faster, shoot at a faster rate and their projectiles move faster. Contrary to the PC version, monsters don't respawn (thankfully, it's hard enough).
I don't know if the game can be completed in that mode, I've only been through 4 levels before I got toasted.
Also note that when continuing a game with a password without the cheat, the difficulty is set by the password, however a password obtained with the cheat enabled and input with the cheat disabled will set the difficulty as "I am a wimp". So a password obtained in the nightmare difficulty must be input with the cheat enabled in order to continue the game with the same difficulty. And a password obtained in an easier difficulty can be used with the cheat enabled to continue the game in nightmare mode.
The cheat codes work in Kronos emulator without needing the master code. They should be input after the Sega logo, in Tools > Cheat Lists.
A tutorial on how to use the Cheat search in Kronos, made by @Benjamin Siskoo :
An Action replay code is obtained from the address found in Kronos Cheat search that way :
- The 1st part of the code is the hexadecimal memory address found in Kronos for a 16 bit value, with the initial 0 of the address generally replaced by 1. There are other possibilities detailed here : ActionReplay - Yabause. However, note that prefixing a code with "0" or "D" can cause issues in the AR handler (all or part of the enabled codes can be ignored).
- The 2nd part is the hexadecimal 16 bit value to be set at that memory address.
- The 1st code sets the number of the difficulty mode displayed by the main menu to 4 which corresponds to the nightmare difficulty (difficulty levels are numbered in order of increasing difficulty starting at 0, and the game initializes that value to 2, which is hurt me plenty). This value is increased or decreased when the difficulty option is modified, and when the player presses start at the main menu, this value sets a separate variable that contains the gameplay difficulty level .
- The 2nd code forces the function that handles the change of the difficulty option on the main menu to consider the case of a press to the left, which should decrease the difficulty, as a press to the right. Since difficulty is above the maximum difficulty where option is modified by a press to the right (that is above hurt me plenty), this code prevents any change of the difficulty level through this option.
- The 3rd code changes the least significant bytes of the start address of the table containing the difficulty level names so that the computation of the address of the current difficulty name points to the string "nightmare." (start_address + 16 * difficulty_number). That string is from the text displayed after the last of the ultimate Doom levels. Displaying that string is not only a neat way to let the player know that the AR code is enabled, but it also prevents a crash at the menu : it happens if the displayed difficulty is set to 4 without changing the table start address, as the game tries to display the passwords alphabet as the difficulty name (it follows the difficulty names table in memory) and fails because that string is too long.
- The 4th code prevents the difficulty read from the passwords to change the displayed difficulty number and the gameplay difficulty. This is forcing the nightmare difficulty on any passwords input in the option menu or in the pause menu. The passwords can't save the nightmare difficulty number because they encode that number on only 2 bits, which you can see in the PSX reverse engineered code. That limits the encoded difficulty to 4 possible values that don't include the 5th one needed for nightmare (also explains that the passwords obtained in nightmare contain "I am a wimp" difficulty as the 2 lower bits of 4 are 0).
- It delays the update of VDP1's frame buffer change or erasure flags that takes place in the vblank out interrupt handler. The higher the number of enabled AR codes, the longer it takes for the AR handler to execute, the more it delays VDP1's flags update. That update is timing sensitive with a tight limit, and it it occurs too late, the frame buffer switch is delayed by a screen frame, or an unwanted frame buffer erasure can be triggered and the screen flickers.
- There are 3 interrupts that occur each screen frame in Doom (vblank out, SMPC's interrupt back, and vblank in), so the default master code calls the AR handler 3 times the vertical video frequency per second (180 calls per second in NTSC). That is overkill, as the AR handler doesn't need to set cheat values that often, and once per screen frame is enough. More than that is wasting CPU cycles that Saturn Doom desperately needs given how poorly it can perform.
The FXXXXXXX part of the master code that is changed replaces the value at address 0XXXXXXX with 0xC305 which is a "TRAPA #0x5" instruction that triggers the AR handler. The value at 0XXXXXXX must meet the following criteria :
- Be an instruction actually executed by the main CPU, otherwise the AR handler will never be called.
- Have no side effect on the program execution if it's not executed : the AR handler call will replace that instruction, so its disappearance mustn't change the program flow.
- Not be a delay slot instruction (an instruction following a branch instruction and executed during the delay incurred by the branch), because the TRAPA instruction isn't compatible with that and will cause an illegal instruction exception that will freeze the console.
Last edited: