So it seems NestopiaUE doesn't do something relating to
VRC2 (mapper 23) H/V mirroring selection ($9000-9003) correctly. This becomes
readily apparent in Konami Wai Wai World during the vertically-scrolling part of the game. (Said part of game is also shown during one of the demo phases, so can be tested there too). I still haven't figured out what the root cause of the final ending screen + sound select
being garbled is, but gut feeling is it's probably related.
I've tried digging through the source to see if the problem was easily fixable, but the amount of abstraction is making it difficult. Was hoping someone else (lidnariq?) might have insights or know what's busted:
*
https://github.com/rdanbrook/nestopia/b ... miVrc2.cpp*
https://github.com/rdanbrook/nestopia/b ... miVrc2.hppReferences for the NmtSwap stuff:
*
https://github.com/rdanbrook/nestopia/b ... tBoard.cpp*
https://github.com/rdanbrook/nestopia/b ... tBoard.hppI've looked through commits between October 2014 and present and don't see anything relevant to fixing this. On the other hand, I do see
other issues with NestopiaUE and VRC2 discussed but that's CHR page swapping and not mirroring.
I'm happy to file a ticket/Issues request with rdanbrook for getting this fixed, but like I said, it's convoluted (for me anyway).
FCEUX 2.2.3 (devel/svn build, date 2015/10/13) gets this right (at least the vertically-scrolling gameplay portion, haven't tested the ending), so it's definitely specific to at least NestopiaUE.
I can reproduce in Nintendulator.
All three emulators use the same mapping of 0,1,2,3 to "VH01".
The NMI handler of Wai Wai World always copies the byte at $07FF to $9000.
For the vertically scrolling portion in the demo there, the chunk of code at $8064 through $8068 writes $FF to $07FF, which is parsed as 1-screen mirroring by Nintedulator and Nestopia.
FCEUX, on the other hand, contains this gem:
Code:
case 0x9000:
case 0x9001: if (V != 0xFF) mirr = V; Sync(); break;
Without someone to test on the original hardware, it's hard to say if that's a bug in the game that FCEUX is working around, or previously-undocumented behavior.
(P.S. to anyone else: if you have a Wai Wai World cartridge, would you mind testing?)
Sorry about the longevity of reply/delay. This subject came up today when talking to deadbody.
FYI, I do have a a Wai Wai World cartridge and original Famicom hardware, but I'm not exactly sure how to go about testing anything related to what's been posted. I can assure you the game visually looks like what FCEUX shows, but what's going on hardware-wise is a different question.
We do have VRC2 documentation now (all in Japanese), but I can get that translated by my neighbour. $9000/$9001 does have special handling according to the VRC2 docs (see file 0012.jpg, bottom) pertaining to H/V mirroring (docs seem to imply only bit 0 is honoured, and 0 = H, 1 = V). I don't know what V or mirr are in FCEUX code. There's no mention of a special $FF value in the docs, but maybe there's something in native Japanese I'm missing. The $07FF write may be what's most relevant though (same document), as there's some kind of correlation between those two things.
Really need to get that VRC2 document translated. I'll ask my neighbour.
koitsu wrote:
FYI, I do have a a Wai Wai World cartridge and original Famicom hardware, but I'm not exactly sure how to go about testing anything related to what's been posted. I can assure you the game visually looks like what FCEUX shows, but what's going on hardware-wise is a different question.
The trivial test is wait for the vertical-scrolling shmup section of the attract mode. If it looks correct, then writing $FF has to do something funny. If there's an obvious seam as in Nestopia, then it's a game bug.
... Oooh, or maybe the VRC2 only supports H/V, and the VRC4 is what supports H/V/0/1, and this entire bug is another instance of the conflation of the VRC2 and VRC4?
Nope, the VRC2 definitely supports 1-screen layouts; the scientist-person talking at you in attract mode is missing his computer if you disable 0/1 as options. (edit:
errāvī)
I'm having some of the VRC2 documentation (the bits relevant to this) translated to English, mainly the pages relating to CHR page mapping and H/V.
It's interesting that all the documentation available (Disch vs. Goroh vs. the Wiki vs. Firebug vs. emulator code) have somewhat conflicting information about how mapper 23 behaves in this regard. The wiki is, well... the way I'd describe it is "all fucked up" for the H/V bits (for both VRC2 and VRC4). You'll just have to look to see what I mean. It looks like someone half-assed something.
Possibly this confusion stems from multiple revisions (2a vs. 2b) and the fact that VRC2/VRC4 were considered in early days to be the exact same? Not really sure.
Spoke with deadbody some more and I mentioned that this may be a good opportunity to have someone like Tepples make a test/exploration ROM for these types of features. There is obviously behaviour of this chip which we either don't understand, aren't documented, or stem from different revision behaviours. Possibly the official documentation we have doesn't match the exact revision of chip used in the cart? If you look at Goroh's document, you'll see that he ended up testing the behaviour on a per-game basis and the behaviour changes.
I wouldn't expect to find anything useful in that ancient documentation like Goroh's or the others you mentioned. They're always inadequate in cases like this. Disch's documents are just based on emulators available at the time of their writing, for example.
What's the documentation you're translating, though?
Just get somebody to do a hardware test. You can hotswap some test code in RAM, no need to do any hardware mods. All a tester needs is a famicom, a relevant cartridge, and something to run the test program from. (I don't have any VRC2/4 games, personally, so I can't help as a tester at the moment.)
VRC2 documentation being translated:
viewtopic.php?f=2&t=10611
This is also present in puNES:
and the issue have been reported on GitHub.
As for the ending + sound select in puNES I'm not sure about that but I can definitely say that this is not occurring on original hardware at all as I own both a Famicom and a copy of the game.
Here is a simple hot-swappable test.
* It'll beep when it's ready to remove the original cartridge.
* Press A to start the test
* It'll play a 30-second long "song", corresponding to
- The 32 different values that can be written to the mirroring control register (the VRC2 isn't connected to CPU D5,6,7 so those cannot change things)
- Each of which consist of five notes, each 183ms long, which are Upper Left, Upper Right, Lower Left, Lower Right, Spacer.
+ 874 Hz = nametable A
+ 437 Hz = nametable B
+ 218 Hz = spacer
How exactly would this hot-swap methodology work? Use a NES/Famicom cartridge adapter (so a Famicom cart can be used on a NES), load ROM via PowerPak, once loaded/running yank cart, insert VRC2 cart + adapter, press A? Sorry if this seems like a stupid question, but...
On a front-loading NES you'll need to somehow bypass/disable the CIC. Otherwise, yes.
Hotswaps often crash during the insertion/removal, so you might have to try 2 or 3 times before it works (try to pull out straight and swift).
Otherwise, yeah, you got it.
rainwarrior wrote:
Hotswaps often crash during the insertion/removal
I remember someone saying that executing OAM DMAs repeatedly helps with preventing crashes, because that means the CPU spends most of the time doing something that doesn't involve reading opcodes from memory, I believe. Can anyone confirm this?
Either way I forgot to add that <_<
I've a front-loader, a top-loader, and a Famicom AV (but no NES cart->Famicom adapter, only Famicom cart->NES). Looks like the top-loader is the best choice for this given its lack of 10NES/CIC. And yeah, what rainwarrior said was another level of concern I had. I'll try to give it a try Tuesday or after, as I've too much stuff tonight and Monday to take care of first.
English translation of a couple pages from the VRC2 docs will be coming later tonight.
tokumaru wrote:
I remember someone saying that executing OAM DMAs repeatedly helps with preventing crashes. ... Can anyone confirm this?
I've tried it. I don't think it makes a big difference, really. I'll still get crashes occasionally even with a DMA loop, and due to the random nature of it's hard to say how much less it might crash.
IMO it probably helps a little, but there may be other factors involved in crashing when a cartridge is yanked that it doesn't affect.
Another useful thing would be to play audio constantly while waiting for the swap. That way it's possible to tell whether the program is still running. Probably easiest to do with the DMC DAC (run a couple of DMAs, toggle the DAC value, rinse and repeat).
I mirrored the rom to fit on a 512kb flash, stuck it on cpld unrom cart, then hotswapped. Worked fourth time! Here is the audio output.
That's strange, I only hear horizontal and vertical mirroring. Shouldn't there also be 1-screen mirroring?
Forgot to mention the cartridge used was Wai Wai World. Attached is a photo of the board.
The recording indicates that your VRC2 on your copy of Wai Wai World only supports H/V mirroring.
I thought I already tested that. But it turns out that the reason that I thought it was wrong is that NestopiaUE has a heisenbug that is somehow masked by using NMT_SWAP_VH01 instead of NMT_SWAP_VH, even though the game only ever writes 0 to $9000. But testing in plain ancient FCEU DTRT.
So it looks like my first guess was right: it is an incompatibility between VRC2 and VRC4.
Okay, so what have we learned exactly?
My initial conclusion is that, at least with the revision of VRC2 in Wai Wai World, the official Konami documents are correct (only H/V mirroring is supported -- there is no single-screen support).
1. But that conflicts with what was
said here in the last paragraph. (My gut feeling is that by disabling H/V (bit 0) support altogether in that part of the game, of course the graphics ("computer") are going to be mangled -- because it needs either horiz or vert mirroring (not sure which)).
2. What does this say about
the weird/odd code in FCEUX? (My gut feeling is that FCEUX tries to implement VRC2 and VRC4 using the same emulation code, and that V != $FF quirk is done as way to distinguish the difference between VRC2 vs. VRC4 mirroring capability).
Yes/no? :-)
"V != $FF" just sounds to me like a hack that solves a problem for the one game that writes that particular value.
(lidnariq already stated that only the bottom 5 bits even go to the mapper anyway, so at the very least testing for the full 8 bits of $FF is inaccurate and impossible for the mapper to do)
That code's been there since
at least 2008, and the revision history runs dry at that point, so I couldn't find any insight in the revision logs.
Re: #1-
I've tested Wai Wai World with the reported correct VRC2 behavior in both FCEU-0.98 & FCEUX and both DTRT.
Nestopia does the wrong thing. Right now I can't summon any enthusiasm for tracing down that bug.
For whatever stupid reason, I can't get puNES to build right now, and I don't have a windows toolchain installed (not even in a VM) to test with Nintendulator.
Re: #2-
The most flattering thing I could say about "don't change mirroring if the game writes #$FF" code is that it's a run-time heuristic, because apparently all other games cleanly just write a number 0-3 there, achieving upwards compatibility between the VRC2 and VRC4. It apparently should probably be "treat it as 1" rather than "no change", though.
It wouldn't be entirely wrong to explicitly handle 0,1,2,3,#$FF and throw a fatal error if another value is written.
Regardless a comment in FCEUX about why the hack is present would be nice.
lidnariq wrote:
Re: #1-
I can't get puNES to build right now
I already tried this out in puNES but you must have missed the post on page 1 with the large image?
Anyway, it's reported and documented on GitHub quite nicely with save states etc. etc.
https://github.com/punesemu/puNES/issues/9
I meant I can't get it to build with my fix.
Makes sense. Thanks everyone! I'll file a bug report/Issue with the NestopiaUE guy to have this rectified. I'll also see about updating the nesdev wiki (for VRC2).
As for FCEUX and its weird
V != 0xff quirk: if the code there is purely for VRC2 and not VRC4, then I don't know why they don't just mask off bits 7-1 and only honour bit 0. In other words, something like this would be clearer:
Code:
/* Per official Konami documentation, VRC2 only implements horizontal (0) and
* vertical (1) mirroring; only bit 0 is used. nesdev thread confirming this fact:
* http://forums.nesdev.com/viewtopic.php?f=3&t=13473
*/
case 0x9000:
case 0x9001: mirr = V & 0x01; Sync(); break;
Though the
case statement isn't accurate -- the docs state clearly $9000-9FFF is mapped to the H/V toggle.
If the same code is used for VRC4, then I don't know what makes the
V != 0xff quirk necessary; possibly there's some justification for it (maybe someone has official VRC4 documentation), but my gut feeling is there's probably a weird game that does something unexpected and it worked around whatever the oddity was. Too bad the commit history doesn't go back to when it was written -- thanks for digging into that, rainwarrior!
Edit: you summarise the situation
beautifully well, lidnariq. Thanks for that. *thumbs up* :-)
P.S. -- I've run into my neighbour twice in the past 2 days, and he was supposed to come by last night to give me the translated results but didn't. I'll poke him tomorrow. He did say the Japanese wasn't hard and he more or less understood/got it all.
koitsu wrote:
If the same code is used for VRC4, then I don't know what makes the V != 0xff quirk necessary
The same code is used for both (mapper 23), and it's there because $FF=1 on VRC2 and $FF=3 on VRC4.
It's a hack that happens to work for Wai Wai World. Seems like it's just "lucky" that the mirroring mode is redundantly set before the $FF, so ignoring it "works", and other mapper 23 games don't write $FF?
Like, if it's a heuristic hack to make a universal mapper 23, it should probably make $FF write a 1, not an ignore? (And for accuracy, it should get an
NES 2.0 submapper.)
The issue is now fixed in puNES:
https://github.com/punesemu/puNES/commi ... 67f665cc9dI'm eagerly awaiting a WIP build to try it out.
koitsu wrote:
Though the case statement isn't accurate -- the docs state clearly $9000-9FFF is mapped to the H/V toggle.
Right, which is why right above that, it's
switch (A & 0xF003) {rainwarrior wrote:
(And for accuracy, it should get an NES 2.0 submapper.)
I started writing a VRC2 / VRC4 set of validation ROMs after that discussion on the wiki ... and I after I got about 70% through I realized that I really needed the hardware to test against to be able to make something that wasn't just parroting what we said on the wiki.
I have plethora of VRC2/VRC4 carts, I can test anything.
Are any of them already set up to take an EEPROM in lieu of PRG? I was originally intending on creating a set of 8 ROMs to make a set of NES 2.0 validation ROMs that would exhaustively test all 6* VRC4 variants and all three VRC2 variants. Rewriting the tests to work via hot-swapping would be more difficult if we don't have things to suspect are wrong.
* Including the pirate VRC4f variant
None of them are, currently. But...with my Irwin Quick-Grip and Hakko-808 I am positive I can produce one in under 15 minutes.
koitsu wrote:
Makes sense. Thanks everyone! I'll file a bug report/Issue with the NestopiaUE guy to have this rectified. I'll also see about updating the nesdev wiki (for VRC2).
As for FCEUX and its weird
V != 0xff quirk: if the code there is purely for VRC2 and not VRC4, then I don't know why they don't just mask off bits 7-1 and only honour bit 0. In other words, something like this would be clearer:
Code:
/* Per official Konami documentation, VRC2 only implements horizontal (0) and
* vertical (1) mirroring; only bit 0 is used. nesdev thread confirming this fact:
* http://forums.nesdev.com/viewtopic.php?f=3&t=13473
*/
case 0x9000:
case 0x9001: mirr = V & 0x01; Sync(); break;
Though the
case statement isn't accurate -- the docs state clearly $9000-9FFF is mapped to the H/V toggle.
If the same code is used for VRC4, then I don't know what makes the
V != 0xff quirk necessary; possibly there's some justification for it (maybe someone has official VRC4 documentation), but my gut feeling is there's probably a weird game that does something unexpected and it worked around whatever the oddity was. Too bad the commit history doesn't go back to when it was written -- thanks for digging into that, rainwarrior!
Edit: you summarise the situation
beautifully well, lidnariq. Thanks for that. *thumbs up*
P.S. -- I've run into my neighbour twice in the past 2 days, and he was supposed to come by last night to give me the translated results but didn't. I'll poke him tomorrow. He did say the Japanese wasn't hard and he more or less understood/got it all.
Hey Koitsu, So is this working in nestopia correctly? I thought lidnariq said that it was correct? I guess the C++ goo is too much to parse?
It gives me fits hahaha.
EDIT** I see where he said it is incorrect with nestopia, i read it wrong.
Please, answer me ok? ^_^;;; This is iNES mapper 22, correct? The address mask should be AND F003, correct?
The bug is only exposed in one mapper 23 game. The only way to solve this without submappers or hashes is something similar to what FCEUX's source has, where it special-cases the value of 0xFF.
It's true that VRC2 was also used in mapper 22 (and one game on mapper 25), but all of those games apparently never tickle this problem.
Neighbour dropped by tonight with translated bits from the official VRC2 docs. Plain and simple: there's really nothing in there we don't already know (in fact, I'd say the wiki is way more thorough, albeit a bit confusing). I even asked him about the serial/EEPROM capability, but there's nothing helpful/useful in the Japanese docs there either (i.e. nothing that would explain the bugs or wiring choices).
Still on my to-do list is to file an Issue with the NestopiaUE guy -- I'll get to it, don't worry, it's on my whiteboard. ;)
Given the
VRC2 clone that we found with a functioning microwire interface, I find myself wondering if it actually works. Perhaps Konami just decided that they were releasing no games where the additional cost of the EEPROM was worth only being able to save the game?
koitsu wrote:
Still on my to-do list is to file an Issue with the NestopiaUE guy -- I'll get to it, don't worry, it's on my whiteboard.
koitsu, you probably already got this issue in Nestopia covered and documented but if you don't I figured I'd make things easier for you and prepared this:
I have also attached a zip file containing 2 sates, 1 with the flying shooter part demo and 1 with Konami man in the hangar ready to take off.
Again, you may already have it covered and this is made using the Nestopia core in RetroArch.
Thanks for the save states -- I already have these though (specifically one before hangar take-off, and one at the very end of the game before the timer runs out). The .state files *do* work in NestopiaUE (just rename the extension from .state to .nsX appropriately).
I'll include these for rdanbrook as they'll help in verification.
The screenshots aren't all that useful, as I already demonstrated in my stream/YT videos (see links in first post) what the issues are. :-)
koitsu wrote:
Thanks for the save states -- I already have these though (specifically one before hangar take-off, and one at the very end of the game before the timer runs out). The .state files *do* work in NestopiaUE (just rename the extension from .state to .nsX appropriately).
I'll include these for rdanbrook as they'll help in verification.
The screenshots aren't all that useful, as I already demonstrated in my stream/YT videos (see links in first post) what the issues are.
No problem! I didn't know what you had so I took and made what I thought might be useful enable to solve this once and for all.
I'm just glad that this is gonna be solved and it works great in puNES now
koitsu wrote:
Nice report
:thumbs up:
Looks like BizHawk (NesHawk) picked up the change as well:
https://github.com/TASVideos/BizHawk/co ... 46edf9fdd1 --
type there refers to an integer they set, where for VRC2 type=2 and for VRC4 type=4. So they up using this variable as the mask for which bits to honour on mirroring writes (when previously it was always set to honour bits 1-0), rather than using an if/else or case statement to differentiate.
There's been positive response to this matter from lots of mainstream emulators. Thumbs up; good community involvement. Thanks everyone!
The only "flack" I've seen, which is still ongoing, is in
the NestopiaUE ticket where a single individual is hellbent on trying to keep this from being fixed properly. First they advocated the same 0xFF comparison kludge as FCEUX. Now they're arguing that 4-screen (don't ask me why 4-screen is being brought up, I think they might mean 1-screen) support can't be removed because "unofficial VRC2 games use the feature" (I've asked for a list of those games because that would be helpful). If anyone here has insights or comments to make on that, I politely ask they comment in the ticket.
I've only two "intuitions" about Wai Wai world: either the $FF write is an unexpected bug (programmer error but it works by chance), or it's intentional in the sense that Konami knew they could write $FF to the mirroring register because only D0 is honoured, hence saving themselves an
lda #$01. Either way, since the hardware only looks at D0, there's absolutely nothing wrong with a non-0 or non-1 write. *shrug*
Just remember one thing: mapper 23 has historically been used for 3 separate chips: VRC2b, VRC4e, and VRC4f. VRC4 supports more than just H/V-only. It's a bummer because had VRC2b not been lumped in with the VRC4e/4f variants in this manner, we wouldn't be dealing with this today.
Attachment:
2016-04-13_15-12-51.png [ 16.46 KiB | Viewed 3822 times ]
The issue at
https://github.com/rdanbrook/nestopia is now closed and finally we can put this one to rest.
This also have been merged to the Libretro core so I can't wait to try it out.