From acf309c9b279c07b92dc1f40d635df3384bec656 Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 18 Mar 2024 02:01:28 +0100 Subject: h8: add more variables to savestate, h8_intc: fix issue with multiple pending edge triggered irq --- src/devices/cpu/h8/h8.cpp | 16 ++++++++++++++-- src/devices/cpu/h8/h8.h | 3 +-- src/devices/cpu/h8/h8_adc.cpp | 2 +- src/devices/cpu/h8/h8_dma.cpp | 7 +++---- src/devices/cpu/h8/h8_dma.h | 1 - src/devices/cpu/h8/h8_dtc.cpp | 13 +++++++++++++ src/devices/cpu/h8/h8_intc.cpp | 38 ++++++++++++++++++++++++++------------ src/devices/cpu/h8/h8_intc.h | 4 +++- src/devices/cpu/h8/h8_port.cpp | 2 +- src/devices/cpu/h8/h8_sci.cpp | 24 +++++++++++++----------- src/devices/cpu/h8/h8_timer16.cpp | 6 ++---- src/devices/cpu/h8/h8_timer8.cpp | 26 +++++++++++++++++++------- src/devices/cpu/h8/h8_watchdog.cpp | 2 +- 13 files changed, 97 insertions(+), 47 deletions(-) diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 4f78cef6752..010205f6cda 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -40,7 +40,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char m_standby_cb(*this), m_PPC(0), m_NPC(0), m_PC(0), m_PIR(0), m_EXR(0), m_CCR(0), m_MAC(0), m_MACF(0), m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0), - m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_required(false), m_irq_nmi(false), + m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_nmi(false), m_standby_pending(false), m_standby_time(0), m_nvram_defval(0), m_nvram_battery(true) { m_supports_advanced = false; @@ -147,7 +147,9 @@ void h8_device::device_start() state_add(H8_R7, "ER7", m_TMPR).callimport().callexport().formatstr("%9s"); } + save_item(NAME(m_current_dma)); save_item(NAME(m_cycles_base)); + save_item(NAME(m_PPC)); save_item(NAME(m_NPC)); save_item(NAME(m_PC)); @@ -156,16 +158,26 @@ void h8_device::device_start() save_item(NAME(m_R)); save_item(NAME(m_EXR)); save_item(NAME(m_CCR)); + save_item(NAME(m_MAC)); + save_item(NAME(m_MACF)); save_item(NAME(m_TMP1)); save_item(NAME(m_TMP2)); + save_item(NAME(m_TMPR)); + + save_item(NAME(m_mode_advanced)); + save_item(NAME(m_mode_a20)); + save_item(NAME(m_mac_saturating)); + save_item(NAME(m_inst_state)); save_item(NAME(m_inst_substate)); + save_item(NAME(m_requested_state)); + save_item(NAME(m_bcount)); + save_item(NAME(m_count_before_instruction_step)); save_item(NAME(m_irq_vector)); save_item(NAME(m_taken_irq_vector)); save_item(NAME(m_irq_level)); save_item(NAME(m_taken_irq_level)); save_item(NAME(m_irq_nmi)); - save_item(NAME(m_current_dma)); save_item(NAME(m_standby_pending)); save_item(NAME(m_standby_time)); save_item(NAME(m_nvram_battery)); diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h index bf6b9540b73..0c6abbaa13c 100644 --- a/src/devices/cpu/h8/h8.h +++ b/src/devices/cpu/h8/h8.h @@ -178,8 +178,7 @@ protected: int m_icount, m_bcount, m_count_before_instruction_step; int m_irq_vector, m_taken_irq_vector; int m_irq_level, m_taken_irq_level; - bool m_irq_required, m_irq_nmi; - bool m_standby_pending; + bool m_irq_nmi, m_standby_pending; u64 m_standby_time; u16 m_nvram_defval; bool m_nvram_battery; diff --git a/src/devices/cpu/h8/h8_adc.cpp b/src/devices/cpu/h8/h8_adc.cpp index c1ad3f4b048..3ca7a0f19dc 100644 --- a/src/devices/cpu/h8/h8_adc.cpp +++ b/src/devices/cpu/h8/h8_adc.cpp @@ -110,8 +110,8 @@ void h8_adc_device::device_start() save_item(NAME(m_channel)); save_item(NAME(m_count)); save_item(NAME(m_analog_powered)); - save_item(NAME(m_next_event)); save_item(NAME(m_adtrg)); + save_item(NAME(m_next_event)); } void h8_adc_device::device_reset() diff --git a/src/devices/cpu/h8/h8_dma.cpp b/src/devices/cpu/h8/h8_dma.cpp index 4dea329f968..3edb36c70e0 100644 --- a/src/devices/cpu/h8/h8_dma.cpp +++ b/src/devices/cpu/h8/h8_dma.cpp @@ -87,10 +87,8 @@ void h8gen_dma_device::start_stop_test() - // DMA channel, common code - h8gen_dma_channel_device::h8gen_dma_channel_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock), m_cpu(*this, finder_base::DUMMY_TAG), @@ -105,9 +103,11 @@ void h8gen_dma_channel_device::device_start() save_item(STRUCT_MEMBER(m_state, m_incs)); save_item(STRUCT_MEMBER(m_state, m_incd)); save_item(STRUCT_MEMBER(m_state, m_count)); + save_item(STRUCT_MEMBER(m_state, m_bcount)); save_item(STRUCT_MEMBER(m_state, m_flags)); save_item(STRUCT_MEMBER(m_state, m_id)); save_item(STRUCT_MEMBER(m_state, m_trigger_vector)); + save_item(NAME(m_mar)); save_item(NAME(m_ioar)); save_item(NAME(m_etcr)); @@ -143,7 +143,6 @@ void h8gen_dma_channel_device::set_dreq(int state) m_dreq = state; // Only subchannel B/1 can react to dreq. - if(m_dreq) { if(((m_state[1].m_flags & (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) == (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) && (m_state[1].m_trigger_vector == DREQ_LEVEL || m_state[1].m_trigger_vector == DREQ_EDGE)) { m_state[1].m_flags &= ~h8_dma_state::SUSPENDED; @@ -359,7 +358,7 @@ void h8gen_dma_channel_device::count_done(int submodule) m_state[submodule].m_source = m_mar[0]; m_state[submodule].m_count = m_etcr[0] & 0xff00 ? m_etcr[0] >> 8 : 0x100; - m_state[submodule].m_bcount --; + m_state[submodule].m_bcount--; if(m_state[submodule].m_bcount == 1) m_state[submodule].m_flags &= ~h8_dma_state::BLOCK; diff --git a/src/devices/cpu/h8/h8_dma.h b/src/devices/cpu/h8/h8_dma.h index 3ad1d731b2a..20858847082 100644 --- a/src/devices/cpu/h8/h8_dma.h +++ b/src/devices/cpu/h8/h8_dma.h @@ -133,7 +133,6 @@ protected: - class h8gen_dma_channel_device : public device_t { public: enum { diff --git a/src/devices/cpu/h8/h8_dtc.cpp b/src/devices/cpu/h8/h8_dtc.cpp index 008f5eabeef..7844c9cec92 100644 --- a/src/devices/cpu/h8/h8_dtc.cpp +++ b/src/devices/cpu/h8/h8_dtc.cpp @@ -39,6 +39,19 @@ h8_dtc_device::h8_dtc_device(const machine_config &mconfig, const char *tag, dev void h8_dtc_device::device_start() { // 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() diff --git a/src/devices/cpu/h8/h8_intc.cpp b/src/devices/cpu/h8/h8_intc.cpp index f599f5e93db..0e471d7330f 100644 --- a/src/devices/cpu/h8/h8_intc.cpp +++ b/src/devices/cpu/h8/h8_intc.cpp @@ -51,7 +51,7 @@ void h8_intc_device::device_start() void h8_intc_device::device_reset() { - memset(m_irq_type, 0, sizeof(m_irq_type)); + memset(m_irq_type, 0, sizeof(m_irq_type)); // LEVEL_LOW m_nmi_type = EDGE_FALL; memset(m_pending_irqs, 0, sizeof(m_pending_irqs)); m_iscr = 0x0000; @@ -98,31 +98,33 @@ void h8_intc_device::set_input(int inputnum, int state) default: assert(0); break; } m_nmi_input = state == ASSERT_LINE; - if(machine().time() > attotime::zero && set) { + if(set && machine().time() > attotime::zero) { m_pending_irqs[0] |= 1 << m_irq_vector_nmi; update_irq_state(); } } else { bool set = false; - bool cur = m_irq_input & (1 << inputnum); + u8 mask = 1 << inputnum; + u8 cur = m_irq_input & mask; switch(m_irq_type[inputnum]) { - case LEVEL_LOW: set = state == ASSERT_LINE; break; + case LEVEL_LOW: + set = state == ASSERT_LINE; + // on base H8, level-triggered IRQ is not latched + if(!set && !m_has_isr) + m_isr &= ~mask; + break; case EDGE_FALL: set = state == ASSERT_LINE && !cur; break; case EDGE_RISE: set = state == CLEAR_LINE && cur; break; case EDGE_DUAL: set = bool(state) != bool(cur); break; } if(state == ASSERT_LINE) - m_irq_input |= 1 << inputnum; + m_irq_input |= mask; else - m_irq_input &= ~(1 << inputnum); + m_irq_input &= ~mask; if(set) { - m_isr |= 1 << inputnum; + m_isr |= mask; update_irq_state(); } - if(!m_has_isr) { - m_isr = 0; - check_level_irqs(!set); - } } } @@ -180,6 +182,8 @@ void h8_intc_device::update_irq_types() m_irq_type[i] = LEVEL_LOW; break; case 1: + if(!m_has_isr && m_irq_type[i] == LEVEL_LOW) + m_isr &= ~(1 << i); m_irq_type[i] = EDGE_FALL; break; } @@ -237,7 +241,8 @@ h8325_intc_device::h8325_intc_device(const machine_config &mconfig, const char * void h8325_intc_device::update_irq_types() { - for(int i = 0; i < m_irq_vector_count; i++) + for(int i = 0; i < m_irq_vector_count; i++) { + u8 type = m_irq_type[i]; switch(bitswap<2>(m_iscr >> i,0,4)) { case 0: case 1: m_irq_type[i] = LEVEL_LOW; @@ -249,6 +254,9 @@ void h8325_intc_device::update_irq_types() m_irq_type[i] = EDGE_RISE; break; } + if(type == LEVEL_LOW && m_irq_type[i] != LEVEL_LOW) + m_isr &= ~(1 << i); + } check_level_irqs(true); } @@ -344,6 +352,12 @@ h8s_intc_device::h8s_intc_device(const machine_config &mconfig, const char *tag, m_irq_vector_nmi = 7; } +void h8s_intc_device::device_start() +{ + h8h_intc_device::device_start(); + save_item(NAME(m_ipr)); +} + void h8s_intc_device::device_reset() { h8h_intc_device::device_reset(); diff --git a/src/devices/cpu/h8/h8_intc.h b/src/devices/cpu/h8/h8_intc.h index 15fe2952f5f..d5ef4c5574f 100644 --- a/src/devices/cpu/h8/h8_intc.h +++ b/src/devices/cpu/h8/h8_intc.h @@ -132,9 +132,11 @@ private: static const int vector_to_slot[]; u8 m_ipr[11]; + virtual void device_start() override; + virtual void device_reset() override; + virtual void get_priority(int vect, int &icr_pri, int &ipr_pri) const override; virtual void update_irq_types() override; - virtual void device_reset() override; }; class gt913_intc_device : public h8_intc_device { diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp index 87253cd3eb0..782f5439646 100644 --- a/src/devices/cpu/h8/h8_port.cpp +++ b/src/devices/cpu/h8/h8_port.cpp @@ -98,9 +98,9 @@ void h8_port_device::update_output() void h8_port_device::device_start() { save_item(NAME(m_ddr)); - save_item(NAME(m_dr)); save_item(NAME(m_pcr)); save_item(NAME(m_odr)); + save_item(NAME(m_dr)); save_item(NAME(m_last_output)); m_last_output = -1; diff --git a/src/devices/cpu/h8/h8_sci.cpp b/src/devices/cpu/h8/h8_sci.cpp index f11e8239805..9f089266111 100644 --- a/src/devices/cpu/h8/h8_sci.cpp +++ b/src/devices/cpu/h8/h8_sci.cpp @@ -293,6 +293,19 @@ void h8_sci_device::device_start() m_internal_to_external_ratio = 1/m_external_to_internal_ratio; } + save_item(NAME(m_tx_state)); + save_item(NAME(m_rx_state)); + save_item(NAME(m_tx_bit)); + save_item(NAME(m_rx_bit)); + save_item(NAME(m_clock_state)); + save_item(NAME(m_tx_parity)); + save_item(NAME(m_rx_parity)); + save_item(NAME(m_tx_clock_counter)); + save_item(NAME(m_rx_clock_counter)); + save_item(NAME(m_clock_mode)); + save_item(NAME(m_ext_clock_value)); + save_item(NAME(m_rx_value)); + save_item(NAME(m_rdr)); save_item(NAME(m_tdr)); save_item(NAME(m_smr)); @@ -301,20 +314,9 @@ void h8_sci_device::device_start() save_item(NAME(m_brr)); save_item(NAME(m_rsr)); save_item(NAME(m_tsr)); - save_item(NAME(m_rx_bit)); - save_item(NAME(m_tx_bit)); - save_item(NAME(m_rx_state)); - save_item(NAME(m_tx_state)); - save_item(NAME(m_tx_parity)); - save_item(NAME(m_clock_mode)); - save_item(NAME(m_clock_state)); save_item(NAME(m_clock_event)); save_item(NAME(m_clock_step)); save_item(NAME(m_divider)); - save_item(NAME(m_rx_value)); - save_item(NAME(m_ext_clock_value)); - save_item(NAME(m_tx_clock_counter)); - save_item(NAME(m_rx_clock_counter)); } void h8_sci_device::device_reset() diff --git a/src/devices/cpu/h8/h8_timer16.cpp b/src/devices/cpu/h8/h8_timer16.cpp index d7aa2c2a8cf..e76f6bd60ca 100644 --- a/src/devices/cpu/h8/h8_timer16.cpp +++ b/src/devices/cpu/h8/h8_timer16.cpp @@ -271,15 +271,13 @@ void h8_timer16_channel_device::update_counter(u64 cur_time) m_tcnt = (tt - 0x10000) % m_counter_cycle; else m_tcnt = tt; - } - else + } else m_tcnt = tt % m_counter_cycle; for(int i = 0; i < m_tgr_count; i++) { bool match = m_tcnt == m_tgr[i] || (tt == m_tgr[i] && tt == m_counter_cycle); if(!match) { - // Need to do additional checks here for software that polls the flags with interrupts disabled, - // since recalc_event only schedules IRQ events. + // Need to do additional checks here for software that polls the flags with interrupts disabled, since recalc_event only schedules IRQ events. if(prev >= m_counter_cycle) match = (m_tgr[i] > prev && tt >= m_tgr[i]) || (m_tgr[i] <= m_counter_cycle && m_tcnt < m_counter_cycle && (delta - (0x10000 - prev)) >= m_tgr[i]); else if(m_tgr[i] <= m_counter_cycle) diff --git a/src/devices/cpu/h8/h8_timer8.cpp b/src/devices/cpu/h8/h8_timer8.cpp index c35310df255..f96a7c8b938 100644 --- a/src/devices/cpu/h8/h8_timer8.cpp +++ b/src/devices/cpu/h8/h8_timer8.cpp @@ -131,12 +131,14 @@ void h8_timer8_channel_device::update_tcr() break; } - if(V>=1) util::stream_format(message, ", irq=%c%c%c\n", - m_tcr & TCR_CMIEB ? 'b' : '-', - m_tcr & TCR_CMIEA ? 'a' : '-', - m_tcr & TCR_OVIE ? 'o' : '-'); + if(V>=1) { + util::stream_format(message, ", irq=%c%c%c\n", + m_tcr & TCR_CMIEB ? 'b' : '-', + m_tcr & TCR_CMIEA ? 'a' : '-', + m_tcr & TCR_OVIE ? 'o' : '-'); - logerror(std::move(message).str()); + logerror(std::move(message).str()); + } } u8 h8_timer8_channel_device::tcsr_r() @@ -189,6 +191,17 @@ void h8_timer8_channel_device::tcnt_w(u8 data) void h8_timer8_channel_device::device_start() { + save_item(NAME(m_tcor)); + save_item(NAME(m_tcr)); + save_item(NAME(m_tcsr)); + save_item(NAME(m_tcnt)); + save_item(NAME(m_extra_clock_bit)); + save_item(NAME(m_clock_type)); + save_item(NAME(m_clock_divider)); + save_item(NAME(m_clear_type)); + save_item(NAME(m_counter_cycle)); + save_item(NAME(m_last_clock_update)); + save_item(NAME(m_event_time)); } void h8_timer8_channel_device::device_reset() @@ -249,8 +262,7 @@ void h8_timer8_channel_device::update_counter(u64 cur_time, u64 delta) m_tcnt = (tt - 0x100) % m_counter_cycle; else m_tcnt = tt; - } - else + } else m_tcnt = tt % m_counter_cycle; if(m_tcnt == m_tcor[0] || (tt == m_tcor[0] && tt == m_counter_cycle)) { diff --git a/src/devices/cpu/h8/h8_watchdog.cpp b/src/devices/cpu/h8/h8_watchdog.cpp index a998c954377..a8af865f2ab 100644 --- a/src/devices/cpu/h8/h8_watchdog.cpp +++ b/src/devices/cpu/h8/h8_watchdog.cpp @@ -135,9 +135,9 @@ void h8_watchdog_device::rst_w(offs_t offset, u16 data, u16 mem_mask) void h8_watchdog_device::device_start() { save_item(NAME(m_tcnt)); - save_item(NAME(m_tcnt_cycle_base)); save_item(NAME(m_tcsr)); save_item(NAME(m_rst)); + save_item(NAME(m_tcnt_cycle_base)); } void h8_watchdog_device::device_reset() -- cgit v1.2.3