Replaced BSMT2000 HLE emulator with emulation of the original TMS32015.

[Dr. Decapitator, Andrew Gardner, Quench, Guru, Ernesto Corvi,
Peter Grounds, Lord Nightmare, Aaron Giles]
This commit is contained in:
Aaron Giles 2011-01-20 16:36:53 +00:00
parent 8fc25a750d
commit 3d748f0316
7 changed files with 581 additions and 487 deletions

View File

@ -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<legacy_device_base *>(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<bsmt2000_device_config *>(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<tms32015_device>("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<bsmt2000_device, &bsmt2000_device::stream_generate>);
}
/*-------------------------------------------------
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;
}

View File

@ -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__ */

View File

@ -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<class T, void (T::*func)(stream_sample_t **inputs, stream_sample_t **outputs, int samples)>
void stream_update_stub(device_t *device, void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
T *target = downcast<T *>(device);
(target->*func)(inputs, outputs, samples);
}
/***************************************************************************

View File

@ -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<bsmt2000_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<bsmt2000_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 )

View File

@ -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<bsmt2000_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>();
dcheese_state *state = space->machine->driver_data<dcheese_state>();
bsmt2000_device *bsmt = space->machine->device<bsmt2000_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 )

View File

@ -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<bsmt2000_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<bsmt2000_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) )

View File

@ -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<bsmt2000_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<bsmt2000_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<bsmt2000_device>("bsmt")->write_reg(data);
COMBINE_DATA(&bsmt_data_bank);
}
static CUSTOM_INPUT( bsmt_status_r )
{
return field->port->machine->device<bsmt2000_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