ES5506: and more optimization...
This commit is contained in:
parent
c0190b81cb
commit
0533f10ef4
|
@ -13,180 +13,6 @@
|
||||||
// DO NOT USE THIS ONE!
|
// DO NOT USE THIS ONE!
|
||||||
void es5506_core::tick()
|
void es5506_core::tick()
|
||||||
{
|
{
|
||||||
// CLKIN
|
|
||||||
if (m_clkin.tick())
|
|
||||||
{
|
|
||||||
// BCLK
|
|
||||||
if (m_clkin.edge().changed() && (!m_mode.bclk_en())) // BCLK is freely running clock
|
|
||||||
{
|
|
||||||
if (m_bclk.tick())
|
|
||||||
{
|
|
||||||
m_intf.bclk(m_bclk.current_edge());
|
|
||||||
// Serial output
|
|
||||||
if (!m_mode.lrclk_en())
|
|
||||||
{
|
|
||||||
if (m_bclk.falling_edge())
|
|
||||||
{
|
|
||||||
// LRCLK
|
|
||||||
if (m_lrclk.tick())
|
|
||||||
{
|
|
||||||
m_intf.lrclk(m_lrclk.current_edge());
|
|
||||||
if (m_lrclk.rising_edge())
|
|
||||||
{
|
|
||||||
m_w_st_curr = m_w_st;
|
|
||||||
m_w_end_curr = m_w_end;
|
|
||||||
}
|
|
||||||
if (m_lrclk.falling_edge())
|
|
||||||
{ // update width
|
|
||||||
m_lrclk.set_width_latch(m_lr_end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// WCLK
|
|
||||||
if (!m_mode.wclk_en())
|
|
||||||
{
|
|
||||||
if (!m_mode.lrclk_en())
|
|
||||||
{
|
|
||||||
if (m_lrclk.edge().changed())
|
|
||||||
{
|
|
||||||
m_wclk = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_bclk.falling_edge())
|
|
||||||
{
|
|
||||||
if (m_wclk == m_w_st_curr)
|
|
||||||
{
|
|
||||||
m_intf.wclk(true);
|
|
||||||
if (m_lrclk.current_edge())
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
// copy output
|
|
||||||
m_output[i].copy_output(m_output_temp[i]);
|
|
||||||
// clamp to 20 bit (upper 3 bits are
|
|
||||||
// overflow guard bits)
|
|
||||||
m_output_latch[i].clamp20(m_ch[i]);
|
|
||||||
m_output_temp[i].reset();
|
|
||||||
m_output_latch[i].clamp20();
|
|
||||||
// set signed
|
|
||||||
if (m_output_latch[i].left() < 0)
|
|
||||||
{
|
|
||||||
m_output_temp[i].set_left(-1);
|
|
||||||
}
|
|
||||||
if (m_output_latch[i].right() < 0)
|
|
||||||
{
|
|
||||||
m_output_temp[i].set_right(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_wclk_lr = m_lrclk.current_edge();
|
|
||||||
m_output_bit = 20;
|
|
||||||
}
|
|
||||||
if (m_wclk < m_w_end_curr)
|
|
||||||
{
|
|
||||||
s8 output_bit = --m_output_bit;
|
|
||||||
if (m_output_bit >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (m_wclk_lr)
|
|
||||||
{
|
|
||||||
// Right output
|
|
||||||
m_output_temp[i].serial_in(
|
|
||||||
m_wclk_lr,
|
|
||||||
bitfield(m_output_latch[i].right(), output_bit));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Left output
|
|
||||||
m_output_temp[i].serial_in(
|
|
||||||
m_wclk_lr,
|
|
||||||
bitfield(m_output_latch[i].left(), output_bit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_wclk == m_w_end_curr)
|
|
||||||
{
|
|
||||||
m_intf.wclk(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_wclk++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// /CAS, E
|
|
||||||
if (m_clkin.falling_edge()) // falling edge triggers /CAS, E clock
|
|
||||||
{
|
|
||||||
// /CAS
|
|
||||||
if (m_cas.tick())
|
|
||||||
{
|
|
||||||
// single OTTO master mode, /CAS high, E low: get sample address
|
|
||||||
// single OTTO early mode, /CAS falling, E high: get sample
|
|
||||||
// address
|
|
||||||
if (m_cas.falling_edge())
|
|
||||||
{
|
|
||||||
if (!m_e.current_edge())
|
|
||||||
{
|
|
||||||
// single OTTO master mode, /CAS low, E low: fetch
|
|
||||||
// sample
|
|
||||||
if (m_mode.master())
|
|
||||||
{
|
|
||||||
m_voice[m_voice_cycle].fetch(m_voice_fetch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_e.current_edge())
|
|
||||||
{
|
|
||||||
// dual OTTO slave mode, /CAS low, E high: fetch sample
|
|
||||||
if (m_mode.dual() && (!m_mode.master()))
|
|
||||||
{ // Dual OTTO, slave mode
|
|
||||||
m_voice[m_voice_cycle].fetch(m_voice_fetch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// E
|
|
||||||
if (m_e.tick())
|
|
||||||
{
|
|
||||||
m_intf.e_pin(m_e.current_edge());
|
|
||||||
if (m_e.rising_edge())
|
|
||||||
{
|
|
||||||
m_host_intf.update_strobe();
|
|
||||||
}
|
|
||||||
else if (m_e.falling_edge())
|
|
||||||
{
|
|
||||||
m_host_intf.clear_host_access();
|
|
||||||
voice_tick();
|
|
||||||
}
|
|
||||||
if (m_e.current_edge()) // Host interface
|
|
||||||
{
|
|
||||||
if (m_host_intf.m_host_access)
|
|
||||||
{
|
|
||||||
if (m_host_intf.m_rw && (m_e.cycle() == 0)) // Read
|
|
||||||
{
|
|
||||||
m_hd = read(m_ha);
|
|
||||||
m_host_intf.clear_host_access();
|
|
||||||
}
|
|
||||||
else if ((!m_host_intf.m_rw) && (m_e.cycle() == 2))
|
|
||||||
{ // Write
|
|
||||||
write(m_ha, m_hd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!m_e.current_edge())
|
|
||||||
{
|
|
||||||
if (m_e.cycle() == 2)
|
|
||||||
{
|
|
||||||
// reset host access state
|
|
||||||
m_hd = 0;
|
|
||||||
m_host_intf.clear_strobe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// less cycle accurate, but less CPU heavy routine
|
// less cycle accurate, but less CPU heavy routine
|
||||||
|
@ -195,7 +21,7 @@ void es5506_core::tick_perf()
|
||||||
// output
|
// output
|
||||||
if (((!m_mode.lrclk_en()) && (!m_mode.bclk_en()) && (!m_mode.wclk_en())) && (m_w_st < m_w_end))
|
if (((!m_mode.lrclk_en()) && (!m_mode.bclk_en()) && (!m_mode.wclk_en())) && (m_w_st < m_w_end))
|
||||||
{
|
{
|
||||||
const int output_bits = (20 - (m_w_end - m_w_st)) * 2;
|
const int output_bits = (20 - (m_w_end - m_w_st));
|
||||||
if (output_bits < 20)
|
if (output_bits < 20)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < 6; c++)
|
for (int c = 0; c < 6; c++)
|
||||||
|
@ -218,55 +44,37 @@ void es5506_core::tick_perf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bounce=m_voice_end;
|
|
||||||
|
|
||||||
// update
|
// update
|
||||||
if (bounce) {
|
voice_tick();
|
||||||
// falling edge
|
|
||||||
m_e.edge().set(false);
|
|
||||||
m_intf.e_pin(false);
|
|
||||||
m_host_intf.clear_host_access();
|
|
||||||
m_host_intf.clear_strobe();
|
|
||||||
}
|
|
||||||
m_voice[m_voice_cycle].fetch(0);
|
|
||||||
voice_tick();
|
|
||||||
if (bounce) {
|
|
||||||
// rising edge
|
// rising edge
|
||||||
m_e.edge().set(true);
|
|
||||||
m_intf.e_pin(true);
|
m_intf.e_pin(true);
|
||||||
m_host_intf.update_strobe();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void es5506_core::voice_tick()
|
void es5506_core::voice_tick()
|
||||||
{
|
{
|
||||||
// Voice updates every 2 E clock cycle (or 4 BCLK clock cycle)
|
// Voice updates every 2 E clock cycle (or 4 BCLK clock cycle)
|
||||||
// Update voice
|
// Update voice
|
||||||
m_voice[m_voice_cycle].tick(m_voice_cycle);
|
for (int i=0; i<VGS_CLAMP(m_active,4,31); i++) {
|
||||||
|
m_voice[i].fetch(0);
|
||||||
|
m_voice[i].tick(i);
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh output
|
// Refresh output
|
||||||
if ((++m_voice_cycle) > VGS_CLAMP(m_active, 4, 31)) // 5 ~ 32 voices
|
m_voice_end = true;
|
||||||
|
m_voice_cycle = 0;
|
||||||
|
for (int i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
m_voice_end = true;
|
m_ch[i].reset();
|
||||||
m_voice_cycle = 0;
|
|
||||||
for (int i=0; i<6; i++)
|
|
||||||
{
|
|
||||||
m_ch[i].reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<32; i++)
|
|
||||||
{
|
|
||||||
const u8 ca = m_voice[i].cr().ca()&7;
|
|
||||||
if (ca < 6)
|
|
||||||
{
|
|
||||||
m_ch[ca] += m_voice[i].ch();
|
|
||||||
}
|
|
||||||
m_voice[i].ch().reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
for (int i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
m_voice_end = false;
|
const u8 ca = m_voice[i].cr().ca()&7;
|
||||||
|
if (ca < 6)
|
||||||
|
{
|
||||||
|
m_ch[ca] += m_voice[i].ch();
|
||||||
|
}
|
||||||
|
m_voice[i].ch().reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +110,8 @@ void es5506_core::voice_t::tick(u8 voice)
|
||||||
if (m_alu.busy())
|
if (m_alu.busy())
|
||||||
{
|
{
|
||||||
// Send to output
|
// Send to output
|
||||||
m_output[0] = m_mute ? 0 : volume_calc(m_lvol, sign_ext<s32>(m_filter.o4_1(), 16));
|
m_output[0] = m_mute ? 0 : volume_calc(m_lvol, (short)m_filter.o4_1());
|
||||||
m_output[1] = m_mute ? 0 : volume_calc(m_rvol, sign_ext<s32>(m_filter.o4_1(), 16));
|
m_output[1] = m_mute ? 0 : volume_calc(m_rvol, (short)m_filter.o4_1());
|
||||||
|
|
||||||
m_ch.set_left(m_output[0]);
|
m_ch.set_left(m_output[0]);
|
||||||
m_ch.set_right(m_output[1]);
|
m_ch.set_right(m_output[1]);
|
||||||
|
@ -346,7 +154,7 @@ void es5506_core::voice_t::tick(u8 voice)
|
||||||
m_filtcount = bitfield(m_filtcount + 1, 0, 3);
|
m_filtcount = bitfield(m_filtcount + 1, 0, 3);
|
||||||
|
|
||||||
// Update IRQ
|
// Update IRQ
|
||||||
m_alu.irq_exec(m_host.m_intf, m_host.m_irqv, voice);
|
//m_alu.irq_exec(m_host.m_intf, m_host.m_irqv, voice);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compressed format
|
// Compressed format
|
||||||
|
@ -426,36 +234,16 @@ void es5506_core::voice_t::reset()
|
||||||
// Accessors
|
// Accessors
|
||||||
u8 es5506_core::host_r(u8 address)
|
u8 es5506_core::host_r(u8 address)
|
||||||
{
|
{
|
||||||
if (!m_host_intf.m_host_access)
|
|
||||||
{
|
|
||||||
m_ha = address;
|
m_ha = address;
|
||||||
if (m_e.rising_edge())
|
|
||||||
{ // update directly
|
|
||||||
m_hd = read(m_ha, true);
|
m_hd = read(m_ha, true);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_host_intf.set_strobe(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m_hd;
|
return m_hd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void es5506_core::host_w(u8 address, u8 data)
|
void es5506_core::host_w(u8 address, u8 data)
|
||||||
{
|
{
|
||||||
if (!m_host_intf.m_host_access)
|
|
||||||
{
|
|
||||||
m_ha = address;
|
m_ha = address;
|
||||||
m_hd = data;
|
m_hd = data;
|
||||||
if (m_e.rising_edge())
|
|
||||||
{ // update directly
|
|
||||||
write(m_ha, m_hd);
|
write(m_ha, m_hd);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_host_intf.set_strobe(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 es5506_core::read(u8 address, bool cpu_access)
|
u8 es5506_core::read(u8 address, bool cpu_access)
|
||||||
|
|
|
@ -41,11 +41,6 @@ bool es550x_shared_core::es550x_voice_t::es550x_alu_t::tick()
|
||||||
|
|
||||||
void es550x_shared_core::es550x_voice_t::es550x_alu_t::loop_exec()
|
void es550x_shared_core::es550x_voice_t::es550x_alu_t::loop_exec()
|
||||||
{
|
{
|
||||||
if (m_cr.irqe())
|
|
||||||
{ // Set IRQ
|
|
||||||
m_cr.set_irq(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_cr.dir()) // Reverse playback
|
if (m_cr.dir()) // Reverse playback
|
||||||
{
|
{
|
||||||
if (m_cr.lpe()) // Loop enable
|
if (m_cr.lpe()) // Loop enable
|
||||||
|
|
|
@ -115,22 +115,6 @@ const char** DivPlatformES5506::getRegisterSheet() {
|
||||||
void DivPlatformES5506::acquire(short** buf, size_t len) {
|
void DivPlatformES5506::acquire(short** buf, size_t len) {
|
||||||
int coL[6], coR[6];
|
int coL[6], coR[6];
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
coL[0]=0;
|
|
||||||
coL[1]=0;
|
|
||||||
coL[2]=0;
|
|
||||||
coL[3]=0;
|
|
||||||
coL[4]=0;
|
|
||||||
coL[5]=0;
|
|
||||||
coR[0]=0;
|
|
||||||
coR[1]=0;
|
|
||||||
coR[2]=0;
|
|
||||||
coR[3]=0;
|
|
||||||
coR[4]=0;
|
|
||||||
coR[5]=0;
|
|
||||||
|
|
||||||
for (int i=31; i>(int)chanMax; i--) {
|
|
||||||
oscBuf[i]->data[oscBuf[i]->needle++]=0;
|
|
||||||
}
|
|
||||||
// convert 32 bit access to 8 bit host interface
|
// convert 32 bit access to 8 bit host interface
|
||||||
while (!hostIntf32.empty()) {
|
while (!hostIntf32.empty()) {
|
||||||
QueuedHostIntf w=hostIntf32.front();
|
QueuedHostIntf w=hostIntf32.front();
|
||||||
|
@ -147,35 +131,26 @@ void DivPlatformES5506::acquire(short** buf, size_t len) {
|
||||||
}
|
}
|
||||||
hostIntf32.pop();
|
hostIntf32.pop();
|
||||||
}
|
}
|
||||||
for (int i=0; i<32; i++) {
|
es5506.tick_perf();
|
||||||
prevChanCycle=es5506.voice_cycle();
|
|
||||||
es5506.tick_perf();
|
|
||||||
if (es5506.voice_end()) {
|
|
||||||
for (int j=chanMax; j>=0; j--) {
|
|
||||||
oscBuf[j]->data[oscBuf[j]->needle++]=(es5506.voice_lout(j)+es5506.voice_rout(j))>>5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int o=0; o<6; o++) {
|
|
||||||
coL[o]+=es5506.lout(o);
|
|
||||||
coR[o]+=es5506.rout(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int o=0; o<6; o++) {
|
for (int o=0; o<6; o++) {
|
||||||
coL[o]>>=3;
|
coL[o]=es5506.lout(o);
|
||||||
coR[o]>>=3;
|
coR[o]=es5506.rout(o);
|
||||||
}
|
}
|
||||||
for (int o=0; o<6; o++) {
|
for (int o=0; o<6; o++) {
|
||||||
buf[(o<<1)|0][h]=coL[o];
|
buf[(o<<1)|0][h]=coL[o];
|
||||||
buf[(o<<1)|1][h]=coR[o];
|
buf[(o<<1)|1][h]=coR[o];
|
||||||
}
|
}
|
||||||
|
for (int i=chanMax; i>=0; i--) {
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=(es5506.voice_lout(i)+es5506.voice_rout(i))>>5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformES5506::e_pin(bool state) {
|
void DivPlatformES5506::e_pin(bool state) {
|
||||||
if (state) { // host interface
|
if (state) { // host interface
|
||||||
if (cycle) { // wait until delay
|
if (cycle>0) { // wait until delay
|
||||||
cycle--;
|
cycle-=2;
|
||||||
} else if (!hostIntf8.empty()) {
|
} else while (!hostIntf8.empty()) {
|
||||||
QueuedHostIntf w=hostIntf8.front();
|
QueuedHostIntf w=hostIntf8.front();
|
||||||
unsigned char shift=24-(w.step<<3);
|
unsigned char shift=24-(w.step<<3);
|
||||||
if (w.isRead) {
|
if (w.isRead) {
|
||||||
|
@ -200,6 +175,7 @@ void DivPlatformES5506::e_pin(bool state) {
|
||||||
maskedVal=((w.val>>shift)&mask)|(es5506.host_r((w.addr<<2)+w.step)&~mask);
|
maskedVal=((w.val>>shift)&mask)|(es5506.host_r((w.addr<<2)+w.step)&~mask);
|
||||||
isMasked=true;
|
isMasked=true;
|
||||||
}
|
}
|
||||||
|
if (cycle>0) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1141,7 +1117,6 @@ void DivPlatformES5506::reset() {
|
||||||
irqv=0x80;
|
irqv=0x80;
|
||||||
isMasked=false;
|
isMasked=false;
|
||||||
irqTrigger=false;
|
irqTrigger=false;
|
||||||
prevChanCycle=0;
|
|
||||||
chanMax=initChanMax;
|
chanMax=initChanMax;
|
||||||
|
|
||||||
pageWriteMask(0x00,0x60,0x0b,chanMax);
|
pageWriteMask(0x00,0x60,0x0b,chanMax);
|
||||||
|
|
|
@ -272,7 +272,6 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
bool isMasked, isReaded;
|
bool isMasked, isReaded;
|
||||||
bool irqTrigger;
|
bool irqTrigger;
|
||||||
unsigned int curCR;
|
unsigned int curCR;
|
||||||
unsigned char prevChanCycle;
|
|
||||||
|
|
||||||
unsigned char initChanMax, chanMax;
|
unsigned char initChanMax, chanMax;
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,6 @@ void putDispatchChip(void* data, int type) {
|
||||||
ImGui::Text("- maskedVal: %.2x",ch->maskedVal);
|
ImGui::Text("- maskedVal: %.2x",ch->maskedVal);
|
||||||
ImGui::Text("- irqv: %.2x",ch->irqv);
|
ImGui::Text("- irqv: %.2x",ch->irqv);
|
||||||
ImGui::Text("- curCR: %.8x",ch->curCR);
|
ImGui::Text("- curCR: %.8x",ch->curCR);
|
||||||
ImGui::Text("- prevChanCycle: %d",ch->prevChanCycle);
|
|
||||||
ImGui::Text("- initChanMax: %d",ch->initChanMax);
|
ImGui::Text("- initChanMax: %d",ch->initChanMax);
|
||||||
ImGui::Text("- chanMax: %d",ch->chanMax);
|
ImGui::Text("- chanMax: %d",ch->chanMax);
|
||||||
COMMON_CHIP_DEBUG_BOOL;
|
COMMON_CHIP_DEBUG_BOOL;
|
||||||
|
|
Loading…
Reference in New Issue