metal combat chip question

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
metal combat chip question
by on (#37019)
HI

I have a METAL COMBAT cart, I read in the snes list that this cart has the FX chip, but, the chip that I see says:
4L01F1234
OBC1
NINTENDO
JAPAN 9204EAI

is this the FX chip?

thanks

by on (#37021)
Yes, it is the peripheral chip, but it is not a FX chip.

by on (#37027)
OBC-1 is a chip only used in Metal Combat. I've never heard specifically what it does but I imagine it helps with the very large and complex enemys you fight in the game compared to the first game, Battle Clash. Both are great games that I think are under appreciated since most people never played it with the Super Scope. I have and I think the games are fantastic.

by on (#37050)
This is what the chip does:

Code:
void OBC1::reset() {
  for(unsigned i = 0x0000; i <= 0x1fff; i++) ram_write(i, 0xff);

  status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00;
  status.address = (ram_read(0x1ff6) & 0x7f);
  status.shift   = (ram_read(0x1ff6) & 3) << 1;
}

uint8 OBC1::read(uint addr) {
  addr &= 0x1fff;
  if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);

  switch(addr) { default: //never used, avoids compiler warning
    case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
    case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
    case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
    case 0x1ff3: return ram_read(status.baseptr + (status.address << 2) + 3);
    case 0x1ff4: return ram_read(status.baseptr + (status.address >> 2) + 0x200);
    case 0x1ff5: case 0x1ff6: case 0x1ff7: return ram_read(addr);
  }
}

void OBC1::write(uint addr, uint8 data) {
  addr &= 0x1fff;
  if((addr & 0x1ff8) != 0x1ff0) return ram_write(addr, data);

  switch(addr) {
    case 0x1ff0: ram_write(status.baseptr + (status.address << 2) + 0, data); break;
    case 0x1ff1: ram_write(status.baseptr + (status.address << 2) + 1, data); break;
    case 0x1ff2: ram_write(status.baseptr + (status.address << 2) + 2, data); break;
    case 0x1ff3: ram_write(status.baseptr + (status.address << 2) + 3, data); break;
    case 0x1ff4: {
      uint8 temp = ram_read(status.baseptr + (status.address >> 2) + 0x200);
      temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
      ram_write(status.baseptr + (status.address >> 2) + 0x200, temp);
    } break;
    case 0x1ff5: {
      status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
      ram_write(addr, data);
    } break;
    case 0x1ff6: {
      status.address = (data & 0x7f);
      status.shift   = (data & 3) << 1;
      ram_write(addr, data);
    } break;
    case 0x1ff7: {
      ram_write(addr, data);
    } break;
  }
}


... and that's it. 100% bit-perfect emulation of the entire chip.

Mapping:

Code:
void sBus::map_obc1() {
  map(MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, obc1);
  map(MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, obc1);
}


It's essentially a very, very simplistic save RAM mapper. It helps build OAM (sprite) tables in RAM (without the need for bit manipulation), that are then DMA'ed into OAM memory.

Honestly, it seems like a serious waste of an engineering effort. It should be a weekend project for an experienced programmer to remove the need for the chip entirely. That said, I'm not going to do it.

I think the biggest justification for it was the anti-piracy benefits.

by on (#37056)
Thanks for the information
I have both games, battle clash and metal combat, but I don't have the Super Scope :(

by on (#37071)
Wow thanks byuu. Nice to know for sure what it does. Very interesting as well to hear that the chip is basically copy protection since it's not really doing anything that couldn't have been done standard.

If I actually understood what all what going on in that code I'd actually want to try to hack the game myself but I don't quite grasp what is going on. Personally I'd be more interested in knowing if it were feasible to hack the Cx4 games to run without the Cx4 chip. I know it is used for building OAM and some calculations and the wireframe business but I don't really think anything couldn't be done in software.

by on (#37125)
The Cx4 is way more complicated. It does a bunch of 3D calculations and sprite sorting, some quite involved. Of course, given the SNES is turing complete, there's not really much you can't do on it. But implementing the full Cx4 in pure SNES ASM would prove much too slow, in my opinion.

The OBC-1 just makes writing sprite attributes easier. Probably helps because MC has some huge bosses, but I think with enough code optimization, you could avoid any visible slowdown and still remove the chip.