Revert "temp revert for for 0.263 of e4e5f3d918"

This reverts commit 34cf9cbaea.
This commit is contained in:
hap 2024-02-24 16:11:17 +01:00
parent 9827b7f547
commit d1501f28eb
2 changed files with 182 additions and 97 deletions

View File

@ -24,8 +24,8 @@ h8_sci_device::h8_sci_device(const machine_config &mconfig, const char *tag, dev
m_cpu(*this, finder_base::DUMMY_TAG),
m_intc(*this, finder_base::DUMMY_TAG),
m_external_to_internal_ratio(0), m_internal_to_external_ratio(0), m_sync_timer(nullptr), m_id(0), m_eri_int(0), m_rxi_int(0), m_txi_int(0), m_tei_int(0),
m_tx_state(0), m_rx_state(0), m_tx_bit(0), m_rx_bit(0), m_clock_state(0), m_tx_parity(0), m_rx_parity(0), m_ext_clock_counter(0), m_clock_mode(clock_mode_t::INTERNAL_ASYNC), m_clock_value(false), m_ext_clock_value(false), m_rx_value(false),
m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_brr(0), m_rsr(0), m_tsr(0), m_clock_base(0), m_divider(0)
m_tx_state(0), m_rx_state(0), m_tx_bit(0), m_rx_bit(0), m_clock_state(0), m_tx_parity(0), m_rx_parity(0), m_tx_ext_clock_counter(0), m_rx_ext_clock_counter(0), m_clock_mode(clock_mode_t::INTERNAL_ASYNC), m_tx_clock_value(false), m_rx_clock_value(false), m_ext_clock_value(false), m_rx_value(false),
m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_brr(0), m_rsr(0), m_tsr(0), m_tx_clock_base(0), m_rx_clock_base(0), m_divider(0)
{
m_external_clock_period = attotime::never;
}
@ -263,11 +263,14 @@ void h8_sci_device::device_start()
save_item(NAME(m_tx_state));
save_item(NAME(m_tx_parity));
save_item(NAME(m_clock_state));
save_item(NAME(m_clock_value));
save_item(NAME(m_clock_base));
save_item(NAME(m_tx_clock_value));
save_item(NAME(m_rx_clock_value));
save_item(NAME(m_tx_clock_base));
save_item(NAME(m_rx_clock_base));
save_item(NAME(m_divider));
save_item(NAME(m_ext_clock_value));
save_item(NAME(m_ext_clock_counter));
save_item(NAME(m_tx_ext_clock_counter));
save_item(NAME(m_rx_ext_clock_counter));
save_item(NAME(m_cur_sync_time));
}
@ -287,13 +290,16 @@ void h8_sci_device::device_reset()
m_rx_state = ST_IDLE;
m_clock_state = 0;
m_clock_mode = clock_mode_t::INTERNAL_ASYNC;
m_clock_base = 0;
m_tx_clock_base = 0;
m_rx_clock_base = 0;
clock_update();
m_clock_value = true;
m_tx_clock_value = true;
m_rx_clock_value = true;
m_ext_clock_value = true;
m_ext_clock_counter = 0;
m_tx_ext_clock_counter = 0;
m_rx_ext_clock_counter = 0;
m_rx_value = true;
m_cpu->do_sci_clk(m_id, m_clock_value);
m_cpu->do_sci_clk(m_id, m_tx_clock_value);
m_cpu->do_sci_tx(m_id, 1);
m_cur_sync_time = attotime::never;
}
@ -325,11 +331,12 @@ void h8_sci_device::do_clk_w(int state)
switch(m_clock_mode) {
case clock_mode_t::EXTERNAL_ASYNC:
if(m_ext_clock_value) {
m_ext_clock_counter = (m_ext_clock_counter+1) & 15;
m_tx_ext_clock_counter = (m_tx_ext_clock_counter+1) & 15;
m_rx_ext_clock_counter = (m_rx_ext_clock_counter+1) & 15;
if((m_clock_state & CLK_TX) && m_ext_clock_counter == 0)
if((m_clock_state & CLK_TX) && m_tx_ext_clock_counter == 0)
tx_dropped_edge();
if((m_clock_state & CLK_RX) && m_ext_clock_counter == 8)
if((m_clock_state & CLK_RX) && m_rx_ext_clock_counter == 8)
rx_raised_edge();
}
break;
@ -351,112 +358,179 @@ void h8_sci_device::do_clk_w(int state)
u64 h8_sci_device::internal_update(u64 current_time)
{
u64 event = 0;
u64 tx_event = 0, rx_event = 0;
switch(m_clock_mode) {
case clock_mode_t::INTERNAL_SYNC_OUT:
if(m_clock_state || !m_clock_value) {
if(m_clock_state & CLK_TX) {
u64 fp = m_divider*2;
if(current_time >= m_clock_base) {
u64 delta = current_time - m_clock_base;
if(current_time >= m_tx_clock_base) {
u64 delta = current_time - m_tx_clock_base;
if(delta >= fp) {
delta -= fp;
m_clock_base += fp;
m_tx_clock_base += fp;
}
assert(delta < fp);
bool new_clock = delta >= m_divider;
if(new_clock != m_clock_value) {
if(new_clock != m_tx_clock_value) {
machine().scheduler().synchronize();
if((!new_clock) && (m_clock_state & CLK_TX))
if(!new_clock)
tx_dropped_edge();
else if(new_clock && (m_clock_state & CLK_RX))
rx_raised_edge();
m_clock_value = new_clock;
if(m_clock_state || m_clock_value)
m_cpu->do_sci_clk(m_id, m_clock_value);
m_tx_clock_value = new_clock;
if(m_clock_state || m_tx_clock_value)
m_cpu->do_sci_clk(m_id, m_tx_clock_value);
}
}
event = m_clock_base + (m_clock_value ? fp : m_divider);
tx_event = m_tx_clock_base + (m_tx_clock_value ? fp : m_divider);
}
if(m_clock_state & CLK_RX) {
u64 fp = m_divider*2;
if(current_time >= m_rx_clock_base) {
u64 delta = current_time - m_rx_clock_base;
if(delta >= fp) {
delta -= fp;
m_rx_clock_base += fp;
}
assert(delta < fp);
bool new_clock = delta >= m_divider;
if(new_clock != m_rx_clock_value) {
machine().scheduler().synchronize();
if(new_clock)
rx_raised_edge();
m_rx_clock_value = new_clock;
}
}
rx_event = m_rx_clock_base + (m_rx_clock_value ? fp : m_divider);
}
break;
case clock_mode_t::INTERNAL_ASYNC:
case clock_mode_t::INTERNAL_ASYNC_OUT:
if(m_clock_state || !m_clock_value) {
if(m_clock_state & CLK_TX) {
u64 fp = m_divider*16;
if(current_time >= m_clock_base) {
u64 delta = current_time - m_clock_base;
if(current_time >= m_tx_clock_base) {
u64 delta = current_time - m_tx_clock_base;
if(delta >= fp) {
delta -= fp;
m_clock_base += fp;
m_tx_clock_base += fp;
}
assert(delta < fp);
bool new_clock = delta >= m_divider*8;
if(new_clock != m_clock_value) {
if(new_clock != m_tx_clock_value) {
machine().scheduler().synchronize();
if((!new_clock) && (m_clock_state & CLK_TX))
if(!new_clock)
tx_dropped_edge();
else if(new_clock && (m_clock_state & CLK_RX))
rx_raised_edge();
m_clock_value = new_clock;
if(m_clock_mode == clock_mode_t::INTERNAL_ASYNC_OUT && (m_clock_state || !m_clock_value))
m_cpu->do_sci_clk(m_id, m_clock_value);
m_tx_clock_value = new_clock;
if(m_clock_mode == clock_mode_t::INTERNAL_ASYNC_OUT && (m_clock_state || !m_tx_clock_value))
m_cpu->do_sci_clk(m_id, m_tx_clock_value);
}
}
tx_event = m_tx_clock_base + (m_tx_clock_value ? fp : m_divider*8);
}
event = m_clock_base + (m_clock_value ? fp : m_divider*8);
if(m_clock_state & CLK_RX) {
u64 fp = m_divider*16;
if(current_time >= m_rx_clock_base) {
u64 delta = current_time - m_rx_clock_base;
if(delta >= fp) {
delta -= fp;
m_rx_clock_base += fp;
}
assert(delta < fp);
bool new_clock = delta >= m_divider*8;
if(new_clock != m_rx_clock_value) {
machine().scheduler().synchronize();
if(new_clock)
rx_raised_edge();
m_rx_clock_value = new_clock;
if(m_clock_mode == clock_mode_t::INTERNAL_ASYNC_OUT && (m_clock_state || !m_rx_clock_value))
m_cpu->do_sci_clk(m_id, m_rx_clock_value);
}
}
rx_event = m_rx_clock_base + (m_rx_clock_value ? fp : m_divider*8);
}
break;
case clock_mode_t::EXTERNAL_RATE_SYNC:
if(m_clock_state || !m_clock_value) {
if(m_clock_state & CLK_TX) {
u64 ctime = u64(current_time*m_internal_to_external_ratio*2);
if(ctime >= m_clock_base) {
u64 delta = ctime - m_clock_base;
m_clock_base += delta & ~1;
if(ctime >= m_tx_clock_base) {
u64 delta = ctime - m_tx_clock_base;
m_tx_clock_base += delta & ~1;
delta &= 1;
bool new_clock = delta >= 1;
if(new_clock != m_clock_value) {
if(new_clock != m_tx_clock_value) {
machine().scheduler().synchronize();
if((!new_clock) && (m_clock_state & CLK_TX))
if(!new_clock)
tx_dropped_edge();
else if(new_clock && (m_clock_state & CLK_RX))
rx_raised_edge();
m_clock_value = new_clock;
m_tx_clock_value = new_clock;
}
}
event = u64((m_clock_base + (m_clock_value ? 2 : 1))*m_external_to_internal_ratio)+1;
tx_event = u64((m_tx_clock_base + (m_tx_clock_value ? 2 : 1))*m_external_to_internal_ratio)+1;
}
if(m_clock_state & CLK_RX) {
u64 ctime = u64(current_time*m_internal_to_external_ratio*2);
if(ctime >= m_rx_clock_base) {
u64 delta = ctime - m_rx_clock_base;
m_rx_clock_base += delta & ~1;
delta &= 1;
bool new_clock = delta >= 1;
if(new_clock != m_rx_clock_value) {
machine().scheduler().synchronize();
if(new_clock)
rx_raised_edge();
m_rx_clock_value = new_clock;
}
}
rx_event = u64((m_rx_clock_base + (m_rx_clock_value ? 2 : 1))*m_external_to_internal_ratio)+1;
}
break;
case clock_mode_t::EXTERNAL_RATE_ASYNC:
if(m_clock_state || !m_clock_value) {
if(m_clock_state & CLK_TX) {
u64 ctime = u64(current_time*m_internal_to_external_ratio);
if(ctime >= m_clock_base) {
u64 delta = ctime - m_clock_base;
m_clock_base += delta & ~15;
if(ctime >= m_tx_clock_base) {
u64 delta = ctime - m_tx_clock_base;
m_tx_clock_base += delta & ~15;
delta &= 15;
bool new_clock = delta >= 8;
if(new_clock != m_clock_value) {
if(new_clock != m_tx_clock_value) {
machine().scheduler().synchronize();
if((!new_clock) && (m_clock_state & CLK_TX))
if(!new_clock)
tx_dropped_edge();
else if(new_clock && (m_clock_state & CLK_RX))
rx_raised_edge();
m_clock_value = new_clock;
m_tx_clock_value = new_clock;
}
}
event = u64((m_clock_base + (m_clock_value ? 16 : 8))*m_external_to_internal_ratio)+1;
tx_event = u64((m_tx_clock_base + (m_tx_clock_value ? 16 : 8))*m_external_to_internal_ratio)+1;
}
if(m_clock_state & CLK_RX) {
u64 ctime = u64(current_time*m_internal_to_external_ratio);
if(ctime >= m_rx_clock_base) {
u64 delta = ctime - m_rx_clock_base;
m_rx_clock_base += delta & ~15;
delta &= 15;
bool new_clock = delta >= 8;
if(new_clock != m_rx_clock_value) {
machine().scheduler().synchronize();
if(new_clock)
rx_raised_edge();
m_rx_clock_value = new_clock;
}
}
rx_event = u64((m_rx_clock_base + (m_rx_clock_value ? 16 : 8))*m_external_to_internal_ratio)+1;
}
break;
@ -464,6 +538,9 @@ u64 h8_sci_device::internal_update(u64 current_time)
case clock_mode_t::EXTERNAL_SYNC:
break;
}
u64 event = rx_event;
if(!event || (tx_event && tx_event < event))
event = tx_event;
if(event) {
attotime ctime = machine().time();
attotime sync_time = attotime::from_ticks(event-10, m_cpu->clock());
@ -472,7 +549,6 @@ u64 h8_sci_device::internal_update(u64 current_time)
m_cur_sync_time = sync_time;
}
}
return event;
}
@ -482,41 +558,50 @@ void h8_sci_device::clock_start(int mode)
if(m_clock_state & mode)
return;
if(!m_clock_state) {
machine().scheduler().synchronize();
m_clock_state = mode;
switch(m_clock_mode) {
case clock_mode_t::INTERNAL_ASYNC:
case clock_mode_t::INTERNAL_ASYNC_OUT:
case clock_mode_t::INTERNAL_SYNC_OUT:
if(V>=2) logerror("Starting internal clock\n");
m_clock_base = m_cpu->total_cycles();
m_cpu->internal_update();
break;
machine().scheduler().synchronize();
m_clock_state |= mode;
switch(m_clock_mode) {
case clock_mode_t::INTERNAL_ASYNC:
case clock_mode_t::INTERNAL_ASYNC_OUT:
case clock_mode_t::INTERNAL_SYNC_OUT:
if(V>=1) logerror("Starting internal clock\n");
if(mode == CLK_TX)
m_tx_clock_base = machine().time().as_ticks(m_cpu->clock());
else
m_rx_clock_base = machine().time().as_ticks(m_cpu->clock());
m_cpu->internal_update();
break;
case clock_mode_t::EXTERNAL_RATE_ASYNC:
if(V>=2) logerror("Simulating external clock async\n");
m_clock_base = u64(m_cpu->total_cycles()*m_internal_to_external_ratio);
m_cpu->internal_update();
break;
case clock_mode_t::EXTERNAL_RATE_ASYNC:
if(V>=1) logerror("Simulating external clock async\n");
if(mode == CLK_TX)
m_tx_clock_base = u64(m_cpu->total_cycles()*m_internal_to_external_ratio);
else
m_rx_clock_base = u64(m_cpu->total_cycles()*m_internal_to_external_ratio);
m_cpu->internal_update();
break;
case clock_mode_t::EXTERNAL_RATE_SYNC:
if(V>=2) logerror("Simulating external clock sync\n");
m_clock_base = u64(m_cpu->total_cycles()*2*m_internal_to_external_ratio);
m_cpu->internal_update();
break;
case clock_mode_t::EXTERNAL_RATE_SYNC:
if(V>=1) logerror("Simulating external clock sync\n");
if(mode == CLK_TX)
m_tx_clock_base = u64(m_cpu->total_cycles()*2*m_internal_to_external_ratio);
else
m_rx_clock_base = u64(m_cpu->total_cycles()*2*m_internal_to_external_ratio);
m_cpu->internal_update();
break;
case clock_mode_t::EXTERNAL_ASYNC:
if(V>=2) logerror("Waiting for external clock async\n");
m_ext_clock_counter = 15;
break;
case clock_mode_t::EXTERNAL_ASYNC:
if(V>=1) logerror("Waiting for external clock async\n");
if(mode == CLK_TX)
m_tx_ext_clock_counter = 15;
else
m_rx_ext_clock_counter = 15;
break;
case clock_mode_t::EXTERNAL_SYNC:
if(V>=2) logerror("Waiting for external clock sync\n");
break;
}
} else
m_clock_state |= mode;
case clock_mode_t::EXTERNAL_SYNC:
if(V>=1) logerror("Waiting for external clock sync\n");
break;
}
}
void h8_sci_device::clock_stop(int mode)

View File

@ -112,12 +112,12 @@ protected:
int m_id, m_eri_int, m_rxi_int, m_txi_int, m_tei_int;
int m_tx_state, m_rx_state, m_tx_bit, m_rx_bit, m_clock_state, m_tx_parity, m_rx_parity, m_ext_clock_counter;
int m_tx_state, m_rx_state, m_tx_bit, m_rx_bit, m_clock_state, m_tx_parity, m_rx_parity, m_tx_ext_clock_counter, m_rx_ext_clock_counter;
clock_mode_t m_clock_mode;
bool m_clock_value, m_ext_clock_value, m_rx_value;
bool m_tx_clock_value, m_rx_clock_value, m_ext_clock_value, m_rx_value;
u8 m_rdr, m_tdr, m_smr, m_scr, m_ssr, m_brr, m_rsr, m_tsr;
u64 m_clock_base, m_divider;
u64 m_tx_clock_base, m_rx_clock_base, m_divider;
std::string m_last_clock_message;