Page 1 of 2

SOROM and older emulators

Posted: Mon May 09, 2016 4:08 pm
by goldenband
Older emulators don't seem to support working battery saves in the three Koei games that use SOROM, i.e. Genghis Khan, Nobunaga's Ambition, and Romance of the Three Kingdoms. Nestopia, for example, creates a file with intelligible data in it (visible character names, etc.), but the game finds "No saved data" after a reset. I've tried ROMs from sources with an excellent reputation, and have gotten the same results, so I don't think it's a bad dump or header issue per se.

Assuming that one had to use one of these emulators (don't ask)* and wanted to avoid using savestates (long story);

1) Is there any possible header change that would trick these emulators into creating a working save file? I tried adding a 2.0 header to Nobunaga based on my admittedly-limited understanding of the spec, but it didn't seem to do any good. (I thought Nestopia supported 2.0 headers?)

2) My memory is that even older emulators, like iNES, actually did support functional saving in ROTK -- at least I seem to remember that iNES created working battery save files when I did an emulator playthrough of ROTK in 2001 or so, though I used savestates. Is my memory correct? If so, what happened to create this downgrade (from the user's perspective) in compatibility?

Thanks in advance for any insights.

*OK, since you had to ask: I'm still running Snow Leopard (OS X 10.6) as my main working OS -- under the "if it ain't broke, don't update it" principle -- and, as far as I can tell, there's no emulator with working SOROM saving that also is supported on Snow Leopard. I can reboot into a more recent OS, but it's annoying to mess up my workspace just to play 3 games.

Re: SOROM and older emulators

Posted: Mon May 09, 2016 4:10 pm
by koitsu
One important question: is there a reason you've intentionally omitted the names/versions of the emulators you've tried which behave this way? The only one I see mentioned is Nestopia, which is open-ended in the sense that you could be using someone's build, or be using the Richard Bannister build (please specify).

Edit: To my knowledge, there is no NES 2.0 header support in Nestopia, but to my knowledge there's no reason this is needed for .sav file restoration to work. The problem with .sav restoration (at least with Genghis Khan -- I haven't tested other Koei titles) exists on NestopiaUE (for Windows) as well.

Code: Select all

File:         Genghis Khan (U).nes
Directory:    D:\Console\NES Games\USA\
Soft-patched: No
CRC:          2225C20F
SHA-1:        209911D7BD15ABB7BEF2E35A473DF725B6738CD7
System:       NES-NTSC
Board:        NES-SOROM, Mapper 1
PRG-ROM:      256k
V-RAM:        8k
W-RAM:        16k
Chips:        MMC1B2
Battery:      Yes
File:         Genghis Khan (U).sav
Directory:    D:\Console\NES\Nestopia\save\
Dump:         OK
Odds are someone is going to need to reverse-engineer what the game is doing (6502-wise) for battery-backed SRAM verification and determine why it's failing. There are several possibilities.

Edit #2: Actually, I'm noticing this behaviour on other non-Koei games as well (such as Destiny of an Emperor), so odds are -- at least for Nestopia -- there is something broken about the .sav bits. Exiting the emulator entirely, deleting the .sav file, starting the emulator, and loading the game results in a .sav being created. Following that, playing the game + finding a save point + saving + choosing Power Off + powering back on shows that there is a fact a save point, but it's the one from when the game started, not when the save took place at the save point. One thing worth noting is that this game also uses MMC1, so maybe something is broken there.

Re: SOROM and older emulators

Posted: Mon May 09, 2016 4:21 pm
by goldenband
koitsu wrote:One important question: is there a reason you've intentionally omitted the names/versions of the emulators you've tried which behave this way? The only one I see mentioned is Nestopia, which is open-ended in the sense that you could be using someone's build, or be using the Richard Bannister build (please specify).
Very good question. I'm using the Richard Bannister build of Nestopia v.1.4.1, and that's the only one I can speak to directly (other than my old experiences with iNES on Mac OS Classic). However, I've found reports that the same issue was happening with VirtuaNES and RockNES ca. 2010, e.g. this Windows XP user:

http://forums.bannister.org/ubbthreads. ... mber=61487

I didn't want to give the impression that I'd personally tried those out, but this person is describing the exact same issue that I've seen, so I assume his report is trustworthy.

I've also contacted Bannister directly about this, but got no response (not that I expected one).

