diff options
Diffstat (limited to 'src/devices/cpu/sparc/mb86901.cpp')
-rw-r--r-- | src/devices/cpu/sparc/mb86901.cpp | 1564 |
1 files changed, 1091 insertions, 473 deletions
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index fad89cf9610..76ef7ac56e4 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -41,8 +41,16 @@ const int mb86901_device::NWINDOWS = 7; mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, MB86901, tag, owner, clock) - , m_program_config("program", ENDIANNESS_BIG, 32, 32) { + m_default_config = address_space_config("program", ENDIANNESS_BIG, 32, 32); + + char buf[32]; + for (uint32_t i = 0; i < AS_COUNT; i++) + { + snprintf(buf, ARRAY_LENGTH(buf), "asi%d", i); + m_asi_names[i] = buf; + m_asi_config[i] = address_space_config(m_asi_names[i].c_str(), ENDIANNESS_BIG, 32, 32); + } } @@ -202,7 +210,11 @@ void mb86901_device::device_start() m_alu_op3_assigned[OP3_UDIVCC] = true; m_alu_op3_assigned[OP3_SDIVCC] = true; #endif - m_program = &space(AS_PROGRAM); + for (uint32_t i = 0; i < AS_COUNT; i++) + { + m_space[i] = &space(AS_START + i); + m_access_cache[i] = m_space[i]->cache<2, 0, ENDIANNESS_BIG>(); + } memset(m_ldst_op3_assigned, 0, 64 * sizeof(bool)); m_ldst_op3_assigned[OP3_LD] = true; @@ -354,7 +366,6 @@ void mb86901_device::device_start() save_item(NAME(m_ps)); save_item(NAME(m_et)); save_item(NAME(m_cwp)); - save_item(NAME(m_asi)); save_item(NAME(m_mae)); save_item(NAME(m_annul)); save_item(NAME(m_hold_bus)); @@ -394,7 +405,6 @@ void mb86901_device::device_reset() m_bp_irl = 0; m_irq_state = 0; - m_asi = 0; MAE = false; HOLD_BUS = false; m_annul = false; @@ -409,6 +419,8 @@ void mb86901_device::device_reset() Y = 0; PSR = PSR_S_MASK | PSR_PS_MASK; + m_s = true; + m_fetch_space = 9; for (int i = 0; i < 8; i++) { @@ -434,9 +446,13 @@ void mb86901_device::device_reset() device_memory_interface::space_config_vector mb86901_device::memory_space_config() const { - return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config) - }; + space_config_vector config_vector; + config_vector.push_back(std::make_pair(AS_PROGRAM, &m_default_config)); + for (uint32_t i = 0; i < 32; i++) + { + config_vector.push_back(std::make_pair(AS_START + i, &m_asi_config[i])); + } + return config_vector; } @@ -449,18 +465,18 @@ device_memory_interface::space_config_vector mb86901_device::memory_space_config uint32_t mb86901_device::read_sized_word(uint8_t asi, uint32_t address, int size) { - m_asi = asi; + assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines. if (size == 1) { - return m_program->read_byte(address) << ((3 - (address & 3)) * 8); + return m_access_cache[asi]->read_byte(address) << ((3 - (address & 3)) * 8); } else if (size == 2) { - return m_program->read_word(address) << ((2 - (address & 2)) * 8); + return m_access_cache[asi]->read_word(address) << ((2 - (address & 2)) * 8); } else { - return m_program->read_dword(address); + return m_access_cache[asi]->read_dword(address); } } @@ -476,18 +492,18 @@ uint32_t mb86901_device::read_sized_word(uint8_t asi, uint32_t address, int size void mb86901_device::write_sized_word(uint8_t asi, uint32_t address, uint32_t data, int size) { - m_asi = asi; + assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines. if (size == 1) { - m_program->write_byte(address, data >> ((3 - (address & 3)) * 8)); + m_access_cache[asi]->write_byte(address, data >> ((3 - (address & 3)) * 8)); } else if (size == 2) { - m_program->write_word(address, data >> ((2 - (address & 2)) * 8)); + m_access_cache[asi]->write_word(address, data >> ((2 - (address & 2)) * 8)); } else { - m_program->write_dword(address, data); + m_access_cache[asi]->write_dword(address, data); } } @@ -676,6 +692,9 @@ void mb86901_device::execute_add(uint32_t op) PSR |= ((BIT31(rs1) && BIT31(operand2)) || (!BIT31(result) && (BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; } + + PC = nPC; + nPC = nPC + 4; } @@ -724,19 +743,21 @@ void mb86901_device::execute_taddcc(uint32_t op) { m_trap = 1; m_tag_overflow = true; + return; } - else - { - CLEAR_ICC; - PSR |= (BIT31(result)) ? PSR_N_MASK : 0; - PSR |= (result == 0) ? PSR_Z_MASK : 0; - PSR |= temp_v ? PSR_V_MASK : 0; - PSR |= ((BIT31(rs1) && BIT31(operand2)) || - (!BIT31(result) && (BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; - if (RD != 0) - RDREG = result; - } + CLEAR_ICC; + PSR |= (BIT31(result)) ? PSR_N_MASK : 0; + PSR |= (result == 0) ? PSR_Z_MASK : 0; + PSR |= temp_v ? PSR_V_MASK : 0; + PSR |= ((BIT31(rs1) && BIT31(operand2)) || + (!BIT31(result) && (BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; + + if (RD != 0) + RDREG = result; + + PC = nPC; + nPC = nPC + 4; } @@ -791,6 +812,9 @@ void mb86901_device::execute_sub(uint32_t op) PSR |= ((!BIT31(rs1) && BIT31(operand2)) || (BIT31(result) && (!BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; } + + PC = nPC; + nPC = nPC + 4; } @@ -840,19 +864,21 @@ void mb86901_device::execute_tsubcc(uint32_t op) { m_trap = 1; m_tag_overflow = 1; + return; } - else - { - CLEAR_ICC; - PSR |= (BIT31(result)) ? PSR_N_MASK : 0; - PSR |= (result == 0) ? PSR_Z_MASK : 0; - PSR |= temp_v ? PSR_V_MASK : 0; - PSR |= ((!BIT31(rs1) && BIT31(operand2)) || - (BIT31(result) && (!BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; - if (RD != 0) - RDREG = result; - } + CLEAR_ICC; + PSR |= (BIT31(result)) ? PSR_N_MASK : 0; + PSR |= (result == 0) ? PSR_Z_MASK : 0; + PSR |= temp_v ? PSR_V_MASK : 0; + PSR |= ((!BIT31(rs1) && BIT31(operand2)) || + (BIT31(result) && (!BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0; + + if (RD != 0) + RDREG = result; + + PC = nPC; + nPC = nPC + 4; } @@ -925,6 +951,9 @@ void mb86901_device::execute_logical(uint32_t op) PSR |= (BIT31(result)) ? PSR_N_MASK : 0; PSR |= (result == 0) ? PSR_Z_MASK : 0; } + + PC = nPC; + nPC = nPC + 4; } @@ -954,6 +983,9 @@ void mb86901_device::execute_shift(uint32_t op) RDREG = uint32_t(RS1REG) >> shift_count; else if (SRA && RD != 0) RDREG = int32_t(RS1REG) >> shift_count; + + PC = nPC; + nPC = nPC + 4; } @@ -1003,6 +1035,9 @@ void mb86901_device::execute_mulscc(uint32_t op) (!BIT31(operand1) && !BIT31(operand2) && BIT31(result))) ? PSR_V_MASK : 0; PSR |= ((BIT31(operand1) && BIT31(operand2)) || (!BIT31(result) && (BIT31(operand1) || BIT31(operand2)))) ? PSR_C_MASK : 0; + + PC = nPC; + nPC = nPC + 4; } @@ -1035,13 +1070,16 @@ void mb86901_device::execute_rdsr(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } else if (m_illegal_instruction_asr[RS1]) { m_trap = 1; m_illegal_instruction = 1; + return; } - else if (RD != 0) + + if (RD != 0) { if (RDASR) { @@ -1059,6 +1097,9 @@ void mb86901_device::execute_rdsr(uint32_t op) else if (RDTBR) RDREG = TBR; } + + PC = nPC; + nPC = nPC + 4; } @@ -1119,6 +1160,8 @@ void mb86901_device::execute_wrsr(uint32_t op) if (WRASR && RD == 0) { Y = result; + PC = nPC; + nPC = nPC + 4; } else if (WRASR) { @@ -1126,15 +1169,19 @@ void mb86901_device::execute_wrsr(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } else if (m_illegal_instruction_asr[RD]) { m_trap = 1; m_illegal_instruction = 1; + return; } else { // SPARCv8 + PC = nPC; + nPC = nPC + 4; } } else if (WRPSR) @@ -1143,17 +1190,25 @@ void mb86901_device::execute_wrsr(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } else if ((result & 31) >= NWINDOWS) { m_trap = 1; m_illegal_instruction = 1; + return; } - else - { - PSR = result &~ PSR_ZERO_MASK; - update_gpr_pointers(); - } + + PSR = result &~ PSR_ZERO_MASK; + update_gpr_pointers(); + + m_et = PSR & PSR_ET_MASK; + m_pil = (PSR & PSR_PIL_MASK) >> PSR_PIL_SHIFT; + m_s = PSR & PSR_S_MASK; + m_fetch_space = m_s ? 9 : 8; + + PC = nPC; + nPC = nPC + 4; } else if (WRWIM) { @@ -1161,11 +1216,12 @@ void mb86901_device::execute_wrsr(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } - else - { - WIM = result & 0x7f; - } + + WIM = result & 0x7f; + PC = nPC; + nPC = nPC + 4; } else if (WRTBR) { @@ -1173,11 +1229,12 @@ void mb86901_device::execute_wrsr(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } - else - { - TBR = result & 0xfffff000; - } + + TBR = result & 0xfffff000; + PC = nPC; + nPC = nPC + 4; } } @@ -1227,7 +1284,7 @@ void mb86901_device::execute_rett(uint32_t op) uint8_t new_cwp = ((PSR & PSR_CWP_MASK) + 1) % NWINDOWS; uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG); - if (PSR & PSR_ET_MASK) + if (m_et) { m_trap = 1; if (IS_USER) @@ -1238,6 +1295,7 @@ void mb86901_device::execute_rett(uint32_t op) { m_illegal_instruction = 1; } + return; } else if (IS_USER) { @@ -1246,6 +1304,7 @@ void mb86901_device::execute_rett(uint32_t op) m_tt = 3; m_execute_mode = 0; m_error_mode = 1; + return; } else if ((WIM & (1 << new_cwp)) != 0) { @@ -1254,6 +1313,7 @@ void mb86901_device::execute_rett(uint32_t op) m_tt = 6; m_execute_mode = 0; m_error_mode = 1; + return; } else if (address & 3) { @@ -1262,20 +1322,28 @@ void mb86901_device::execute_rett(uint32_t op) m_tt = 7; m_execute_mode = 0; m_error_mode = 1; + return; } - else - { - PSR |= PSR_ET_MASK; - PC = nPC; - nPC = address; - PSR &= ~PSR_CWP_MASK; - PSR |= new_cwp; + PSR |= PSR_ET_MASK; + m_et = true; + PC = nPC; + nPC = address; - if (PSR & PSR_PS_MASK) - PSR |= PSR_S_MASK; - else - PSR &= ~PSR_S_MASK; + PSR &= ~PSR_CWP_MASK; + PSR |= new_cwp; + + if (PSR & PSR_PS_MASK) + { + PSR |= PSR_S_MASK; + m_s = true; + m_fetch_space = 9; + } + else + { + PSR &= ~PSR_S_MASK; + m_s = false; + m_fetch_space = 8; } update_gpr_pointers(); @@ -1331,14 +1399,13 @@ void mb86901_device::execute_saverestore(uint32_t op) { m_trap = 1; m_window_overflow = 1; + return; } - else - { - result = rs1 + operand2; - PSR &= ~PSR_CWP_MASK; - PSR |= new_cwp; - BREAK_PSR; - } + + result = rs1 + operand2; + PSR &= ~PSR_CWP_MASK; + PSR |= new_cwp; + //BREAK_PSR; } else if (RESTORE) { @@ -1347,20 +1414,22 @@ void mb86901_device::execute_saverestore(uint32_t op) { m_trap = 1; m_window_underflow = 1; + return; } - else - { - result = rs1 + operand2; - PSR &= ~PSR_CWP_MASK; - PSR |= new_cwp; - BREAK_PSR; - } + + result = rs1 + operand2; + PSR &= ~PSR_CWP_MASK; + PSR |= new_cwp; + //BREAK_PSR; } update_gpr_pointers(); - if (m_trap == 0 && RD != 0) + if (RD != 0) RDREG = result; + + PC = nPC; + nPC = nPC + 4; } @@ -1475,8 +1544,13 @@ void mb86901_device::execute_group2(uint32_t op) case OP3_FPOP1: case OP3_FPOP2: - // Not yet implemented - break; + if (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present) + { + //printf("fpop @ %08x: %08x\n", PC, op); + m_trap = 1; + m_fp_disabled = 1; + } + return; case OP3_JMPL: execute_jmpl(op); @@ -1492,6 +1566,8 @@ void mb86901_device::execute_group2(uint32_t op) case OP3_IFLUSH: // Ignored + PC = nPC; + nPC = nPC + 4; break; case OP3_SAVE: @@ -1516,15 +1592,17 @@ void mb86901_device::execute_group2(uint32_t op) case OP3_CPOP1: case OP3_CPOP2: - break; + printf("fpop @ %08x: %08x\n", PC, op); + m_trap = 1; + m_cp_disabled = 1; + return; #endif default: - { + printf("illegal instruction at %08x: %08x\n", PC, op); m_trap = 1; m_illegal_instruction = 1; break; - } } } @@ -1676,188 +1754,186 @@ void mb86901_device::execute_store(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } else if (USEIMM && (STDA || STA || STHA || STBA)) { m_trap = 1; m_illegal_instruction = 1; + return; } uint32_t address = 0; uint8_t addr_space = 0; - if (!m_trap) + if (STD || ST || STH || STB || STF || STDF || STFSR || STDFQ || STCSR || STC || STDC || STDCQ) { - if (STD || ST || STH || STB || STF || STDF || STFSR || STDFQ || STCSR || STC || STDC || STDCQ) - { - address = RS1REG + (USEIMM ? SIMM13 : RS2REG); - addr_space = (IS_USER ? 10 : 11); - } - else if (STDA || STA || STHA || STBA) - { - address = RS1REG + RS2REG; - addr_space = ASI; - } - if ((STF || STDF || STFSR || STDFQ) && (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present)) - { - m_trap = 1; - m_fp_disabled = 1; - } - if ((STC || STDC || STCSR || STDCQ) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)) - { - m_trap = 1; - m_cp_disabled = 1; - } + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + } + else if (STDA || STA || STHA || STBA) + { + address = RS1REG + RS2REG; + addr_space = ASI; + } + if ((STF || STDF || STFSR || STDFQ) && (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present)) + { + m_trap = 1; + m_fp_disabled = 1; + return; + } + if ((STC || STDC || STCSR || STDCQ) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)) + { + m_trap = 1; + m_cp_disabled = 1; + return; } - if (!m_trap) + if ((STH || STHA) && ((address & 1) != 0)) { - if ((STH || STHA) && ((address & 1) != 0)) - { - m_trap = 1; - m_mem_address_not_aligned = 1; - } - else if ((ST || STA || STF || STFSR || STC || STCSR) && ((address & 3) != 0)) - { - m_trap = 1; - m_mem_address_not_aligned = 1; - } - else if ((STD || STDA || STDF || STDFQ || STDC || STDCQ) && ((address & 7) != 0)) - { - m_trap = 1; - m_mem_address_not_aligned = 1; - } - else - { - if (STDFQ) - { - // assume no floating-point queue for now - m_trap = 1; - m_fp_exception = 1; - m_ftt = m_fpu_sequence_err; - } - if (STDCQ) - { - // assume no coprocessor queue for now - m_trap = 1; - m_cp_exception = 1; - // { possibly additional implementation-dependent actions } - } - if (STDF && ((RD & 1) != 0)) - { - m_trap = 1; - m_fp_exception = 1; - m_ftt = 0xff; - } - } + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + else if ((ST || STA || STF || STFSR || STC || STCSR) && ((address & 3) != 0)) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + else if ((STD || STDA || STDF || STDFQ || STDC || STDCQ) && ((address & 7) != 0)) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (STDFQ) + { + // assume no floating-point queue for now + m_trap = 1; + m_fp_exception = 1; + m_ftt = m_fpu_sequence_err; + return; + } + if (STDCQ) + { + // assume no coprocessor queue for now + m_trap = 1; + m_cp_exception = 1; + // { possibly additional implementation-dependent actions } + return; + } + if (STDF && ((RD & 1) != 0)) + { + m_trap = 1; + m_fp_exception = 1; + m_ftt = 0xff; + return; } uint32_t data0 = 0; - if (!m_trap) + //uint8_t byte_mask; + if (STF) { - //uint8_t byte_mask; - if (STF) - { - //byte_mask = 15; - data0 = FREG(RD); - } - else if (STC) - { - //byte_mask = 15; - data0 = 0; - } - else if (STDF) - { - //byte_mask = 15; - data0 = FREG(RD & 0x1e); - } - else if (STDC) - { - //byte_mask = 15; - data0 = 0; - } - else if (STD || STDA) + //byte_mask = 15; + data0 = FREG(RD); + } + else if (STC) + { + //byte_mask = 15; + data0 = 0; + } + else if (STDF) + { + //byte_mask = 15; + data0 = FREG(RD & 0x1e); + } + else if (STDC) + { + //byte_mask = 15; + data0 = 0; + } + else if (STD || STDA) + { + //byte_mask = 15; + data0 = REG(RD & 0x1e); + } + else if (STDFQ) + { + //byte_mask = 15; + data0 = 0; + } + else if (STDCQ) + { + //byte_mask = 15; + data0 = 0; + } + else if (STFSR) + { + // while ((FSR.qne = 1) and (trap = 0)) ( + // wait for pending floating-point instructions to complete + // ) + // next; + //byte_mask = 15; + data0 = FSR; + } + else if (STCSR) + { + // { implementation-dependent actions } + //byte_mask = 15; + data0 = 0; + } + else if (ST || STA) + { + //byte_mask = 15; + data0 = REG(RD); + } + else if (STH || STHA) + { + if ((address & 3) == 0) { - //byte_mask = 15; - data0 = REG(RD & 0x1e); + //byte_mask = 12; + data0 = REG(RD) << 16; } - else if (STDFQ) + else if ((address & 3) == 2) { - //byte_mask = 15; - data0 = 0; + //byte_mask = 3; + data0 = REG(RD); } - else if (STDCQ) + } + else if (STB || STBA) + { + if ((address & 3) == 0) { - //byte_mask = 15; - data0 = 0; + //byte_mask = 8; + data0 = REG(RD) << 24; } - else if (STFSR) + else if ((address & 3) == 1) { - // while ((FSR.qne = 1) and (trap = 0)) ( - // wait for pending floating-point instructions to complete - // ) - // next; - //byte_mask = 15; - data0 = FSR; + //byte_mask = 4; + data0 = REG(RD) << 16; } - else if (STCSR) + else if ((address & 3) == 2) { - // { implementation-dependent actions } - //byte_mask = 15; - data0 = 0; + //byte_mask = 2; + data0 = REG(RD) << 8; } - else if (ST || STA) + else if ((address & 3) == 3) { - //byte_mask = 15; + //byte_mask = 1; data0 = REG(RD); } - else if (STH || STHA) - { - if ((address & 3) == 0) - { - //byte_mask = 12; - data0 = REG(RD) << 16; - } - else if ((address & 3) == 2) - { - //byte_mask = 3; - data0 = REG(RD); - } - } - else if (STB || STBA) - { - if ((address & 3) == 0) - { - //byte_mask = 8; - data0 = REG(RD) << 24; - } - else if ((address & 3) == 1) - { - //byte_mask = 4; - data0 = REG(RD) << 16; - } - else if ((address & 3) == 2) - { - //byte_mask = 2; - data0 = REG(RD) << 8; - } - else if ((address & 3) == 3) - { - //byte_mask = 1; - data0 = REG(RD); - } - } } - if (!m_trap) + write_sized_word(addr_space, address, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 4 : ((STH || STHA) ? 2 : 1)); + if (MAE) { - write_sized_word(addr_space, address, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 4 : ((STH || STHA) ? 2 : 1)); - if (MAE) - { - m_trap = 1; - m_data_access_exception = 1; - } + m_trap = 1; + m_data_access_exception = 1; + return; } - if (!m_trap && (STD || STDA || STDF || STDC || STDFQ || STDCQ)) + + if (STD || STDA || STDF || STDC || STDFQ || STDCQ) { uint32_t data1 = 0; if (STD || STDA) @@ -1886,8 +1962,12 @@ void mb86901_device::execute_store(uint32_t op) { m_trap = 1; m_data_access_exception = 1; + return; } } + + PC = nPC; + nPC = nPC + 4; } //------------------------------------------------- @@ -1998,140 +2078,688 @@ void mb86901_device::execute_load(uint32_t op) uint32_t address = 0; uint8_t addr_space = 0; - if (LDD || LD || LDSH || LDUH || LDSB || LDUB || LDDF || LDF || LDFSR || LDDC || LDC || LDCSR) - { - address = RS1REG + (USEIMM ? SIMM13 : RS2REG); - addr_space = (IS_USER ? 10 : 11); - } - else if (LDDA || LDA || LDSHA || LDUHA || LDSBA || LDUBA) + switch (OP3) { - if (IS_USER) + case OP3_LDD: { - m_trap = 1; - m_privileged_instruction = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (address & 7) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + RDREG = data; + + const uint32_t word1 = read_sized_word(addr_space, address + 4, 4); + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + REG(RD | 1) = word1; + break; } - else if (USEIMM) + case OP3_LD: { - m_trap = 1; - m_illegal_instruction = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + RDREG = data; + break; } - else + case OP3_LDSH: { - address = RS1REG + RS2REG; - addr_space = ASI; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (address & 1) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 2); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = (int32_t)data >> 16; + else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16; + } + break; } - } + case OP3_LDUH: + { + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); - if (!m_trap) - { - if ((LDF || LDDF || LDFSR) && (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)) + if (address & 1) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 2); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = data >> 16; + else if ((address & 3) == 2) RDREG = data & 0xffff; + } + break; + } + case OP3_LDSB: { - m_trap = 1; - m_fp_disabled = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + const uint32_t data = read_sized_word(addr_space, address, 1); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = (int32_t)data >> 24; + else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24; + else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24; + else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24; + } + break; } - else if ((LDC || LDDC || LDCSR) && (!(PSR & PSR_EC_MASK) || m_bp_cp_present == 0)) + case OP3_LDUB: { - m_trap = 1; - m_cp_disabled = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + const uint32_t data = read_sized_word(addr_space, address, 1); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = data >> 24; + else if ((address & 3) == 1) RDREG = (data >> 16) & 0xff; + else if ((address & 3) == 2) RDREG = (data >> 8) & 0xff; + else if ((address & 3) == 3) RDREG = data & 0xff; + } + break; } - else if (((LDD || LDDA || LDDF || LDDC) && ((address & 7) != 0)) || - ((LD || LDA || LDF || LDFSR || LDC || LDCSR) && ((address & 3) != 0)) || - ((LDSH || LDSHA || LDUH || LDUHA) && ((address & 1) != 0))) + case OP3_LDDFPR: { - m_trap = 1; - m_mem_address_not_aligned = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0) + { + m_trap = 1; + m_fp_disabled = 1; + return; + } + + if (address & 7) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (RD & 1) + { + m_trap = 1; + m_fp_exception = 1; + m_ftt = 0xff; + return; + } + + if (m_fpu_sequence_err) + { + m_trap = 1; + m_fp_exception = 1; + m_ftt = m_fpu_sequence_err; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + FREG(RD & 0x1e) = data; + + const uint32_t word1 = read_sized_word(addr_space, address + 4, 4); + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + FREG(RD | 1) = word1; + break; } - else if (LDDF && ((RD & 1) != 0)) + case OP3_LDFPR: { - m_trap = 1; - m_fp_exception = 1; - m_ftt = 0xff; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0) + { + m_trap = 1; + m_fp_disabled = 1; + return; + } + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (m_fpu_sequence_err) + { + m_trap = 1; + m_fp_exception = 1; + m_ftt = m_fpu_sequence_err; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + FDREG = data; + break; } - else if ((LDF || LDDF || LDFSR) && m_fpu_sequence_err != 0) + case OP3_LDFSR: { - m_trap = 1; - m_fp_exception = 1; - m_ftt = m_fpu_sequence_err; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0) + { + m_trap = 1; + m_fp_disabled = 1; + return; + } + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (m_fpu_sequence_err) + { + m_trap = 1; + m_fp_exception = 1; + m_ftt = m_fpu_sequence_err; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + FSR = data; + break; } - else if ((LDC || LDDC || LDCSR) && m_cp_sequence_err != 0) + case OP3_LDDCPR: { - m_trap = 1; - m_cp_exception = 1; - // possibly additional implementation-dependent actions + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present) + { + m_trap = 1; + m_cp_disabled = 1; + return; + } + + if (address & 7) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (m_cp_sequence_err) + { + m_trap = 1; + m_cp_exception = 1; + // possibly additional implementation-dependent actions + return; + } + + read_sized_word(addr_space, address, 4); + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + // implementation-dependent actions + + read_sized_word(addr_space, address + 4, 4); + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + // implementation-dependent actions + break; } - } + case OP3_LDCPR: + { + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); - uint32_t word0(0); - if (!m_trap) - { - uint32_t data = read_sized_word(addr_space, address, (LD || LDD || LDA || LDDA) ? 4 : ((LDUH || LDSH || LDUHA || LDSHA) ? 2 : 1)); + if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present) + { + m_trap = 1; + m_cp_disabled = 1; + return; + } + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (m_cp_sequence_err) + { + m_trap = 1; + m_cp_exception = 1; + // possibly additional implementation-dependent actions + return; + } - if (m_mae) + read_sized_word(addr_space, address, 4); + + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + // implementation-dependent actions + break; + } + case OP3_LDCSR: { - m_trap = 1; - m_data_access_exception = 1; + address = RS1REG + (USEIMM ? SIMM13 : RS2REG); + addr_space = (IS_USER ? 10 : 11); + + if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present) + { + m_trap = 1; + m_cp_disabled = 1; + return; + } + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + if (m_cp_sequence_err) + { + m_trap = 1; + m_cp_exception = 1; + // possibly additional implementation-dependent actions + return; + } + + read_sized_word(addr_space, address, 4); + + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + // implementation-dependent actions + break; } - else + case OP3_LDDA: { - if (LDSB || LDSBA || LDUB || LDUBA) + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) { - uint8_t byte = 0; - if ((address & 3) == 0) byte = (data >> 24) & 0xff; - else if ((address & 3) == 1) byte = (data >> 16) & 0xff; - else if ((address & 3) == 2) byte = (data >> 8) & 0xff; - else if ((address & 3) == 3) byte = data & 0xff; + m_trap = 1; + m_illegal_instruction = 1; + return; + } + else + { + address = RS1REG + RS2REG; + addr_space = ASI; + } + + if (address & 7) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } - if (LDSB || LDSBA) - word0 = (((int32_t)byte) << 24) >> 24; - else - word0 = byte; + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; } - else if (LDSH || LDSHA || LDUH || LDUHA) + + if (RD != 0) + RDREG = data; + + uint32_t word1 = read_sized_word(addr_space, address + 4, 4); + if (MAE) { - uint16_t halfword = 0; - if ((address & 3) == 0) halfword = (data >> 16) & 0xffff; - else if ((address & 3) == 2) halfword = data & 0xffff; + m_trap = 1; + m_data_access_exception = 1; + return; + } - if (LDSH || LDSHA) - { - word0 = (((int32_t)halfword) << 16) >> 16; - } - else - { - word0 = halfword; - } + REG(RD | 1) = word1; + break; + } + case OP3_LDA: + { + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) + { + m_trap = 1; + m_illegal_instruction = 1; + return; } else { - word0 = data; + address = RS1REG + RS2REG; + addr_space = ASI; } + + if (address & 3) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 4); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + RDREG = data; + break; } - } + case OP3_LDSHA: + { + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) + { + m_trap = 1; + m_illegal_instruction = 1; + return; + } + else + { + address = RS1REG + RS2REG; + addr_space = ASI; + } - if (!m_trap) - { - if (RD == 0) { } - else if (LD || LDA || LDSH || LDSHA || LDUHA || LDUH || LDSB || LDSBA || LDUB || LDUBA) RDREG = word0; - else if (LDF) FDREG = word0; - else if (LDC) { } // implementation-dependent actions - else if (LDFSR) FSR = word0; - else if (LDD || LDDA) REG(RD & 0x1e) = word0; - else if (LDDF) FREG(RD & 0x1e) = word0; - else if (LDDC) { } // implementation-dependent actions - } + if (address & 1) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } - if (!m_trap && (LDD || LDDA || LDDF || LDDC)) - { - uint32_t word1 = read_sized_word(addr_space, address + 4, 4); - if (MAE) + const uint32_t data = read_sized_word(addr_space, address, 2); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = (int32_t)data >> 16; + else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16; + } + break; + } + case OP3_LDUHA: { - m_trap = 1; - m_data_access_exception = 1; + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) + { + m_trap = 1; + m_illegal_instruction = 1; + return; + } + else + { + address = RS1REG + RS2REG; + addr_space = ASI; + } + + if (address & 1) + { + m_trap = 1; + m_mem_address_not_aligned = 1; + return; + } + + const uint32_t data = read_sized_word(addr_space, address, 2); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = data >> 16; + else if ((address & 3) == 2) RDREG = data & 0xffff; + } + break; + } + case OP3_LDSBA: + { + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) + { + m_trap = 1; + m_illegal_instruction = 1; + return; + } + else + { + address = RS1REG + RS2REG; + addr_space = ASI; + } + + const uint32_t data = read_sized_word(addr_space, address, 1); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = (int32_t)data >> 24; + else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24; + else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24; + else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24; + } + break; + } + case OP3_LDUBA: + { + if (IS_USER) + { + m_trap = 1; + m_privileged_instruction = 1; + return; + } + else if (USEIMM) + { + m_trap = 1; + m_illegal_instruction = 1; + return; + } + else + { + address = RS1REG + RS2REG; + addr_space = ASI; + } + + const uint32_t data = read_sized_word(addr_space, address, 1); + + if (m_mae) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + if (RD != 0) + { + if ((address & 3) == 0) RDREG = data >> 24; + else if ((address & 3) == 1) RDREG = (data >> 16) & 0xff; + else if ((address & 3) == 2) RDREG = (data >> 8) & 0xff; + else if ((address & 3) == 3) RDREG = data & 0xff; + } + break; } - else if (LDD || LDDA) REG(RD | 1) = word1; - else if (LDDF) FREG(RD | 1) = word1; - else if (LDDC) { } // implementation-dependent actions + default: + break; } + + PC = nPC; + nPC = nPC + 4; } @@ -2214,91 +2842,91 @@ void mb86901_device::execute_ldstub(uint32_t op) { m_trap = 1; m_privileged_instruction = 1; + return; } else if (USEIMM) { m_trap = 1; m_illegal_instruction = 1; + return; } else { address = RS1REG + RS2REG; addr_space = ASI; + return; } } uint32_t data(0); - if (!m_trap) + while (m_pb_block_ldst_byte || m_pb_block_ldst_word) { - while (m_pb_block_ldst_byte || m_pb_block_ldst_word) - { - // { wait for lock(s) to be lifted } - // { an implementation actually need only block when another LDSTUB or SWAP - // is pending on the same byte in memory as the one addressed by this LDSTUB } - } + // { wait for lock(s) to be lifted } + // { an implementation actually need only block when another LDSTUB or SWAP + // is pending on the same byte in memory as the one addressed by this LDSTUB } + } - m_pb_block_ldst_byte = 1; + m_pb_block_ldst_byte = 1; - data = read_sized_word(addr_space, address, 1); + data = read_sized_word(addr_space, address, 1); - if (MAE) - { - m_trap = 1; - m_data_access_exception = 1; - } + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; } - if (!m_trap) + //uint8_t byte_mask; + if ((address & 3) == 0) { - //uint8_t byte_mask; - if ((address & 3) == 0) - { - //byte_mask = 8; - } - else if ((address & 3) == 1) - { - //byte_mask = 4; - } - else if ((address & 3) == 2) - { - //byte_mask = 2; - } - else if ((address & 3) == 3) - { - //byte_mask = 1; - } - write_sized_word(addr_space, address, 0xffffffff, 1); + //byte_mask = 8; + } + else if ((address & 3) == 1) + { + //byte_mask = 4; + } + else if ((address & 3) == 2) + { + //byte_mask = 2; + } + else if ((address & 3) == 3) + { + //byte_mask = 1; + } + write_sized_word(addr_space, address, 0xffffffff, 1); - m_pb_block_ldst_byte = 0; + m_pb_block_ldst_byte = 0; - if (MAE) - { - m_trap = 1; - m_data_access_exception = 1; - } - else - { - uint32_t word; - if ((address & 3) == 0) - { - word = (data >> 24) & 0xff; - } - else if ((address & 3) == 1) - { - word = (data >> 16) & 0xff; - } - else if ((address & 3) == 2) - { - word = (data >> 8) & 0xff; - } - else // if ((address & 3) == 3) - { - word = data & 0xff; - } - if (RD != 0) - RDREG = word; - } + if (MAE) + { + m_trap = 1; + m_data_access_exception = 1; + return; + } + + uint32_t word; + if ((address & 3) == 0) + { + word = (data >> 24) & 0xff; + } + else if ((address & 3) == 1) + { + word = (data >> 16) & 0xff; + } + else if ((address & 3) == 2) + { + word = (data >> 8) & 0xff; + } + else // if ((address & 3) == 3) + { + word = data & 0xff; } + if (RD != 0) + RDREG = word; + + PC = nPC; + nPC = nPC + 4; } @@ -2373,6 +3001,12 @@ void mb86901_device::execute_group3(uint32_t op) execute_swap(op); break; #endif + + default: + printf("illegal instruction at %08x: %08x\n", PC, op); + m_trap = 1; + m_illegal_instruction = 1; + break; } if (MAE || HOLD_BUS) @@ -2548,7 +3182,7 @@ void mb86901_device::select_trap() m_trap = 0; return; } - else if (!(PSR & PSR_ET_MASK)) + else if (!m_et) { m_execute_mode = 0; m_error_mode = 1; @@ -2712,6 +3346,7 @@ void mb86901_device::execute_trap() if (!m_error_mode) { PSR &= ~PSR_ET_MASK; + m_et = false; if (IS_USER) PSR &= ~PSR_PS_MASK; @@ -2719,6 +3354,8 @@ void mb86901_device::execute_trap() PSR |= PSR_PS_MASK; PSR |= PSR_S_MASK; + m_s = true; + m_fetch_space = 9; int cwp = PSR & PSR_CWP_MASK; int new_cwp = ((cwp + NWINDOWS) - 1) % NWINDOWS; @@ -2756,17 +3393,41 @@ void mb86901_device::execute_trap() //------------------------------------------------- -// complete_instruction_execution - execute a -// single fetched instruction that has been -// checked for FP-disabled, CP-disabled, and -// validity. +// dispatch_instruction - executes a +// single fetched instruction. //------------------------------------------------- -void mb86901_device::complete_instruction_execution(uint32_t op) +/* The SPARC Instruction Manual: Version 8, page 159, "Appendix C - ISP Descriptions - C.6. Instruction Dispatch" (SPARCv8.pdf, pg. 156) + +illegal_IU_instr :- ( + if ( ( (op == 00) and (op2 == 000) ) { UNIMP instruction } + or + ( ((op=11) or (op=10)) and (op3=unassigned) ) + then 1 else 0 + +if (illegal_IU_instr = 1) then ( + trap <- 1 + illegal_instruction <- 1 +); +if ((FPop1 or FPop2 or FBfcc) and ((EF = 0) or (bp_FPU_present = 0))) then ( + trap <- 1; + fp_disabled <- 1 +); +if (CPop1 or CPop2 or CBccc) and ((EC = 0) or (bp_CP_present = 0))) then ( + trap <- 1; + cp_disabled <- 1 +); +next; +if (trap = 0) then ( + { code for specific instruction, defined below } +); +*/ + +inline void mb86901_device::dispatch_instruction(uint32_t op) { - switch (OP) + switch (OP_NS) { - case OP_TYPE0: // Bicc, SETHI, FBfcc + case OP_TYPE0_NS: // Bicc, SETHI, FBfcc switch (OP2) { case OP2_UNIMP: // unimp @@ -2776,22 +3437,41 @@ void mb86901_device::complete_instruction_execution(uint32_t op) execute_bicc(op); break; case OP2_SETHI: // sethi - SET_RDREG(IMM22); + //SET_RDREG(IMM22); + *m_regs[RD] = op << 10; + m_r[0] = 0; + PC = nPC; + nPC = nPC + 4; break; case OP2_FBFCC: // branch on floating-point condition codes - printf("fbfcc @ %x\n", PC); + if (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present) + { + //printf("fbfcc at %08x: %08x\n", PC, op); + m_trap = 1; + m_fp_disabled = 1; + return; + } break; #if SPARCV8 case OP2_CBCCC: // branch on coprocessor condition codes, SPARCv8 - break; + if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present) + { + printf("cbccc @ %08x: %08x\n", PC, op); + m_trap = 1; + m_cp_disabled = 1; + return; + } + return; #endif default: - printf("unknown %08x @ %x\n", op, PC); - break; + printf("illegal instruction at %08x: %08x\n", PC, op); + m_trap = 1; + m_illegal_instruction = 1; + return; } break; - case OP_CALL: // call + case OP_CALL_NS: // call { uint32_t pc = PC; uint32_t callpc = PC + DISP30; @@ -2802,77 +3482,16 @@ void mb86901_device::complete_instruction_execution(uint32_t op) break; } - case OP_ALU: + case OP_ALU_NS: execute_group2(op); break; - case OP_LDST: + case OP_LDST_NS: execute_group3(op); break; - default: - break; } } - -//------------------------------------------------- -// dispatch_instruction - dispatch the previously -// fetched instruction -//------------------------------------------------- - -void mb86901_device::dispatch_instruction(uint32_t op) -{ - /* The SPARC Instruction Manual: Version 8, page 159, "Appendix C - ISP Descriptions - C.6. Instruction Dispatch" (SPARCv8.pdf, pg. 156) - - illegal_IU_instr :- ( - if ( ( (op == 00) and (op2 == 000) ) { UNIMP instruction } - or - ( ((op=11) or (op=10)) and (op3=unassigned) ) - then 1 else 0 - - if (illegal_IU_instr = 1) then ( - trap <- 1 - illegal_instruction <- 1 - ); - if ((FPop1 or FPop2 or FBfcc) and ((EF = 0) or (bp_FPU_present = 0))) then ( - trap <- 1; - fp_disabled <- 1 - ); - if (CPop1 or CPop2 or CBccc) and ((EC = 0) or (bp_CP_present = 0))) then ( - trap <- 1; - cp_disabled <- 1 - ); - next; - if (trap = 0) then ( - { code for specific instruction, defined below } - ); - */ - bool illegal_IU_instr = (OP == 0 && OP2 == 0) || ((OP == 3 && !m_ldst_op3_assigned[OP3]) || (OP == 2 && !m_alu_op3_assigned[OP3])); - - if (illegal_IU_instr) - { - printf("illegal instruction at %08x: %08x\n", PC, op); - m_trap = 1; - m_illegal_instruction = 1; - } - if (((OP == OP_ALU && (FPOP1 || FPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_FBFCC)) && (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present)) - { - m_trap = 1; - m_fp_disabled = 1; - } - if (((OP == OP_ALU && (CPOP1 || CPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_CBCCC)) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)) - { - m_trap = 1; - m_cp_disabled = 1; - } - - if (!m_trap) - { - complete_instruction_execution(op); - } -} - - //------------------------------------------------- // complete_fp_execution - completes execution // of a floating-point operation @@ -2949,7 +3568,7 @@ void mb86901_device::execute_step() //printf("Entering reset mode\n"); return; } - else if ((PSR & PSR_ET_MASK) && (m_bp_irl == 15 || m_bp_irl > ((PSR & PSR_PIL_MASK) >> PSR_PIL_SHIFT))) + else if (m_et && (m_bp_irl == 15 || m_bp_irl > m_pil)) { m_trap = 1; m_interrupt_level = m_bp_irl; @@ -2958,7 +3577,7 @@ void mb86901_device::execute_step() if (m_trap) { execute_trap(); - BREAK_PSR; + //BREAK_PSR; debugger_instruction_hook(PC); } @@ -2966,8 +3585,7 @@ void mb86901_device::execute_step() { // write-state-register delay not yet implemented - uint32_t addr_space = (IS_USER ? 8 : 9); - uint32_t op = read_sized_word(addr_space, PC, 4); + const uint32_t op = read_sized_word(m_fetch_space, PC, 4); #if LOG_FCODES //if (m_log_fcodes) @@ -2992,11 +3610,11 @@ void mb86901_device::execute_step() complete_fp_execution(op); } - if (m_trap == 0 && !(OP == OP_CALL || (OP == OP_TYPE0 && (OP2 == OP2_BICC || OP2 == OP2_FBFCC || OP2 == OP2_CBCCC)) || (OP == OP_ALU && (JMPL || TICC || RETT)))) - { - PC = nPC; - nPC = nPC + 4; - } + //if (m_trap == 0 && !(OP == OP_CALL || (OP == OP_TYPE0 && (OP2 == OP2_BICC || OP2 == OP2_FBFCC || OP2 == OP2_CBCCC)) || (OP == OP_ALU && (JMPL || TICC || RETT)))) + //{ + //PC = nPC; + //nPC = nPC + 4; + //} } else { @@ -3081,7 +3699,7 @@ void mb86901_device::execute_run() continue; } - BREAK_PSR; + //BREAK_PSR; debugger_instruction_hook(PC); if (m_reset_mode) |