(MESS) nes.c: fixed WRAM banking for MMC5, so that Bandit Kings of Ancient China

(and Suikoden - Tenmei no Chikai) can be considered as working. Also fixed wrong
battery size for Aoki Ookami to Shiroki Mejika - Genchou Hishi in xml, which was causing 
a "Memory Over" error message ingame. [Fabio Priuli]

out of whatsnew: apparently the current WRAM mirroring (based on nesdev wiki notes)
causes glitches in some of these games. I hope to improve this soonish.
This commit is contained in:
Fabio Priuli 2014-06-03 17:08:51 +00:00
parent 5582b6aba7
commit 3517de3580
5 changed files with 48 additions and 105 deletions

View File

@ -1701,7 +1701,7 @@
</part>
</software>
<software name="genchohi" supported="no">
<software name="genchohi">
<description>Aoki Ookami to Shiroki Mejika - Genchou Hishi (Jpn)</description>
<year>1993</year>
<publisher>Koei</publisher>
@ -1718,8 +1718,7 @@
<rom name="koe-gg-0 chr" size="262144" crc="28e1a2c7" sha1="3c644d6d11f7eef992c314d7822216cd00de9293" offset="00000" />
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
<dataarea name="bwram" size="32768">
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -2756,7 +2755,7 @@
</part>
</software>
<software name="bandking" supported="no">
<software name="bandking">
<description>Bandit Kings of Ancient China (USA)</description>
<year>1990</year>
<publisher>Koei</publisher>
@ -2773,7 +2772,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -7638,7 +7636,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -14040,7 +14037,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -18022,7 +18018,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -19000,7 +18995,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -20918,7 +20912,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -20947,7 +20940,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -26680,7 +26672,6 @@
</dataarea>
<!-- 32k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="32768">
<rom value="0x00" size="32768" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -26706,7 +26697,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -26787,7 +26777,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -31162,7 +31151,6 @@
</dataarea>
<!-- 32k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="32768">
<rom value="0x00" size="32768" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -31933,7 +31921,6 @@
</dataarea>
<!-- 32k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="32768">
<rom value="0x00" size="32768" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -31959,7 +31946,6 @@
</dataarea>
<!-- 32k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="32768">
<rom value="0x00" size="32768" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -32957,7 +32943,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 1k Internal RAM in the MMC5 chip (ExRAM) -->
<dataarea name="mapper_ram" size="1024">
@ -35507,7 +35492,7 @@
</part>
</software>
<software name="suikoden" cloneof="bandking" supported="no">
<software name="suikoden" cloneof="bandking">
<description>Suikoden - Tenmei no Chikai (Jpn)</description>
<year>1990</year>
<publisher>Koei</publisher>
@ -35525,7 +35510,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -40364,7 +40348,6 @@
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">
@ -43324,7 +43307,6 @@ We should eventually add it to MESS as a separate driver with a NES CPU and a GB
</dataarea>
<!-- 32k WRAM on cartridge (or 40k? readme mentions 5x16k srams!) no batteries? -->
<dataarea name="bwram" size="32768">
<rom value="0x00" size="32768" offset="0" loadflag="fill" />
</dataarea>
<dataarea name="wram" size="8192">
</dataarea>
@ -47858,7 +47840,6 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx
</dataarea>
<!-- 8k WRAM on cartridge, battery backed up -->
<dataarea name="bwram" size="8192">
<rom value="0x00" size="8192" offset="0" loadflag="fill" />
</dataarea>
<!-- 8k WRAM on cartridge -->
<dataarea name="wram" size="8192">

View File