EDIT: The wiki also notes the following about SOROM, if this is helpful for context:

"SOROM uses a similar method, using the second-highest CHR bank select line to choose between two 8KB PRG RAM chips. Of chip 0 and chip 1, only chip 1 is battery backed."

There's info in this thread that also might be helpful.

Re: SOROM and older emulators

Posted: Mon May 09, 2016 4:46 pm
by goldenband
koitsu wrote:Edit #2: Actually, I'm noticing this behaviour on other non-Koei games as well (such as Destiny of an Emperor), so odds are -- at least for Nestopia -- there is something broken about the .sav bits.
Huh, really? i'm 98% sure that when I played through Destiny last year in Nestopia, I used the "proper" savegame function. In fact, let me check...

...yep, I just fired up Destiny, loaded my end-of-game battery save from the in-game menu, and had no problems.

Re: SOROM and older emulators

Posted: Mon May 09, 2016 5:05 pm
by koitsu
Ah, I see where I made a mistake. This has to do with where Destiny of an Emperor actually puts you if you save in Xu Zhou early on in the game. I'll explain my confusion:

1. Make sure the emulator is not running (this matters greatly)
2. Delete the .sav file
3. Run the emulator and load the ROM
4. Create a new game/story, starting at Lou Sang village
5. Exit Lou Sang and head west to Xu Zhou castle
6. Go to the save house and choose Record. Merchant should say "I have recorded your status."
7. Power off the emulator (Machine -> Power off)
8. Power on the emulator (Machine -> Power on)
9. Load your game/story ("Game Start") -- you'll find yourself at Lou Sang village

My confusion was with the fact that you start at Lou Sang. To confirm I was wrong, between steps 5 and 6, I fought a battle to let Guan Yu's men drop to 0. At step 9, I still found Guan Yu's men at 0, but started at Lou Sang, despite saving at Xu Zhou. This just seems to be a game mechanic that I had forgotten and lead me down the wrong road.

I'd definitely say it's possible that for SOROM titles, Nestopia is backing up the wrong 8KB PRG RAM page. It's certainly possible other emulators have this wrong too. I did verify that Romance of the Three Kingdoms, Genghis Khan, and Nobunaga's Ambition are all SOROM (not just from the ROM header, but actual cartridges) -- and in fact, they're the only 3 SOROM games that are known.

I'll try to go make heads/tails of the NestopiaUE code (often troublesome for me because of it's highly abstracted design) and see if I can pinpoint it. lidnariq might have better luck though, as he's more famliar with the NestopiaUE code than I am. :D

Re: SOROM and older emulators

Posted: Mon May 09, 2016 5:23 pm
by goldenband
koitsu wrote:I'd definitely say it's possible that for SOROM titles, Nestopia is backing up the wrong 8KB PRG RAM page. It's certainly possible other emulators have this wrong too.
I wonder if that explains what I'm seeing in the .sav file for Nobunaga? I'm not sure what form of compression is being used, but I have a text editor (TextWrangler) that seems to handle it automatically, as while a hex editor reveals nothing, TextWrangler shows the following at the bottom of the file:

HatakeyaUesugiHojoHonganjiAsakuraAnekojiImagawaTokugawaUeteTsutsui
AsaiRokkakuKitabataAshikagaMiyoshiTakedaOda

NotoEchigoMusashiKagaEchizenHida
SurugaMikawaMinoYamatoOmiIgaIseshimaYamashirSettsu
ShinanoOwari

I have 3 different Nobunaga saves, all with that same text block, and ranging from 1423 - 1453 bytes in size. Genghis Khan has similar game-specific blocks of text at the beginning and end (.sav file 3443 bytes), but ROTK has nothing recognizable (.sav is 3488 bytes).
koitsu wrote:I did verify that Romance of the Three Kingdoms, Genghis Khan, and Nobunaga's Ambition are all SOROM (not just from the ROM header, but actual cartridges) -- and in fact, they're the only 3 SOROM games that are known.
Yes indeedy -- I checked with BootGod's site, which compiles them here. BTW I verified that the Japanese release of ROTK has the same issue.
koitsu wrote:I'll try to go make heads/tails of the NestopiaUE code (often troublesome for me because of it's highly abstracted design) and see if I can pinpoint it. lidnariq might have better luck though, as he's more famliar with the NestopiaUE code than I am. :D
Awesome! Anything you can do would be very much appreciated. :)

