summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/namcoc7x.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/namcoc7x.c')
-rw-r--r--src/mame/audio/namcoc7x.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/mame/audio/namcoc7x.c b/src/mame/audio/namcoc7x.c
new file mode 100644
index 00000000000..e40c0cda585
--- /dev/null
+++ b/src/mame/audio/namcoc7x.c
@@ -0,0 +1,175 @@
+/*
+ namcoc7x.c - sound hardware for mid-90s Namco systems
+
+ System MCU Synthesizer
+ ------------------------------------
+ NB-1 C351 C352
+ NB-2 C351 C352
+ System 22 C74 C352
+ FL C75 C352
+ System 11 C76 C352
+
+ All of these MCUs are Mitsubishi M377xx family (65c816 based)
+ with 16k of internal BIOS ROM. The BIOS is the same for all
+ chips of the same number. We currently use the BIOS from a
+ Super System 22 game (Prop Cycle) to substitute for the
+ BIOS in these chips. This is compatible enough to play
+ the sound and music, but not enough to read the inputs or
+ handle coinage (the other task these MCUs have).
+
+ These systems have 48k of shared RAM with the host. Due to
+ the MCU's work variables being moved around we cannot enable
+ full sharing or else the main CPU can overwrite important
+ MCU work variables and crash it.
+
+ Emulation by R. Belmont.
+ Thanks to Cync and Cap for invaluable assistance.
+*/
+
+#include "driver.h"
+#include "audio/namcoc7x.h"
+
+static UINT16 *namcoc7x_mcuram;
+static UINT16 su_82;
+static UINT32 *namcoc7x_hostram;
+
+static READ16_HANDLER( speedup_r )
+{
+ if ((activecpu_get_pc() == 0xc12d) && (!(su_82 & 0xff00)))
+ {
+ cpu_spinuntil_int();
+ }
+
+ return su_82;
+}
+
+static WRITE16_HANDLER( speedup_w )
+{
+ COMBINE_DATA(&su_82);
+}
+
+void namcoc7x_sound_write16(UINT16 command, UINT32 offset)
+{
+ namcoc7x_mcuram[offset] = command;
+}
+
+void namcoc7x_on_driver_init(void)
+{
+ UINT8 *pROM = (UINT8 *)memory_region(REGION_USER4);
+ int cpunum;
+
+ // clear the first page of the data ROM
+ // (prevents external init routines from getting called - they assume a
+ // RAM layout for a different BIOS and crash ours)
+ memset(pROM, 0xff, 0x100);
+
+ // install speedup cheat
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ if (Machine->drv->cpu[cpunum].type == CPU_M37702)
+ {
+ memory_install_read16_handler(cpunum, ADDRESS_SPACE_PROGRAM, 0x82, 0x83, 0, 0, speedup_r);
+ memory_install_write16_handler(cpunum, ADDRESS_SPACE_PROGRAM, 0x82, 0x83, 0, 0, speedup_w);
+ }
+}
+
+void namcoc7x_set_host_ram(UINT32 *hostram)
+{
+ namcoc7x_hostram = hostram;
+}
+
+// Only share the sound work area
+static READ16_HANDLER( c7x_shared_r )
+{
+ UINT16 *share16 = (UINT16 *)namcoc7x_hostram;
+
+ if (offset >= 0x400/2)
+ {
+ return namcoc7x_mcuram[offset];
+ }
+
+ return share16[BYTE_XOR_LE(offset)];
+}
+
+static WRITE16_HANDLER( c7x_shared_w )
+{
+ UINT16 *share16 = (UINT16 *)namcoc7x_hostram;
+
+ if (offset >= 0x400/2)
+ {
+ COMBINE_DATA(&namcoc7x_mcuram[offset]);
+ }
+ else
+ {
+ COMBINE_DATA(&share16[BYTE_XOR_LE(offset)]);
+ }
+}
+
+ADDRESS_MAP_START( namcoc7x_mcu_map, ADDRESS_SPACE_PROGRAM, 16 )
+ AM_RANGE(0x002000, 0x002fff) AM_READWRITE( c352_0_r, c352_0_w )
+ AM_RANGE(0x004000, 0x00bfff) AM_RAM AM_BASE(&namcoc7x_mcuram)
+ AM_RANGE(0x00c000, 0x00ffff) AM_ROM AM_REGION(REGION_USER4, 0x8c000)
+ AM_RANGE(0x080000, 0x0fffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x200000, 0x27ffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x280000, 0x2fffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x301000, 0x301001) AM_NOP // watchdog? LEDs?
+ AM_RANGE(0x308000, 0x308003) AM_NOP // volume control IC?
+ADDRESS_MAP_END
+
+ADDRESS_MAP_START( namcoc7x_mcu_share_map, ADDRESS_SPACE_PROGRAM, 16 )
+ AM_RANGE(0x002000, 0x002fff) AM_READWRITE( c352_0_r, c352_0_w )
+ AM_RANGE(0x004000, 0x00bfff) AM_RAM AM_READWRITE( c7x_shared_r, c7x_shared_w ) AM_BASE(&namcoc7x_mcuram)
+ AM_RANGE(0x00c000, 0x00ffff) AM_ROM AM_REGION(REGION_USER4, 0x8c000)
+ AM_RANGE(0x080000, 0x0fffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x200000, 0x27ffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x280000, 0x2fffff) AM_ROM AM_REGION(REGION_USER4, 0)
+ AM_RANGE(0x301000, 0x301001) AM_NOP // watchdog? LEDs?
+ AM_RANGE(0x308000, 0x308003) AM_NOP // volume control IC?
+ADDRESS_MAP_END
+
+static int p4;
+
+static READ8_HANDLER( mcu_port5_r )
+{
+ return 0xff;
+}
+
+static WRITE8_HANDLER( mcu_port4_w )
+{
+ p4 = data;
+}
+
+static READ8_HANDLER( mcu_port4_r )
+{
+ return p4;
+}
+
+static WRITE8_HANDLER( mcu_port5_w )
+{
+}
+
+static READ8_HANDLER( mcu_port6_r )
+{
+ return 0;
+}
+
+static READ8_HANDLER( mcu_port7_r )
+{
+ return 0;
+}
+
+ADDRESS_MAP_START( namcoc7x_mcu_io, ADDRESS_SPACE_IO, 8 )
+ AM_RANGE(M37710_PORT4, M37710_PORT4) AM_READ( mcu_port4_r ) AM_WRITE( mcu_port4_w )
+ AM_RANGE(M37710_PORT5, M37710_PORT5) AM_READ( mcu_port5_r ) AM_WRITE( mcu_port5_w )
+ AM_RANGE(M37710_PORT6, M37710_PORT6) AM_READ( mcu_port6_r ) AM_WRITENOP
+ AM_RANGE(M37710_PORT7, M37710_PORT7) AM_READ( mcu_port7_r )
+ AM_RANGE(0x10, 0x1f) AM_NOP
+ADDRESS_MAP_END
+
+INTERRUPT_GEN( namcoc7x_interrupt )
+{
+ if (cpu_getiloops() == 0)
+ cpunum_set_input_line(1, M37710_LINE_IRQ0, HOLD_LINE);
+ else
+ cpunum_set_input_line(1, M37710_LINE_IRQ2, HOLD_LINE);
+}
+