Vs. DualSystem

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Vs. DualSystem
by on (#231248)
I'm trying to determine the plausibility of integrating Vs. DualSystem support with Netplay in my emulator. But I can't seem to get any of the DualSystem ROMs to function. From the wiki and other sources, I've collected the following information:

The DualSystem uses 2 CPUs, one configured as Master and the other Slave. That status can be determined by reading 4016.7 (0 = Slave, 1 = Master).

The CPUs share a common memory region (6000--67FF), though it can only be accessed by 1 CPU at a time. Access is coordinated via 4016.1 on both CPUs. Specifically, when Master 4016.1 drops from 1 to 0, that triggers an interrupt in Slave. Slave acknowledges that the interrupt handler completed by dropping its 4016.1 from 1 to 0. I think the cycle works something like:

1. Master and Slave both start out with 4016.1 set to 1.
2. Master reads and writes from shared memory.
3. Master 4016.1 drops from 1 to 0 indicating that it's done with shared memory.
4. That drop triggers an interrupt on Slave.
5. Slave's interrupt handler reads and writes from shared memory.
6. Slave 4016.1 drops from 1 to 0 indicating that it's done with shared memory.
7. Master sets 4016.1 to 1.
8. Slave responds to rise in Master's 4016.1 by setting its 4016.1 to 1.
9. Goto 1

I suspect, but I can't find documentation to back this up, that there is some external clock that causes interrupts in Master that drives that cycle. If that exists, can someone point me to some info on it.

Regarding the Vs. DualSystem ROMs. I'm looking at Balloon Fight (VS) [!].nes. PRG ROM and CHR ROM are twice the size as their counterparts in Balloon Fight (U) [!].nes. I didn't compare the bytes, but I assume the CHR ROMs are probably the same, but the code in PRG ROMs might be different, enabling 1 CPU to act as Master and the other Slave. But that could also be achieved through configuration; so, it might be exactly the same ROMs repeated twice in the file.

Anyway, I'd like to get VS Balloon Fight running in a single CPU (with some hacking of my emulator) if that's possible. Specifically, can I fool the Master into thinking that a Slave exists, when there is no actual Slave connected? In other words, what is the minimum things that I need to do to simulate a fake Slave?

Regarding Netplay, I need to know how much data is transferred in shared memory region and how often that region is accessed. E.g. can I transfer that data once-per-frame and keep the CPUs working? If I can simulate a fake Slave, then I can analyze how often shared memory is accessed and determine if Netplay is possible.

Any input is much appreciated. Thx.
Re: Vs. DualSystem
by on (#231249)
zeroone wrote:
That status can be determined by reading 4016.7 (0 = Slave, 1 = Master).
Backwards... I know I helped Sour implement Vs. System recently, and he was having seriously problems with it backwards. The current text on the wiki was his suggested wording ... are you using an older snapshot of the wiki?

Nocash's EveryNES has it backwards.

Quote:
The CPUs share a common memory region (6000--67FF)
2 KiB of RAM, but mirrored over the entire range from $6000-$7FFF.

Quote:
4016.1 drops from 1 to 0, that triggers an interrupt in Slave. Slave acknowledges that the interrupt handler completed by dropping its 4016.1 from 1 to 0.
/IRQ is level triggered, not edge triggered. IRQ will re-start until the other CPU releases it.

Quote:
Anyway, I'd like to get VS Balloon Fight running in a single CPU (with some hacking of my emulator) if that's possible. Specifically, can I fool the Master into thinking that a Slave exists, when there is no actual Slave connected? In other words, what is the minimum things that I need to do to simulate a fake Slave?
The specifics of the protocol is game-specific, so unfortunately you're not going to get away with faking something. You simply must emulate the second CPU. You probably don't have to emulate the second PPU.
Re: Vs. DualSystem
by on (#231251)
Can we gather all the DualSystem information onto a dedicated Wiki page or a separate block within the existing VS page? It seems scattered. And I did use NoCash's info to fill in gaps, which apparently mixed me up.

lidnariq wrote:
/IRQ is level triggered, not edge triggered. IRQ will re-start until the other CPU releases it.


Can you spell that out for me in terms of 4016.1 reads and writes? The wiki says that Master sets 4016.1 to 1 to gain shared memory access and when Master sets 4016.1 to 0, Slave gains shared memory access. When Master writes 0 to 4016.1, I assume that asserts the interrupt on Slave. And Slave writes 0 to 4016.1 to acknowledge that it's done with shared memory?

If I knew a little more about what data is passed over shared memory, it sounds like I could fake the Slave. Of course, that's game specific.

@Sour please give me some hints!
Re: Vs. DualSystem
by on (#231252)
The VS schematic is available, if that helps. The shared RAM is in the upper-left corner.
https://archive.org/details/vsschematicmds-02-cpu
Re: Vs. DualSystem
by on (#231253)
It's not exactly fresh in my mind, but Mesen actually runs both CPUs (and both PPUs) at once (running 1 full CPU instruction on one before switching to the other, which isn't perfectly accurate, but close enough).

Logic used on $4016 writes (pseudocode, see VsControlManager::UpdateSlaveMasterBit in Mesen if you want to see the actual code):
Code:
void UpdateSlaveMasterBit(uint8_t slaveMasterBit)
{
   //slaveMasterBit is the value of bit 1 ($02) that was just written to $4016
   CPU* otherCpu= _currentCpu->GetOtherCpu();
   if(otherCpu != nullptr) {
      if(_currentCpu->IsMasterCpu()) {
         //Update memory access - this is only done when the master CPU writes to $4016
         if(slaveMasterBit) {
            //Set memory at $6000-$7FFF as readable/writable for master CPU
            //Set memory at $6000-$7FFF as open bus for slave CPU
         } else {
            //Set memory at $6000-$7FFF as open bus for master CPU
            //Set memory at $6000-$7FFF as readable/writable for slave CPU
         }
      }

      if(slaveMasterBit) {
         otherCpu->ClearIrqSource(IRQSource::External);
      } else {
         //When low, asserts /IRQ on the other CPU
         otherCpu->SetIrqSource(IRQSource::External);
      }
   }
}

For netplay/savestates/movies, the state of the master & slave consoles are both saved together in the same data stream. For the "P1" and "P2" inputs of the slave console, I cheated and internally mapped them to the standard P3 and P4 logic, which allows netplay and movies to work without any Dualsystem-specific changes.

Hopefully this helps a bit? I can't really offer any advice on how to fake the slave CPU, though, since I just emulated everything and display both screens in the emulator.

Edit: RE: Netplay, Mesen emulates both CPUs on both machines when playing via netplay. It doesn't try to synchronize the shared RAM between both PCs - that is most likely not viable since the RAM is probably read/written to every frame (e.g to synchronize the position of players/monsters in Balloon fight, for example)
Re: Vs. DualSystem
by on (#231254)
Does the Dualsystem PCB actually say "master" or "slave"?
Re: Vs. DualSystem
by on (#231255)
zeroone wrote:
Regarding the Vs. DualSystem ROMs. I'm looking at Balloon Fight (VS) [!].nes
There is also my conversion utility that will create canonical NES ROM files from MAME split ROMs.
zeroone wrote:
Anyway, I'd like to get VS Balloon Fight running in a single CPU (with some hacking of my emulator) if that's possible. Specifically, can I fool the Master into thinking that a Slave exists, when there is no actual Slave connected? In other words, what is the minimum things that I need to do to simulate a fake Slave?
Fake certain responses in the shared ram at $6000. Doing so can only be done on a game-specific basis. Here is what I did before I added actual emulation of a second CPU to NintendulatorNRS:
Code:
void   MAPINT   Write4 (int Bank, int Addr, int Val) {
   if (Addr ==0x16) {
      EMU->SetIRQ((Val &2)? 1: 0);
      // Fake Vs. Dual System
      if (~Val &2) switch (ROM->PRGROMCRC32) {
         // Vs. Balloon fight
         case 0x9213A19E: case 0xAD407F52: case 0x6AD67502:
            switch((EMU->GetCPUReadHandler(6))(6, 0x000)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x000, 0x00); break;
               case 0x55: (EMU->GetCPUWriteHandler(6))(6, 0x000, 0xAA); break;
               case 0xAA: (EMU->GetCPUWriteHandler(6))(6, 0x000, 0x55); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x220)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x220, 0x55); break;
               case 0x55: (EMU->GetCPUWriteHandler(6))(6, 0x220, 0xAA); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x0FF)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x0FF, 0x11); break;
               case 0x11: (EMU->GetCPUWriteHandler(6))(6, 0x0FF, 0x88); break;
            }
            break;
         // Vs. Wrecking Crew
         case 0x008A9C16: case 0x30C42B1E: case 0x12B36F73:
            switch((EMU->GetCPUReadHandler(6))(6, 0x051)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x051, 0x01); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x053)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x053, 0x01); break;
            }
            break;
         // Vs. Baseball
         case 0xF5DEBF88: case 0xB5853830: case 0xC4DD2523: case 0x13A91937: case 0xF64D7252: case 0x968A6E9D:
         case 0x44691677: case 0x327BD71D: case 0x038E1E1B: case 0x60C90D8A:
            switch((EMU->GetCPUReadHandler(6))(6, 0x002)) {
               case 0x63: (EMU->GetCPUWriteHandler(6))(6, 0x002, 0x64); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x00A)) {
               case 0x01: (EMU->GetCPUWriteHandler(6))(6, 0x00A, 0x00); break;
            }
            break;
         // Vs. Tennis
         case 0xB90497AA: case 0xBC202DB6: case 0x2AF7E14E: case 0x777EE984: case 0xD46B8C5F:
            switch((EMU->GetCPUReadHandler(6))(6, 0x002)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x002, 0x80); break;
               case 0x40: (EMU->GetCPUWriteHandler(6))(6, 0x002, 0xC0); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x113)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x113, 0x01); break;
            }
            break;
         // Vs. Mahjong
         case 0x381E5E08:
            switch((EMU->GetCPUReadHandler(6))(6, 0x002)) {
               case 0x3C: (EMU->GetCPUWriteHandler(6))(6, 0x002, 0xA5); break;
            }
            switch((EMU->GetCPUReadHandler(6))(6, 0x011)) {
               case 0x00: (EMU->GetCPUWriteHandler(6))(6, 0x011, 0x88); break;
            }
            break;
      }
   }
   _Write4(Bank, Addr, Val);
}
Re: Vs. DualSystem
by on (#231256)
zeroone wrote:
Can we gather all the DualSystem information onto a dedicated Wiki page or a separate block within the existing VS page? It seems scattered. And I did use NoCash's info to fill in gaps, which apparently mixed me up.
I've added a bit of a summary about how the Vs. System is like and how it's dislike a plain NES at the top of the page. I hope it clears up any confusion....

The only thing not mentioned on the Vs. System page is the specifics of mapper 99. I'm not clear what I could possibly say to make it clearer.

There's no other information on the wiki about this. What would we add?


zeroone wrote:
Can you spell that out for me in terms of 4016.1 reads and writes?
It means that as long as the last value CPU "A" wrote to $4016 had the 2s bit clear (".1"), and CPU "B" has not disabled interrupts ("sei" or due to being in its NMI or IRQ handler), CPU "B" will always enter its IRQ handler.

This is just like any other IRQ in the NES, it's just that it's coming from a CPU instead of a timer.

Quote:
And Slave writes 0 to 4016.1 to acknowledge that it's done with shared memory?
Maybe! Maybe not! The hardware only imposes these exact behaviors:
* The primary CPU controls which CPU has access to RAM
* When the primary CPU asserts /IRQ on the secondary CPU, this also gives the secondary CPU access to RAM.
* The secondary CPU can assert /IRQ on the primary CPU.

Any higher-level interpretation will be fragile and game-specific.



Tepples: All the OEM documentation uses "M" and "S" ubiquitously.
Re: Vs. DualSystem
by on (#231258)
lidnariq wrote:
The hardware only imposes these exact behaviors:
* The primary CPU controls which CPU has access to RAM
* When the primary CPU asserts /IRQ on the secondary CPU, this also gives the secondary CPU access to RAM.
* The secondary CPU can assert /IRQ on the primary CPU.

How can each CPU determine whether /IRQ was asserted because of APU DMC or because of a request from the other CPU? Is looking for a signature in shared RAM the primary way?

How are vertical blanks aligned between the two PPUs? Synchronized? Constant offset? Offset that drifts over the course of a game?

lidnariq wrote:
All the OEM documentation uses "M" and "S" ubiquitously.

I imagine it'd be more polite nowadays, in the era of Python issue 34605, to expand these as "main" and "secondary". Or am I missing something? EDIT: Withdrawn, as consensus has not yet formed
Re: Vs. DualSystem
by on (#231261)
tepples wrote:
How can each CPU determine whether /IRQ was asserted because of APU DMC or because of a request from the other CPU? Is looking for a signature in shared RAM the primary way?
The IRQ handler usually checks $4016 D7.
Re: Vs. DualSystem
by on (#231264)
tepples wrote:
How can each CPU determine whether /IRQ was asserted because of APU DMC or because of a request from the other CPU?
The pithy answer is "they don't use DMC or frame interrupts".

NewRisingSun wrote:
The IRQ handler usually checks $4016 D7.
That's to handle only having one set of ROMs that can run on both sides, not an indication that the IRQ is caused by the other CPU.

Quote:
How are vertical blanks aligned between the two PPUs? Synchronized? Constant offset? Offset that drifts over the course of a game?
Ok, these are things that should be on the page.

To answer:

PPUs are perfectly synchronized, but entirely by accident. All CPUs and PPUs are fed by the same 21.477MHz crystal, and all CPUs and PPUs are released from reset at the same time. The RGB PPUs never have missing dots under any conditions, so cannot get out of sync. Since they are fed by the same clock, they cannot drift.
Re: Vs. DualSystem
by on (#231265)
tepples wrote:
Does the Dualsystem PCB actually say "master" or "slave"?

I see what you're doing. Stop now.
Re: Vs. DualSystem
by on (#231267)
Thanks everyone for the great responses. It's going to take me a bit to fully digest all this.

There are only 5 VS. DualSystem ROMs that I am aware of: Balloon Fight, Baseball, Mahjong, Tennis and Wrecking Crew. I have all of them as listed as mapper 0, except for Baseball, which is mapper 99. But I could not confirm those mapper numbers. Does anyone have a table of them?
Re: Vs. DualSystem
by on (#231268)
Nocash additionally lists a version of Ice Climber.

No games for the Vs. System are really ever mapper 0; they're all actually mapper 99. If only 8 KiB of CHR is present—which I think specifically means only Vs. Mahjong—when $4016.2 is set there will be garbage graphics—it'll fetch open bus. All other Vs. DualSystem games seem to have 16 KiB CHR.

MAME enumerates 6 Vs. DualSystem games, plus five more variants (earlier versions or bad dumps):
"vstennis", 32 KiB PRG and 16 KiB CHR per side, different PRG and CHR for both sides
("vstennisa" and "vstennisb", same, with different PRG from above but identical CHR)
"wrecking" [crew], 32 KiB PRG and 16 KiB CHR per side, the same CHR on both sides
"balonfgt" [balloon fight], 32 and 16, same CHR on both sides
"vsmahjng" [mahjong], 24 and 8, same CHR on both sides
"vsbball" [baseball], 32 and 16, same CHR on both sides
("vsbballj", "vsbballja", and "vsbballjb", 32 and 16, all with the same CHR that differs from above)
"iceclmrd", 32 and 16, same CHR on both sides and almost-identical PRG.
Re: Vs. DualSystem
by on (#231269)
I am looking at the Dipswitch definitions file in Mesen. The number of switches and options suggests that the VS. DualSystem games have 16 DIPs instead of 8 DIPs. Perhaps this is possible since there are 4 controller ports instead of 2?

Is there a table in MAME or Nintendulator-NRS by any chance? I can't seem to locate it is in the sources.

lidnariq wrote:
No games for the Vs. System are really ever mapper 0; they're all actually mapper 99. If only 8 KiB of CHR is present—which I think specifically means only Vs. Mahjong—when $4016.2 is set there will be garbage graphics—it'll fetch open bus. All other Vs. DualSystem games seem to have 16 KiB CHR.


I've used other sources for reference, but I have VS Mighty Bomb Jack and VS Slalom as mapper 0. In addition, many other VS games are not mapper 99. They appear to work :)
Re: Vs. DualSystem
by on (#231270)
There is no mapper 0 Vs. System game. If you find one, it is a bad header.

The mapper 0 hardware is defined as "no PRG bankswitching, no CHR bankswitching" and that cannot happen on the Vs. System board: it is physically laid out such that you can't not have CHR bankswitching. It's not like putting an 8 KiB CHR ROM in a CNROM board and having a latch that does nothing: instead there are two physical sockets, and you can only put an 8 KiB (or smaller, but that was never done) ROM in each socket or fail to put anything in that socket: The result is still mapper 99 and the empty socket results in open bus.

It may work as mapper 0, in the same way emulators don't "have" to enforce bus conflicts on discrete logic mappers, but it's incorrect.


MAME's database is in https://github.com/mamedev/mame/blob/ma ... /vsnes.cpp
To convert common names to MAME codename, go to the bottom with the GAME macro.
To convert MAME codename into dipswitches, look for INPUT_PORTS_START( codename )
To convert MAME codename into ROM sizes and hashes, look for ROM_START( codename )
Re: Vs. DualSystem
by on (#231271)
zeroone wrote:
I am looking at the Dipswitch definitions file in Mesen. The number of switches and options suggests that the VS. DualSystem games have 16 DIPs instead of 8 DIPs. Perhaps this is possible since there are 4 controller ports instead of 2?


Yes, for a DualSystem game there effectively are 16 dipswitches. Each CPU sees 8, mapped into the same location. Other than the shared RAM, the 2 sides are symmetrical. In a dual cabinet it can run 2 UniSystem games independently. The single monitor cabinets use the same board but only install one CPU/PPU.
Re: Vs. DualSystem
by on (#231285)
Do any of the VS games in GoodNES3.23b work in the current Mesen release? None of them seem to open.
Re: Vs. DualSystem
by on (#231287)
No. As mentioned before, you need to create them from MAME ROM sets.
Re: Vs. DualSystem
by on (#231291)
NewRisingSun wrote:
No. As mentioned before, you need to create them from MAME ROM sets.


Oh. Why are the GoodNES ROMs useless? There is absolute no way to run them? It's starting to sound like if I support the VS DualSystem, no one is going to have the games to play it.
Re: Vs. DualSystem
by on (#231293)
Historically, it's been impossible to encode Vs. DualSystem ROMs in iNES format because the iNES format implies exactly one chunk of PRG and one chunk of CHR.

The DualSystem requires two chunks of PRG and two chunks of CHR... NewRisingSun has lead the effort to define an official encoding of Vs. DualSystems into NES2.0, but that's very recent.

Supporting MAME romsets would be the most immediate way to make it easy for people to run.
Re: Vs. DualSystem
by on (#231294)
lidnariq wrote:
The DualSystem requires two chunks of PRG and two chunks of CHR...


The existing GoodNES VS DualSystem .nes files are twice the size as their regular counterparts. Is the PRG and CHR ROMs not just doubled up?
Re: Vs. DualSystem
by on (#231296)
At the very least, the GoodNES 3.23b's Vs. System image for Balloon Fight is only one half. (The other half is named "(Player 2 Mode) [b1]" but it isn't a bad dump, it's the same hashes as in MAME).

Balloon Fight for NES/Famicom is a 16+8 game. Balloon Fight for the Vs. DualSystem is a 32+32+16+16 game. (Almost all DualSystem games are 32+32+16+16. Except Vs. Mahjong, which is 24+24+8+8)

There's no way for the original iNES format to mark whether the contents of the file is one PRG chunk or two. That's one of the things that NewRisingSun added in NES2.0.
Re: Vs. DualSystem
by on (#231313)
zeroone wrote:
It's starting to sound like if I support the VS DualSystem, no one is going to have the games to play it.
As more emulators add Vs. Dual System support, future versions of No-Intro and GoodNES (if there ever is one again) will likely include the proper NES 2.0 ROMs in their their datfiles and the associated collections, so I would say it's more of a temporary problem.
Re: Vs. DualSystem
by on (#231322)
lidnariq wrote:
At the very least, the GoodNES 3.23b's Vs. System image for Balloon Fight is only one half. (The other half is named "(Player 2 Mode) [b1]" but it isn't a bad dump, it's the same hashes as in MAME).

Balloon Fight for NES/Famicom is a 16+8 game. Balloon Fight for the Vs. DualSystem is a 32+32+16+16 game. (Almost all DualSystem games are 32+32+16+16. Except Vs. Mahjong, which is 24+24+8+8)

There's no way for the original iNES format to mark whether the contents of the file is one PRG chunk or two. That's one of the things that NewRisingSun added in NES2.0.


Ouch. Those GoodNES files are going to confuse anyone who wants to play those games. For the emulators that support the VS DualSystem, those ROMs are going to create the impression that the support is incomplete or buggy.

NewRisingSun wrote:
As more emulators add Vs. Dual System support, future versions of No-Intro and GoodNES (if there ever is one again) will likely include the proper NES 2.0 ROMs in their their datfiles and the associated collections, so I would say it's more of a temporary problem.


This is the first time I heard of "No-Intro". Is it a better collection than GoodNES?

More importantly, I agree with your sentiment. Let me PM you with a proposal.
Re: Vs. DualSystem
by on (#231340)
No-Intro is a community-run effort to replace Cowering's GoodTools, especially after he took leave for a decade.

Currently their NES/FC set don't include headers: it's just hashes of known good dumps. Official headers might be included there after NewRisingSun / Kevtris release a canonical set.
Re: Vs. DualSystem
by on (#231552)
lidnariq wrote:
There is no mapper 0 Vs. System game. If you find one, it is a bad header.

The mapper 0 hardware is defined as "no PRG bankswitching, no CHR bankswitching" and that cannot happen on the Vs. System board: it is physically laid out such that you can't not have CHR bankswitching. It's not like putting an 8 KiB CHR ROM in a CNROM board and having a latch that does nothing: instead there are two physical sockets, and you can only put an 8 KiB (or smaller, but that was never done) ROM in each socket or fail to put anything in that socket: The result is still mapper 99 and the empty socket results in open bus.

It may work as mapper 0, in the same way emulators don't "have" to enforce bus conflicts on discrete logic mappers, but it's incorrect.


MAME's database is in https://github.com/mamedev/mame/blob/ma ... /vsnes.cpp
To convert common names to MAME codename, go to the bottom with the GAME macro.
To convert MAME codename into dipswitches, look for INPUT_PORTS_START( codename )
To convert MAME codename into ROM sizes and hashes, look for ROM_START( codename )


FCEUX contains a table describing each VS UniSystem game:

Code:
VSUNIENTRY VSUniGames[] =
{
   { "Baseball", 0x691d4200ea42be45LL, 99, 2, RP2C04_001, 0 },
   { "Battle City", 0x8540949d74c4d0ebLL, 99, 2, RP2C04_001, 0 },
   { "Battle City(Bootleg)", 0x8093cbe7137ac031LL, 99, 2, RP2C04_001, 0 },

   { "Clu Clu Land", 0x1b8123218f62b1eeLL, 99, 2, RP2C05_004, IOPTION_SWAPDIRAB },
   { "Dr Mario", 0xe1af09c477dc0081LL, 1, 0, RP2C04_003, IOPTION_SWAPDIRAB },
   { "Duck Hunt", 0x47735d1e5f1205bbLL, 99, 2, RCP2C03B, IOPTION_GUN },
   { "Excitebike", 0x3dcd1401bcafde77LL, 99, 2, RP2C04_003, 0 },
   { "Excitebike (J)", 0x7ea51c9d007375f0LL, 99, 2, RP2C05_004, 0 },
   { "Freedom Force", 0xed96436bd1b5e688LL, 4, 0, RP2C04_001, IOPTION_GUN }, /* Wrong color in game select screen? */
   { "Stroke and Match Golf", 0x612325606e82bc66LL, 99, 2, RP2C04_002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x01 },

   { "Goonies", 0xb4032d694e1d2733LL, 151, 1, RP2C04_003, 0 },
   { "Gradius", 0x50687ae63bdad976LL, 151, 1, RP2C04_001, IOPTION_SWAPDIRAB },
   { "Gumshoe", 0x87161f8ee37758d3LL, 99, 2, RC2C05_03, IOPTION_GUN },
   { "Gumshoe", 0xb8500780bf69ce29LL, 99, 2, RC2C05_03, IOPTION_GUN },
   { "Hogan's Alley", 0xd78b7f0bb621fb45LL, 99, 2, RP2C04_001, IOPTION_GUN },
   { "Ice Climber", 0xd21e999513435e2aLL, 99, 2, RP2C05_004, IOPTION_SWAPDIRAB },
   { "Ladies Golf", 0x781b24be57ef6785LL, 99, 2, RP2C04_002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },

   { "Mach Rider", 0x015672618af06441LL, 99, 2, RP2C04_002, 0 },
   { "Mach Rider (J)", 0xa625afb399811a8aLL, 99, 2, RP2C04_001, 0 },
   { "Mighty Bomb Jack", 0xe6a89f4873fac37bLL, 0, 2, RC2C05_02, 0 },
   { "Ninja Jajamaru Kun", 0xb26a2c31474099c0LL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB },
   { "Pinball", 0xc5f49d3de7f2e9b8LL, 99, 2, RP2C04_001, IOPTION_PREDIP, 0x01 },
   { "Pinball (J)", 0x66ab1a3828cc901cLL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x1 },
   { "Platoon", 0x160f237351c19f1fLL, 68, 1, RP2C04_001, 0 },
   { "RBI Baseball", 0x6a02d345812938afLL, 4, 1, RP2C04_001, IOPTION_SWAPDIRAB },
   { "Soccer", 0xd4e7a9058780eda3LL, 99, 2, RP2C04_003, IOPTION_SWAPDIRAB },
   { "Star Luster", 0x8360e134b316d94cLL, 99, 2, RCP2C03B, 0 },
   { "Stroke and Match Golf (J)", 0x869bb83e02509747LL, 99, 2, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },
   { "Super Sky Kid", 0x78d04c1dd4ec0101LL, 4, 1, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x20 },

   { "Super Xevious", 0x2d396247cf58f9faLL, 206, 0, RP2C04_001, 0 },
   { "Tetris", 0x531a5e8eea4ce157LL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x20 },
   { "Top Gun", 0xf1dea36e6a7b531dLL, 2, 0, RC2C05_04, 0 },
   { "VS Castlevania", 0x92fd6909c81305b9LL, 2, 1, RP2C04_002, 0 },
   { "VS Slalom", 0x4889b5a50a623215LL, 0, 1, RP2C04_002, 0 },
   { "VS Super Mario Bros", 0x39d8cfa788e20b6cLL, 99, 2, RP2C05_004, 0 },
   { "VS Super Mario Bros [a1]", 0xfc182e5aefbce14dLL, 99, 2, RP2C05_004, 0 },
   { "VS TKO Boxing", 0x6e1ee06171d8ce3aLL, 4, 1, RP2C04_003, IOPTION_PREDIP, 0x00 },
   { 0 }
};


The value to the right of the checksum is mapper number. Several games function outside of mapper 99. And a few are mapper 0.

If this is incorrect, does that mean that description of Mapper 99 on the wiki is incomplete since it needs to absorb characteristics of other mappers for certain games?
Re: Vs. DualSystem
by on (#231554)
Mapper 99 is the CHR-ROM bank switch built into the Vs. System hardware. Since all games run on the Vs. System hardware, they will at minimum have mapper 99. Vs. Slalom merely has only one 8 KiB CHR-ROM bank, so not emulating the $4016 CHR-ROM switch by specifying mapper 0 amounts to the same result. But pedantically speaking, it's wrong. Other games do indeed bring their own mappers 1, 206, and 67/68. Mapper 151 is a duplicate of 75, meaning VRC1. Their existence does not mean that Mapper 99's description is incomplete, though.
Re: Vs. DualSystem
by on (#231618)
NewRisingSun wrote:
Other games do indeed bring their own mappers 1, 206, and 67/68. Mapper 151 is a duplicate of 75, meaning VRC1. Their existence does not mean that Mapper 99's description is incomplete, though.


Does the NES 2.0 header indicate the use of these other mappers?
Re: Vs. DualSystem
by on (#231620)
Of course. Just look at the Vs. System's ROM files...
Re: Vs. DualSystem
by on (#232160)
NewRisingSun wrote:
Of course. Just look at the Vs. System's ROM files...


I started working with your VS DualSystem NES 2.0 files. I setup 2 CPUs bridged by the shared memory range. And I am alternating between executing one instruction each processor. The master CPU appears to be attempting to trigger interrupts on the slave processor and I see reads from the exact addresses listed in your stub-processor code snippet. But the slave processor appears to be stuck in an infinite loop. It's not interested in the interrupt requests.

I'm not sure what I'm missing here. Any suggestions or experiments I can try?
Re: Vs. DualSystem
by on (#232161)
Well, you need to actually raise the IRQ pin, of course, and $4016 must return reads with D7 clear on the master and D7 set on the slave CPU, so that the code knows on which CPU it's running.
Re: Vs. DualSystem
by on (#232165)
NewRisingSun wrote:
Well, you need to actually raise the IRQ pin, of course, and $4016 must return reads with D7 clear on the master and D7 set on the slave CPU, so that the code knows on which CPU it's running.


Yep. I'm doing all that (I think). I also split the NES 2.0 PRG ROM, giving each CPU a half.
Re: Vs. DualSystem
by on (#232172)
Just so I can follow along, which specific game are you testing with right now?
Re: Vs. DualSystem
by on (#232179)
lidnariq wrote:
Just so I can follow along, which specific game are you testing with right now?


I've primarily focused on Balloon Fight and Wrecking Crew. They both have the behavior that I described where only the Master CPU seems to be doing it's thing.

Is there one game in particular that's easier to get running?
Re: Vs. DualSystem
by on (#232483)
I finally got most of the VS DualSystem games running. It turned out that I was failing to initialize the slave PPU properly, preventing it from receiving NMI's.

The only game that won't launch is Raid on Bungeling Bay. Supposedly, it has the same copy protection that Ice Climber has, but duplicating that has yet to get it going. I'm also testing with the padded NES 2.0 version; so, it's not an issue with PRG RAM locations.

Anyone have any hints for this one?

Edit: I got Raid on Bungeling Bay loaded. It just a typo on my end.
Re: Vs. DualSystem
by on (#233035)
I noticed that if I power on VS. Baseball in test mode (B2 - DS1), it shows a red battery:

Image

But if I reset it, the battery turns green.

Any idea how it does it's battery check?

Edit: Nevermind. It's supposed to do that.
Re: Vs. DualSystem
by on (#233037)
... oh, huh, I guess the wiki should mention that the shared RAM can be battery backed.
Re: Vs. DualSystem
by on (#233038)
lidnariq wrote:
... oh, huh, I guess the wiki should mention that the shared RAM can be battery backed.


In addition to high scores, these games appear to keep track of total coinage. For example, in the screenshot below of VS. Ice Climber (Japan), 6 coins were inserted into the left slot of System 2:

Image

This also means that the left and right coin slots provide independent signal bits. The wiki incorrectly suggests that the slots are usually wired in parallel. Nonetheless, for user-interface simplicity, I'm considering only providing options for inserting a coin into System 1 and into System 2, instead of System 1 - Slot 1, System 1 - Slot 2, System 2 - Slot 1, and System 2 - Slot 2. Unless someone really cares about the numbers displayed in test mode, is there any reason to provide all 4 options?

Edit: On a side note, all the VS manuals refer to the systems as "Main" and "Sub" as opposed to "Master" and "Slave". And the slots are referred to as "left" and "right". If I got with 4 insert-coin menu options, I may use that nomenclature.
Re: Vs. DualSystem
by on (#233041)
zeroone wrote:
these games appear to keep track of total coinage. For example, in the screenshot below of VS. Ice Climber (Japan), 6 coins were inserted into the left slot of System 2:

Image

Transcribing text in this screenshot in case it disappears from Imgur or Imgur changes its policy on third-party hosting, as ImageShack and Photobucket have:
Code:
    DISTRIBUTION

MAIN LEFT   000000
MAIN RIGHT  000000
SUB  LEFT   000006
SUB  RIGHT  000000

The main/sub terminology reminds me of what I would later see in the DS homebrew scene. On the DS, only the main GPU has a 3D unit, but the system can switch which physical screen gets the main GPU's output and which gets the 2D-only sub GPU's output.
Re: Vs. DualSystem
by on (#233044)
Does that mean that the canonical NES 2.0 headers for Vs. Uni/Dual games should have the battery bit set?
Re: Vs. DualSystem
by on (#233045)
Not all games use, or can use, that RAM. I'd naively assume that DualSystem games probably do. Most UniSystem games probably don't?
Re: Vs. DualSystem
by on (#233046)
NewRisingSun wrote:
Does that mean that the canonical NES 2.0 headers for Vs. Uni/Dual games should have the battery bit set?


The manuals may reveal which titles have battery-backed RAM and which do not. But I can't find manuals for all the games.
Re: Vs. DualSystem
by on (#233112)
I found an old forum post that mentions VS game batteries: https://web.archive.org/web/20050206091 ... webbat.htm

It's still unclear if that applies to all VS games or only a subset of them.

Also, here's an unrelated yet interesting link about "suicide batteries": http://www.arcadecollecting.com/dead/

Edit: Here is a pic of VS. Excitebike board. It's a VS. UniSystem board and an AA batteries holder is fixed to the left-side. I'll check other VS boards if I find more pics.

Edit 2: In the VS schematic, the battery appears in the upper-left and it powers chip 8L (MB8416-15 2k x 8bit Static CMOS RAM 150 ns). Even though VS games have 2K of nonvolatile RAM, that doesn't necessarily mean that all VS games use it. And it's uncertain what memory region it is mapped to.
Re: Vs. DualSystem
by on (#233124)
As far as I can tell, the Vs. System only had one class of PCB ("MDS-version-CPU"), regardless of game. All five versions have the battery holder, so all games could have that RAM battery-backed.

But because the battery is clearly field serviceable, and only one side can have access to the RAM at any given time, I don't know how many ever did.

"8L" is the 2K shared RAM.
Re: Vs. DualSystem
by on (#233134)
lidnariq wrote:
"8L" is the 2K shared RAM.


For VS. UniSystem, I assume it's the same $6000--$67FF (and mirrors) region that's shared in the VS. DualSystem. Since there aren't that many games, we could inspect that region for writes and see which games actually took advantage of the battery.

None of the manuals that I found revealed how to reset that RAM. Apparently, if you want to reset the high scores, you'd have to pull out the batteries. And doing so would also lose the coin counts. During my search, I noticed that some coin acceptors had mechanical odometers that indicated lifetime totals. That seems nicer than counts since last battery failure.
Re: Vs. DualSystem
by on (#233137)
All Vs. Dual System games access the $6000-$7FFF area. Among the Vs. Unisystem ones, only Vs. Super Mario Brothers, Vs. Xevious, and Vs. Tetris do. And Vs. Xevious may be a stray read from the protection check in the $5xxx area.
Re: Vs. DualSystem
by on (#233138)
zeroone wrote:
For VS. UniSystem, I assume it's the same $6000--$67FF (and mirrors) region that's shared in the VS. DualSystem.
It's the same physical PCB. The only difference between the UniSystem and DualSystem is the physical cabinet, and whether it has two CRTs and two sets of controls, or just one.

Here's someone's (Great Hierophant?) blog summarizing all three well-known physical cabinets.
http://nerdlypleasures.blogspot.com/201 ... -home.html

Quote:
During my search, I noticed that some coin acceptors had mechanical odometers that indicated lifetime totals.
As far as I know, all Vs. System cabinets have a physical coin counter. I don't know why Vs. Baseball keeps a redundant copy in battery-backed RAM.



NewRisingSun wrote:
All Vs. Dual System games access the $6000-$7FFF area.
Right, they have to to communicate with the other CPU. The question is whether things put there are expected to persist across a power outage.

Most (non-Vs. System) arcade machines that hold on to high scores don't; they instead expect the arcade operator will just leave them on.
Re: Vs. DualSystem
by on (#233140)
Vs. Tetris checks the $6000-$60E0 values before overwriting them, but that could be a soft vs. hard reset detection check instead of a battery-backed memory thing.
Re: Vs. DualSystem
by on (#233258)
Regarding the DualSystem, VS. Baseball and VS. Tennis show battery icons in Test Mode.

VS. Balloon Fight and VS. Ice Climber (Dual) show coin distribution counts in Test Mode, indicating battery use.

VS. Raid on Bungeling Bay and VS. Wrecking Crew have high score tables, but it's unknown if those tables are persisted through a power cycle. Neither provide Test Modes.

VS. Mahjong has a Test Mode. But, since I can't read Japanese, I can't ascertain if there is evidence of battery use there. From what I can tell, it doesn't look necessary.

NewRisingSun wrote:
Among the Vs. Unisystem ones, only Vs. Super Mario Brothers, Vs. Xevious, and Vs. Tetris do. And Vs. Xevious may be a stray read from the protection check in the $5xxx area. ...
Vs. Tetris checks the $6000-$60E0 values before overwriting them, but that could be a soft vs. hard reset detection check instead of a battery-backed memory thing.


I also can't find any evidence that any VS. UniSystem games employ battery-backed RAM.

As far as emulation goes, the safest bet is to persist shared memory for DualSystem games. And don't for UniSystem games.

Regarding the left vs. right coin slots and Main vs. Sub, I ended up with 4 menu items for testing. The left coin slot is associated with $4016.5, while the right slot is associated with $4016.6. This is based on the aforementioned coin distribution Test Mode screens. The manuals probably reveal this and in practice, the coin acceptors could be wired up differently.
Re: Vs. DualSystem
by on (#233259)
zeroone wrote:
VS. Balloon Fight and VS. Ice Climber (Dual) show coin distribution counts in Test Mode, indicating battery use.
I'm not sure that follows? The cabinets always have mechanical coin counters as well, so it's credible that this is intended only for tracking coins since the last power outage.
Re: Vs. DualSystem
by on (#233325)
lidnariq wrote:
The cabinets always have mechanical coin counters as well, so it's credible that this is intended only for tracking coins since the last power outage.


Agreed. The coin distribution count screens do not alone confirm battery use.

However, we have established that all the VS PCBs are nearly identical. They all have battery holders and when batteries are installed, the memory in range $6000--$67FF (and mirrors) is made non-volatile. Nonetheless, we only care about which games actually take advantage of that fact.

As a test, in my emulator, I persisted the data in that memory range on shutdown and restored it on start up. The coin distribution screens in VS. Balloon Fight and VS. Ice Climber (Dual) maintained their values. So, if the battery works like we expect it to, then those 2 games appear to be taking advantage of it.

Furthermore, the VS. Wrecking Crew high score table is retained.

But the VS. Raid on Bungeling Bay high score table is not! I can see the table in a hex dump of the shared memory region, but it's not maintained between bounces. It'll check if there's another copy in CPU RAM.

As for VS. Mahjong, I can't tell because I can't read Japanese.

My conclusion thus far is that VS. Balloon Fight, VS. Baseball, VS. Ice Climber (Dual), VS. Tennis and VS. Wrecking Crew all use battery-backed non-volatile RAM. And only VS. Raid on Bungeling Bay and VS. Mahjong (probably) do not.
Re: Vs. DualSystem
by on (#233326)
And neither Vs. Tetris and Vs. Super Mario Bros. keep the SRAM content upon startup. Boo.
Re: Vs. DualSystem
by on (#233327)
That's interesting to know, I've always wondered if anything really used the battery backup. In the arcade collecting community (when I was around it) I always saw people saying the battery was useless, and to remove them. I'm pretty sure my VS board had the factory original batteries in when I got it, a little corrosion on there.

It makes sense that only the DualSystem games would use it. The UniSystem games would either need to cooperate, or do something drastic like SMB does, it uses a fake CPU that is internally just a jumper, so the shared memory is forced to be available to the real CPU.

Referring to here: http://www.johnsarcade.com/nintendo_vs_ppu_info.php
It sounds like Raid on Bungeling Bay is doing something similar, it's only intended to be used with a UniSystem cabinet.
Re: Vs. DualSystem
by on (#233328)
Memblers wrote:
something drastic like SMB does, it uses a fake CPU that is internally just a jumper, so the shared memory is forced to be available to the real CPU.
Uh, what? A fake CPU that is a jumper? Vs. Raid on Bungeling Bay does have a real second CPU with PRG-ROM, one that only sets a flag in the shared memory though on which the first PRG-ROM code depends.
Re: Vs. DualSystem
by on (#233329)
Vs. SMB is the Vs. UniSystem game that requires that the game be operating in the secondary slot, and that a "2A04" be installed in the primary CPU slot.

The "2A04" is nothing but a jumper, giving the secondary CPU permanent access to the shared memory.
Re: Vs. DualSystem
by on (#233330)
NewRisingSun wrote:
And neither Vs. Tetris and Vs. Super Mario Bros. keep the SRAM content upon startup. Boo.


I can see the VS. Super Mario Bros. high score table in the SRAM region in a hex editor. I'll run a test in my emulator to see what happens if that region is persisted.
Re: Vs. DualSystem
by on (#233331)
Ah yeah I meant it's similar in that it's intended for a UniSystem cabinet, I wasn't certain about the way that RoBB did it.

So far it sounds like VS Wrecking Crew the only game that uses the battery for something interesting (not coin counting alone).
Re: Vs. DualSystem
by on (#233332)
zeroone wrote:
I can see the VS. Super Mario Bros. high score table in the SRAM region in a hex editor. I'll run a test in my emulator to see what happens if that region is persisted.
I told you I did, and nothing happens, because the game always clears that RAM.
Re: Vs. DualSystem
by on (#233334)
NewRisingSun wrote:
I told you I did, and nothing happens, because the game always clears that RAM.


Yep. I just wanted to see for myself. I actually played until I legitimately got my name on the high score table. Then I was saddened when it disappeared after a bounce.

Apparently, as mentioned several times already in this thread, the VS. UniSystem games do not take advantage of the battery.

Memblers wrote:
So far it sounds like VS Wrecking Crew the only game that uses the battery for something interesting (not coin counting alone).


I'll check if the others keep their score tables. I was only looking for any evidence of battery use.
Re: Vs. DualSystem
by on (#233343)
Memblers wrote:
So far it sounds like VS Wrecking Crew the only game that uses the battery for something interesting (not coin counting alone).


Here are the results (from most interesting to worst):

VS. Wrecking Crew -- High score table is saved

VS. Balloon Fight / VS. Ice Climber (Dual) -- Coin slot distribution saved | High score table is not saved

VS. Baseball / VS. Tennis -- Provides battery tester | Saves nothing (doesn't even provide high score table)

VS. Raid on Bungeling Bay / VS. Mahjong -- Saves nothing

If you want to get pedantic, all VS games have battery-backed RAM. The list above reveals how that feature was utilized. In the cart DB in my emulator, I'm going to mark the ones that do something with with the battery as having NVRAM.

@NewRisingSun As the keeper of the NES 2.0 ROMs, I'll leave the header bit choices up to you.
Re: Vs. DualSystem
by on (#233345)
zeroone wrote:
If you want to get pedantic, all VS games have battery-backed RAM.
I mean, sorta. Arcades aren't like cartridges. Most MDS games were distributed as packs of discrete ROMs and a manual, and the manual could have said something like "insert batteries to retain high score table".

It's not like Family BASIC where the data and hardware are coupled and only exist in one form, with a user-serviceable battery holder where it's reasonable to assume that the user would have always added those batteries.
Re: Vs. DualSystem
by on (#233348)
On a slightly different topic, other than frequenters of this forum, no one is going to have the ROMs to play the VS. DualSystem. But someone mentioned that the ROMs actually exists in the GoodNES set, but they are split across multiple files. Is it plausible to construct a table in which an emulator could seek out all the pieces and run this stuff, if you direct it to a GoodNES zip file? Alternatively, are the MAME files standard enough and available enough to use as an alternate source? Are there any plans to seed warez sites with the NES 2.0 files (maybe that should be answered privately)?
Re: Vs. DualSystem
by on (#233350)
zeroone wrote:
Is it plausible to construct a table in which an emulator could seek out all the pieces and run this stuff, if you direct it to a GoodNES zip file?
I'm not entirely certain there's a canonical packet for the redistributed copies of the ROMs referred to by Cowering's GoodTools. "GoodMerged" sets are a thing, most often 7z of each individual group. It might be best off just saving filenames? e.g. "Balloon Fight (VS) [!].nes" and "Balloon Fight (VS) (Player 2 Mode).nes"

Quote:
Alternatively, are the MAME files standard enough
Absolutely. Those have canonical contents and hashes.

(edit: to be specific, for the mapper 99 games, the filenames inside have canonical forms, where the extension specifies exactly at which CPU/PPU memory address each of the up-to-twelve ROMs are mapped)
Re: Vs. DualSystem
by on (#233351)
You could direct people to my little batch file that converts MAME sets to canonical NES 2.0 files (well, except now for the battery bit), or include them with your emulator.
Re: Vs. DualSystem
by on (#233422)
NewRisingSun wrote:
You could direct people to my little batch file that converts MAME sets to canonical NES 2.0 files (well, except now for the battery bit), or include them with your emulator.

With that batch file as a template and the set of hdr files, I was able to get my emulator to load MAME archives. That is, if you open an archive file that contains the complete MAME file set representing a VS game, it will assemble the pieces together in memory and collectively load it as a virtual NES 2.0 file. But, for space-saving reasons, MAME archives are organized using a parent-child scheme; game variant archives only contain modified ROM files, and MAME expects the original archive and the variant archive to coexist on the same drive. I didn't add that extra loading complexity. So, at least for now, the VS variants won't load, unless of course you assembled your own archive containing all the files.

lidnariq wrote:
I'm not entirely certain there's a canonical packet for the redistributed copies of the ROMs referred to by Cowering's GoodTools. "GoodMerged" sets are a thing, most often 7z of each individual group. It might be best off just saving filenames? e.g. "Balloon Fight (VS) [!].nes" and "Balloon Fight (VS) (Player 2 Mode).nes"

I'll examine if it's possible to load in multiple files like that if they are present within a common archive. I believe this is really an important feature because most people won't think of trying the MAME archives. And if they open one of those files, they'll just assume that the emulator is faulty.
Re: Vs. DualSystem
by on (#233478)
I compared a few GoodNES sets and they all had these files:

Balloon Fight.7z <Balloon Fight (VS) (Player 2 Mode) [b1].nes>
Balloon Fight.7z <Balloon Fight (VS) [!].nes>

Baseball.7z <Baseball (VS) (Player 1 Mode) [b1].nes>
Baseball.7z <Baseball (VS) (Player 1 Mode) [b2].nes>
Baseball.7z <Baseball (VS) (Player 1 Mode) [b3].nes>
Baseball.7z <Baseball (VS) (Player 2 Mode) [b1].nes>
Baseball.7z <Baseball (VS) (Player 2 Mode) [b2].nes>
Baseball.7z <Baseball (VS) (Player 2 Mode) [b3].nes>
Baseball.7z <Baseball (VS) [b1].nes>

Ice Climber.7z <Ice Climber (VS) (Player 1 Mode) [b1].nes>
Ice Climber.7z <Ice Climber (VS) (Player 2 Mode) [b1].nes>

Mahjong.7z <Mahjong (VS) (Player 1 Mode) [b1].nes>
Mahjong.7z <Mahjong (VS) (Player 2 Mode) [b1].nes>
Mahjong.7z <Mahjong (VS) [!].nes>
Mahjong.7z <Mahjong (VS) [a1].nes>

Tennis.7z <Tennis (VS) (Player 2 Mode) [b1].nes>
Tennis.7z <Tennis (VS) [!].nes>
Tennis.7z <Tennis (VS) [o1].nes>

Wrecking Crew.7z <Wrecking Crew (VS) (Player 1 Mode) [b1].nes>
Wrecking Crew.7z <Wrecking Crew (VS) (Player 2 Mode) [b1].nes>
Wrecking Crew.7z <Wrecking Crew (VS) [!].nes>
Wrecking Crew.7z <Wrecking Crew (VS) [hM01].nes>

The only VS. DualSystem game missing from that list is Raid on Bungeling Bay. And I'm still not sure if it really is possible to combine those files to play them.

As for other ROM sources, the No-Intro sets appear highly sanitized. Each archive contains only 1 NES file. And the VS games are not among them. Those games may be treated as MAME-only.

I found other ROM collections and they're also missing the VS games.

In other words, even if I support combining the files listed above, the trick will only work for GoodNES.
Re: Vs. DualSystem
by on (#233583)
I implemented the GoodNES trick discussed above and it works fine. Aside from Raid on Bungeling Bay, the VS. DualSystem games can be loaded from the GoodNES set.

This means that there is 3 valid sources of VS. DualSystem ROMs: NES 2.0 files, MAME files and GoodNES files.
Re: Vs. DualSystem
by on (#233596)
zeroone wrote:
This means that there is 3 valid sources of VS. DualSystem ROMs: NES 2.0 files, MAME files and GoodNES files.

You should give the option to convert from one ROM set to another.
Re: Vs. DualSystem
by on (#233625)
Zepper wrote:
You should give the option to convert from one ROM set to another.


I'm considering adding that feature. However, unlike NewRisingSun's script, the aforementioned MAME parent-child archive file mechanism would prevent conversion of the variants. NewRisingSun's script works because it acts on the full universe of MAME VS. ROMs as opposed to individual archives. Aside from being incomplete in that regard, there are other things that could be converted, e.g. UNIF to NES 2.0.
Re: Vs. DualSystem
by on (#233921)
zeroone wrote:
Here are the results (from most interesting to worst):

VS. Wrecking Crew -- High score table is saved

VS. Balloon Fight / VS. Ice Climber (Dual) -- Coin slot distribution saved | High score table is not saved

VS. Baseball / VS. Tennis -- Provides battery tester | Saves nothing (doesn't even provide high score table)

VS. Raid on Bungeling Bay / VS. Mahjong -- Saves nothing


One other minor discovery: If you power cycle VS. Wrecking Crew, your current game will be lost, but you don't lose any remaining credits. In fact, if you insert coins and power cycle before hitting a start button, the machine resumes exactly where it left off, with all your credits intact. None of the other VS. DualSystem games retain credits between power cycles.
Re: Vs. DualSystem
by on (#234415)
Regarding the VS. System schematic, I see that the battery in the upper-left is in parallel with power. And the battery and power are protected with diodes. I assume this means that when the cabinet is powered by the mains, the battery is idle and its not losing energy. However, to the very right of that are a few resistors and a transistor. Is that circuit part of the switch-between-power-and-battery mechanism?
Re: Vs. DualSystem
by on (#234422)
Yes.

In A1: D6, W03B ¹
D8, W03B ¹
R121, 100k ²
R77, 3.3k ³
R76, 12k ³
R75, 10k ³
unlabeled NPN transistor ³

In A2: R119, 680Ω ²
D9, 2A953 ²

In C2: LS157 ²

In F1: R3, 10KΩ ³
C3, 10µF ³
R4, 27 ³
PST518A, brownout detection IC ³

In F 1/2: retriggerable one-shot for reset detection ⁴

In G 1/2: retriggerable one-shot for watchdog ⁵

¹ - the actual thing that allows whichever of battery, and +5V, are higher to power the shared RAM
² - diode-OR logic between the multiplexed /SharedRAMCE and brownout signal
³ - the brownout detection circuit, enabling shared RAM as long as the +5V line is high enough
⁴ - ultimately what resets the CPUs, PPUs, and coin counter latch, for roughly 1/3 second
⁵ - ultimately what requires that the secondary CPU read from $4017 every second