summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2014-02-09 11:21:08 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2014-02-09 11:21:08 +0000
commit98ea494a9f3438f8cc57fa0b241827b01938ae8d (patch)
tree6549b10bab79eb821869111172b5449340d85126
parentbab0e881678b95bc01e31cb4080ca9697b75eab2 (diff)
(MESS) nes: added support for iNES 2.0 submappers [Fabio Priuli]
out of whatsnew: + fixed a small bug in handling MMC-1 games with > 8K of WRAM (only a Jpn baseball games use this, and I can see no difference in behavior) + updated emulation status in xml for a few games I had made working during slot-ification
-rw-r--r--hash/nes.xml20
-rw-r--r--src/mess/machine/nes_ines.inc169
-rw-r--r--src/mess/machine/nes_mmc1.c8
-rw-r--r--src/mess/machine/nes_nxrom.c5
-rw-r--r--src/mess/machine/nes_pcb.inc4
5 files changed, 164 insertions, 42 deletions
diff --git a/hash/nes.xml b/hash/nes.xml
index 43229551374..08f54f32e38 100644
--- a/hash/nes.xml
+++ b/hash/nes.xml
@@ -1365,7 +1365,7 @@
</part>
</software>
- <software name="aliensyn" supported="no">
+ <software name="aliensyn">
<description>Alien Syndrome (USA)</description>
<year>1989</year>
<publisher>Tengen</publisher>
@@ -17169,13 +17169,14 @@
</part>
</software>
- <software name="ideyumj" supported="no">
+ <software name="ideyumj">
<description>Ide Yousuke Meijin no Jissen Mahjong (Jpn, Rev. A)</description>
<year>1987</year>
<publisher>Capcom</publisher>
<info name="serial" value="CAP-IM"/>
<info name="release" value="19870924"/>
<info name="alt_title" value="井出洋介名人の実戦麻雀"/>
+ <info name="usage" value="This only works on a Famicom with Mahjong Controller attached"/>
<part name="cart" interface="nes_cart">
<feature name="slot" value="uxrom" />
<feature name="pcb" value="HVC-UNROM" />
@@ -17190,13 +17191,14 @@
</part>
</software>
- <software name="ideyumj2" supported="no">
+ <software name="ideyumj2">
<description>Ide Yousuke Meijin no Jissen Mahjong II (Jpn)</description>
<year>1991</year>
<publisher>Capcom</publisher>
<info name="serial" value="CAP-2Q"/>
<info name="release" value="19910222"/>
<info name="alt_title" value="井出洋介名人の実戦麻雀Ⅱ"/>
+ <info name="usage" value="This only works on a Famicom with Mahjong Controller attached"/>
<part name="cart" interface="nes_cart">
<feature name="slot" value="sxrom" />
<feature name="pcb" value="HVC-SNROM" />
@@ -17516,7 +17518,7 @@
</part>
</software>
- <software name="impmiss2" supported="no">
+ <software name="impmiss2">
<description>Impossible Mission-II (USA)</description>
<year>1989</year>
<publisher>American Video Entertainment / SEI</publisher>
@@ -20187,7 +20189,7 @@
</part>
</software>
- <software name="klax" supported="no">
+ <software name="klax">
<description>Klax (USA)</description>
<year>1990</year>
<publisher>Tengen</publisher>
@@ -30163,7 +30165,7 @@
</part>
</software>
- <software name="roadrunn" supported="partial">
+ <software name="roadrunn">
<description>Road Runner (USA)</description>
<year>1989</year>
<publisher>Tengen</publisher>
@@ -31798,7 +31800,7 @@
</part>
</software>
- <software name="sango2ht" supported="no">
+ <software name="sango2ht">
<description>Sangokushi II - Haou no Tairiku (Jpn)</description>
<year>1992</year>
<publisher>Namcot</publisher>
@@ -42848,7 +42850,7 @@
<!-- Non game cartridges -->
- <software name="ggenie" supported="no">
+ <software name="ggenie">
<description>Game Genie (USA, v1.5 &amp; v1.5A)</description>
<year>1990</year>
<publisher>Galoob</publisher>
@@ -46570,7 +46572,7 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx
</part>
</software>
- <software name="klaxp" cloneof="klax" supported="no">
+ <software name="klaxp" cloneof="klax">
<description>Klax (USA, Prototype)</description>
<year>1990</year>
<publisher>Tengen</publisher>
diff --git a/src/mess/machine/nes_ines.inc b/src/mess/machine/nes_ines.inc
index 08adf48c30c..1a4c1533f77 100644
--- a/src/mess/machine/nes_ines.inc
+++ b/src/mess/machine/nes_ines.inc
@@ -340,11 +340,12 @@ void nes_cart_slot_device::call_load_ines()
UINT32 vram_size = 0, prgram_size = 0, battery_size = 0, mapper_sram_size = 0;
UINT32 prg_size, vrom_size;
UINT8 header[0x10];
- UINT8 mapper, local_options;
+ UINT8 mapper, submapper = 0, local_options;
bool ines20 = FALSE, prg16k;
const char *mapinfo = NULL;
int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0;
int crc_hack = 0;
+ bool bus_conflict = FALSE;
// check if the image is recognized by nes.hsi
mapinfo = hashfile_extrainfo(*this);
@@ -406,12 +407,93 @@ void nes_cart_slot_device::call_load_ines()
if (ines20)
{
mapper |= (header[8] & 0x0f) << 8;
- // header[8] & 0xf0 is used for submappers, but I haven't found any specific image to implement this
+ // read submappers (based on 20140116 specs)
+ submapper = (header[8] & 0xf0 >> 8);
prg_size += ((header[9] & 0x0f) << 8) * 0x4000;
vrom_size += ((header[9] & 0xf0) << 4) * 0x2000;
}
ines_mapr_setup(mapper, &pcb_id);
+ // handle submappers
+ if (submapper)
+ {
+ // 001: MMC1
+ if (mapper == 1 && submapper == 3)
+ pcb_id = STD_SXROM_A;
+ else if (mapper == 1 && submapper == 5)
+ logerror("Unimplemented iNES2.0 submapper: SEROM/SHROM/SH1ROM.\n");
+ // 002, 003, 007: UxROM, CNROM, AxROM
+ else if (mapper == 2 && submapper == 2)
+ bus_conflict = TRUE;
+ else if (mapper == 3 && submapper == 2)
+ bus_conflict = TRUE;
+ else if (mapper == 7 && submapper == 2)
+ bus_conflict = TRUE;
+ // 021, 023, 025: VRC4 / VRC2
+ else if (mapper == 21 || mapper == 23 || mapper == 25)
+ {
+ // 021, 023, 025: VRC4
+ int line_1 = submapper & 0x07;
+ int line_2 = (submapper & 0x08) ? line_1 + 1 : line_1 - 1;
+ if (line_2 >= 0 && line_2 <= 7)
+ {
+ pcb_id = KONAMI_VRC4;
+ m_cart->set_vrc_lines(line_1, line_2, 0);
+ }
+ else if (submapper == 15)
+ {
+ pcb_id = KONAMI_VRC2;
+ m_cart->set_vrc_lines(1, 0, 0);
+ }
+ }
+ // 032: Irem G101
+ else if (mapper == 32 && submapper == 1)
+ {
+ m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring
+ }
+ // iNES Mapper 034
+ else if (mapper == 34 && submapper == 1)
+ {
+ pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards
+ }
+ // iNES Mapper 068 / Sunsoft 4
+ else if (mapper == 68 && submapper == 1)
+ {
+ submapper = 0;
+ logerror("Unimplemented iNES2.0 submapper: SUNSOFT-DCS.\n");
+ }
+ // iNES Mapper 071
+ else if (mapper == 71 && submapper == 1)
+ {
+ m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 71 is used for 2 diff boards
+ }
+ // iNES Mapper 078
+ else if (mapper == 78)
+ {
+ if (submapper == 1)
+ pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards
+ else if (submapper == 3)
+ pcb_id = IREM_HOLYDIVR;
+ }
+ // iNES Mapper 185
+ else if (mapper == 185)
+ {
+ int ce_state = (submapper & 0x0c) >> 2;
+ m_cart->set_ce(0x03, ce_state);
+ }
+ // iNES Mapper 232
+ else if (mapper == 210 && submapper == 1)
+ {
+ submapper = 0;
+ logerror("Unimplemented iNES2.0 submapper: CAMERICA-BF9096.\n");
+ }
+ else if (submapper)
+ {
+ submapper = 0;
+ logerror("Undocumented iNES2.0 submapper, please report it to the MESS boards!\n");
+ }
+ }
+
// SETUP step 3: storing the info needed for emulation
m_pcb_id = pcb_id;
m_cart->set_mirroring(BIT(local_options, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
@@ -426,11 +508,13 @@ void nes_cart_slot_device::call_load_ines()
if ((header[10] & 0x0f) > 0)
prgram_size = 0x80 << ((header[10] & 0x0f) - 1);
if ((header[10] & 0xf0) > 0)
- battery_size = 0x80 << ((header[10] & 0xf0) - 5);
+ battery_size = 0x80 << (((header[10] & 0xf0) >> 4) - 1);
// VRAM
vram_size = 0;
if ((header[11] & 0x0f) > 0)
vram_size = 0x80 << ((header[11] & 0x0f) - 1);
+ if ((header[11] & 0xf0) > 0)
+ vram_size |= 0x80 << (((header[11] & 0xf0) >> 4) - 1);
// header[11] & 0xf0 is the size of battery backed VRAM, found so far in Racermate II only and not supported yet
}
else
@@ -473,7 +557,7 @@ void nes_cart_slot_device::call_load_ines()
break;
case STD_CNROM:
- if (mapper == 185)
+ if (mapper == 185 && !submapper)
{
switch (crc_hack)
{
@@ -483,7 +567,7 @@ void nes_cart_slot_device::call_load_ines()
case 0x4: // pin26: CE, pin27: /CE (Mighty Bomb Jack, Spy Vs. Spy)
m_cart->set_ce(0x03, 0x01);
break;
- case 0x8: // pin26: /CE, pin27: CE (Sansu 1, 2, 3 Nen)
+ case 0x8: // pin26: /CE, pin27: CE (Sansu 1, 2, 3 Nen, Othello)
m_cart->set_ce(0x03, 0x02);
break;
case 0xc: // pin26: /CE, pin27: /CE (Seicross v2.0)
@@ -496,9 +580,9 @@ void nes_cart_slot_device::call_load_ines()
case KONAMI_VRC2:
if (mapper == 22)
m_cart->set_vrc_lines(0, 1, 1);
- if (mapper == 23 && !crc_hack)
+ if (mapper == 23 && !crc_hack && !submapper)
m_cart->set_vrc_lines(1, 0, 0);
- if (mapper == 23 && crc_hack)
+ if (mapper == 23 && crc_hack && !submapper)
{
// here there are also Akumajou Special, Crisis Force, Parodius da!, Tiny Toons which are VRC-4
m_cart->set_vrc_lines(3, 2, 0);
@@ -507,9 +591,9 @@ void nes_cart_slot_device::call_load_ines()
break;
case KONAMI_VRC4:
- if (mapper == 21) // Wai Wai World 2 & Ganbare Goemon Gaiden 2 (the latter with crc_hack)
+ if (mapper == 21 && !submapper) // Wai Wai World 2 & Ganbare Goemon Gaiden 2 (the latter with crc_hack)
m_cart->set_vrc_lines(crc_hack ? 7 : 2, crc_hack ? 6 : 1, 0);
- if (mapper == 25) // here there is also Ganbare Goemon Gaiden which is VRC-2
+ if (mapper == 25 && !submapper) // here there is also Ganbare Goemon Gaiden which is VRC-2
m_cart->set_vrc_lines(crc_hack ? 2 : 0, crc_hack ? 3 : 1, 0);
break;
@@ -521,9 +605,9 @@ void nes_cart_slot_device::call_load_ines()
break;
case IREM_G101:
- if (crc_hack)
+ if (crc_hack && !submapper)
m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring
- else
+ else if (!submapper)
m_cart->set_pcb_ctrl_mirror(TRUE);
break;
@@ -547,12 +631,12 @@ void nes_cart_slot_device::call_load_ines()
break;
case CAMERICA_BF9093:
- if (crc_hack)
+ if (crc_hack && !submapper)
m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 71 is used for 2 diff boards
break;
case STD_BXROM:
- if (crc_hack)
+ if (crc_hack && !submapper)
m_pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards
break;
@@ -562,7 +646,7 @@ void nes_cart_slot_device::call_load_ines()
break;
case IREM_HOLYDIVR:
- if (crc_hack)
+ if (crc_hack && !submapper)
m_pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards
break;
@@ -576,7 +660,6 @@ void nes_cart_slot_device::call_load_ines()
m_pcb_id = BMC_MARIOPARTY_7IN1; // Mapper 52 is used for 2 diff boards
break;
-
case BTL_MARIOBABY:
if (crc_hack)
m_pcb_id = BTL_AISENSHINICOL; // Mapper 42 is used for 2 diff boards
@@ -599,7 +682,7 @@ void nes_cart_slot_device::call_load_ines()
}
// Finally turn off bus conflict emulation, because the pirate variants of the boards are bus conflict free and games would glitch
- m_cart->set_bus_conflict(FALSE);
+ m_cart->set_bus_conflict(bus_conflict);
// SETUP step 4: logging what we have found
if (!ines20)
@@ -625,10 +708,10 @@ void nes_cart_slot_device::call_load_ines()
logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
- logerror("-- PRG NVWRAM: %d\n", header[10] & 0x0f);
- logerror("-- PRG WRAM: %d\n", (header[10] & 0xf0) >> 4);
- logerror("-- CHR NVWRAM: %d\n", header[11] & 0x0f);
- logerror("-- CHR WRAM: %d\n", (header[11] & 0xf0) >> 4);
+ logerror("-- PRG NVWRAM: %d\n", (header[10] & 0xf0) >> 4);
+ logerror("-- PRG WRAM: %d\n", header[10] & 0x0f);
+ logerror("-- CHR NVWRAM: %d\n", (header[11] & 0xf0) >> 4);
+ logerror("-- CHR WRAM: %d\n", header[11] & 0x0f);
logerror("-- TV System: %s\n", (header[12] & 2) ? "Both NTSC and PAL" : (header[12] & 1) ? "PAL" : "NTSC");
}
@@ -715,6 +798,7 @@ void nes_cart_slot_device::call_load_ines()
battery_load(temp_nvram, tot_size, 0x00);
if (battery_size)
{
+ //printf("here %d\n", battery_size);
m_cart->battery_alloc(machine(), battery_size);
memcpy(m_cart->get_battery_base(), temp_nvram, battery_size);
}
@@ -728,7 +812,7 @@ void nes_cart_slot_device::call_load_ines()
const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len)
{
- UINT8 mapper;
+ UINT8 mapper, submapper = 0;
bool ines20 = FALSE;
const char *mapinfo = NULL;
int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0;
@@ -769,11 +853,46 @@ const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len)
if (ines20)
{
mapper |= (ROM[8] & 0x0f) << 8;
- // ROM[8] & 0xf0 is used for submappers, but I haven't found any specific image to implement this
+ // read submappers (based on 20140116 specs)
+ submapper = (ROM[8] & 0xf0 >> 8);
}
ines_mapr_setup(mapper, &pcb_id);
+ // handle submappers
+ if (submapper)
+ {
+ // 001: MMC1
+ if (mapper == 1 && submapper == 3)
+ pcb_id = STD_SXROM_A;
+ else if (mapper == 1 && submapper == 5)
+ logerror("Unimplemented iNES2.0 submapper: SEROM/SHROM/SH1ROM.\n");
+ // 021, 023, 025: VRC4 / VRC2
+ else if (mapper == 21 || mapper == 23 || mapper == 25)
+ {
+ // 021, 023, 025: VRC4
+ int line_1 = submapper & 0x07;
+ int line_2 = (submapper & 0x08) ? line_1 + 1 : line_1 - 1;
+ if (line_2 >= 0 && line_2 <= 7)
+ pcb_id = KONAMI_VRC4;
+ else if (submapper == 15)
+ pcb_id = KONAMI_VRC2;
+ }
+ // iNES Mapper 034
+ else if (mapper == 34 && submapper == 1)
+ {
+ pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards
+ }
+ // iNES Mapper 078
+ else if (mapper == 78)
+ {
+ if (submapper == 1)
+ pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards
+ else if (submapper == 3)
+ pcb_id = IREM_HOLYDIVR;
+ }
+ }
+
// solve mapper conflicts
switch (pcb_id)
{
@@ -783,12 +902,12 @@ const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len)
break;
case KONAMI_VRC2:
- if (mapper == 23 && crc_hack)
+ if (mapper == 23 && crc_hack && !submapper)
pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset
break;
case STD_BXROM:
- if (crc_hack)
+ if (crc_hack && !submapper)
pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards
break;
@@ -798,7 +917,7 @@ const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len)
break;
case IREM_HOLYDIVR:
- if (crc_hack)
+ if (crc_hack && !submapper)
pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards
break;
diff --git a/src/mess/machine/nes_mmc1.c b/src/mess/machine/nes_mmc1.c
index 145a7d277bf..5f528424c5d 100644
--- a/src/mess/machine/nes_mmc1.c
+++ b/src/mess/machine/nes_mmc1.c
@@ -268,7 +268,7 @@ WRITE8_MEMBER( nes_sxrom_device::write_h )
WRITE8_MEMBER(nes_sxrom_device::write_m)
{
- UINT8 bank = (m_reg[1] & 3) >> 2;
+ UINT8 bank = (m_reg[1] >> 2) & 3;
LOG_MMC(("sxrom write_m, offset: %04x, data: %02x\n", offset, data));
if (!BIT(m_reg[3], 4)) // WRAM enabled
@@ -282,7 +282,7 @@ WRITE8_MEMBER(nes_sxrom_device::write_m)
READ8_MEMBER(nes_sxrom_device::read_m)
{
- UINT8 bank = (m_reg[1] & 3) >> 2;
+ UINT8 bank = (m_reg[1] >> 2) & 3;
LOG_MMC(("sxrom read_m, offset: %04x\n", offset));
if (!BIT(m_reg[3], 4)) // WRAM enabled
@@ -330,7 +330,7 @@ READ8_MEMBER(nes_sorom_device::read_m)
// MMC1A boards have no wram enable/disable bit
WRITE8_MEMBER(nes_sxrom_a_device::write_m)
{
- UINT8 bank = (m_reg[1] & 3) >> 2;
+ UINT8 bank = (m_reg[1] >> 2) & 3;
LOG_MMC(("sxrom_a write_m, offset: %04x, data: %02x\n", offset, data));
if (m_battery)
@@ -341,7 +341,7 @@ WRITE8_MEMBER(nes_sxrom_a_device::write_m)
READ8_MEMBER(nes_sxrom_a_device::read_m)
{
- UINT8 bank = (m_reg[1] & 3) >> 2;
+ UINT8 bank = (m_reg[1] >> 2) & 3;
LOG_MMC(("sxrom_a read_m, offset: %04x\n", offset));
if (m_battery)
diff --git a/src/mess/machine/nes_nxrom.c b/src/mess/machine/nes_nxrom.c
index ec5c93856bf..7c93db7f789 100644
--- a/src/mess/machine/nes_nxrom.c
+++ b/src/mess/machine/nes_nxrom.c
@@ -403,6 +403,7 @@ WRITE8_MEMBER(nes_cnrom_device::write_h)
if (m_ce_mask)
{
+ //printf("mask %x state %x\n", m_ce_mask, m_ce_state);
chr8(data & ~m_ce_mask, CHRROM);
if ((data & m_ce_mask) == m_ce_state)
@@ -423,8 +424,8 @@ READ8_MEMBER(nes_cnrom_device::chr_r)
// give actual VROM content or open bus values.
// For most boards, chr_open_bus remains always zero.
if (m_chr_open_bus)
- return 0xff;
-
+ return m_open_bus;
+
return m_chr_access[bank][offset & 0x3ff];
}
diff --git a/src/mess/machine/nes_pcb.inc b/src/mess/machine/nes_pcb.inc
index e3c0dd3c671..258dad7d4c9 100644
--- a/src/mess/machine/nes_pcb.inc
+++ b/src/mess/machine/nes_pcb.inc
@@ -561,8 +561,8 @@ void nes_cart_slot_device::call_load_pcb()
logerror("\n-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
- logerror("-- PRG NVWRAM: %d\n", m_cart->get_battery_size());
- logerror("-- PRG WRAM: %d\n", m_cart->get_prgram_size());
+ logerror("-- PRG NVWRAM: %d\n", battery_size + mapper_sram_size);
+ logerror("-- PRG WRAM: %d\n", prgram_size);
// SETUP steps 5/6: allocate pointers for PRG/VROM and load the data!
m_cart->prg_alloc(machine(), prg_size);