Re: SOROM and older emulators

Posted: Mon May 09, 2016 5:47 pm
by koitsu
This is tough to dig through (I cannot stress how much I hate OO).

It looks like Board::Save in source/core/board/NstBoard.cpp might be responsible, as an abstracted method/thing/whatever for most/all of the mappers? I'm not really sure. What I'm having trouble mentally grasping is why I see no Mmc1::Save function in source/core/board/NstBoardMmc1.cpp, yet somehow the .sav bits do in fact work (for non-SOROM boards of course), so I'm thinking the "magic" is happening there; there's definitely some SOROM code in there. How or where to exactly fix this I'm not sure (either there or in source/core/board/NstBoardMmc1.cpp).

Bare minimum I've filed Nestopia issue 178 for this problem. I've put some details in there (possibly the issue is with the .sav loading, not with the saving?). Possibly rdanbrook knows exactly where the fix should go. I urge folks to put useful info in there. :-)

Re: SOROM and older emulators

Posted: Wed May 11, 2016 3:41 pm
by goldenband
Thanks very much for your efforts on this. I'll keep an eye on the Github thread. Even if none of this translates to a version I can use on Snow Leopard, I'll still be glad to have contributed some (very) small amount toward squashing a long-standing bug. :)

Re: SOROM and older emulators

Posted: Sat Aug 27, 2016 3:41 pm
by goldenband
I just saw joepogo's suggestion on GitHub of editing database.xml to restore save functionality. Would that work (even if it's a hack), and if so what would the edit look like?

Re: SOROM and older emulators

Posted: Sat Aug 27, 2016 5:44 pm
by rainwarrior
koitsu wrote:It looks like Board::Save in source/core/board/NstBoard.cpp might be responsible, as an abstracted method/thing/whatever for most/all of the mappers? I'm not really sure. What I'm having trouble mentally grasping is why I see no Mmc1::Save function in source/core/board/NstBoardMmc1.cpp, yet somehow the .sav bits do in fact work (for non-SOROM boards of course), so I'm thinking the "magic" is happening there; there's definitely some SOROM code in there. How or where to exactly fix this I'm not sure (either there or in source/core/board/NstBoardMmc1.cpp).
Yes, if a child class does not override (virtual) Save, it will use the one from the parent.
NstBoardMmc1.hpp line 38 wrote:class NST_NO_VTABLE Mmc1 : public Board
This is the line that tells you that MMC1's parent is Board. Since it has no Save function of its own, you are correct in thinking that Board::Save in NstBoard.cpp applies.

If you think your fix applies generically, fix Board::Save. If you think you should have a special version for Mmc1, create an Mmc1::Save that overrides it instead.

This particular hierarchy is only 1 level deep, so there's really only one other place to look (Board), but if you ever have to work on something with deeper ones, IDEs have a lot of really helpful features for finding what you're looking for (e.g. Visual Studio has its Class Explorer window).

Re: SOROM and older emulators

Posted: Sat Aug 27, 2016 7:09 pm
by koitsu
I haven't put any effort into this since filing the Issue + talking about it there + nesdev. But here's one thing I did do today, which makes me believe the issue likely relates to both loading *and* saving in Nestopia. I tested with Genghis Khan.

FCEUX appears to work fine/correctly across the board.

Nestopia loading test: I took the 8KB .sav from FCEUX and dropped it into Nestopia's save\ directory (overwriting the existing one I had there). In Nestopia, the result was "No saved data". To me, that means there's an issue with Nestopia and loading, or with the MMC1 emulation bits somehow.

Nestopia saving test: Deleted the existing .sav file, started a game in Nestopia, played for a season, saved in-game (Other -> Save), closed the emulator and made sure the 8KB file was there. Copied that into the FCEUX sav\ directory and ran FCEUX + game: "No saved data". So FCEUX won't work with the 8KB .sav from Nestopia, leading me to believe Nestopia is also saving incorrect/wrong data to the .sav.

