diff --git a/hash/nes.xml b/hash/nes.xml index 8e670c97665..b1e3e068473 100644 --- a/hash/nes.xml +++ b/hash/nes.xml @@ -50999,21 +50999,24 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx - + Chuugoku Taitei (Tw) 19?? Sachen - - + + + + + @@ -63085,25 +63088,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Baseball (Asia, FDS conversion?) - 19?? - <unknown> - - - - - - - - - - - - - - - Mario Baby ~ Bio Miracle Bokutte Upa (Asia, FDS conversion) 19?? @@ -63171,23 +63155,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - - Clu Clu Land D (Asia, FDS conversion) - 19?? - <pirate> - - - - - - - - - - - - Doki Doki Panic (Asia, FDS conversion) 19?? @@ -63310,38 +63277,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Ice Climber (Asia, FDS conversion) - 19?? - <pirate> - - - - - - - - - - - - - - Ice Hockey (Asia, FDS conversion) - 19?? - <pirate> - - - - - - - - - - - - Meikyuu Jiin Dababa (Asia, FDS conversion) 19?? @@ -63379,22 +63314,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Othello (Asia, FDS conversion) - 19?? - <pirate> - - - - - - - - - - - - ProWres - Famicom Wrestling Association (Asia, FDS conversion) 19?? @@ -63412,6 +63331,269 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t + + Super Mario Bros. 2 (LF36) + 19?? + <pirate> + + + + + + + + + + + + + + + Super Mario Bros. 2 (Kaiser) + 19?? + <pirate> + + + + + + + + + + + + + + + Super Mario Bros. 2 (Super Mario Bros. Pirate) + 19?? + <pirate> + + + + + + + + + + + + + + + Super Mario Bros Malee 2 + 19?? + <pirate> + + + + + + + + + + + + + + + + + + + Super Mario Bros. 2 (FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + + + + Super Mario Bros. 2 (FDS conversion, Alt PCB) + 19?? + <pirate> + + + + + + + + + + + + + + + Tobidase Daisakusen (Asia, FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + + + + Volleyball (Asia, FDS conversion, Alt) + 19?? + <pirate> + + + + + + + + + + + + + + Zanac (Asia, FDS conversion) + 19?? + Whirlwind Manu + + + + + + + + + + + + + + + Zanac (Asia, FDS conversion, Alt) + 19?? + Kaiser + + + + + + + + + + + + + + + + + + + + + Baseball (Asia, FDS conversion?) + 19?? + <unknown> + + + + + + + + + + + + + + + + + + Clu Clu Land D (Asia, FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + + + Ice Climber (Asia, FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + + + Ice Hockey (Asia, FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + + + Othello (Asia, FDS conversion) + 19?? + <pirate> + + + + + + + + + + + + Smash Ping Pong (Asia, FDS conversion) 19?? @@ -63495,19 +63677,19 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Tobidase Daisakusen (Asia, FDS conversion) + + Super Mario Bros. 2 (FDS pirate, Alt 3) 19?? <pirate> - - + + - - + + - - + + @@ -63563,57 +63745,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Volleyball (Asia, FDS conversion, Alt) - 19?? - <pirate> - - - - - - - - - - - - - - Zanac (Asia, FDS conversion) - 19?? - Whirlwind Manu - - - - - - - - - - - - - - - Zanac (Asia, FDS conversion, Alt) - 19?? - Kaiser - - - - - - - - - - - - - - @@ -69285,129 +69416,6 @@ resulting in tons of glitches? --> - - Super Mario Bros. 2 (FDS pirate, Alt) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros. 2 (FDS pirate, Alt 2) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros. 2 (FDS pirate, Alt 3) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros. 2 (LF36) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros. 2 (Kaiser) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros. 2 (Super Mario Bros. Pirate) - 19?? - <pirate> - - - - - - - - - - - - - - - Super Mario Bros Malee 2 (Super Mario Bros. Pirate) - 19?? - <pirate> - - - - - - - - - - - - - - - - - Super Mario Bros. 3 (Pirate) diff --git a/src/mess/includes/nes.h b/src/mess/includes/nes.h index 43846fd3bef..d673c09b77e 100644 --- a/src/mess/includes/nes.h +++ b/src/mess/includes/nes.h @@ -279,7 +279,7 @@ static SLOT_INTERFACE_START(nes_cart) SLOT_INTERFACE_INTERNAL("smb2j", NES_SMB2J) SLOT_INTERFACE_INTERNAL("smb2ja", NES_SMB2JA) SLOT_INTERFACE_INTERNAL("smb2jb", NES_SMB2JB) - SLOT_INTERFACE_INTERNAL("smb2jc", NES_SMB2JC) // really? + SLOT_INTERFACE_INTERNAL("09034a", NES_09034A) SLOT_INTERFACE_INTERNAL("tobidase", NES_TOBIDASE) // mapper 120 SLOT_INTERFACE_INTERNAL("mmalee2", NES_MMALEE) // mapper 55? SLOT_INTERFACE_INTERNAL("unl_2708", NES_2708) // mapper 103 @@ -396,6 +396,7 @@ static SLOT_INTERFACE_START(nes_cart) SLOT_INTERFACE_INTERNAL("ffe3", NES_FFE3) SLOT_INTERFACE_INTERNAL("ffe4", NES_FFE4) SLOT_INTERFACE_INTERNAL("ffe8", NES_FFE8) +SLOT_INTERFACE_INTERNAL("test", NES_NROM) // SLOT_INTERFACE_INTERNAL("unknown", NES_NROM) // a few pirate dumps uses the wrong mapper... SLOT_INTERFACE_END diff --git a/src/mess/machine/nes.c b/src/mess/machine/nes.c index 03f33022bf4..1c43728d1b6 100644 --- a/src/mess/machine/nes.c +++ b/src/mess/machine/nes.c @@ -166,7 +166,7 @@ void nes_state::machine_start() space.install_read_handler(0x8000, 0xffff, read8_delegate(FUNC(nes_cart_slot_device::read_h), (nes_cart_slot_device *)m_cartslot)); } - if (m_cartslot->get_pcb_id() == BTL_SMB2JB || m_cartslot->get_pcb_id() == UNL_AC08 || m_cartslot->get_pcb_id() == BTL_SMB2JC) + if (m_cartslot->get_pcb_id() == BTL_SMB2JB || m_cartslot->get_pcb_id() == UNL_AC08 || m_cartslot->get_pcb_id() == UNL_SMB2J || m_cartslot->get_pcb_id() == BTL_09034A) { logerror("write_ex installed!\n"); space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)m_cartslot)); diff --git a/src/mess/machine/nes_bandai.c b/src/mess/machine/nes_bandai.c index 26bda15aabf..bc99f00421e 100644 --- a/src/mess/machine/nes_bandai.c +++ b/src/mess/machine/nes_bandai.c @@ -127,13 +127,18 @@ void nes_karaokestudio_device::pcb_reset() void nes_oekakids_device::device_start() { common_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_reg)); } void nes_oekakids_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg32(0); - chr8(0, m_chr_source); + chr4_0(0, CHRRAM); + chr4_4(3, CHRRAM); + set_nt_mirroring(PPU_MIRROR_LOW); + m_latch = 0; + m_reg = 0; } void nes_lz93d50_device::device_start() @@ -230,13 +235,62 @@ WRITE8_MEMBER(nes_karaokestudio_device::write_h) -------------------------------------------------*/ + +WRITE8_MEMBER(nes_oekakids_device::nt_w) +{ + int page = ((offset & 0xc00) >> 10); + +#if 0 + if (offset < 0x1000 && (m_latch != (offset & 0x300) >> 8)) + { + m_latch = (offset & 0x300) >> 8; + update_chr(); + } +#endif + + m_nt_access[page][offset & 0x3ff] = data; +} + +READ8_MEMBER(nes_oekakids_device::nt_r) +{ + int page = ((offset & 0xc00) >> 10); + +#if 0 + if (offset < 0x1000 && (m_latch != (offset & 0x300) >> 8)) + { + m_latch = (offset & 0x300) >> 8; + update_chr(); + } +#endif + + return m_nt_access[page][offset & 0x3ff]; +} + +void nes_oekakids_device::update_chr() +{ + chr4_0(m_reg | m_latch, CHRRAM); + chr4_4(m_reg | 0x03, CHRRAM); +} + +// this only monitors accesses to $2007 while we would need to monitor accesses to $2006... +void nes_oekakids_device::ppu_latch(offs_t offset) +{ +#if 0 + if ((offset & 0x3000) == 0x2000) + { + m_latch = (offset & 0x300) >> 8; + update_chr(); + } +#endif +} + WRITE8_MEMBER(nes_oekakids_device::write_h) { LOG_MMC(("oeka kids write_h, offset: %04x, data: %02x\n", offset, data)); prg32(data); - chr4_0(0x00 | (data & 0x04), CHRRAM); - chr4_4(0x03 | (data & 0x04), CHRRAM); + m_reg = (data & 0x04); + update_chr(); } /*------------------------------------------------- diff --git a/src/mess/machine/nes_bandai.h b/src/mess/machine/nes_bandai.h index 09b426275b6..c126238cbfa 100644 --- a/src/mess/machine/nes_bandai.h +++ b/src/mess/machine/nes_bandai.h @@ -34,10 +34,17 @@ public: // device-level overrides virtual void device_start(); virtual DECLARE_WRITE8_MEMBER(write_h); + virtual DECLARE_READ8_MEMBER(nt_r); + virtual DECLARE_WRITE8_MEMBER(nt_w); virtual void pcb_reset(); + virtual void ppu_latch(offs_t offset); + // TODO: add oeka kids controller emulation +protected: + void update_chr(); + UINT8 m_reg, m_latch; }; diff --git a/src/mess/machine/nes_bootleg.c b/src/mess/machine/nes_bootleg.c index 94ef6074c32..bbfa25bef99 100644 --- a/src/mess/machine/nes_bootleg.c +++ b/src/mess/machine/nes_bootleg.c @@ -49,7 +49,7 @@ const device_type NES_WHIRLWIND_2706 = &device_creator; const device_type NES_SMB2J = &device_creator; const device_type NES_SMB2JA = &device_creator; const device_type NES_SMB2JB = &device_creator; -const device_type NES_SMB2JC = &device_creator; +const device_type NES_09034A = &device_creator; const device_type NES_TOBIDASE = &device_creator; const device_type NES_LH32 = &device_creator; const device_type NES_LH10 = &device_creator; @@ -110,8 +110,8 @@ nes_smb2jb_device::nes_smb2jb_device(const machine_config &mconfig, const char * { } -nes_smb2jc_device::nes_smb2jc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : nes_nrom_device(mconfig, NES_SMB2JC, "NES Cart Super Mario Bros. 2 Jpn (Alt 3) PCB", tag, owner, clock, "nes_smb2jc", __FILE__) +nes_09034a_device::nes_09034a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_09034A, "NES Cart 09-034A PCB", tag, owner, clock, "nes_09034a", __FILE__) { } @@ -287,13 +287,21 @@ void nes_whirl2706_device::pcb_reset() void nes_smb2j_device::device_start() { common_start(); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_count)); } void nes_smb2j_device::pcb_reset() { m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); chr8(0, m_chr_source); + prg8_89(1); + prg8_ab(0); + prg8_cd(0); + prg8_ef(9); + + m_irq_enable = 0; + m_irq_count = 0; } void nes_smb2ja_device::device_start() @@ -336,29 +344,20 @@ void nes_smb2jb_device::pcb_reset() m_irq_count = 0; } -void nes_smb2jc_device::device_start() +void nes_09034a_device::device_start() { common_start(); - save_item(NAME(m_irq_enable)); - save_item(NAME(m_irq_count)); - save_item(NAME(m_prg_base)); + save_item(NAME(m_reg)); } -void nes_smb2jc_device::pcb_reset() +void nes_09034a_device::pcb_reset() { m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + prg32(0); chr8(0, m_chr_source); - prg8_89(1); - prg8_ab(0); - prg8_cd(0); - prg8_ef(9); - - m_irq_enable = 0; - m_irq_count = 0; - m_prg_base = 1; + m_reg = 0; } - void nes_tobidase_device::device_start() { common_start(); @@ -889,103 +888,18 @@ READ8_MEMBER(nes_whirl2706_device::read_m) Games: Super Mario Bros. 2 Pirate (LF36) iNES: mapper 43 - - This is actually strange. There is one variant of - mappers 43 games which maps the PRG linearly from - 0x5000 to 0xffff and then can switch the upper 32K - part (0x8000-0xffff). These are games with 80K of - PRG (SMB2 conversions only? also the Zanac FDS even - if has smaller PRG?). - Then there is a second variant (Volleyball FDS) with - only 32K of PRG which do not switches PRG (no 0x4200 - writes) and probably mirrors lower 12K in 0x5000-0x7fff. - The Zanac FDS conversion might not belong to this - board... - - In any case, for the moment we split the two variants - in smb2j and smb2jc! - - In MESS: Unsupported? The only image I found is not working - (not even in NEStopia). Partially supported the - smb2jc variant (to be investigated...) + + In MESS: Supported. -------------------------------------------------*/ -/* This PCB can map PRG RAM to 0x8000-0xdfff like MMC5 */ -void nes_smb2j_device::prgram_bank8_x(int start, int bank) -{ - assert(start < 4); - assert(bank >= 0); - - bank &= (m_prgram_size / 0x2000) - 1; - - // 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]); -} - -WRITE8_MEMBER(nes_smb2j_device::write_h) -{ - int bank = (((offset >> 8) & 0x03) * 0x20) + (offset & 0x1f); - - LOG_MMC(("smb2j_w, offset: %04x, data: %02x\n", offset, data)); - - set_nt_mirroring((offset & 0x2000) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - - if (offset & 0x0800) - { - if (offset & 0x1000) - { - if (bank * 2 >= m_prg_chunks) - { - prgram_bank8_x(2, 0); - prgram_bank8_x(3, 0); - } - else - { - LOG_MMC(("smb2j_w, selecting upper 16KB bank of #%02x\n", bank)); - prg16_cdef(2 * bank + 1); - } - } - else - { - if (bank * 2 >= m_prg_chunks) - { - prgram_bank8_x(0, 0); - prgram_bank8_x(1, 0); - } - else - { - LOG_MMC(("smb2j_w, selecting lower 16KB bank of #%02x\n", bank)); - prg16_89ab(2 * bank); - } - } - } - else - { - if (bank * 2 >= m_prg_chunks) - { - prgram_bank8_x(0, 0); - prgram_bank8_x(1, 0); - prgram_bank8_x(2, 0); - prgram_bank8_x(3, 0); - } - else - { - LOG_MMC(("smb2j_w, selecting 32KB bank #%02x\n", bank)); - prg32(bank); - } - } -} - - -void nes_smb2jc_device::hblank_irq(int scanline, int vblank, int blanked) +void nes_smb2j_device::hblank_irq(int scanline, int vblank, int blanked) { if (m_irq_enable) { - if ((0xfff - m_irq_count) <= 114) + if ((0xfff - m_irq_count) < 114) { - m_irq_count = (m_irq_count + 1) & 0xfff; + m_irq_count = (m_irq_count + 114) & 0xfff; m_irq_enable = 0; machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); } @@ -993,47 +907,56 @@ void nes_smb2jc_device::hblank_irq(int scanline, int vblank, int blanked) m_irq_count += 114; } } -WRITE8_MEMBER(nes_smb2jc_device::write_l) -{ - LOG_MMC(("smb2jc write_l, offset: %04x, data: %02x\n", offset, data)); - offset += 0x100; - if (offset == 0x122) +WRITE8_MEMBER(nes_smb2j_device::write_l) +{ + LOG_MMC(("smb2j write_l, offset: %04x, data: %02x\n", offset, data)); + offset += 0x100; + + if (offset == 0x122) // $4122 + m_irq_enable = data & 3; // maybe also m_irq_count = 0?!? +} + +WRITE8_MEMBER(nes_smb2j_device::write_h) +{ + LOG_MMC(("smb2j write_h, offset: %04x, data: %02x\n", offset, data)); + + if (offset == 0x122) // $8122 too? m_irq_enable = data & 3; } -WRITE8_MEMBER(nes_smb2jc_device::write_ex) +WRITE8_MEMBER(nes_smb2j_device::write_ex) { - LOG_MMC(("smb2jc write_ex, offset: %04x, data: %02x\n", offset, data)); - + LOG_MMC(("smb2j write_ex, offset: %04x, data: %02x\n", offset, data)); + if (offset == 2) { int temp = 0; - + // According to hardware tests if (data & 1) temp = 3; else temp = 4 + ((data & 7) >> 1); - + prg8_cd(temp); } } -READ8_MEMBER(nes_smb2jc_device::read_l) +READ8_MEMBER(nes_smb2j_device::read_l) { - LOG_MMC(("smb2jc read_l, offset: %04x\n", offset)); + LOG_MMC(("smb2j read_l, offset: %04x\n", offset)); offset += 0x100; - + if (offset >= 0x1000) return m_prg[0x10000 + (offset & 0x0fff)]; - - return ((offset + 0x4000) & 0xff00) >> 8; + + return ((offset + 0x4000) & 0xff00) >> 8; // open bus } -READ8_MEMBER(nes_smb2jc_device::read_m) +READ8_MEMBER(nes_smb2j_device::read_m) { - LOG_MMC(("smb2jc read_m, offset: %04x\n", offset)); + LOG_MMC(("smb2j read_m, offset: %04x\n", offset)); return m_prg[0x4000 + offset]; } @@ -1107,17 +1030,14 @@ void nes_smb2jb_device::hblank_irq(int scanline, int vblank, int blanked) { if (m_irq_enable) { - if (m_irq_count < 0x1000) + if ((0xfff - m_irq_count) < 114) { - if ((0x1000 - m_irq_count) <= 114) - machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); - else - m_irq_count += 114; + m_irq_count = (m_irq_count + 114) & 0xfff; + m_irq_enable = 0; + machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); } else m_irq_count += 114; - - m_irq_count &= 0xffff; // according to docs is 16bit counter -> it wraps only after 0xffff? } } @@ -1160,6 +1080,40 @@ WRITE8_MEMBER(nes_smb2jb_device::write_ex) } } +/*------------------------------------------------- + + (UNL-)09-034A + + Games: Zanac FDS conversion with two PRG chips and + no CHRROM (apparently also a Volleyball FDS conversion + but the ones we have do not seem to be on this hw + Originally dumps were marked as UNL-SMB2J pcb + + + iNES: + + In MESS: Supported (for Zanac) + + -------------------------------------------------*/ + +WRITE8_MEMBER(nes_09034a_device::write_ex) +{ + LOG_MMC(("09-034a write_ex, offset: %04x, data: %02x\n", offset, data)); + + if (offset == 7) // $4027 + { + m_reg = data & 1; + if (m_chr_source == CHRRAM) // zanac has no CHRROM and is wired differently so to access the second PRG chip + m_reg += 4; + } +} + +READ8_MEMBER(nes_09034a_device::read_m) +{ + LOG_MMC(("09-034a read_m, offset: %04x\n", offset)); + return m_prg[(m_reg * 0x2000) + offset]; +} + /*------------------------------------------------- Bootleg Board used for FDS conversion diff --git a/src/mess/machine/nes_bootleg.h b/src/mess/machine/nes_bootleg.h index 09f55f74381..6dfcb7a4a38 100644 --- a/src/mess/machine/nes_bootleg.h +++ b/src/mess/machine/nes_bootleg.h @@ -160,15 +160,21 @@ class nes_smb2j_device : public nes_nrom_device public: // construction/destruction nes_smb2j_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - + // device-level overrides virtual void device_start(); + virtual DECLARE_READ8_MEMBER(read_l); + virtual DECLARE_READ8_MEMBER(read_m); + virtual DECLARE_WRITE8_MEMBER(write_ex); + virtual DECLARE_WRITE8_MEMBER(write_l); virtual DECLARE_WRITE8_MEMBER(write_h); - + + virtual void hblank_irq(int scanline, int vblank, int blanked); virtual void pcb_reset(); - + private: - void prgram_bank8_x(int start, int bank); + UINT16 m_irq_count; + int m_irq_enable; }; @@ -217,28 +223,23 @@ private: }; -// ======================> nes_smb2jc_device +// ======================> nes_09034a_device -class nes_smb2jc_device : public nes_nrom_device +class nes_09034a_device : public nes_nrom_device { public: // construction/destruction - nes_smb2jc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - + nes_09034a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + // device-level overrides virtual void device_start(); - virtual DECLARE_READ8_MEMBER(read_l); - virtual DECLARE_READ8_MEMBER(read_m); virtual DECLARE_WRITE8_MEMBER(write_ex); - virtual DECLARE_WRITE8_MEMBER(write_l); - - virtual void hblank_irq(int scanline, int vblank, int blanked); + virtual DECLARE_READ8_MEMBER(read_m); + virtual void pcb_reset(); - + private: - UINT16 m_irq_count; - int m_irq_enable; - UINT8 m_prg_base; + UINT8 m_reg; }; @@ -421,7 +422,7 @@ extern const device_type NES_WHIRLWIND_2706; extern const device_type NES_SMB2J; extern const device_type NES_SMB2JA; extern const device_type NES_SMB2JB; -extern const device_type NES_SMB2JC; +extern const device_type NES_09034A; extern const device_type NES_TOBIDASE; extern const device_type NES_LH32; extern const device_type NES_LH10; diff --git a/src/mess/machine/nes_jy.c b/src/mess/machine/nes_jy.c index 4862cbcb8e2..5de6d0fec3a 100644 --- a/src/mess/machine/nes_jy.c +++ b/src/mess/machine/nes_jy.c @@ -163,13 +163,17 @@ READ8_MEMBER(nes_jy_typea_device::chr_r) switch (offset & 0xff8) { case 0xfd0: + m_chr_latch[BIT(offset, 12)] = (bank & 0x4); + if ((m_reg[0] & 0x18) == 0x08) // 4KB mode is the only one using these latches! + update_chr_latches(); + break; case 0xfe8: -// m_chr_latch[BIT(offset, 12)] = ((bank & 0x4) | 0x2) & (offset >> 4); + m_chr_latch[BIT(offset, 12)] = (bank & 0x4) | 0x2; + if ((m_reg[0] & 0x18) == 0x08) // 4KB mode is the only one using these latches! + update_chr_latches(); break; } - if ((m_reg[0] & 0x18) == 0x08) // 4KB mode is the only one using these latches! - update_chr_latches(); return val; } @@ -199,7 +203,7 @@ void nes_jy_typea_device::irq_clock(int mode, int blanked) if (m_irq_up) { - if ((m_irq_prescale & m_irq_prescale_mask) == m_irq_prescale) + if ((m_irq_prescale & m_irq_prescale_mask) == m_irq_prescale_mask) { clock = TRUE; m_irq_prescale = (m_irq_prescale_mask == 7) ? (m_irq_prescale & 0xf8) : 0; @@ -363,9 +367,14 @@ void nes_jy_typea_device::update_extra_chr() { // Block mode enabled: in this case lower bits select a 256KB page inside CHRROM // and the low bytes of m_mmc_vrom_bank select the banks inside such a page - int mode = (m_reg[0] & 0x18) >> 3; - m_extra_chr_mask = 0x00ff >> (mode ^ 0x3); - m_extra_chr_bank = ((m_reg[3] & 1) | ((m_reg[3] & 0x18) >> 2)) << (mode + 5); + m_extra_chr_bank = ((m_reg[3] & 1) | ((m_reg[3] & 0x18) >> 2)); + switch (m_reg[0] & 0x18) + { + case 0x00: m_extra_chr_bank <<= 5; m_extra_chr_mask = 0x1f; break; + case 0x08: m_extra_chr_bank <<= 6; m_extra_chr_mask = 0x3f; break; + case 0x10: m_extra_chr_bank <<= 7; m_extra_chr_mask = 0x7f; break; + case 0x18: m_extra_chr_bank <<= 8; m_extra_chr_mask = 0xff; break; + } } } @@ -506,7 +515,7 @@ WRITE8_MEMBER(nes_jy_typea_device::write_h) break; case 2: m_irq_enable = 0; - break; + break; case 3: m_irq_enable = 1; break; diff --git a/src/mess/machine/nes_legacy.c b/src/mess/machine/nes_legacy.c index d198b92ed8a..a432e813a2f 100644 --- a/src/mess/machine/nes_legacy.c +++ b/src/mess/machine/nes_legacy.c @@ -78,6 +78,12 @@ void nes_ffe3_device::pcb_reset() void nes_ffe4_device::device_start() { common_start(); + + m_exram = auto_alloc_array_clear(machine(), UINT8, 0x8000); + save_pointer(NAME(m_exram), 0x8000); + save_item(NAME(m_exram_enabled)); + save_item(NAME(m_exram_bank)); + save_item(NAME(m_irq_enable)); save_item(NAME(m_irq_count)); save_item(NAME(m_latch)); @@ -90,6 +96,9 @@ void nes_ffe4_device::pcb_reset() prg16_cdef(7); chr8(0, m_chr_source); + m_exram_enabled = 0; + m_exram_bank = 0; + m_latch = 0; m_irq_enable = 0; m_irq_count = 0; @@ -103,6 +112,10 @@ void nes_ffe8_device::pcb_reset() prg16_cdef(0xff); chr8(0, m_chr_source); + // extra vram is not used by this board, so these will remain always zero + m_exram_enabled = 0; + m_exram_bank = 0; + m_latch = 0; m_irq_enable = 0; m_irq_count = 0; @@ -158,10 +171,10 @@ void nes_ffe4_device::hblank_irq(int scanline, int vblank, int blanked) if ((0xffff - m_irq_count) < 114) { machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); - m_irq_count = 0xffff; + m_irq_count = 0; m_irq_enable = 0; } - m_irq_count -= 114; + m_irq_count += 114; } } @@ -180,7 +193,7 @@ WRITE8_MEMBER(nes_ffe4_device::write_l) break; case 0x401: - m_irq_enable = data & 0x01; + m_irq_enable = 0; break; case 0x402: m_irq_count = (m_irq_count & 0xff00) | data; @@ -192,6 +205,26 @@ WRITE8_MEMBER(nes_ffe4_device::write_l) } } +WRITE8_MEMBER(nes_ffe4_device::chr_w) +{ + int bank = offset >> 10; + if (m_exram_enabled) + m_exram[(m_exram_bank * 0x2000) + (bank * 0x400) + (offset & 0x3ff)] = data; + + if (m_chr_src[bank] == CHRRAM) + m_chr_access[bank][offset & 0x3ff] = data; +} + +READ8_MEMBER(nes_ffe4_device::chr_r) +{ + int bank = offset >> 10; + if (m_exram_enabled) + return m_exram[(m_exram_bank * 0x2000) + (bank * 0x400) + (offset & 0x3ff)]; + + return m_chr_access[bank][offset & 0x3ff]; +} + + WRITE8_MEMBER(nes_ffe4_device::write_h) { LOG_MMC(("mapper6 write_h, offset: %04x, data: %02x\n", offset, data)); @@ -199,12 +232,20 @@ WRITE8_MEMBER(nes_ffe4_device::write_h) if (!m_latch) // when in "FFE mode" we are forced to use CHRRAM/EXRAM bank? { prg16_89ab(data >> 2); - // chr8(data & 0x03, ???); - // due to lack of info on the exact behavior, we simply act as if m_latch=1 - if (m_chr_source == CHRROM) - chr8(data & 0x03, CHRROM); + + // This part is not fully documented, so we proceed a bit blindly... + if (data & 0x03 == 0) + { + m_exram_enabled = 0; + chr8(0, CHRRAM); + } + else + { + m_exram_enabled = 1; + m_exram_bank = data & 0x03; + } } - else if (m_chr_source == CHRROM) // otherwise, we can use CHRROM (when present) + else // otherwise, we use CHRROM (shall we check if it's present?) chr8(data, CHRROM); } @@ -215,8 +256,7 @@ WRITE8_MEMBER(nes_ffe4_device::write_h) Known Boards: FFE8 Copier Board Games: Hacked versions of games - In MESS: Supported?. IRQ support is just a guess (used to - use MMC3 IRQ but it was wrong and it never enabled it) + In MESS: Partially Supported. -------------------------------------------------*/ @@ -234,7 +274,7 @@ WRITE8_MEMBER(nes_ffe8_device::write_l) break; case 0x401: - m_irq_enable = data & 0x01; + m_irq_enable = 0; break; case 0x402: m_irq_count = (m_irq_count & 0xff00) | data; diff --git a/src/mess/machine/nes_legacy.h b/src/mess/machine/nes_legacy.h index df905ce1a89..dfb8895a5f9 100644 --- a/src/mess/machine/nes_legacy.h +++ b/src/mess/machine/nes_legacy.h @@ -33,6 +33,8 @@ public: virtual void device_start(); virtual DECLARE_WRITE8_MEMBER(write_l); virtual DECLARE_WRITE8_MEMBER(write_h); + virtual DECLARE_READ8_MEMBER(chr_r); + virtual DECLARE_WRITE8_MEMBER(chr_w); virtual void hblank_irq(int scanline, int vblank, int blanked); virtual void pcb_reset(); @@ -42,6 +44,9 @@ protected: int m_irq_enable; UINT8 m_latch; + UINT8 *m_exram; + int m_exram_enabled; + int m_exram_bank; }; diff --git a/src/mess/machine/nes_pcb.c b/src/mess/machine/nes_pcb.c index bbe76a7eb90..1398da275b1 100644 --- a/src/mess/machine/nes_pcb.c +++ b/src/mess/machine/nes_pcb.c @@ -193,7 +193,7 @@ static const nes_pcb pcb_list[] = { "smb2j", UNL_SMB2J }, { "smb2ja", BTL_SMB2JA }, { "smb2jb", BTL_SMB2JB }, - { "smb2jc", BTL_SMB2JC }, // really? + { "09034a", BTL_09034A }, { "tobidase", BTL_TOBIDASE }, // mapper 120 { "dbz5", REXSOFT_DBZ5 }, { "sl1632", REXSOFT_SL1632 }, @@ -307,6 +307,7 @@ static const nes_pcb pcb_list[] = { "unl_dance", UNSUPPORTED_BOARD }, { "bmc_hik_kof", UNSUPPORTED_BOARD }, { "onebus", UNSUPPORTED_BOARD }, + { "test", TEST_BOARD }, { "unknown", UNKNOWN_BOARD } // a few pirate dumps uses the wrong mapper... }; diff --git a/src/mess/machine/nes_slot.h b/src/mess/machine/nes_slot.h index 3265fc38cc8..83e0353f7c1 100644 --- a/src/mess/machine/nes_slot.h +++ b/src/mess/machine/nes_slot.h @@ -101,7 +101,7 @@ enum UNL_43272, UNL_TF1201, UNL_CITYFIGHT, /* Bootleg boards */ BTL_SMB2JA, BTL_MARIOBABY, BTL_AISENSHINICOL, BTL_TOBIDASE, - BTL_SMB2JB, BTL_SMB2JC, BTL_SMB3, BTL_SBROS11, BTL_DRAGONNINJA, + BTL_SMB2JB, BTL_09034A, BTL_SMB3, BTL_SBROS11, BTL_DRAGONNINJA, BTL_PIKACHUY2K, BTL_SHUIGUAN, /* Misc: these are needed to convert mappers to boards, I will sort them later */ OPENCORP_DAOU306, HES_BOARD, SVISION16_BOARD, RUMBLESTATION_BOARD, JYCOMPANY_A, JYCOMPANY_B, JYCOMPANY_C, @@ -118,7 +118,7 @@ enum KAY_BOARD, HOSENKAN_BOARD, NITRA_TDA, GOUDER_37017, NANJING_BOARD, WHIRLWIND_2706, /* FFE boards, for mappers 6, 8, 17 */ - FFE3_BOARD, FFE4_BOARD, FFE8_BOARD, + FFE3_BOARD, FFE4_BOARD, FFE8_BOARD, TEST_BOARD, /* Unsupported (for place-holder boards, with no working emulation) & no-board (at init) */ UNSUPPORTED_BOARD, UNKNOWN_BOARD, NO_BOARD }; diff --git a/src/mess/machine/nes_somari.c b/src/mess/machine/nes_somari.c index 0b234f521dd..05f3d9278dd 100644 --- a/src/mess/machine/nes_somari.c +++ b/src/mess/machine/nes_somari.c @@ -25,6 +25,11 @@ #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0) +#define SOMARI_VRC2_MODE 0 +#define SOMARI_MMC3_MODE 1 +#define SOMARI_MMC1_MODE 2 +#define SOMARI_MMC1_MODE_AGAIN 3 + //------------------------------------------------- // constructor @@ -53,6 +58,7 @@ void nes_somari_device::device_start() save_item(NAME(m_prg_mask)); save_item(NAME(m_chr_base)); save_item(NAME(m_chr_mask)); + save_item(NAME(m_mmc3_mirror_reg)); save_item(NAME(m_irq_enable)); save_item(NAME(m_irq_count)); @@ -67,6 +73,7 @@ void nes_somari_device::device_start() // VRC2 save_item(NAME(m_vrc_prg_bank)); save_item(NAME(m_vrc_vrom_bank)); + save_item(NAME(m_vrc_mirror_reg)); } void nes_somari_device::pcb_reset() @@ -84,8 +91,8 @@ void nes_somari_device::pcb_reset() m_latch = 0; m_mmc_prg_bank[0] = 0x3c; m_mmc_prg_bank[1] = 0x3d; - m_mmc_prg_bank[2] = 0xfe; - m_mmc_prg_bank[3] = 0xff; + m_mmc_prg_bank[2] = 0x3e; + m_mmc_prg_bank[3] = 0x3f; m_mmc_vrom_bank[0] = 0x00; m_mmc_vrom_bank[1] = 0x01; m_mmc_vrom_bank[2] = 0x04; @@ -144,41 +151,6 @@ void nes_somari_device::pcb_reset() -------------------------------------------------*/ // MMC1 Mode emulation -void nes_somari_device::mmc1_set_prg() -{ - UINT8 prg_mode = m_mmc1_reg[0] & 0x0c; - UINT8 prg_offset = m_mmc1_reg[1] & 0x10; - - switch (prg_mode) - { - case 0x00: - case 0x04: - prg32((prg_offset + m_mmc1_reg[3]) >> 1); - break; - case 0x08: - prg16_89ab(prg_offset + 0); - prg16_cdef(prg_offset + m_mmc1_reg[3]); - break; - case 0x0c: - prg16_89ab(prg_offset + m_mmc1_reg[3]); - prg16_cdef(prg_offset + 0x0f); - break; - } -} - -void nes_somari_device::mmc1_set_chr() -{ - UINT8 chr_mode = BIT(m_mmc1_reg[0], 4); - - if (chr_mode) - { - chr4_0(m_mmc1_reg[1] & 0x1f, m_chr_source); - chr4_4(m_mmc1_reg[2] & 0x1f, m_chr_source); - } - else - chr8((m_mmc1_reg[1] & 0x1f) >> 1, m_chr_source); -} - WRITE8_MEMBER(nes_somari_device::mmc1_w) { assert(m_board_mode == 2); @@ -189,7 +161,7 @@ WRITE8_MEMBER(nes_somari_device::mmc1_w) m_mmc1_latch = 0; m_mmc1_reg[0] |= 0x0c; - mmc1_set_prg(); + update_prg(); return; } @@ -203,35 +175,11 @@ WRITE8_MEMBER(nes_somari_device::mmc1_w) if (m_count == 5) { - switch (offset & 0x6000) - { - case 0x0000: - m_mmc1_reg[0] = m_mmc1_latch; - switch (m_mmc1_reg[0] & 0x03) - { - case 0: set_nt_mirroring(PPU_MIRROR_LOW); break; - case 1: set_nt_mirroring(PPU_MIRROR_HIGH); break; - case 2: set_nt_mirroring(PPU_MIRROR_VERT); break; - case 3: set_nt_mirroring(PPU_MIRROR_HORZ); break; - } - mmc1_set_chr(); - mmc1_set_prg(); - break; - case 0x2000: - m_mmc1_reg[1] = m_mmc1_latch; - mmc1_set_chr(); - mmc1_set_prg(); - break; - case 0x4000: - m_mmc1_reg[2] = m_mmc1_latch; - mmc1_set_chr(); - break; - case 0x6000: - m_mmc1_reg[3] = m_mmc1_latch; - mmc1_set_prg(); - break; - } - + m_mmc1_reg[(offset & 0x6000) >> 13] = m_mmc1_latch; + update_mirror(); + update_prg(); + update_chr(); + m_count = 0; } } @@ -250,10 +198,10 @@ WRITE8_MEMBER(nes_somari_device::mmc3_w) m_latch = data; if (mmc_helper & 0x40) - set_prg(m_prg_base, m_prg_mask); + update_prg(); if (mmc_helper & 0x80) - set_chr(m_chr_source, m_chr_base, m_chr_mask); + update_chr(); break; case 0x0001: @@ -263,18 +211,19 @@ WRITE8_MEMBER(nes_somari_device::mmc3_w) case 0: case 1: case 2: case 3: case 4: case 5: m_mmc_vrom_bank[cmd] = data; - set_chr(m_chr_source, m_chr_base, m_chr_mask); + update_chr(); break; case 6: case 7: - m_mmc_prg_bank[cmd - 6] = data; - set_prg(m_prg_base, m_prg_mask); + m_mmc_prg_bank[cmd - 6] = data & 0x3f; + update_prg(); break; } break; case 0x2000: - set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + m_mmc3_mirror_reg = data & 1; + update_mirror(); break; case 0x2001: break; case 0x4000: m_irq_count_latch = data; break; @@ -294,47 +243,147 @@ WRITE8_MEMBER(nes_somari_device::vrc2_w) switch (offset & 0x7000) { case 0x0000: - m_vrc_prg_bank[0] = data; - prg8_89(m_vrc_prg_bank[0]); + m_vrc_prg_bank[0] = data & 0x1f; + update_prg(); break; case 0x1000: - switch (data & 0x03) - { - case 0x00: set_nt_mirroring(PPU_MIRROR_VERT); break; - case 0x01: set_nt_mirroring(PPU_MIRROR_HORZ); break; - case 0x02: set_nt_mirroring(PPU_MIRROR_LOW); break; - case 0x03: set_nt_mirroring(PPU_MIRROR_HIGH); break; - } + m_vrc_mirror_reg = data & 1; + update_mirror(); break; case 0x2000: - m_vrc_prg_bank[1] = data; - prg8_ab(m_vrc_prg_bank[1]); + m_vrc_prg_bank[1] = data & 0x1f; + update_prg(); break; case 0x3000: case 0x4000: case 0x5000: case 0x6000: + // this makes no sense for vrc2 and breaks somari, but it's ok for garousp!! bank = ((offset & 0x7000) - 0x3000) / 0x0800 + BIT(offset, 1); shift = BIT(offset, 2) * 4; data = (data & 0x0f) << shift; - m_vrc_vrom_bank[bank] = data | m_chr_base; - chr1_x(bank, m_vrc_vrom_bank[bank], CHRROM); + m_vrc_vrom_bank[bank] = data; + + update_chr(); break; } } + +void nes_somari_device::update_prg() +{ + switch (m_board_mode) + { + case SOMARI_VRC2_MODE: + prg8_89(m_vrc_prg_bank[0]); + prg8_ab(m_vrc_prg_bank[1]); + prg8_cd(0x3e); + prg8_ef(0x3f); + break; + case SOMARI_MMC3_MODE: + { + UINT8 prg_flip = (m_latch & 0x40) ? 2 : 0; + prg8_x(0, m_mmc_prg_bank[0 ^ prg_flip]); + prg8_x(1, m_mmc_prg_bank[1]); + prg8_x(2, m_mmc_prg_bank[2 ^ prg_flip]); + prg8_x(3, m_mmc_prg_bank[3]); + } + break; + case SOMARI_MMC1_MODE: +// case SOMARI_MMC1_MODE_AGAIN: + { + UINT8 prg_offset = m_mmc1_reg[1] & 0x10; + + switch (m_mmc1_reg[0] & 0x0c) + { + case 0x00: + case 0x04: + prg32((prg_offset + m_mmc1_reg[3]) >> 1); + break; + case 0x08: + prg16_89ab(prg_offset + 0); + prg16_cdef(prg_offset + m_mmc1_reg[3]); + break; + case 0x0c: + prg16_89ab(prg_offset + m_mmc1_reg[3]); + prg16_cdef(prg_offset + 0x0f); + break; + } + } + break; + } +} + +void nes_somari_device::update_chr() +{ + switch (m_board_mode) + { + case SOMARI_VRC2_MODE: + for (int i = 0; i < 8; i++) + chr1_x(i, m_chr_base | m_vrc_vrom_bank[i], CHRROM); + break; + case SOMARI_MMC3_MODE: + { + UINT8 chr_page = (m_latch & 0x80) >> 5; + chr1_x(chr_page ^ 0, m_chr_base | ((m_mmc_vrom_bank[0] & ~0x01)), CHRROM); + chr1_x(chr_page ^ 1, m_chr_base | ((m_mmc_vrom_bank[0] | 0x01)), CHRROM); + chr1_x(chr_page ^ 2, m_chr_base | ((m_mmc_vrom_bank[1] & ~0x01)), CHRROM); + chr1_x(chr_page ^ 3, m_chr_base | ((m_mmc_vrom_bank[1] | 0x01)), CHRROM); + chr1_x(chr_page ^ 4, m_chr_base | (m_mmc_vrom_bank[2]), CHRROM); + chr1_x(chr_page ^ 5, m_chr_base | (m_mmc_vrom_bank[3]), CHRROM); + chr1_x(chr_page ^ 6, m_chr_base | (m_mmc_vrom_bank[4]), CHRROM); + chr1_x(chr_page ^ 7, m_chr_base | (m_mmc_vrom_bank[5]), CHRROM); + } + break; + case SOMARI_MMC1_MODE: +// case SOMARI_MMC1_MODE_AGAIN: + if (BIT(m_mmc1_reg[0], 4)) + { + chr4_0(m_mmc1_reg[1] & 0x1f, CHRROM); + chr4_4(m_mmc1_reg[2] & 0x1f, CHRROM); + } + else + chr8((m_mmc1_reg[1] & 0x1f) >> 1, CHRROM); + break; + } +} + +void nes_somari_device::update_mirror() +{ + switch (m_board_mode) + { + case SOMARI_VRC2_MODE: + set_nt_mirroring(m_vrc_mirror_reg ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + break; + case SOMARI_MMC3_MODE: + set_nt_mirroring(m_mmc3_mirror_reg ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + break; + case SOMARI_MMC1_MODE: +// case SOMARI_MMC1_MODE_AGAIN: + switch (m_mmc1_reg[0] & 0x03) + { + case 0x00: set_nt_mirroring(PPU_MIRROR_LOW); break; + case 0x01: set_nt_mirroring(PPU_MIRROR_HIGH); break; + case 0x02: set_nt_mirroring(PPU_MIRROR_VERT); break; + case 0x03: set_nt_mirroring(PPU_MIRROR_HORZ); break; + } + break; + } +} + + WRITE8_MEMBER(nes_somari_device::write_h) { LOG_MMC(("somari write_h, mode %d, offset: %04x, data: %02x\n", m_board_mode, offset, data)); switch (m_board_mode) { - case 0x00: vrc2_w(space, offset, data, mem_mask); break; - case 0x01: mmc3_w(space, offset, data, mem_mask); break; - case 0x02: mmc1_w(space, offset, data, mem_mask); break; + case SOMARI_VRC2_MODE: vrc2_w(space, offset, data, mem_mask); break; + case SOMARI_MMC3_MODE: mmc3_w(space, offset, data, mem_mask); break; + case SOMARI_MMC1_MODE: mmc1_w(space, offset, data, mem_mask); break; } } @@ -342,27 +391,21 @@ void nes_somari_device::bank_update_switchmode() { switch (m_board_mode) { - case 0x00: - prg8_89(m_vrc_prg_bank[0]); - prg8_ab(m_vrc_prg_bank[1]); - for (int i = 0; i < 8; i++) - chr1_x(i, m_vrc_vrom_bank[i], CHRROM); + case SOMARI_VRC2_MODE: break; - case 0x01: - set_prg(m_prg_base, m_prg_mask); - set_chr(m_chr_source, m_chr_base, m_chr_mask); + case SOMARI_MMC3_MODE: break; - case 0x02: - mmc1_set_prg(); - mmc1_set_chr(); + case SOMARI_MMC1_MODE: break; } + update_mirror(); + update_prg(); + update_chr(); } -WRITE8_MEMBER(nes_somari_device::write_l) +WRITE8_MEMBER(nes_somari_device::write_m) { - LOG_MMC(("somari write_l, offset: %04x, data: %02x\n", offset, data)); - offset += 0x100; + LOG_MMC(("somari write_m, offset: %04x, data: %02x\n", offset, data)); if (offset & 0x100) { diff --git a/src/mess/machine/nes_somari.h b/src/mess/machine/nes_somari.h index 2f201de9b9e..5770bfa9614 100644 --- a/src/mess/machine/nes_somari.h +++ b/src/mess/machine/nes_somari.h @@ -14,7 +14,8 @@ public: // device-level overrides virtual void device_start(); - virtual DECLARE_WRITE8_MEMBER(write_l); + virtual DECLARE_WRITE8_MEMBER(write_l) { write_m(space, offset + 0x100, data, mem_mask); } + virtual DECLARE_WRITE8_MEMBER(write_m); virtual DECLARE_WRITE8_MEMBER(mmc1_w); virtual DECLARE_WRITE8_MEMBER(mmc3_w); virtual DECLARE_WRITE8_MEMBER(vrc2_w); @@ -22,13 +23,15 @@ public: virtual void pcb_reset(); private: - void mmc1_set_prg(); - void mmc1_set_chr(); + void update_prg(); + void update_chr(); + void update_mirror(); void bank_update_switchmode(); UINT8 m_board_mode; // MMC3 - inherited from txrom + UINT8 m_mmc3_mirror_reg; // MMC1 UINT8 m_count; @@ -38,6 +41,7 @@ private: // VRC2 UINT8 m_vrc_prg_bank[2]; UINT8 m_vrc_vrom_bank[8]; + UINT8 m_vrc_mirror_reg; };