summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i86/i186.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i86/i186.cpp')
-rw-r--r--src/devices/cpu/i86/i186.cpp106
1 files changed, 49 insertions, 57 deletions
diff --git a/src/devices/cpu/i86/i186.cpp b/src/devices/cpu/i86/i186.cpp
index ee0500e0fc9..d1c87e1cd4d 100644
--- a/src/devices/cpu/i86/i186.cpp
+++ b/src/devices/cpu/i86/i186.cpp
@@ -634,27 +634,14 @@ void i80186_cpu_device::device_start()
state_add( I80186_POLLSTS, "POLLSTS", m_intr.poll_status ).formatstr("%04X");
// register for savestates
- save_item(NAME(m_timer[0].control));
- save_item(NAME(m_timer[0].maxA));
- save_item(NAME(m_timer[0].maxB));
- save_item(NAME(m_timer[0].active_count));
- save_item(NAME(m_timer[0].count));
- save_item(NAME(m_timer[1].control));
- save_item(NAME(m_timer[1].maxA));
- save_item(NAME(m_timer[1].maxB));
- save_item(NAME(m_timer[1].active_count));
- save_item(NAME(m_timer[1].count));
- save_item(NAME(m_timer[2].control));
- save_item(NAME(m_timer[2].maxA));
- save_item(NAME(m_timer[2].count));
- save_item(NAME(m_dma[0].source));
- save_item(NAME(m_dma[0].dest));
- save_item(NAME(m_dma[0].count));
- save_item(NAME(m_dma[0].control));
- save_item(NAME(m_dma[1].source));
- save_item(NAME(m_dma[1].dest));
- save_item(NAME(m_dma[1].count));
- save_item(NAME(m_dma[1].control));
+ save_item(STRUCT_MEMBER(m_timer, control));
+ save_item(STRUCT_MEMBER(m_timer, maxA));
+ save_item(STRUCT_MEMBER(m_timer, maxB));
+ save_item(STRUCT_MEMBER(m_timer, count));
+ save_item(STRUCT_MEMBER(m_dma, source));
+ save_item(STRUCT_MEMBER(m_dma, dest));
+ save_item(STRUCT_MEMBER(m_dma, count));
+ save_item(STRUCT_MEMBER(m_dma, control));
save_item(NAME(m_intr.vector));
save_item(NAME(m_intr.pending));
save_item(NAME(m_intr.ack_mask));
@@ -732,7 +719,6 @@ void i80186_cpu_device::device_reset()
elem.control = 0;
elem.maxA = 0;
elem.maxB = 0;
- elem.active_count = false;
elem.count = 0;
}
}
@@ -1260,36 +1246,21 @@ void i80186_cpu_device::device_timer(emu_timer &timer, device_timer_id id, int p
else
{
if(which)
- m_out_tmrout1_func(t->active_count);
+ m_out_tmrout1_func((t->control & 0x1000) ? 1 : 0);
else
- m_out_tmrout0_func(t->active_count);
+ m_out_tmrout0_func((t->control & 0x1000) ? 1 : 0);
}
}
/* if we're continuous or altcounting, reset */
- if((t->control & 1) || ((t->control & 2) && (which != 2) && !t->active_count))
+ if((t->control & 1) || ((t->control & 2) && !(t->control & 0x1000)))
{
- int count;
- if((t->control & 2) && (which != 2))
- {
- count = t->active_count ? t->maxA : t->maxB;
- if(!t->active_count)
- {
- t->active_count = 1;
- t->control |= 0x1000;
- }
- else
- {
- t->active_count = 0;
- t->control &= ~0x1000;
- }
- }
+ if((t->control & 2) && !(t->control & 0x1000))
+ t->control |= 0x1000;
else
- count = t->maxA;
+ t->control &= ~0x1000;
- count = count ? count : 0x10000;
- if(!(t->control & 4))
- t->int_timer->adjust((attotime::from_hz(clock()/8) * count), which);
+ restart_timer(which);
if (LOG_TIMER) logerror(" Repriming interrupt\n");
}
else
@@ -1307,13 +1278,21 @@ void i80186_cpu_device::device_timer(emu_timer &timer, device_timer_id id, int p
}
+void i80186_cpu_device::restart_timer(int which)
+{
+ timer_state *t = &m_timer[which];
+ int count = (t->control & 0x1000) ? t->maxB : t->maxA;
+ if(!(t->control & 4))
+ t->int_timer->adjust((attotime::from_hz(clock()/8) * (count ? count : 0x10000)), which);
+}
+
void i80186_cpu_device::internal_timer_sync(int which)
{
timer_state *t = &m_timer[which];
/* if we have a timing timer running, adjust the count */
- if ((t->control & 0x8000) && !(t->control & 0x0c))
- t->count = (((which != 2) && t->active_count) ? t->maxB : t->maxA) - t->int_timer->remaining().as_ticks(clock() / 8);
+ if ((t->control & 0x8000) && !(t->control & 0x0c) && t->int_timer->enabled())
+ t->count = ((t->control & 0x1000) ? t->maxB : t->maxA) - t->int_timer->remaining().as_ticks(clock() / 8);
}
void i80186_cpu_device::inc_timer(int which)
@@ -1323,7 +1302,7 @@ void i80186_cpu_device::inc_timer(int which)
t->count++;
if (t->control & 2)
{
- if (t->count == (t->active_count ? t->maxB : t->maxA))
+ if (t->count == ((t->control & 0x1000) ? t->maxB : t->maxA))
device_timer(*t->int_timer, which, which, nullptr);
}
else if (t->count == t->maxA)
@@ -1386,7 +1365,6 @@ void i80186_cpu_device::internal_timer_update(int which, int new_count, int new_
/* handle control changes */
if (new_control != -1)
{
- int diff;
uint16_t resbits = (which == 2) ? 0x1fde : 0x1fc0;
/* merge back in the bits we don't modify */
@@ -1397,12 +1375,8 @@ void i80186_cpu_device::internal_timer_update(int which, int new_count, int new_
new_control = (new_control & ~0x8000) | (t->control & 0x8000);
new_control &= ~0x4000;
- /* check for control bits we don't handle */
- diff = new_control ^ t->control;
- if (diff & 0x0010)
- logerror("%05X:ERROR! -unsupported timer mode %04X\n", m_pc, new_control);
-
/* if we have real changes, update things */
+ uint16_t diff = new_control ^ t->control;
if (diff != 0)
{
/* if we're going off, make sure our timers are gone */
@@ -1427,6 +1401,10 @@ void i80186_cpu_device::internal_timer_update(int which, int new_count, int new_
}
}
+ /* RIU is cleared whenever ALT = 0 */
+ if (!(new_control & 0x0002))
+ new_control &= ~0x1000;
+
/* set the new control register */
t->control = new_control;
}
@@ -1434,11 +1412,9 @@ void i80186_cpu_device::internal_timer_update(int which, int new_count, int new_
/* update the interrupt timer */
if (update_int_timer)
{
- t->active_count = 0;
- t->control &= ~0x1000;
- if ((t->control & 0x8000) && !(t->control & 4))
+ if ((t->control & 0x8004) == 0x8000 && (!(t->control & 0x10) || t->int_timer->enabled()))
{
- int diff = t->maxA - t->count;
+ int diff = ((t->control & 0x1000) ? t->maxB : t->maxA) - t->count;
if (diff <= 0)
diff += 0x10000;
t->int_timer->adjust(attotime::from_hz(clock()/8) * diff, which);
@@ -1451,6 +1427,22 @@ void i80186_cpu_device::internal_timer_update(int which, int new_count, int new_
}
}
+void i80186_cpu_device::external_tmrin(int which, int state)
+{
+ // TODO: make this an actual edge trigger
+ if (state)
+ {
+ if ((m_timer[which].control & 0x8004) == 0x8004)
+ inc_timer(which);
+ else if ((m_timer[which].control & 0x8014) == 0x8010)
+ {
+ m_timer[which].count = 0;
+ restart_timer(which);
+ if (LOG_TIMER) logerror("Retriggered timer %d\n", which);
+ }
+ }
+}
+
/*************************************