diff options
Diffstat (limited to 'src/devices/cpu/hphybrid/hphybrid.cpp')
-rw-r--r-- | src/devices/cpu/hphybrid/hphybrid.cpp | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 246804ec468..cad5e86d801 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -175,6 +175,8 @@ uint8_t hp_hybrid_cpu_device::pa_r() const hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t addrwidth) : cpu_device(mconfig, type, tag, owner, clock) , m_pa_changed_func(*this) + , m_opcode_func(*this) + , m_stm_func(*this) , m_addr_mask((1U << addrwidth) - 1) , m_relative_mode(true) , m_r_cycles(DEF_MEM_R_CYCLES) @@ -241,6 +243,11 @@ void hp_hybrid_cpu_device::device_start() set_icountptr(m_icount); m_pa_changed_func.resolve_safe(); + m_opcode_func.resolve(); + m_stm_func.resolve(); + // Cache active state of m_stm_func & m_opcode_func + m_opcode_func_defd = bool(m_opcode_func); + m_stm_func_defd = bool(m_stm_func); } void hp_hybrid_cpu_device::device_reset() @@ -260,6 +267,7 @@ void hp_hybrid_cpu_device::device_reset() m_dmapa = 0; m_dmama = 0; m_dmac = 0; + m_curr_cycle = 0; m_forced_bsc_25 = m_boot_mode; m_last_pa = ~0; @@ -312,7 +320,7 @@ uint16_t hp_hybrid_cpu_device::execute_one(uint16_t opcode) } // Indirect addressing in EXE instruction seems to use AEC case A instead of case C // (because it's an opcode fetch) - return RM(add_mae(AEC_CASE_A , fetch_addr)); + return fetch_at(add_mae(AEC_CASE_A , fetch_addr)); } else { uint16_t next_P; if (!execute_one_bpc(opcode , next_P) && @@ -952,6 +960,11 @@ uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) // Any access to internal registers removes forcing of BSC 2x m_forced_bsc_25 = false; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RAL_MASK | CYCLE_RD_MASK); + m_curr_cycle = 0; + } + // Memory mapped BPC registers uint16_t tmp; switch (addr_wo_bsc) { @@ -1016,6 +1029,10 @@ uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) return tmp; } else { m_icount -= m_r_cycles; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RD_MASK); + m_curr_cycle = 0; + } return m_cache->read_word(addr); } } @@ -1065,6 +1082,11 @@ void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) // Any access to internal registers removes forcing of BSC 2x m_forced_bsc_25 = false; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RAL_MASK | CYCLE_WR_MASK); + m_curr_cycle = 0; + } + // Memory mapped BPC registers switch (addr_wo_bsc) { case HP_REG_A_ADDR: @@ -1130,6 +1152,10 @@ void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) m_icount -= REGISTER_RW_CYCLES; } else { m_icount -= m_w_cycles; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } m_program->write_word(addr , v); } } @@ -1168,7 +1194,17 @@ bool hp_hybrid_cpu_device::write_emc_reg(uint16_t addr , uint16_t v) uint16_t hp_hybrid_cpu_device::fetch() { m_genpc = add_mae(AEC_CASE_A , m_reg_P); - return RM(m_genpc); + return fetch_at(m_genpc); +} + +uint16_t hp_hybrid_cpu_device::fetch_at(uint32_t addr) +{ + m_curr_cycle |= CYCLE_IFETCH_MASK; + uint16_t opcode = RM(addr); + if (m_opcode_func_defd) { + m_opcode_func(opcode); + } + return opcode; } uint16_t hp_hybrid_cpu_device::get_indirect_target(uint32_t addr) @@ -1586,6 +1622,10 @@ bool hp_5061_3011_cpu_device::execute_no_bpc(uint16_t opcode , uint16_t& next_pc // 16 bits units. WM(tmp_addr >> 1 , tmp); } else { + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } // Extend address, form byte address uint16_t mask = BIT(tmp_addr , 0) ? 0x00ff : 0xff00; tmp_addr = add_mae(AEC_CASE_C , tmp_addr >> 1); @@ -1674,6 +1714,7 @@ void hp_5061_3011_cpu_device::handle_dma() bool tc = BIT(--m_dmac , 15) != 0; uint16_t tmp; + m_curr_cycle |= CYCLE_DMA_MASK; // Timing here assumes that DMA transfers are isolated and not done in bursts if (BIT(m_flags , HPHYBRID_DMADIR_BIT)) { // "Outward" DMA: memory -> peripheral @@ -1955,6 +1996,10 @@ bool hp_09825_67907_cpu_device::execute_no_bpc(uint16_t opcode , uint16_t& next_ // 16 bits units. WM(tmp_addr , tmp); } else { + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } uint16_t mask = BIT(*ptr_reg , 15) ? 0xff00 : 0x00ff; m_program->write_word(tmp_addr , tmp , mask); m_icount -= m_w_cycles; @@ -2037,6 +2082,7 @@ void hp_09825_67907_cpu_device::handle_dma() uint16_t tmp; // Timing here assumes that DMA transfers are isolated and not done in bursts + m_curr_cycle |= CYCLE_DMA_MASK; if (BIT(m_dmama , 15)) { // "Outward" DMA: memory -> peripheral tmp = RM(AEC_CASE_D , m_dmama); |