diff options
Diffstat (limited to 'src/devices/cpu/h8/h8_dtc.cpp')
-rw-r--r-- | src/devices/cpu/h8/h8_dtc.cpp | 228 |
1 files changed, 120 insertions, 108 deletions
diff --git a/src/devices/cpu/h8/h8_dtc.cpp b/src/devices/cpu/h8/h8_dtc.cpp index f600b71c6a8..3dd276fca11 100644 --- a/src/devices/cpu/h8/h8_dtc.cpp +++ b/src/devices/cpu/h8/h8_dtc.cpp @@ -1,11 +1,16 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + #include "emu.h" #include "h8_dtc.h" +#include "h8.h" + // Verbosity level // 0 = no messages // 1 = in-memory registers once read // 2 = everything -const int V = 0; +static constexpr int V = 0; DEFINE_DEVICE_TYPE(H8_DTC, h8_dtc_device, "h8_dtc", "H8 DTC controller") @@ -24,191 +29,198 @@ const int h8_dtc_device::vector_to_enable[92] = { -1, 40, 41, -1 // ERI2, RXI2, TXI2, TEI2 }; -h8_dtc_device::h8_dtc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +h8_dtc_device::h8_dtc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, H8_DTC, tag, owner, clock), - cpu(*this, DEVICE_SELF_OWNER) -{ -} - -void h8_dtc_device::set_info(const char *_intc_tag, int _irq) + m_cpu(*this, finder_base::DUMMY_TAG), + m_intc(*this, finder_base::DUMMY_TAG) { - intc_tag = _intc_tag; - irq = _irq; } void h8_dtc_device::device_start() { - intc = siblingdevice<h8_intc_device>(intc_tag); + // TODO, probably need to kill the vectors + save_item(STRUCT_MEMBER(m_states, m_base)); + save_item(STRUCT_MEMBER(m_states, m_sra)); + save_item(STRUCT_MEMBER(m_states, m_dar)); + save_item(STRUCT_MEMBER(m_states, m_cr)); + save_item(STRUCT_MEMBER(m_states, m_incs)); + save_item(STRUCT_MEMBER(m_states, m_incd)); + save_item(STRUCT_MEMBER(m_states, m_count)); + save_item(STRUCT_MEMBER(m_states, m_id)); + save_item(STRUCT_MEMBER(m_states, m_next)); + + save_item(NAME(m_dtcer)); + save_item(NAME(m_dtvecr)); + save_item(NAME(m_cur_active_vector)); } void h8_dtc_device::device_reset() { - memset(dtcer, 0x00, sizeof(dtcer)); - memset(states, 0, sizeof(states)); - for(uint8_t i=0; i<sizeof(states)/sizeof(states[0]); i++) - states[i].id = i; - dtvecr = 0x00; - cur_active_vector = -1; + memset(m_dtcer, 0x00, sizeof(m_dtcer)); + memset(m_states, 0, sizeof(m_states)); + for(u8 i=0; i<sizeof(m_states)/sizeof(m_states[0]); i++) + m_states[i].m_id = i; + m_dtvecr = 0x00; + m_cur_active_vector = -1; } -READ8_MEMBER(h8_dtc_device::dtcer_r) +u8 h8_dtc_device::dtcer_r(offs_t offset) { - if(V>=2) logerror("dtcer_r %x, %02x\n", offset, dtcer[offset]); - return dtcer[offset]; + if(V>=2) logerror("dtcer_r %x, %02x\n", offset, m_dtcer[offset]); + return m_dtcer[offset]; } -WRITE8_MEMBER(h8_dtc_device::dtcer_w) +void h8_dtc_device::dtcer_w(offs_t offset, u8 data) { - dtcer[offset] = data; + m_dtcer[offset] = data; if(V>=2) logerror("dtcer_w %x, %02x\n", offset, data); } -READ8_MEMBER(h8_dtc_device::dtvecr_r) +u8 h8_dtc_device::dtvecr_r() { - if(V>=2) logerror("dtvecr_r %02x\n", dtvecr); - return dtvecr; + if(V>=2) logerror("dtvecr_r %02x\n", m_dtvecr); + return m_dtvecr; } -WRITE8_MEMBER(h8_dtc_device::dtvecr_w) +void h8_dtc_device::dtvecr_w(u8 data) { - dtvecr = data; + m_dtvecr = data; if(V>=2) logerror("dtvecr_w %02x\n", data); } void h8_dtc_device::edge(int vector) { - for(std::list<int>::const_iterator i = waiting_vector.begin(); i != waiting_vector.end(); ++i) - if(*i == vector) + for(auto i : m_waiting_vector) + if(i == vector) return; - for(std::list<int>::const_iterator i = waiting_writeback.begin(); i != waiting_writeback.end(); ++i) - if(*i == vector) + for(auto i : m_waiting_writeback) + if(i == vector) return; - if(waiting_vector.empty() && waiting_writeback.empty()) - cpu->request_state(h8_device::STATE_DTC_VECTOR); - waiting_vector.push_back(vector); + if(m_waiting_vector.empty() && m_waiting_writeback.empty()) + m_cpu->request_state(h8_device::STATE_DTC_VECTOR); + m_waiting_vector.push_back(vector); } int h8_dtc_device::get_waiting_vector() { - assert(!waiting_vector.empty()); - return waiting_vector.front(); + assert(!m_waiting_vector.empty()); + return m_waiting_vector.front(); } int h8_dtc_device::get_waiting_writeback() { - assert(!waiting_writeback.empty()); - return waiting_writeback.front(); + assert(!m_waiting_writeback.empty()); + return m_waiting_writeback.front(); } void h8_dtc_device::queue(int vector) { int ps = -1; - int cs = cur_active_vector; + int cs = m_cur_active_vector; while(cs != -1 && cs < vector) { ps = cs; - cs = states[cs].next; + cs = m_states[cs].m_next; } - states[vector].next = cs; + m_states[vector].m_next = cs; if(ps == -1) { - cur_active_vector = vector; - cpu->set_current_dtc(&states[vector]); + m_cur_active_vector = vector; + m_cpu->set_current_dtc(&m_states[vector]); } else - states[ps].next = vector; + m_states[ps].m_next = vector; } void h8_dtc_device::vector_done(int vector) { - std::list<int>::iterator wi; - for(wi = waiting_vector.begin(); wi != waiting_vector.end() && *wi != vector && *wi != vector + DTC_CHAINED; ++wi) {}; - assert(wi != waiting_vector.end()); - waiting_vector.erase(wi); - - h8_dtc_state *state = states + vector; - uint32_t sra = state->sra; - uint32_t dar = state->dar; - uint32_t cr = state->cr; - - uint32_t mode = sra & 0x0c000000; - if(V>=1) logerror("regs at %08x sra=%08x dar=%08x cr=%08x %s mode\n", state->base, sra, dar, cr, + std::vector<int>::iterator wi; + for(wi = m_waiting_vector.begin(); wi != m_waiting_vector.end() && *wi != vector && *wi != vector + DTC_CHAINED; ++wi) {}; + assert(wi != m_waiting_vector.end()); + m_waiting_vector.erase(wi); + + h8_dtc_state *state = m_states + vector; + u32 sra = state->m_sra; + u32 dar = state->m_dar; + u32 cr = state->m_cr; + + u32 mode = sra & 0x0c000000; + if(V>=1) logerror("regs at %08x sra=%08x dar=%08x cr=%08x %s mode\n", state->m_base, sra, dar, cr, mode == 0x00000000 || mode == 0x0c000000 ? "normal" : mode == 0x04000000 ? "repeat" : "block"); - state->incs = sra & 0x80000000 ? + state->m_incs = sra & 0x80000000 ? sra & 0x40000000 ? sra & 0x01000000 ? -2 : -1 : sra & 0x01000000 ? 2 : 1 : 0; - state->incd = sra & 0x20000000 ? + state->m_incd = sra & 0x20000000 ? sra & 0x10000000 ? sra & 0x01000000 ? -2 : -1 : sra & 0x01000000 ? 2 : 1 : 0; switch(mode) { case 0x00000000: case 0x0c0000000: - state->count = 1; + state->m_count = 1; break; case 0x04000000: - state->count = 1; + state->m_count = 1; break; case 0x08000000: - state->count = (cr >> 16) & 255; - if(!state->count) - state->count = 256; + state->m_count = (cr >> 16) & 255; + if(!state->m_count) + state->m_count = 256; break; } queue(vector); - if(!waiting_vector.empty()) - cpu->request_state(h8_device::STATE_DTC_VECTOR); - else if(!waiting_writeback.empty()) - cpu->request_state(h8_device::STATE_DTC_WRITEBACK); + if(!m_waiting_vector.empty()) + m_cpu->request_state(h8_device::STATE_DTC_VECTOR); + else if(!m_waiting_writeback.empty()) + m_cpu->request_state(h8_device::STATE_DTC_WRITEBACK); } void h8_dtc_device::writeback_done(int vector) { - std::list<int>::iterator wi; - for(wi = waiting_writeback.begin(); wi != waiting_writeback.end() && *wi != vector; ++wi) {}; - assert(wi != waiting_writeback.end()); - waiting_writeback.erase(wi); + std::vector<int>::iterator wi; + for(wi = m_waiting_writeback.begin(); wi != m_waiting_writeback.end() && *wi != vector; ++wi) {}; + assert(wi != m_waiting_writeback.end()); + m_waiting_writeback.erase(wi); - h8_dtc_state *state = states + vector; + h8_dtc_state *state = m_states + vector; bool done = false; - switch(state->sra & 0x0c000000) { + switch(state->m_sra & 0x0c000000) { case 0x00000000: case 0x0c0000000: - done = !(state->cr & 0xffff0000); + done = !(state->m_cr & 0xffff0000); break; case 0x04000000: break; case 0x08000000: - done = !(state->cr & 0x0000ffff); + done = !(state->m_cr & 0x0000ffff); break; } - if(done && state->dar & 0x80000000) { - cpu->request_state(h8_device::STATE_DTC_VECTOR); - waiting_vector.push_back(vector + DTC_CHAINED); + if(done && state->m_dar & 0x80000000) { + m_cpu->request_state(h8_device::STATE_DTC_VECTOR); + m_waiting_vector.push_back(vector + DTC_CHAINED); return; } - if(done || (state->dar & 0x40000000)) { + if(done || (state->m_dar & 0x40000000)) { if(vector) { int slot = vector_to_enable[vector]; assert(slot != -1); - dtcer[slot >> 3] &= ~(0x01 << (7-(slot & 7))); - intc->internal_interrupt(vector); + m_dtcer[slot >> 3] &= ~(0x01 << (7-(slot & 7))); + m_intc->internal_interrupt(vector); } else { logerror("Software dtc done\n"); - exit(0); } } - if(!waiting_vector.empty()) - cpu->request_state(h8_device::STATE_DTC_VECTOR); - else if(!waiting_writeback.empty()) - cpu->request_state(h8_device::STATE_DTC_WRITEBACK); + if(!m_waiting_vector.empty()) + m_cpu->request_state(h8_device::STATE_DTC_VECTOR); + else if(!m_waiting_writeback.empty()) + m_cpu->request_state(h8_device::STATE_DTC_WRITEBACK); } bool h8_dtc_device::trigger_dtc(int vector) @@ -216,7 +228,7 @@ bool h8_dtc_device::trigger_dtc(int vector) int slot = vector_to_enable[vector]; if(slot == -1) return false; - if(dtcer[slot >> 3] & (0x01 << (7-(slot & 7)))) { + if(m_dtcer[slot >> 3] & (0x01 << (7-(slot & 7)))) { edge(vector); return true; } @@ -225,44 +237,44 @@ bool h8_dtc_device::trigger_dtc(int vector) void h8_dtc_device::count_done(int id) { - assert(cur_active_vector == id); - cur_active_vector = states[id].next; - if(cur_active_vector != -1) - cpu->set_current_dtc(states + cur_active_vector); + assert(m_cur_active_vector == id); + m_cur_active_vector = m_states[id].m_next; + if(m_cur_active_vector != -1) + m_cpu->set_current_dtc(m_states + m_cur_active_vector); - h8_dtc_state *state = states + id; - switch(state->sra & 0x0c000000) { + h8_dtc_state *state = m_states + id; + switch(state->m_sra & 0x0c000000) { case 0x00000000: case 0x0c0000000: - state->cr -= 0x00010000; + state->m_cr -= 0x00010000; break; case 0x04000000: - state->cr = (state->cr & 0xff00ffff) | ((state->cr - 0x00010000) & 0x00ff0000); - if(!(state->cr & 0x00ff0000)) { - int cnt = (state->cr >> 24) & 0xff; + state->m_cr = (state->m_cr & 0xff00ffff) | ((state->m_cr - 0x00010000) & 0x00ff0000); + if(!(state->m_cr & 0x00ff0000)) { + int cnt = (state->m_cr >> 24) & 0xff; if(!cnt) cnt = 256; - if(state->sra & 0x02000000) - state->sra = (state->sra & 0xff000000) | ((state->sra - cnt*state->incs) & 0xffffff); + if(state->m_sra & 0x02000000) + state->m_sra = (state->m_sra & 0xff000000) | ((state->m_sra - cnt*state->m_incs) & 0xffffff); else - state->dar = (state->dar & 0xff000000) | ((state->dar - cnt*state->incd) & 0xffffff); - state->cr |= (state->cr >> 8) & 0x00ff0000; + state->m_dar = (state->m_dar & 0xff000000) | ((state->m_dar - cnt*state->m_incd) & 0xffffff); + state->m_cr |= (state->m_cr >> 8) & 0x00ff0000; } break; case 0x08000000: { - int cnt = (state->cr >> 16) & 0xff; + int cnt = (state->m_cr >> 16) & 0xff; if(!cnt) cnt = 256; - if(state->sra & 0x02000000) - state->sra = (state->sra & 0xff000000) | ((state->sra - cnt*state->incs) & 0xffffff); + if(state->m_sra & 0x02000000) + state->m_sra = (state->m_sra & 0xff000000) | ((state->m_sra - cnt*state->m_incs) & 0xffffff); else - state->dar = (state->dar & 0xff000000) | ((state->dar - cnt*state->incd) & 0xffffff); - state->cr = (state->cr & 0xff000000) | ((state->cr >> 8) & 0x00ff0000) | ((state->cr - 0x00000001) & 0x0000ffff); + state->m_dar = (state->m_dar & 0xff000000) | ((state->m_dar - cnt*state->m_incd) & 0xffffff); + state->m_cr = (state->m_cr & 0xff000000) | ((state->m_cr >> 8) & 0x00ff0000) | ((state->m_cr - 0x00000001) & 0x0000ffff); break; } } - if(waiting_vector.empty() && waiting_writeback.empty()) - cpu->request_state(h8_device::STATE_DTC_WRITEBACK); - waiting_writeback.push_back(id); + if(m_waiting_vector.empty() && m_waiting_writeback.empty()) + m_cpu->request_state(h8_device::STATE_DTC_WRITEBACK); + m_waiting_writeback.push_back(id); } |