So I had posted recently about converting a no-mapper game (NES Balloon Fight) to run on real VS hardware. Mapper 0 games seem to be a breeze, since ROM mirroring isn't an issue and there aren't any additional complexities introduced by adding CHR-RAM or other strange add-on hardware.
The next logical step is to try to tackle some of the games that use actual mappers. I'm trying to help a small group of VS owners get some better quality games on their machines, and I was asked to give Contra a shot. This is the second UNROM(2) game that I've tried, the first was Skate or Die! Neither "worked", because it appears to be using incorrect tile data (presumably from addressing incorrect name tables) anytime that scrolling is introduced. I'm using the VS Castlevania daughterboard for both of these games, and I'm operating under the assumption that because the NES version is UNROM(2) so must be the VS version (well, that and it has CHR-RAM on the board, and a single PRG ROM on it).
Can anybody clue me in to potential ways of solving this behavior? Am I right about the cause, or is it something more nefarious, like the RAM size difference between the VS/NES systems? I'd like to work this out, because the VS library is somewhat limited, and there's just a couple of games I'd like to have available to make better use of the 2-players per side functionality of the cabinet.
Album of NES Contra on VS (2 images)
Vs. System uses 4-screen VRAM. Try setting the 4-screen bit in your ROM's header and seeing if it makes the same garbage in an emulator.
tepples wrote:
Vs. System uses 4-screen VRAM. Try setting the 4-screen bit in your ROM's header and seeing if it makes the same garbage in an emulator.
That's a good suggestion. Do you know if OpenEmu (for Mac) will honor the mirroring bit in the header? My Windows machine is at a friend's house currently, so I only have access to Raspberry Pis and Macs at the moment. Also, if it's determined that the 4-screen VRAM of the VS system makes these games impossible to run; what do you think about the idea of modding the motherboard by cutting some of the traces and installing toggles to change the mirroring schemes? Or is that just crazy talk?
NovaSquirrel has a Raspberry Pi and may be able to help you get an emulator running.
I'm pretty sure FCEUX (SDL version) supports 4-screen, and you can probably compile that yourself on your Mac. If you want, I can test FCEUX's 4-screen support using my Linux box once I get home from work.
You wouldn't necessarily need to modify the system board itself if you can ROM hack the games to respect 4-screen.
tepples wrote:
NovaSquirrel has a Raspberry Pi and may be able to help you get an emulator running.
No worries, there. I can get something up and working later on, I was just asking because I'm at work currently.
tepples wrote:
I'm pretty sure FCEUX (SDL version) supports 4-screen, and you can probably compile that yourself on your Mac. If you want, I can test FCEUX's 4-screen support using my Linux box once I get home from work.
If you don't mind checking it tonight, I'd appreciate it. I've got some family business going on this evening, so it may take me longer to get around to it. If not, I'll get to it sometime tomorrow.
tepples wrote:
You wouldn't necessarily need to modify the system board itself if you can ROM hack the games to respect 4-screen.
I was hoping that would be the case, but I wasn't sure how trivial it would be to modify those routines. My understanding was that the mirroring usually served a purpose, which was to facilitate scrolling in a specific direction, by allowing access to a buffer of VRAM. Maybe I need to revisit the purpose of mirroring to understand it better. At any rate, wouldn't the 4-screen mirroring be both cases simultaneously? And ultimately, isn't that the reason the VS system has double the VRAM on both sides of the board (compared to the NES)?
I really quickly modified the header in a copy of Contra (U) [!] to indicate 4-screen nametables ... and, yes, it breaks. Apparently it sets the Y scroll value to show the lower nametables but draws the first stage (at least) to the upper nametables.
lidnariq wrote:
I really quickly modified the header in a copy of Contra (U) [!] to indicate 4-screen nametables ... and, yes, it breaks. Apparently it sets the Y scroll value to show the lower nametables but draws the first stage (at least) to the upper nametables.
Thanks for checking on that, Lidnariq. So now I guess I need to work out the best way to handle the problem. Has anyone worked with this problem before, that is, modifying a ROM to use a different mirroring scheme? Is anyone interested or up to the challenge of helping me modify the ROM to work? Or was my original idea of modifying hardware probably a little more tangible in terms of effort/results?
I'm a programmer by trade, but my low-level skills are really rusty. Combine that with my inexperience on the 6502, and this could take me a long time. I'd like the satisfaction of working it out on my own, but I might have questions. A lot of them.
I have confirmed that FCEUX 2.2.3 indeed supports UNROM + 4-screen. Change byte 6 of the header from $21 to $28.
How to mapper hack: Trap all writes to $2001 in the debugger and see where the data is loaded for those writes. If they're wrong, you'll want to either change the data at the source or EOR #$02 before writing to $2001.
Contra would need quite a bit of hacking to make the vertical scrolling levels work correctly on 4-screen mode.
I wonder if it's possible to wire switches to disable address selection pins on the nametable memory, thus getting mirroring?
Yeah, modifying either mainboard or daughterboard to limit the portion of the nametable RAM seen wouldn't be hard.
A daughter modification would be the most "accurate" in the spirit of NES mirroring controlled by the Game Pak.
tepples wrote:
A daughter modification would be the most "accurate" in the spirit of NES mirroring controlled by the Game Pak.
I'm starting to think that's really the way to go. Can't I just run A10 from CIRAM to either the PPU's A10 (vertical) or A11 (horizontal) pins? If so, that seems like it would be very easy to just throw a switch in the circuit to control that behavior, especially being isolated on the daughterboard like that.
Unfortunately(?) the Vs. System uses a 4K RAM for its nametables, so there isn't really something equivalent to the NES's CIRAM A10 signal.
Although some of the mappers could have runtime selected mirroring (MMC1, VRC, and SUNSOFT-3), the rest seem to all use hard-wired mirroring (UNROM, m99≈NROM/CNROM/m87, N108). For these latter ones, you should be able to add a pair of SPDT switches such that PPU A10 and/or PPU A11 are passed through to the mainboard (where it will then connect to the NTRAM, 2C/8C TC5533), or are replaced with a constant signal (e.g. ground).
However, the tricky bit is that the CHR ROM (or CHR RAM in the case of UNROM) on the daughterboard still needs to retain access to both signals. What do the sockets look like on the underside? Are they a combination socket-and-pin-header? Or might it be possible to get something in between the two?
lidnariq wrote:
However, the tricky bit is that the CHR ROM (or CHR RAM in the case of UNROM) on the daughterboard still needs to retain access to both signals. What do the sockets look like on the underside? Are they a combination socket-and-pin-header? Or might it be possible to get something in between the two?
The daughterboards remain completely separated from the system, barring the pin headers that pass the CPU and PPU pins to the mainboard. Is that what you were asking?
I think I'm asking specifically about the headers that pass through to the system.
If the whole thing is a sandwich with these layers:
PPU
socket
daughterboard
pins
mainboard
this would need to interpose between the daughterboard and the mainboard ... but if the socket and pins are one and the same, the only way I can think of to do this would be to add another set of sockets between the pins and the mainboard.
lidnariq wrote:
I think I'm asking specifically about the headers that pass through to the system.
If the whole thing is a sandwich with these layers:
PPU
socket
daughterboard
pins
mainboard
this would need to interpose between the daughterboard and the mainboard ... but if the socket and pins are one and the same, the only way I can think of to do this would be to add another set of sockets between the pins and the mainboard.
Ah, now I understand. Yes, that is exactly how the board is setup. I believe the sockets have really long pins on them, so they are soldered to the daughterboard, but pass through to the main board.
Well, you could try getting three 40-pin sockets -- either milled or stamped -- and breaking or otherwise removing only one of either PPU A10 or PPU A11.
Put the unmodified one in the CPU socket, and put the one missing PPU A10 or PPU A11 in the PPU socket according to the mirroring the game needs. (Contra should need the one missing PPU A11). Then put the daughterboard in the new sockets.
Mind, this leaves that pin floating, which isn't the best idea, so you might want to additionally add a jumper in one of the CHR ROM sockets from the now-floating pin to either ground or +5V.
Got excited when I realized that I have a bunch of cheapo 40-pin sockets laying around... Folded pin 27 (A11) out of the way, and booted it up. It ain't perfect, but it's a step in the right direction! Disclaimer: I did not ground or tie the pin to +5V yet, do you think that might clear up what's in
this video?
A11 for the nametables only, not for the CHR RAM, correct?
Doesn't VS system also have some mode to use more CHR data than a usual NES game? Wonder if that would be triggered here?
Dwedit wrote:
A11 for the nametables only, not for the CHR RAM, correct?
Correct; I did it in a way that would be like unplugging A11 from the PPU.
lupin3rd wrote:
It ain't perfect, but it's a step in the right direction! Disclaimer: I did not ground or tie the pin to +5V yet, do you think that might clear up what's in this video?
Part of it could be, but the sprites would not be caused by that. That behavior's just wrong.
I suppose another possibility is, since the NTRAM is also socketed (that Toshiba RAM in 2C/8C), you could get a 28-pin socket and do the same trick with pulling out PPU A10/A11 from that.
Dwedit wrote:
Doesn't VS system also have some mode to use more CHR data than a usual NES game? Wonder if that would be triggered here?
Yes, but no. This is on the UNROM-like daughterboard, which doesn't use the M99 CHR banking.
lidnariq wrote:
lupin3rd wrote:
It ain't perfect, but it's a step in the right direction! Disclaimer: I did not ground or tie the pin to +5V yet, do you think that might clear up what's in this video?
Part of it could be, but the sprites would not be caused by that. That behavior's just wrong.
In the video,
to me anyway, it looks like some crazy stuff is happening during the drawing of the screen. Like, the game is writing graphical data to the PPU outside of the VBLANK cycle. I want to be wrong about that.
Can anyone explain the
purpose of mirroring to me? I mean, is it used for double-buffering type purposes -- where one screen is drawn, while the other section of memory is being written to? And then it flips on the next frame?
lidnariq wrote:
I suppose another possibility is, since the NTRAM is also socketed (that Toshiba RAM in 2C/8C), you could get a 28-pin socket and do the same trick with pulling out PPU A10/A11 from that.
Mine isn't socketed. I can fix that, though. I wish there was another test I could try to see if the behavior changes.
lidnariq wrote:
Dwedit wrote:
Doesn't VS system also have some mode to use more CHR data than a usual NES game? Wonder if that would be triggered here?
Yes, but no. This is on the UNROM-like daughterboard, which doesn't use the M99 CHR banking.
Is VS Gumshoe the game that used that method? I know there was a service release about modifying the board to be able to do it; did any other games get released that used it?
lupin3rd wrote:
Can anyone explain the purpose of mirroring to me?
Cost-cutting.
Honestly, that Nintendo managed to find a 4K RAM for the Vs. System at all is kinda surprising.
Quote:
Is VS Gumshoe the game that used that method? I know there was a service release about modifying the board to be able to do it; did any other games get released that used it?
m99 CHR banking was used by all games that came as 6 ROMs (well, specifically any game that had two ROMs for sockets 2A/2B or 8A/8B)
Vs. Gumshoe did something a little weirder, and used that same control to also control one of the address lines (A13) on socket 1D or 6D.
lupin3rd wrote:
Can anyone explain the purpose of mirroring to me? I mean, is it used for double-buffering type purposes -- where one screen is drawn, while the other section of memory is being written to? And then it flips on the next frame?
Mirroring in the NES is basically because the VRAM doesn't have room for the four pattern tables that they decided to address [because doubling the on-system VRAM wouldhave been incredibly expensive at the time (beaten by: lidnariq), but still to allow for cartridge-based expansion for those who would spend]. Really, it's "how do we connect A10 of console VRAM? [when] Do we use the console-supplied 2KiB VRAM?"
One can use one-screen patterns to double-buffer, yes--then it's basically bankswitching the VRAM.
The two-screen size of [NES] VRAM means one can have scrolling buffer OR have a complete separate screen to buffer.
We have a rather excellent graphic on the wiki showing how basic sidescrolling works.I hope that's not confusing.
Myask wrote:
Mirroring in the NES is basically because the VRAM doesn't have room for the four pattern tables that they decided to address [because doubling the on-system VRAM would have been incredibly expensive at the time (beaten by: lidnariq), but still to allow for cartridge-based expansion for those who would spend]. Really, it's "how do we connect A10 of console VRAM? [when] Do we use the console-supplied 2KiB VRAM?"
I think I'm understanding a bit more about that now. On the console, you have the convenience of connecting to more RAM supplied by a cart, or other features (mappers, SRAM, backups, etc.). Thanks!
Myask wrote:
I saw that image! It is indeed helpful, especially due to the circular nature of wrapping the scrolling buffer back around to the start.
Okay, so this project is starting to wear me out. I feel like there is a simple-ish solution within reach, but I'm overlooking it. What about this idea...
Making a CPU/PPU daughterboard, but instead of modifying NES ROMs to burn and play on it, do you think I'd get better mileage out of adding an edge connector to plug the original cart in, but then tying the necessary CPU/PPU pins to the cart's edge connector?
In essence, wouldn't I be recreating the same interface that the NES uses to talk to games? I think the only necessary modification using this approach would be using a socket to intercept a few of the address lines, as the VS is by default hardwired to more RAM, so to
downgrade it, shouldn't I just be able to tie those extra addressing pins to the connector and plug the cart in?
lupin3rd wrote:
Making a CPU/PPU daughterboard, but instead of modifying NES ROMs to burn and play on it, do you think I'd get better mileage out of adding an edge connector to plug the original cart in, but then tying the necessary CPU/PPU pins to the cart's edge connector?
That would make sense for future ease-of-use, but there's still the need to interpose between the PPU and the NT RAM.
Plus, the Vs. System is incompatible with any games that add their own RAM for the CPU. Might still be worth it, though.
Quote:
so to downgrade it, shouldn't I just be able to tie those extra addressing pins to the connector and plug the cart in?
Yeah, theoretically. That's what the sockets you added should have been doing... but why it caused corruption on sprites is just confusing.
Comparing the behavior in your video to the behavior in FCEUX, ... it kinda looks like the connection between PPU A11 and the RAM on the daughterboard maybe being interfered with? All of the tiles that are "good" on the title screen come from the upper half (tiles where PPU A11 is +5V), and all the wrong tiles of the title screen are replaced by the tile where PPU A11 was high instead. (You'll note that the lower half of the "CONTRA" is mostly intact, but the upper half and all of the places that would be text are instead bits of the stylized protagonists:
Attachment:
contra-title-screen-fceux-ppu-viewer.png [ 5.23 KiB | Viewed 2105 times ]
Attachment:
Contra on Nintendo VS System-I1cCh12hHIg-18.275sX.jpg [ 17.74 KiB | Viewed 2105 times ]
Similarly, the tile that's supposed to contain the stars in the background ($4F) is replaced with the pattern for tile $CF...
Did folding the pin over in the socket actually keep it from making contact?
lidnariq wrote:
Did folding the pin over in the socket actually keep it from making contact?
Yes. There should have been no connection there. The socket that normally holds the PPU is plastic and is the type that has no metal near the entry hole. So the pin that was folded out of the way, was flat over the top of a plastic socket, no metal touching!
Just for paranoia's sake, does the title screen work correctly if you get rid of the sockets? (Like it did in the first place)
lidnariq wrote:
Just for paranoia's sake, does the title screen work correctly if you get rid of the sockets? (Like it did in the first place)
Yes. As soon as I put it all back with all pins connected, title screen looks good, the black screen showing the score and number of lives looks good, and then the game starts and we're back to square one, with incorrect tiles everywhere.
So in other words, you disconnected PPU A11 for everything and not just nametables, just as I suspected above.
PPU memory map:
0000-1FFF: CHR-RAM
2000-2FFF: Nametables (full 4K)
To get vertical mirroring, we want to have it disable the bottom set of nametables (2800-2FFF) without messing with CHR-RAM.
NES Cartridges have pins that go back to the address selection for the internal nametable memory, and can be controlled by the wiring on the board, or by a mapper, or even let the cartridge host the full 4K of nametables.
But if there is no such thing there, I guess you'd need to do 'A11 = (NOT A13) AND A11.'
Well, either disconnected PPU A11 from the CHR RAM, or somehow connected something else to PPU A11 such that that overrode it on the daughterboard. It would have the same symptoms.