summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Joakim Larsson Edstrom <joakimlarsson42@gmail.com>2017-02-17 00:02:12 +0100
committer Joakim Larsson Edstrom <joakimlarsson42@gmail.com>2017-02-17 09:05:30 +0100
commitabd59b39cfd6532fbe60222252ca4b771efd1fcb (patch)
tree01ab2bd12208a70ee0133e4a53cece6ae789b517
parent87bec7146f4fa3cb4e6591ac7d6fe2cfaf40f9ea (diff)
Added missing final and leading flanks when shifting out and in respectivelly
-rw-r--r--src/devices/machine/6522via.cpp108
-rw-r--r--src/devices/machine/6522via.h11
2 files changed, 95 insertions, 24 deletions
diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp
index 79085eecbca..23b680cce50 100644
--- a/src/devices/machine/6522via.cpp
+++ b/src/devices/machine/6522via.cpp
@@ -13,7 +13,6 @@
T2 pulse counting mode
Pulse mode handshake output
- More shift register
**********************************************************************/
@@ -22,6 +21,10 @@
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"
@@ -33,13 +36,18 @@
#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_SETUP|LOG_READ)
+//#define LOG_OUTPUT_FUNC printf
-#define VERBOSE 0 // (LOG_SETUP|LOG_SHIFT)
-#define LOG_OUTPUT_FUNC printf
#include "logmacro.h"
#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
#define LOGSHIFT(...) LOGMASKED(LOG_SHIFT, __VA_ARGS__)
+#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__)
+#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
/***************************************************************************
@@ -170,7 +178,8 @@ via6522_device::via6522_device(const machine_config &mconfig, const char *tag, d
m_pcr(0),
m_acr(0),
m_ier(0),
- m_ifr(0)
+ m_ifr(0),
+ m_shift_state(SHIFTER_IDLE)
{
}
@@ -291,6 +300,7 @@ void via6522_device::output_irq()
{
if ((m_ifr & INT_ANY) == 0)
{
+ LOGINT("INT asserted\n");
m_ifr |= INT_ANY;
m_irq_handler(ASSERT_LINE);
}
@@ -299,6 +309,7 @@ void via6522_device::output_irq()
{
if (m_ifr & INT_ANY)
{
+ LOGINT("INT cleared\n");
m_ifr &= ~INT_ANY;
m_irq_handler(CLEAR_LINE);
}
@@ -318,8 +329,13 @@ void via6522_device::set_int(int data)
output_irq();
+ LOGINT("granted\n");
LOG("%s:6522VIA chip %s: IFR = %02X\n", machine().describe_context(), tag(), m_ifr);
}
+ else
+ {
+ LOGINT("denied\n");
+ }
}
@@ -346,36 +362,36 @@ void via6522_device::clear_int(int data)
void via6522_device::shift_out()
{
- LOGSHIFT("Shift Out SR: %02x->", m_sr);
+ LOGSHIFT(" %s shift Out SR: %02x->", tag(), m_sr);
m_out_cb2 = (m_sr >> 7) & 1;
m_sr = (m_sr << 1) | m_out_cb2;
- LOGSHIFT("%02x\n", m_sr);
+ LOGSHIFT("%02x CB2: %d\n", m_sr, m_out_cb2);
m_cb2_handler(m_out_cb2);
if (!SO_T2_RATE(m_acr))
{
- m_shift_counter = (m_shift_counter - 1) & 7;
-
if (m_shift_counter == 0)
{
- set_int(INT_SR);
+ LOGINT("SHIFT out INT request ");
+ set_int(INT_SR); // TODO: this interrupt is 1-2 clock cycles too early for O2 control mode
}
+ m_shift_counter = (m_shift_counter - 1) & 7;
}
}
void via6522_device::shift_in()
{
- LOGSHIFT("Shift In SR: %02x->", m_sr);
+ LOGSHIFT("%s shift In SR: %02x->", tag(), m_sr);
m_sr = (m_sr << 1) | (m_in_cb2 & 1);
LOGSHIFT("%02x\n", m_sr);
- m_shift_counter = (m_shift_counter - 1) & 7;
-
if (m_shift_counter == 0)
{
- set_int(INT_SR);
+ LOGINT("SHIFT in INT request ");
+ set_int(INT_SR);// TODO: this interrupt is 1-2 clock cycles too early for O2 control mode
}
+ m_shift_counter = (m_shift_counter - 1) & 7;
}
@@ -384,22 +400,52 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
switch (id)
{
case TIMER_SHIFT:
- LOGSHIFT("SHIFT timer event\n");
+ 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);
+ if ((SO_O2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr)) && m_shift_state == SHIFTER_FINISH)
+ {
+ if (m_out_cb1 & 1) // last raising flank
+ {
+ shift_in();
+ m_shift_state = SHIFTER_IDLE;
+ m_shift_timer->adjust(attotime::never);
+ LOGSHIFT("Timer stops");
+ }
+ else // last falling flank (just for shift in)
+ {
+ m_shift_timer->adjust(clocks_to_attotime(1));
+ }
+ break;
+ }
+
if (m_out_cb1 & 1) // raising flank
{
if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr))
{
- shift_in();
+ shift_in(); // close latch
+
+ // Shift in also on the last flanks
+ if (m_shift_counter == 0)
+ {
+ m_shift_state = SHIFTER_FINISH;
+ m_shift_timer->adjust(clocks_to_attotime(1));
+ }
}
}
else // falling flank
{
if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
{
- shift_out();
+ shift_out(); // close latch
+ }
+
+ // Let external devices latch also on last raising edge.
+ if ((SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr)) && m_shift_counter == 0)
+ {
+ m_shift_state = SHIFTER_FINISH;
+ m_shift_timer->adjust(clocks_to_attotime(1));
}
}
@@ -415,7 +461,6 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
}
break;
-
case TIMER_T1:
if (T1_CONTINUOUS (m_acr))
{
@@ -434,6 +479,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
output_pb();
}
+ LOGINT("T1 INT request ");
set_int(INT_T1);
break;
@@ -441,6 +487,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
m_t2_active = 0;
m_time2 = machine().time();
+ LOGINT("T2 INT request ");
set_int(INT_T2);
break;
@@ -627,12 +674,14 @@ READ8_MEMBER( via6522_device::read )
LOGSHIFT("Read SR: %02x ", m_sr);
val = m_sr;
m_out_cb1 = 1;
+ m_cb1_handler(m_out_cb1);
m_shift_counter = 8;
clear_int(INT_SR);
LOGSHIFT("ACR: %02x ", m_acr);
if (SI_O2_CONTROL(m_acr))
{
m_shift_timer->adjust(clocks_to_attotime(1));
+ shift_in();
LOGSHIFT("SI_O2 starts timer ");
}
else if (SI_T2_CONTROL(m_acr))
@@ -664,6 +713,9 @@ READ8_MEMBER( via6522_device::read )
val = m_ifr;
break;
}
+ LOGR(" * %s Reg %02x -> %02x - %s\n", tag(), offset, val, std::array<char const *, 16>
+ {{"IRB", "IRA", "DDRB", "DDRA", "T1CL","T1CH","T1LL","T1LH","T2CL","T2CH","SR","ACR","PCR","IFR","IER","IRA (nh)"}}[offset]);
+
return val;
}
@@ -676,7 +728,8 @@ WRITE8_MEMBER( via6522_device::write )
{
offset &=0x0f;
- LOGSETUP(" * %s Reg %02x <- %02x \n", tag(), offset, data);
+ LOGSETUP(" * %s Reg %02x <- %02x - %s\n", tag(), offset, data, std::array<char const *, 16>
+ {{"ORB", "ORA", "DDRB", "DDRA", "T1CL","T1CH","T1LL","T1LH","T2CL","T2CH","SR","ACR","PCR","IFR","IER","ORA (nh)"}}[offset]);
switch (offset)
{
@@ -799,13 +852,21 @@ WRITE8_MEMBER( via6522_device::write )
case VIA_SR:
m_sr = data;
LOGSHIFT("Write SR: %02x\n", m_sr);
- m_out_cb1 = 1;
+
+ // make sure CB1 is high - this should not be needed though
+ if (m_out_cb1 != 1)
+ {
+ logerror("VIA: CB1 is low starting shifter\n");
+ m_out_cb1 = 1;
+ m_cb1_handler(m_out_cb1);
+ }
+
m_shift_counter = 8;
clear_int(INT_SR);
- LOGSHIFT("ACR: %02x ", m_acr);
+ LOGSHIFT(" - ACR is: %02x ", m_acr);
if (SO_O2_CONTROL(m_acr))
{
- m_shift_timer->adjust(clocks_to_attotime(1));
+ m_shift_timer->adjust(clocks_to_attotime(1)); // Let CB1 clock it on into to remote device
LOGSHIFT("SO_O2 starts timer");
}
else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr))
@@ -927,6 +988,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca1 )
m_latch_a = input_pa();
}
+ LOGINT("CA1 INT request ");
set_int(INT_CA1);
if (!m_out_ca2 && CA2_AUTO_HS(m_pcr))
@@ -953,6 +1015,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca2 )
{
if ((m_in_ca2 && CA2_LOW_TO_HIGH(m_pcr)) || (!m_in_ca2 && CA2_HIGH_TO_LOW(m_pcr)))
{
+ LOGINT("CA2 INT request ");
set_int(INT_CA2);
}
}
@@ -999,6 +1062,7 @@ WRITE_LINE_MEMBER( via6522_device::write_cb1 )
shift_in();
}
+ LOGINT("CB1 INT request ");
set_int(INT_CB1);
if (!m_out_cb2 && CB2_AUTO_HS(m_pcr))
@@ -1032,11 +1096,13 @@ WRITE_LINE_MEMBER( via6522_device::write_cb2 )
if (m_in_cb2 != state)
{
m_in_cb2 = state;
+ LOGSHIFT("CB2 IN: %d\n", m_in_cb2);
if (CB2_INPUT(m_pcr))
{
if ((m_in_cb2 && CB2_LOW_TO_HIGH(m_pcr)) || (!m_in_cb2 && CB2_HIGH_TO_LOW(m_pcr)))
{
+ LOGINT("CB2 INT request ");
set_int(INT_CB2);
}
}
diff --git a/src/devices/machine/6522via.h b/src/devices/machine/6522via.h
index 0c06863494c..785fa0f50a2 100644
--- a/src/devices/machine/6522via.h
+++ b/src/devices/machine/6522via.h
@@ -18,9 +18,6 @@
#ifndef __6522VIA_H__
#define __6522VIA_H__
-
-
-
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
@@ -210,6 +207,14 @@ private:
emu_timer *m_shift_timer;
uint8_t m_shift_counter;
+ enum m_shift_state_t
+ {
+ SHIFTER_IDLE,
+ SHIFTER_SHIFT,
+ SHIFTER_FINISH,
+ SHIFTER_IRQ
+ };
+ m_shift_state_t m_shift_state;
};