@ -83,6 +83,8 @@ void nes_exrom_device::device_start()
save_item(NAME(m_split_bank));
save_item(NAME(m_vcount));
save_item(NAME(m_exram));
save_item(NAME(m_ram_hi_banks));
}
void nes_exrom_device::pcb_reset()
@ -129,6 +131,11 @@ void nes_exrom_device::pcb_reset()
m_prg_ram_mapped[1] = 0;
m_prg_ram_mapped[2] = 0;
m_prg_ram_mapped[3] = 0;
m_ram_hi_banks[0] = 0;
m_ram_hi_banks[1] = 0;
m_ram_hi_banks[2] = 0;
m_ram_hi_banks[3] = 0;
}
@ -144,29 +151,10 @@ void nes_exrom_device::pcb_reset()
iNES: mapper 5
MESS status: Mostly Unsupported
MESS status: Partially supported
-------------------------------------------------*/
/* MMC5 can map PRG RAM to 0x8000-0xdfff */
void nes_exrom_device::prgram_bank8_x(int start, int bank)
{
assert(start < 4);
assert(bank >= 0);
assert(m_prgram.count() + m_battery.count());
// currently we use 4x8k BWRAM + 4x8k WRAM banks, independently from the actual PRG-RAM size
// mirroring of the actual size is taken care of at bank setup (even if no known commercial game relies on it!)
//bank &= (m_prgram.count() / 0x2000) - 1;
if (!m_prgram.count() || !m_battery.count())
bank &= 3;
// PRG RAM is mapped after PRG ROM
m_prg_bank[start] = m_prg_chunks + bank;
m_prg_bank_mem[start]->set_entry(m_prg_bank[start]);
}
void nes_exrom_device::update_prg()
{
int bank0, bank1, bank2, bank3;
@ -184,8 +172,8 @@ void nes_exrom_device::update_prg()
if (m_prg_ram_mapped[1])
{
prgram_bank8_x(0, ((bank1 << 1) & 0x07));
prgram_bank8_x(1, ((bank1 << 1) & 0x07) | 1);
m_ram_hi_banks[0] = ((bank1 << 1) & 0x07);
m_ram_hi_banks[1] = ((bank1 << 1) & 0x07) | 1;
}
else
prg16_89ab(bank1);
@ -200,14 +188,14 @@ void nes_exrom_device::update_prg()
if (m_prg_ram_mapped[1])
{
prgram_bank8_x(0, ((bank1 << 1) & 0x07));
prgram_bank8_x(1, ((bank1 << 1) & 0x07) | 1);
m_ram_hi_banks[0] = ((bank1 << 1) & 0x07);
m_ram_hi_banks[1] = ((bank1 << 1) & 0x07) | 1;
}
else
prg16_89ab(bank1);
if (m_prg_ram_mapped[2])
prgram_bank8_x(2, bank2 & 0x07);
m_ram_hi_banks[2] = (bank2 & 0x07);
else
prg8_cd(bank2);
@ -221,17 +209,17 @@ void nes_exrom_device::update_prg()
bank3 = m_prg_regs[3];
if (m_prg_ram_mapped[0])
prgram_bank8_x(0, bank0 & 0x07);
m_ram_hi_banks[0] = (bank0 & 0x07);
else
prg8_89(bank0);
if (m_prg_ram_mapped[1])
prgram_bank8_x(1, bank1 & 0x07);
m_ram_hi_banks[1] = (bank1 & 0x07);
else
prg8_ab(bank1);
if (m_prg_ram_mapped[2])
prgram_bank8_x(2, bank2 & 0x07);
m_ram_hi_banks[2] = (bank2 & 0x07);
else
prg8_cd(bank2);
@ -631,10 +619,10 @@ WRITE8_MEMBER(nes_exrom_device::write_l)
// 3bits are used to access the "WRAM" banks
// bit3 select the chip (2 of them can be accessed, each up to 32KB)
// bit1 & bit2 select the 8KB banks inside the chip
// same mechanism is used also when "WRAM" is mapped in higher banks, but there we setup the bank map in a smart
// way so to access the correct bank as if the 3 bits were directly selecting the bank in a 64KB RAM area
// same mechanism is used also when "WRAM" is mapped in higher banks
READ8_MEMBER(nes_exrom_device::read_m)
{
LOG_MMC(("exrom read_m, offset: %04x\n", offset));
if (m_battery && m_prgram) // 2 chips present: first is BWRAM, second is WRAM
{
if (m_wram_base & 0x04)
@ -652,6 +640,7 @@ READ8_MEMBER(nes_exrom_device::read_m)
WRITE8_MEMBER(nes_exrom_device::write_m)
{
LOG_MMC(("exrom write_m, offset: %04x, data: %02x\n", offset, data));
if (m_wram_protect_1 != 0x02 || m_wram_protect_2 != 0x01)
return;
@ -662,16 +651,31 @@ WRITE8_MEMBER(nes_exrom_device::write_m)
}
// some games (e.g. Bandit Kings of Ancient China) write to PRG-RAM through 0x8000-0xdfff
// it does not work well yet!
READ8_MEMBER(nes_exrom_device::read_h)
{
LOG_MMC(("exrom read_h, offset: %04x\n", offset));
int bank = offset / 0x2000;
if (bank < 3 && offset >= bank * 0x2000 && offset < (bank + 1) * 0x2000 && m_prg_ram_mapped[bank])
{
if (m_battery && m_ram_hi_banks[bank] < 4)
return m_battery[((m_ram_hi_banks[bank] * 0x2000) + (offset & 0x1fff)) & (m_battery.count() - 1)];
else if (m_prgram)
return m_prgram[(((m_ram_hi_banks[bank] & 3) * 0x2000) + (offset & 0x1fff)) & (m_prgram.count() - 1)];
}
return hi_access_rom(offset);
}
WRITE8_MEMBER(nes_exrom_device::write_h)
{
LOG_MMC(("exrom write_h, offset: %04x, data: %02x\n", offset, data));
int bank = offset / 0x2000;
if (m_wram_protect_1 != 0x02 || m_wram_protect_2 != 0x01 || bank == 3 || !m_prg_ram_mapped[bank])
return;
bank = m_prg_bank[bank] - m_prg_chunks;
if (m_battery && m_prg_bank[bank] < m_prg_chunks + 4)
m_battery[((bank * 0x2000) + (offset & 0x1fff)) & (m_battery.count() - 1)] = data;
if (m_battery && m_ram_hi_banks[bank] < 4)
m_battery[((m_ram_hi_banks[bank] * 0x2000) + (offset & 0x1fff)) & (m_battery.count() - 1)] = data;
else if (m_prgram)
m_prgram[(((bank & 3) * 0x2000) + (offset & 0x1fff)) & (m_prgram.count() - 1)] = data;
m_prgram[(((m_ram_hi_banks[bank] & 3) * 0x2000) + (offset & 0x1fff)) & (m_prgram.count() - 1)] = data;
}

View File

@ -16,6 +16,7 @@ public:
virtual void device_start();
virtual DECLARE_READ8_MEMBER(read_l);
virtual DECLARE_READ8_MEMBER(read_m);
virtual DECLARE_READ8_MEMBER(read_h);
virtual DECLARE_WRITE8_MEMBER(write_l);
virtual DECLARE_WRITE8_MEMBER(write_m);
virtual DECLARE_WRITE8_MEMBER(write_h);
@ -29,7 +30,6 @@ public:
protected:
void set_mirror(int page, int src);
void prgram_bank8_x(int start, int bank);
void update_render_mode();
void update_prg();
@ -78,6 +78,8 @@ protected:
// MMC-5 contains 1K of internal ram
UINT8 m_exram[0x400];
UINT8 m_ram_hi_banks[4];
// int m_nes_vram_sprite[8];
};

View File

@ -672,52 +672,7 @@ void device_nes_cart_interface::pcb_start(running_machine &machine, UINT8 *ciram
m_prg_bank_mem[3] = machine.root_device().membank("prg3");
for (int i = 0; i < 4; i++)
{
int next_bank = m_prg.count() / 0x2000;
m_prg_bank_mem[i]->configure_entries(0, m_prg.count() / 0x2000, m_prg, 0x2000);
// MMC5 (and a few other PCBs) can also map WRAM/BWRAM in these banks, so we add here 4x8K banks for each RAM chip
// No boards with 64Kb of WRAM/BWRAM has been found so far, otherwise the code has to be updated!
if (m_battery)
{
if (m_battery.count() / 0x2000 == 4)
{
m_prg_bank_mem[i]->configure_entries(next_bank, 4, m_battery, 0x2000);
}
if (m_battery.count() / 0x2000 == 2)
{
m_prg_bank_mem[i]->configure_entries(next_bank + 0, 2, m_battery, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 2, 2, m_battery, 0x2000);
}
if (m_battery.count() / 0x2000 == 1)
{
m_prg_bank_mem[i]->configure_entries(next_bank + 0, 1, m_battery, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 1, 1, m_battery, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 2, 1, m_battery, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 3, 1, m_battery, 0x2000);
}
next_bank += 4;
}
if (m_prgram)
{
if (m_prgram.count() / 0x2000 == 4)
{
m_prg_bank_mem[i]->configure_entries(next_bank, 4, m_prgram, 0x2000);
}
if (m_prgram.count() / 0x2000 == 2)
{
m_prg_bank_mem[i]->configure_entries(next_bank + 0, 2, m_prgram, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 2, 2, m_prgram, 0x2000);
}
if (m_prgram.count() / 0x2000 == 1)
{
m_prg_bank_mem[i]->configure_entries(next_bank + 0, 1, m_prgram, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 1, 1, m_prgram, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 2, 1, m_prgram, 0x2000);
m_prg_bank_mem[i]->configure_entries(next_bank + 3, 1, m_prgram, 0x2000);
}
next_bank += 4;
}
// ...but we always map the banks to PRG at start
m_prg_bank_mem[i]->set_entry(i);
m_prg_bank[i] = i;
}

View File

@ -158,7 +158,8 @@ void nes_state::machine_start()
m_ppu->set_latch(ppu2c0x_latch_delegate(FUNC(device_nes_cart_interface::ppu_latch),m_cartslot->m_cart));
// install additional handlers (read_h, read_ex, write_ex)
if (m_cartslot->get_pcb_id() == STD_NROM368 || m_cartslot->get_pcb_id() == GG_NROM || m_cartslot->get_pcb_id() == CAMERICA_ALADDIN || m_cartslot->get_pcb_id() == SUNSOFT_DCS
if (m_cartslot->get_pcb_id() == STD_EXROM || m_cartslot->get_pcb_id() == STD_NROM368
|| m_cartslot->get_pcb_id() == GG_NROM || m_cartslot->get_pcb_id() == CAMERICA_ALADDIN || m_cartslot->get_pcb_id() == SUNSOFT_DCS
|| m_cartslot->get_pcb_id() == BANDAI_DATACH || m_cartslot->get_pcb_id() == BANDAI_KARAOKE || m_cartslot->get_pcb_id() == BTL_2A03_PURITANS || m_cartslot->get_pcb_id() == AVE_MAXI15
|| m_cartslot->get_pcb_id() == KAISER_KS7022 || m_cartslot->get_pcb_id() == KAISER_KS7031 || m_cartslot->get_pcb_id() == BMC_VT5201
|| m_cartslot->get_pcb_id() == UNL_LH32 || m_cartslot->get_pcb_id() == UNL_LH10 || m_cartslot->get_pcb_id() == UNL_2708