diff options
Diffstat (limited to 'src/mame/audio/namcoc7x.c')
-rw-r--r-- | src/mame/audio/namcoc7x.c | 175 |
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); +} + |