Move Multipcm bank schemes to DEVICE_ADDRESS_MAP (#3113)

* multipcm : Move bank schemes to DEVICE_ADDRESS_MAP, Allow 512 Samples (0x1800 Header size, 12byte Header per sample)
segas32: Fix multipcm banking(Chip doesn't have panning-related bankswitching)

* oops

* segas32 : configured banking, notes

* segam1audio : do configured banking
This commit is contained in:
cam900 2018-01-26 03:31:33 +09:00 committed by ajrhacker
parent 3d595b9ca1
commit 11cafea0c6
11 changed files with 405 additions and 330 deletions

View File

@ -78,6 +78,7 @@ void multipcm_device::init_sample(sample_t *sample, uint32_t index)
uint32_t address = index * 12;
sample->m_start = (read_byte(address) << 16) | (read_byte(address + 1) << 8) | read_byte(address + 2);
sample->m_start &= 0x3fffff;
sample->m_loop = (read_byte(address + 3) << 8) | read_byte(address + 4);
sample->m_end = 0xffff - ((read_byte(address + 5) << 8) | read_byte(address + 6));
sample->m_attack_reg = (read_byte(address + 8) >> 4) & 0xf;
@ -333,7 +334,7 @@ void multipcm_device::write_slot(slot_t *slot, int32_t reg, uint8_t data)
//according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
//the game should never change the sample while playing.
sample_t sample;
init_sample(&sample, slot->m_regs[1]);
init_sample(&sample, slot->m_regs[1] | ((slot->m_regs[2] & 1) << 8));
write_slot(slot, 6, sample.m_lfo_vibrato_reg);
write_slot(slot, 7, sample.m_lfo_amplitude_reg);
break;
@ -358,7 +359,7 @@ void multipcm_device::write_slot(slot_t *slot, int32_t reg, uint8_t data)
case 4: //KeyOn/Off (and more?)
if (data & 0x80) //KeyOn
{
init_sample(&slot->m_sample, slot->m_regs[1]);
init_sample(&slot->m_sample, slot->m_regs[1] | ((slot->m_regs[2] & 1) << 8));
slot->m_playing = true;
slot->m_base = slot->m_sample.m_start;
slot->m_offset = 0;
@ -368,19 +369,6 @@ void multipcm_device::write_slot(slot_t *slot, int32_t reg, uint8_t data)
envelope_generator_calc(slot);
slot->m_envelope_gen.m_state = state_t::ATTACK;
slot->m_envelope_gen.m_volume = 0;
if (slot->m_base >= 0x100000)
{
if (slot->m_pan & 8)
{
slot->m_base = (slot->m_base & 0xfffff) | m_bank_left;
}
else
{
slot->m_base = (slot->m_base & 0xfffff) | m_bank_right;
}
}
}
else
{
@ -456,13 +444,6 @@ WRITE8_MEMBER( multipcm_device::write )
/* MAME/M1 access functions */
void multipcm_device::set_bank(uint32_t leftoffs, uint32_t rightoffs)
{
m_bank_left = leftoffs;
m_bank_right = rightoffs;
printf("%08x, %08x\n", leftoffs, rightoffs);
}
DEFINE_DEVICE_TYPE(MULTIPCM, multipcm_device, "ymw258f", "Yamaha YMW-258-F")
multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@ -473,8 +454,6 @@ multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag,
m_slots(nullptr),
m_cur_slot(0),
m_address(0),
m_bank_right(0),
m_bank_left(0),
m_rate(0),
m_attack_step(nullptr),
m_decay_release_step(nullptr),
@ -592,8 +571,6 @@ void multipcm_device::device_start()
save_item(NAME(m_cur_slot));
save_item(NAME(m_address));
save_item(NAME(m_bank_left));
save_item(NAME(m_bank_right));
// Slots
m_slots = auto_alloc_array_clear(machine(), slot_t, 28);
@ -630,6 +607,24 @@ void multipcm_device::device_start()
lfo_init();
}
//-------------------------------------------------
// device_clock_changed - called if the clock
// changes
//-------------------------------------------------
void multipcm_device::device_clock_changed()
{
const float clock_divider = 180.0f;
m_rate = (float)clock() / clock_divider;
m_stream->set_sample_rate(m_rate);
for (int32_t i = 0; i < 0x400; ++i)
{
const float fcent = m_rate * (1024.0f + (float)i) / 1024.0f;
m_freq_step_table[i] = value_to_fixed(TL_SHIFT, fcent);
}
}
//-----------------------------------------------------
// clamp_to_int16 - clamp a 32-bit value to 16 bits
//-----------------------------------------------------

View File

@ -15,11 +15,10 @@ public:
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( read );
void set_bank(uint32_t leftoffs, uint32_t rightoffs);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_clock_changed() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
@ -96,8 +95,6 @@ private:
slot_t *m_slots;
uint32_t m_cur_slot;
uint32_t m_address;
uint32_t m_bank_right;
uint32_t m_bank_left;
float m_rate;
uint32_t *m_attack_step;

View File

@ -19,10 +19,12 @@
#define MULTIPCM_2_TAG "pcm2"
#define YM3438_TAG "ymsnd"
#define UART_TAG "uart"
#define MPCMBANK1_TAG "m1pcm1_bank"
#define MPCMBANK2_TAG "m1pcm2_bank"
static ADDRESS_MAP_START( segam1audio_map, AS_PROGRAM, 16, segam1audio_device )
AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_REGION(":m1sndcpu", 0)
AM_RANGE(0x080000, 0x09ffff) AM_ROM AM_REGION(":m1sndcpu", 0x20000) // mirror of upper ROM socket
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x080000, 0x09ffff) AM_ROM AM_REGION(M68000_TAG, 0x20000) // mirror of upper ROM socket
AM_RANGE(0xc20000, 0xc20001) AM_DEVREADWRITE8(UART_TAG, i8251_device, data_r, data_w, 0x00ff)
AM_RANGE(0xc20002, 0xc20003) AM_DEVREADWRITE8(UART_TAG, i8251_device, status_r, control_w, 0x00ff)
AM_RANGE(0xc40000, 0xc40007) AM_DEVREADWRITE8(MULTIPCM_1_TAG, multipcm_device, read, write, 0x00ff)
@ -35,11 +37,13 @@ static ADDRESS_MAP_START( segam1audio_map, AS_PROGRAM, 16, segam1audio_device )
ADDRESS_MAP_END
static ADDRESS_MAP_START( mpcm1_map, 0, 8, segam1audio_device )
AM_RANGE(0x000000, 0x3fffff) AM_ROM AM_REGION(":m1pcm1", 0)
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1fffff) AM_ROMBANK(MPCMBANK1_TAG)
ADDRESS_MAP_END
static ADDRESS_MAP_START( mpcm2_map, 0, 8, segam1audio_device )
AM_RANGE(0x000000, 0x3fffff) AM_ROM AM_REGION(":m1pcm2", 0)
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1fffff) AM_ROMBANK(MPCMBANK2_TAG)
ADDRESS_MAP_END
//**************************************************************************
@ -96,6 +100,10 @@ segam1audio_device::segam1audio_device(const machine_config &mconfig, const char
m_multipcm_2(*this, MULTIPCM_2_TAG),
m_ym(*this, YM3438_TAG),
m_uart(*this, UART_TAG),
m_multipcm1_region(*this, MULTIPCM_1_TAG),
m_multipcm2_region(*this, MULTIPCM_2_TAG),
m_mpcmbank1(*this, MPCMBANK1_TAG),
m_mpcmbank2(*this, MPCMBANK2_TAG),
m_rxd_handler(*this)
{
}
@ -107,6 +115,8 @@ segam1audio_device::segam1audio_device(const machine_config &mconfig, const char
void segam1audio_device::device_start()
{
m_rxd_handler.resolve_safe();
m_mpcmbank1->configure_entries(0, 4, m_multipcm1_region->base(), 0x100000);
m_mpcmbank2->configure_entries(0, 4, m_multipcm2_region->base(), 0x100000);
}
//-------------------------------------------------
@ -120,12 +130,12 @@ void segam1audio_device::device_reset()
WRITE16_MEMBER(segam1audio_device::m1_snd_mpcm_bnk1_w)
{
m_multipcm_1->set_bank(0x100000 * (data & 3), 0x100000 * (data & 3));
m_mpcmbank1->set_entry(data & 3);
}
WRITE16_MEMBER(segam1audio_device::m1_snd_mpcm_bnk2_w)
{
m_multipcm_2->set_bank(0x100000 * (data & 3), 0x100000 * (data & 3));
m_mpcmbank2->set_entry(data & 3);
}
WRITE_LINE_MEMBER(segam1audio_device::write_txd)

View File

@ -10,9 +10,10 @@
#pragma once
#define M1AUDIO_CPU_REGION "m1sndcpu"
#define M1AUDIO_MPCM1_REGION "m1pcm1"
#define M1AUDIO_MPCM2_REGION "m1pcm2"
#define M1AUDIO_TAG "m1audio"
#define M1AUDIO_CPU_REGION "m1audio:sndcpu"
#define M1AUDIO_MPCM1_REGION "m1audio:pcm1"
#define M1AUDIO_MPCM2_REGION "m1audio:pcm2"
#define MCFG_SEGAM1AUDIO_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, SEGAM1AUDIO, 0)
@ -51,6 +52,12 @@ private:
required_device<multipcm_device> m_multipcm_2;
required_device<ym3438_device> m_ym;
required_device<i8251_device> m_uart;
required_memory_region m_multipcm1_region;
required_memory_region m_multipcm2_region;
required_memory_bank m_mpcmbank1;
required_memory_bank m_mpcmbank2;
devcb_write_line m_rxd_handler;

View File

@ -640,7 +640,6 @@ Notes:
#include "vr.lh"
READ16_MEMBER(model1_state::io_r)
{
if(offset < 0x8)
@ -1641,11 +1640,11 @@ MACHINE_CONFIG_START(model1_state::model1)
MCFG_VIDEO_START_OVERRIDE(model1_state,model1)
MCFG_SEGAM1AUDIO_ADD("m1audio")
MCFG_SEGAM1AUDIO_ADD(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_rxd))
MCFG_DEVICE_ADD("m1uart", I8251, 8000000) // uPD71051C, clock unknown
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("m1audio", segam1audio_device, write_txd))
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(M1AUDIO_TAG, segam1audio_device, write_txd))
MCFG_CLOCK_ADD("m1uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate)
MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_txc))
@ -1661,7 +1660,7 @@ MACHINE_CONFIG_DERIVED(model1_state::swa, model1)
MCFG_SOUND_ROUTE(1, "dright", 1.0)
// Apparently m1audio has to filter out commands the DSB shouldn't see
MCFG_DEVICE_MODIFY("m1audio")
MCFG_DEVICE_MODIFY(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_rxd))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(DSBZ80_TAG, dsbz80_device, write_txd))
MACHINE_CONFIG_END
@ -1711,11 +1710,11 @@ MACHINE_CONFIG_START(model1_state::model1_vr)
MCFG_VIDEO_START_OVERRIDE(model1_state,model1)
MCFG_SEGAM1AUDIO_ADD("m1audio")
MCFG_SEGAM1AUDIO_ADD(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_rxd))
MCFG_DEVICE_ADD("m1uart", I8251, 8000000) // uPD71051C, clock unknown
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("m1audio", segam1audio_device, write_txd))
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(M1AUDIO_TAG, segam1audio_device, write_txd))
MCFG_CLOCK_ADD("m1uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate)
MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_txc))

