diff --git a/src/emu/sound/bsmt2000.c b/src/emu/sound/bsmt2000.c index 618bb040759..1dab3550d05 100644 --- a/src/emu/sound/bsmt2000.c +++ b/src/emu/sound/bsmt2000.c @@ -2,9 +2,40 @@ bsmt2000.c - BSMT2000 sound emulator. + BSMT2000 device emulator. + +**************************************************************************** Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**************************************************************************** Chip is actually a TMS320C15 DSP with embedded mask rom Trivia: BSMT stands for "Brian Schmidt's Mouse Trap" @@ -16,486 +47,372 @@ #include "bsmt2000.h" -/*************************************************************************** - DEBUGGING/OPTIONS -***************************************************************************/ -#define LOG_COMMANDS 0 +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* NOTE: the original chip did not support interpolation, but it sounds */ -/* nicer if you enable it. For accuracy's sake, we leave it off by default. */ -#define ENABLE_INTERPOLATION 0 +// devices +const device_type BSMT2000 = bsmt2000_device_config::static_alloc_device_config; + + +// program map for the DSP (points to internal ROM) +static ADDRESS_MAP_START( tms_program_map, ADDRESS_SPACE_PROGRAM, 16 ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x000, 0xfff) AM_ROM +ADDRESS_MAP_END + + +// I/O map for the DSP +static ADDRESS_MAP_START( tms_io_map, ADDRESS_SPACE_IO, 16 ) + AM_RANGE(0, 0) AM_DEVREADWRITE_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_register_r, tms_rom_addr_w) + AM_RANGE(1, 1) AM_DEVREADWRITE_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_data_r, tms_rom_bank_w) + AM_RANGE(2, 2) AM_DEVREAD_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_rom_r) + AM_RANGE(3, 3) AM_DEVWRITE_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_left_w) + AM_RANGE(7, 7) AM_DEVWRITE_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_right_w) + AM_RANGE(TMS32010_BIO, TMS32010_BIO) AM_DEVREAD_MODERN(DEVICE_SELF_OWNER, bsmt2000_device, tms_write_pending_r) +ADDRESS_MAP_END + + +// machine fragment +static MACHINE_CONFIG_FRAGMENT( bsmt2000 ) + MCFG_CPU_ADD("bsmt2000", TMS32015, DERIVED_CLOCK(1,1)) + MCFG_CPU_PROGRAM_MAP(tms_program_map) + // data map is internal to the CPU + MCFG_CPU_IO_MAP(tms_io_map) +MACHINE_CONFIG_END + + +// default address map for the external memory interface +// the BSMT can address a full 32 bits but typically only 24 are used +static ADDRESS_MAP_START( bsmt2000, 0, 8 ) + AM_RANGE(0x00000, 0xffffff) AM_ROM +ADDRESS_MAP_END + + +// ROM definition for the BSMT2000 program ROM +ROM_START( bsmt2000 ) + ROM_REGION( 0x2000, "bsmt2000", ROMREGION_LOADBYNAME ) + ROM_LOAD16_WORD_SWAP( "bsmt2000.bin", 0x0000, 0x2000, CRC(c2a265af) SHA1(6ec9eb038fb8eb842c5482aebe1d149daf49f2e6) ) +ROM_END -/*************************************************************************** - CONSTANTS -***************************************************************************/ -#define MAX_VOICES (12+1) -#define ADPCM_VOICE 12 +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** +//------------------------------------------------- +// bsmt2000_device_config - constructor +//------------------------------------------------- - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* struct describing a single playing voice */ -typedef struct _bsmt2000_voice bsmt2000_voice; -struct _bsmt2000_voice +bsmt2000_device_config::bsmt2000_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) + : device_config(mconfig, static_alloc_device_config, "BSMT2000", tag, owner, clock), + device_config_sound_interface(mconfig, *this), + device_config_memory_interface(mconfig, *this), + m_space_config("samples", ENDIANNESS_LITTLE, 8, 32, 0, NULL, *ADDRESS_MAP_NAME(bsmt2000)), + m_ready_callback(NULL) { - UINT16 pos; /* current position */ - UINT16 rate; /* stepping value */ - UINT16 loopend; /* loop end value */ - UINT16 loopstart; /* loop start value */ - UINT16 bank; /* bank number */ - UINT16 leftvol; /* left volume */ - UINT16 rightvol; /* right volume */ - UINT16 fraction; /* current fractional position */ -}; +} -typedef struct _bsmt2000_chip bsmt2000_chip; -struct _bsmt2000_chip + +//------------------------------------------------- +// static_alloc_device_config - allocate a new +// configuration object +//------------------------------------------------- + +device_config *bsmt2000_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) { - sound_stream *stream; /* which stream are we using */ - UINT8 last_register; /* last register address written */ - - INT8 * region_base; /* pointer to the base of the region */ - int total_banks; /* number of total banks in the region */ - - bsmt2000_voice voice[MAX_VOICES]; /* the voices */ - UINT16 * regmap[128]; /* mapping of registers to voice params */ - UINT8 mode; /* current mode */ - - UINT32 clock; /* original clock on the chip */ - UINT8 stereo; /* stereo output? */ - UINT8 voices; /* number of voices */ - UINT8 adpcm; /* adpcm enabled? */ - - INT32 adpcm_current; /* current ADPCM sample */ - INT32 adpcm_delta_n; /* current ADPCM scale factor */ -}; + return global_alloc(bsmt2000_device_config(mconfig, tag, owner, clock)); +} +//------------------------------------------------- +// alloc_device - allocate a new device object +//------------------------------------------------- -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* core implementation */ -static STREAM_UPDATE( bsmt2000_update ); - -/* local functions */ -static void set_mode(bsmt2000_chip *chip); -static void set_regmap(bsmt2000_chip *chip, UINT8 posbase, UINT8 ratebase, UINT8 endbase, UINT8 loopbase, UINT8 bankbase, UINT8 rvolbase, UINT8 lvolbase); - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -INLINE bsmt2000_chip *get_safe_token(device_t *device) +device_t *bsmt2000_device_config::alloc_device(running_machine &machine) const { - assert(device != NULL); - assert(device->type() == BSMT2000); - return (bsmt2000_chip *)downcast(device)->token(); + return auto_alloc(&machine, bsmt2000_device(machine, *this)); +} + + +//------------------------------------------------- +// static_set_pin7 - configuration helper to set +// the pin 7 state +//------------------------------------------------- + +void bsmt2000_device_config::static_set_ready_callback(device_config *device, ready_callback callback) +{ + bsmt2000_device_config *bsmt = downcast(device); + bsmt->m_ready_callback = callback; +} + + +//------------------------------------------------- +// rom_region - return a pointer to the device's +// internal ROM region +//------------------------------------------------- + +const rom_entry *bsmt2000_device_config::rom_region() const +{ + return ROM_NAME( bsmt2000 ); +} + + +//------------------------------------------------- +// machine_config_additions - return a pointer to +// the device's machine fragment +//------------------------------------------------- + +machine_config_constructor bsmt2000_device_config::machine_config_additions() const +{ + return MACHINE_CONFIG_NAME( bsmt2000 ); +} + + +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +const address_space_config *bsmt2000_device_config::memory_space_config(int spacenum) const +{ + return (spacenum == 0) ? &m_space_config : NULL; } -/*************************************************************************** - CORE IMPLEMENTATION -***************************************************************************/ +//************************************************************************** +// LIVE DEVICE +//************************************************************************** -/*------------------------------------------------- - bsmt2000_postload - save-state load callback --------------------------------------------------*/ +//------------------------------------------------- +// bsmt2000_device - constructor +//------------------------------------------------- -static STATE_POSTLOAD( bsmt2000_postload ) +bsmt2000_device::bsmt2000_device(running_machine &_machine, const bsmt2000_device_config &config) + : device_t(_machine, config), + device_sound_interface(_machine, config, *this), + device_memory_interface(_machine, config, *this), + m_config(config), + m_stream(NULL), + m_direct(NULL), + m_cpu(NULL), + m_register_select(0), + m_write_data(0), + m_rom_address(0), + m_rom_bank(0), + m_left_data(0), + m_right_data(0), + m_write_pending(false) { - bsmt2000_chip *chip = (bsmt2000_chip*)param; - set_mode(chip); } -/*------------------------------------------------- - DEVICE_START( bsmt2000 ) - initialization callback --------------------------------------------------*/ +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- -static DEVICE_START( bsmt2000 ) +void bsmt2000_device::device_start() { - bsmt2000_chip *chip = get_safe_token(device); - int voicenum; + // find our CPU + m_cpu = subdevice("bsmt2000"); - /* create a stream at a nominal sample rate (real one specified later) */ - chip->stream = stream_create(device, 0, 2, device->clock() / 1000, chip, bsmt2000_update); - chip->clock = device->clock(); + // find our direct access + m_direct = &space()->direct(); - /* initialize the regions */ - chip->region_base = *device->region(); - chip->total_banks = device->region()->bytes() / 0x10000; - - /* register chip-wide data for save states */ - state_save_register_postload(device->machine, bsmt2000_postload, chip); - state_save_register_device_item(device, 0, chip->last_register); - state_save_register_device_item(device, 0, chip->mode); - state_save_register_device_item(device, 0, chip->stereo); - state_save_register_device_item(device, 0, chip->voices); - state_save_register_device_item(device, 0, chip->adpcm); - state_save_register_device_item(device, 0, chip->adpcm_current); - state_save_register_device_item(device, 0, chip->adpcm_delta_n); - - /* register voice-specific data for save states */ - for (voicenum = 0; voicenum < MAX_VOICES; voicenum++) - { - bsmt2000_voice *voice = &chip->voice[voicenum]; - - state_save_register_device_item(device, voicenum, voice->pos); - state_save_register_device_item(device, voicenum, voice->rate); - state_save_register_device_item(device, voicenum, voice->loopend); - state_save_register_device_item(device, voicenum, voice->loopstart); - state_save_register_device_item(device, voicenum, voice->bank); - state_save_register_device_item(device, voicenum, voice->leftvol); - state_save_register_device_item(device, voicenum, voice->rightvol); - state_save_register_device_item(device, voicenum, voice->fraction); - } + // create the stream; BSMT typically runs at 24MHz and writes to a DAC, so + // in theory we should generate a 24MHz stream, but that's certainly overkill + // internally at 24MHz the max output sample rate is 32kHz + // divided by 128 gives us 6x the max output rate which is plenty for oversampling + m_stream = stream_create(this, 0, 2, clock() / 128, this, stream_update_stub); } -/*------------------------------------------------- - DEVICE_RESET( bsmt2000 ) - chip reset callback --------------------------------------------------*/ +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- -static DEVICE_RESET( bsmt2000 ) +void bsmt2000_device::device_reset() { - bsmt2000_chip *chip = get_safe_token(device); - int voicenum; - - /* reset all the voice data */ - for (voicenum = 0; voicenum < MAX_VOICES; voicenum++) - { - bsmt2000_voice *voice = &chip->voice[voicenum]; - memset(voice, 0, sizeof(*voice)); - voice->leftvol = 0x7fff; - voice->rightvol = 0x7fff; - } - - /* recompute the mode - this comes from the address of the last register accessed */ - chip->mode = chip->last_register; - set_mode(chip); + device_timer_call_after_resynch(*this, TIMER_ID_RESET); } -/*------------------------------------------------- - bsmt2000_update - update callback for - sample generation --------------------------------------------------*/ +//------------------------------------------------- +// device_timer - handle deferred writes and +// resets as a timer callback +//------------------------------------------------- -static STREAM_UPDATE( bsmt2000_update ) +void bsmt2000_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - stream_sample_t *left = outputs[0]; - stream_sample_t *right = outputs[1]; - bsmt2000_chip *chip = (bsmt2000_chip *)param; - bsmt2000_voice *voice; - int samp, voicenum; - - /* clear out the accumulator */ - memset(left, 0, samples * sizeof(left[0])); - memset(right, 0, samples * sizeof(right[0])); - - /* loop over voices */ - for (voicenum = 0; voicenum < chip->voices; voicenum++) + switch (id) { - voice = &chip->voice[voicenum]; - - /* compute the region base */ - if (voice->bank < chip->total_banks) - { - INT8 *base = &chip->region_base[voice->bank * 0x10000]; - UINT32 rate = voice->rate; - INT32 rvol = voice->rightvol; - INT32 lvol = chip->stereo ? voice->leftvol : rvol; - UINT16 pos = voice->pos; - UINT16 frac = voice->fraction; - - /* loop while we still have samples to generate */ - for (samp = 0; samp < samples; samp++) - { -#if ENABLE_INTERPOLATION - INT32 sample = (base[pos] * (0x800 - frac) + (base[pos + 1] * frac)) >> 11; -#else - INT32 sample = base[pos]; -#endif - /* apply volumes and add */ - left[samp] += sample * lvol; - right[samp] += sample * rvol; - - /* update position */ - frac += rate; - pos += frac >> 11; - frac &= 0x7ff; - - /* check for loop end */ - if (pos >= voice->loopend) - pos += voice->loopstart - voice->loopend; - } - - /* update the position */ - voice->pos = pos; - voice->fraction = frac; - } - } - - /* compressed voice (11-voice model only) */ - voice = &chip->voice[ADPCM_VOICE]; - if (chip->adpcm && voice->bank < chip->total_banks && voice->rate) - { - INT8 *base = &chip->region_base[voice->bank * 0x10000]; - INT32 rvol = voice->rightvol; - INT32 lvol = chip->stereo ? voice->leftvol : rvol; - UINT32 pos = voice->pos; - UINT32 frac = voice->fraction; - - /* loop while we still have samples to generate */ - for (samp = 0; samp < samples && pos < voice->loopend; samp++) - { - /* apply volumes and add */ - left[samp] += (chip->adpcm_current * lvol) >> 8; - right[samp] += (chip->adpcm_current * rvol) >> 8; - - /* update position */ - frac++; - if (frac == 6) - { - pos++; - frac = 0; - } - - /* every 3 samples, we update the ADPCM state */ - if (frac == 1 || frac == 4) - { - static const UINT8 delta_tab[] = { 58,58,58,58,77,102,128,154 }; - int nibble = base[pos] >> ((frac == 1) ? 4 : 0); - int value = (INT8)(nibble << 4) >> 4; - int delta; - - /* compute the delta for this sample */ - delta = chip->adpcm_delta_n * value; - if (value > 0) - delta += chip->adpcm_delta_n >> 1; - else - delta -= chip->adpcm_delta_n >> 1; - - /* add and clamp against the sample */ - chip->adpcm_current += delta; - if (chip->adpcm_current >= 32767) - chip->adpcm_current = 32767; - else if (chip->adpcm_current <= -32768) - chip->adpcm_current = -32768; - - /* adjust the delta multiplier */ - chip->adpcm_delta_n = (chip->adpcm_delta_n * delta_tab[abs(value)]) >> 6; - if (chip->adpcm_delta_n > 2000) - chip->adpcm_delta_n = 2000; - else if (chip->adpcm_delta_n < 1) - chip->adpcm_delta_n = 1; - } - } - - /* update the position */ - voice->pos = pos; - voice->fraction = frac; - - /* "rate" is a control register; clear it to 0 when done */ - if (pos >= voice->loopend) - voice->rate = 0; - } - - /* reduce the overall gain */ - for (samp = 0; samp < samples; samp++) - { - left[samp] >>= 9; - right[samp] >>= 9; - } -} - - - -/*************************************************************************** - READ/WRITE ACCESS -***************************************************************************/ - -/*------------------------------------------------- - bsmt2000_reg_write - handle a register write --------------------------------------------------*/ - -WRITE16_DEVICE_HANDLER( bsmt2000_data_w ) -{ - bsmt2000_chip *chip = get_safe_token(device); - - if (LOG_COMMANDS) mame_printf_debug("BSMT write: reg %02X = %04X\n", offset, data); - - /* remember the last write */ - chip->last_register = offset; - - /* update the register */ - if (offset < 0x80 && chip->regmap[offset] != NULL) - { - UINT16 *dest = chip->regmap[offset]; - - /* force an update, then write the data */ - stream_update(chip->stream); - *dest = data; - - /* special case: reset ADPCM parameters when writing to the ADPCM position */ - if (dest == &chip->voice[ADPCM_VOICE].rate) - { - chip->adpcm_current = 0; - chip->adpcm_delta_n = 10; - } - } -} - - - -/*************************************************************************** - LOCAL FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - set_mode - set the mode after reset --------------------------------------------------*/ - -static void set_mode(bsmt2000_chip *chip) -{ - int sample_rate; - - /* force an update */ - stream_update(chip->stream); - - switch (chip->mode) - { - /* mode 0: 24kHz, 12 channel PCM, 1 channel ADPCM, mono */ - default: - case 0: - sample_rate = chip->clock / 1000; - chip->stereo = FALSE; - chip->voices = 12; - chip->adpcm = TRUE; - set_regmap(chip, 0x00, 0x18, 0x24, 0x30, 0x3c, 0x48, 0); + // deferred reset + case TIMER_ID_RESET: + stream_update(m_stream); + m_cpu->reset(); break; - - /* mode 1: 24kHz, 11 channel PCM, 1 channel ADPCM, stereo */ - case 1: - sample_rate = chip->clock / 1000; - chip->stereo = TRUE; - chip->voices = 11; - chip->adpcm = TRUE; - set_regmap(chip, 0x00, 0x16, 0x21, 0x2c, 0x37, 0x42, 0x4d); + + // deferred register write + case TIMER_ID_REG_WRITE: + m_register_select = param & 0xffff; break; - - /* mode 5: 24kHz, 12 channel PCM, stereo */ - case 5: - sample_rate = chip->clock / 1000; - chip->stereo = TRUE; - chip->voices = 12; - chip->adpcm = FALSE; - set_regmap(chip, 0x00, 0x18, 0x24, 0x30, 0x3c, 0x54, 0x60); - break; - - /* mode 6: 34kHz, 8 channel PCM, stereo */ - case 6: - sample_rate = chip->clock / 706; - chip->stereo = TRUE; - chip->voices = 8; - chip->adpcm = FALSE; - set_regmap(chip, 0x00, 0x10, 0x18, 0x20, 0x28, 0x38, 0x40); - break; - - /* mode 7: 32kHz, 9 channel PCM, stereo */ - case 7: - sample_rate = chip->clock / 750; - chip->stereo = TRUE; - chip->voices = 9; - chip->adpcm = FALSE; - set_regmap(chip, 0x00, 0x12, 0x1b, 0x24, 0x2d, 0x3f, 0x48); + + // deferred data write + case TIMER_ID_DATA_WRITE: + m_write_data = param & 0xffff; + if (m_write_pending) logerror("BSMT2000: Missed data\n"); + m_write_pending = true; break; } - - /* update the sample rate */ - stream_set_sample_rate(chip->stream, sample_rate); } -/*------------------------------------------------- - set_regmap - initialize the register mapping --------------------------------------------------*/ +//------------------------------------------------- +// stream_generate - handle update requests for +// our sound stream +//------------------------------------------------- -static void set_regmap(bsmt2000_chip *chip, UINT8 posbase, UINT8 ratebase, UINT8 endbase, UINT8 loopbase, UINT8 bankbase, UINT8 rvolbase, UINT8 lvolbase) +void bsmt2000_device::stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - int voice; - - /* reset the map */ - memset(chip->regmap, 0, sizeof(chip->regmap)); - - /* iterate over voices */ - for (voice = 0; voice < chip->voices; voice++) + // just fill with current left/right values + for (int samp = 0; samp < samples; samp++) { - chip->regmap[posbase + voice] = &chip->voice[voice].pos; - chip->regmap[ratebase + voice] = &chip->voice[voice].rate; - chip->regmap[endbase + voice] = &chip->voice[voice].loopend; - chip->regmap[loopbase + voice] = &chip->voice[voice].loopstart; - chip->regmap[bankbase + voice] = &chip->voice[voice].bank; - chip->regmap[rvolbase + voice] = &chip->voice[voice].rightvol; - if (chip->stereo) - chip->regmap[lvolbase + voice] = &chip->voice[voice].leftvol; - } - - /* set the ADPCM register */ - if (chip->adpcm) - { - chip->regmap[0x6d] = &chip->voice[ADPCM_VOICE].loopend; - chip->regmap[0x6f] = &chip->voice[ADPCM_VOICE].bank; - chip->regmap[0x73] = &chip->voice[ADPCM_VOICE].rate; - chip->regmap[0x74] = &chip->voice[ADPCM_VOICE].rightvol; - chip->regmap[0x75] = &chip->voice[ADPCM_VOICE].pos; - if (chip->stereo) - chip->regmap[0x76] = &chip->voice[ADPCM_VOICE].leftvol; + outputs[0][samp] = m_left_data * 16; + outputs[1][samp] = m_right_data * 16; } } +//------------------------------------------------- +// read_status - return the write pending status +//------------------------------------------------- -/*************************************************************************** - GET/SET INFO CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - DEVICE_GET_INFO( bsmt2000 ) - callback for - retrieving chip information --------------------------------------------------*/ - -DEVICE_GET_INFO( bsmt2000 ) +UINT16 bsmt2000_device::read_status() { - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(bsmt2000_chip); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( bsmt2000 ); break; - case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( bsmt2000 ); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_NAME: strcpy(info->s, "BSMT2000"); break; - case DEVINFO_STR_FAMILY: strcpy(info->s, "Data East Wavetable"); break; - case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break; - } + return m_write_pending ? 0 : 1; } -DEFINE_LEGACY_SOUND_DEVICE(BSMT2000, bsmt2000); +//------------------------------------------------- +// write_reg - handle writes to the BSMT2000 +// register select interface +//------------------------------------------------- + +void bsmt2000_device::write_reg(UINT16 data) +{ + device_timer_call_after_resynch(*this, TIMER_ID_REG_WRITE, data); +} + + +//------------------------------------------------- +// write_data - handle writes to the BSMT2000 +// data port +//------------------------------------------------- + +void bsmt2000_device::write_data(UINT16 data) +{ + device_timer_call_after_resynch(*this, TIMER_ID_DATA_WRITE, data); + + // boost the interleave on a write so that the caller detects the status more accurately + m_machine.scheduler().boost_interleave(ATTOTIME_IN_USEC(1), ATTOTIME_IN_USEC(10)); +} + + +//------------------------------------------------- +// tms_register_r - return the value written to +// the register select port +//------------------------------------------------- + +READ16_MEMBER( bsmt2000_device::tms_register_r ) +{ + return m_register_select; +} + + +//------------------------------------------------- +// tms_data_r - return the value written to the +// data port +//------------------------------------------------- + +READ16_MEMBER( bsmt2000_device::tms_data_r ) +{ + // also implicitly clear the write pending flag + m_write_pending = false; + if (m_config.m_ready_callback != NULL) + (*m_config.m_ready_callback)(*this); + return m_write_data; +} + + +//------------------------------------------------- +// tms_rom_r - read a byte from the currently +// selected ROM bank and address +//------------------------------------------------- + +READ16_MEMBER( bsmt2000_device::tms_rom_r ) +{ + // underlying logic assumes this is a sign-extended value + return (INT8)m_direct->read_raw_byte((m_rom_bank << 16) + m_rom_address); +} + + +//------------------------------------------------- +// tms_rom_addr_w - selects which byte within the +// current ROM bank to access +//------------------------------------------------- + +WRITE16_MEMBER( bsmt2000_device::tms_rom_addr_w ) +{ + m_rom_address = data; +} + + +//------------------------------------------------- +// tms_rom_bank_w - selects which bank of ROM to +// access +//------------------------------------------------- + +WRITE16_MEMBER( bsmt2000_device::tms_rom_bank_w ) +{ + m_rom_bank = data; +} + + +//------------------------------------------------- +// tms_left_w - handle writes to the left channel +// DAC +//------------------------------------------------- + +WRITE16_MEMBER( bsmt2000_device::tms_left_w ) +{ + stream_update(m_stream); + m_left_data = data; +} + + +//------------------------------------------------- +// tms_right_w - handle writes to the right +// channel DAC +//------------------------------------------------- + +WRITE16_MEMBER( bsmt2000_device::tms_right_w ) +{ + stream_update(m_stream); + m_right_data = data; +} + + +//------------------------------------------------- +// tms_write_pending_r - return whether a write +// is pending; this data is fed into the BIO line +// on the TMS32015 +//------------------------------------------------- + +READ16_MEMBER( bsmt2000_device::tms_write_pending_r ) +{ + return m_write_pending ? 1 : 0; +} diff --git a/src/emu/sound/bsmt2000.h b/src/emu/sound/bsmt2000.h index acd37756687..9076d93571b 100644 --- a/src/emu/sound/bsmt2000.h +++ b/src/emu/sound/bsmt2000.h @@ -1,19 +1,172 @@ -/********************************************************************************************** - * - * BSMT2000 driver - * by Aaron Giles - * - **********************************************************************************************/ +/*************************************************************************** + + bsmt2000.h + + BSMT2000 device emulator. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ #pragma once #ifndef __BSMT2000_H__ #define __BSMT2000_H__ -#include "devlegcy.h" +#include "cpu/tms32010/tms32010.h" -WRITE16_DEVICE_HANDLER( bsmt2000_data_w ); -DECLARE_LEGACY_SOUND_DEVICE(BSMT2000, bsmt2000); +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_BSMT2000_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, BSMT2000, _clock) \ + +#define MCFG_BSMT2000_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, BSMT2000, _clock) \ + +#define MCFG_BSMT2000_READY_CALLBACK(_callback) \ + bsmt2000_device_config::static_set_ready_callback(device, _callback); \ + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bsmt2000_device; + + +// ======================> bsmt2000_device_config + +class bsmt2000_device_config : public device_config, + public device_config_sound_interface, + public device_config_memory_interface +{ + friend class bsmt2000_device; + + typedef void (*ready_callback)(bsmt2000_device &device); + + // construction/destruction + bsmt2000_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; + + // inline configuration helpers + static void static_set_ready_callback(device_config *device, ready_callback callback); + + // optional information overrides + virtual const rom_entry *rom_region() const; + virtual machine_config_constructor machine_config_additions() const; + +protected: + // device_config overrides + virtual const address_space_config *memory_space_config(int spacenum = 0) const; + + // internal state + const address_space_config m_space_config; + + // inline data + ready_callback m_ready_callback; +}; + + + +// ======================> bsmt2000_device + +class bsmt2000_device : public device_t, + public device_sound_interface, + public device_memory_interface +{ + friend class bsmt2000_device_config; + + // construction/destruction + bsmt2000_device(running_machine &_machine, const bsmt2000_device_config &config); + +public: + UINT16 read_status(); + void write_reg(UINT16 data); + void write_data(UINT16 data); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // internal callbacks + void stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + // internal TMS I/O callbacks + DECLARE_READ16_MEMBER( tms_register_r ); + DECLARE_READ16_MEMBER( tms_data_r ); + DECLARE_READ16_MEMBER( tms_rom_r ); + DECLARE_WRITE16_MEMBER( tms_rom_addr_w ); + DECLARE_WRITE16_MEMBER( tms_rom_bank_w ); + DECLARE_WRITE16_MEMBER( tms_left_w ); + DECLARE_WRITE16_MEMBER( tms_right_w ); + DECLARE_READ16_MEMBER( tms_write_pending_r ); + +private: + // timers + enum + { + TIMER_ID_RESET, + TIMER_ID_REG_WRITE, + TIMER_ID_DATA_WRITE + }; + + // internal state + const bsmt2000_device_config &m_config; + sound_stream * m_stream; + direct_read_data * m_direct; + tms32015_device * m_cpu; + UINT16 m_register_select; + UINT16 m_write_data; + UINT16 m_rom_address; + UINT16 m_rom_bank; + INT16 m_left_data; + INT16 m_right_data; + bool m_write_pending; +}; + + +// device type definition +extern const device_type BSMT2000; + #endif /* __BSMT2000_H__ */ diff --git a/src/emu/streams.h b/src/emu/streams.h index 263c22ae6e4..2c0aabf602f 100644 --- a/src/emu/streams.h +++ b/src/emu/streams.h @@ -33,6 +33,13 @@ typedef void (*stream_update_func)(device_t *device, void *param, stream_sample_ #define STREAM_UPDATE(name) void name(device_t *device, void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +template +void stream_update_stub(device_t *device, void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + T *target = downcast(device); + (target->*func)(inputs, outputs, samples); +} + /*************************************************************************** diff --git a/src/mame/drivers/btoads.c b/src/mame/drivers/btoads.c index 5c00f6c7521..9a5481d2473 100644 --- a/src/mame/drivers/btoads.c +++ b/src/mame/drivers/btoads.c @@ -158,15 +158,16 @@ static WRITE8_HANDLER( sound_int_state_w ) static READ8_HANDLER( bsmt_ready_r ) { - return 0x80; + bsmt2000_device *bsmt = space->machine->device("bsmt"); + return bsmt->read_status() << 7; } -static WRITE8_DEVICE_HANDLER( bsmt2000_port_w ) +static WRITE8_HANDLER( bsmt2000_port_w ) { - UINT16 reg = offset >> 8; - UINT16 val = ((offset & 0xff) << 8) | data; - bsmt2000_data_w(device, reg, val, 0xffff); + bsmt2000_device *bsmt = space->machine->device("bsmt"); + bsmt->write_reg(offset >> 8); + bsmt->write_data(((offset & 0xff) << 8) | data); } @@ -219,7 +220,7 @@ static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) ADDRESS_MAP_END static ADDRESS_MAP_START( sound_io_map, ADDRESS_SPACE_IO, 8 ) - AM_RANGE(0x0000, 0x7fff) AM_DEVWRITE("bsmt", bsmt2000_port_w) + AM_RANGE(0x0000, 0x7fff) AM_WRITE(bsmt2000_port_w) AM_RANGE(0x8000, 0x8000) AM_READWRITE(sound_data_r, sound_data_w) AM_RANGE(0x8002, 0x8002) AM_WRITE(sound_int_state_w) AM_RANGE(0x8004, 0x8004) AM_READ(sound_data_ready_r) @@ -359,7 +360,7 @@ static MACHINE_CONFIG_START( btoads, driver_device ) /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("bsmt", BSMT2000, SOUND_CLOCK) + MCFG_BSMT2000_ADD("bsmt", SOUND_CLOCK) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END @@ -380,7 +381,7 @@ ROM_START( btoads ) ROM_LOAD32_WORD( "btc0-p0.u120", 0x000000, 0x400000, CRC(0dfd1e35) SHA1(733a0a4235bebd598c600f187ed2628f28cf9bd0) ) ROM_LOAD32_WORD( "btc0-p1.u121", 0x000002, 0x400000, CRC(df7487e1) SHA1(67151b900767bb2653b5261a98c81ff8827222c3) ) - ROM_REGION( 0x200000, "bsmt", 0 ) /* BSMT data, M27C160 rom */ + ROM_REGION( 0x1000000, "bsmt", 0 ) /* BSMT data, M27C160 rom */ ROM_LOAD( "btc0-s.u109", 0x00000, 0x200000, CRC(d9612ddb) SHA1(f186dfb013e81abf81ba8ac5dc7eb731c1ad82b6) ) ROM_REGION( 0x080a, "plds", 0 ) diff --git a/src/mame/drivers/dcheese.c b/src/mame/drivers/dcheese.c index 5b7f6f7042e..33f1ebacade 100644 --- a/src/mame/drivers/dcheese.c +++ b/src/mame/drivers/dcheese.c @@ -171,7 +171,8 @@ static READ8_HANDLER( sound_command_r ) static READ8_HANDLER( sound_status_r ) { /* seems to be ready signal on BSMT or latching hardware */ - return 0x80; + bsmt2000_device *bsmt = space->machine->device("bsmt"); + return bsmt->read_status() << 7; } @@ -190,15 +191,19 @@ static WRITE8_HANDLER( sound_control_w ) } -static WRITE8_DEVICE_HANDLER( bsmt_data_w ) +static WRITE8_HANDLER( bsmt_data_w ) { - dcheese_state *state = device->machine->driver_data(); + dcheese_state *state = space->machine->driver_data(); + bsmt2000_device *bsmt = space->machine->device("bsmt"); /* writes come in pairs; even bytes latch, odd bytes write */ if (offset % 2 == 0) + { + bsmt->write_reg(offset / 2); state->sound_msb_latch = data; + } else - bsmt2000_data_w(device, offset / 2, (state->sound_msb_latch << 8) | data, 0xffff); + bsmt->write_data((state->sound_msb_latch << 8) | data); } @@ -235,7 +240,7 @@ static ADDRESS_MAP_START( sound_cpu_map, ADDRESS_SPACE_PROGRAM, 8 ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x07ff) AM_READWRITE(sound_status_r, sound_control_w) AM_RANGE(0x0800, 0x0fff) AM_READ(sound_command_r) - AM_RANGE(0x1000, 0x10ff) AM_MIRROR(0x0700) AM_DEVWRITE("bsmt", bsmt_data_w) + AM_RANGE(0x1000, 0x10ff) AM_MIRROR(0x0700) AM_WRITE(bsmt_data_w) AM_RANGE(0x1800, 0x1fff) AM_RAM AM_RANGE(0x2000, 0xffff) AM_ROM ADDRESS_MAP_END @@ -437,7 +442,7 @@ static MACHINE_CONFIG_START( dcheese, dcheese_state ) /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("bsmt", BSMT2000, SOUND_OSC) + MCFG_BSMT2000_ADD("bsmt", SOUND_OSC) MCFG_SOUND_ROUTE(0, "lspeaker", 1.2) MCFG_SOUND_ROUTE(1, "rspeaker", 1.2) MACHINE_CONFIG_END @@ -480,7 +485,7 @@ ROM_START( dcheese ) ROM_LOAD( "dchez.127", 0x40000, 0x40000, CRC(372f9d67) SHA1(74f73f0344bfb890b5e457fcde3d82c9106e7edd) ) ROM_LOAD( "dchez.125", 0x80000, 0x40000, CRC(ddf28bab) SHA1(0f3bc86d0db7afebf8c6094b8337e5f343a82f29) ) - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "dchez.ar0", 0x000000, 0x40000, CRC(6a9e2b12) SHA1(f7cb4d6b4a459682a68f734b2b2e27e3639b9ed5) ) ROM_RELOAD( 0x040000, 0x40000 ) ROM_RELOAD( 0x080000, 0x40000 ) @@ -526,7 +531,7 @@ ROM_START( lottof2 ) ROM_LOAD( "u125.r10", 0x80000, 0x40000, CRC(c70cf1c6) SHA1(eb5f0c5f7485d92ce569ad915b9f5c3c48338172) ) ROM_LOAD( "u129.r10", 0xc0000, 0x40000, CRC(e9c9e4b0) SHA1(02a3bc279e2489fd53f9a08df5f1023f75fff4d1) ) - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0.r10", 0x000000, 0x40000, CRC(05e7581b) SHA1(e12be200abfbef269fc085d6c5efea106487e05f) ) ROM_RELOAD( 0x040000, 0x40000 ) ROM_RELOAD( 0x080000, 0x40000 ) @@ -576,7 +581,7 @@ ROM_START( fredmem ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.129", 0x180000, 0x80000, CRC(d5715a02) SHA1(b7d9d29f2fc5d74adff1fefce312e6472c0f7565) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -609,7 +614,7 @@ ROM_START( fredmemus ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.129", 0x180000, 0x80000, CRC(d5715a02) SHA1(b7d9d29f2fc5d74adff1fefce312e6472c0f7565) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -641,7 +646,7 @@ ROM_START( fredmemuk ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.129", 0x180000, 0x80000, CRC(d5715a02) SHA1(b7d9d29f2fc5d74adff1fefce312e6472c0f7565) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -674,7 +679,7 @@ ROM_START( fredmemj ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom_japan.129", 0x180000, 0x80000, CRC(aaaddc7b) SHA1(27e4d31a904a451249affda2226c6556e24bfaf6) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -706,7 +711,7 @@ ROM_START( fredmemc ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.129.mandarin", 0x180000, 0x80000, CRC(31444b3f) SHA1(dd3930fd784e685a05b7fc8039e6542710861ae5) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -738,7 +743,7 @@ ROM_START( fredmesp ) ROM_LOAD( "art-rom.127", 0x100000, 0x80000, CRC(93095f3b) SHA1(de746829e04bf153024e94e6ef0ceffb1eae2b14) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.129.spanish", 0x180000, 0x80000, CRC(8f0fa246) SHA1(10eef16f41c82224d369fd6b7c2fa9212e22fb42) ) /* Graphics / Art at U129 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x80000, CRC(3b85ea34) SHA1(0a68e7df20a2c36e230c7935415dd5068c338669) ) ROM_RELOAD( 0x080000, 0x80000 ) ROM_LOAD( "arom1", 0x100000, 0x80000, CRC(405df3d4) SHA1(190b928789a879408beadd1647136bd85b018c63) ) @@ -771,7 +776,7 @@ ROM_START( cecmatch ) ROM_LOAD( "art-rom.127", 0x040000, 0x40000, CRC(dc9be2ca) SHA1(d5059a49a3aad309e242c9c4791d10aa5ecd5d1a) ) /* Graphics / Art at U127 */ ROM_LOAD( "art-rom.125", 0x080000, 0x40000, CRC(7abe18d9) SHA1(c5a582ded7c1b0a02847b342111c64ac0ccb70c2) ) /* Graphics / Art at U125 */ - ROM_REGION( 0x400000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "arom0", 0x000000, 0x40000, CRC(82129830) SHA1(2fa3a32ac4f81dd9c2ab11f34257df4074447f3a)) ROM_RELOAD( 0x040000, 0x40000 ) ROM_RELOAD( 0x080000, 0x40000 ) diff --git a/src/mame/drivers/deco32.c b/src/mame/drivers/deco32.c index aaa326964cd..23a78dad5a9 100644 --- a/src/mame/drivers/deco32.c +++ b/src/mame/drivers/deco32.c @@ -965,15 +965,23 @@ static WRITE8_HANDLER(deco32_bsmt0_w) bsmt_latch = data; } -static WRITE8_DEVICE_HANDLER(deco32_bsmt1_w) +static void bsmt_ready_callback(bsmt2000_device &device) { - bsmt2000_data_w(device, offset^ 0xff, ((bsmt_latch << 8) | data), 0xffff); - cputag_set_input_line(device->machine, "audiocpu", M6809_IRQ_LINE, HOLD_LINE); /* BSMT is ready */ + cputag_set_input_line(device.machine, "audiocpu", M6809_IRQ_LINE, ASSERT_LINE); /* BSMT is ready */ +} + +static WRITE8_HANDLER(deco32_bsmt1_w) +{ + bsmt2000_device *bsmt = space->machine->device("bsmt"); + bsmt->write_reg(offset ^ 0xff); + bsmt->write_data((bsmt_latch << 8) | data); + cputag_set_input_line(space->machine, "audiocpu", M6809_IRQ_LINE, CLEAR_LINE); /* BSMT is not ready */ } static READ8_HANDLER(deco32_bsmt_status_r) { - return 0x80; + bsmt2000_device *bsmt = space->machine->device("bsmt"); + return bsmt->read_status() << 7; } static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) @@ -993,7 +1001,7 @@ static ADDRESS_MAP_START( tattass_sound_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x2002, 0x2003) AM_READ(soundlatch_r) AM_RANGE(0x2006, 0x2007) AM_READ(deco32_bsmt_status_r) AM_RANGE(0x6000, 0x6000) AM_WRITE(deco32_bsmt0_w) - AM_RANGE(0xa000, 0xa0ff) AM_DEVWRITE("bsmt", deco32_bsmt1_w) + AM_RANGE(0xa000, 0xa0ff) AM_WRITE(deco32_bsmt1_w) AM_RANGE(0x2000, 0xffff) AM_ROM ADDRESS_MAP_END @@ -1925,7 +1933,8 @@ static MACHINE_CONFIG_START( tattass, driver_device ) /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("bsmt", BSMT2000, 24000000) + MCFG_BSMT2000_ADD("bsmt", 24000000) + MCFG_BSMT2000_READY_CALLBACK(bsmt_ready_callback) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END @@ -2781,7 +2790,7 @@ ROM_START( tattass ) ROM_LOAD32_BYTE( "ob2_c2.b3", 0x600000, 0x80000, CRC(90fe5f4f) SHA1(2149e9eae152556c632ebd4d0b2de49e40916a77) ) ROM_LOAD32_BYTE( "ob2_c3.b3", 0x600002, 0x80000, CRC(e3517e6e) SHA1(68ac60570423d8f0d7cff3db1901c9c050d0be91) ) - ROM_REGION(0x200000, "bsmt", 0 ) + ROM_REGION(0x1000000, "bsmt", 0 ) ROM_LOAD( "u17.snd", 0x000000, 0x80000, CRC(b945c18d) SHA1(6556bbb4a7057df3680132f24687fa944006c784) ) ROM_LOAD( "u21.snd", 0x080000, 0x80000, CRC(10b2110c) SHA1(83e5938ed22da2874022e1dc8df76c72d95c448d) ) ROM_LOAD( "u36.snd", 0x100000, 0x80000, CRC(3b73abe2) SHA1(195096e2302e84123b23b4ccd982fb3ab9afe42c) ) @@ -2854,7 +2863,7 @@ ROM_START( tattassa ) ROM_LOAD32_BYTE( "ob2_c2.b3", 0x600000, 0x80000, CRC(90fe5f4f) SHA1(2149e9eae152556c632ebd4d0b2de49e40916a77) ) ROM_LOAD32_BYTE( "ob2_c3.b3", 0x600002, 0x80000, CRC(e3517e6e) SHA1(68ac60570423d8f0d7cff3db1901c9c050d0be91) ) - ROM_REGION(0x200000, "bsmt", 0 ) + ROM_REGION(0x1000000, "bsmt", 0 ) ROM_LOAD( "u17.snd", 0x000000, 0x80000, CRC(b945c18d) SHA1(6556bbb4a7057df3680132f24687fa944006c784) ) ROM_LOAD( "u21.snd", 0x080000, 0x80000, CRC(10b2110c) SHA1(83e5938ed22da2874022e1dc8df76c72d95c448d) ) ROM_LOAD( "u36.snd", 0x100000, 0x80000, CRC(3b73abe2) SHA1(195096e2302e84123b23b4ccd982fb3ab9afe42c) ) diff --git a/src/mame/drivers/policetr.c b/src/mame/drivers/policetr.c index c69f367dd8a..037a255367d 100644 --- a/src/mame/drivers/policetr.c +++ b/src/mame/drivers/policetr.c @@ -101,7 +101,6 @@ UINT32 * policetr_rambase; /* local variables */ static UINT32 control_data; -static UINT32 bsmt_reg; static UINT32 bsmt_data_bank; static UINT32 bsmt_data_offset; @@ -164,9 +163,8 @@ static WRITE32_HANDLER( control_w ) /* toggling BSMT off then on causes a reset */ if (!(old & 0x80000000) && (control_data & 0x80000000)) { - device_t *device = space->machine->device("bsmt"); - bsmt2000_data_w(device, bsmt_data_bank, 0, 0xffff); - device->reset(); + bsmt2000_device *bsmt = space->machine->device("bsmt"); + bsmt->reset(); } /* log any unknown bits */ @@ -182,10 +180,10 @@ static WRITE32_HANDLER( control_w ) * *************************************/ -static WRITE32_DEVICE_HANDLER( policetr_bsmt2000_reg_w ) +static WRITE32_HANDLER( policetr_bsmt2000_reg_w ) { if (control_data & 0x80000000) - bsmt2000_data_w(device, bsmt_reg, data & 0xffff, mem_mask & 0xffff); + space->machine->device("bsmt")->write_data(data); else COMBINE_DATA(&bsmt_data_offset); } @@ -193,10 +191,14 @@ static WRITE32_DEVICE_HANDLER( policetr_bsmt2000_reg_w ) static WRITE32_HANDLER( policetr_bsmt2000_data_w ) { - if (control_data & 0x80000000) - COMBINE_DATA(&bsmt_reg); - else - COMBINE_DATA(&bsmt_data_bank); + space->machine->device("bsmt")->write_reg(data); + COMBINE_DATA(&bsmt_data_bank); +} + + +static CUSTOM_INPUT( bsmt_status_r ) +{ + return field->port->machine->device("bsmt")->read_status(); } @@ -271,7 +273,7 @@ static ADDRESS_MAP_START( policetr_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x00400000, 0x00400003) AM_READ(policetr_video_r) AM_RANGE(0x00500000, 0x00500003) AM_WRITENOP // copies ROM here at startup, plus checksum AM_RANGE(0x00600000, 0x00600003) AM_READ(bsmt2000_data_r) - AM_RANGE(0x00700000, 0x00700003) AM_DEVWRITE("bsmt", policetr_bsmt2000_reg_w) + AM_RANGE(0x00700000, 0x00700003) AM_WRITE(policetr_bsmt2000_reg_w) AM_RANGE(0x00800000, 0x00800003) AM_WRITE(policetr_bsmt2000_data_w) AM_RANGE(0x00900000, 0x00900003) AM_WRITE(policetr_palette_offset_w) AM_RANGE(0x00920000, 0x00920003) AM_WRITE(policetr_palette_data_w) @@ -292,7 +294,7 @@ static ADDRESS_MAP_START( sshooter_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x00400000, 0x00400003) AM_READ(policetr_video_r) AM_RANGE(0x00500000, 0x00500003) AM_WRITENOP // copies ROM here at startup, plus checksum AM_RANGE(0x00600000, 0x00600003) AM_READ(bsmt2000_data_r) - AM_RANGE(0x00700000, 0x00700003) AM_DEVWRITE("bsmt", policetr_bsmt2000_reg_w) + AM_RANGE(0x00700000, 0x00700003) AM_WRITE(policetr_bsmt2000_reg_w) AM_RANGE(0x00800000, 0x0080000f) AM_WRITE(policetr_video_w) AM_RANGE(0x00a00000, 0x00a00003) AM_WRITE(control_w) AM_RANGE(0x00a00000, 0x00a00003) AM_READ_PORT("IN0") @@ -337,7 +339,7 @@ static INPUT_PORTS_START( policetr ) PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_SERVICE( 0x00200000, IP_ACTIVE_LOW ) /* Not actually a dipswitch */ PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x00800000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(bsmt_status_r, NULL) PORT_BIT( 0x01000000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x02000000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x04000000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) @@ -452,7 +454,7 @@ static MACHINE_CONFIG_START( policetr, driver_device ) /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("bsmt", BSMT2000, MASTER_CLOCK/2) + MCFG_BSMT2000_ADD("bsmt", MASTER_CLOCK/2) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END @@ -486,7 +488,7 @@ ROM_START( policetr ) /* Rev 0.3 PCB , with all chips dated 04/01/97 */ ROM_LOAD32_BYTE( "pt-u111.bin", 0x00002, 0x20000, CRC(fb5ce933) SHA1(4a07ac3e2d86262061092f112cab89f8660dce3d) ) ROM_LOAD32_BYTE( "pt-u110.bin", 0x00003, 0x20000, CRC(40bd6f60) SHA1(156000d3c439eab45962f0a2681bd806a17f47ee) ) - ROM_REGION( 0x600000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "pt-u160.bin", 0x000000, 0x100000, CRC(f267f813) SHA1(ae58507947fe2e9701b5df46565fd9908e2f9d77) ) ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "pt-u162.bin", 0x100000, 0x100000, CRC(75fe850e) SHA1(ab8cf24ae6e5cf80f6a9a34e46f2b1596879643b) ) @@ -507,7 +509,7 @@ ROM_START( policetr11 ) /* Rev 0.3 PCB with all chips dated 01/06/97 */ ROM_LOAD32_BYTE( "pt-u111.v11", 0x00002, 0x20000, CRC(da6c45a7) SHA1(471bd372d2ad5bcb29af19dae09f3cfab4b010fd) ) ROM_LOAD32_BYTE( "pt-u110.v11", 0x00003, 0x20000, CRC(f1c8a8c0) SHA1(8a2d1ada002be6f2a3c2d21d193e7cde6531545a) ) - ROM_REGION( 0x600000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "pt-u160.bin", 0x000000, 0x100000, CRC(f267f813) SHA1(ae58507947fe2e9701b5df46565fd9908e2f9d77) ) ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "pt-u162.bin", 0x100000, 0x100000, CRC(75fe850e) SHA1(ab8cf24ae6e5cf80f6a9a34e46f2b1596879643b) ) @@ -533,7 +535,7 @@ ROM_START( policetr10 ) /* Rev 0.2 PCB with all chips dated 10/07/96 */ ROM_LOAD32_BYTE( "pt-u111.v10", 0x00002, 0x20000, CRC(61f79667) SHA1(25298cd8706b5c59f7c9e0f8d44db0df73c23403) ) ROM_LOAD32_BYTE( "pt-u110.v10", 0x00003, 0x20000, CRC(5c3c1548) SHA1(aab977274ecff7cb5fd540a3d0da7940e9707906) ) - ROM_REGION( 0x600000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) /* Same data as the other sets, but split in 4 meg roms */ ROM_LOAD( "pt-u160.v10", 0x000000, 0x080000, CRC(cd374405) SHA1(e53689d4344c78c3faac22747ada28bc3add8c56) ) ROM_RELOAD( 0x3f8000, 0x080000 ) @@ -569,7 +571,7 @@ Note: With this version, the program roms are twice the size of those found on a ROM_LOAD32_BYTE( "pt-av13.u111", 0x00002, 0x40000, CRC(8c4f3a64) SHA1(4953e6fc26bae7d6e7c7230f4ca76e3f5032af14) ) /* Checksum printed on label F343 */ ROM_LOAD32_BYTE( "pt-av13.u110", 0x00003, 0x40000, CRC(738a8277) SHA1(423a9bcecb82959f38ae79a0728d72eb13ed93b3) ) /* Checksum printed on label 050C */ - ROM_REGION( 0x600000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "pt-u160.bin", 0x000000, 0x100000, CRC(f267f813) SHA1(ae58507947fe2e9701b5df46565fd9908e2f9d77) ) ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "pt-u162.bin", 0x100000, 0x100000, CRC(75fe850e) SHA1(ab8cf24ae6e5cf80f6a9a34e46f2b1596879643b) ) @@ -597,7 +599,7 @@ Note: If you set the dipswitch to service mode and reset the game within Mame. A ROM_LOAD32_BYTE( "ptb-u111.v13", 0x00002, 0x20000, CRC(39e96d6a) SHA1(efe6ffe70432b94c98f3d7247408a6d2f6f9e33d) ) /* Checksum printed on label E5F1 */ ROM_LOAD32_BYTE( "ptb-u110.v13", 0x00003, 0x20000, CRC(d7e6f4cb) SHA1(9dffe4937bc5cf47d870f06ae0dced362cd2dd66) ) /* Checksum printed on label 556D */ - ROM_REGION( 0x600000, "bsmt", 0 ) + ROM_REGION( 0x1000000, "bsmt", 0 ) ROM_LOAD( "pt-u160.bin", 0x000000, 0x100000, CRC(f267f813) SHA1(ae58507947fe2e9701b5df46565fd9908e2f9d77) ) ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "pt-u162.bin", 0x100000, 0x100000, CRC(75fe850e) SHA1(ab8cf24ae6e5cf80f6a9a34e46f2b1596879643b) ) @@ -622,7 +624,7 @@ ROM_START( sshooter ) /* Rev 0.5B PCB , unknown program rom date */ ROM_LOAD32_BYTE( "ss-u111.v17", 0x00002, 0x40000, CRC(4240fa2f) SHA1(54223207c1e228d6b836918601c0f65c2692e5bc) ) // 1:3 ROM_LOAD32_BYTE( "ss-u110.v17", 0x00003, 0x40000, CRC(8ae744ce) SHA1(659cd27865cf5507aae6b064c5bc24b927cf5f5a) ) // 1:4 - ROM_REGION( 0x600000, "bsmt", 0 ) /* Sound v1.2 */ + ROM_REGION( 0x1000000, "bsmt", 0 ) /* Sound v1.2 */ ROM_LOAD( "ss-u160.bin", 0x000000, 0x100000, CRC(1c603d42) SHA1(880992871be52129684052d542946de0cc32ba9a) ) // 1:1 ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "ss-u162.bin", 0x100000, 0x100000, CRC(40ef448a) SHA1(c96f7b169be2576e9f3783af84c07259efefb812) ) // 2:1 @@ -647,7 +649,7 @@ ROM_START( sshooter12 ) /* Rev 0.5B PCB , program roms dated 04/17/98 */ ROM_LOAD32_BYTE( "ss-u111.v12", 0x00002, 0x40000, CRC(0b291731) SHA1(bd04f0b1b52198344df625fcddfc6c6ccb0bd923) ) // 1:3 ROM_LOAD32_BYTE( "ss-u110.v12", 0x00003, 0x40000, CRC(76841008) SHA1(ccbb88c8d63bf929814144a9d8757c9c7048fdef) ) // 1:4 - ROM_REGION( 0x600000, "bsmt", 0 ) /* Sound v1.2 */ + ROM_REGION( 0x1000000, "bsmt", 0 ) /* Sound v1.2 */ ROM_LOAD( "ss-u160.bin", 0x000000, 0x100000, CRC(1c603d42) SHA1(880992871be52129684052d542946de0cc32ba9a) ) // 1:1 ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "ss-u162.bin", 0x100000, 0x100000, CRC(40ef448a) SHA1(c96f7b169be2576e9f3783af84c07259efefb812) ) // 2:1 @@ -672,7 +674,7 @@ ROM_START( sshooter11 ) /* Rev 0.5B PCB , program roms dated 04/03/98 */ ROM_LOAD32_BYTE( "ss-u111.v11", 0x00002, 0x40000, CRC(ec209b5f) SHA1(1408b509853b325e865d0b23d237bca321e73f60) ) // 1:3 ROM_LOAD32_BYTE( "ss-u110.v11", 0x00003, 0x40000, CRC(0f1de201) SHA1(5001de3349357545a6a45102340caf0008b50d7b) ) // 1:4 - ROM_REGION( 0x600000, "bsmt", 0 ) /* Sound v1.2 */ + ROM_REGION( 0x1000000, "bsmt", 0 ) /* Sound v1.2 */ ROM_LOAD( "ss-u160.bin", 0x000000, 0x100000, CRC(1c603d42) SHA1(880992871be52129684052d542946de0cc32ba9a) ) // 1:1 ROM_RELOAD( 0x3f8000, 0x100000 ) ROM_LOAD( "ss-u162.bin", 0x100000, 0x100000, CRC(40ef448a) SHA1(c96f7b169be2576e9f3783af84c07259efefb812) ) // 2:1