mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00
es5506.cpp : Implement more differs between ES5505/5506, Reduce duplicates (#5829)
* es5506.cpp : More constant-expandable volume lookup tables, Reduce duplicates * es5506.cpp : Minor correction * es5506.cpp : Reduce unnecessary constants, Bit differences, Add notes
This commit is contained in:
parent
65fb297023
commit
26f3f0f0c6
@ -101,12 +101,12 @@ Ensoniq OTIS - ES5505 Ensoniq OTTO -
|
|||||||
|
|
||||||
#define RAINE_CHECK 0
|
#define RAINE_CHECK 0
|
||||||
|
|
||||||
static constexpr unsigned FINE_FILTER_BIT = 16;
|
static constexpr u32 FINE_FILTER_BIT = 16;
|
||||||
static constexpr unsigned FILTER_BIT = 12;
|
static constexpr u32 FILTER_BIT = 12;
|
||||||
static constexpr unsigned FILTER_SHIFT = FINE_FILTER_BIT - FILTER_BIT;
|
static constexpr u32 FILTER_SHIFT = FINE_FILTER_BIT - FILTER_BIT;
|
||||||
|
|
||||||
static constexpr unsigned MAX_SAMPLE_CHUNK = 10000;
|
static constexpr u32 MAX_SAMPLE_CHUNK = 10000;
|
||||||
static constexpr unsigned ULAW_MAXBITS = 8;
|
static constexpr u32 ULAW_MAXBITS = 8;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -201,9 +201,6 @@ void es550x_device::device_start()
|
|||||||
m_sample_rate_changed_cb.resolve();
|
m_sample_rate_changed_cb.resolve();
|
||||||
m_irqv = 0x80;
|
m_irqv = 0x80;
|
||||||
|
|
||||||
/* compute the tables */
|
|
||||||
compute_tables();
|
|
||||||
|
|
||||||
/* allocate memory */
|
/* allocate memory */
|
||||||
m_scratch = make_unique_clear<s32[]>(2 * MAX_SAMPLE_CHUNK);
|
m_scratch = make_unique_clear<s32[]>(2 * MAX_SAMPLE_CHUNK);
|
||||||
|
|
||||||
@ -286,6 +283,9 @@ void es5506_device::device_start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* compute the tables */
|
||||||
|
compute_tables(VOLUME_BIT_ES5506, 4, 8, 11); // 4 bit exponent, 8 bit mantissa
|
||||||
|
|
||||||
/* initialize the rest of the structure */
|
/* initialize the rest of the structure */
|
||||||
m_channels = channels;
|
m_channels = channels;
|
||||||
|
|
||||||
@ -296,14 +296,13 @@ void es5506_device::device_start()
|
|||||||
|
|
||||||
/* init the voices */
|
/* init the voices */
|
||||||
// 21 bit integer and 11 bit fraction
|
// 21 bit integer and 11 bit fraction
|
||||||
m_accum_shift = ADDRESS_FRAC_BIT - ADDRESS_FRAC_BIT_ES5506;
|
get_accum_mask(ADDRESS_INTEGER_BIT_ES5506, ADDRESS_FRAC_BIT_ES5506);
|
||||||
m_accum_mask = (((((1 << 21) - 1) << ADDRESS_FRAC_BIT_ES5506) | ((1 << ADDRESS_FRAC_BIT_ES5506) - 1)) << m_accum_shift) | ((1 << m_accum_shift) - 1);
|
|
||||||
for (int j = 0; j < 32; j++)
|
for (int j = 0; j < 32; j++)
|
||||||
{
|
{
|
||||||
m_voice[j].index = j;
|
m_voice[j].index = j;
|
||||||
m_voice[j].control = CONTROL_STOPMASK;
|
m_voice[j].control = CONTROL_STOPMASK;
|
||||||
m_voice[j].lvol = 0xffff << VOLUME_SHIFT_ES5506; // 16 bit volume
|
m_voice[j].lvol = 0xffff << m_volume_shift; // 16 bit volume
|
||||||
m_voice[j].rvol = 0xffff << VOLUME_SHIFT_ES5506;
|
m_voice[j].rvol = 0xffff << m_volume_shift;
|
||||||
m_voice[j].exbank = 0;
|
m_voice[j].exbank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,19 +403,21 @@ void es5505_device::device_start()
|
|||||||
m_region_base[1] = region ? reinterpret_cast<u16 *>(region->base()) : nullptr;
|
m_region_base[1] = region ? reinterpret_cast<u16 *>(region->base()) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* compute the tables */
|
||||||
|
compute_tables(VOLUME_BIT_ES5505, 4, 4, 15); // 4 bit exponent, 4 bit mantissa
|
||||||
|
|
||||||
/* initialize the rest of the structure */
|
/* initialize the rest of the structure */
|
||||||
m_channels = channels;
|
m_channels = channels;
|
||||||
|
|
||||||
/* init the voices */
|
/* init the voices */
|
||||||
// 20 bit integer and 9 bit fraction
|
// 20 bit integer and 9 bit fraction
|
||||||
m_accum_shift = ADDRESS_FRAC_BIT - ADDRESS_FRAC_BIT_ES5505;
|
get_accum_mask(ADDRESS_INTEGER_BIT_ES5505, ADDRESS_FRAC_BIT_ES5505);
|
||||||
m_accum_mask = (((((1 << 20) - 1) << ADDRESS_FRAC_BIT_ES5505) | ((1 << ADDRESS_FRAC_BIT_ES5505) - 1)) << m_accum_shift) | ((1 << m_accum_shift) - 1);
|
|
||||||
for (int j = 0; j < 32; j++)
|
for (int j = 0; j < 32; j++)
|
||||||
{
|
{
|
||||||
m_voice[j].index = j;
|
m_voice[j].index = j;
|
||||||
m_voice[j].control = CONTROL_STOPMASK;
|
m_voice[j].control = CONTROL_STOPMASK;
|
||||||
m_voice[j].lvol = 0xff << VOLUME_SHIFT_ES5505; // 8 bit volume
|
m_voice[j].lvol = 0xff << m_volume_shift; // 8 bit volume
|
||||||
m_voice[j].rvol = 0xff << VOLUME_SHIFT_ES5505;
|
m_voice[j].rvol = 0xff << m_volume_shift;
|
||||||
m_voice[j].exbank = 0;
|
m_voice[j].exbank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +462,7 @@ void es550x_device::update_internal_irq_state()
|
|||||||
|
|
||||||
***********************************************************************************************/
|
***********************************************************************************************/
|
||||||
|
|
||||||
void es550x_device::compute_tables()
|
void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 mantissa_bit, u32 mantissa_shift)
|
||||||
{
|
{
|
||||||
/* allocate ulaw lookup table */
|
/* allocate ulaw lookup table */
|
||||||
m_ulaw_lookup = make_unique_clear<s16[]>(1 << ULAW_MAXBITS);
|
m_ulaw_lookup = make_unique_clear<s16[]>(1 << ULAW_MAXBITS);
|
||||||
@ -469,8 +470,8 @@ void es550x_device::compute_tables()
|
|||||||
/* generate ulaw lookup table */
|
/* generate ulaw lookup table */
|
||||||
for (int i = 0; i < (1 << ULAW_MAXBITS); i++)
|
for (int i = 0; i < (1 << ULAW_MAXBITS); i++)
|
||||||
{
|
{
|
||||||
u16 rawval = (i << (16 - ULAW_MAXBITS)) | (1 << (15 - ULAW_MAXBITS));
|
const u16 rawval = (i << (16 - ULAW_MAXBITS)) | (1 << (15 - ULAW_MAXBITS));
|
||||||
u8 exponent = rawval >> 13;
|
const u8 exponent = rawval >> 13;
|
||||||
u32 mantissa = (rawval << 3) & 0xffff;
|
u32 mantissa = (rawval << 3) & 0xffff;
|
||||||
|
|
||||||
if (exponent == 0)
|
if (exponent == 0)
|
||||||
@ -482,23 +483,37 @@ void es550x_device::compute_tables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 volume_len = 1 << VOLUME_INTEGER_BIT;
|
const u32 volume_bit = (exponent_bit + mantissa_bit);
|
||||||
|
m_volume_shift = FINE_VOLUME_BIT - total_volume_bit;
|
||||||
|
m_volume_shift_int = FINE_VOLUME_BIT - volume_bit;
|
||||||
|
const u32 volume_len = 1 << volume_bit;
|
||||||
/* allocate volume lookup table */
|
/* allocate volume lookup table */
|
||||||
m_volume_lookup = make_unique_clear<u32[]>(volume_len);
|
m_volume_lookup = make_unique_clear<u32[]>(volume_len);
|
||||||
|
|
||||||
/* generate volume lookup table */
|
/* generate volume lookup table */
|
||||||
const u8 exponent_bit = (VOLUME_INTEGER_BIT - 4);
|
const u8 exponent_mask = (1 << exponent_bit) - 1;
|
||||||
const u32 mantissa_len = (1 << exponent_bit);
|
const u32 mantissa_len = (1 << mantissa_bit);
|
||||||
const u32 mantissa_mask = (mantissa_len - 1);
|
const u32 mantissa_mask = (mantissa_len - 1);
|
||||||
for (int i = 0; i < volume_len; i++)
|
for (int i = 0; i < volume_len; i++)
|
||||||
{
|
{
|
||||||
u8 exponent = i >> exponent_bit;
|
const u8 exponent = (i >> mantissa_bit) & exponent_mask;
|
||||||
u32 mantissa = (i & mantissa_mask) | mantissa_len;
|
const u32 mantissa = (i & mantissa_mask) | mantissa_len;
|
||||||
|
|
||||||
m_volume_lookup[i] = (mantissa << 11) >> (20 - exponent);
|
m_volume_lookup[i] = (mantissa << mantissa_shift) >> (((mantissa_shift - mantissa_bit) + 1 + (1 << exponent_bit)) - exponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************
|
||||||
|
|
||||||
|
get_accum_mask -- get address accumulator mask
|
||||||
|
|
||||||
|
***********************************************************************************************/
|
||||||
|
|
||||||
|
void es550x_device::get_accum_mask(u32 address_integer, u32 address_frac)
|
||||||
|
{
|
||||||
|
m_accum_shift = ADDRESS_FRAC_BIT - address_frac;
|
||||||
|
m_accum_mask = (((((1 << address_integer) - 1) << address_frac) | ((1 << address_frac) - 1)) << m_accum_shift) | ((1 << m_accum_shift) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
@ -1765,13 +1780,13 @@ inline void es5505_device::reg_write_low(es550x_voice *voice, offs_t offset, u16
|
|||||||
case 0x08: /* LVOL */
|
case 0x08: /* LVOL */
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
voice->lvol = (voice->lvol & ~0xff00) | (data & 0xff00);
|
voice->lvol = (voice->lvol & ~0xff00) | (data & 0xff00);
|
||||||
LOG("%s:voice %d, left vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->lvol >> VOLUME_SHIFT_ES5505);
|
LOG("%s:voice %d, left vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->lvol >> m_volume_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: /* RVOL */
|
case 0x09: /* RVOL */
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
voice->rvol = (voice->rvol & ~0xff00) | (data & 0xff00);
|
voice->rvol = (voice->rvol & ~0xff00) | (data & 0xff00);
|
||||||
LOG("%s:voice %d, right vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->rvol >> VOLUME_SHIFT_ES5505);
|
LOG("%s:voice %d, right vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->rvol >> m_volume_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0a: /* ACC (hi) */
|
case 0x0a: /* ACC (hi) */
|
||||||
|
@ -34,11 +34,13 @@ protected:
|
|||||||
LP_MASK = LP3 | LP4
|
LP_MASK = LP3 | LP4
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned FINE_VOLUME_BIT = 16;
|
// constants for volumes
|
||||||
const unsigned VOLUME_INTEGER_BIT = 12;
|
const u32 FINE_VOLUME_BIT = 16;
|
||||||
const unsigned VOLUME_INTEGER_SHIFT = FINE_VOLUME_BIT - VOLUME_INTEGER_BIT;
|
|
||||||
const unsigned VOLUME_ACC_SHIFT = 23 - VOLUME_INTEGER_BIT;
|
const u32 VOLUME_ACC_SHIFT = 11;
|
||||||
const unsigned ADDRESS_FRAC_BIT = 11;
|
|
||||||
|
// constants for address
|
||||||
|
const u32 ADDRESS_FRAC_BIT = 11;
|
||||||
|
|
||||||
// struct describing a single playing voice
|
// struct describing a single playing voice
|
||||||
struct es550x_voice
|
struct es550x_voice
|
||||||
@ -86,15 +88,16 @@ protected:
|
|||||||
|
|
||||||
void update_irq_state();
|
void update_irq_state();
|
||||||
void update_internal_irq_state();
|
void update_internal_irq_state();
|
||||||
void compute_tables();
|
void compute_tables(u32 total_volume_bit = 16, u32 exponent_bit = 4, u32 mantissa_bit = 8, u32 mantissa_shift = 11);
|
||||||
|
void get_accum_mask(u32 address_integer, u32 address_frac);
|
||||||
|
|
||||||
virtual inline u32 get_bank(u32 control) { return 0; }
|
virtual inline u32 get_bank(u32 control) { return 0; }
|
||||||
virtual inline u32 get_ca(u32 control) { return 0; }
|
virtual inline u32 get_ca(u32 control) { return 0; }
|
||||||
virtual inline u32 get_lp(u32 control) { return 0; }
|
virtual inline u32 get_lp(u32 control) { return 0; }
|
||||||
|
|
||||||
inline u32 get_volume(u16 volume) { return m_volume_lookup[volume >> VOLUME_INTEGER_SHIFT]; }
|
inline u32 get_volume(u16 volume) { return m_volume_lookup[volume >> m_volume_shift_int]; }
|
||||||
inline unsigned get_accum_shifted_val(unsigned val, int bias = 0) { return val << (m_accum_shift - bias); }
|
inline u32 get_accum_shifted_val(u32 val, int bias = 0) { return val << (m_accum_shift - bias); }
|
||||||
inline unsigned get_accum_res(unsigned val, int bias = 0) { return val >> (m_accum_shift - bias); }
|
inline u32 get_accum_res(u32 val, int bias = 0) { return val >> (m_accum_shift - bias); }
|
||||||
inline u32 get_integer_addr(u32 accum, s32 bias = 0) { return ((accum + (bias << ADDRESS_FRAC_BIT)) & m_accum_mask) >> ADDRESS_FRAC_BIT; }
|
inline u32 get_integer_addr(u32 accum, s32 bias = 0) { return ((accum + (bias << ADDRESS_FRAC_BIT)) & m_accum_mask) >> ADDRESS_FRAC_BIT; }
|
||||||
|
|
||||||
inline s32 interpolate(s32 sample1, s32 sample2, u32 accum);
|
inline s32 interpolate(s32 sample1, s32 sample2, u32 accum);
|
||||||
@ -116,6 +119,9 @@ protected:
|
|||||||
u64 m_accum_shift;
|
u64 m_accum_shift;
|
||||||
u64 m_accum_mask;
|
u64 m_accum_mask;
|
||||||
|
|
||||||
|
u64 m_volume_shift;
|
||||||
|
u64 m_volume_shift_int;
|
||||||
|
|
||||||
u8 m_current_page; /* current register page */
|
u8 m_current_page; /* current register page */
|
||||||
u8 m_active_voices; /* number of active voices */
|
u8 m_active_voices; /* number of active voices */
|
||||||
u16 m_mode; /* MODE register */
|
u16 m_mode; /* MODE register */
|
||||||
@ -158,9 +164,9 @@ protected:
|
|||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
const unsigned VOLUME_BIT_ES5506 = 16;
|
const u32 VOLUME_BIT_ES5506 = 16;
|
||||||
const unsigned VOLUME_SHIFT_ES5506 = FINE_VOLUME_BIT - VOLUME_BIT_ES5506;
|
const u32 ADDRESS_INTEGER_BIT_ES5506 = 21;
|
||||||
const unsigned ADDRESS_FRAC_BIT_ES5506 = ADDRESS_FRAC_BIT;
|
const u32 ADDRESS_FRAC_BIT_ES5506 = 11;
|
||||||
|
|
||||||
virtual inline u32 get_bank(u32 control) override { return (control >> 14) & 3; }
|
virtual inline u32 get_bank(u32 control) override { return (control >> 14) & 3; }
|
||||||
virtual inline u32 get_ca(u32 control) override { return (control >> 10) & 7; }
|
virtual inline u32 get_ca(u32 control) override { return (control >> 10) & 7; }
|
||||||
@ -203,9 +209,9 @@ protected:
|
|||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
|
|
||||||
const unsigned VOLUME_BIT_ES5505 = 8;
|
const u32 VOLUME_BIT_ES5505 = 8;
|
||||||
const unsigned VOLUME_SHIFT_ES5505 = FINE_VOLUME_BIT - VOLUME_BIT_ES5505;
|
const u32 ADDRESS_INTEGER_BIT_ES5505 = 20;
|
||||||
const unsigned ADDRESS_FRAC_BIT_ES5505 = 9;
|
const u32 ADDRESS_FRAC_BIT_ES5505 = 9;
|
||||||
|
|
||||||
virtual inline u32 get_lp(u32 control) override { return (control >> 10) & LP_MASK; }
|
virtual inline u32 get_lp(u32 control) override { return (control >> 10) & LP_MASK; }
|
||||||
virtual inline u32 get_ca(u32 control) override { return (control >> 8) & 3; }
|
virtual inline u32 get_ca(u32 control) override { return (control >> 8) & 3; }
|
||||||
|
Loading…
Reference in New Issue
Block a user