View File

@ -2171,11 +2171,11 @@ MACHINE_CONFIG_START(model2_state::model2o)
MCFG_VIDEO_START_OVERRIDE(model2_state,model2)
MCFG_SEGAM1AUDIO_ADD("m1audio")
MCFG_SEGAM1AUDIO_ADD(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxd))
MCFG_DEVICE_ADD("uart", I8251, 8000000) // uPD71051C, clock unknown
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("m1audio", segam1audio_device, write_txd))
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(M1AUDIO_TAG, segam1audio_device, write_txd))
MCFG_CLOCK_ADD("uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate)
MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart", i8251_device, write_txc))
@ -2297,11 +2297,11 @@ MACHINE_CONFIG_DERIVED(model2_state::manxtt, model2a)
MACHINE_CONFIG_END
MACHINE_CONFIG_DERIVED(model2_state::manxttdx, manxtt) /* Includes a Model 1 Sound board for additional sounds - Deluxe version only */
MCFG_SEGAM1AUDIO_ADD("m1audio")
MCFG_SEGAM1AUDIO_ADD(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxd))
MCFG_DEVICE_MODIFY("uart")
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("m1audio", segam1audio_device, write_txd))
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(M1AUDIO_TAG, segam1audio_device, write_txd))
MACHINE_CONFIG_END
uint16_t model2_state::crypt_read_callback(uint32_t addr)

