Sorry Vas,

I guess it's just impatience mixed with a short attention span and a dash of ridiculous 8-).

How about this solution: the problem is that it gets out of sync because the timing is not in sync.

So in the e05a30 device why don't we make a time stamp of when the strobe falls and the data latch gets set.

Then when the ap2000 reads c002 to check the status, it won't report that the latch is true unless the current time is greater than that timestamp.
That would solve the time desync. It shouldn't report true until it "actually happens".

Code

static double input_strobe_time;


WRITE_LINE_MEMBER( e05a30_device::centronics_input_strobe )
{
        if (m_centronics_strobe == true && state == false && !m_centronics_busy) {

              printf("Centronics STROBE falling at %.9f\n",machine().time().as_double());
               input_strobe_time = machine().time().as_double();     // make a timestamp

                m_centronics_data_latch   = m_centronics_data;

                m_centronics_data_latched = true;
                m_centronics_busy         = true;
                m_write_centronics_busy(m_centronics_busy);
        }

        m_centronics_strobe = state;
}


uint8_t e05a30_device::read(offs_t offset)
{
        uint8_t result = 0;

        LOG("%s: e05a30_r([0xC0%02x]): ", machine().describe_context(), offset);

        switch (offset) {
        case 0x00:
                result = BIT(m_c000_shift_register, 23) << 7;
                if (!machine().side_effects_disabled()) {
                        m_c000_shift_register = (m_c000_shift_register << 1) & 0xffffff;
                }
                break;
        case 0x02:

                 if (m_centronics_data_latched && machine().time().as_double() - input_strobe_time > 0)
                         result = m_centronics_data_latched << 7;
                else
                           result = 0;
                break;