Allow reading from port A in output mode. Add a separate bit for timer 1 PB7 toggling rather than changing the PB register directly. Don't clear the SR register on reset. Clears pcr & acr at construct time, in case something sets one of the handshaking lines before we've started. Use a separate variable for the latched inputs and the current inputs. Consolidated the input and output code. [smf]

This commit is contained in:
smf- 2014-01-26 22:05:49 +00:00
parent 4830ec15d8
commit 91a1d90bb6
2 changed files with 100 additions and 125 deletions

View File

@ -156,12 +156,14 @@ via6522_device::via6522_device(const machine_config &mconfig, const char *tag, d
m_cb1_handler(*this),
m_cb2_handler(*this),
m_irq_handler(*this),
m_in_a(0),
m_in_a(0xff),
m_in_ca1(0),
m_in_ca2(0),
m_in_b(0),
m_in_cb1(0),
m_in_cb2(0),
m_pcr(0),
m_acr(0),
m_irq(CLEAR_LINE)
{
}
@ -186,12 +188,13 @@ void via6522_device::device_start()
m_t1lh = 0xb5; /* ports are not written by kernel! */
m_t2ll = 0xff; /* taken from vice */
m_t2lh = 0xff;
m_sr = 0;
m_time2 = m_time1 = machine().time();
m_t1 = timer_alloc(TIMER_T1);
m_t2 = timer_alloc(TIMER_T2);
m_ca2_timer = timer_alloc(TIMER_CA2);
m_shift_timer = timer_alloc(TIMER_SHIFT);
m_pcr = 0;
/* Default clock is from CPU1 */
if (clock() == 0)
@ -206,6 +209,7 @@ void via6522_device::device_start()
save_item(NAME(m_out_a));
save_item(NAME(m_out_ca2));
save_item(NAME(m_ddr_a));
save_item(NAME(m_latch_a));
save_item(NAME(m_in_b));
save_item(NAME(m_in_cb1));
save_item(NAME(m_in_cb2));
@ -213,6 +217,7 @@ void via6522_device::device_start()
save_item(NAME(m_out_cb1));
save_item(NAME(m_out_cb2));
save_item(NAME(m_ddr_b));
save_item(NAME(m_latch_b));
save_item(NAME(m_t1cl));
save_item(NAME(m_t1ch));
save_item(NAME(m_t1ll));
@ -228,6 +233,7 @@ void via6522_device::device_start()
save_item(NAME(m_ifr));
save_item(NAME(m_irq));
save_item(NAME(m_t1_active));
save_item(NAME(m_t1_pb7));
save_item(NAME(m_t2_active));
save_item(NAME(m_shift_counter));
}
@ -252,15 +258,17 @@ void via6522_device::device_reset()
m_t2cl = 0;
m_t2ch = 0;
m_sr = 0;
m_pcr = 0;
m_acr = 0;
m_ier = 0;
m_ifr = 0;
m_t1_active = 0;
m_t1_pb7 = 1;
m_t2_active = 0;
m_shift_counter = 0;
output_pa();
output_pb();
m_ca2_handler(m_out_ca2);
m_cb1_handler(m_out_cb1);
m_cb2_handler(m_out_cb2);
@ -387,25 +395,19 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
case TIMER_T1:
if (T1_CONTINUOUS (m_acr))
{
if (T1_SET_PB7(m_acr))
{
m_out_b ^= 0x80;
}
m_t1_pb7 = !m_t1_pb7;
m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY));
}
else
{
if (T1_SET_PB7(m_acr))
{
m_out_b |= 0x80;
}
m_t1_pb7 = 1;
m_t1_active = 0;
m_time1 = machine().time();
}
if (m_ddr_b)
if (T1_SET_PB7(m_acr))
{
UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
m_out_b_handler(write_data);
output_pb();
}
if (!(m_ifr & INT_T1))
@ -431,6 +433,52 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
}
UINT8 via6522_device::input_pa()
{
/// TODO: REMOVE THIS
if (!m_in_a_handler.isnull())
{
m_in_a = m_in_a_handler(0);
}
/* combine input and output values */
return m_in_a & (m_out_a | ~m_ddr_a);
}
void via6522_device::output_pa()
{
UINT8 write_data = (m_out_a & m_ddr_a) | ~m_ddr_a;
m_out_a_handler(write_data);
}
UINT8 via6522_device::input_pb()
{
/// TODO: REMOVE THIS
if (m_ddr_b != 0xff && !m_in_b_handler.isnull())
{
m_in_b = m_in_b_handler(0);
}
UINT8 data = (m_in_b & ~m_ddr_b) | (m_out_b & m_ddr_b);
if (T1_SET_PB7(m_acr))
{
data = (data & 0x7f) | (m_t1_pb7 << 7);
}
return data;
}
void via6522_device::output_pb()
{
UINT8 write_data = (m_out_b & m_ddr_b) | ~m_ddr_b;
if (T1_SET_PB7(m_acr))
write_data = (write_data & 0x7f) | (m_t1_pb7 << 7);
m_out_b_handler(write_data);
}
/*-------------------------------------------------
via_r - CPU interface for VIA read
-------------------------------------------------*/
@ -447,54 +495,25 @@ READ8_MEMBER( via6522_device::read )
/* update the input */
if (PB_LATCH_ENABLE(m_acr) == 0)
{
if (m_ddr_b != 0xff)
{
if (!m_in_b_handler.isnull())
{
m_in_b = m_in_b_handler(0);
}
else
{
logerror("%s:6522VIA chip %s: Port B is being read but has no handler\n", machine().describe_context(), tag());
}
}
}
CLR_PB_INT();
/* combine input and output values, hold DDRB bit 7 high if T1_SET_PB7 */
if (T1_SET_PB7(m_acr))
{
val = (m_out_b & (m_ddr_b | 0x80)) | (m_in_b & ~(m_ddr_b | 0x80));
val = input_pb();
}
else
{
val = (m_out_b & m_ddr_b) + (m_in_b & ~m_ddr_b);
val = m_latch_b;
}
CLR_PB_INT();
break;
case VIA_PA:
/* update the input */
if (PA_LATCH_ENABLE(m_acr) == 0)
{
if (m_ddr_a != 0xff)
{
if (!m_in_a_handler.isnull())
{
m_in_a = m_in_a_handler(0);
}
else
{
logerror("%s:6522VIA chip %s: Port A is being read but has no handler\n", machine().describe_context(), tag());
}
}
/* combine input and output values */
val = (m_out_a & m_ddr_a) + (m_in_a & ~m_ddr_a);
val = input_pa();
}
else
{
val = m_in_a;
val = m_latch_a;
}
CLR_PA_INT();
@ -514,18 +533,12 @@ READ8_MEMBER( via6522_device::read )
/* update the input */
if (PA_LATCH_ENABLE(m_acr) == 0)
{
if (!m_in_a_handler.isnull())
{
m_in_a = m_in_a_handler(0);
}
else
{
logerror("%s:6522VIA chip %s: Port A is being read but has no handler\n", machine().describe_context(), tag());
}
val = input_pa();
}
else
{
val = m_latch_a;
}
/* combine input and output values */
val = (m_out_a & m_ddr_a) + (m_in_a & ~m_ddr_a);
break;
case VIA_DDRB:
@ -635,15 +648,11 @@ WRITE8_MEMBER( via6522_device::write )
switch (offset)
{
case VIA_PB:
if (T1_SET_PB7(m_acr))
m_out_b = (m_out_b & 0x80) | (data & 0x7f);
else
m_out_b = data;
m_out_b = data;
if (m_ddr_b)
if (m_ddr_b != 0)
{
UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
m_out_b_handler(write_data);
output_pb();
}
CLR_PB_INT();
@ -658,10 +667,9 @@ WRITE8_MEMBER( via6522_device::write )
case VIA_PA:
m_out_a = data;
if (m_ddr_a)
if (m_ddr_a != 0)
{
UINT8 write_data = (m_out_a & m_ddr_a) | (m_ddr_a ^ 0xff);
m_out_a_handler(write_data);
output_pa();
}
CLR_PA_INT();
@ -680,39 +688,28 @@ WRITE8_MEMBER( via6522_device::write )
case VIA_PANH:
m_out_a = data;
if (m_ddr_a)
if (m_ddr_a != 0)
{
UINT8 write_data = (m_out_a & m_ddr_a) | (m_ddr_a ^ 0xff);
m_out_a_handler(write_data);
output_pa();
}
break;
case VIA_DDRB:
/* EHC 03/04/2000 - If data direction changed, present output on the lines */
if ( data != m_ddr_b )
{
m_ddr_b = data;
//if (m_ddr_b)
{
UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
m_out_b_handler(write_data);
}
output_pb();
}
break;
case VIA_DDRA:
/* EHC 03/04/2000 - If data direction changed, present output on the lines */
if ( data != m_ddr_a )
if (m_ddr_a != data)
{
m_ddr_a = data;
//if (m_ddr_a)
{
UINT8 write_data = (m_out_a & m_ddr_a) | (m_ddr_a ^ 0xff);
m_out_a_handler(write_data);
}
output_pa();
}
break;
@ -732,16 +729,13 @@ WRITE8_MEMBER( via6522_device::write )
clear_int(INT_T1);
m_t1_pb7 = 0;
if (T1_SET_PB7(m_acr))
{
m_out_b &= 0x7f;
//if (m_ddr_b)
{
UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
m_out_b_handler(write_data);
}
output_pb();
}
m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY));
m_t1_active = 1;
break;
@ -808,23 +802,9 @@ WRITE8_MEMBER( via6522_device::write )
{
UINT16 counter1 = get_counter1_value();
m_acr = data;
if (T1_SET_PB7(m_acr))
{
if (m_t1_active)
{
m_out_b &= ~0x80;
}
else
{
m_out_b |= 0x80;
}
//if (m_ddr_b)
{
UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
m_out_b_handler(write_data);
}
}
output_pb();
if (T1_CONTINUOUS(data))
{
m_t1->adjust(clocks_to_attotime(counter1 + IFR_DELAY));
@ -896,14 +876,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca1 )
{
if (PA_LATCH_ENABLE(m_acr))
{
if (!m_in_a_handler.isnull())
{
m_in_a = m_in_a_handler(0);
}
else
{
logerror("%s:6522VIA chip %s: Port A is being read but has no handler\n", machine().describe_context(), tag());
}
m_latch_a = input_pa();
}
set_int(INT_CA1);
@ -963,14 +936,7 @@ WRITE_LINE_MEMBER( via6522_device::write_cb1 )
{
if (PB_LATCH_ENABLE(m_acr))
{
if (!m_in_b_handler.isnull())
{
m_in_b = m_in_b_handler(0);
}
else
{
logerror("%s:6522VIA chip %s: Port B is being read but has no handler\n", machine().describe_context(), tag());
}
m_latch_b = input_pb();
}
if (SO_EXT_CONTROL(m_acr))

View File

@ -144,6 +144,11 @@ private:
void write_pa(int line, int state);
void write_pb(int line, int state);
UINT8 input_pa();
void output_pa();
UINT8 input_pb();
void output_pb();
// TODO: REMOVE THESE
devcb2_read8 m_in_a_handler;
devcb2_read8 m_in_b_handler;
@ -163,6 +168,7 @@ private:
UINT8 m_out_a;
UINT8 m_out_ca2;
UINT8 m_ddr_a;
UINT8 m_latch_a;
UINT8 m_in_b;
UINT8 m_in_cb1;
@ -171,11 +177,14 @@ private:
UINT8 m_out_cb1;
UINT8 m_out_cb2;
UINT8 m_ddr_b;
UINT8 m_latch_b;
UINT8 m_t1cl;
UINT8 m_t1ch;
UINT8 m_t1ll;
UINT8 m_t1lh;
int m_t1_pb7;
UINT8 m_t2cl;
UINT8 m_t2ch;
UINT8 m_t2ll;