diff options
Diffstat (limited to 'src/devices/cpu/i86/i186.cpp')
-rw-r--r-- | src/devices/cpu/i86/i186.cpp | 106 |
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); + } + } +} + /************************************* |