diff options
Diffstat (limited to 'src/devices/cpu/e132xs/e132xs.cpp')
-rw-r--r-- | src/devices/cpu/e132xs/e132xs.cpp | 253 |
1 files changed, 151 insertions, 102 deletions
diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index 3793e351b73..73725ec8a25 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -33,7 +33,6 @@ TODO: - some wrong cycle counts - verify register wrapping with sregf/dregf on hardware - CHANGELOG: Pierpaolo Prazzoli @@ -148,6 +147,7 @@ #include "debugger.h" #include "32xsdefs.h" +#include "32xsdasm.h" //#define VERBOSE 1 #include "logmacro.h" @@ -195,10 +195,10 @@ ADDRESS_MAP_END hyperstone_device::hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map) - : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map) - , m_io_config("io", ENDIANNESS_BIG, io_data_width, 15) - , m_icount(0) + : cpu_device(mconfig, type, tag, owner, clock), + m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map), + m_io_config("io", ENDIANNESS_BIG, io_data_width, 15), + m_icount(0) { } @@ -374,26 +374,46 @@ uint32_t hyperstone_device::get_emu_code_addr(uint8_t num) /* num is OP */ return addr; } -/*static*/ const uint32_t hyperstone_device::s_trap_entries[8] = { - 0x00000000, // MEM0 - 0x40000000, // MEM1 - 0x80000000, // MEM2 - 0xc0000000, // IRAM - 0, - 0, - 0, - 0xffffff00, // MEM3 -}; +void hyperstone_device::hyperstone_set_trap_entry(int which) +{ + switch( which ) + { + case E132XS_ENTRY_MEM0: + m_trap_entry = 0x00000000; + break; + + case E132XS_ENTRY_MEM1: + m_trap_entry = 0x40000000; + break; + + case E132XS_ENTRY_MEM2: + m_trap_entry = 0x80000000; + break; + + case E132XS_ENTRY_MEM3: + m_trap_entry = 0xffffff00; + break; + + case E132XS_ENTRY_IRAM: + m_trap_entry = 0xc0000000; + break; + + default: + LOG("Set entry point to a reserved value: %d\n", which); + break; + } +} -void hyperstone_device::compute_tr() +uint32_t hyperstone_device::compute_tr() { uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles; uint64_t clocks_since_base = cycles_since_base >> m_clck_scale; - m_tr_result = m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); + return m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); } void hyperstone_device::update_timer_prescale() { + uint32_t prevtr = compute_tr(); TPR &= ~0x80000000; m_clck_scale = (TPR >> 26) & m_clock_scale_mask; m_clock_cycles_1 = 1 << m_clck_scale; @@ -402,7 +422,7 @@ void hyperstone_device::update_timer_prescale() m_clock_cycles_4 = 4 << m_clck_scale; m_clock_cycles_6 = 6 << m_clck_scale; m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2; - m_tr_base_value = m_tr_result; + m_tr_base_value = prevtr; m_tr_base_cycles = total_cycles(); } @@ -452,13 +472,10 @@ TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback ) /* update the values if necessary */ if (update) - { update_timer_prescale(); - } /* see if the timer is right for firing */ - compute_tr(); - if (!((m_tr_result - TCR) & 0x80000000)) + if (!((compute_tr() - TCR) & 0x80000000)) m_timer_int_pending = 1; /* adjust ourselves for the next time */ @@ -508,8 +525,7 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) /* it is common to poll this in a loop */ if (m_icount > m_tr_clocks_per_tick / 2) m_icount -= m_tr_clocks_per_tick / 2; - compute_tr(); - return m_tr_result; + return compute_tr(); } return m_global_regs[code & 0x1f]; } @@ -563,10 +579,7 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) case TPR_REGISTER: m_global_regs[code] = val; if (!(val & 0x80000000)) /* change immediately */ - { - compute_tr(); update_timer_prescale(); - } adjust_timer_interrupt(); return; case TCR_REGISTER: @@ -597,14 +610,10 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) m_intblock = 1; return; case MCR_REGISTER: - { // bits 14..12 EntryTableMap - const int which = (val & 0x7000) >> 12; - assert(which < 4 || which == 7); - m_trap_entry = s_trap_entries[which]; + hyperstone_set_trap_entry((val & 0x7000) >> 12); m_global_regs[code] = val; return; - } case 28: case 29: case 30: @@ -625,8 +634,10 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) #define SIGN_BIT(val) ((val & 0x80000000) >> 31) #define SIGN_TO_N(val) ((val & 0x80000000) >> 29) -/*static*/ const int32_t hyperstone_device::s_immediate_values[16] = +static constexpr int32_t immediate_values[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), -8, -7, -6, -5, -4, -3, -2, -1 }; @@ -640,7 +651,7 @@ do if (m_delay_slot) \ { \ PC = m_delay_pc; \ - m_delay_slot = 0; \ + m_delay_slot = false; \ } \ } while (0) @@ -659,7 +670,8 @@ uint32_t hyperstone_device::decode_immediate_s() switch (nybble) { case 0: - return 16; + default: + return immediate_values[0x10 + nybble]; case 1: { m_instruction_length = (3<<19); @@ -681,8 +693,6 @@ uint32_t hyperstone_device::decode_immediate_s() PC += 2; return extra_u; } - default: - return s_immediate_values[nybble]; } } @@ -754,7 +764,7 @@ void hyperstone_device::ignore_pcrel() } } -void hyperstone_device::hyperstone_br() +void hyperstone_device::execute_br() { const int32_t offset = decode_pcrel(); check_delay_PC(); @@ -767,18 +777,24 @@ void hyperstone_device::hyperstone_br() void hyperstone_device::execute_trap(uint32_t addr) { - const uint8_t reg = GET_FP + GET_FL; + uint8_t reg; + uint32_t oldSR; + reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); - const uint32_t oldSR = SR; + + oldSR = SR; SET_FL(6); SET_FP(reg); - m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; - m_local_regs[(1 + reg) & 0x3f] = oldSR; + set_local_register(0, (PC & 0xfffffffe) | GET_S); + set_local_register(1, oldSR); - SR &= ~(M_MASK | T_MASK); - SR |= (L_MASK | S_MASK); + SET_M(0); + SET_T(0); + SET_L(1); + SET_S(1); PC = addr; @@ -813,8 +829,8 @@ void hyperstone_device::execute_exception(uint32_t addr) SET_ILC(m_instruction_length); const uint32_t oldSR = SR; - SET_FL(2); SET_FP(reg); + SET_FL(2); m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; m_local_regs[(1 + reg) & 0x3f] = oldSR; @@ -1005,7 +1021,6 @@ void hyperstone_device::init(int scale_mask) m_tr_base_cycles = 0; m_tr_base_value = 0; - m_tr_result = 0; m_tr_clocks_per_tick = 0; m_timer_int_pending = 0; @@ -1259,7 +1274,7 @@ void hyperstone_device::device_reset() m_tr_clocks_per_tick = 2; - m_trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3 + hyperstone_set_trap_entry(E132XS_ENTRY_MEM3); /* default entry point @ MEM3 */ set_global_register(BCR_REGISTER, ~0); set_global_register(MCR_REGISTER, ~0); @@ -1341,45 +1356,79 @@ void hyperstone_device::state_string_export(const device_state_entry &entry, std util::disasm_interface *hyperstone_device::create_disassembler() { - return new hyperstone_disassembler(this); -} - -u8 hyperstone_device::get_fp() const -{ - return GET_FP; -} - -bool hyperstone_device::get_h() const -{ - return GET_H; + return new hyperstone_disassembler; } /* Opcodes */ void hyperstone_device::hyperstone_trap() { - static const uint32_t conditions[16] = { - 0, 0, 0, 0, N_MASK | Z_MASK, N_MASK | Z_MASK, N_MASK, N_MASK, C_MASK | Z_MASK, C_MASK | Z_MASK, C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, 0 - }; - static const bool trap_if_set[16] = { - false, false, false, false, true, false, true, false, true, false, true, false, true, false, true, false - }; - check_delay_PC(); const uint8_t trapno = (m_op & 0xfc) >> 2; const uint32_t addr = get_trap_addr(trapno); const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03); - if (trap_if_set[code]) - { - if (SR & conditions[code]) - execute_trap(addr); - } - else + switch (code) { - if (!(SR & conditions[code])) + case TRAPLE: + if (SR & (N_MASK | Z_MASK)) + execute_trap(addr); + break; + + case TRAPGT: + if(!(SR & (N_MASK | Z_MASK))) + execute_trap(addr); + break; + + case TRAPLT: + if (SR & N_MASK) + execute_trap(addr); + break; + + case TRAPGE: + if (!(SR & N_MASK)) + execute_trap(addr); + break; + + case TRAPSE: + if (SR & (C_MASK | Z_MASK)) + execute_trap(addr); + break; + + case TRAPHT: + if (!(SR & (C_MASK | Z_MASK))) + execute_trap(addr); + break; + + case TRAPST: + if (SR & C_MASK) + execute_trap(addr); + break; + + case TRAPHE: + if (!(SR & C_MASK)) + execute_trap(addr); + break; + + case TRAPE: + if (SR & Z_MASK) + execute_trap(addr); + break; + + case TRAPNE: + if (!(SR & Z_MASK)) + execute_trap(addr); + break; + + case TRAPV: + if (SR & V_MASK) + execute_trap(addr); + break; + + case TRAP: execute_trap(addr); + break; } m_icount -= m_clock_cycles_1; @@ -1466,7 +1515,7 @@ void hyperstone_device::execute_run() m_instruction_length = (1<<19); - switch (m_op >> 8) + switch ((OP >> 8) & 0x00ff) { case 0x00: hyperstone_chk<GLOBAL, GLOBAL>(); break; case 0x01: hyperstone_chk<GLOBAL, LOCAL>(); break; @@ -1680,8 +1729,8 @@ void hyperstone_device::execute_run() case 0xd1: hyperstone_ldwr<LOCAL>(); break; case 0xd2: hyperstone_lddr<GLOBAL>(); break; case 0xd3: hyperstone_lddr<LOCAL>(); break; - case 0xd4: hyperstone_ldwp<GLOBAL>(); break; - case 0xd5: hyperstone_ldwp<LOCAL>(); break; + case 0xd4: hypesrtone_ldwp<GLOBAL>(); break; + case 0xd5: hypesrtone_ldwp<LOCAL>(); break; case 0xd6: hyperstone_lddp<GLOBAL>(); break; case 0xd7: hyperstone_lddp<LOCAL>(); break; case 0xd8: hyperstone_stwr<GLOBAL>(); break; @@ -1692,35 +1741,35 @@ void hyperstone_device::execute_run() case 0xdd: hyperstone_stwp<LOCAL>(); break; case 0xde: hyperstone_stdp<GLOBAL>(); break; case 0xdf: hyperstone_stdp<LOCAL>(); break; - case 0xe0: hyperstone_db<COND_V, IS_SET>(); break; - case 0xe1: hyperstone_db<COND_V, IS_CLEAR>(); break; - case 0xe2: hyperstone_db<COND_Z, IS_SET>(); break; - case 0xe3: hyperstone_db<COND_Z, IS_CLEAR>(); break; - case 0xe4: hyperstone_db<COND_C, IS_SET>(); break; - case 0xe5: hyperstone_db<COND_C, IS_CLEAR>(); break; - case 0xe6: hyperstone_db<COND_CZ, IS_SET>(); break; - case 0xe7: hyperstone_db<COND_CZ, IS_CLEAR>(); break; - case 0xe8: hyperstone_db<COND_N, IS_SET>(); break; - case 0xe9: hyperstone_db<COND_N, IS_CLEAR>(); break; - case 0xea: hyperstone_db<COND_NZ, IS_SET>(); break; - case 0xeb: hyperstone_db<COND_NZ, IS_CLEAR>(); break; + case 0xe0: hyperstone_dbv(); break; + case 0xe1: hyperstone_dbnv(); break; + case 0xe2: hyperstone_dbe(); break; + case 0xe3: hyperstone_dbne(); break; + case 0xe4: hyperstone_dbc(); break; + case 0xe5: hyperstone_dbnc(); break; + case 0xe6: hyperstone_dbse(); break; + case 0xe7: hyperstone_dbht(); break; + case 0xe8: hyperstone_dbn(); break; + case 0xe9: hyperstone_dbnn(); break; + case 0xea: hyperstone_dble(); break; + case 0xeb: hyperstone_dbgt(); break; case 0xec: hyperstone_dbr(); break; case 0xed: hyperstone_frame(); break; - case 0xee: hyperstone_call<GLOBAL>(); break; - case 0xef: hyperstone_call<LOCAL>(); break; - case 0xf0: hyperstone_b<COND_V, IS_SET>(); break; - case 0xf1: hyperstone_b<COND_V, IS_CLEAR>(); break; - case 0xf2: hyperstone_b<COND_Z, IS_SET>(); break; - case 0xf3: hyperstone_b<COND_Z, IS_CLEAR>(); break; - case 0xf4: hyperstone_b<COND_C, IS_SET>(); break; - case 0xf5: hyperstone_b<COND_C, IS_CLEAR>(); break; - case 0xf6: hyperstone_b<COND_CZ, IS_SET>(); break; - case 0xf7: hyperstone_b<COND_CZ, IS_CLEAR>(); break; - case 0xf8: hyperstone_b<COND_N, IS_SET>(); break; - case 0xf9: hyperstone_b<COND_N, IS_CLEAR>(); break; - case 0xfa: hyperstone_b<COND_NZ, IS_SET>(); break; - case 0xfb: hyperstone_b<COND_NZ, IS_CLEAR>(); break; - case 0xfc: hyperstone_br(); break; + case 0xee: hyperstone_call_global(); break; + case 0xef: hyperstone_call_local(); break; + case 0xf0: hyperstone_bv(); break; + case 0xf1: hyperstone_bnv(); break; + case 0xf2: hyperstone_be(); break; + case 0xf3: hyperstone_bne(); break; + case 0xf4: hyperstone_bc(); break; + case 0xf5: hyperstone_bnc(); break; + case 0xf6: hyperstone_bse(); break; + case 0xf7: hyperstone_bht(); break; + case 0xf8: hyperstone_bn(); break; + case 0xf9: hyperstone_bnn(); break; + case 0xfa: hyperstone_ble(); break; + case 0xfb: hyperstone_bgt(); break; + case 0xfc: execute_br(); break; case 0xfd: hyperstone_trap(); break; case 0xfe: hyperstone_trap(); break; case 0xff: hyperstone_trap(); break; |