From 4518f0eadeb4482ba01ab5add75d6eae921ce571 Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 23 Nov 2021 23:46:12 +0100 Subject: sparc: added initial support for SPARClite [Ryan Holtz] --- src/devices/cpu/sparc/sparc.cpp | 687 ++++++++++++++++++++++++++++++++++-- src/devices/cpu/sparc/sparc.h | 119 ++++++- src/devices/cpu/sparc/sparcdasm.cpp | 28 +- src/devices/cpu/sparc/sparcdasm.h | 8 +- src/devices/cpu/sparc/sparcdefs.h | 2 + 5 files changed, 792 insertions(+), 52 deletions(-) diff --git a/src/devices/cpu/sparc/sparc.cpp b/src/devices/cpu/sparc/sparc.cpp index de53e0aa1ea..3312bd236b3 100644 --- a/src/devices/cpu/sparc/sparc.cpp +++ b/src/devices/cpu/sparc/sparc.cpp @@ -27,8 +27,32 @@ #include "softfloat3/source/include/softfloat.h" +#define LOG_BIU_CTRL (1U << 1) +#define LOG_LOCK_CTRL (1U << 2) +#define LOG_LOCK_CTRL_SAVE (1U << 3) +#define LOG_CACHE_STATUS (1U << 4) +#define LOG_RESTORE_LOCK_CTRL (1U << 5) +#define LOG_SYSTEM_CTRL (1U << 6) +#define LOG_SAME_PAGE_MASK (1U << 7) +#define LOG_ADDR_RANGE (1U << 8) +#define LOG_ADDR_MASK (1U << 9) +#define LOG_WAIT_STATE (1U << 10) +#define LOG_TIMER (1U << 11) +#define LOG_TIMER_PRELOAD (1U << 12) +#define LOG_UNMAPPED (1U << 13) +#define LOG_ICACHE_LOCK (1U << 14) +#define LOG_ICACHE_TAG (1U << 15) +#define LOG_ICACHE_DATA (1U << 16) +#define LOG_DCACHE_LOCK (1U << 17) +#define LOG_DCACHE_TAG (1U << 18) +#define LOG_DCACHE_DATA (1U << 19) + +#define VERBOSE (0) +#include "logmacro.h" + DEFINE_DEVICE_TYPE(SPARCV7, sparcv7_device, "sparcv7", "Sun SPARC v7") DEFINE_DEVICE_TYPE(SPARCV8, sparcv8_device, "sparcv8", "Sun SPARC v8") +DEFINE_DEVICE_TYPE(MB86930, mb86930_device, "mb86930", "Fujitsu MB86930 'SPARClite'") const int sparc_base_device::NWINDOWS = 7; @@ -36,6 +60,23 @@ const int sparc_base_device::NWINDOWS = 7; #include "ss1fcode.ipp" #endif +namespace +{ +const sparc_disassembler::asi_desc_map::value_type mb86930_asi_desc[] = { + + { 0x01, { nullptr, "Control Registers" } }, + { 0x02, { nullptr, "Instruction Cache Lock" } }, + { 0x03, { nullptr, "Data Cache Lock" } }, + { 0x08, { nullptr, "User Instruction" } }, + { 0x09, { nullptr, "Supervisor Instruction" } }, + { 0x0a, { nullptr, "User Data" } }, + { 0x0b, { nullptr, "Supervisor Data" } }, + { 0x0c, { nullptr, "Instruction Cache Tag RAM" } }, + { 0x0d, { nullptr, "Instruction Cache Data RAM" } }, + { 0x0e, { nullptr, "Data Cache Tag RAM" } }, + { 0x0f, { nullptr, "Data Cache Data RAM" } } +}; +} //------------------------------------------------- // sparc_base_device - constructor @@ -46,20 +87,29 @@ sparc_base_device::sparc_base_device(const machine_config &mconfig, device_type , m_mmu(*this, finder_base::DUMMY_TAG) { m_debugger_config = address_space_config("debug", ENDIANNESS_BIG, 32, 32); - for (int i = 0; i < 0x10; i++) + + if (type != MB86930) { - m_asi_names[i] = util::string_format("asi%x", i); - m_asi_config[i] = address_space_config(m_asi_names[i].c_str(), ENDIANNESS_BIG, 32, 32); + for (int i = 0; i < 0x10; i++) + { + m_asi_names[i] = util::string_format("asi%x", i); + m_asi_config[i] = address_space_config(m_asi_names[i].c_str(), ENDIANNESS_BIG, 32, 32); + } } } //------------------------------------------------- -// sparcv7_device - constructor +// sparcv7_device - constructors //------------------------------------------------- sparcv7_device::sparcv7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sparc_base_device(mconfig, SPARCV7, tag, owner, clock) + : sparcv7_device(mconfig, SPARCV7, tag, owner, clock) +{ +} + +sparcv7_device::sparcv7_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : sparc_base_device(mconfig, type, tag, owner, clock) { } @@ -69,8 +119,61 @@ sparcv7_device::sparcv7_device(const machine_config &mconfig, const char *tag, d //------------------------------------------------- sparcv8_device::sparcv8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sparc_base_device(mconfig, SPARCV8, tag, owner, clock) + : sparcv8_device(mconfig, SPARCV8, tag, owner, clock) +{ +} + + +sparcv8_device::sparcv8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : sparc_base_device(mconfig, type, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// mb86930_device - constructor +//------------------------------------------------- + +mb86930_device::mb86930_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sparcv8_device(mconfig, MB86930, tag, owner, clock) + , m_cs_r(*this) + , m_cs_w(*this) { + m_asi_names[0x00] = "debugger"; + m_asi_names[0x01] = "system_control"; + m_asi_names[0x02] = "icache_lock"; + m_asi_names[0x03] = "dcache_lock"; + m_asi_names[0x04] = "asi4"; + m_asi_names[0x05] = "asi5"; + m_asi_names[0x06] = "asi6"; + m_asi_names[0x07] = "asi7"; + m_asi_names[0x08] = "user_insn"; + m_asi_names[0x09] = "super_insn"; + m_asi_names[0x0a] = "user_data"; + m_asi_names[0x0b] = "super_data"; + m_asi_names[0x0c] = "icache_tag"; + m_asi_names[0x0d] = "icache_data"; + m_asi_names[0x0e] = "dcache_tag"; + m_asi_names[0x0f] = "dcache_data"; + + m_asi_config[0x00] = address_space_config(m_asi_names[0x00].c_str(), ENDIANNESS_BIG, 32, 32); + m_asi_config[0x01] = address_space_config(m_asi_names[0x01].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::control_map), this)); + m_asi_config[0x02] = address_space_config(m_asi_names[0x02].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::icache_lock_map), this)); + m_asi_config[0x03] = address_space_config(m_asi_names[0x03].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::dcache_lock_map), this)); + m_asi_config[0x04] = address_space_config(m_asi_names[0x04].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<4>), this)); + m_asi_config[0x05] = address_space_config(m_asi_names[0x05].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<5>), this)); + m_asi_config[0x06] = address_space_config(m_asi_names[0x06].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<6>), this)); + m_asi_config[0x07] = address_space_config(m_asi_names[0x07].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<7>), this)); + m_asi_config[0x08] = address_space_config(m_asi_names[0x08].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<8>), this)); + m_asi_config[0x09] = address_space_config(m_asi_names[0x09].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<9>), this)); + m_asi_config[0x0a] = address_space_config(m_asi_names[0x0a].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<10>), this)); + m_asi_config[0x0b] = address_space_config(m_asi_names[0x0b].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::mmu_map<11>), this)); + m_asi_config[0x0c] = address_space_config(m_asi_names[0x0c].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::icache_tag_map), this)); + m_asi_config[0x0d] = address_space_config(m_asi_names[0x0d].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::icache_data_map), this)); + m_asi_config[0x0e] = address_space_config(m_asi_names[0x0e].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::dcache_tag_map), this)); + m_asi_config[0x0f] = address_space_config(m_asi_names[0x0f].c_str(), ENDIANNESS_BIG, 32, 32, 0, address_map_constructor(FUNC(mb86930_device::dcache_data_map), this)); + + add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(mb86930_asi_desc); }); } @@ -176,13 +279,13 @@ void sparc_base_device::device_start() space(i).specific(m_asi[i]); } - memset(m_dbgregs, 0, 24 * sizeof(uint32_t)); + std::fill_n(m_dbgregs, std::size(m_dbgregs), 0); - memset(m_illegal_instruction_asr, 0, 32 * sizeof(bool)); - memset(m_privileged_asr, 1, 32 * sizeof(bool)); + std::fill_n(m_illegal_instruction_asr, std::size(m_illegal_instruction_asr), false); + std::fill_n(m_privileged_asr, std::size(m_privileged_asr), true); m_privileged_asr[0] = false; - memset(m_alu_setcc, 0, 64 * sizeof(bool)); + std::fill_n(m_alu_setcc, std::size(m_alu_setcc), false); m_alu_setcc[OP3_ADDCC] = true; m_alu_setcc[OP3_ANDCC] = true; m_alu_setcc[OP3_ORCC] = true; @@ -199,7 +302,7 @@ void sparc_base_device::device_start() m_alu_setcc[OP3_TSUBCCTV] = true; m_alu_setcc[OP3_MULSCC] = true; - memset(m_alu_op3_assigned, 0, 64 * sizeof(bool)); + std::fill_n(m_alu_op3_assigned, std::size(m_alu_op3_assigned), false); m_alu_op3_assigned[OP3_ADD] = true; m_alu_op3_assigned[OP3_AND] = true; m_alu_op3_assigned[OP3_OR] = true; @@ -247,7 +350,7 @@ void sparc_base_device::device_start() m_alu_op3_assigned[OP3_SAVE] = true; m_alu_op3_assigned[OP3_RESTORE] = true; - memset(m_ldst_op3_assigned, 0, 64 * sizeof(bool)); + std::fill_n(m_ldst_op3_assigned, std::size(m_ldst_op3_assigned), false); m_ldst_op3_assigned[OP3_LD] = true; m_ldst_op3_assigned[OP3_LDUB] = true; m_ldst_op3_assigned[OP3_LDUH] = true; @@ -315,7 +418,7 @@ void sparc_base_device::device_start() for (int i = 0; i < 32; i++) state_add(SPARC_F0 + i, util::string_format("f%d", i).c_str(), m_fpr[i]); - for (int i = 0; i < 120; i++) + for (int i = 0; i < 136; i++) state_add(SPARC_R0 + i, util::string_format("r%d", i).c_str(), m_r[i]).formatstr("%08X"); save_item(NAME(m_r)); @@ -401,35 +504,38 @@ void sparc_base_device::device_start() void sparc_base_device::device_resolve_objects() { - m_mmu->set_host(this); + if (m_mmu.found()) + m_mmu->set_host(this); } void sparc_base_device::device_reset() { - m_trap = 0; + m_trap = false; m_tt = 0; m_ticc_trap_type = 0; - m_privileged_instruction = 0; - m_illegal_instruction = 0; - m_mem_address_not_aligned = 0; - m_fp_disabled = 0; - m_fp_exception = 0; - m_fp_exception_pending = 0; + m_interrupt_level = 0; + m_privileged_instruction = false; + m_illegal_instruction = false; + m_mem_address_not_aligned = false; + m_fp_disabled = false; + m_cp_disabled = false; + m_fp_exception = false; + m_fp_exception_pending = false; m_fpr_pending = 0; m_pending_fpr = std::size(m_fpr); + m_cp_exception = false; + m_instruction_access_exception = false; + m_data_access_exception = false; + m_trap_instruction = false; + m_window_underflow = false; + m_window_overflow = false; + m_tag_overflow = false; + m_reset_mode = true; + m_reset_trap = false; + m_execute_mode = false; + m_error_mode = false; m_fpu_sequence_err = 0; - m_cp_disabled = 0; - m_cp_exception = 0; m_cp_sequence_err = 0; - m_instruction_access_exception = 0; - m_trap_instruction = 0; - m_window_underflow = 0; - m_window_overflow = 0; - m_tag_overflow = 0; - m_reset_mode = 1; - m_reset_trap = 0; - m_execute_mode = 0; - m_error_mode = 0; m_bp_irl = 0; m_irq_state = 0; @@ -442,8 +548,8 @@ void sparc_base_device::device_reset() PC = 0; nPC = 4; - memset(m_r, 0, sizeof(uint32_t) * 120); - memset(m_fpr, 0, sizeof(uint32_t) * 32); + std::fill_n(m_r, std::size(m_r), 0); + std::fill_n(m_fpr, std::size(m_fpr), 0); WIM = 0; TBR = 0; @@ -516,6 +622,424 @@ void sparcv8_device::device_reset() m_division_by_zero = 0; } + +//------------------------------------------------- +// mb86930_device - initializers +//------------------------------------------------- + +void mb86930_device::device_start() +{ + sparcv8_device::device_start(); + + m_alu_setcc[OP3_DIVSCC] = true; + + m_alu_op3_assigned[OP3_DIVSCC] = true; + m_alu_op3_assigned[OP3_SCAN] = true; + + save_item(NAME(m_spmr)); + save_item(NAME(m_spmr_mask)); + save_item(NAME(m_arsr)); + save_item(NAME(m_amr)); + save_item(NAME(m_wssr)); + save_item(NAME(m_last_masked_addr)); + save_item(NAME(m_same_page_waits[6])); + save_item(NAME(m_other_page_waits[6])); + + std::fill_n(&m_arsr[0], 6, 0); + std::fill_n(&m_amr[0], 6, 0); + + m_cs_r.resolve_all_safe(0); + m_cs_w.resolve_all_safe(); +} + +void mb86930_device::device_reset() +{ + sparcv8_device::device_reset(); + + m_spmr = 0; + m_spmr_mask = ~0ULL; + std::fill_n(&m_wssr[0], 3, 0); + m_last_masked_addr = 0ULL; + + std::fill_n(&m_same_page_waits[0], 6, 0); + std::fill_n(&m_other_page_waits[0], 6, 0); + + m_arsr[0] = (9 << 23); + m_amr[0] = (0x1f << 1); + + update_addr_masks(); +} + + +//------------------------------------------------- +// mb86930_device - internal maps +//------------------------------------------------- + +void mb86930_device::control_map(address_map &map) +{ + map(0x00000000, 0x00000003).rw(FUNC(mb86930_device::biu_ctrl_r), FUNC(mb86930_device::biu_ctrl_w)); + map(0x00000004, 0x00000007).rw(FUNC(mb86930_device::lock_ctrl_r), FUNC(mb86930_device::lock_ctrl_w)); + map(0x00000008, 0x0000000b).rw(FUNC(mb86930_device::lock_ctrl_save_r), FUNC(mb86930_device::lock_ctrl_save_w)); + map(0x0000000c, 0x0000000f).rw(FUNC(mb86930_device::cache_status_r), FUNC(mb86930_device::cache_status_w)); + map(0x00000010, 0x00000013).rw(FUNC(mb86930_device::restore_lock_ctrl_r), FUNC(mb86930_device::restore_lock_ctrl_w)); + map(0x00000080, 0x00000083).rw(FUNC(mb86930_device::system_support_ctrl_r), FUNC(mb86930_device::system_support_ctrl_w)); + map(0x00000120, 0x00000123).rw(FUNC(mb86930_device::same_page_mask_r), FUNC(mb86930_device::same_page_mask_w)); + map(0x00000124, 0x00000137).rw(FUNC(mb86930_device::addr_range_spec_r), FUNC(mb86930_device::addr_range_spec_w)); + map(0x00000140, 0x00000157).rw(FUNC(mb86930_device::addr_mask_r), FUNC(mb86930_device::addr_mask_w)); + map(0x00000160, 0x0000016b).rw(FUNC(mb86930_device::wait_specifier_r), FUNC(mb86930_device::wait_specifier_w)); + map(0x00000174, 0x00000177).rw(FUNC(mb86930_device::timer_r), FUNC(mb86930_device::timer_w)); + map(0x00000178, 0x0000017b).rw(FUNC(mb86930_device::timer_preload_r), FUNC(mb86930_device::timer_preload_w)); +} + +void mb86930_device::icache_lock_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::icache_lock_r), FUNC(mb86930_device::icache_lock_w)); +} + +void mb86930_device::dcache_lock_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::dcache_lock_r), FUNC(mb86930_device::dcache_lock_w)); +} + +void mb86930_device::icache_tag_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::icache_tag_r), FUNC(mb86930_device::icache_tag_w)); +} + +void mb86930_device::icache_data_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::icache_data_r), FUNC(mb86930_device::icache_data_w)); +} + +void mb86930_device::dcache_tag_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::dcache_tag_r), FUNC(mb86930_device::dcache_tag_w)); +} + +void mb86930_device::dcache_data_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::dcache_data_r), FUNC(mb86930_device::dcache_data_w)); +} + + +//------------------------------------------------- +// mb86930_device - cache control (TODO) +//------------------------------------------------- + +uint32_t mb86930_device::icache_lock_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_ICACHE_LOCK, "%s: icache_lock_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::icache_lock_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_ICACHE_LOCK, "%s: icache_lock_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::dcache_lock_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_DCACHE_LOCK, "%s: dcache_lock_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::dcache_lock_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_DCACHE_LOCK, "%s: dcache_lock_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::icache_tag_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_ICACHE_TAG, "%s: icache_tag_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::icache_tag_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_ICACHE_TAG, "%s: icache_tag_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::icache_data_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_ICACHE_DATA, "%s: icache_data_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::icache_data_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_ICACHE_DATA, "%s: icache_data_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::dcache_tag_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_DCACHE_TAG, "%s: dcache_tag_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::dcache_tag_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_DCACHE_TAG, "%s: dcache_tag_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::dcache_data_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_DCACHE_DATA, "%s: dcache_data_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::dcache_data_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_DCACHE_DATA, "%s: dcache_data_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +//------------------------------------------------- +// mb86930_device - MMU map and handlers +//------------------------------------------------- + +template +void mb86930_device::mmu_map(address_map &map) +{ + map(0x00000000, 0xffffffff).rw(FUNC(mb86930_device::mmu_r), FUNC(mb86930_device::mmu_w)); +} + +template +uint32_t mb86930_device::mmu_r(offs_t offset, uint32_t mem_mask) +{ + const uint64_t full_addr = ((uint64_t)Asi << 30) | offset; + + const uint64_t masked_addr = full_addr & m_spmr_mask; + const bool is_same_page = (masked_addr == m_last_masked_addr); + m_last_masked_addr = masked_addr; + + for (int cs = 0; cs < 6; cs++) + { + if ((full_addr & m_full_masks[cs]) == m_full_ranges[cs]) + { + eat_cycles(is_same_page ? m_same_page_waits[cs] : m_other_page_waits[cs]); + return m_cs_r[cs](offset, mem_mask); + } + } + LOGMASKED(LOG_UNMAPPED, "%s: mmu_r, unmapped access: ASI %d, address %08x & %08x\n", machine().describe_context(), Asi, offset << 2, mem_mask); + return 0; +} + +template void mb86930_device::mmu_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + const uint64_t full_addr = ((uint64_t)Asi << 30) | offset; + + const uint64_t masked_addr = full_addr & m_spmr_mask; + const bool is_same_page = (masked_addr == m_last_masked_addr); + m_last_masked_addr = masked_addr; + + for (int cs = 0; cs < 6; cs++) + { + if ((full_addr & m_full_masks[cs]) == m_full_ranges[cs]) + { + eat_cycles(is_same_page ? m_same_page_waits[cs] : m_other_page_waits[cs]); + m_cs_w[cs](offset, data, mem_mask); + return; + } + } + LOGMASKED(LOG_UNMAPPED, "%s: mmu_w, unmapped access: ASI %d, address %08x = %08x & %08x\n", machine().describe_context(), Asi, offset << 2, data, mem_mask); +} + + +//------------------------------------------------- +// mb86930_device - system control handlers +//------------------------------------------------- + +void mb86930_device::update_addr_masks() +{ + for (int i = 0; i < 6; i++) + { + m_full_masks[i] = ~(((uint64_t)m_amr[i] << 7) | 0xff); + m_full_ranges[i] = ((uint64_t)m_arsr[i] << 7) & m_full_masks[i]; + } +} + +uint32_t mb86930_device::biu_ctrl_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_BIU_CTRL, "%s: biu_ctrl_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::biu_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_BIU_CTRL, "%s: biu_ctrl_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::lock_ctrl_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_LOCK_CTRL, "%s: lock_ctrl_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::lock_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_LOCK_CTRL, "%s: lock_ctrl_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::lock_ctrl_save_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_LOCK_CTRL_SAVE, "%s: lock_ctrl_save_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::lock_ctrl_save_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_LOCK_CTRL_SAVE, "%s: lock_ctrl_save_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::cache_status_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_CACHE_STATUS, "%s: cache_status_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::cache_status_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_CACHE_STATUS, "%s: cache_status_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::restore_lock_ctrl_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_RESTORE_LOCK_CTRL, "%s: restore_lock_ctrl_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::restore_lock_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_RESTORE_LOCK_CTRL, "%s: restore_lock_ctrl_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::system_support_ctrl_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_SYSTEM_CTRL, "%s: system_ctrl_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::system_support_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_SYSTEM_CTRL, "%s: system_ctrl_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::same_page_mask_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = m_spmr; + LOGMASKED(LOG_SAME_PAGE_MASK, "%s: same_page_mask_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::same_page_mask_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_SAME_PAGE_MASK, "%s: same_page_mask_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_spmr); + m_spmr_mask = ~(((uint64_t)m_spmr << 7) | 0xff); +} + + +uint32_t mb86930_device::addr_range_spec_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = m_arsr[offset + 1]; + LOGMASKED(LOG_ADDR_RANGE, "%s: addr_range_spec_r[%d]: %08x & %08x\n", machine().describe_context(), offset + 1, data, mem_mask); + return data; +} + +void mb86930_device::addr_range_spec_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_ADDR_RANGE, "%s: addr_range_spec_w[%d]: %08x & %08x\n", machine().describe_context(), offset + 1, data, mem_mask); + COMBINE_DATA(&m_arsr[offset + 1]); + update_addr_masks(); +} + + +uint32_t mb86930_device::addr_mask_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = m_amr[offset]; + LOGMASKED(LOG_ADDR_MASK, "%s: addr_mask_r[%d]: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + return data; +} + +void mb86930_device::addr_mask_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_ADDR_MASK, "%s: addr_mask_w[%d]: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + COMBINE_DATA(&m_amr[offset]); + update_addr_masks(); +} + + +uint32_t mb86930_device::wait_specifier_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = m_wssr[offset]; + LOGMASKED(LOG_WAIT_STATE, "%s: wait_state_r[%d]: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::wait_specifier_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_WAIT_STATE, "%s: wait_state_w[%d]: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + COMBINE_DATA(&m_wssr[offset]); + + const uint32_t wait_idx = (offset << 1); + const bool wait_en0 = BIT(m_wssr[offset], 21) && !BIT(m_wssr[offset], 20); + const bool wait_en1 = BIT(m_wssr[offset], 8) && !BIT(m_wssr[offset], 7); + m_other_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 27) & 0x1f) + 1) : 0; + m_same_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 22) & 0x1f) + 1) : 0; + m_other_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 14) & 0x1f) + 1) : 0; + m_same_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 9) & 0x1f) + 1) : 0; +} + + +uint32_t mb86930_device::timer_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_TIMER, "%s: timer_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::timer_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_TIMER, "%s: timer_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + +uint32_t mb86930_device::timer_preload_r(offs_t offset, uint32_t mem_mask) +{ + uint32_t data = 0; + LOGMASKED(LOG_TIMER_PRELOAD, "%s: timer_preload_r: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void mb86930_device::timer_preload_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + LOGMASKED(LOG_TIMER_PRELOAD, "%s: timer_preload_w: %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + + //------------------------------------------------- // device_post_load - update register pointers // after loading a savestate @@ -614,11 +1138,24 @@ void sparc_base_device::state_string_export(const device_state_entry &entry, std std::unique_ptr sparc_base_device::create_disassembler() { - auto dasm = std::make_unique(static_cast(this), 7); + auto dasm = std::make_unique(static_cast(this), sparc_disassembler::v7); + m_asi_desc_adder(dasm.get()); + return std::move(dasm); +} + +std::unique_ptr sparcv8_device::create_disassembler() +{ + auto dasm = std::make_unique(static_cast(this), sparc_disassembler::v8); m_asi_desc_adder(dasm.get()); return std::move(dasm); } +std::unique_ptr mb86930_device::create_disassembler() +{ + auto dasm = std::make_unique(static_cast(this), sparc_disassembler::sparclite); + m_asi_desc_adder(dasm.get()); + return std::move(dasm); +} //************************************************************************** // CORE EXECUTION LOOP @@ -1361,6 +1898,12 @@ void sparc_base_device::execute_wrsr(uint32_t op) m_data_space = 10; } + if (m_et && (m_bp_irl == 15 || m_bp_irl > m_pil) && m_interrupt_level == 0) + { + m_trap = 1; + m_interrupt_level = m_bp_irl; + } + PC = nPC; nPC = nPC + 4; } @@ -1786,12 +2329,24 @@ inline void sparc_base_device::execute_group2(uint32_t op) //------------------------------------------------- // update_extra_group2 - execute a group2 // instruction belonging to a newer SPARC version -// than v7 +// than v7, or which can be overridden from v7 //------------------------------------------------- bool sparcv7_device::execute_extra_group2(uint32_t op) { - return false; + switch (OP3) + { + case OP3_TADDCCTV: + execute_taddcc(op); + return true; + + case OP3_TSUBCCTV: + execute_tsubcc(op); + return true; + + default: + return false; + } } bool sparcv8_device::execute_extra_group2(uint32_t op) @@ -1826,6 +2381,40 @@ bool sparcv8_device::execute_extra_group2(uint32_t op) } } +void mb86930_device::execute_divscc(uint32_t op) +{ + fatalerror("Not yet supported: divscc at %08x\n", PC); + /*const bool n_flag = (PSR & PSR_N_MASK); + const bool v_flag = (PSR & PSR_V_MASK); + const bool true_sign = n_flag ^ v_flag; + const uint64_t dividend = ((uint64_t)m_y << 32) | RS1REG; + const uint32_t remainder = m_y << 1; + const uint32_t divisor = (USEIMM ? SIMM13 : RS2REG);*/ + +} + +void mb86930_device::execute_scan(uint32_t op) +{ + fatalerror("Not yet supported: scan at %08x\n", PC); +} + +bool mb86930_device::execute_extra_group2(uint32_t op) +{ + switch (OP3) + { + case OP3_DIVSCC: + execute_divscc(op); + return true; + + case OP3_SCAN: + execute_scan(op); + return true; + + default: + return false; + } +} + //------------------------------------------------- // update_gpr_pointers - cache pointers to // the registers in our current window @@ -4527,11 +5116,17 @@ void sparcv8_device::execute_swap(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + m_stashed_icount = m_icount; + m_icount = 0; + return; } else if (USEIMM) { m_trap = 1; m_illegal_instruction = 1; + m_stashed_icount = m_icount; + m_icount = 0; + return; } else { @@ -4561,6 +5156,9 @@ void sparcv8_device::execute_swap(uint32_t op) { m_trap = 1; m_data_access_exception = 1; + m_stashed_icount = m_icount; + m_icount = 0; + return; } } if (!m_trap) @@ -4572,6 +5170,9 @@ void sparcv8_device::execute_swap(uint32_t op) { m_trap = 1; m_data_access_exception = 1; + m_stashed_icount = m_icount; + m_icount = 0; + return; } else { @@ -4579,6 +5180,9 @@ void sparcv8_device::execute_swap(uint32_t op) RDREG = word; } } + + PC = nPC; + nPC = nPC + 4; } @@ -4632,6 +5236,9 @@ void sparcv8_device::execute_mul(uint32_t op) PSR |= BIT31(result) ? PSR_N_MASK : 0; PSR |= (result == 0) ? PSR_Z_MASK : 0; } + + PC = nPC; + nPC = nPC + 4; } @@ -4692,6 +5299,9 @@ void sparcv8_device::execute_div(uint32_t op) { m_trap = 1; m_division_by_zero = 1; + m_stashed_icount = m_icount; + m_icount = 0; + return; } else { @@ -4742,6 +5352,9 @@ void sparcv8_device::execute_div(uint32_t op) PSR |= temp_v ? PSR_V_MASK : 0; } } + + PC = nPC; + nPC = nPC + 4; } diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index acdc044a62c..8f071a8c72b 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -152,7 +152,7 @@ protected: void log_fcodes(); #endif - required_device m_mmu; + optional_device m_mmu; // address spaces std::string m_asi_names[0x10]; @@ -172,7 +172,7 @@ protected: virtual uint8_t get_fcc(unsigned index) const override; // general-purpose registers - uint32_t m_r[120]; + uint32_t m_r[136]; // FPU registers uint32_t m_fpr[32]; @@ -278,6 +278,9 @@ class sparcv7_device : public sparc_base_device public: sparcv7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +protected: + sparcv7_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + protected: virtual bool execute_extra_group2(uint32_t op) override; virtual bool execute_extra_group3(uint32_t op) override; @@ -290,7 +293,12 @@ class sparcv8_device : public sparc_base_device public: sparcv8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + protected: + sparcv8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_start() override; virtual void device_reset() override; @@ -312,9 +320,116 @@ private: bool m_division_by_zero; }; +class mb86930_device : public sparcv8_device +{ +public: + mb86930_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + + auto cs0_read_cb() { return m_cs_r[0].bind(); } + auto cs0_write_cb() { return m_cs_w[0].bind(); } + auto cs1_read_cb() { return m_cs_r[1].bind(); } + auto cs1_write_cb() { return m_cs_w[1].bind(); } + auto cs2_read_cb() { return m_cs_r[2].bind(); } + auto cs2_write_cb() { return m_cs_w[2].bind(); } + auto cs3_read_cb() { return m_cs_r[3].bind(); } + auto cs3_write_cb() { return m_cs_w[3].bind(); } + auto cs4_read_cb() { return m_cs_r[4].bind(); } + auto cs4_write_cb() { return m_cs_w[4].bind(); } + auto cs5_read_cb() { return m_cs_r[5].bind(); } + auto cs5_write_cb() { return m_cs_w[5].bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual bool execute_extra_group2(uint32_t op) override; + + void execute_divscc(uint32_t op); + void execute_scan(uint32_t op); + + uint32_t biu_ctrl_r(offs_t offset, uint32_t mem_mask); + void biu_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t lock_ctrl_r(offs_t offset, uint32_t mem_mask); + void lock_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t lock_ctrl_save_r(offs_t offset, uint32_t mem_mask); + void lock_ctrl_save_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t cache_status_r(offs_t offset, uint32_t mem_mask); + void cache_status_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t restore_lock_ctrl_r(offs_t offset, uint32_t mem_mask); + void restore_lock_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t system_support_ctrl_r(offs_t offset, uint32_t mem_mask); + void system_support_ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t same_page_mask_r(offs_t offset, uint32_t mem_mask); + void same_page_mask_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t addr_range_spec_r(offs_t offset, uint32_t mem_mask); + void addr_range_spec_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t addr_mask_r(offs_t offset, uint32_t mem_mask); + void addr_mask_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t wait_specifier_r(offs_t offset, uint32_t mem_mask); + void wait_specifier_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t timer_r(offs_t offset, uint32_t mem_mask); + void timer_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t timer_preload_r(offs_t offset, uint32_t mem_mask); + void timer_preload_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + template uint32_t mmu_r(offs_t offset, uint32_t mem_mask); + template void mmu_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t icache_lock_r(offs_t offset, uint32_t mem_mask); + void icache_lock_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t dcache_lock_r(offs_t offset, uint32_t mem_mask); + void dcache_lock_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + uint32_t icache_tag_r(offs_t offset, uint32_t mem_mask); + void icache_tag_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t icache_data_r(offs_t offset, uint32_t mem_mask); + void icache_data_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + u32 dcache_tag_r(offs_t offset, u32 mem_mask); + void dcache_tag_w(offs_t offset, u32 data, u32 mem_mask); + u32 dcache_data_r(offs_t offset, u32 mem_mask); + void dcache_data_w(offs_t offset, u32 data, u32 mem_mask); + + void control_map(address_map &map); + void icache_lock_map(address_map &map); + void dcache_lock_map(address_map &map); + template void mmu_map(address_map &map); + void icache_tag_map(address_map &map); + void icache_data_map(address_map &map); + void dcache_tag_map(address_map &map); + void dcache_data_map(address_map &map); + + void update_addr_masks(); + + devcb_read32::array<6> m_cs_r; + devcb_write32::array<6> m_cs_w; + + u32 m_spmr; + u64 m_spmr_mask; + u32 m_arsr[6]; + u32 m_amr[6]; + u64 m_full_masks[6]; + u64 m_full_ranges[6]; + u64 m_last_masked_addr; + int m_same_page_waits[6]; + int m_other_page_waits[6]; + + u32 m_wssr[3]; +}; + // device type definition DECLARE_DEVICE_TYPE(SPARCV7, sparcv7_device) DECLARE_DEVICE_TYPE(SPARCV8, sparcv8_device) +DECLARE_DEVICE_TYPE(MB86930, mb86930_device) enum { diff --git a/src/devices/cpu/sparc/sparcdasm.cpp b/src/devices/cpu/sparc/sparcdasm.cpp index 1fcbcdfa7a8..b6a5a590b9c 100644 --- a/src/devices/cpu/sparc/sparcdasm.cpp +++ b/src/devices/cpu/sparc/sparcdasm.cpp @@ -176,6 +176,10 @@ const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V7_INT { 0x3d, { false, "restore" } } }; +const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::SPARCLITE_INT_OP_DESC[] = { + { 0x1d, { false, "divscc" } }, { 0x22, { false, "scan" } } +}; + const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V8_INT_OP_DESC[] = { { 0x0a, { false, "umul" } }, { 0x1a, { false, "umulcc" } }, { 0x0b, { false, "smul" } }, { 0x1b, { false, "smulcc" } }, @@ -610,24 +614,24 @@ inline void sparc_disassembler::pad_op_field(std::ostream &stream, std::streampo stream << ' '; } -sparc_disassembler::sparc_disassembler(const config *conf, unsigned version) +sparc_disassembler::sparc_disassembler(const config *conf, sparc_version version) : sparc_disassembler(conf, version, vis_none) { } -sparc_disassembler::sparc_disassembler(const config *conf, unsigned version, vis_level vis) +sparc_disassembler::sparc_disassembler(const config *conf, sparc_version version, vis_level vis) : m_version(version) , m_vis_level(vis) , m_op_field_width(9) , m_branch_desc{ EMPTY_BRANCH_DESC, - (version >= 9) ? BPCC_DESC : EMPTY_BRANCH_DESC, // branch on integer condition codes with prediction, SPARCv9 - BICC_DESC, // branch on integer condition codes - (version >= 9) ? BPR_DESC : EMPTY_BRANCH_DESC, // branch on integer register with prediction, SPARCv9 + (version >= v9) ? BPCC_DESC : EMPTY_BRANCH_DESC, // branch on integer condition codes with prediction, SPARCv9 + BICC_DESC, // branch on integer condition codes + (version >= v9) ? BPR_DESC : EMPTY_BRANCH_DESC, // branch on integer register with prediction, SPARCv9 EMPTY_BRANCH_DESC, - (version >= 9) ? FBPFCC_DESC : EMPTY_BRANCH_DESC, // branch on floating-point condition codes with prediction, SPARCv9 - FBFCC_DESC, // branch on floating-point condition codes - (version == 8) ? CBCCC_DESC : EMPTY_BRANCH_DESC // branch on coprocessor condition codes, SPARCv8 + (version >= v9) ? FBPFCC_DESC : EMPTY_BRANCH_DESC, // branch on floating-point condition codes with prediction, SPARCv9 + FBFCC_DESC, // branch on floating-point condition codes + (version == v8) ? CBCCC_DESC : EMPTY_BRANCH_DESC // branch on coprocessor condition codes, SPARCv8 } , m_int_op_desc(std::begin(V7_INT_OP_DESC), std::end(V7_INT_OP_DESC)) , m_state_reg_desc() @@ -638,12 +642,16 @@ sparc_disassembler::sparc_disassembler(const config *conf, unsigned version, vis , m_prftch_desc() , m_vis_op_desc() { - if (m_version >= 8) + if (m_version == sparclite) + { + add_int_op_desc(SPARCLITE_INT_OP_DESC); + } + else if (m_version >= v8) { add_int_op_desc(V8_INT_OP_DESC); } - if (m_version >= 9) + if (m_version >= v9) { m_op_field_width = 11; diff --git a/src/devices/cpu/sparc/sparcdasm.h b/src/devices/cpu/sparc/sparcdasm.h index f6f0e7bc27d..91a22df173a 100644 --- a/src/devices/cpu/sparc/sparcdasm.h +++ b/src/devices/cpu/sparc/sparcdasm.h @@ -26,6 +26,7 @@ public: virtual uint8_t get_fcc(unsigned index) const = 0; // ?><= }; + enum sparc_version { v7, v8, sparclite, v9 }; enum vis_level { vis_none, vis_1, vis_2, vis_2p, vis_3, vis_3b }; struct asi_desc @@ -55,8 +56,8 @@ public: }; typedef std::map prftch_desc_map; - sparc_disassembler(const config *conf, unsigned version); - sparc_disassembler(const config *conf, unsigned version, vis_level vis); + sparc_disassembler(const config *conf, sparc_version version); + sparc_disassembler(const config *conf, sparc_version version, vis_level vis); template void add_state_reg_desc(const T &desc) { @@ -215,6 +216,7 @@ private: static const branch_desc CBCCC_DESC; static const int_op_desc_map::value_type V7_INT_OP_DESC[]; static const int_op_desc_map::value_type V8_INT_OP_DESC[]; + static const int_op_desc_map::value_type SPARCLITE_INT_OP_DESC[]; static const int_op_desc_map::value_type V9_INT_OP_DESC[]; static const state_reg_desc_map::value_type V9_STATE_REG_DESC[]; static const char * const MOVCC_CC_NAMES[8]; @@ -239,7 +241,7 @@ private: static const vis_op_desc_map::value_type VIS3B_OP_DESC[]; //const config *m_config; - unsigned m_version; + sparc_version m_version; vis_level m_vis_level; int m_op_field_width; branch_desc m_branch_desc[8]; diff --git a/src/devices/cpu/sparc/sparcdefs.h b/src/devices/cpu/sparc/sparcdefs.h index f5eff0f55c9..d7e291cbcdd 100644 --- a/src/devices/cpu/sparc/sparcdefs.h +++ b/src/devices/cpu/sparc/sparcdefs.h @@ -200,10 +200,12 @@ #define OP3_UMULCC 26 #define OP3_SMULCC 27 #define OP3_SUBXCC 28 +#define OP3_DIVSCC 29 #define OP3_UDIVCC 30 #define OP3_SDIVCC 31 #define OP3_TADDCC 32 #define OP3_TSUBCC 33 +#define OP3_SCAN 34 #define OP3_TADDCCTV 34 #define OP3_TSUBCCTV 35 #define OP3_MULSCC 36 -- cgit v1.2.3