diff options
Diffstat (limited to 'trunk/src/mame/audio/namco54.c')
-rw-r--r-- | trunk/src/mame/audio/namco54.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/trunk/src/mame/audio/namco54.c b/trunk/src/mame/audio/namco54.c new file mode 100644 index 00000000000..d8ba961ef15 --- /dev/null +++ b/trunk/src/mame/audio/namco54.c @@ -0,0 +1,197 @@ +/*************************************************************************** + + Namco 54XX + + This custom chip is a Fujitsu MB8844 MCU programmed to act as a noise + generator. It is used for explosions, the shoot sound in Bosconian, + and the tire screech sound in Pole Position. + + CMD = command from main CPU + OUTn = sound outputs (3 channels) + + The chip reads the command when the /IRQ is pulled down. + + +------+ + EX|1 28|Vcc + X|2 27|K3 (CMD7) + /RESET|3 26|K2 (CMD6) + (OUT0.0) O0|4 25|K1 (CMD5) + (OUT0.1) O1|5 24|K0 (CMD4) + (OUT0.2) O2|6 23|R10/IRQ + (OUT0.3) O3|7 22|R9/TC + (OUT1.0) O4|8 21|R8 + (OUT1.1) O5|9 20|R7 (OUT2.3) + (OUT1.2) O6|10 19|R6 (OUT2.2) + (OUT1.3) O7|11 18|R5 (OUT2.1) + (CMD0) R0|12 17|R4 (OUT2.0) + (CMD1) R1|13 16|R3 (CMD3) + GND|14 15|R2 (CMD2) + +------+ + + [1] The RNG that drives the type A output is output on pin 21, and + the one that drives the type B output is output on pin 22, but those + pins are not connected on the board. + + + The command format is very simple: + + 0x: nop + 1x: play sound type A + 2x: play sound type B + 3x: set parameters (type A) (followed by 4 bytes) + 4x: set parameters (type B) (followed by 4 bytes) + 5x: play sound type C + 6x: set parameters (type C) (followed by 5 bytes) + 7x: set volume for sound type C to x + 8x-Fx: nop + +***************************************************************************/ + +#include "emu.h" +#include "namco54.h" +#include "cpu/mb88xx/mb88xx.h" + +typedef struct _namco_54xx_state namco_54xx_state; +struct _namco_54xx_state +{ + device_t *m_cpu; + device_t *m_discrete; + int m_basenode; + UINT8 m_latched_cmd; +}; + +INLINE namco_54xx_state *get_safe_token(device_t *device) +{ + assert(device != NULL); + assert(device->type() == NAMCO_54XX); + + return (namco_54xx_state *)downcast<legacy_device_base *>(device)->token(); +} + + + +static TIMER_CALLBACK( namco_54xx_latch_callback ) +{ + namco_54xx_state *state = get_safe_token((device_t *)ptr); + state->m_latched_cmd = param; +} + +static READ8_HANDLER( namco_54xx_K_r ) +{ + namco_54xx_state *state = get_safe_token(space->device().owner()); + return state->m_latched_cmd >> 4; +} + +static READ8_HANDLER( namco_54xx_R0_r ) +{ + namco_54xx_state *state = get_safe_token(space->device().owner()); + return state->m_latched_cmd & 0x0f; +} + + +static WRITE8_HANDLER( namco_54xx_O_w ) +{ + namco_54xx_state *state = get_safe_token(space->device().owner()); + UINT8 out = (data & 0x0f); + if (data & 0x10) + discrete_sound_w(state->m_discrete, NAMCO_54XX_1_DATA(state->m_basenode), out); + else + discrete_sound_w(state->m_discrete, NAMCO_54XX_0_DATA(state->m_basenode), out); +} + +static WRITE8_HANDLER( namco_54xx_R1_w ) +{ + namco_54xx_state *state = get_safe_token(space->device().owner()); + UINT8 out = (data & 0x0f); + + discrete_sound_w(state->m_discrete, NAMCO_54XX_2_DATA(state->m_basenode), out); +} + + + + +static TIMER_CALLBACK( namco_54xx_irq_clear ) +{ + namco_54xx_state *state = get_safe_token((device_t *)ptr); + device_set_input_line(state->m_cpu, 0, CLEAR_LINE); +} + +WRITE8_DEVICE_HANDLER( namco_54xx_write ) +{ + namco_54xx_state *state = get_safe_token(device); + + device->machine().scheduler().synchronize(FUNC(namco_54xx_latch_callback), data, (void *)device); + + device_set_input_line(state->m_cpu, 0, ASSERT_LINE); + + // The execution time of one instruction is ~4us, so we must make sure to + // give the cpu time to poll the /IRQ input before we clear it. + // The input clock to the 06XX interface chip is 64H, that is + // 18432000/6/64 = 48kHz, so it makes sense for the irq line to be + // asserted for one clock cycle ~= 21us. + device->machine().scheduler().timer_set(attotime::from_usec(21), FUNC(namco_54xx_irq_clear), 0, (void *)device); +} + + +/*************************************************************************** + DEVICE INTERFACE +***************************************************************************/ + +static ADDRESS_MAP_START( namco_54xx_map_io, AS_IO, 8 ) + AM_RANGE(MB88_PORTK, MB88_PORTK) AM_READ(namco_54xx_K_r) + AM_RANGE(MB88_PORTO, MB88_PORTO) AM_WRITE(namco_54xx_O_w) + AM_RANGE(MB88_PORTR0, MB88_PORTR0) AM_READ(namco_54xx_R0_r) + AM_RANGE(MB88_PORTR1, MB88_PORTR1) AM_WRITE(namco_54xx_R1_w) + AM_RANGE(MB88_PORTR2, MB88_PORTR2) AM_NOP +ADDRESS_MAP_END + + +static MACHINE_CONFIG_FRAGMENT( namco_54xx ) + MCFG_CPU_ADD("mcu", MB8844, DERIVED_CLOCK(1,1)) /* parent clock, internally divided by 6 */ + MCFG_CPU_IO_MAP(namco_54xx_map_io) +MACHINE_CONFIG_END + + +ROM_START( namco_54xx ) + ROM_REGION( 0x400, "mcu", 0 ) + ROM_LOAD( "54xx.bin", 0x0000, 0x0400, CRC(ee7357e0) SHA1(01bdf984a49e8d0cc8761b2cc162fd6434d5afbe) ) +ROM_END + + +/*------------------------------------------------- + device start callback +-------------------------------------------------*/ + +static DEVICE_START( namco_54xx ) +{ + namco_54xx_config *config = (namco_54xx_config *)downcast<const legacy_device_base *>(device)->inline_config(); + namco_54xx_state *state = get_safe_token(device); + astring tempstring; + + /* find our CPU */ + state->m_cpu = device->subdevice("mcu"); + assert(state->m_cpu != NULL); + + /* find the attached discrete sound device */ + assert(config->discrete != NULL); + state->m_discrete = device->machine().device(config->discrete); + assert(state->m_discrete != NULL); + state->m_basenode = config->firstnode; +} + + +/*------------------------------------------------- + device definition +-------------------------------------------------*/ + +static const char DEVTEMPLATE_SOURCE[] = __FILE__; + +#define DEVTEMPLATE_ID(p,s) p##namco_54xx##s +#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_ROM_REGION | DT_HAS_MACHINE_CONFIG | DT_HAS_INLINE_CONFIG +#define DEVTEMPLATE_NAME "Namco 54xx" +#define DEVTEMPLATE_SHORTNAME "namco54" +#define DEVTEMPLATE_FAMILY "Namco I/O" +#include "devtempl.h" + + +DEFINE_LEGACY_DEVICE(NAMCO_54XX, namco_54xx); |