diff --git a/trunk/src/fceu.cpp b/trunk/src/fceu.cpp
index a6dd4f2e..bafe8d18 100644
--- a/trunk/src/fceu.cpp
+++ b/trunk/src/fceu.cpp
@@ -796,12 +796,63 @@ void ResetNES(void) {
 }
 
 
+int RAMInitSeed = 0;
 int RAMInitOption = 0;
 // Note: this option does not currently apply to WRAM.
 // Would it be appropriate to call FCEU_MemoryRand inside FCEU_gmalloc to initialize them?
 
+u64 splitmix64(u32 input) {
+	u64 z = (input + 0x9e3779b97f4a7c15);
+	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+	z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+	return z ^ (z >> 31);
+}
+
+static inline u64 xoroshiro128plus_rotl(const u64 x, int k) {
+	return (x << k) | (x >> (64 - k));
+}
+
+u64 xoroshiro128plus_s[2];
+void xoroshiro128plus_seed(u32 input)
+{
+//http://xoroshiro.di.unimi.it/splitmix64.c
+	u64 x = input;
+
+	u64 z = (x += 0x9e3779b97f4a7c15);
+	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+	z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+	xoroshiro128plus_s[0] = z ^ (z >> 31);
+	
+	z = (x += 0x9e3779b97f4a7c15);
+	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+	z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+	xoroshiro128plus_s[1] = z ^ (z >> 31);
+}
+
+//http://vigna.di.unimi.it/xorshift/xoroshiro128plus.c
+u64 xoroshiro128plus_next() {
+	const u64 s0 = xoroshiro128plus_s[0];
+	u64 s1 = xoroshiro128plus_s[1];
+	const u64 result = s0 + s1;
+
+	s1 ^= s0;
+	xoroshiro128plus_s[0] = xoroshiro128plus_rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
+	xoroshiro128plus_s[1] = xoroshiro128plus_rotl(s1, 36); // c
+
+	return result;
+}
+
 void FCEU_MemoryRand(uint8 *ptr, uint32 size) {
 	int x = 0;
+
+	//reseed random, unless we're in a movie
+	extern int disableBatteryLoading;
+	if(FCEUMOV_Mode(MOVIEMODE_INACTIVE) && !disableBatteryLoading)
+		RAMInitSeed = rand()&0x7FFF;
+
+	//always reseed the PRNG with the current seed, for deterministic results (for that seed)
+	xoroshiro128plus_seed(RAMInitSeed);
+
 	while (size) {
 		uint8 v = 0;
 		switch (RAMInitOption)
@@ -810,7 +861,7 @@ void FCEU_MemoryRand(uint8 *ptr, uint32 size) {
 			case 0: v = (x & 4) ? 0xFF : 0x00; break;
 			case 1: v = 0xFF; break;
 			case 2: v = 0x00; break;
-			case 3: v = uint8(rand()); break;
+			case 3: v = (u8)(xoroshiro128plus_next()); break;
 
 			// the default is this 8 byte pattern: 00 00 00 00 FF FF FF FF
 			// it has been used in FCEUX since time immemorial
diff --git a/trunk/src/movie.cpp b/trunk/src/movie.cpp
index e58dcf98..76be97b7 100644
--- a/trunk/src/movie.cpp
+++ b/trunk/src/movie.cpp
@@ -35,6 +35,7 @@ extern bool mustEngageTaseditor;
 #endif
 
 extern int RAMInitOption;
+extern int RAMInitSeed;
 
 #include <cstdio>
 #include <cstdlib>
@@ -395,6 +396,7 @@ MovieData::MovieData()
 	, palFlag(false)
 	, PPUflag(false)
 	, RAMInitOption(0)
+	, RAMInitSeed(0)
 	, rerecordCount(0)
 	, binaryFlag(false)
 	, loadFrameCount(-1)
@@ -417,6 +419,8 @@ void MovieData::installValue(std::string& key, std::string& val)
 		installBool(val,PPUflag);
 	else if(key == "RAMInitOption")
 		installInt(val,RAMInitOption);
+	else if(key == "RAMInitSeed")
+		installInt(val,RAMInitSeed);
 	else if(key == "version")
 		installInt(val,version);
 	else if(key == "emuVersion")
@@ -481,6 +485,7 @@ int MovieData::dump(EMUFILE *os, bool binary)
 	os->fprintf("FDS %d\n" , fds?1:0 );
 	os->fprintf("NewPPU %d\n" , PPUflag?1:0 );
 	os->fprintf("RAMInitOption %d\n", RAMInitOption);
+	os->fprintf("RAMInitSeed %d\n", RAMInitSeed);
 
 	for(uint32 i=0;i<comments.size();i++)
 		os->fprintf("comment %s\n" , wcstombs(comments[i]).c_str() );
@@ -817,6 +822,7 @@ void FCEUMOV_CreateCleanMovie()
 	currMovieData.fds = isFDS;
 	currMovieData.PPUflag = (newppu != 0);
 	currMovieData.RAMInitOption = RAMInitOption;
+	currMovieData.RAMInitSeed = RAMInitSeed;
 }
 void FCEUMOV_ClearCommands()
 {
@@ -881,6 +887,9 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
 	LoadSubtitles(currMovieData);
 	delete fp;
 
+	RAMInitOption = currMovieData.RAMInitOption;
+	RAMInitSeed = currMovieData.RAMInitSeed;
+
 	freshMovie = true;	//Movie has been loaded, so it must be unaltered
 	if (bindSavestate) AutoSS = false;	//If bind savestate to movie is true, then their isn't a valid auto-save to load, so flag it
 	//fully reload the game to reinitialize everything before playing any movie
@@ -903,7 +912,7 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
 	else
 		FCEUI_SetVidSystem(0);
 
-	RAMInitOption = currMovieData.RAMInitOption;
+
 
 	//force the input configuration stored in the movie to apply
 	FCEUD_SetInput(currMovieData.fourscore, currMovieData.microphone, (ESI)currMovieData.ports[0], (ESI)currMovieData.ports[1], (ESIFC)currMovieData.ports[2]);
@@ -1573,6 +1582,7 @@ bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount)
 	info.pal = md.palFlag;
 	info.ppuflag = md.PPUflag;
 	info.RAMInitOption = md.RAMInitOption;
+	info.RAMInitSeed = md.RAMInitSeed;
 	info.nosynchack = true;
 	info.num_frames = md.records.size();
 	info.md5_of_rom_used = md.romChecksum;
diff --git a/trunk/src/movie.h b/trunk/src/movie.h
index f37a17a2..cab767bd 100644
--- a/trunk/src/movie.h
+++ b/trunk/src/movie.h
@@ -42,7 +42,7 @@ typedef struct
 	uint32 emu_version_used;				// 9813 = 0.98.13
 	MD5DATA md5_of_rom_used;
 	std::string name_of_rom_used;
-	int RAMInitOption;
+	int RAMInitOption, RAMInitSeed;
 
 	std::vector<std::wstring> comments;
 	std::vector<std::string> subtitles;
@@ -199,7 +199,7 @@ public:
 
 	int getNumRecords() { return records.size(); }
 
-	int RAMInitOption;
+	int RAMInitOption, RAMInitSeed;
 
 	class TDictionary : public std::map<std::string,std::string>
 	{