[WIP] K063260 skeleton
This commit is contained in:
parent
fe7ba3c56b
commit
9c56c3d01b
20 changed files with 837 additions and 84 deletions
|
|
@ -8,18 +8,19 @@
|
|||
|
||||
#include "k053260.hpp"
|
||||
|
||||
void k053260_core::tick()
|
||||
void k053260_core::tick(u32 cycle)
|
||||
{
|
||||
m_out[0] = m_out[1] = 0;
|
||||
if (m_ctrl.sound_en())
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_voice[i].tick();
|
||||
m_voice[i].tick(cycle);
|
||||
m_out[0] += m_voice[i].out(0);
|
||||
m_out[1] += m_voice[i].out(1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
// dac clock (YM3012 format)
|
||||
u8 dac_clock = m_dac.clock();
|
||||
if (bitfield(++dac_clock, 0, 4) == 0)
|
||||
|
|
@ -34,62 +35,59 @@ void k053260_core::tick()
|
|||
m_dac.set_state(bitfield(dac_state, 0, 2));
|
||||
}
|
||||
m_dac.set_clock(bitfield(dac_clock, 0, 4));
|
||||
*/
|
||||
}
|
||||
|
||||
void k053260_core::voice_t::tick()
|
||||
void k053260_core::voice_t::tick(u32 cycle)
|
||||
{
|
||||
if (m_enable && m_busy)
|
||||
{
|
||||
bool update = false;
|
||||
// update counter
|
||||
if (bitfield(++m_counter, 0, 12) == 0)
|
||||
m_counter += cycle;
|
||||
if (m_counter >= 0x1000)
|
||||
{
|
||||
if (m_bitpos < 8)
|
||||
{
|
||||
m_bitpos += 8;
|
||||
m_addr = bitfield(m_addr + 1, 0, 21);
|
||||
m_remain--;
|
||||
if (m_remain < 0) // check end flag
|
||||
{
|
||||
if (m_loop)
|
||||
{
|
||||
m_addr = m_start;
|
||||
m_remain = m_length;
|
||||
m_output = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_data = m_host.m_intf.read_sample(bitfield(m_addr, 0, 21)); // fetch ROM
|
||||
if (m_adpcm)
|
||||
{
|
||||
m_bitpos -= 4;
|
||||
update = true;
|
||||
m_bitpos -= 4;
|
||||
const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM
|
||||
if (nibble)
|
||||
{
|
||||
m_output += m_host.adpcm_lut(nibble);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bitpos -= 8;
|
||||
}
|
||||
m_counter = bitfield(m_pitch, 0, 12);
|
||||
}
|
||||
m_data = m_host.m_intf.read_sample(bitfield(m_addr, 0, 21)); // fetch ROM
|
||||
if (update)
|
||||
{
|
||||
const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM
|
||||
if (nibble)
|
||||
{
|
||||
m_adpcm_buf += bitfield(nibble, 3) ? s8(0x80 >> bitfield(nibble, 0, 3))
|
||||
: (1 << bitfield(nibble - 1, 0, 3));
|
||||
}
|
||||
m_counter = 0x1000 - bitfield(m_pitch, 0, 12);
|
||||
}
|
||||
|
||||
if (m_remain < 0) // check end flag
|
||||
{
|
||||
if (m_loop)
|
||||
{
|
||||
m_addr = m_start;
|
||||
m_remain = m_length;
|
||||
m_adpcm_buf = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_busy = false;
|
||||
}
|
||||
}
|
||||
// calculate output
|
||||
s32 output = m_adpcm ? m_adpcm_buf : sign_ext<s32>(m_data, 8) * s32(m_volume);
|
||||
s32 output = (m_adpcm ? m_output : sign_ext<s32>(m_data, 8)) * s32(m_volume);
|
||||
// use math for now; actually fomula unknown
|
||||
m_out[0] = (m_pan >= 0) ? s32(output * cos(f64(m_pan) * PI / 180)) : 0;
|
||||
m_out[1] = (m_pan >= 0) ? s32(output * sin(f64(m_pan) * PI / 180)) : 0;
|
||||
m_out[0] = (output * m_host.pan_lut(m_pan, 0)) >> 7;
|
||||
m_out[1] = (output * m_host.pan_lut(m_pan, 1)) >> 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -244,7 +242,8 @@ void k053260_core::voice_t::keyon()
|
|||
m_addr = m_start;
|
||||
m_remain = m_length;
|
||||
m_bitpos = 4;
|
||||
m_adpcm_buf = 0;
|
||||
m_data = 0;
|
||||
m_output = 0;
|
||||
std::fill(m_out.begin(), m_out.end(), 0);
|
||||
}
|
||||
|
||||
|
|
@ -259,12 +258,12 @@ void k053260_core::reset()
|
|||
elem.reset();
|
||||
}
|
||||
|
||||
m_intf.write_int(0);
|
||||
//m_intf.write_int(0);
|
||||
|
||||
std::fill(m_host2snd.begin(), m_host2snd.end(), 0);
|
||||
std::fill(m_snd2host.begin(), m_snd2host.end(), 0);
|
||||
m_ctrl.reset();
|
||||
m_dac.reset();
|
||||
//m_dac.reset();
|
||||
|
||||
std::fill(m_reg.begin(), m_reg.end(), 0);
|
||||
std::fill(m_out.begin(), m_out.end(), 0);
|
||||
|
|
@ -273,20 +272,20 @@ void k053260_core::reset()
|
|||
// reset voice
|
||||
void k053260_core::voice_t::reset()
|
||||
{
|
||||
m_enable = 0;
|
||||
m_busy = 0;
|
||||
m_loop = 0;
|
||||
m_adpcm = 0;
|
||||
m_pitch = 0;
|
||||
m_start = 0;
|
||||
m_length = 0;
|
||||
m_volume = 0;
|
||||
m_pan = -1;
|
||||
m_counter = 0;
|
||||
m_addr = 0;
|
||||
m_remain = 0;
|
||||
m_bitpos = 4;
|
||||
m_data = 0;
|
||||
m_adpcm_buf = 0;
|
||||
m_enable = 0;
|
||||
m_busy = 0;
|
||||
m_loop = 0;
|
||||
m_adpcm = 0;
|
||||
m_pitch = 0;
|
||||
m_start = 0;
|
||||
m_length = 0;
|
||||
m_volume = 0;
|
||||
m_pan = 4;
|
||||
m_counter = 0;
|
||||
m_addr = 0;
|
||||
m_remain = 0;
|
||||
m_bitpos = 4;
|
||||
m_data = 0;
|
||||
m_output = 0;
|
||||
m_out[0] = m_out[1] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class k053260_intf : public vgsound_emu_core
|
|||
|
||||
virtual u8 read_sample(u32 address) { return 0; } // sample fetch
|
||||
|
||||
virtual void write_int(u8 out) {} // timer interrupt
|
||||
//virtual void write_int(u8 out) {} // timer interrupt
|
||||
};
|
||||
|
||||
class k053260_core : public vgsound_emu_core
|
||||
|
|
@ -33,7 +33,19 @@ class k053260_core : public vgsound_emu_core
|
|||
friend class k053260_intf; // k053260 specific interface
|
||||
|
||||
private:
|
||||
const int pan_dir[8] = {-1, 0, 24, 35, 45, 55, 66, 90}; // pan direction
|
||||
const s32 m_pan_lut[8][2] = {
|
||||
{0x00, 0x00},
|
||||
{0x7f, 0x00},
|
||||
{0x74, 0x34},
|
||||
{0x68, 0x49},
|
||||
{0x5a, 0x5a},
|
||||
{0x49, 0x68},
|
||||
{0x34, 0x74},
|
||||
{0x00, 0x7f}
|
||||
}; // pan LUT
|
||||
|
||||
const s8 m_adpcm_lut[16] =
|
||||
{0, 1, 2, 4, 8, 16, 32, 64, -128, -64, -32, -16, -8, -4, -2, -1}; // ADPCM LUT
|
||||
|
||||
class voice_t : public vgsound_emu_core
|
||||
{
|
||||
|
|
@ -50,20 +62,20 @@ class k053260_core : public vgsound_emu_core
|
|||
, m_start(0)
|
||||
, m_length(0)
|
||||
, m_volume(0)
|
||||
, m_pan(-1)
|
||||
, m_pan(4)
|
||||
, m_counter(0)
|
||||
, m_addr(0)
|
||||
, m_remain(0)
|
||||
, m_bitpos(4)
|
||||
, m_data(0)
|
||||
, m_adpcm_buf(0)
|
||||
, m_output(0)
|
||||
{
|
||||
m_out.fill(0);
|
||||
}
|
||||
|
||||
// internal state
|
||||
void reset();
|
||||
void tick();
|
||||
void tick(u32 cycle);
|
||||
|
||||
// accessors
|
||||
void write(u8 address, u8 data);
|
||||
|
|
@ -81,7 +93,7 @@ class k053260_core : public vgsound_emu_core
|
|||
|
||||
inline void length_inc() { m_length = (m_length + 1) & 0xffff; }
|
||||
|
||||
inline void set_pan(u8 pan) { m_pan = m_host.pan_dir[pan & 7]; }
|
||||
inline void set_pan(u8 pan) { m_pan = pan & 7; }
|
||||
|
||||
// getters
|
||||
inline bool enable() { return m_enable; }
|
||||
|
|
@ -97,21 +109,21 @@ class k053260_core : public vgsound_emu_core
|
|||
private:
|
||||
// registers
|
||||
k053260_core &m_host;
|
||||
u16 m_enable : 1; // enable flag
|
||||
u16 m_busy : 1; // busy status
|
||||
u16 m_loop : 1; // loop flag
|
||||
u16 m_adpcm : 1; // ADPCM flag
|
||||
u16 m_pitch : 12; // pitch
|
||||
u32 m_start = 0; // start position
|
||||
u16 m_length = 0; // source length
|
||||
u8 m_volume = 0; // master volume
|
||||
int m_pan = -1; // master pan
|
||||
u16 m_counter = 0; // frequency counter
|
||||
u32 m_addr = 0; // current address
|
||||
s32 m_remain = 0; // remain for end sample
|
||||
u8 m_bitpos = 4; // bit position for ADPCM decoding
|
||||
u8 m_data = 0; // current data
|
||||
s8 m_adpcm_buf = 0; // ADPCM buffer
|
||||
u16 m_enable : 1; // enable flag
|
||||
u16 m_busy : 1; // busy status
|
||||
u16 m_loop : 1; // loop flag
|
||||
u16 m_adpcm : 1; // ADPCM flag
|
||||
u16 m_pitch : 12; // pitch
|
||||
u32 m_start = 0; // start position
|
||||
u16 m_length = 0; // source length
|
||||
u8 m_volume = 0; // master volume
|
||||
int m_pan = -1; // master pan
|
||||
u16 m_counter = 0; // frequency counter
|
||||
u32 m_addr = 0; // current address
|
||||
s32 m_remain = 0; // remain for end sample
|
||||
u8 m_bitpos = 4; // bit position for ADPCM decoding
|
||||
u8 m_data = 0; // current data
|
||||
s8 m_output = 0; // ADPCM buffer
|
||||
std::array<s32, 2> m_out; // current output
|
||||
};
|
||||
|
||||
|
|
@ -152,6 +164,7 @@ class k053260_core : public vgsound_emu_core
|
|||
u8 m_input_en : 2; // Input enable
|
||||
};
|
||||
|
||||
/*
|
||||
class ym3012_t
|
||||
{
|
||||
public:
|
||||
|
|
@ -177,7 +190,9 @@ class k053260_core : public vgsound_emu_core
|
|||
std::array<s32, 2> m_in;
|
||||
std::array<s32, 2> m_out;
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
class dac_t
|
||||
{
|
||||
public:
|
||||
|
|
@ -205,6 +220,7 @@ class k053260_core : public vgsound_emu_core
|
|||
u8 m_clock : 4; // DAC clock (16 clock)
|
||||
u8 m_state : 2; // DAC state (4 state - SAM1, SAM2)
|
||||
};
|
||||
*/
|
||||
|
||||
public:
|
||||
// constructor
|
||||
|
|
@ -213,8 +229,8 @@ class k053260_core : public vgsound_emu_core
|
|||
, m_voice{*this, *this, *this, *this}
|
||||
, m_intf(intf)
|
||||
, m_ctrl(ctrl_t())
|
||||
, m_ym3012(ym3012_t())
|
||||
, m_dac(dac_t())
|
||||
//, m_ym3012(ym3012_t())
|
||||
//, m_dac(dac_t())
|
||||
{
|
||||
m_host2snd.fill(0);
|
||||
m_snd2host.fill(0);
|
||||
|
|
@ -233,7 +249,7 @@ class k053260_core : public vgsound_emu_core
|
|||
|
||||
// internal state
|
||||
void reset();
|
||||
void tick();
|
||||
void tick(u32 cycle);
|
||||
|
||||
// getters for debug, trackers, etc
|
||||
inline s32 output(u8 ch) { return m_out[ch & 1]; } // output for each channels
|
||||
|
|
@ -245,6 +261,11 @@ class k053260_core : public vgsound_emu_core
|
|||
return (voice < 4) ? m_voice[voice].out(ch & 1) : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline s32 pan_lut(const u8 pan, const u8 out) { return m_pan_lut[pan][out]; }
|
||||
|
||||
inline s32 adpcm_lut(const u8 nibble) { return m_adpcm_lut[nibble]; }
|
||||
|
||||
private:
|
||||
std::array<voice_t, 4> m_voice;
|
||||
k053260_intf &m_intf; // common memory interface
|
||||
|
|
@ -254,8 +275,8 @@ class k053260_core : public vgsound_emu_core
|
|||
|
||||
ctrl_t m_ctrl; // chip control
|
||||
|
||||
ym3012_t m_ym3012; // YM3012 output
|
||||
dac_t m_dac; // YM3012 interface
|
||||
//ym3012_t m_ym3012; // YM3012 output
|
||||
//dac_t m_dac; // YM3012 interface
|
||||
|
||||
std::array<u8, 64> m_reg; // register pool
|
||||
std::array<s32, 2> m_out; // stereo output
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue