h8_sci: Implement sync-start [O. Galibert]

h8: Fix problem in the sleep instruction [O. Galibert]
at45dbxx: Fix communications [O. Galibert]
This commit is contained in:
Olivier Galibert 2014-04-26 10:31:13 +00:00
parent 862d0e262d
commit bb221d260a
4 changed files with 38 additions and 18 deletions

View File

@ -61,6 +61,16 @@ READ8_MEMBER(h8_sci_device::brr_r)
return brr;
}
bool h8_sci_device::is_sync_start() const
{
return (ssr & SMR_CA) && ((scr & (SCR_TE|SCR_RE)) == (SCR_TE|SCR_RE));
}
bool h8_sci_device::has_recv_error() const
{
return ssr & (SSR_ORER|SSR_PER|SSR_FER);
}
WRITE8_MEMBER(h8_sci_device::scr_w)
{
logerror("%s: scr_w %02x%s%s%s%s%s%s clk=%d (%06x)\n", tag(), data,
@ -82,7 +92,7 @@ WRITE8_MEMBER(h8_sci_device::scr_w)
clock_stop(CLK_RX);
}
if((delta & SCR_RE) && (scr & SCR_RE) && rx_state == ST_IDLE && !(ssr & (SSR_ORER|SSR_PER|SSR_FER)))
if((delta & SCR_RE) && (scr & SCR_RE) && rx_state == ST_IDLE && !has_recv_error() && !is_sync_start())
rx_start();
if((delta & SCR_TIE) && (scr & SCR_TIE) && (ssr & SSR_TDRE))
intc->internal_interrupt(txi_int);
@ -90,7 +100,7 @@ WRITE8_MEMBER(h8_sci_device::scr_w)
intc->internal_interrupt(tei_int);
if((delta & SCR_RIE) && (scr & SCR_RIE) && (ssr & SSR_RDRF))
intc->internal_interrupt(rxi_int);
if((delta & SCR_RIE) && (scr & SCR_RIE) && (ssr & (SSR_ORER|SSR_PER|SSR_FER)))
if((delta & SCR_RIE) && (scr & SCR_RIE) && has_recv_error())
intc->internal_interrupt(eri_int);
}
@ -126,7 +136,7 @@ WRITE8_MEMBER(h8_sci_device::ssr_w)
if(tx_state == ST_IDLE && !(ssr & SSR_TDRE))
tx_start();
if((scr & SCR_RE) && rx_state == ST_IDLE && !(ssr & (SSR_ORER|SSR_PER|SSR_FER)))
if((scr & SCR_RE) && rx_state == ST_IDLE && !has_recv_error() && !is_sync_start())
rx_start();
}
@ -502,6 +512,8 @@ void h8_sci_device::tx_start()
tx_bit = 1;
}
clock_start(CLK_TX);
if(rx_state == ST_IDLE && !has_recv_error() && is_sync_start())
rx_start();
}
void h8_sci_device::tx_dropped_edge()
@ -608,12 +620,12 @@ void h8_sci_device::rx_done()
}
}
if(scr & SCR_RIE) {
if(ssr & (SSR_ORER|SSR_PER|SSR_FER))
if(has_recv_error())
intc->internal_interrupt(eri_int);
else
intc->internal_interrupt(rxi_int);
}
if((scr & SCR_RE) && !(ssr & (SSR_ORER|SSR_PER|SSR_FER)))
if((scr & SCR_RE) && !has_recv_error() && !is_sync_start())
rx_start();
else {
clock_stop(CLK_RX);

View File

@ -165,6 +165,9 @@ protected:
void rx_start();
void rx_done();
void rx_raised_edge();
bool is_sync_start() const;
bool has_recv_error() const;
};
extern const device_type H8_SCI;

View File

@ -54,7 +54,7 @@ def save_full_one(f, t, name, source):
print >>f, line
substate = substate + 1
elif has_eat(line):
print >>f, "\ticount = bcount; inst_substate = %d; return;" % substate
print >>f, "\tif(icount) icount = bcount; inst_substate = %d; return;" % substate
substate = substate + 1
else:
print >>f, line
@ -74,7 +74,7 @@ def save_partial_one(f, t, name, source):
print >>f, line
substate = substate + 1
elif has_eat(line):
print >>f, "\ticount = bcount; inst_substate = %d; return;" % substate
print >>f, "\tif(icount) icount = bcount; inst_substate = %d; return;" % substate
print >>f, "case %d:;" % substate
substate = substate + 1
else:

View File

@ -82,6 +82,14 @@ void at45db041_device::device_start()
m_buffer1.resize(page_size());
//m_buffer2.resize(page_size());
// pins
m_pin.cs = 0;
m_pin.sck = 0;
m_pin.si = 0;
m_pin.wp = 0;
m_pin.reset = 0;
m_pin.busy = 0;
// data
save_item(NAME(m_data));
// pins
@ -115,13 +123,7 @@ void at45db041_device::device_reset()
m_io.size = 0;
m_io.pos = 0;
// pins
m_pin.cs = 0;
m_pin.sck = 0;
m_pin.si = 0;
m_pin.so = 0;
m_pin.wp = 0;
m_pin.reset = 0;
m_pin.busy = 0;
m_pin.so = 0;
// output
m_so_byte = 0;
m_so_bits = 0;
@ -362,6 +364,13 @@ WRITE_LINE_MEMBER(at45db041_device::sck_w)
m_so_bits = 0;
m_so_byte = read_byte();
}
// output (part 2)
m_pin.so = (m_so_byte >> m_so_bits) & 1;
write_so(m_pin.so);
m_so_bits++;
}
else
{
// input
if (m_pin.si) m_si_byte = m_si_byte | (1 << m_si_bits);
m_si_bits++;
@ -371,10 +380,6 @@ WRITE_LINE_MEMBER(at45db041_device::sck_w)
write_byte(m_si_byte);
m_si_byte = 0;
}
// output (part 2)
m_pin.so = (m_so_byte >> m_so_bits) & 1;
write_so(m_pin.so);
m_so_bits++;
}
// save sck
m_pin.sck = state;