File diff suppressed because it is too large Load Diff

View File

@ -205,8 +205,10 @@ private:
uint32_t m_multipcma_bank_l;
uint32_t m_multipcma_bank_r;
uint32_t m_multipcma_banked;
uint32_t m_multipcmb_bank_l;
uint32_t m_multipcmb_bank_r;
uint32_t m_multipcmb_banked;
uint32_t r32(int offset) const;
uint8_t r8(int offset) const;
@ -958,11 +960,55 @@ READ8_MEMBER(vgmplay_device::ymz280b_rom_r)
READ8_MEMBER(vgmplay_device::multipcma_rom_r)
{
if (m_multipcma_banked == 1)
{
offset &= 0x1fffff;
if (offset & 0x100000)
{
if (m_multipcma_bank_l == m_multipcma_bank_r)
{
offset = ((m_multipcma_bank_r & ~0xf) << 16) | (offset & 0xfffff);
}
else
{
if (offset & 0x80000)
{
offset = ((m_multipcma_bank_l & ~0x7) << 16) | (offset & 0x7ffff);
}
else
{
offset = ((m_multipcma_bank_r & ~0x7) << 16) | (offset & 0x7ffff);
}
}
}
}
return rom_r(0, 0x89, offset);
}
READ8_MEMBER(vgmplay_device::multipcmb_rom_r)
{
if (m_multipcmb_banked == 1)
{
offset &= 0x1fffff;
if (offset & 0x100000)
{
if (m_multipcmb_bank_l == m_multipcmb_bank_r)
{
offset = ((m_multipcmb_bank_r & ~0xf) << 16) | (offset & 0xfffff);
}
else
{
if (offset & 0x80000)
{
offset = ((m_multipcmb_bank_l & ~0x7) << 16) | (offset & 0x7ffff);
}
else
{
offset = ((m_multipcmb_bank_r & ~0x7) << 16) | (offset & 0x7ffff);
}
}
}
}
return rom_r(1, 0x89, offset);
}
@ -1306,7 +1352,7 @@ WRITE8_MEMBER(vgmplay_state::multipcm_bank_lo_a_w)
if (offset & 2)
m_multipcma_bank_r = (m_multipcma_bank_r & 0xff00) | data;
m_multipcma->set_bank(m_multipcma_bank_l << 16, m_multipcma_bank_r << 16);
m_multipcma_banked = 1;
}
WRITE8_MEMBER(vgmplay_state::multipcm_bank_hi_b_w)
@ -1324,7 +1370,7 @@ WRITE8_MEMBER(vgmplay_state::multipcm_bank_lo_b_w)
if (offset & 2)
m_multipcmb_bank_r = (m_multipcmb_bank_r & 0xff00) | data;
m_multipcmb->set_bank(m_multipcmb_bank_l << 16, m_multipcmb_bank_r << 16);
m_multipcmb_banked = 1;
}
static INPUT_PORTS_START( vgmplay )

View File

@ -33,7 +33,7 @@ public:
model1_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_m1audio(*this, "m1audio")
, m_m1audio(*this, M1AUDIO_TAG)
, m_m1uart(*this, "m1uart")
, m_m1comm(*this, "m1comm")
, m_dsbz80(*this, DSBZ80_TAG)

View File

@ -36,7 +36,7 @@ public:
m_tgpx4_program(*this, "tgpx4_program"),
m_maincpu(*this,"maincpu"),
m_dsbz80(*this, DSBZ80_TAG),
m_m1audio(*this, "m1audio"),
m_m1audio(*this, M1AUDIO_TAG),
m_uart(*this, "uart"),
m_m2comm(*this, "m2comm"),
m_audiocpu(*this, "audiocpu"),

View File

@ -186,6 +186,7 @@ public:
void int_control_w(int offset, uint8_t data);
void update_sound_irq_state();
void segas32_common_init();
void multi32_common_init();
void radm_sw1_output( int which, uint16_t data );
void radm_sw2_output( int which, uint16_t data );
void radr_sw2_output( int which, uint16_t data );