summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/6522via.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/6522via.cpp')
-rw-r--r--src/devices/machine/6522via.cpp431
1 files changed, 255 insertions, 176 deletions
diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp
index 3a9f6b10378..1b1d0ea0766 100644
--- a/src/devices/machine/6522via.cpp
+++ b/src/devices/machine/6522via.cpp
@@ -11,17 +11,6 @@
**********************************************************************/
-/*
- 1999-Dec-22 PeT
- vc20 random number generation only partly working
- (reads (uninitialized) timer 1 and timer 2 counter)
- timer init, reset, read changed
-
- 2017-Feb-15 Edstrom
- Fixed shift registers to be more accurate, eg 50/50 duty cycle, latching
- on correct flanks and leading and trailing flanks added + logging.
- */
-
#include "emu.h"
#include "6522via.h"
@@ -29,10 +18,10 @@
PARAMETERS
***************************************************************************/
-#define LOG_SETUP (1U << 1)
-#define LOG_SHIFT (1U << 2)
-#define LOG_READ (1U << 3)
-#define LOG_INT (1U << 4)
+#define LOG_SETUP (1U << 1)
+#define LOG_SHIFT (1U << 2)
+#define LOG_READ (1U << 3)
+#define LOG_INT (1U << 4)
//#define VERBOSE (LOG_SHIFT|LOG_INT|LOG_SETUP)
//#define LOG_OUTPUT_FUNC printf
@@ -165,8 +154,11 @@ void via6522_device::counter2_decrement()
// LIVE DEVICE
//**************************************************************************
-// device type definition
-DEFINE_DEVICE_TYPE(VIA6522, via6522_device, "via6522", "6522 VIA")
+// device type definitions
+DEFINE_DEVICE_TYPE(MOS6522, mos6522_device, "mos6522", "MOS 6522 VIA")
+DEFINE_DEVICE_TYPE(R65C22, r65c22_device, "r65c22", "Rockwell R65C22 VIA")
+DEFINE_DEVICE_TYPE(R65NC22, r65nc22_device, "r65nc22", "Rockwell R65NC22 VIA")
+DEFINE_DEVICE_TYPE(W65C22S, w65c22s_device, "w65c22s", "WDC W65C22S VIA")
void via6522_device::map(address_map &map)
{
@@ -177,27 +169,64 @@ void via6522_device::map(address_map &map)
// via6522_device - constructor
//-------------------------------------------------
-via6522_device::via6522_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, VIA6522, tag, owner, clock),
- m_in_a_handler(*this),
- m_in_b_handler(*this),
- m_out_a_handler(*this),
- m_out_b_handler(*this),
- m_ca2_handler(*this),
- m_cb1_handler(*this),
- m_cb2_handler(*this),
- m_irq_handler(*this),
- m_in_a(0xff),
- m_in_ca1(0),
- m_in_ca2(0),
- m_out_ca2(0),
- m_in_b(0xff),
- m_in_cb1(0),
- m_in_cb2(0),
- m_pcr(0),
- m_acr(0),
- m_ier(0),
- m_ifr(0)
+via6522_device::via6522_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ m_in_a_handler(*this, 0xff),
+ m_in_b_handler(*this, 0xff),
+ m_out_a_handler(*this),
+ m_out_b_handler(*this),
+ m_ca2_handler(*this),
+ m_cb1_handler(*this),
+ m_cb2_handler(*this),
+ m_irq_handler(*this),
+ m_in_a(0xff),
+ m_in_ca1(0),
+ m_in_ca2(0),
+ m_in_b(0xff),
+ m_in_cb1(0),
+ m_in_cb2(0),
+ m_pcr(0),
+ m_acr(0)
+{
+}
+
+
+//-------------------------------------------------
+// mos6522_device - constructor
+//-------------------------------------------------
+
+mos6522_device::mos6522_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ via6522_device(mconfig, MOS6522, tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// r65c22_device - constructor
+//-------------------------------------------------
+
+r65c22_device::r65c22_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ via6522_device(mconfig, R65C22, tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// r65c22_device - constructor
+//-------------------------------------------------
+
+r65nc22_device::r65nc22_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ via6522_device(mconfig, R65NC22, tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// w65c22s_device - constructor
+//-------------------------------------------------
+
+w65c22s_device::w65c22s_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ via6522_device(mconfig, W65C22S, tag, owner, clock)
{
}
@@ -208,29 +237,49 @@ via6522_device::via6522_device(const machine_config &mconfig, const char *tag, d
void via6522_device::device_start()
{
- m_in_a_handler.resolve();
- m_in_b_handler.resolve();
- m_out_a_handler.resolve_safe();
- m_out_b_handler.resolve_safe();
- m_cb1_handler.resolve_safe();
- m_ca2_handler.resolve_safe();
- m_cb2_handler.resolve_safe();
- m_irq_handler.resolve_safe();
-
m_t1ll = 0xf3; /* via at 0x9110 in vic20 show these values */
m_t1lh = 0xb5; /* ports are not written by kernel! */
m_t2ll = 0xff; /* taken from vice */
m_t2lh = 0xff;
+
+ m_time1 = machine().time();
+ m_time2 = machine().time();
+
+ m_t1 = timer_alloc(FUNC(via6522_device::t1_tick), this);
+ m_t2 = timer_alloc(FUNC(via6522_device::t2_tick), this);
+ m_ca2_timer = timer_alloc(FUNC(via6522_device::ca2_tick), this);
+ m_cb2_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
+ m_shift_timer = timer_alloc(FUNC(via6522_device::shift_tick), this);
+ m_shift_irq_timer = timer_alloc(FUNC(via6522_device::shift_irq_tick), this);
+
+ // zerofill other
+ m_out_a = 0;
+ m_out_ca2 = 0;
+ m_ddr_a = 0;
+ m_latch_a = 0;
+ m_out_b = 0;
+ m_out_cb1 = 0;
+ m_out_cb2 = 0;
+ m_ddr_b = 0;
+ m_latch_b = 0;
+
+ m_t1cl = 0;
+ m_t1ch = 0;
+ m_t2cl = 0;
+ m_t2ch = 0;
+
m_sr = 0;
+ m_pcr = 0;
+ m_acr = 0;
+ m_ier = 0;
+ m_ifr = 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_shift_irq_timer = timer_alloc(TIMER_SHIFT_IRQ);
+ m_t1_active = 0;
+ m_t1_pb7 = 0;
+ m_t2_active = 0;
+ m_shift_counter = 0;
- /* save state register */
+ // save state register
save_item(NAME(m_in_a));
save_item(NAME(m_in_ca1));
save_item(NAME(m_in_ca2));
@@ -238,6 +287,7 @@ void via6522_device::device_start()
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));
@@ -246,6 +296,7 @@ void via6522_device::device_start()
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));
@@ -254,11 +305,13 @@ void via6522_device::device_start()
save_item(NAME(m_t2ch));
save_item(NAME(m_t2ll));
save_item(NAME(m_t2lh));
+
save_item(NAME(m_sr));
save_item(NAME(m_pcr));
save_item(NAME(m_acr));
save_item(NAME(m_ier));
save_item(NAME(m_ifr));
+
save_item(NAME(m_time1));
save_item(NAME(m_t1_active));
save_item(NAME(m_t1_pb7));
@@ -308,6 +361,7 @@ void via6522_device::device_reset()
m_t1->adjust(attotime::never);
m_t2->adjust(attotime::never);
m_ca2_timer->adjust(attotime::never);
+ m_cb2_timer->adjust(attotime::never);
m_shift_timer->adjust(attotime::never);
m_shift_irq_timer->adjust(attotime::never);
}
@@ -381,12 +435,12 @@ void via6522_device::clear_int(int data)
/*-------------------------------------------------
- via_shift
+ shift_out
-------------------------------------------------*/
void via6522_device::shift_out()
{
- // Only shift out msb on falling flank
+ // Only shift out msb on falling edge
if (m_shift_counter & 1)
{
LOGSHIFT(" %s shift Out SR: %02x->", tag(), m_sr);
@@ -399,130 +453,128 @@ void via6522_device::shift_out()
if (m_shift_counter == 1 && SO_EXT_CONTROL(m_acr))
{
LOGINT("SHIFT EXT out INT request ");
- set_int(INT_SR); // IRQ on last falling flank for external clock (mode 7)
+ set_int(INT_SR); // IRQ on last falling edge for external clock (mode 7)
}
}
- else // Check for INT condition, eg the last and raising flank of the 15-0 falling/raising flanks
+ else // Check for INT condition, eg the last and raising edge of the 15-0 falling/raising edges
{
- if (!SO_T2_RATE(m_acr)) // The T2 continous shifter doesn't do interrupts (mode 4)
+ if (!SO_T2_RATE(m_acr)) // The T2 continuous shifter doesn't do interrupts (mode 4)
{
if (m_shift_counter == 0 && (SO_O2_CONTROL(m_acr) || SO_T2_CONTROL(m_acr)))
{
LOGINT("SHIFT O2/T2 out INT request ");
- set_int(INT_SR); // IRQ on last raising flank for internal clock (mode 5-6)
+ set_int(INT_SR); // IRQ on last raising edge for internal clock (mode 5-6)
}
}
}
- m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all flanks
+ m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all edges
}
void via6522_device::shift_in()
{
- // Only shift in data on raising flank
- if ( !(m_shift_counter & 1) )
+ // Only shift in data on raising edge
+ if (!(m_shift_counter & 1))
{
LOGSHIFT("%s shift In SR: %02x->", tag(), m_sr);
m_sr = (m_sr << 1) | (m_in_cb2 & 1);
LOGSHIFT("%02x\n", m_sr);
- if (m_shift_counter == 0)
+ if (m_shift_counter == 0 && !SR_DISABLED(m_acr))
{
LOGINT("SHIFT in INT request ");
// set_int(INT_SR);// TODO: this interrupt is 1-2 clock cycles too early
- m_shift_irq_timer->adjust(clocks_to_attotime(2)/2); // Delay IRQ 2 flanks for all shift INs (mode 1-3)
+ m_shift_irq_timer->adjust(clocks_to_attotime(2)/2); // Delay IRQ 2 edges for all shift INs (mode 1-3)
}
}
- m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all flanks
+ m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all edges
}
-void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(via6522_device::shift_irq_tick)
{
- switch (id)
- {
- case TIMER_SHIFT_IRQ: // This timer event is a delayed IRQ for improved cycle accuracy
- set_int(INT_SR); // triggered from shift_in or shift_out on the last rising flank
- m_shift_irq_timer->adjust(attotime::never); // Not needed really...
- break;
- case TIMER_SHIFT:
- LOGSHIFT("SHIFT timer event CB1 %s edge, %d\n", m_out_cb1 & 1 ? "falling" : "raising", m_shift_counter);
- m_out_cb1 ^= 1;
- m_cb1_handler(m_out_cb1);
-
- // we call shift methods for all flanks
- if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
- {
- shift_out();
- }
- else if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr))
- {
- shift_in();
- }
-
- // If in continous mode or the shifter is still shifting we re-arm the timer
- if (SO_T2_RATE(m_acr) || (m_shift_counter != 0x0f))
- {
- if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
- {
- m_shift_timer->adjust(clocks_to_attotime(1));
- }
- else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SI_T2_CONTROL(m_acr))
- {
- m_shift_timer->adjust(clocks_to_attotime(m_t2ll + 2) / 2);
- }
- else // otherwise we stop it
- {
- m_shift_timer->adjust(attotime::never);
- }
- }
- break;
- case TIMER_T1:
- if (T1_CONTINUOUS (m_acr))
- {
- m_t1_pb7 = !m_t1_pb7;
- m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY));
- }
- else
- {
- m_t1_pb7 = 1;
- m_t1_active = 0;
- m_time1 = machine().time();
- }
+ // This timer event is a delayed IRQ for improved cycle accuracy
+ set_int(INT_SR); // triggered from shift_in or shift_out on the last rising edge
+ m_shift_irq_timer->adjust(attotime::never); // Not needed really...
+}
- if (T1_SET_PB7(m_acr))
- {
- output_pb();
- }
+TIMER_CALLBACK_MEMBER(via6522_device::shift_tick)
+{
+ LOGSHIFT("SHIFT timer event CB1 %s edge, %d\n", m_out_cb1 & 1 ? "falling" : "raising", m_shift_counter);
+ m_out_cb1 ^= 1;
+ m_cb1_handler(m_out_cb1);
- LOGINT("T1 INT request ");
- set_int(INT_T1);
- break;
+ // we call shift methods for all edges
+ if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
+ {
+ shift_out();
+ }
+ else if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr))
+ {
+ shift_in();
+ }
- case TIMER_T2:
- m_t2_active = 0;
- m_time2 = machine().time();
+ // If in continuous mode or the shifter is still shifting we re-arm the timer
+ if (SO_T2_RATE(m_acr) || (m_shift_counter < 0x0f))
+ {
+ if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
+ {
+ m_shift_timer->adjust(clocks_to_attotime(1));
+ }
+ else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SI_T2_CONTROL(m_acr))
+ {
+ m_shift_timer->adjust(clocks_to_attotime(m_t2ll + 2) / 2);
+ }
+ else // otherwise we stop it
+ {
+ m_shift_timer->adjust(attotime::never);
+ }
+ }
+}
- LOGINT("T2 INT request ");
- set_int(INT_T2);
- break;
+TIMER_CALLBACK_MEMBER(via6522_device::t1_tick)
+{
+ if (T1_CONTINUOUS (m_acr))
+ {
+ m_t1_pb7 = !m_t1_pb7;
+ m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY));
+ }
+ else
+ {
+ m_t1_pb7 = 1;
+ m_t1_active = 0;
+ m_time1 = machine().time();
+ }
- case TIMER_CA2:
- m_out_ca2 = 1;
- m_ca2_handler(m_out_ca2);
- break;
+ if (T1_SET_PB7(m_acr))
+ {
+ output_pb();
}
+
+ LOGINT("T1 INT request ");
+ set_int(INT_T1);
}
-uint8_t via6522_device::input_pa()
+TIMER_CALLBACK_MEMBER(via6522_device::t2_tick)
{
- uint8_t pa = m_in_a & ~m_ddr_a;
+ m_t2_active = 0;
+ m_time2 = machine().time();
- /// TODO: REMOVE THIS
- if (m_ddr_a != 0xff && !m_in_a_handler.isnull())
- pa &= m_in_a_handler();
+ LOGINT("T2 INT request ");
+ set_int(INT_T2);
+}
- pa |= m_out_a & m_ddr_a;
+TIMER_CALLBACK_MEMBER(via6522_device::ca2_tick)
+{
+ m_out_ca2 = 1;
+ m_ca2_handler(m_out_ca2);
+}
- return pa;
+uint8_t via6522_device::input_pa()
+{
+ // HACK: port a in the real 6522 does not mask off the output pins, but you can't trust handlers.
+ if (!m_in_a_handler.isunset())
+ return (m_in_a & ~m_ddr_a & m_in_a_handler()) | (m_out_a & m_ddr_a);
+ else
+ return (m_out_a | ~m_ddr_a) & m_in_a;
}
void via6522_device::output_pa()
@@ -531,12 +583,17 @@ void via6522_device::output_pa()
m_out_a_handler(pa);
}
+uint8_t via6522_device::read_pa() const
+{
+ return (m_out_a & m_ddr_a) | ~m_ddr_a;
+}
+
uint8_t via6522_device::input_pb()
{
uint8_t pb = m_in_b & ~m_ddr_b;
/// TODO: REMOVE THIS
- if (m_ddr_b != 0xff && !m_in_b_handler.isnull())
+ if (m_ddr_b != 0xff && !m_in_b_handler.isunset())
{
pb &= m_in_b_handler();
}
@@ -559,6 +616,16 @@ void via6522_device::output_pb()
m_out_b_handler(pb);
}
+uint8_t via6522_device::read_pb() const
+{
+ uint8_t pb = (m_out_b & m_ddr_b) | ~m_ddr_b;
+
+ if (T1_SET_PB7(m_acr))
+ pb = (pb & 0x7f) | (m_t1_pb7 << 7);
+
+ return pb;
+}
+
/*-------------------------------------------------
via_r - CPU interface for VIA read
-------------------------------------------------*/
@@ -572,13 +639,13 @@ u8 via6522_device::read(offs_t offset)
{
case VIA_PB:
/* update the input */
- if (PB_LATCH_ENABLE(m_acr) == 0)
+ if ((PB_LATCH_ENABLE(m_acr) != 0) && ((m_ifr & INT_CB1) != 0))
{
- val = input_pb();
+ val = m_latch_b;
}
else
{
- val = m_latch_b;
+ val = input_pb();
}
if (!machine().side_effects_disabled())
@@ -590,13 +657,13 @@ u8 via6522_device::read(offs_t offset)
case VIA_PA:
/* update the input */
- if (PA_LATCH_ENABLE(m_acr) == 0)
+ if ((PA_LATCH_ENABLE(m_acr) != 0) && ((m_ifr & INT_CA1) != 0))
{
- val = input_pa();
+ val = m_latch_a;
}
else
{
- val = m_latch_a;
+ val = input_pa();
}
if (!machine().side_effects_disabled())
@@ -618,13 +685,13 @@ u8 via6522_device::read(offs_t offset)
case VIA_PANH:
/* update the input */
- if (PA_LATCH_ENABLE(m_acr) == 0)
+ if ((PA_LATCH_ENABLE(m_acr) != 0) && ((m_ifr & INT_CA1) != 0))
{
- val = input_pa();
+ val = m_latch_a;
}
else
{
- val = m_latch_a;
+ val = input_pa();
}
break;
@@ -703,15 +770,20 @@ u8 via6522_device::read(offs_t offset)
val = m_sr;
if (!machine().side_effects_disabled())
{
- m_out_cb1 = 1;
- m_cb1_handler(m_out_cb1);
- m_shift_counter = 0x0f;
+ if (!(SI_EXT_CONTROL(m_acr) || SO_EXT_CONTROL(m_acr))) {
+ m_out_cb1 = 1;
+ m_cb1_handler(m_out_cb1);
+ m_shift_counter = 0x0f;
+ }
+ else
+ m_shift_counter = m_in_cb1 ? 0x0f : 0x10;
+
LOGINT("SR INT ");
clear_int(INT_SR);
LOGSHIFT(" - ACR: %02x ", m_acr);
if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
{
- m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 flanks to start shifter from a read
+ m_shift_timer->adjust(clocks_to_attotime(7) / 2); // 7 edges to cb1 change from start of read
LOGSHIFT(" - read SR starts O2 timer ");
}
else if (SI_T2_CONTROL(m_acr) || SO_T2_CONTROL(m_acr))
@@ -775,11 +847,16 @@ void via6522_device::write(offs_t offset, u8 data)
LOGINT("PB INT ");
CLR_PB_INT();
- if (m_out_cb2 && CB2_AUTO_HS(m_pcr))
+ if (m_out_cb2 && (CB2_PULSE_OUTPUT(m_pcr) || CB2_AUTO_HS(m_pcr)))
{
m_out_cb2 = 0;
m_cb2_handler(m_out_cb2);
}
+
+ if (CB2_PULSE_OUTPUT(m_pcr))
+ {
+ m_cb2_timer->adjust(clocks_to_attotime(1));
+ }
break;
case VIA_PA:
@@ -815,7 +892,7 @@ void via6522_device::write(offs_t offset, u8 data)
break;
case VIA_DDRB:
- if ( data != m_ddr_b )
+ if (data != m_ddr_b)
{
m_ddr_b = data;
@@ -889,21 +966,20 @@ void via6522_device::write(offs_t offset, u8 data)
m_sr = data;
LOGSHIFT("Write SR: %02x\n", m_sr);
- // make sure CB1 is high - this should not be needed though
- if (m_out_cb1 != 1)
- {
- logerror("VIA: CB1 is low starting shifter\n");
+ if (!(SI_EXT_CONTROL(m_acr) || SO_EXT_CONTROL(m_acr))) {
m_out_cb1 = 1;
m_cb1_handler(m_out_cb1);
+ m_shift_counter = 0x0f;
}
+ else
+ m_shift_counter = m_in_cb1 ? 0x0f : 0x10;
- m_shift_counter = 0x0f;
LOGINT("SR INT ");
clear_int(INT_SR);
LOGSHIFT(" - ACR is: %02x ", m_acr);
if (SO_O2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr))
{
- m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 flanks to start shifter from a write
+ m_shift_timer->adjust(clocks_to_attotime(6) / 2); // 6 edges to cb2 change from start of write
LOGSHIFT(" - write SR starts O2 timer");
}
else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SI_T2_CONTROL(m_acr))
@@ -950,7 +1026,7 @@ void via6522_device::write(offs_t offset, u8 data)
if (SI_T2_CONTROL(m_acr)) LOGSHIFT("IN on T2");
if (SI_O2_CONTROL(m_acr)) LOGSHIFT("IN on O2");
if (SI_EXT_CONTROL(m_acr)) LOGSHIFT("IN on EXT");
- if (SO_T2_RATE(m_acr)) LOGSHIFT("OUT on continous T2");
+ if (SO_T2_RATE(m_acr)) LOGSHIFT("OUT on continuous T2");
if (SO_T2_CONTROL(m_acr)) LOGSHIFT("OUT on T2");
if (SO_O2_CONTROL(m_acr)) LOGSHIFT("OUT on O2");
if (SO_EXT_CONTROL(m_acr)) LOGSHIFT("OUT on EXT");
@@ -966,6 +1042,13 @@ void via6522_device::write(offs_t offset, u8 data)
m_t1->adjust(clocks_to_attotime(counter1 + IFR_DELAY));
m_t1_active = 1;
}
+
+ if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr) || SI_EXT_CONTROL(m_acr))
+ {
+ m_out_cb2 = 1;
+ m_cb2_handler(m_out_cb2);
+ }
+
LOGSHIFT("\n");
}
break;
@@ -984,12 +1067,8 @@ void via6522_device::write(offs_t offset, u8 data)
break;
case VIA_IFR:
- if (data & INT_ANY)
- {
- data = 0x7f;
- }
LOGINT("IFR INT ");
- clear_int(data);
+ clear_int(data & 0x7f);
break;
}
}
@@ -1002,7 +1081,7 @@ void via6522_device::set_pa_line(int line, int state)
m_in_a &= ~(1 << line);
}
-void via6522_device::write_pa( u8 data )
+void via6522_device::write_pa(u8 data)
{
m_in_a = data;
}
@@ -1011,7 +1090,7 @@ void via6522_device::write_pa( u8 data )
ca1_w - interface setting VIA port CA1 input
-------------------------------------------------*/
-WRITE_LINE_MEMBER( via6522_device::write_ca1 )
+void via6522_device::write_ca1(int state)
{
if (m_in_ca1 != state)
{
@@ -1043,7 +1122,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca1 )
ca2_w - interface setting VIA port CA2 input
-------------------------------------------------*/
-WRITE_LINE_MEMBER( via6522_device::write_ca2 )
+void via6522_device::write_ca2(int state)
{
if (m_in_ca2 != state)
{
@@ -1073,7 +1152,7 @@ void via6522_device::set_pb_line(int line, int state)
}
}
-void via6522_device::write_pb( u8 data )
+void via6522_device::write_pb(u8 data)
{
if (!BIT(data, 6) && BIT(m_in_b, 6))
counter2_decrement();
@@ -1085,7 +1164,7 @@ void via6522_device::write_pb( u8 data )
write_cb1 - interface setting VIA port CB1 input
-------------------------------------------------*/
-WRITE_LINE_MEMBER( via6522_device::write_cb1 )
+void via6522_device::write_cb1(int state)
{
if (m_in_cb1 != state)
{
@@ -1113,7 +1192,7 @@ WRITE_LINE_MEMBER( via6522_device::write_cb1 )
LOGSHIFT("SHIFT OUT EXT/CB1 falling edge, %d\n", m_shift_counter);
shift_out();
}
- else if (SI_EXT_CONTROL(m_acr))
+ else if (SI_EXT_CONTROL(m_acr) || SR_DISABLED(m_acr))
{
LOGSHIFT("SHIFT IN EXT/CB1 raising edge, %d\n", m_shift_counter);
shift_in();
@@ -1126,7 +1205,7 @@ WRITE_LINE_MEMBER( via6522_device::write_cb1 )
write_cb2 - interface setting VIA port CB2 input
-------------------------------------------------*/
-WRITE_LINE_MEMBER( via6522_device::write_cb2 )
+void via6522_device::write_cb2(int state)
{
if (m_in_cb2 != state)
{