I did a binary file compare between the Nestopia .sav and the FCEUX .sav. There are several differences given the randomness and variance of events in the game (I've no control over that), but nothing "obviously gigantic" -- what I was looking for was to see if, say, the lower or upper 4KByte regions were massively different -- they weren't. However, one thing I did notice is that FCEUX .sav had this, consistently at this offset (referring to $1F09 to $1F0F):

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00001F00  2E 00 01 00 06 00 00 00 00 11 A4 4B 4F 45 49 00  ..........¤KOEI.
While I couldn't find that identifier anywhere in the Nestopia .sav. I even tried injecting those values into the Nestopia .sav at the same offset, thinking maybe that was their simple identifier check -- nope, still "No saved data".

Finally: I will say that the "16KB WRAM" tweak proposed in the GitHub Issues is the wrong approach. I believe fixing this the proper way (whatever that may be) is the better choice. "Kludge fixes" just end up creating more work for someone later on/down the road, or make someone go "Eh? Why are KOEI games in Nestopia making 16KB saves while every other emulator uses 8KB? What is the history behind this?" (We've seen tons of evidence of this in the past few years, where people dig through FCEUX source to find "behavioural quirks" that can't be explained/justified very well. The less we do this going forward, in any emulator, the better!)

Re: SOROM and older emulators

Posted: Sun Aug 28, 2016 3:25 am
by zxbdragon
nestopia to wram 32K, working fine

Re: SOROM and older emulators

Posted: Sun Aug 28, 2016 4:08 pm
by *Spitfire_NES*
How did you fix this with 32?

Re: SOROM and older emulators

Posted: Sun Aug 28, 2016 5:22 pm
by koitsu
It's not a fix, it's a kludge, and one that shouldn't be committed as a fix. The relevant SRAM is 8KBytes; changing the .xml to force 16KB or 32KB SRAM/WRAM just allows for one, somehow, to work around the real issue.

I'm really growing sick and tired of every single Nestopia-related thread/issue having comments in it (both on nesdev and in the GitHub) from one or two particular users who do very little to *solve* actual issues, instead just creating kludge hack-fixes that "make things work". All they do is confuse end-users, piss me off, and ultimately solve nothing. This type of shit makes me **very** unwilling to put forth any kind of effort into fixing (or reporting!) actual problems.

P.S. -- One of the biggest problems I have with spending time testing patches/fixes in Nestopia is that the NestopiaUE repository on GitHub doesn't include the Win32 code/GUI. I'm not sure how rdanbrook builds NestopiaUE binaries as a result -- he must be backporting fixes committed to GitHub to a personal/private repo/directory/something that contains the original Nestopia code. This is very confusing.

Re: SOROM and older emulators

Posted: Sun Aug 28, 2016 6:14 pm
by *Spitfire_NES*
koitsu wrote:It's not a fix, it's a kludge, and one that shouldn't be committed as a fix. The relevant SRAM is 8KBytes; changing the .xml to force 16KB or 32KB SRAM/WRAM just allows for one, somehow, to work around the real issue.

I'm really growing sick and tired of every single Nestopia-related thread/issue having comments in it (both on nesdev and in the GitHub) from one or two particular users who do very little to *solve* actual issues, instead just creating kludge hack-fixes that "make things work". All they do is confuse end-users, piss me off, and ultimately solve nothing. This type of shit makes me **very** unwilling to put forth any kind of effort into fixing (or reporting!) actual problems.

P.S. -- One of the biggest problems I have with spending time testing patches/fixes in Nestopia is that the NestopiaUE repository on GitHub doesn't include the Win32 code/GUI. I'm not sure how rdanbrook builds NestopiaUE binaries as a result -- he must be backporting fixes committed to GitHub to a personal/private repo/directory/something that contains the original Nestopia code. This is very confusing.
I suspected as much and that is why i asked him why he set it to 32. Its obviously not the right way to do it.

I don't believe i have ever suggested anyone hack up a fix, I just asked how 32 is supposed to fix this issue. Its obvious that its a problem with the creation and loading back of a save so hacking up the xml is not the way to go. ( I initially asked about editing the xml file before but now I understand more now about how the xml works, so it is def not the way to go, and i stand corrected)

I definitely do not like the "throw shit at the wall and see what sticks" mentality either. Rdanbrook and i have spoke many times and i know that he will not post any hack up as a commit for nestopia. You are correct, kludge quick fixes only make it harder to undo something else down the road if done enough times. Accurate and correct emulation should be a priority, especially one like nestopia. (But that's just my opinion)

As far the Win32code, Ive wondered the exact same thing. I'll have to ask next time we chat.

Edit**

Thank you for testing out the save files koitsu by the way. This only further verifies that it is something in NstBoard most likely.