bsnes-emu / bsnes

bsnes is a Super Nintendo (SNES) emulator focused on performance, features, and ease of use.
Other
1.69k stars 158 forks source link

Ram initialization values #140

Closed UNHchabo closed 3 years ago

UNHchabo commented 3 years ago

So I'm curious about the Low Entropy setting, and how to potentially improve it to model actual hardware behavior -- but I'm a software engineer, and have a limited knowledge of how DRAM works on the circuit level.

To be clear, it would be in my interest as a speedrunner for these values to be less randomized, but most of all I want it to be hardware accurate, I don't want to disable entropy to have an advantage over hardware, but I don't want a disadvantage from excessive randomization either.

I understand that DRAM can keep a charge for some time after it's powered off: https://en.wikipedia.org/wiki/Dynamic_random-access_memory#Data_remanence But if I really wanted to make sure my RAM was completely cleared, and powered off my console for minutes or even hours, what value does the RAM hold at startup? Do the cells trend towards a voltage of 0 over time, just at different rates?

byuu's commit notes say that the values are biased towards 0x00 and 0xff, but this only happens 1 out of every 8 calls, and 75% of the time the "stripes" will have completely random values. I'm curious if this bias should be adjusted, especially given his previous checkin that would always use stripes of 0x00 and 0xff. https://github.com/higan-emu/higan/commits/b38a657192a50aa045c3fdba6424e8eaa885e415/higan/emulator/random.hpp

Screwtapello commented 3 years ago

The most rigorous investigation of power-up memory state I've found is Power-up SRAM State as an Identifying Fingerprint and Source of True Random Numbers (from about 2008), although it's specifically about SRAM rather than DRAM. Since the process described is about the chemical structure of silicon, rather than anything specifically about SRAM circuitry, I assume the basic ideas hold true.

As I understand it, it works like this:

The paper I linked to groups every bit of RAM into one of three categories: "always 0 at power-on", "always 1 at power-on", and "random at power on". The exact map of which bits fall into which categories is consistent for every RAM chip, and different between them, so you can use the consistent bits to fingerprint a specific physical chip, and the random bits to generate true random numbers (since they're determined by quantum mechanics).

As for the patterns:

To be clear, it would be in my interest as a speedrunner for these values to be less randomized, but most of all I want it to be hardware accurate

As far as I know, you could pick a state for a few choice bytes in RAM and there's a chance that somewhere out there (possibly in a parallel universe) there's a real, physical SNES that happens to set those bytes to those values at power-on nearly every time, just down to manufacturing tolerances. At this point, "hardware accuracy" is as much a matter for philosophers as electronics engineers.

But if I really wanted to make sure my RAM was completely cleared, and powered off my console for minutes or even hours, what value does the RAM hold at startup?

No idea. If you experiment on your console repeatedly, you'll see patterns emerge, but those are just the patterns for your console, they'll be different for every other console ever made.

Do the cells trend towards a voltage of 0 over time, just at different rates?

Nope. As described above, they trend towards a voltage determined by the quantum randomness of a physical process at the atomic level during the manufacturing process. At different rates.

I'm curious if this bias should be adjusted...

Normally, a memory cell holds a 0 or a 1, but at power-on cells may (I believe) be anything inbetween, and when you read out a voltage something has to decide whether it's "really" a 0 or a 1. That mechanism is probably what produces the bias in question. You could probably do a bunch of investigation, gathering a bunch of power-on states and averaging them, trying to build up a statistical distribution for each bit in the memory map... but then you'd only know about one chip in one specific SNES unit.

I'm not sure we want to go there. It's hard enough to hardware-verify behaviour that's common across all SNES units, never mind trying to verify behaviour that's unique to a specific unit.

UNHchabo commented 3 years ago

Thank you for the very thorough explanation, and for the link to that paper. That's fascinating.

I am interested to see if there's a pattern that would emerge if we did look across a number of consoles -- instead of a flat distribution with spikes at either end, maybe it would be a bathtub curve, for instance.

To gather that data we could make a rom that could run on sd2snes, and save the WRAM state to an SRAM image on the flash card. This is done on the Super Metroid Practice Rom to implement save states, and the main impediment I can think of is the unknown degree to which the sd2snes writes to WRAM from power-on until the rom is loaded. Though this might be found out by overwriting WRAM, exiting out to the sd2snes menu, then loading the rom and writing the WRAM state again.

Feel free to close this, as I don't actually have a feature request. I don't want to request a change without data to back it up. Thanks again for the insights on the subject!