ES5506: and more optimization...

This commit is contained in:
tildearrow 2023-02-11 16:11:39 -05:00
parent c0190b81cb
commit 0533f10ef4
5 changed files with 31 additions and 275 deletions

View File

@ -13,180 +13,6 @@
// DO NOT USE THIS ONE!
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
@ -195,7 +21,7 @@ void es5506_core::tick_perf()
// output
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)
{
for (int c = 0; c < 6; c++)
@ -218,55 +44,37 @@ void es5506_core::tick_perf()
}
}
bool bounce=m_voice_end;
// update
if (bounce) {
// 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) {
voice_tick();
// rising edge
m_e.edge().set(true);
m_intf.e_pin(true);
m_host_intf.update_strobe();
}
}
void es5506_core::voice_tick()
{
// Voice updates every 2 E clock cycle (or 4 BCLK clock cycle)
// 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
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_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();
}
m_ch[i].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())
{
// Send to output
m_output[0] = m_mute ? 0 : volume_calc(m_lvol, sign_ext<s32>(m_filter.o4_1(), 16));
m_output[1] = m_mute ? 0 : volume_calc(m_rvol, 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, (short)m_filter.o4_1());
m_ch.set_left(m_output[0]);
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);
// 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
@ -426,36 +234,16 @@ void es5506_core::voice_t::reset()
// Accessors
u8 es5506_core::host_r(u8 address)
{
if (!m_host_intf.m_host_access)
{
m_ha = address;
if (m_e.rising_edge())
{ // update directly
m_hd = read(m_ha, true);
}
else
{
m_host_intf.set_strobe(true);
}
}
return m_hd;
}
void es5506_core::host_w(u8 address, u8 data)
{
if (!m_host_intf.m_host_access)
{
m_ha = address;
m_hd = data;
if (m_e.rising_edge())
{ // update directly
write(m_ha, m_hd);
}
else
{
m_host_intf.set_strobe(false);
}
}
}
u8 es5506_core::read(u8 address, bool cpu_access)

View File

@ -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()
{
if (m_cr.irqe())
{ // Set IRQ
m_cr.set_irq(true);
}
if (m_cr.dir()) // Reverse playback
{
if (m_cr.lpe()) // Loop enable

View File

@ -115,22 +115,6 @@ const char** DivPlatformES5506::getRegisterSheet() {
void DivPlatformES5506::acquire(short** buf, size_t len) {
int coL[6], coR[6];
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
while (!hostIntf32.empty()) {
QueuedHostIntf w=hostIntf32.front();
@ -147,35 +131,26 @@ void DivPlatformES5506::acquire(short** buf, size_t len) {
}
hostIntf32.pop();
}
for (int i=0; i<32; i++) {
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);
}
}
es5506.tick_perf();
for (int o=0; o<6; o++) {
coL[o]>>=3;
coR[o]>>=3;
coL[o]=es5506.lout(o);
coR[o]=es5506.rout(o);
}
for (int o=0; o<6; o++) {
buf[(o<<1)|0][h]=coL[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) {
if (state) { // host interface
if (cycle) { // wait until delay
cycle--;
} else if (!hostIntf8.empty()) {
if (cycle>0) { // wait until delay
cycle-=2;
} else while (!hostIntf8.empty()) {
QueuedHostIntf w=hostIntf8.front();
unsigned char shift=24-(w.step<<3);
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);
isMasked=true;
}
if (cycle>0) break;
}
}
}
@ -1141,7 +1117,6 @@ void DivPlatformES5506::reset() {
irqv=0x80;
isMasked=false;
irqTrigger=false;
prevChanCycle=0;
chanMax=initChanMax;
pageWriteMask(0x00,0x60,0x0b,chanMax);

View File

@ -272,7 +272,6 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
bool isMasked, isReaded;
bool irqTrigger;
unsigned int curCR;
unsigned char prevChanCycle;
unsigned char initChanMax, chanMax;

View File

@ -500,7 +500,6 @@ void putDispatchChip(void* data, int type) {
ImGui::Text("- maskedVal: %.2x",ch->maskedVal);
ImGui::Text("- irqv: %.2x",ch->irqv);
ImGui::Text("- curCR: %.8x",ch->curCR);
ImGui::Text("- prevChanCycle: %d",ch->prevChanCycle);
ImGui::Text("- initChanMax: %d",ch->initChanMax);
ImGui::Text("- chanMax: %d",ch->chanMax);
COMMON_CHIP_DEBUG_BOOL;