diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 12258806460..cd45ab81ee5 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -111,6 +111,7 @@ WRITE_LINE_MEMBER(hp_hybrid_cpu_device::flag_w) hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname , UINT8 addrwidth) : cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__), + m_pa_changed_func(*this), m_program_config("program", ENDIANNESS_BIG, 16, addrwidth, -1), m_io_config("io", ENDIANNESS_BIG, 16, 6, -1) { @@ -178,6 +179,8 @@ void hp_hybrid_cpu_device::device_start() save_item(NAME(m_forced_bsc_25)); m_icountptr = &m_icount; + + m_pa_changed_func.resolve_safe(); } void hp_hybrid_cpu_device::device_reset() @@ -503,9 +506,11 @@ UINT16 hp_hybrid_cpu_device::execute_one_sub(UINT16 opcode) if (BIT(m_flags , HPHYBRID_IRH_SVC_BIT)) { BIT_CLR(m_flags , HPHYBRID_IRH_SVC_BIT); memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((UINT8)CURRENT_PA); } else if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { BIT_CLR(m_flags , HPHYBRID_IRL_SVC_BIT); memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((UINT8)CURRENT_PA); } } tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); @@ -755,6 +760,7 @@ void hp_hybrid_cpu_device::WM(UINT32 addr , UINT16 v) case HP_REG_PA_ADDR: CURRENT_PA = v & HP_REG_PA_MASK; + m_pa_changed_func((UINT8)CURRENT_PA); break; case HP_REG_W_ADDR: @@ -1007,6 +1013,8 @@ void hp_hybrid_cpu_device::check_for_interrupts(void) CURRENT_PA = new_PA; + m_pa_changed_func((UINT8)CURRENT_PA); + // Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence // lasts for 32 cycles (6 are already accounted for in get_ea for one indirection) m_icount -= 26; @@ -1456,7 +1464,7 @@ UINT32 hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , UINT16 addr) bool top_half = BIT(addr , 15) != 0; // Detect accesses to top half of base page - if ((addr & 0xfe00) == 0xfe00) { + if (aec_case == AEC_CASE_C && (addr & 0xfe00) == 0xfe00) { aec_case = AEC_CASE_B; } diff --git a/src/devices/cpu/hphybrid/hphybrid.h b/src/devices/cpu/hphybrid/hphybrid.h index 33124ab19ee..2b59a44120b 100644 --- a/src/devices/cpu/hphybrid/hphybrid.h +++ b/src/devices/cpu/hphybrid/hphybrid.h @@ -16,6 +16,7 @@ // and "enabling" resource of all // - US Patent 4,180,854 describing the HP9845 system // - Study of disassembly of firmware of HP64000 & HP9845 systems +// - hp9800e emulator for inspiration on implementing EMC instructions // - A lot of "educated" guessing #ifndef _HPHYBRID_H_ @@ -74,6 +75,10 @@ #define MCFG_HPHYBRID_SET_9845_BOOT(_mode) \ hp_5061_3001_cpu_device::set_boot_mode_static(*device, _mode); +// PA changed callback +#define MCFG_HPHYBRID_PA_CHANGED(_devcb) \ + hp_hybrid_cpu_device::set_pa_changed_func(*device , DEVCB_##_devcb); + class hp_hybrid_cpu_device : public cpu_device { public: @@ -82,6 +87,8 @@ public: DECLARE_WRITE_LINE_MEMBER(status_w); DECLARE_WRITE_LINE_MEMBER(flag_w); + template static devcb_base &set_pa_changed_func(device_t &device, _Object object) { return downcast(device).m_pa_changed_func.set_callback(object); } + protected: hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname , UINT8 addrwidth); @@ -138,6 +145,8 @@ protected: UINT16 get_skip_addr(UINT16 opcode , bool condition) const; + devcb_write8 m_pa_changed_func; + int m_icount; bool m_forced_bsc_25;