diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index f110dcdfef7..0dcc3945d93 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -492,6 +492,7 @@ void hyperstone_device::update_timer_prescale() m_clck_scale = (TPR >> 26) & m_clock_scale_mask; m_clock_cycles_1 = 1 << m_clck_scale; m_clock_cycles_2 = 2 << m_clck_scale; + m_clock_cycles_3 = 3 << m_clck_scale; 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; @@ -1608,7 +1609,7 @@ void hyperstone_device::device_reset() void hyperstone_device::device_stop() { -#if 1 +#if 0 int indices[256]; for (int i = 0; i < 256; i++) { @@ -1784,27 +1785,6 @@ void hyperstone_device::hyperstone_subc(regs_decode &decode) m_icount -= m_clock_cycles_1; } -void hyperstone_device::hyperstone_sub(regs_decode &decode) -{ - if (SRC_IS_SR) - SREG = GET_C; - - uint64_t tmp = (uint64_t)(DREG) - (uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,DREG,tmp); - - DREG = DREG - SREG; - SET_DREG(DREG); - - if (DST_IS_PC) - SR &= ~M_MASK; - - SET_Z(DREG == 0 ? 1 : 0); - SET_N(SIGN_BIT(DREG)); - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_subs(regs_decode &decode) { if (SRC_IS_SR) @@ -1834,63 +1814,6 @@ void hyperstone_device::hyperstone_subs(regs_decode &decode) } } -void hyperstone_device::hyperstone_addc(regs_decode &decode) -{ - uint64_t tmp; - if (SRC_IS_SR) - { - tmp = (uint64_t)(DREG) + (uint64_t)(GET_C); - CHECK_VADD(DREG,GET_C,tmp); - } - else - { - tmp = (uint64_t)(SREG) + (uint64_t)(DREG) + (uint64_t)(GET_C); - - //CHECK! - //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1); - //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C) - /* check if DREG + GET_C overflows */ -// if( (DREG == 0x7FFFFFFF) && (GET_C == 1) ) -// SET_V(1); -// else -// CHECK_VADD(SREG,DREG + GET_C,tmp); - - CHECK_VADD3(SREG,DREG,GET_C,tmp); - } - - if (SRC_IS_SR) - DREG = DREG + GET_C; - else - DREG = SREG + DREG + GET_C; - - CHECK_C(tmp); - - SET_DREG(DREG); - SET_Z(GET_Z & (DREG == 0 ? 1 : 0)); - SET_N(SIGN_BIT(DREG)); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_neg(regs_decode &decode) -{ - if (SRC_IS_SR) - SREG = GET_C; - - uint64_t tmp = -(uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,0,tmp); - - DREG = -SREG; - - SET_DREG(DREG); - - SET_Z(DREG == 0 ? 1 : 0); - SET_N(SIGN_BIT(DREG)); - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_negs(regs_decode &decode) { if (SRC_IS_SR) @@ -1920,37 +1843,6 @@ void hyperstone_device::hyperstone_negs(regs_decode &decode) } } -void hyperstone_device::hyperstone_addsi(regs_decode &decode) -{ - int32_t imm; - if (N_VALUE) - imm = EXTRA_S; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - int64_t tmp = (int64_t)(imm) + (int64_t)((int32_t)(DREG)); - CHECK_VADD(imm,DREG,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - int32_t res = imm + (int32_t)(DREG); - - SET_DREG(res); - - SET_Z(res == 0 ? 1 : 0); - SET_N(SIGN_BIT(res)); - - m_icount -= m_clock_cycles_1; - - if (SR & V_MASK) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - void hyperstone_device::hyperstone_sardi() { check_delay_PC(); @@ -2053,241 +1945,6 @@ void hyperstone_device::hyperstone_shl() m_icount -= m_clock_cycles_1; } -void hyperstone_device::hyperstone_testlz() -{ - check_delay_PC(); - - uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) % 64]; - uint32_t zeros = 0; - for (uint32_t mask = 0x80000000; mask != 0; mask >>= 1 ) - { - if (sreg & mask) - break; - else - zeros++; - } - - m_local_regs[(DST_CODE + GET_FP) % 64] = zeros; - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_stxx2(regs_decode &decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - if( DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC)); - } - else - { - switch( decode.sub_type ) - { - case 0: // STBS.N - - /* TODO: missing trap on range error */ - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 1: // STBU.N - - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 2: - - WRITE_HW(DREG, SREG & 0xffff); - SET_DREG(DREG + (EXTRA_S & ~1)); - - /* - if( EXTRA_S & 1 ) // STHS.N - { - // TODO: missing trap on range error - } - else // STHU.N - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STW.S - { - if(DREG < SP) - WRITE_W(DREG, SREG); - else - { - if(((DREG & 0xfc) >> 2) == ((decode.src + GET_FP) % 64) && (OP & 0x100)) - DEBUG_PRINTF(("STW.S denoted the same local register @ %08X\n",PPC)); - - m_local_regs[(DREG & 0xfc) >> 2] = SREG; - } - - SET_DREG(DREG + (EXTRA_S & ~3)); - - m_icount -= m_clock_cycles_2; // extra cycles - - } - else if( (EXTRA_S & 3) == 2 ) // Reserved - { - DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC)); - } - else if( (EXTRA_S & 3) == 1 ) // STD.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - - if( decode.same_srcf_dst ) - WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented - else - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sari(regs_decode &decode) -{ - uint32_t val = DREG; - uint32_t sign_bit = val & 0x80000000; - - const uint32_t n = N_VALUE; - - SR &= ~(C_MASK | Z_MASK | N_MASK); - if (n) - SET_C((val >> (n - 1)) & 1); - - val >>= n; - - if (sign_bit) - for (int i = 0; i < n; i++) - val |= (0x80000000 >> i); - - SET_DREG(val); - if (val == 0) - SR |= Z_MASK; - if (SIGN_BIT(val)) - SR |= N_MASK; - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mulu(regs_decode &decode) -{ - uint32_t low_order, high_order; - uint64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); - } - else - { - double_word = (uint64_t)SREG *(uint64_t)DREG; - - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if(SREG <= 0xffff && DREG <= 0xffff) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_muls(regs_decode &decode) -{ - uint32_t low_order, high_order; - int64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); - } - else - { - double_word = (int64_t)(int32_t)(SREG) * (int64_t)(int32_t)(DREG); - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_mul(regs_decode &decode) -{ - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); - } - else - { - const uint32_t single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken - - SET_DREG(single_word); - - SR &= ~(Z_MASK | N_MASK); - if (single_word == 0) - SR |= Z_MASK; - if (SIGN_BIT(single_word)) - SR |= N_MASK; - } - - if ((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= 3 << m_clck_scale; - else - m_icount -= 5 << m_clck_scale; -} - -void hyperstone_device::hyperstone_stdr(regs_decode &decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - WRITE_W(DREG, SREG); - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_2; -} - void hyperstone_device::hyperstone_trap() { check_delay_PC(); @@ -2435,7 +2092,7 @@ void hyperstone_device::execute_run() m_instruction_length = (1<<19); #if 1 - m_opcode_hits[(OP >> 8) & 0x00ff]++; + //m_opcode_hits[(OP >> 8) & 0x00ff]++; /* execute opcode */ switch ((OP >> 8) & 0x00ff) { @@ -2511,25 +2168,25 @@ void hyperstone_device::execute_run() case 0x45: hyperstone_not_global_local(); break; case 0x46: hyperstone_not_local_global(); break; case 0x47: hyperstone_not_local_local(); break; - case 0x48: op48(); break; - case 0x49: op49(); break; + case 0x48: hyperstone_sub_global_global(); break; + case 0x49: hyperstone_sub_global_local(); break; case 0x4a: hyperstone_sub_local_global(); break; case 0x4b: hyperstone_sub_local_local(); break; case 0x4c: op4c(); break; case 0x4d: op4d(); break; case 0x4e: op4e(); break; case 0x4f: op4f(); break; - case 0x50: op50(); break; - case 0x51: op51(); break; + case 0x50: hyperstone_addc_global_global(); break; + case 0x51: hyperstone_addc_global_local(); break; case 0x52: hyperstone_addc_local_global(); break; case 0x53: hyperstone_addc_local_local(); break; case 0x54: hyperstone_and_global_global(); break; case 0x55: hyperstone_and_global_local(); break; case 0x56: hyperstone_and_local_global(); break; case 0x57: hyperstone_and_local_local(); break; - case 0x58: op58(); break; - case 0x59: op59(); break; - case 0x5a: op5a(); break; + case 0x58: hyperstone_neg_global_global(); break; + case 0x59: hyperstone_neg_global_local(); break; + case 0x5a: hyperstone_neg_local_global(); break; case 0x5b: hyperstone_neg_local_local(); break; case 0x5c: op5c(); break; case 0x5d: op5d(); break; @@ -2547,10 +2204,10 @@ void hyperstone_device::execute_run() case 0x69: hyperstone_addi_global_limm(); break; case 0x6a: hyperstone_addi_local_simm(); break; case 0x6b: hyperstone_addi_local_limm(); break; - case 0x6c: op6c(); break; - case 0x6d: op6d(); break; - case 0x6e: op6e(); break; - case 0x6f: op6f(); break; + case 0x6c: hyperstone_addsi_global_simm(); break; + case 0x6d: hyperstone_addsi_global_limm(); break; + case 0x6e: hyperstone_addsi_local_simm(); break; + case 0x6f: hyperstone_addsi_local_limm(); break; case 0x70: hyperstone_cmpbi_global_simm(); break; case 0x71: hyperstone_cmpbi_global_limm(); break; case 0x72: hyperstone_cmpbi_local_simm(); break; @@ -2596,15 +2253,15 @@ void hyperstone_device::execute_run() case 0x9a: hyperstone_stxx1_local_global(); break; case 0x9b: hyperstone_stxx1_local_local(); break; case 0x9c: hyperstone_stxx2_global_global(); break; - case 0x9d: op9d(); break; + case 0x9d: hyperstone_stxx2_global_local(); break; case 0x9e: hyperstone_stxx2_local_global(); break; case 0x9f: hyperstone_stxx2_local_local(); break; case 0xa0: hyperstone_shri_global(); break; case 0xa1: hyperstone_shri_global(); break; case 0xa2: hyperstone_shri_local(); break; case 0xa3: hyperstone_shri_local(); break; - case 0xa4: opa4(); break; - case 0xa5: opa5(); break; + case 0xa4: hyperstone_sari_global(); break; + case 0xa5: hyperstone_sari_global(); break; case 0xa6: hyperstone_sari_local(); break; case 0xa7: hyperstone_sari_local(); break; case 0xa8: hyperstone_shli_global(); break; @@ -2615,21 +2272,21 @@ void hyperstone_device::execute_run() case 0xad: DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP)); break; case 0xae: DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP)); break; case 0xaf: DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP)); break; - case 0xb0: opb0(); break; - case 0xb1: opb1(); break; - case 0xb2: opb2(); break; + case 0xb0: hyperstone_mulu_global_global(); break; + case 0xb1: hyperstone_mulu_global_local(); break; + case 0xb2: hyperstone_mulu_local_global(); break; case 0xb3: hyperstone_mulu_local_local(); break; - case 0xb4: opb4(); break; - case 0xb5: opb5(); break; - case 0xb6: opb6(); break; + case 0xb4: hyperstone_muls_global_global(); break; + case 0xb5: hyperstone_muls_global_local(); break; + case 0xb6: hyperstone_muls_local_global(); break; case 0xb7: hyperstone_muls_local_local(); break; case 0xb8: hyperstone_set_global(); break; case 0xb9: hyperstone_set_global(); break; case 0xba: hyperstone_set_local(); break; case 0xbb: hyperstone_set_local(); break; - case 0xbc: opbc(); break; - case 0xbd: opbd(); break; - case 0xbe: opbe(); break; + case 0xbc: hyperstone_mul_global_global(); break; + case 0xbd: hyperstone_mul_global_local(); break; + case 0xbe: hyperstone_mul_local_global(); break; case 0xbf: hyperstone_mul_local_local(); break; case 0xc0: execute_software(); break; // fadd case 0xc1: execute_software(); break; // faddd @@ -2657,8 +2314,8 @@ void hyperstone_device::execute_run() case 0xd7: hyperstone_lddp_local_local(); break; case 0xd8: hyperstone_stwr_global(); break; case 0xd9: hyperstone_stwr_local(); break; - case 0xda: opda(); break; - case 0xdb: opdb(); break; + case 0xda: hyperstone_stdr_global(); break; + case 0xdb: hyperstone_stdr_local(); break; case 0xdc: hyperstone_stwp_global_local(); break; case 0xdd: hyperstone_stwp_local_local(); break; case 0xde: hyperstone_stdp_global_local(); break; diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index be09448a379..05793f4e1f2 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -145,6 +145,7 @@ protected: uint8_t m_clck_scale; uint8_t m_clock_cycles_1; uint8_t m_clock_cycles_2; + uint8_t m_clock_cycles_3; uint8_t m_clock_cycles_4; uint8_t m_clock_cycles_6; @@ -271,14 +272,18 @@ private: void hyperstone_cmpb_local_global(); void hyperstone_cmpb_local_local(); void hyperstone_subc(regs_decode &decode); - void hyperstone_sub(regs_decode &decode); + void hyperstone_sub_global_global(); + void hyperstone_sub_global_local(); void hyperstone_sub_local_global(); void hyperstone_sub_local_local(); void hyperstone_subs(regs_decode &decode); - void hyperstone_addc(regs_decode &decode); + void hyperstone_addc_global_global(); + void hyperstone_addc_global_local(); void hyperstone_addc_local_global(); void hyperstone_addc_local_local(); - void hyperstone_neg(regs_decode &decode); + void hyperstone_neg_global_global(); + void hyperstone_neg_global_local(); + void hyperstone_neg_local_global(); void hyperstone_neg_local_local(); void hyperstone_negs(regs_decode &decode); void hyperstone_and_global_global(); @@ -315,7 +320,10 @@ private: void hyperstone_addi_global_limm(); void hyperstone_addi_local_simm(); void hyperstone_addi_local_limm(); - void hyperstone_addsi(regs_decode &decode); + void hyperstone_addsi_global_simm(); + void hyperstone_addsi_global_limm(); + void hyperstone_addsi_local_simm(); + void hyperstone_addsi_local_limm(); void hyperstone_cmpbi_global_simm(); void hyperstone_cmpbi_global_limm(); void hyperstone_cmpbi_local_simm(); @@ -335,14 +343,18 @@ private: void hyperstone_shrdi(); void hyperstone_shrd(); void hyperstone_shr(); + void hyperstone_shri_global(); + void hyperstone_shri_local(); void hyperstone_sardi(); void hyperstone_sard(); void hyperstone_sar(); - void hyperstone_sari(regs_decode &decode); + void hyperstone_sari_global(); void hyperstone_sari_local(); void hyperstone_shldi(); void hyperstone_shld(); void hyperstone_shl(); + void hyperstone_shli_global(); + void hyperstone_shli_local(); void hyperstone_testlz(); void hyperstone_rol(); void hyperstone_ldxx1_global_global(); @@ -357,20 +369,25 @@ private: void hyperstone_stxx1_global_local(); void hyperstone_stxx1_local_global(); void hyperstone_stxx1_local_local(); - void hyperstone_stxx2(regs_decode &decode); void hyperstone_stxx2_global_global(); + void hyperstone_stxx2_global_local(); void hyperstone_stxx2_local_global(); void hyperstone_stxx2_local_local(); - void hyperstone_mulu(regs_decode &decode); + void hyperstone_mulu_global_global(); + void hyperstone_mulu_global_local(); + void hyperstone_mulu_local_global(); void hyperstone_mulu_local_local(); - void hyperstone_muls(regs_decode &decode); + void hyperstone_muls_global_global(); + void hyperstone_muls_global_local(); + void hyperstone_muls_local_global(); void hyperstone_muls_local_local(); - void hyperstone_mul(regs_decode &decode); + void hyperstone_mul_global_global(); + void hyperstone_mul_global_local(); + void hyperstone_mul_local_global(); void hyperstone_mul_local_local(); void hyperstone_set_global(); void hyperstone_set_local(); - void hyperstone_ldwr(regs_decode &decode); void hyperstone_ldwr_global_local(); void hyperstone_ldwr_local_local(); void hyperstone_lddr_global_local(); @@ -382,7 +399,8 @@ private: void hyperstone_stwr_global(); void hyperstone_stwr_local(); - void hyperstone_stdr(regs_decode &decode); + void hyperstone_stdr_global(); + void hyperstone_stdr_local(); void hyperstone_stwp_global_local(); void hyperstone_stwp_local_local(); void hyperstone_stdp_global_local(); @@ -420,14 +438,8 @@ private: void hyperstone_bgt(); void hyperstone_trap(); - void hyperstone_do(regs_decode &decode); void hyperstone_extend(); - void hyperstone_shli_global(); - void hyperstone_shli_local(); - void hyperstone_shri_global(); - void hyperstone_shri_local(); - int32_t decode_pcrel(); void ignore_pcrel(); @@ -447,38 +459,10 @@ private: bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); #endif - - - - - - void op2c(); void op2d(); void op2e(); void op2f(); - - - void op40(); void op41(); void op42(); void op43(); - void op48(); void op49(); void op4c(); void op4d(); void op4e(); void op4f(); - void op50(); void op51(); - void op58(); void op59(); void op5a(); void op5c(); void op5d(); void op5e(); void op5f(); - - void op6c(); void op6d(); void op6e(); void op6f(); - - - - - - void op9d(); - void opa4(); void opa5(); - - void opb0(); void opb1(); void opb2(); void opb4(); void opb5(); void opb6(); - void opbc(); void opbd(); void opbe(); - - - - void opda(); void opdb(); - - - - + void op2c(); void op2d(); void op2e(); void op2f(); // addc + void op40(); void op41(); void op42(); void op43(); // subc + void op4c(); void op4d(); void op4e(); void op4f(); // subs + void op5c(); void op5d(); void op5e(); void op5f(); // negs #if 0 void generate_op00(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op01(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); diff --git a/src/devices/cpu/e132xs/e132xsop.hxx b/src/devices/cpu/e132xs/e132xsop.hxx index a3d48a36771..57f4ad5e691 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -889,9 +889,7 @@ void hyperstone_device::hyperstone_sum_global_global() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; const uint32_t dreg = sreg + extra_u; @@ -916,9 +914,7 @@ void hyperstone_device::hyperstone_sum_global_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; const uint32_t dreg = sreg + extra_u; @@ -943,9 +939,7 @@ void hyperstone_device::hyperstone_sum_local_global() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; const uint32_t dreg = sreg + extra_u; @@ -972,9 +966,7 @@ void hyperstone_device::hyperstone_sum_local_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; const uint32_t dreg = sreg + extra_u; @@ -997,9 +989,7 @@ void hyperstone_device::hyperstone_sums_global_global() const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : m_global_regs[src_code]; const int64_t tmp = (int64_t)sreg + (int64_t)extra_s; - - if ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; //#if SETCARRYS // CHECK_C(tmp); @@ -1026,9 +1016,7 @@ void hyperstone_device::hyperstone_sums_global_local() const int32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; const int64_t tmp = (int64_t)sreg + (int64_t)extra_s; - - if ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; //#if SETCARRYS // CHECK_C(tmp); @@ -1056,9 +1044,7 @@ void hyperstone_device::hyperstone_sums_local_global() const uint32_t src_code = SRC_CODE; const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : m_global_regs[src_code]; const int64_t tmp = (int64_t)sreg + (int64_t)extra_s; - - if ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; //#if SETCARRYS // CHECK_C(tmp); @@ -1086,9 +1072,7 @@ void hyperstone_device::hyperstone_sums_local_local() const uint32_t fp = GET_FP; const int32_t sreg = m_local_regs[(SRC_CODE + fp) & 0x3f]; const int64_t tmp = (int64_t)sreg + (int64_t)extra_s; - - if ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; //#if SETCARRYS // CHECK_C(tmp); @@ -1116,7 +1100,10 @@ void hyperstone_device::hyperstone_cmp_global_global() const uint32_t sreg = ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]); const uint32_t dreg = m_global_regs[DST_CODE]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; if (dreg == sreg) SR |= Z_MASK; @@ -1124,11 +1111,6 @@ void hyperstone_device::hyperstone_cmp_global_global() if ((int32_t)dreg < (int32_t)sreg) SR |= N_MASK; - const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; - if (dreg < sreg) SR |= C_MASK; @@ -1142,7 +1124,10 @@ void hyperstone_device::hyperstone_cmp_global_local() const uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; const uint32_t dreg = m_global_regs[DST_CODE]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; if (dreg == sreg) SR |= Z_MASK; @@ -1150,11 +1135,6 @@ void hyperstone_device::hyperstone_cmp_global_local() if ((int32_t)dreg < (int32_t)sreg) SR |= N_MASK; - const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; - if (dreg < sreg) SR |= C_MASK; @@ -1169,7 +1149,10 @@ void hyperstone_device::hyperstone_cmp_local_global() const uint32_t sreg = ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]); const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; if (dreg == sreg) SR |= Z_MASK; @@ -1177,11 +1160,6 @@ void hyperstone_device::hyperstone_cmp_local_global() if ((int32_t)dreg < (int32_t)sreg) SR |= N_MASK; - const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; - if (dreg < sreg) SR |= C_MASK; @@ -1196,17 +1174,17 @@ void hyperstone_device::hyperstone_cmp_local_local() const uint32_t sreg = m_local_regs[(SRC_CODE + fp) & 0x3f]; const uint32_t dreg = m_local_regs[(DST_CODE + fp) & 0x3f]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; + if (dreg == sreg) SR |= Z_MASK; if ((int32_t)dreg < (int32_t)sreg) SR |= N_MASK; - const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; - if (dreg < sreg) SR |= C_MASK; @@ -1333,9 +1311,7 @@ void hyperstone_device::hyperstone_add_global_global() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += sreg; set_global_register(dst_code, dreg); @@ -1364,9 +1340,7 @@ void hyperstone_device::hyperstone_add_global_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += sreg; set_global_register(dst_code, dreg); @@ -1398,9 +1372,7 @@ void hyperstone_device::hyperstone_add_local_global() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += sreg; m_local_regs[dst_code] = dreg; @@ -1427,9 +1399,7 @@ void hyperstone_device::hyperstone_add_local_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += sreg; m_local_regs[dst_code] = dreg; @@ -1919,38 +1889,61 @@ void hyperstone_device::hyperstone_not_local_local() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op48() +void hyperstone_device::hyperstone_sub_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : m_global_regs[src_code]; + const uint32_t dst_code = DST_CODE; + uint32_t dreg = m_global_regs[dst_code]; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - hyperstone_sub(decode); - printf("0x48, sub global,global\n"); + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + SR |= (tmp & 0x100000000L) >> 32; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; + + dreg -= sreg; + set_global_register(dst_code, dreg); + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op49() +void hyperstone_device::hyperstone_sub_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + const uint32_t sreg = m_global_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dst_code = DST_CODE; + uint32_t dreg = m_global_regs[dst_code]; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + const uint64_t tmp = (uint64_t)dreg - (uint64_t)sreg; - hyperstone_sub(decode); - printf("0x49, sub global,local\n"); + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + SR |= (tmp & 0x100000000L) >> 32; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; + + dreg -= sreg; + set_global_register(dst_code, dreg); + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } void hyperstone_device::hyperstone_sub_local_global() @@ -1967,9 +1960,7 @@ void hyperstone_device::hyperstone_sub_local_global() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; dreg -= sreg; m_local_regs[dst_code] = dreg; @@ -1995,9 +1986,7 @@ void hyperstone_device::hyperstone_sub_local_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; dreg -= sreg; m_local_regs[dst_code] = dreg; @@ -2079,38 +2068,74 @@ void hyperstone_device::op4f() -void hyperstone_device::op50() +void hyperstone_device::hyperstone_addc_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = m_global_regs[src_code]; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + const uint32_t dst_code = DST_CODE; + uint32_t dreg = m_global_regs[dst_code]; - hyperstone_addc(decode); - printf("0x50, addc global,global\n"); + const bool old_z = (SR & Z_MASK) != 0; + const uint32_t c = SR & C_MASK; + + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + uint64_t tmp; + if (src_code == SR_REGISTER) + { + tmp = (uint64_t)dreg + (uint64_t)c; + SR |= ((dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; + dreg += c; + } + else + { + tmp = (uint64_t)sreg + (uint64_t)dreg + (uint64_t)c; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; + dreg += sreg + c; + } + + SR |= (tmp & 0x100000000L) >> 32; + + set_global_register(dst_code, dreg); + + if (dreg == 0 && old_z) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op51() +void hyperstone_device::hyperstone_addc_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + const uint32_t src_code = (SRC_CODE + GET_FP) & 0x3f; + const uint32_t sreg = m_local_regs[src_code]; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + const uint32_t dst_code = DST_CODE; + uint32_t dreg = m_global_regs[dst_code]; - hyperstone_addc(decode); - printf("0x51, addc global,local\n"); + const bool old_z = (SR & Z_MASK) != 0; + const uint32_t c = SR & C_MASK; + const uint64_t tmp = (uint64_t)sreg + (uint64_t)dreg + (uint64_t)c; + + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + SR |= (tmp & 0x100000000L) >> 32; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; + + dreg += sreg + c; + + set_global_register(dst_code, dreg); + + if (dreg == 0 && old_z) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } void hyperstone_device::hyperstone_addc_local_global() @@ -2132,19 +2157,13 @@ void hyperstone_device::hyperstone_addc_local_global() if (src_code == SR_REGISTER) { tmp = (uint64_t)dreg + (uint64_t)c; - - if ((dreg ^ tmp) & (c ^ tmp) & 0x80000000) - SR |= V_MASK; - + SR |= ((dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; dreg += c; } else { tmp = (uint64_t)sreg + (uint64_t)dreg + (uint64_t)c; - - if ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) - SR |= V_MASK; - + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; dreg += sreg + c; } @@ -2175,9 +2194,7 @@ void hyperstone_device::hyperstone_addc_local_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; dreg += sreg + c; @@ -2255,55 +2272,73 @@ void hyperstone_device::hyperstone_and_local_local() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op58() +void hyperstone_device::hyperstone_neg_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : m_global_regs[src_code]; + const uint64_t tmp = -(uint64_t)sreg; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (tmp & 0x100000000L) >> 32; + SR |= (tmp & sreg & 0x80000000) >> 28; - hyperstone_neg(decode); - printf("0x58, neg global,global\n"); + const uint32_t dreg = -sreg; + m_global_regs[DST_CODE] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op59() +void hyperstone_device::hyperstone_neg_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + const uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint64_t tmp = -(uint64_t)sreg; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - hyperstone_neg(decode); - printf("0x59, neg global,local\n"); + SR |= (tmp & 0x100000000L) >> 32; + SR |= (tmp & sreg & 0x80000000) >> 28; + + const uint32_t dreg = -sreg; + m_global_regs[DST_CODE] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op5a() +void hyperstone_device::hyperstone_neg_local_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : m_global_regs[src_code]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + const uint64_t tmp = -(uint64_t)sreg; - hyperstone_neg(decode); - printf("0x5a, neg local,global\n"); + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + SR |= (tmp & 0x100000000L) >> 32; + SR |= (tmp & sreg & 0x80000000) >> 28; + + const uint32_t dreg = -sreg; + m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } void hyperstone_device::hyperstone_neg_local_local() @@ -2318,9 +2353,7 @@ void hyperstone_device::hyperstone_neg_local_local() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); SR |= (tmp & 0x100000000L) >> 32; - - if (tmp & sreg & 0x80000000) - SR |= V_MASK; + SR |= (tmp & sreg & 0x80000000) >> 28; const uint32_t dreg = -sreg; m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; @@ -2412,8 +2445,7 @@ void hyperstone_device::hyperstone_cmpi_global_simm() SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; - if ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; if (dreg == imm) SR |= Z_MASK; @@ -2438,8 +2470,7 @@ void hyperstone_device::hyperstone_cmpi_global_limm() SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; - if ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; if (dreg == imm) SR |= Z_MASK; @@ -2463,8 +2494,7 @@ void hyperstone_device::hyperstone_cmpi_local_simm() SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; - if ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; if (dreg == imm) SR |= Z_MASK; @@ -2490,8 +2520,7 @@ void hyperstone_device::hyperstone_cmpi_local_limm() SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; - if ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) - SR |= V_MASK; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; if (dreg == imm) SR |= Z_MASK; @@ -2621,9 +2650,7 @@ void hyperstone_device::hyperstone_addi_global_simm() const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; SR |= (tmp & 0x100000000L) >> 32; - - if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += imm; set_global_register(dst_code, dreg); @@ -2657,9 +2684,7 @@ void hyperstone_device::hyperstone_addi_global_limm() const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; SR |= (tmp & 0x100000000L) >> 32; - - if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += imm; set_global_register(dst_code, dreg); @@ -2693,9 +2718,7 @@ void hyperstone_device::hyperstone_addi_local_simm() const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; SR |= (tmp & 0x100000000L) >> 32; - - if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += imm; m_local_regs[dst_code] = dreg; @@ -2723,9 +2746,7 @@ void hyperstone_device::hyperstone_addi_local_limm() const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; SR |= (tmp & 0x100000000L) >> 32; - - if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) - SR |= V_MASK; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; dreg += imm; m_local_regs[dst_code] = dreg; @@ -2737,66 +2758,158 @@ void hyperstone_device::hyperstone_addi_local_limm() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op6c() +void hyperstone_device::hyperstone_addsi_global_simm() { - regs_decode decode; - decode_immediate_u(decode); check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; + const uint32_t dst_code = DST_CODE; + const int32_t dreg = m_global_regs[dst_code]; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + int32_t imm; + if (N_OP_MASK) + imm = immediate_values[m_op & 0x0f]; + else + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); - hyperstone_addsi(decode); - printf("0x6c, addsi global,simm\n"); + SR &= ~(V_MASK | Z_MASK | N_MASK); + + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// CHECK_C(tmp); +//#endif + + const int32_t res = imm + (int32_t)dreg; + + set_global_register(dst_code, res); + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op6d() +void hyperstone_device::hyperstone_addsi_global_limm() { - regs_decode decode; - DECODE_IMMEDIATE_S(decode); - check_delay_PC(); - decode.dst = DST_CODE; + const uint32_t dst_code = DST_CODE; + const int32_t dreg = m_global_regs[dst_code]; - decode.dst_is_local = 0; + int32_t imm; + if (N_OP_MASK) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + ignore_immediate_s(); + check_delay_PC(); + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + } - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + SR &= ~(V_MASK | Z_MASK | N_MASK); - hyperstone_addsi(decode); - printf("0x6d, addsi global,limm\n"); + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// CHECK_C(tmp); +//#endif + + const int32_t res = imm + (int32_t)dreg; + + set_global_register(dst_code, res); + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op6e() +void hyperstone_device::hyperstone_addsi_local_simm() { - regs_decode decode; - decode_immediate_u(decode); check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const int32_t dreg = m_local_regs[dst_code]; - hyperstone_addsi(decode); - printf("0x6e, addsi local,simm\n"); + int32_t imm; + if (N_OP_MASK) + imm = immediate_values[m_op & 0x0f]; + else + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + + SR &= ~(V_MASK | Z_MASK | N_MASK); + + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// CHECK_C(tmp); +//#endif + + const int32_t res = imm + (int32_t)dreg; + + m_local_regs[dst_code] = res; + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op6f() +void hyperstone_device::hyperstone_addsi_local_limm() { - regs_decode decode; - DECODE_IMMEDIATE_S(decode); - check_delay_PC(); - decode.dst = DST_CODE; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const int32_t dreg = m_local_regs[dst_code]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + int32_t imm; + if (N_OP_MASK) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + ignore_immediate_s(); + check_delay_PC(); + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + } - hyperstone_addsi(decode); - printf("0x6f, addsi local,limm\n"); + SR &= ~(V_MASK | Z_MASK | N_MASK); + + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// CHECK_C(tmp); +//#endif + + const int32_t res = imm + (int32_t)dreg; + + m_local_regs[dst_code] = res; + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } @@ -3385,6 +3498,25 @@ void hyperstone_device::hyperstone_shldi() m_icount -= m_clock_cycles_2; } +void hyperstone_device::hyperstone_testlz() +{ + check_delay_PC(); + + uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) % 64]; + uint32_t zeros = 0; + for (uint32_t mask = 0x80000000; mask != 0; mask >>= 1 ) + { + if (sreg & mask) + break; + else + zeros++; + } + + m_local_regs[(DST_CODE + GET_FP) % 64] = zeros; + + m_icount -= m_clock_cycles_2; +} + void hyperstone_device::hyperstone_rol() { check_delay_PC(); @@ -3429,7 +3561,7 @@ void hyperstone_device::hyperstone_ldxx1_global_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -3463,22 +3595,22 @@ void hyperstone_device::hyperstone_ldxx1_global_global() { switch (sub_type) { - case 0x0000: // LDBS.A + case 0: // LDBS.A m_global_regs[src_code] = (int32_t)(int8_t)READ_B(extra_s); break; - case 0x1000: // LDBU.A + case 1: // LDBU.A m_global_regs[src_code] = READ_B(extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.A m_global_regs[src_code] = (int32_t)(int16_t)READ_HW(extra_s); else // LDHU.A m_global_regs[src_code] = READ_HW(extra_s); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.A @@ -3506,22 +3638,22 @@ void hyperstone_device::hyperstone_ldxx1_global_global() const uint32_t dreg = m_global_regs[dst_code]; switch (sub_type) { - case 0x0000: // LDBS.D + case 0: // LDBS.D m_global_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); break; - case 0x1000: // LDBU.D + case 1: // LDBU.D m_global_regs[src_code] = READ_B(dreg + extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) m_global_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)); else m_global_regs[src_code] = READ_HW(dreg + (extra_s & ~1)); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.D @@ -3553,7 +3685,7 @@ void hyperstone_device::hyperstone_ldxx1_global_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -3585,22 +3717,22 @@ void hyperstone_device::hyperstone_ldxx1_global_local() { switch (sub_type) { - case 0x0000: // LDBS.A + case 0: // LDBS.A m_local_regs[src_code] = (int32_t)(int8_t)READ_B(extra_s); break; - case 0x1000: // LDBU.A + case 1: // LDBU.A m_local_regs[src_code] = READ_B(extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.A m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(extra_s); else // LDHU.A m_local_regs[src_code] = READ_HW(extra_s); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.A @@ -3628,22 +3760,22 @@ void hyperstone_device::hyperstone_ldxx1_global_local() const uint32_t dreg = m_global_regs[DST_CODE]; switch (sub_type) { - case 0x0000: // LDBS.D + case 0: // LDBS.D m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); break; - case 0x1000: // LDBU.D + case 1: // LDBU.D m_local_regs[src_code] = READ_B(dreg + extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)); else m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1)); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.D @@ -3675,7 +3807,7 @@ void hyperstone_device::hyperstone_ldxx1_local_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -3705,22 +3837,22 @@ void hyperstone_device::hyperstone_ldxx1_local_global() { switch (sub_type) { - case 0x0000: // LDBS.A + case 0: // LDBS.A set_global_register(SRC_CODE, (int32_t)(int8_t)READ_B(extra_s)); break; - case 0x1000: // LDBU.A + case 1: // LDBU.A set_global_register(SRC_CODE, READ_B(extra_s)); break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.A set_global_register(SRC_CODE, (int32_t)(int16_t)READ_HW(extra_s)); else // LDHU.A set_global_register(SRC_CODE, READ_HW(extra_s)); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.A @@ -3748,22 +3880,22 @@ void hyperstone_device::hyperstone_ldxx1_local_global() const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; switch (sub_type) { - case 0x0000: // LDBS.D + case 0: // LDBS.D set_global_register(SRC_CODE, (int32_t)(int8_t)READ_B(dreg + extra_s)); break; - case 0x1000: // LDBU.D + case 1: // LDBU.D set_global_register(SRC_CODE, READ_B(dreg + extra_s)); break; - case 0x2000: + case 2: if (extra_s & 1) set_global_register(SRC_CODE, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1))); else set_global_register(SRC_CODE, READ_HW(dreg + (extra_s & ~1))); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.D @@ -3795,7 +3927,7 @@ void hyperstone_device::hyperstone_ldxx1_local_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -3828,22 +3960,22 @@ void hyperstone_device::hyperstone_ldxx1_local_local() switch (sub_type) { - case 0x0000: // LDBS.D + case 0: // LDBS.D m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); break; - case 0x1000: // LDBU.D + case 1: // LDBU.D m_local_regs[src_code] = READ_B(dreg + extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)); else m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1)); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.D @@ -3874,7 +4006,7 @@ void hyperstone_device::hyperstone_ldxx2_global_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -3914,19 +4046,19 @@ void hyperstone_device::hyperstone_ldxx2_global_global() switch (sub_type) { - case 0x0000: // LDBS.N + case 0: // LDBS.N m_global_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); if (src_code != dst_code) m_global_regs[dst_code] += extra_s; break; - case 0x1000: // LDBU.N + case 1: // LDBU.N m_global_regs[src_code] = READ_B(dreg); if(src_code != dst_code) m_global_regs[dst_code] += extra_s; break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.N m_global_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); else // LDHU.N @@ -3936,7 +4068,7 @@ void hyperstone_device::hyperstone_ldxx2_global_global() m_global_regs[dst_code] += (extra_s & ~1); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.N @@ -3979,7 +4111,7 @@ void hyperstone_device::hyperstone_ldxx2_global_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4021,17 +4153,17 @@ void hyperstone_device::hyperstone_ldxx2_global_local() switch (sub_type) { - case 0x0000: // LDBS.N + case 0: // LDBS.N m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); set_global_register(dst_code, dreg + extra_s); break; - case 0x1000: // LDBU.N + case 1: // LDBU.N m_local_regs[src_code] = READ_B(dreg); set_global_register(dst_code, dreg + extra_s); break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.N m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); else // LDHU.N @@ -4039,7 +4171,7 @@ void hyperstone_device::hyperstone_ldxx2_global_local() set_global_register(dst_code, dreg + (extra_s & ~1)); break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.N @@ -4075,7 +4207,7 @@ void hyperstone_device::hyperstone_ldxx2_local_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4107,17 +4239,17 @@ void hyperstone_device::hyperstone_ldxx2_local_global() switch (sub_type) { - case 0x0000: // LDBS.N + case 0: // LDBS.N set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg)); m_local_regs[dst_code] += extra_s; break; - case 0x1000: // LDBU.N + case 1: // LDBU.N set_global_register(src_code, READ_B(dreg)); m_local_regs[dst_code] += extra_s; break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.N set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg)); else // LDHU.N @@ -4125,7 +4257,7 @@ void hyperstone_device::hyperstone_ldxx2_local_global() m_local_regs[dst_code] += extra_s & ~1; break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.N @@ -4161,7 +4293,7 @@ void hyperstone_device::hyperstone_ldxx2_local_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4196,17 +4328,17 @@ void hyperstone_device::hyperstone_ldxx2_local_local() switch (sub_type) { - case 0x0000: // LDBS.N + case 0: // LDBS.N m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); m_local_regs[dst_code] += extra_s; break; - case 0x1000: // LDBU.N + case 1: // LDBU.N m_local_regs[src_code] = READ_B(dreg); m_local_regs[dst_code] += extra_s; break; - case 0x2000: + case 2: if (extra_s & 1) // LDHS.N m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); else // LDHU.N @@ -4214,7 +4346,7 @@ void hyperstone_device::hyperstone_ldxx2_local_local() m_local_regs[dst_code] += extra_s & ~1; break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // LDW.N @@ -4250,7 +4382,7 @@ void hyperstone_device::hyperstone_stxx1_global_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4286,21 +4418,21 @@ void hyperstone_device::hyperstone_stxx1_global_global() { switch (sub_type) { - case 0x0000: // STBS.A + case 0: // STBS.A // TODO: missing trap on range error WRITE_B(extra_s, (uint8_t)sreg); break; - case 0x1000: // STBU.A + case 1: // STBU.A WRITE_B(extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.A, STHU.A + case 2: // STHS.A, STHU.A WRITE_HW(extra_s, (uint16_t)sreg); // TODO: missing trap on range error with STHS.A break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.A @@ -4329,21 +4461,21 @@ void hyperstone_device::hyperstone_stxx1_global_global() { switch (sub_type) { - case 0x0000: // STBS.D + case 0: // STBS.D // TODO: missing trap on range error WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x1000: // STBU.D + case 1: // STBU.D WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.D, STHU.D + case 2: // STHS.D, STHU.D WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); // TODO: missing trap on range error with STHS.D break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.D @@ -4377,7 +4509,7 @@ void hyperstone_device::hyperstone_stxx1_global_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4411,21 +4543,21 @@ void hyperstone_device::hyperstone_stxx1_global_local() { switch (sub_type) { - case 0x0000: // STBS.A + case 0: // STBS.A WRITE_B(extra_s, (uint8_t)sreg); // TODO: missing trap on range error break; - case 0x1000: // STBU.A + case 1: // STBU.A WRITE_B(extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.A & STHU.A + case 2: // STHS.A & STHU.A WRITE_HW(extra_s, (uint16_t)sreg); // TODO: missing trap on range error with STHS.A break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.A @@ -4453,21 +4585,21 @@ void hyperstone_device::hyperstone_stxx1_global_local() const uint32_t dreg = m_global_regs[dst_code]; switch (sub_type) { - case 0x0000: // STBS.D + case 0: // STBS.D WRITE_B(dreg + extra_s, (uint8_t)sreg); // TODO: missing trap on range error break; - case 0x1000: // STBU.D + case 1: // STBU.D WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.D & STHU.D + case 2: // STHS.D & STHU.D WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); // TODO: Missing trap on range error for STHS.D break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.D @@ -4499,7 +4631,7 @@ void hyperstone_device::hyperstone_stxx1_local_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4532,21 +4664,21 @@ void hyperstone_device::hyperstone_stxx1_local_global() switch (sub_type) { - case 0x0000: // STBS.D + case 0: // STBS.D /* TODO: missing trap on range error */ WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x1000: // STBU.D + case 1: // STBU.D WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.D, STHU.D + case 2: // STHS.D, STHU.D WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); // missing trap on range error with STHS.D break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.D @@ -4575,7 +4707,7 @@ void hyperstone_device::hyperstone_stxx1_local_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4607,21 +4739,21 @@ void hyperstone_device::hyperstone_stxx1_local_local() switch (sub_type) { - case 0x0000: // STBS.D + case 0: // STBS.D /* TODO: missing trap on range error */ WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x1000: // STBU.D + case 1: // STBU.D WRITE_B(dreg + extra_s, (uint8_t)sreg); break; - case 0x2000: // STHS.D, STHU.D + case 2: // STHS.D, STHU.D WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); // missing trap on range error with STHS.D break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.D @@ -4650,7 +4782,7 @@ void hyperstone_device::hyperstone_stxx2_global_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4690,24 +4822,24 @@ void hyperstone_device::hyperstone_stxx2_global_global() switch (sub_type) { - case 0x0000: // STBS.N + case 0: // STBS.N // TODO: missing trap on range error WRITE_B(dreg, (uint8_t)sreg); m_global_regs[dst_code] += extra_s; break; - case 0x1000: // STBU.N + case 1: // STBU.N WRITE_B(dreg, (uint8_t)sreg); m_global_regs[dst_code] += extra_s; break; - case 0x2000: // STHS.N, STHU.N + case 2: // STHS.N, STHU.N WRITE_HW(dreg, (uint16_t)sreg); m_global_regs[dst_code] += extra_s & ~1; // TODO: missing trap on range error with STHS.N break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.N @@ -4740,27 +4872,100 @@ void hyperstone_device::hyperstone_stxx2_global_global() } } -void hyperstone_device::op9d() // stxx2 global,local +void hyperstone_device::hyperstone_stxx2_global_local() { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC)); + m_icount -= m_clock_cycles_1; + return; + } - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_stxx2(decode); - //printf("0x9d, stxx2 global,local\n"); + const uint32_t src_code = (SRC_CODE + GET_FP) & 0x3f; + const uint32_t sreg = m_local_regs[src_code]; + const uint32_t sregf = m_local_regs[(src_code + 1) & 0x3f]; + const uint32_t dreg = m_global_regs[dst_code]; + + switch (sub_type) + { + case 0: // STBS.N + // TODO: missing trap on range error + WRITE_B(dreg, (uint8_t)sreg); + set_global_register(dst_code, dreg + extra_s); + break; + + case 1: // STBU.N + + WRITE_B(dreg, (uint8_t)sreg); + set_global_register(dst_code, dreg + extra_s); + break; + + case 2: // STHS.N, STHU.N + WRITE_HW(dreg, (uint16_t)sreg); + set_global_register(dst_code, dreg + (extra_s & ~1)); + // TODO: Missing trap on range error with STHS.N + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.N + WRITE_W(dreg, sreg); + set_global_register(dst_code, dreg + extra_s); + break; + case 1: // STD.N + WRITE_W(dreg, sreg); + WRITE_W(dreg + 4, sregf); + set_global_register(dst_code, dreg + (extra_s & ~1)); + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // Reserved + DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC)); + break; + case 3: // STW.S + if(dreg < SP) + WRITE_W(dreg, sreg); + else + m_local_regs[(dreg & 0xfc) >> 2] = sreg; + set_global_register(dst_code, dreg + (extra_s & ~3)); + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; } void hyperstone_device::hyperstone_stxx2_local_global() @@ -4768,7 +4973,7 @@ void hyperstone_device::hyperstone_stxx2_local_global() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4803,24 +5008,24 @@ void hyperstone_device::hyperstone_stxx2_local_global() switch (sub_type) { - case 0x0000: // STBS.N + case 0: // STBS.N // TODO: missing trap on range error WRITE_B(dreg, (uint8_t)sreg); m_local_regs[dst_code] += extra_s; break; - case 0x1000: // STBU.N + case 1: // STBU.N WRITE_B(dreg, (uint8_t)sreg); m_local_regs[dst_code] += extra_s; break; - case 0x2000: // STHS.N, STHU.N + case 2: // STHS.N, STHU.N WRITE_HW(dreg, (uint16_t)sreg); m_local_regs[dst_code] += extra_s & ~1; // TODO: missing trap on range error for STHS.N break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.N @@ -4856,7 +5061,7 @@ void hyperstone_device::hyperstone_stxx2_local_local() uint16_t next_1 = READ_OP(PC); PC += 2; - const uint16_t sub_type = next_1 & 0x3000; + const uint16_t sub_type = (next_1 & 0x3000) >> 12; uint32_t extra_s; if (next_1 & 0x8000) @@ -4888,24 +5093,24 @@ void hyperstone_device::hyperstone_stxx2_local_local() switch (sub_type) { - case 0x0000: // STBS.N + case 0: // STBS.N /* TODO: missing trap on range error */ WRITE_B(dreg, (uint8_t)sreg); m_local_regs[dst_code] += extra_s; break; - case 0x1000: // STBU.N + case 1: // STBU.N WRITE_B(dreg, (uint8_t)sreg); m_local_regs[dst_code] += extra_s; break; - case 0x2000: + case 2: WRITE_HW(dreg, (uint16_t)sreg); m_local_regs[dst_code] += extra_s & ~1; // Missing trap on range error with STHS.N break; - case 0x3000: + case 3: switch (extra_s & 3) { case 0: // STW.N @@ -4989,34 +5194,33 @@ void hyperstone_device::hyperstone_shri_local() m_icount -= m_clock_cycles_1; } -void hyperstone_device::opa4() +void hyperstone_device::hyperstone_sari_global() { - regs_decode decode; check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; + const uint32_t dst_code = DST_CODE; + uint32_t val = m_global_regs[dst_code]; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t n = N_VALUE; - hyperstone_sari(decode); - printf("0xa4, sari\n"); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); + if (n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opa5() -{ - regs_decode decode; - check_delay_PC(); - decode.dst = DST_CODE; + uint32_t sign_bit = val & 0x80000000; + val >>= n; - decode.dst_is_local = 0; + if (sign_bit) + val |= 0xffffffff << (32 - n); + } - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + set_global_register(dst_code, val); + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); - hyperstone_sari(decode); - printf("0xa5, sari\n"); + m_icount -= m_clock_cycles_1; } void hyperstone_device::hyperstone_sari_local() @@ -5099,70 +5303,104 @@ void hyperstone_device::hyperstone_shli_local() -void hyperstone_device::opb0() +void hyperstone_device::hyperstone_mulu_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (src_code < 2 || dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == (DST_CODE + 1)); - decode.same_srcf_dst = ((SRC_CODE + 1) == DST_CODE); - hyperstone_mulu(decode); - printf("0xb0, mulu global,global\n"); + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t sreg = m_global_regs[src_code]; + const uint64_t double_word = (uint64_t)sreg *(uint64_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + set_global_register(dst_code, high_order); + set_global_register(dst_code + 1, (uint32_t)double_word); + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if(sreg <= 0xffff && dreg <= 0xffff) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opb1() +void hyperstone_device::hyperstone_mulu_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; + const uint32_t src_code = (SRC_CODE + GET_FP) & 0x3f; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_mulu(decode); - printf("0xb1, mulu global,local\n"); + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t sreg = m_local_regs[src_code]; + const uint64_t double_word = (uint64_t)sreg *(uint64_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + set_global_register(dst_code, high_order); + set_global_register(dst_code + 1, (uint32_t)double_word); + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if(sreg <= 0xffff && dreg <= 0xffff) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opb2() +void hyperstone_device::hyperstone_mulu_local_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dstf_code = (dst_code + 1) & 0x3f; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + if (src_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_mulu(decode); - printf("0xb2, mulu local,global\n"); + const uint32_t dreg = m_local_regs[dst_code]; + const uint32_t sreg = m_global_regs[src_code]; + const uint64_t double_word = (uint64_t)sreg *(uint64_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = (uint32_t)double_word; + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if(sreg <= 0xffff && dreg <= 0xffff) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } void hyperstone_device::hyperstone_mulu_local_local() @@ -5194,70 +5432,109 @@ void hyperstone_device::hyperstone_mulu_local_local() m_icount -= m_clock_cycles_6; } -void hyperstone_device::opb4() +void hyperstone_device::hyperstone_muls_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dst_code = DST_CODE; + const uint32_t dstf_code = dst_code + 1; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (src_code < 2 || dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == (DST_CODE + 1)); - decode.same_srcf_dst = ((SRC_CODE + 1) == DST_CODE); - hyperstone_muls(decode); - printf("0xb4, mulu global,global\n"); + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t sreg = m_global_regs[src_code]; + const int64_t double_word = (int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + set_global_register(dst_code, high_order); + set_global_register(dstf_code, (uint32_t)double_word); + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opb5() +void hyperstone_device::hyperstone_muls_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; + const uint32_t src_code = (SRC_CODE + GET_FP) & 0x3f; + const uint32_t dst_code = DST_CODE; + const uint32_t dstf_code = dst_code + 1; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_muls(decode); - printf("0xb4, mulu global,local\n"); + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t sreg = m_local_regs[src_code]; + const int64_t double_word = (int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + set_global_register(dst_code, high_order); + set_global_register(dstf_code, (uint32_t)double_word); + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opb6() +void hyperstone_device::hyperstone_muls_local_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_CODE; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_muls(decode); - printf("0xb4, mulu local,global\n"); + if (src_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); + return; + } + + const uint32_t dreg = m_local_regs[dst_code]; + const uint32_t sreg = m_local_regs[src_code]; + const int64_t double_word = (int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg; + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = (uint32_t)double_word; + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } void hyperstone_device::hyperstone_muls_local_local() @@ -5711,71 +5988,94 @@ void hyperstone_device::hyperstone_set_local() m_icount -= m_clock_cycles_1; } -void hyperstone_device::opbc() +void hyperstone_device::hyperstone_mul_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (src_code < 2 || dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == (DST_CODE + 1)); - decode.same_srcf_dst = ((SRC_CODE + 1) == DST_CODE); - hyperstone_mul(decode); - printf("0xbc, mul global,global\n"); + const uint32_t sreg = m_global_regs[src_code]; + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t result = sreg * dreg; + + set_global_register(dst_code, result); + + SR &= ~(Z_MASK | N_MASK); + if (result == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(result); + + if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= 3 << m_clck_scale; + else + m_icount -= 5 << m_clck_scale; } -void hyperstone_device::opbd() +void hyperstone_device::hyperstone_mul_global_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; + const uint32_t src_code = (SRC_CODE + GET_FP) & 0x3f; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 0; + if (dst_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); + return; + } - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t sreg = m_local_regs[src_code]; + const uint32_t dreg = m_global_regs[dst_code]; + const uint32_t result = sreg * dreg; - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - //hyperstone_mul(decode); - //printf("0xbd, mul global,local\n"); + set_global_register(dst_code, result); + + SR &= ~(Z_MASK | N_MASK); + if (result == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(result); + + if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= 3 << m_clck_scale; + else + m_icount -= 5 << m_clck_scale; } -void hyperstone_device::opbe() +void hyperstone_device::hyperstone_mul_local_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + if (src_code < 2) + { + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); + return; + } - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_mul(decode); - printf("0xbe, mul local,global\n"); + const uint32_t sreg = m_global_regs[src_code]; + const uint32_t dreg = m_local_regs[dst_code]; + const uint32_t result = sreg * dreg; + + m_local_regs[dst_code] = result; + + SR &= ~(Z_MASK | N_MASK); + if (result == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(result); + + if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= 3 << m_clck_scale; + else + m_icount -= 5 << m_clck_scale; } void hyperstone_device::hyperstone_mul_local_local() @@ -6067,45 +6367,34 @@ void hyperstone_device::hyperstone_stwr_local() m_icount -= m_clock_cycles_1; } -void hyperstone_device::opda() +void hyperstone_device::hyperstone_stdr_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode_source_noh(decode); - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + const uint32_t src_code = SRC_CODE; + const bool src_is_sr = (src_code == SR_REGISTER); + const uint32_t sreg = src_is_sr ? 0 : m_global_regs[src_code]; + const uint32_t sregf = src_is_sr ? 0 : m_global_regs[src_code + 1]; + const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_stdr(decode); - printf("0xda, stdr local,global\n"); + WRITE_W(dreg, sreg); + WRITE_W(dreg + 4, sregf); + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opdb() +void hyperstone_device::hyperstone_stdr_local() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[(DST_CODE + fp) & 0x3f]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; + WRITE_W(dreg, m_local_regs[src_code]); + WRITE_W(dreg + 4, m_local_regs[(src_code + 1) & 0x3f]); - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); - //hyperstone_stdr(decode); - //printf("0xdb, stdr local,local\n"); + m_icount -= m_clock_cycles_2; } void hyperstone_device::hyperstone_stwp_global_local()