summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes/konami.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nes/konami.cpp')
-rw-r--r--src/devices/bus/nes/konami.cpp424
1 files changed, 182 insertions, 242 deletions
diff --git a/src/devices/bus/nes/konami.cpp b/src/devices/bus/nes/konami.cpp
index bae7ec4ca9d..27362d28c8c 100644
--- a/src/devices/bus/nes/konami.cpp
+++ b/src/devices/bus/nes/konami.cpp
@@ -16,11 +16,6 @@
* Konami VRC-6 [mapper 24,26]
* Konami VRC-7 [mapper 85]
-
- TODO:
- - improve IRQ (CPU mode not currently emulated)
- - add VRC-6 sound features
-
***********************************************************************************************************/
@@ -29,14 +24,15 @@
#include "speaker.h"
+#define LOG_UNHANDLED (1U << 1)
#ifdef NES_PCB_DEBUG
-#define VERBOSE 1
+#define VERBOSE (LOG_UNHANDLED | LOG_GENERAL)
#else
-#define VERBOSE 0
+#define VERBOSE (LOG_UNHANDLED)
#endif
+#include "logmacro.h"
-#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
//-------------------------------------------------
// constructor
@@ -50,28 +46,28 @@ DEFINE_DEVICE_TYPE(NES_VRC6, nes_konami_vrc6_device, "nes_vrc6", "NES Cart Konam
DEFINE_DEVICE_TYPE(NES_VRC7, nes_konami_vrc7_device, "nes_vrc7", "NES Cart Konami VRC-7 PCB")
-nes_konami_vrc1_device::nes_konami_vrc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc1_device::nes_konami_vrc1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_nrom_device(mconfig, NES_VRC1, tag, owner, clock)
{
}
-nes_konami_vrc2_device::nes_konami_vrc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc2_device::nes_konami_vrc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: nes_nrom_device(mconfig, type, tag, owner, clock), m_latch(0)
{
}
-nes_konami_vrc2_device::nes_konami_vrc2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc2_device::nes_konami_vrc2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_konami_vrc2_device(mconfig, NES_VRC2, tag, owner, clock)
{
}
-nes_konami_vrc3_device::nes_konami_vrc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc3_device::nes_konami_vrc3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_nrom_device(mconfig, NES_VRC3, tag, owner, clock), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_enable_latch(0), m_irq_mode(0), irq_timer(nullptr)
{
}
nes_konami_vrc4_device::nes_konami_vrc4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
- : nes_nrom_device(mconfig, type, tag, owner, clock), m_prg_flip(0), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_enable_latch(0), m_irq_mode(0), m_irq_prescale(0), irq_timer(nullptr)
+ : nes_nrom_device(mconfig, type, tag, owner, clock), m_prg_flip(0), m_wram_enable(0), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_enable_latch(0), m_irq_mode(0), m_irq_prescale(0), irq_timer(nullptr)
{
}
@@ -80,12 +76,12 @@ nes_konami_vrc4_device::nes_konami_vrc4_device(const machine_config &mconfig, co
{
}
-nes_konami_vrc6_device::nes_konami_vrc6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc6_device::nes_konami_vrc6_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_konami_vrc4_device(mconfig, NES_VRC6, tag, owner, clock), m_vrc6snd(*this, "vrc6snd")
{
}
-nes_konami_vrc7_device::nes_konami_vrc7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_konami_vrc7_device::nes_konami_vrc7_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_konami_vrc4_device(mconfig, NES_VRC7, tag, owner, clock), m_vrc7snd(*this, "vrc7snd")
{
}
@@ -100,12 +96,11 @@ void nes_konami_vrc1_device::device_start()
void nes_konami_vrc1_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
prg16_89ab(0);
prg16_cdef(m_prg_chunks - 1);
chr8(0, m_chr_source);
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
+ m_mmc_vrom_bank[0] = m_mmc_vrom_bank[1] = 0;
}
void nes_konami_vrc2_device::device_start()
@@ -117,19 +112,18 @@ void nes_konami_vrc2_device::device_start()
void nes_konami_vrc2_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
prg16_89ab(0);
prg16_cdef(m_prg_chunks - 1);
chr8(0, m_chr_source);
m_latch = 0;
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
+ std::fill(std::begin(m_mmc_vrom_bank), std::end(m_mmc_vrom_bank), 0x00);
}
void nes_konami_vrc3_device::device_start()
{
common_start();
- irq_timer = timer_alloc(TIMER_IRQ);
+ irq_timer = timer_alloc(FUNC(nes_konami_vrc3_device::irq_timer_tick), this);
irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
save_item(NAME(m_irq_mode));
@@ -141,7 +135,6 @@ void nes_konami_vrc3_device::device_start()
void nes_konami_vrc3_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
prg16_89ab(0);
prg16_cdef(m_prg_chunks - 1);
chr8(0, m_chr_source);
@@ -153,11 +146,10 @@ void nes_konami_vrc3_device::pcb_reset()
m_irq_count_latch = 0;
}
-
void nes_konami_vrc4_device::device_start()
{
common_start();
- irq_timer = timer_alloc(TIMER_IRQ);
+ irq_timer = timer_alloc(FUNC(nes_konami_vrc4_device::irq_timer_tick), this);
irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
save_item(NAME(m_irq_mode));
@@ -167,15 +159,13 @@ void nes_konami_vrc4_device::device_start()
save_item(NAME(m_irq_count));
save_item(NAME(m_irq_count_latch));
save_item(NAME(m_prg_flip));
+ save_item(NAME(m_wram_enable));
save_item(NAME(m_mmc_prg_bank));
save_item(NAME(m_mmc_vrom_bank));
}
void nes_konami_vrc4_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- chr8(0, m_chr_source);
-
m_irq_mode = 0;
m_irq_prescale = 0;
m_irq_enable = 0;
@@ -184,46 +174,20 @@ void nes_konami_vrc4_device::pcb_reset()
m_irq_count_latch = 0;
m_prg_flip = 0;
+ m_wram_enable = 0;
m_mmc_prg_bank[0] = 0;
m_mmc_prg_bank[1] = 0;
set_prg();
- std::fill(std::begin(m_mmc_vrom_bank), std::end(m_mmc_vrom_bank), 0x00);
-}
-void nes_konami_vrc6_device::device_start()
-{
- nes_konami_vrc4_device::device_start();
-}
-
-void nes_konami_vrc7_device::device_start()
-{
- common_start();
- irq_timer = timer_alloc(TIMER_IRQ);
- irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
-
- save_item(NAME(m_irq_mode));
- save_item(NAME(m_irq_prescale));
- save_item(NAME(m_irq_enable));
- save_item(NAME(m_irq_enable_latch));
- save_item(NAME(m_irq_count));
- save_item(NAME(m_irq_count_latch));
+ for (int i = 0; i < 8; i++)
+ m_mmc_vrom_bank[i] = i;
+ set_chr();
}
void nes_konami_vrc7_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- prg8_89(0);
- prg8_ab(0);
- prg8_cd(0);
- prg8_ef(0xff);
- chr8(0, m_chr_source);
-
- m_irq_mode = 0;
- m_irq_prescale = 0;
- m_irq_enable = 0;
- m_irq_enable_latch = 0;
- m_irq_count = 0;
- m_irq_count_latch = 0;
+ nes_konami_vrc4_device::pcb_reset();
+ prg32((m_prg_chunks >> 1) - 1);
}
@@ -240,29 +204,25 @@ void nes_konami_vrc7_device::pcb_reset()
iNES: mapper 75
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_konami_vrc1_device::write_h(offs_t offset, uint8_t data)
+void nes_konami_vrc1_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("VRC-1 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-1 write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x7000)
{
case 0x0000:
- prg8_89(data);
- break;
case 0x2000:
- prg8_ab(data);
- break;
case 0x4000:
- prg8_cd(data);
+ prg8_x(BIT(offset, 13, 2), data & 0x0f);
break;
case 0x1000:
- set_nt_mirroring((data & 0x01) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
- m_mmc_vrom_bank[0] = (m_mmc_vrom_bank[0] & 0x0f) | ((data & 0x02) << 3);
- m_mmc_vrom_bank[1] = (m_mmc_vrom_bank[1] & 0x0f) | ((data & 0x04) << 2);
+ set_nt_mirroring(data & 1 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
+ m_mmc_vrom_bank[0] = (m_mmc_vrom_bank[0] & 0x0f) | BIT(data, 1) << 4;
+ m_mmc_vrom_bank[1] = (m_mmc_vrom_bank[1] & 0x0f) | BIT(data, 2) << 4;
chr4_0(m_mmc_vrom_bank[0], CHRROM);
chr4_4(m_mmc_vrom_bank[1], CHRROM);
break;
@@ -281,47 +241,41 @@ void nes_konami_vrc1_device::write_h(offs_t offset, uint8_t data)
Konami VRC-2
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-uint8_t nes_konami_vrc2_device::read_m(offs_t offset)
+u8 nes_konami_vrc2_device::read_m(offs_t offset)
{
- LOG_MMC(("VRC-2 read_m, offset: %04x\n", offset));
+ LOG("VRC-2 read_m, offset: %04x\n", offset);
- if (!m_battery.empty())
- return m_battery[offset & (m_battery.size() - 1)];
- else if (!m_prgram.empty())
- return m_prgram[offset & (m_prgram.size() - 1)];
- else // sort of protection? it returns open bus in $7000-$7fff and (open bus & 0xfe) | m_latch in $6000-$6fff
- return (offset < 0x1000) ? ((get_open_bus() & 0xfe) | (m_latch & 1)) : get_open_bus();
+ if (!m_battery.empty() || !m_prgram.empty())
+ return device_nes_cart_interface::read_m(offset);
+ else // VRC2 was planned with EEPROM support; the non-working feature behaves as a vestigial 1-bit latch in $6000-$6fff on certain boards (contraj, ggoemon2 depend on this)
+ return (offset < 0x1000) ? (get_open_bus() & 0xfe) | (m_latch & 1) : get_open_bus();
}
-void nes_konami_vrc2_device::write_m(offs_t offset, uint8_t data)
+void nes_konami_vrc2_device::write_m(offs_t offset, u8 data)
{
- LOG_MMC(("VRC-2 write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-2 write_m, offset: %04x, data: %02x\n", offset, data);
- if (!m_battery.empty())
- m_battery[offset & (m_battery.size() - 1)] = data;
- else if (!m_prgram.empty())
- m_prgram[offset & (m_prgram.size() - 1)] = data;
+ if (!m_battery.empty() || !m_prgram.empty())
+ device_nes_cart_interface::write_m(offset, data);
else if (offset < 0x1000)
m_latch = data;
}
-void nes_konami_vrc2_device::write_h(offs_t offset, uint8_t data)
+void nes_konami_vrc2_device::write_h(offs_t offset, u8 data)
{
- uint8_t bank, shift, mask;
- uint16_t add_lines = ((offset << (9 - m_vrc_ls_prg_a)) & 0x200) | ((offset << (8 - m_vrc_ls_prg_b)) & 0x100);
- LOG_MMC(("VRC-2 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-2 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ u8 addr_lines = bitswap<2>(offset, m_vrc_ls_prg_a, m_vrc_ls_prg_b);
switch (offset & 0x7000)
{
case 0x0000:
- prg8_89(data);
- break;
case 0x2000:
- prg8_ab(data);
+ prg8_x(BIT(offset, 13), data);
break;
case 0x1000:
set_nt_mirroring(data & 1 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
@@ -330,14 +284,16 @@ void nes_konami_vrc2_device::write_h(offs_t offset, uint8_t data)
case 0x4000:
case 0x5000:
case 0x6000:
- bank = ((offset & 0x7000) - 0x3000) / 0x0800 + BIT(add_lines, 9);
- shift = BIT(add_lines, 8) * 4;
- mask = (0xf0 >> shift);
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & mask) | (((data >> m_vrc_ls_chr) & 0x0f) << shift);
- chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
+ {
+ int bank = 2 * (BIT(offset, 12, 3) - 3) + BIT(addr_lines, 1);
+ int shift = BIT(addr_lines, 0) * 4;
+ int mask = 0x0f << shift;
+ m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & ~mask) | (((data >> m_vrc_ls_chr) << shift) & mask);
+ chr1_x(bank, m_mmc_vrom_bank[bank], m_chr_source);
break;
+ }
default:
- logerror("VRC-2 write_h uncaught write, addr: %04x value: %02x\n", offset + 0x8000, data);
+ LOGMASKED(LOG_UNHANDLED, "VRC-2 write_h uncaught write, addr: %04x value: %02x\n", offset + 0x8000, data);
break;
}
}
@@ -350,63 +306,47 @@ void nes_konami_vrc2_device::write_h(offs_t offset, uint8_t data)
iNES: mapper 73
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_konami_vrc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(nes_konami_vrc3_device::irq_timer_tick)
{
- if (id == TIMER_IRQ)
+ if (m_irq_enable)
{
- if (m_irq_enable)
+ u16 mask = m_irq_mode ? 0x00ff : 0xffff; // 8 or 16 bit mode?
+
+ // upper byte only incremented and reloaded in 16-bit mode
+ m_irq_count = (m_irq_count & ~mask) | ((m_irq_count + 1) & mask);
+ if (!(m_irq_count & mask))
{
- if (m_irq_mode) // 8bits mode
- {
- if ((m_irq_count & 0x00ff) == 0xff)
- {
- set_irq_line(ASSERT_LINE);
- m_irq_count = m_irq_count_latch;
- }
- else
- m_irq_count = (m_irq_count & 0xff00) | ((m_irq_count & 0x00ff) + 1);
- }
- else // 16bits mode
- {
- if (m_irq_count == 0xffff)
- {
- set_irq_line(ASSERT_LINE);
- m_irq_count = m_irq_count_latch;
- }
- else
- m_irq_count++;
- }
+ set_irq_line(ASSERT_LINE);
+ m_irq_count = (m_irq_count & ~mask) | (m_irq_count_latch & mask);
}
}
}
-void nes_konami_vrc3_device::write_h(offs_t offset, uint8_t data)
+void nes_konami_vrc3_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("VRC-3 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-3 write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x7000)
{
case 0x0000:
- m_irq_count_latch = (m_irq_count_latch & 0xfff0) | ((data & 0x0f) << 0);
- break;
case 0x1000:
- m_irq_count_latch = (m_irq_count_latch & 0xff0f) | ((data & 0x0f) << 4);
- break;
case 0x2000:
- m_irq_count_latch = (m_irq_count_latch & 0xf0ff) | ((data & 0x0f) << 8);
- break;
case 0x3000:
- m_irq_count_latch = (m_irq_count_latch & 0x0fff) | ((data & 0x0f) << 12);
+ {
+ int shift = 4 * BIT(offset, 12, 2);
+ m_irq_count_latch &= ~(0x000f << shift);
+ m_irq_count_latch |= (data & 0x0f) << shift;
break;
+ }
case 0x4000:
m_irq_mode = data & 0x04;
m_irq_enable = data & 0x02;
m_irq_enable_latch = data & 0x01;
- if (data & 0x02)
+ if (m_irq_enable)
m_irq_count = m_irq_count_latch;
set_irq_line(CLEAR_LINE);
break;
@@ -415,10 +355,10 @@ void nes_konami_vrc3_device::write_h(offs_t offset, uint8_t data)
set_irq_line(CLEAR_LINE);
break;
case 0x7000:
- prg16_89ab(data);
+ prg16_89ab(data & 0x07);
break;
default:
- logerror("VRC-3 write_h uncaught write, offset %04x, data: %02x\n", offset, data);
+ LOGMASKED(LOG_UNHANDLED, "VRC-3 write_h uncaught write, offset %04x, data: %02x\n", offset, data);
break;
}
}
@@ -442,26 +382,23 @@ void nes_konami_vrc4_device::irq_tick()
m_irq_count++;
}
-void nes_konami_vrc4_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(nes_konami_vrc4_device::irq_timer_tick)
{
- if (id == TIMER_IRQ)
+ if (m_irq_enable)
{
- if (m_irq_enable)
+ if (m_irq_mode) // cycle mode
+ irq_tick();
+ else // scanline mode
{
- if (m_irq_mode) // cycle mode
- irq_tick();
- else // scanline mode
+ // A prescaler divides the passing CPU cycles by 114, 114, then 113 (and repeats that order).
+ // This approximates 113+2/3 CPU cycles, which is one NTSC scanline.
+ // Since this is a CPU-based IRQ, though, it is triggered also during non visible scanlines...
+ m_irq_prescale -= 3;
+
+ if (m_irq_prescale <= 0)
{
- // A prescaler divides the passing CPU cycles by 114, 114, then 113 (and repeats that order).
- // This approximates 113+2/3 CPU cycles, which is one NTSC scanline.
- // Since this is a CPU-based IRQ, though, it is triggered also during non visible scanlines...
- if (m_irq_prescale < 3)
- {
- m_irq_prescale += 341;
- irq_tick();
- }
-
- m_irq_prescale -= 3;
+ m_irq_prescale += 341;
+ irq_tick();
}
}
}
@@ -505,11 +442,35 @@ void nes_konami_vrc4_device::set_prg(int prg_base, int prg_mask)
prg8_x(3, prg_base | prg_mask);
}
+void nes_konami_vrc4_device::set_chr(int chr_base, int chr_mask)
+{
+ for (int i = 0; i < 8; i++)
+ chr1_x(i, chr_base | (m_mmc_vrom_bank[i] & chr_mask), m_chr_source);
+}
+
+u8 nes_konami_vrc4_device::read_m(offs_t offset)
+{
+ LOG("VRC-4 read_m, offset: %04x\n", offset);
+
+ if (m_wram_enable)
+ return device_nes_cart_interface::read_m(offset);
+ else
+ return get_open_bus();
+}
+
+void nes_konami_vrc4_device::write_m(offs_t offset, u8 data)
+{
+ LOG("VRC-4 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (m_wram_enable)
+ device_nes_cart_interface::write_m(offset, data);
+}
+
void nes_konami_vrc4_device::write_h(offs_t offset, u8 data)
{
- int bank, shift, mask;
- u16 add_lines = ((offset << (9 - m_vrc_ls_prg_a)) & 0x200) | ((offset << (8 - m_vrc_ls_prg_b)) & 0x100);
- LOG_MMC(("VRC-4 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-4 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ u8 addr_lines = bitswap<2>(offset, m_vrc_ls_prg_a, m_vrc_ls_prg_b);
switch (offset & 0x7000)
{
@@ -519,8 +480,9 @@ void nes_konami_vrc4_device::write_h(offs_t offset, u8 data)
set_prg();
break;
case 0x1000:
- if (add_lines & 0x200)
+ if (BIT(addr_lines, 1))
{
+ m_wram_enable = data & 0x01;
m_prg_flip = data & 0x02;
set_prg();
}
@@ -531,32 +493,31 @@ void nes_konami_vrc4_device::write_h(offs_t offset, u8 data)
case 0x4000:
case 0x5000:
case 0x6000:
- bank = ((offset & 0x7000) - 0x3000) / 0x0800 + BIT(add_lines, 9);
- shift = BIT(add_lines, 8) * 4;
- mask = shift ? 0x1f0 : 0x0f;
+ {
+ int bank = 2 * (BIT(offset, 12, 3) - 3) + BIT(addr_lines, 1);
+ int shift = BIT(addr_lines, 0) * 4;
+ int mask = shift ? 0x1f0 : 0x0f;
m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & ~mask) | ((data << shift) & mask);
- chr1_x(bank, m_mmc_vrom_bank[bank], m_chr_source);
+ set_chr();
break;
+ }
case 0x7000:
- switch (add_lines)
+ switch (addr_lines)
{
- case 0x000:
+ case 0:
m_irq_count_latch = (m_irq_count_latch & 0xf0) | (data & 0x0f);
break;
- case 0x100:
- m_irq_count_latch = (m_irq_count_latch & 0x0f) | ((data & 0x0f) << 4);
+ case 1:
+ m_irq_count_latch = (m_irq_count_latch & 0x0f) | (data & 0x0f) << 4;
break;
- case 0x200:
+ case 2:
irq_ctrl_w(data);
break;
- case 0x300:
+ case 3:
irq_ack_w();
break;
}
break;
- default:
- logerror("VRC-4 write_h uncaught write, addr: %04x value: %02x\n", ((offset & 0x7000) | add_lines) + 0x8000, data);
- break;
}
}
@@ -564,62 +525,64 @@ void nes_konami_vrc4_device::write_h(offs_t offset, u8 data)
Konami VRC-6
- In MESS: Supported. It also uses konami_irq (there are IRQ
+ In MAME: Supported. It also uses konami_irq (there are IRQ
issues though: see Akumajou Densetsu intro).
+ TODO: Implement other CHR modes not used by any of
+ the three released VRC6 games?
+
-------------------------------------------------*/
-void nes_konami_vrc6_device::write_h(offs_t offset, uint8_t data)
+void nes_konami_vrc6_device::write_h(offs_t offset, u8 data)
{
- uint8_t bank;
- uint16_t add_lines = ((offset << (9 - m_vrc_ls_prg_a)) & 0x200) | ((offset << (8 - m_vrc_ls_prg_b)) & 0x100);
- LOG_MMC(("VRC-6 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("VRC-6 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ u8 addr_lines = bitswap<2>(offset, m_vrc_ls_prg_a, m_vrc_ls_prg_b);
switch (offset & 0x7000)
{
case 0x0000:
- prg16_89ab(data);
+ prg16_89ab(data & 0x0f);
break;
case 0x4000:
- prg8_cd(data);
+ prg8_cd(data & 0x1f);
break;
case 0x1000: // pulse 1 & global control
- m_vrc6snd->write(add_lines>>8, data);
+ m_vrc6snd->write(addr_lines, data);
break;
case 0x2000: // pulse 2
- m_vrc6snd->write((add_lines>>8) | 0x100, data);
+ m_vrc6snd->write(addr_lines | 0x100, data);
break;
case 0x3000:
- if (add_lines == 0x300)
+ if (addr_lines == 3)
+ {
set_mirror(data >> 2);
+ m_wram_enable = BIT(data, 7);
+ }
else // saw
- m_vrc6snd->write((add_lines>>8) | 0x200, data);
+ m_vrc6snd->write(addr_lines | 0x200, data);
break;
case 0x5000:
case 0x6000:
- bank = ((offset & 0x7000) - 0x5000) / 0x0400 + ((add_lines & 0x0300) >> 8);
- chr1_x(bank, data, CHRROM);
+ chr1_x(4 * BIT(offset, 13) + addr_lines, data, CHRROM);
break;
case 0x7000:
- switch (add_lines)
+ switch (addr_lines)
{
- case 0x000:
+ case 0:
m_irq_count_latch = data;
break;
- case 0x100:
+ case 1:
irq_ctrl_w(data);
break;
- case 0x200:
+ case 2:
irq_ack_w();
break;
default:
- logerror("VRC-6 write_h uncaught write, addr: %04x value: %02x\n", ((offset & 0x7000) | add_lines) + 0x8000, data);
+ LOGMASKED(LOG_UNHANDLED, "VRC-6 write_h uncaught write, addr: %04x value: %02x\n", ((offset & 0x7000) | addr_lines) + 0x8000, data);
break;
}
break;
- default:
- logerror("VRC-6 write_h uncaught write, addr: %04x value: %02x\n", ((offset & 0x7000) | add_lines) + 0x8000, data);
- break;
}
}
@@ -646,75 +609,52 @@ void nes_konami_vrc6_device::device_add_mconfig(machine_config &config)
iNES: mapper 85
- In MESS: Supported. It also uses konami_irq.
+ In MAME: Supported. It also uses konami_irq.
-------------------------------------------------*/
-void nes_konami_vrc7_device::write_h(offs_t offset, uint8_t data)
+void nes_konami_vrc7_device::write_h(offs_t offset, u8 data)
{
- uint8_t bank;
- LOG_MMC(("VRC-7 write_h, offset: %04x, data: %02x\n", offset, data));
-
- switch (offset & 0x7038)
- {
- case 0x0000:
- prg8_89(data);
- break;
- case 0x0008:
- case 0x0010:
- case 0x0018:
- prg8_ab(data);
- break;
-
- case 0x1000:
- prg8_cd(data);
- break;
-
- case 0x1010:
- case 0x1018:
- m_vrc7snd->address_w(data);
- break;
- case 0x1030:
- case 0x1038:
- m_vrc7snd->data_w(data);
- break;
+ LOG("VRC-7 write_h, offset: %04x, data: %02x\n", offset, data);
- case 0x2000:
- case 0x2008:
- case 0x2010:
- case 0x2018:
- case 0x3000:
- case 0x3008:
- case 0x3010:
- case 0x3018:
- case 0x4000:
- case 0x4008:
- case 0x4010:
- case 0x4018:
- case 0x5000:
- case 0x5008:
- case 0x5010:
- case 0x5018:
- bank = ((offset & 0x7000) - 0x2000) / 0x0800 + ((offset & 0x0018) ? 1 : 0);
- chr1_x(bank, data, m_chr_source);
- break;
+ u8 reg = bitswap<4>(offset, 14, 13, 12, m_vrc_ls_prg_a);
- case 0x6000:
+ switch (reg)
+ {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ prg8_x(reg, data & 0x3f);
+ break;
+ case 0x3:
+ if (BIT(offset, 5))
+ m_vrc7snd->data_w(data);
+ else
+ m_vrc7snd->address_w(data);
+ break;
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ chr1_x(reg - 4, data, m_chr_source);
+ break;
+ case 0xc:
set_mirror(data);
+ m_wram_enable = BIT(data, 7);
break;
- case 0x6008: case 0x6010: case 0x6018:
+ case 0xd:
m_irq_count_latch = data;
break;
- case 0x7000:
+ case 0xe:
irq_ctrl_w(data);
break;
- case 0x7008: case 0x7010: case 0x7018:
+ case 0xf:
irq_ack_w();
break;
-
- default:
- logerror("VRC-7 write_h uncaught write, addr: %04x value: %02x\n", offset + 0x8000, data);
- break;
}
}