From b937bfec958b74bc2f0eeca8dd824e647682973d Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sun, 12 Nov 2017 00:07:33 +0100 Subject: [PATCH] more e132xs optimization and some func renaming to show coverage, nw --- src/devices/cpu/e132xs/e132xs.cpp | 793 ++-------- src/devices/cpu/e132xs/e132xs.h | 108 +- src/devices/cpu/e132xs/e132xsop.hxx | 2283 ++++++++++++++++++--------- 3 files changed, 1713 insertions(+), 1471 deletions(-) diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index ff7fb8ca15e..32da50941b6 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -699,6 +699,7 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) #define S_BIT ((OP & 0x100) >> 8) #define D_BIT ((OP & 0x200) >> 9) #define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f)) +#define N_OP_MASK (m_op & 0x10f) #define DST_CODE ((OP & 0xf0) >> 4) #define SRC_CODE (OP & 0x0f) #define SIGN_BIT(val) ((val & 0x80000000) >> 31) @@ -1041,8 +1042,11 @@ do } \ } while (0) -void hyperstone_device::execute_br(int32_t offset) +void hyperstone_device::execute_br() { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + PPC = PC; PC += offset; SR &= ~M_MASK; @@ -1604,7 +1608,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++) { @@ -2000,26 +2004,6 @@ void hyperstone_device::hyperstone_cmp(regs_decode &decode) m_icount -= m_clock_cycles_1; } -void hyperstone_device::hyperstone_mov(regs_decode &decode) -{ - if (!GET_S && decode.dst >= 16) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(SREG); - - if (DST_IS_PC) - SR &= ~M_MASK; - - SET_Z(SREG == 0 ? 1 : 0); - SET_N(SIGN_BIT(SREG)); - - m_icount -= m_clock_cycles_1; -} - - void hyperstone_device::hyperstone_add(regs_decode &decode) { if (SRC_IS_SR) @@ -2241,54 +2225,6 @@ void hyperstone_device::hyperstone_negs(regs_decode &decode) } } -void hyperstone_device::hyperstone_movi(regs_decode &decode) -{ - if (!GET_S && decode.dst >= 16) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(EXTRA_U); - - if (DST_IS_PC) - SR &= ~M_MASK; - - SET_Z(EXTRA_U == 0 ? 1 : 0); - SET_N(SIGN_BIT(EXTRA_U)); - -#if MISSIONCRAFT_FLAGS - SR &= ~V_MASK; // or V undefined ? -#endif - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_addi(regs_decode &decode) -{ - uint32_t imm; - if (N_VALUE) - imm = EXTRA_U; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - - uint64_t tmp = (uint64_t)(imm) + (uint64_t)(DREG); - CHECK_C(tmp); - CHECK_VADD(imm,DREG,tmp); - - DREG = imm + DREG; - 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_addsi(regs_decode &decode) { int32_t imm; @@ -2320,35 +2256,6 @@ void hyperstone_device::hyperstone_addsi(regs_decode &decode) } } -void hyperstone_device::hyperstone_cmpbi(regs_decode &decode) -{ - uint32_t imm; - - if( N_VALUE ) - { - if( N_VALUE == 31 ) - { - imm = 0x7fffffff; // bit 31 = 0, others = 1 - } - else - { - imm = EXTRA_U; - } - - SET_Z( (DREG & imm) == 0 ? 1 : 0 ); - } - else - { - if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 || - (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 ) - SET_Z(1); - else - SET_Z(0); - } - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_andni(regs_decode &decode) { uint32_t imm; @@ -2366,16 +2273,6 @@ void hyperstone_device::hyperstone_andni(regs_decode &decode) m_icount -= m_clock_cycles_1; } -void hyperstone_device::hyperstone_xori(regs_decode &decode) -{ - DREG = DREG ^ EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_shrdi(regs_decode &decode) { uint32_t high_order = DREG; @@ -2599,130 +2496,6 @@ void hyperstone_device::hyperstone_rol(regs_decode &decode) m_icount -= m_clock_cycles_1; } -//TODO: add trap error -void hyperstone_device::hyperstone_ldxx1(regs_decode &decode) -{ - uint32_t load; - - if (DST_IS_SR) - { - switch( decode.sub_type ) - { - case 0: // LDBS.A - - load = READ_B(EXTRA_S); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - break; - - case 1: // LDBU.A - - load = READ_B(EXTRA_S); - SET_SREG(load); - - break; - - case 2: - - load = READ_HW(EXTRA_S); - - if( EXTRA_S & 1 ) // LDHS.A - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - } - /* - else // LDHU.A - { - // nothing more - } - */ - - SET_SREG(load); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDD.IOA - { - SET_SREG(IO_READ_W(EXTRA_S)); - - load = IO_READ_W((EXTRA_S & ~3) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if ((EXTRA_S & 3) == 2) // LDW.IOA - { - SET_SREG(IO_READ_W(EXTRA_S)); - } - else if( (EXTRA_S & 3) == 1) // LDD.A - { - SET_SREG(READ_W(EXTRA_S)); - SET_SREGF(READ_W(EXTRA_S + 4)); - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.A - { - SET_SREG(READ_W(EXTRA_S)); - } - - break; - } - } - else - { - switch (decode.sub_type) - { - case 0: // LDBS.D - SET_SREG((int32_t)(int8_t)READ_B(DREG + EXTRA_S)); - break; - - case 1: // LDBU.D - SET_SREG(READ_B(DREG + EXTRA_S)); - break; - - case 2: - if (EXTRA_S & 1) - { - SET_SREG((int32_t)(int16_t)READ_HW(DREG + (EXTRA_S & ~1))); - } - else - { - SET_SREG(READ_HW(DREG + (EXTRA_S & ~1))); - } - break; - - case 3: - if ((EXTRA_S & 3) == 3) // LDD.IOD - { - SET_SREG(IO_READ_W(DREG + (EXTRA_S & ~3))); - SET_SREGF(IO_READ_W(DREG + (EXTRA_S & ~3) + 4)); - m_icount -= m_clock_cycles_1; // extra cycle - } - else if ((EXTRA_S & 3) == 2) // LDW.IOD - { - SET_SREG(IO_READ_W(DREG + (EXTRA_S & ~3))); - } - else if ((EXTRA_S & 3) == 1) // LDD.D - { - SET_SREG(READ_W(DREG + (EXTRA_S & ~1))); - SET_SREGF(READ_W(DREG + (EXTRA_S & ~1) + 4)); - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.D - { - SET_SREG(READ_W(DREG + (EXTRA_S & ~1))); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_ldxx2(regs_decode &decode) { if (DST_IS_PC || DST_IS_SR) @@ -3024,24 +2797,6 @@ void hyperstone_device::hyperstone_stxx2(regs_decode &decode) m_icount -= m_clock_cycles_1; } -void hyperstone_device::hyperstone_shri(regs_decode &decode) -{ - uint32_t val = DREG; - - if (N_VALUE) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - SET_DREG(val); - SET_Z(val == 0 ? 1 : 0); - SET_N(SIGN_BIT(val)); - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_sari(regs_decode &decode) { uint32_t val = DREG; @@ -3127,344 +2882,6 @@ void hyperstone_device::hyperstone_muls(regs_decode &decode) m_icount -= m_clock_cycles_6; } -void hyperstone_device::hyperstone_set(regs_decode &decode) -{ - const uint32_t n = N_VALUE; - - if ( DST_IS_PC) - { - DEBUG_PRINTF(("Denoted PC in hyperstone_set. PC = %08X\n", PC)); - } - else if (DST_IS_SR) - { - //TODO: add fetch opcode when there's the pipeline - - //TODO: no 1! - m_icount -= m_clock_cycles_1; - } - else - { - switch (n) - { - // SETADR - case 0: - SET_DREG((SP & 0xfffffe00) | (GET_FP << 2) | (((SP & 0x100) && (SIGN_BIT(SR) == 0)) ? 1 : 0)); - break; - - // Reserved - case 1: - case 16: - case 17: - case 19: - DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC)); - break; - - // SETxx - case 2: - SET_DREG(1); - break; - - case 3: - SET_DREG(0); - break; - - case 4: - if( GET_N || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 5: - if( !GET_N && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 6: - if( GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 7: - if( !GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 8: - if( GET_C || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 9: - if( !GET_C && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 10: - if( GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 11: - if( !GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 12: - if( GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 13: - if( !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 14: - if( GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 15: - if( !GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 18: - SET_DREG(-1); - break; - - case 20: - if( GET_N || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 21: - if( !GET_N && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 22: - if( GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 23: - if( !GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 24: - if( GET_C || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 25: - if( !GET_C && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 26: - if( GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 27: - if( !GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 28: - if( GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 29: - if( !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 30: - if( GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 31: - if( !GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - } - - m_icount -= m_clock_cycles_1; - } -} - void hyperstone_device::hyperstone_mul(regs_decode &decode) { // PC or SR aren't denoted, else result is undefined @@ -3542,16 +2959,6 @@ void hyperstone_device::hyperstone_lddp(regs_decode &decode) m_icount -= m_clock_cycles_2; } -void hyperstone_device::hyperstone_stwr(regs_decode &decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - WRITE_W(DREG, SREG); - - m_icount -= m_clock_cycles_1; -} - void hyperstone_device::hyperstone_stdr(regs_decode &decode) { if( SRC_IS_SR ) @@ -3592,85 +2999,72 @@ void hyperstone_device::hyperstone_stdp(regs_decode &decode) void hyperstone_device::hyperstone_trap() { - uint8_t code, trapno; - uint32_t addr; + check_delay_PC(); - trapno = (OP & 0xfc) >> 2; + const uint8_t trapno = (m_op & 0xfc) >> 2; - addr = get_trap_addr(trapno); - code = ((OP & 0x300) >> 6) | (OP & 0x03); + const uint32_t addr = get_trap_addr(trapno); + const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03); - switch( code ) + switch (code) { case TRAPLE: - if( GET_N || GET_Z ) + if (SR & (N_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPGT: - if( !GET_N && !GET_Z ) + if(!(SR & (N_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPLT: - if( GET_N ) + if (SR & N_MASK) execute_trap(addr); - break; case TRAPGE: - if( !GET_N ) + if (!(SR & N_MASK)) execute_trap(addr); - break; case TRAPSE: - if( GET_C || GET_Z ) + if (SR & (C_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPHT: - if( !GET_C && !GET_Z ) + if (!(SR & (C_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPST: - if( GET_C ) + if (SR & C_MASK) execute_trap(addr); - break; case TRAPHE: - if( !GET_C ) + if (!(SR & C_MASK)) execute_trap(addr); - break; case TRAPE: - if( GET_Z ) + if (SR & Z_MASK) execute_trap(addr); - break; case TRAPNE: - if( !GET_Z ) + if (!(SR & Z_MASK)) execute_trap(addr); - break; case TRAPV: - if( GET_V ) + if (SR & V_MASK) execute_trap(addr); - break; case TRAP: execute_trap(addr); - break; } @@ -3725,7 +3119,6 @@ void hyperstone_device::execute_set_input(int inputnum, int state) ISR &= ~(1 << inputnum); } - //------------------------------------------------- // execute_run - execute a timeslice's worth of // opcodes @@ -3760,9 +3153,9 @@ void hyperstone_device::execute_run() case 0x02: hyperstone_chk_local_global(); break; case 0x03: hyperstone_chk_local_local(); break; case 0x04: op04(); break; - case 0x05: op05(); break; - case 0x06: op06(); break; - case 0x07: op07(); break; + case 0x05: hyperstone_movd_global_local(); break; + case 0x06: hyperstone_movd_local_global(); break; + case 0x07: hyperstone_movd_local_local(); break; case 0x08: op08(); break; case 0x09: op09(); break; case 0x0a: op0a(); break; @@ -3770,63 +3163,63 @@ void hyperstone_device::execute_run() case 0x0c: op0c(); break; case 0x0d: op0d(); break; case 0x0e: op0e(); break; - case 0x0f: op0f(); break; + case 0x0f: hyperstone_divs_local_local(); break; case 0x10: op10(); break; case 0x11: op11(); break; case 0x12: op12(); break; case 0x13: op13(); break; case 0x14: op14(); break; - case 0x15: op15(); break; - case 0x16: op16(); break; - case 0x17: op17(); break; - case 0x18: op18(); break; + case 0x15: hyperstone_mask_global_local(); break; + case 0x16: hyperstone_mask_local_global(); break; + case 0x17: hyperstone_mask_local_local(); break; + case 0x18: hyperstone_sum_global_global(); break; case 0x19: op19(); break; - case 0x1a: op1a(); break; - case 0x1b: op1b(); break; + case 0x1a: hyperstone_sum_local_global(); break; + case 0x1b: hyperstone_sum_local_local(); break; case 0x1c: op1c(); break; case 0x1d: op1d(); break; case 0x1e: op1e(); break; case 0x1f: op1f(); break; case 0x20: op20(); break; case 0x21: op21(); break; - case 0x22: op22(); break; - case 0x23: op23(); break; - case 0x24: op24(); break; - case 0x25: op25(); break; - case 0x26: op26(); break; - case 0x27: op27(); break; + case 0x22: hyperstone_cmp_local_global(); break; + case 0x23: hyperstone_cmp_local_local(); break; + case 0x24: hyperstone_mov_global_global(); break; + case 0x25: hyperstone_mov_global_local(); break; + case 0x26: hyperstone_mov_local_global(); break; + case 0x27: hyperstone_mov_local_local(); break; case 0x28: op28(); break; - case 0x29: op29(); break; - case 0x2a: op2a(); break; - case 0x2b: op2b(); break; + case 0x29: hyperstone_add_global_local(); break; + case 0x2a: hyperstone_add_local_global(); break; + case 0x2b: hyperstone_add_local_local(); break; case 0x2c: op2c(); break; case 0x2d: op2d(); break; case 0x2e: op2e(); break; case 0x2f: op2f(); break; - case 0x30: op30(); break; // cmpb - case 0x31: op31(); break; // cmpb - case 0x32: op32(); break; // cmpb - case 0x33: op33(); break; // cmpb - case 0x34: op34(); break; - case 0x35: op35(); break; - case 0x36: op36(); break; - case 0x37: op37(); break; - case 0x38: op38(); break; - case 0x39: op39(); break; - case 0x3a: op3a(); break; - case 0x3b: op3b(); break; - case 0x3c: op3c(); break; - case 0x3d: op3d(); break; - case 0x3e: op3e(); break; - case 0x3f: op3f(); break; + case 0x30: hyperstone_cmpb_global_global(); break; + case 0x31: hyperstone_cmpb_global_local(); break; + case 0x32: hyperstone_cmpb_local_global(); break; + case 0x33: hyperstone_cmpb_local_local(); break; + case 0x34: hyperstone_andn_global_global(); break; + case 0x35: hyperstone_andn_global_local(); break; + case 0x36: hyperstone_andn_local_global(); break; + case 0x37: hyperstone_andn_local_local(); break; + case 0x38: hyperstone_or_global_global(); break; + case 0x39: hyperstone_or_global_local(); break; + case 0x3a: hyperstone_or_local_global(); break; + case 0x3b: hyperstone_or_local_local(); break; + case 0x3c: hyperstone_xor_global_global(); break; + case 0x3d: hyperstone_xor_global_local(); break; + case 0x3e: hyperstone_xor_local_global(); break; + case 0x3f: hyperstone_xor_local_local(); break; case 0x40: op40(); break; case 0x41: op41(); break; case 0x42: op42(); break; case 0x43: op43(); break; - case 0x44: op44(); break; - case 0x45: op45(); break; - case 0x46: op46(); break; - case 0x47: op47(); break; + case 0x44: hyperstone_not_global_global(); break; + 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 0x4a: op4a(); break; @@ -3855,22 +3248,22 @@ void hyperstone_device::execute_run() case 0x61: hyperstone_cmpi_global_limm(); break; case 0x62: hyperstone_cmpi_local_simm(); break; case 0x63: hyperstone_cmpi_local_limm(); break; - case 0x64: op64(); break; - case 0x65: op65(); break; - case 0x66: op66(); break; - case 0x67: op67(); break; - case 0x68: op68(); break; - case 0x69: op69(); break; - case 0x6a: op6a(); break; - case 0x6b: op6b(); break; + case 0x64: hyperstone_movi_global_simm(); break; + case 0x65: hyperstone_movi_global_limm(); break; + case 0x66: hyperstone_movi_local_simm(); break; + case 0x67: hyperstone_movi_local_limm(); break; + case 0x68: hyperstone_addi_global_simm(); break; + 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 0x70: op70(); break; - case 0x71: op71(); break; - case 0x72: op72(); break; - case 0x73: op73(); break; + case 0x70: hyperstone_cmpbi_global_simm(); break; + case 0x71: hyperstone_cmpbi_global_limm(); break; + case 0x72: hyperstone_cmpbi_local_simm(); break; + case 0x73: hyperstone_cmpbi_local_limm(); break; case 0x74: op74(); break; case 0x75: op75(); break; case 0x76: op76(); break; @@ -3879,10 +3272,10 @@ void hyperstone_device::execute_run() case 0x79: hyperstone_ori_global_limm(); break; case 0x7a: hyperstone_ori_local_simm(); break; case 0x7b: hyperstone_ori_local_limm(); break; - case 0x7c: op7c(); break; - case 0x7d: op7d(); break; - case 0x7e: op7e(); break; - case 0x7f: op7f(); break; + case 0x7c: hyperstone_xori_global_simm(); break; + case 0x7d: hyperstone_xori_global_limm(); break; + case 0x7e: hyperstone_xori_local_simm(); break; + case 0x7f: hyperstone_xori_local_limm(); break; case 0x80: op80(); break; case 0x81: op81(); break; case 0x82: hyperstone_shrd(); break; @@ -3899,10 +3292,10 @@ void hyperstone_device::execute_run() case 0x8d: op8d(); break; case 0x8e: hyperstone_testlz(); break; case 0x8f: op8f(); break; - case 0x90: op90(); break; - case 0x91: op91(); break; - case 0x92: op92(); break; - case 0x93: op93(); break; + case 0x90: hyperstone_ldxx1_global_global(); break; + case 0x91: hyperstone_ldxx1_global_local(); break; + case 0x92: hyperstone_ldxx1_local_global(); break; + case 0x93: hyperstone_ldxx1_local_local(); break; case 0x94: op94(); break; case 0x95: op95(); break; case 0x96: op96(); break; @@ -3915,8 +3308,8 @@ void hyperstone_device::execute_run() case 0x9d: op9d(); break; case 0x9e: op9e(); break; case 0x9f: op9f(); break; - case 0xa0: opa0(); break; - case 0xa1: opa1(); 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; @@ -3939,10 +3332,10 @@ void hyperstone_device::execute_run() case 0xb5: opb5(); break; case 0xb6: opb6(); break; case 0xb7: opb7(); break; - case 0xb8: opb8(); break; - case 0xb9: opb9(); break; - case 0xba: opba(); break; - case 0xbb: opbb(); 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; @@ -3971,8 +3364,8 @@ void hyperstone_device::execute_run() case 0xd5: opd5(); break; case 0xd6: opd6(); break; case 0xd7: opd7(); break; - case 0xd8: opd8(); break; - case 0xd9: opd9(); break; + case 0xd8: hyperstone_stwr_global(); break; + case 0xd9: hyperstone_stwr_local(); break; case 0xda: opda(); break; case 0xdb: opdb(); break; case 0xdc: opdc(); break; @@ -4007,10 +3400,10 @@ void hyperstone_device::execute_run() case 0xf9: opf9(); break; case 0xfa: opfa(); break; case 0xfb: opfb(); break; - case 0xfc: opfc(); break; - case 0xfd: opfd(); break; - case 0xfe: opfe(); break; - case 0xff: opff(); break; + case 0xfc: execute_br(); break; + case 0xfd: hyperstone_trap(); break; + case 0xfe: hyperstone_trap(); break; + case 0xff: hyperstone_trap(); break; } #else (this->*m_opcode[(OP & 0xff00) >> 8])(); diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index a3d4261d724..6b7a1b254ba 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -209,7 +209,7 @@ private: TIMER_CALLBACK_MEMBER(timer_callback); - void execute_br(int32_t offset); + void execute_br(); void execute_dbr(int32_t offset); void execute_trap(uint32_t addr); void execute_int(uint32_t addr); @@ -225,16 +225,39 @@ private: void hyperstone_chk_local_global(); void hyperstone_chk_local_local(); void hyperstone_movd(regs_decode &decode); + void hyperstone_movd_global_local(); + void hyperstone_movd_local_global(); + void hyperstone_movd_local_local(); void hyperstone_divu(regs_decode &decode); void hyperstone_divs(regs_decode &decode); + void hyperstone_divs_local_local(); void hyperstone_xm(regs_decode &decode); void hyperstone_mask(regs_decode &decode); + void hyperstone_mask_global_local(); + void hyperstone_mask_local_global(); + void hyperstone_mask_local_local(); void hyperstone_sum(regs_decode &decode); + void hyperstone_sum_global_global(); + void hyperstone_sum_local_global(); + void hyperstone_sum_local_local(); void hyperstone_sums(regs_decode &decode); void hyperstone_cmp(regs_decode &decode); + void hyperstone_cmp_local_global(); + void hyperstone_cmp_local_local(); void hyperstone_mov(regs_decode &decode); + void hyperstone_mov_global_global(); + void hyperstone_mov_global_local(); + void hyperstone_mov_local_global(); + void hyperstone_mov_local_local(); void hyperstone_add(regs_decode &decode); + void hyperstone_add_global_local(); + void hyperstone_add_local_global(); + void hyperstone_add_local_local(); void hyperstone_adds(regs_decode &decode); + void hyperstone_cmpb_global_global(); + void hyperstone_cmpb_global_local(); + void hyperstone_cmpb_local_global(); + void hyperstone_cmpb_local_local(); void hyperstone_subc(regs_decode &decode); void hyperstone_sub(regs_decode &decode); void hyperstone_subs(regs_decode &decode); @@ -245,24 +268,53 @@ private: void hyperstone_and_global_local(); void hyperstone_and_local_global(); void hyperstone_and_local_local(); + void hyperstone_andn_global_global(); + void hyperstone_andn_global_local(); + void hyperstone_andn_local_global(); + void hyperstone_andn_local_local(); + void hyperstone_or_global_global(); + void hyperstone_or_global_local(); + void hyperstone_or_local_global(); + void hyperstone_or_local_local(); + void hyperstone_xor_global_global(); + void hyperstone_xor_global_local(); + void hyperstone_xor_local_global(); + void hyperstone_xor_local_local(); + void hyperstone_not_global_global(); + void hyperstone_not_global_local(); + void hyperstone_not_local_global(); + void hyperstone_not_local_local(); void hyperstone_cmpi_global_simm(); void hyperstone_cmpi_global_limm(); void hyperstone_cmpi_local_simm(); void hyperstone_cmpi_local_limm(); void hyperstone_movi(regs_decode &decode); + void hyperstone_movi_global_simm(); + void hyperstone_movi_global_limm(); + void hyperstone_movi_local_simm(); + void hyperstone_movi_local_limm(); void hyperstone_addi(regs_decode &decode); + void hyperstone_addi_global_simm(); + void hyperstone_addi_global_limm(); + void hyperstone_addi_local_simm(); + void hyperstone_addi_local_limm(); void hyperstone_addsi(regs_decode &decode); - void hyperstone_cmpbi(regs_decode &decode); + void hyperstone_cmpbi_global_simm(); + void hyperstone_cmpbi_global_limm(); + void hyperstone_cmpbi_local_simm(); + void hyperstone_cmpbi_local_limm(); void hyperstone_andni(regs_decode &decode); void hyperstone_ori_global_simm(); void hyperstone_ori_global_limm(); void hyperstone_ori_local_simm(); void hyperstone_ori_local_limm(); - void hyperstone_xori(regs_decode &decode); + void hyperstone_xori_global_simm(); + void hyperstone_xori_global_limm(); + void hyperstone_xori_local_simm(); + void hyperstone_xori_local_limm(); void hyperstone_shrdi(regs_decode &decode); void hyperstone_shrd(); void hyperstone_shr(regs_decode &decode); - void hyperstone_shri(regs_decode &decode); void hyperstone_sardi(); void hyperstone_sard(); void hyperstone_sar(regs_decode &decode); @@ -272,21 +324,26 @@ private: void hyperstone_shl(); void hyperstone_testlz(); void hyperstone_rol(regs_decode &decode); - void hyperstone_ldxx1(regs_decode &decode); + void hyperstone_ldxx1_global_global(); + void hyperstone_ldxx1_global_local(); + void hyperstone_ldxx1_local_global(); + void hyperstone_ldxx1_local_local(); void hyperstone_ldxx2(regs_decode &decode); void hyperstone_stxx1(regs_decode &decode); void hyperstone_stxx2(regs_decode &decode); void hyperstone_mulu(regs_decode &decode); void hyperstone_muls(regs_decode &decode); void hyperstone_mul(regs_decode &decode); - void hyperstone_set(regs_decode &decode); + void hyperstone_set_global(); + void hyperstone_set_local(); void hyperstone_ldwr(regs_decode &decode); void hyperstone_lddr(regs_decode &decode); void hyperstone_ldwp(regs_decode &decode); void hyperstone_lddp(regs_decode &decode); - void hyperstone_stwr(regs_decode &decode); + void hyperstone_stwr_global(); + void hyperstone_stwr_local(); void hyperstone_stdr(regs_decode &decode); void hyperstone_stwp(regs_decode &decode); void hyperstone_stdp(regs_decode &decode); @@ -296,6 +353,7 @@ private: void hyperstone_shli_global(); void hyperstone_shli_local(); + void hyperstone_shri_global(); void hyperstone_shri_local(); int32_t decode_pcrel(); @@ -317,38 +375,38 @@ private: bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); #endif - void op04(); void op05(); void op06(); void op07(); - void op08(); void op09(); void op0a(); void op0b(); void op0c(); void op0d(); void op0e(); void op0f(); - void op10(); void op11(); void op12(); void op13(); void op14(); void op15(); void op16(); void op17(); - void op18(); void op19(); void op1a(); void op1b(); void op1c(); void op1d(); void op1e(); void op1f(); - void op20(); void op21(); void op22(); void op23(); void op24(); void op25(); void op26(); void op27(); - void op28(); void op29(); void op2a(); void op2b(); void op2c(); void op2d(); void op2e(); void op2f(); - void op30(); void op31(); void op32(); void op33(); void op34(); void op35(); void op36(); void op37(); - void op38(); void op39(); void op3a(); void op3b(); void op3c(); void op3d(); void op3e(); void op3f(); - void op40(); void op41(); void op42(); void op43(); void op44(); void op45(); void op46(); void op47(); + void op04(); + void op08(); void op09(); void op0a(); void op0b(); void op0c(); void op0d(); void op0e(); + void op10(); void op11(); void op12(); void op13(); void op14(); + void op19(); void op1c(); void op1d(); void op1e(); void op1f(); + void op20(); void op21(); void op23(); + void op28(); void op2c(); void op2d(); void op2e(); void op2f(); + + + void op40(); void op41(); void op42(); void op43(); void op48(); void op49(); void op4a(); void op4b(); void op4c(); void op4d(); void op4e(); void op4f(); void op50(); void op51(); void op52(); void op53(); void op58(); void op59(); void op5a(); void op5b(); void op5c(); void op5d(); void op5e(); void op5f(); - void op64(); void op65(); void op66(); void op67(); - void op68(); void op69(); void op6a(); void op6b(); void op6c(); void op6d(); void op6e(); void op6f(); - void op70(); void op71(); void op72(); void op73(); void op74(); void op75(); void op76(); void op77(); - void op7c(); void op7d(); void op7e(); void op7f(); + + void op6c(); void op6d(); void op6e(); void op6f(); + void op74(); void op75(); void op76(); void op77(); + void op7c(); void op7d(); void op7e(); void op7f(); void op80(); void op81(); void op83(); void op87(); void op8c(); void op8d(); void op8f(); - void op90(); void op91(); void op92(); void op93(); void op94(); void op95(); void op96(); void op97(); + void op94(); void op95(); void op96(); void op97(); void op98(); void op99(); void op9a(); void op9b(); void op9c(); void op9d(); void op9e(); void op9f(); - void opa0(); void opa1(); void opa4(); void opa5(); void opa6(); void opa7(); + void opa0(); void opa1(); void opa4(); void opa5(); void opa6(); void opa7(); void opac(); void opad(); void opae(); void opaf(); void opb0(); void opb1(); void opb2(); void opb3(); void opb4(); void opb5(); void opb6(); void opb7(); - void opb8(); void opb9(); void opba(); void opbb(); void opbc(); void opbd(); void opbe(); void opbf(); + void opb8(); void opb9(); void opba(); void opbb(); void opbc(); void opbd(); void opbe(); void opbf(); void opce(); void opcf(); void opd0(); void opd1(); void opd2(); void opd3(); void opd4(); void opd5(); void opd6(); void opd7(); - void opd8(); void opd9(); void opda(); void opdb(); void opdc(); void opdd(); void opde(); void opdf(); + void opda(); void opdb(); void opdc(); void opdd(); void opde(); void opdf(); void ope0(); void ope1(); void ope2(); void ope3(); void ope4(); void ope5(); void ope6(); void ope7(); void ope8(); void ope9(); void opea(); void opeb(); void opec(); void oped(); void opee(); void opef(); void opf0(); void opf1(); void opf2(); void opf3(); void opf4(); void opf5(); void opf6(); void opf7(); - void opf8(); void opf9(); void opfa(); void opfb(); void opfc(); void opfd(); void opfe(); void opff(); + void opf8(); void opf9(); void opfa(); void opfb(); #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 747280c8b60..e26914d2002 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -108,7 +108,7 @@ void hyperstone_device::op04() hyperstone_movd(decode); } -void hyperstone_device::op05() // movd, local src, global dst +void hyperstone_device::hyperstone_movd_global_local() { check_delay_PC(); const uint32_t src_code = SRC_CODE + GET_FP; @@ -167,28 +167,41 @@ void hyperstone_device::op05() // movd, local src, global dst } } -void hyperstone_device::op06() +void hyperstone_device::hyperstone_movd_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; + const uint32_t dst_code = DST_CODE; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + if (src_code == SR_REGISTER) // Rd doesn't denote PC and Rs denotes SR + { + m_local_regs[(dst_code + fp) & 0x3f] = 0; + m_local_regs[(dst_code + 1 + fp) & 0x3f] = 0; + SR |= Z_MASK; + SR &= ~N_MASK; - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_movd(decode); + m_icount -= m_clock_cycles_2; + } + else // Rd doesn't denote PC and Rs doesn't denote SR + { + const uint32_t sreg = m_global_regs[src_code]; + const uint32_t sregf = m_global_regs[src_code + 1]; + m_local_regs[(dst_code + fp) & 0x3f] = sreg; + m_local_regs[(dst_code + 1 + fp) & 0x3f] = sregf; + + SR &= ~(Z_MASK | N_MASK); + + if (sreg == 0 && sregf == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + + m_icount -= m_clock_cycles_2; + } } -void hyperstone_device::op07() // movd local,local +void hyperstone_device::hyperstone_movd_local_local() { check_delay_PC(); @@ -202,9 +215,9 @@ void hyperstone_device::op07() // movd local,local m_local_regs[(dst_code + fp) & 0x3f] = sreg; m_local_regs[(dst_code + 1 + fp) & 0x3f] = sregf; - uint64_t tmp = concat_64(sreg, sregf); SR &= ~(Z_MASK | N_MASK); - if (tmp == 0) + + if (sreg == 0 && sregf == 0) SR |= Z_MASK; SR |= SIGN_TO_N(sreg); @@ -241,8 +254,8 @@ void hyperstone_device::op09() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; @@ -267,8 +280,8 @@ void hyperstone_device::op0a() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -284,16 +297,16 @@ void hyperstone_device::op0b() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_divu(decode); } @@ -327,8 +340,8 @@ void hyperstone_device::op0d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; @@ -353,8 +366,8 @@ void hyperstone_device::op0e() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -362,25 +375,47 @@ void hyperstone_device::op0e() hyperstone_divs(decode); } -void hyperstone_device::op0f() +void hyperstone_device::hyperstone_divs_local_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) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + 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.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + if (src_code == dst_code || src_code == dstf_code) + { + m_icount -= 36 << m_clck_scale; + return; + } - decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); - hyperstone_divs(decode); + const uint32_t sreg = m_local_regs[src_code]; + const int64_t dividend = (int64_t) concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); + + if (sreg == 0 || (dividend & 0x8000000000000000U)) + { + //Rd//Rdf -> undefined + //Z -> undefined + //N -> undefined + SR |= V_MASK; + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + else + { + /* TODO: add quotient overflow */ + const int32_t quotient = dividend / (int32_t)sreg; + m_local_regs[dst_code] = dividend % (int32_t)sreg; + m_local_regs[dstf_code] = quotient; + + SR &= ~(V_MASK | Z_MASK | N_MASK); + if (quotient == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(quotient); + } + + m_icount -= 36 << m_clck_scale; } @@ -417,8 +452,8 @@ void hyperstone_device::op11() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -443,8 +478,8 @@ void hyperstone_device::op12() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -461,16 +496,16 @@ void hyperstone_device::op13() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_xm(decode); } @@ -496,7 +531,7 @@ void hyperstone_device::op14() hyperstone_mask(decode); } -void hyperstone_device::op15() +void hyperstone_device::hyperstone_mask_global_local() { const uint32_t extra_u = decode_const(); @@ -513,7 +548,7 @@ void hyperstone_device::op15() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op16() +void hyperstone_device::hyperstone_mask_local_global() { const uint32_t extra_u = decode_const(); @@ -530,7 +565,7 @@ void hyperstone_device::op16() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op17() // mask local,local +void hyperstone_device::hyperstone_mask_local_local() { const uint32_t extra_u = decode_const(); @@ -548,26 +583,31 @@ void hyperstone_device::op17() // mask local,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op18() +void hyperstone_device::hyperstone_sum_global_global() { - regs_decode decode; - DECODE_CONST(decode); + const uint32_t extra_u = decode_const(); + 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 sreg = m_global_regs[SRC_CODE]; + const uint64_t tmp = (uint64_t)sreg + (uint64_t)extra_u; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - 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_sum(decode); + SR |= (tmp & 0x100000000L) >> 32; + + if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) + SR |= V_MASK; + + const uint32_t dreg = sreg + extra_u; + + set_global_register(DST_CODE, dreg); + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } void hyperstone_device::op19() @@ -579,8 +619,8 @@ void hyperstone_device::op19() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -592,29 +632,34 @@ void hyperstone_device::op19() hyperstone_sum(decode); } -void hyperstone_device::op1a() +void hyperstone_device::hyperstone_sum_local_global() { - regs_decode decode; - DECODE_CONST(decode); + const uint32_t extra_u = decode_const(); + 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 sreg = m_global_regs[SRC_CODE]; + const uint64_t tmp = (uint64_t)sreg + (uint64_t)extra_u; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_sum(decode); + SR |= (tmp & 0x100000000L) >> 32; + + if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) + SR |= V_MASK; + + const uint32_t dreg = sreg + extra_u; + + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op1b() // sum local,local +void hyperstone_device::hyperstone_sum_local_local() { const uint32_t extra_u = decode_const(); @@ -627,8 +672,7 @@ void hyperstone_device::op1b() // sum local,local SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; if ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) SR |= V_MASK; @@ -675,8 +719,8 @@ void hyperstone_device::op1d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -701,8 +745,8 @@ void hyperstone_device::op1e() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -719,16 +763,16 @@ void hyperstone_device::op1f() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_sums(decode); } @@ -763,8 +807,8 @@ void hyperstone_device::op21() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; @@ -777,7 +821,7 @@ void hyperstone_device::op21() hyperstone_cmp(decode); } -void hyperstone_device::op22() // cmp local,global +void hyperstone_device::hyperstone_cmp_local_global() { check_delay_PC(); @@ -804,7 +848,7 @@ void hyperstone_device::op22() // cmp local,global m_icount -= m_clock_cycles_1; } -void hyperstone_device::op23() // cmp local,local +void hyperstone_device::hyperstone_cmp_local_local() { check_delay_PC(); @@ -829,32 +873,70 @@ void hyperstone_device::op23() // cmp local,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op24() +void hyperstone_device::hyperstone_mov_global_global() { - regs_decode decode; check_delay_PC(); - decode.src = SRC_CODE; - decode.dst = DST_CODE; - decode_source(decode, GET_H); - decode_dest(decode, GET_H); - hyperstone_mov(decode); + + const uint32_t dst_code = DST_CODE; + + uint32_t sreg; + if (SR & H_MASK) + { + if (!(SR & S_MASK)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + + const uint32_t src_code = SRC_CODE + 16; + sreg = (WRITE_ONLY_REGMASK & (1 << src_code)) ? 0 : get_global_register(src_code); + set_global_register(dst_code + 16, sreg); + } + else + { + sreg = m_global_regs[SRC_CODE]; + m_global_regs[dst_code] = sreg; + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + + SR &= ~(Z_MASK | N_MASK); + if (sreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op25() +void hyperstone_device::hyperstone_mov_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) % 64]; + const uint32_t dst_code = DST_CODE; + const uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; - decode_dest(decode, GET_H); - hyperstone_mov(decode); + if (SR & H_MASK) + { + if (!(SR & S_MASK)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + + set_global_register(DST_CODE + 16, sreg); + } + else + { + m_global_regs[dst_code] = sreg; + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + + SR &= ~(Z_MASK | N_MASK); + if (sreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op26() +void hyperstone_device::hyperstone_mov_local_global() { check_delay_PC(); uint32_t src_code = SRC_CODE; @@ -863,9 +945,7 @@ void hyperstone_device::op26() if (SR & H_MASK) { src_code += 16; - sreg = get_global_register(src_code); - if ((WRITE_ONLY_REGMASK >> src_code) & 1) - sreg = 0; /* write-only registers */ + sreg = (WRITE_ONLY_REGMASK & (1 << src_code)) ? 0 : get_global_register(src_code); } else { @@ -882,7 +962,7 @@ void hyperstone_device::op26() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op27() +void hyperstone_device::hyperstone_mov_local_local() { check_delay_PC(); @@ -914,7 +994,7 @@ void hyperstone_device::op28() hyperstone_add(decode); } -void hyperstone_device::op29() // add global,local +void hyperstone_device::hyperstone_add_global_local() { check_delay_PC(); @@ -927,8 +1007,7 @@ void hyperstone_device::op29() // add global,local SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -946,7 +1025,7 @@ void hyperstone_device::op29() // add global,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op2a() // add local,global +void hyperstone_device::hyperstone_add_local_global() { check_delay_PC(); @@ -962,8 +1041,7 @@ void hyperstone_device::op2a() // add local,global SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -978,7 +1056,7 @@ void hyperstone_device::op2a() // add local,global m_icount -= m_clock_cycles_1; } -void hyperstone_device::op2b() +void hyperstone_device::hyperstone_add_local_local() { check_delay_PC(); @@ -992,8 +1070,7 @@ void hyperstone_device::op2b() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; if ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -1033,7 +1110,7 @@ void hyperstone_device::op2d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1052,7 +1129,7 @@ void hyperstone_device::op2e() SREG = m_global_regs[decode.src]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_adds(decode); } @@ -1065,17 +1142,17 @@ void hyperstone_device::op2f() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_adds(decode); } -void hyperstone_device::op30() // cmpb +void hyperstone_device::hyperstone_cmpb_global_global() { check_delay_PC(); @@ -1090,11 +1167,11 @@ void hyperstone_device::op30() // cmpb m_icount -= m_clock_cycles_1; } -void hyperstone_device::op31() // cmpb +void hyperstone_device::hyperstone_cmpb_global_local() { check_delay_PC(); - uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) % 64]; + uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; uint32_t dreg = m_global_regs[DST_CODE]; if (dreg & sreg) @@ -1105,12 +1182,12 @@ void hyperstone_device::op31() // cmpb m_icount -= m_clock_cycles_1; } -void hyperstone_device::op32() // cmpb +void hyperstone_device::hyperstone_cmpb_local_global() { check_delay_PC(); uint32_t sreg = m_global_regs[SRC_CODE]; - uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) % 64]; /* registers offset by frame pointer */ + uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; /* registers offset by frame pointer */ if (dreg & sreg) SR &= ~Z_MASK; @@ -1120,12 +1197,12 @@ void hyperstone_device::op32() // cmpb m_icount -= m_clock_cycles_1; } -void hyperstone_device::op33() // cmpb +void hyperstone_device::hyperstone_cmpb_local_local() { check_delay_PC(); - uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) % 64]; - uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) % 64]; /* registers offset by frame pointer */ + uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; /* registers offset by frame pointer */ if (dreg & sreg) SR &= ~Z_MASK; @@ -1135,68 +1212,14 @@ void hyperstone_device::op33() // cmpb m_icount -= m_clock_cycles_1; } -void hyperstone_device::op34() // andn -{ - check_delay_PC(); - - uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg &= ~m_global_regs[SRC_CODE]; - - set_global_register(dst_code, dreg); - SET_Z(dreg == 0 ? 1 : 0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::op35() // andn -{ - check_delay_PC(); - - uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg &= ~m_local_regs[(SRC_CODE + GET_FP) % 64]; - - set_global_register(dst_code, dreg); - SET_Z(dreg == 0 ? 1 : 0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::op36() // andn -{ - check_delay_PC(); - - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] &= ~m_global_regs[SRC_CODE]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::op37() // andn -{ - check_delay_PC(); - - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] &= ~m_local_regs[(SRC_CODE + GET_FP) % 64]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::op38() // or global,global +void hyperstone_device::hyperstone_andn_global_global() { check_delay_PC(); const uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg |= m_global_regs[SRC_CODE]; - + const uint32_t dreg = m_global_regs[dst_code] & ~m_global_regs[SRC_CODE]; set_global_register(dst_code, dreg); + if (dreg == 0) SR |= Z_MASK; else @@ -1205,16 +1228,14 @@ void hyperstone_device::op38() // or global,global m_icount -= m_clock_cycles_1; } -void hyperstone_device::op39() // or global,local +void hyperstone_device::hyperstone_andn_global_local() { check_delay_PC(); const uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg |= m_local_regs[(SRC_CODE + GET_FP) % 64]; - + const uint32_t dreg = m_global_regs[dst_code] & ~m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; set_global_register(dst_code, dreg); + if (dreg == 0) SR |= Z_MASK; else @@ -1223,11 +1244,76 @@ void hyperstone_device::op39() // or global,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3a() // or local,global +void hyperstone_device::hyperstone_andn_local_global() { check_delay_PC(); - const uint32_t dst_code = (DST_CODE + GET_FP) % 64; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] & ~m_global_regs[SRC_CODE]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_andn_local_local() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] & ~m_local_regs[(SRC_CODE + fp) & 0x3f]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_or_global_global() +{ + check_delay_PC(); + + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] | m_global_regs[SRC_CODE]; + set_global_register(dst_code, dreg); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_or_global_local() +{ + check_delay_PC(); + + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] | m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + set_global_register(dst_code, dreg); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_or_local_global() +{ + check_delay_PC(); + + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; const uint32_t dreg = m_local_regs[dst_code] | m_global_regs[SRC_CODE]; m_local_regs[dst_code] = dreg; @@ -1239,7 +1325,7 @@ void hyperstone_device::op3a() // or local,global m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3b() // or local,local +void hyperstone_device::hyperstone_or_local_local() { check_delay_PC(); @@ -1255,54 +1341,67 @@ void hyperstone_device::op3b() // or local,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3c() // xor global,global +void hyperstone_device::hyperstone_xor_global_global() { check_delay_PC(); const uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg ^= m_global_regs[SRC_CODE]; - + const uint32_t dreg = m_global_regs[dst_code] ^ m_global_regs[SRC_CODE]; set_global_register(dst_code, dreg); - SET_Z(dreg == 0 ? 1 : 0); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3d() // xor +void hyperstone_device::hyperstone_xor_global_local() { check_delay_PC(); - uint32_t dst_code = DST_CODE; - uint32_t dreg = m_global_regs[dst_code]; - - dreg ^= m_local_regs[(SRC_CODE + GET_FP) % 64]; - + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] ^ m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; set_global_register(dst_code, dreg); - SET_Z(dreg == 0 ? 1 : 0); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3e() // xor +void hyperstone_device::hyperstone_xor_local_global() { check_delay_PC(); - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] ^= m_global_regs[SRC_CODE]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] ^ m_global_regs[SRC_CODE]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3f() // xor +void hyperstone_device::hyperstone_xor_local_local() { check_delay_PC(); - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] ^= m_local_regs[(SRC_CODE + GET_FP) % 64]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] ^ m_local_regs[(SRC_CODE + fp) & 0x3f]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } @@ -1338,8 +1437,8 @@ void hyperstone_device::op41() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1363,8 +1462,8 @@ void hyperstone_device::op42() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -1380,59 +1479,77 @@ void hyperstone_device::op43() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_subc(decode); } -void hyperstone_device::op44() // not +void hyperstone_device::hyperstone_not_global_global() // not { check_delay_PC(); - uint32_t dreg = ~m_global_regs[SRC_CODE]; + const uint32_t dreg = ~m_global_regs[SRC_CODE]; set_global_register(DST_CODE, dreg); - SET_Z(dreg == 0 ? 1 : 0); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op45() // not +void hyperstone_device::hyperstone_not_global_local() { check_delay_PC(); - uint32_t dreg = ~m_local_regs[(SRC_CODE + GET_FP) % 64]; + const uint32_t dreg = ~m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; set_global_register(DST_CODE, dreg); - SET_Z(dreg == 0 ? 1 : 0); + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op46() // not +void hyperstone_device::hyperstone_not_local_global() { check_delay_PC(); - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] = ~m_global_regs[SRC_CODE]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = ~m_global_regs[SRC_CODE]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } -void hyperstone_device::op47() // not +void hyperstone_device::hyperstone_not_local_local() { check_delay_PC(); - uint32_t dst_code = (DST_CODE + GET_FP) % 64; - m_local_regs[dst_code] = ~m_local_regs[(SRC_CODE + GET_FP) % 64]; - SET_Z(m_local_regs[dst_code] == 0 ? 1 : 0); + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = ~m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; m_icount -= m_clock_cycles_1; } @@ -1461,7 +1578,7 @@ void hyperstone_device::op49() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1480,7 +1597,7 @@ void hyperstone_device::op4a() SREG = m_global_regs[decode.src]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_sub(decode); } @@ -1498,8 +1615,8 @@ void hyperstone_device::op4b() SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; + if ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) SR |= V_MASK; @@ -1537,7 +1654,7 @@ void hyperstone_device::op4d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1556,7 +1673,7 @@ void hyperstone_device::op4e() SREG = m_global_regs[decode.src]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; hyperstone_subs(decode); } @@ -1569,10 +1686,10 @@ void hyperstone_device::op4f() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_subs(decode); } @@ -1603,7 +1720,7 @@ void hyperstone_device::op51() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1611,20 +1728,50 @@ void hyperstone_device::op51() hyperstone_addc(decode); } -void hyperstone_device::op52() +void hyperstone_device::op52() // addc 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 src_code = SRC_CODE; + const uint32_t sreg = m_global_regs[src_code]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + uint32_t dreg = m_local_regs[dst_code]; - hyperstone_addc(decode); + const bool old_z = (SR & Z_MASK) != 0; + const uint32_t c = SR & C_MASK; + + SR &= ~(V_MASK | C_MASK | Z_MASK | N_MASK); + + uint64_t tmp; + if (src_code == SR_REGISTER) + { + tmp = (uint64_t)dreg + (uint64_t)c; + + if ((dreg ^ tmp) & (c ^ tmp) & 0x80000000) + SR |= V_MASK; + + dreg += c; + } + else + { + tmp = (uint64_t)sreg + (uint64_t)dreg + (uint64_t)c; + + if ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) + SR |= V_MASK; + + dreg += sreg + c; + } + + SR |= (tmp & 0x100000000L) >> 32; + + m_local_regs[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::op53() // addc local,local @@ -1637,13 +1784,13 @@ void hyperstone_device::op53() // addc local,local uint32_t dreg = m_local_regs[dst_code]; const bool old_z = (SR & Z_MASK) != 0; - const uint32_t c = (SR & C_MASK) ? 1 : 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); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; + if ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) SR |= V_MASK; @@ -1681,7 +1828,7 @@ void hyperstone_device::hyperstone_and_global_local() const uint32_t dst_code = DST_CODE; uint32_t dreg = m_global_regs[dst_code]; - dreg &= m_local_regs[(SRC_CODE + GET_FP) % 64]; + dreg &= m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; set_global_register(dst_code, dreg); if (m_local_regs[dst_code] == 0) @@ -1747,7 +1894,7 @@ void hyperstone_device::op59() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1766,7 +1913,7 @@ void hyperstone_device::op5a() SREG = m_global_regs[decode.src]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_neg(decode); } @@ -1782,8 +1929,7 @@ void hyperstone_device::op5b() // neg local,local SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); - if (tmp & 0x100000000L) - SR |= C_MASK; + SR |= (tmp & 0x100000000L) >> 32; if (tmp & sreg & 0x80000000) SR |= V_MASK; @@ -1822,7 +1968,7 @@ void hyperstone_device::op5d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -1841,7 +1987,7 @@ void hyperstone_device::op5e() SREG = m_global_regs[decode.src]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_negs(decode); } @@ -1854,10 +2000,10 @@ void hyperstone_device::op5f() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ hyperstone_negs(decode); } @@ -1967,31 +2113,71 @@ void hyperstone_device::hyperstone_cmpi_local_limm() // cmpi local,long imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op64() +void hyperstone_device::hyperstone_movi_global_simm() { - regs_decode decode; - decode_immediate_u(decode); + const uint32_t extra_u = immediate_values[m_op & 0x0f]; check_delay_PC(); - decode.dst = DST_CODE; - decode_dest(decode, GET_H); - hyperstone_movi(decode); + + uint32_t dst_code = DST_CODE; + if (SR & H_MASK) + { + dst_code += 16; + if (!(SR & S_MASK)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + + set_global_register(dst_code, extra_u); + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + + SR &= ~(Z_MASK | N_MASK); + if (extra_u == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(extra_u); + +#if MISSIONCRAFT_FLAGS + SR &= ~V_MASK; // or V undefined ? +#endif + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op65() +void hyperstone_device::hyperstone_movi_global_limm() { - regs_decode decode; - DECODE_IMMEDIATE_S(decode); + const uint32_t extra_u = decode_immediate_s(); check_delay_PC(); - decode.dst = DST_CODE; - decode_dest(decode, GET_H); - hyperstone_movi(decode); + + uint32_t dst_code = DST_CODE; + if (SR & H_MASK) + { + dst_code += 16; + if (!(SR & S_MASK)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + + set_global_register(dst_code, extra_u); + + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + + SR &= ~(Z_MASK | N_MASK); + if (extra_u == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(extra_u); + +#if MISSIONCRAFT_FLAGS + SR &= ~V_MASK; // or V undefined ? +#endif + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op66() // movi local,short imm +void hyperstone_device::hyperstone_movi_local_simm() { check_delay_PC(); - const uint32_t imm = immediate_values[OP & 0x0f]; + const uint32_t imm = immediate_values[m_op & 0x0f]; m_local_regs[(DST_CODE + GET_FP) & 0x3f] = imm; SR &= ~(Z_MASK | N_MASK); @@ -2006,7 +2192,7 @@ void hyperstone_device::op66() // movi local,short imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op67() // movi local,long imm +void hyperstone_device::hyperstone_movi_local_limm() { const uint32_t extra_u = decode_immediate_s(); check_delay_PC(); @@ -2025,44 +2211,25 @@ void hyperstone_device::op67() // movi local,long imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op68() // addi global,short imm +void hyperstone_device::hyperstone_addi_global_simm() { - regs_decode decode; - decode_immediate_u(decode); - check_delay_PC(); - decode.dst = DST_CODE; - - decode.dst_is_local = 0; - - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; - - hyperstone_addi(decode); -} - -void hyperstone_device::op69() // addi global,long imm -{ - const uint32_t extra_u = decode_immediate_s(); check_delay_PC(); const uint32_t dst_code = DST_CODE; uint32_t dreg = m_global_regs[dst_code]; uint32_t imm; - if (N_VALUE) - { - imm = extra_u; - } + if (N_OP_MASK) + imm = immediate_values[m_op & 0x0f]; else - { imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); - } SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; - if (tmp & 0x100000000L) - SR |= C_MASK; + + SR |= (tmp & 0x100000000L) >> 32; + if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -2079,7 +2246,43 @@ void hyperstone_device::op69() // addi global,long imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op6a() // addi local,short imm +void hyperstone_device::hyperstone_addi_global_limm() +{ + const uint32_t extra_u = decode_immediate_s(); + check_delay_PC(); + + const uint32_t dst_code = DST_CODE; + uint32_t dreg = m_global_regs[dst_code]; + + uint32_t imm; + if (N_OP_MASK) + imm = extra_u; + else + imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + + const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; + + SR |= (tmp & 0x100000000L) >> 32; + + if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) + SR |= V_MASK; + + dreg += imm; + set_global_register(dst_code, dreg); + + if (dst_code == 0) + SR &= ~M_MASK; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_addi_local_simm() { check_delay_PC(); @@ -2088,7 +2291,7 @@ void hyperstone_device::op6a() // addi local,short imm uint32_t dreg = m_local_regs[dst_code]; uint32_t imm; - if (N_VALUE) + if (N_OP_MASK) imm = immediate_values[m_op & 0x0f]; else imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); @@ -2096,8 +2299,9 @@ void hyperstone_device::op6a() // addi local,short imm SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; - if (tmp & 0x100000000L) - SR |= C_MASK; + + SR |= (tmp & 0x100000000L) >> 32; + if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -2111,7 +2315,7 @@ void hyperstone_device::op6a() // addi local,short imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op6b() // addi local,long imm +void hyperstone_device::hyperstone_addi_local_limm() { uint32_t imm = decode_immediate_s(); check_delay_PC(); @@ -2119,14 +2323,15 @@ void hyperstone_device::op6b() // addi local,long imm const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; uint32_t dreg = m_local_regs[dst_code]; - if (!N_VALUE) + if (!N_OP_MASK) imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; - if (tmp & 0x100000000L) - SR |= C_MASK; + + SR |= (tmp & 0x100000000L) >> 32; + if ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) SR |= V_MASK; @@ -2178,8 +2383,8 @@ void hyperstone_device::op6e() decode.dst = DST_CODE; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; hyperstone_addsi(decode); } @@ -2192,30 +2397,46 @@ void hyperstone_device::op6f() decode.dst = DST_CODE; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; hyperstone_addsi(decode); } -void hyperstone_device::op70() +void hyperstone_device::hyperstone_cmpbi_global_simm() { - regs_decode decode; - decode_immediate_u(decode); check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; + const uint32_t dreg = m_global_regs[DST_CODE]; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t n = N_VALUE; + if (n) + { + uint32_t imm; + if (n == 31) + imm = 0x7fffffff; // bit 31 = 0, others = 1 + else + imm = immediate_values[m_op & 0x0f]; - hyperstone_cmpbi(decode); + if (dreg & imm) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + } + else + { + if ((dreg & 0xff000000) == 0 || (dreg & 0x00ff0000) == 0 || (dreg & 0x0000ff00) == 0 || (dreg & 0x000000ff) == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op71() // cmpbi global,long imm +void hyperstone_device::hyperstone_cmpbi_global_limm() { const uint32_t dreg = m_global_regs[DST_CODE]; @@ -2253,7 +2474,7 @@ void hyperstone_device::op71() // cmpbi global,long imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op72() // cmpbi local,short imm +void hyperstone_device::hyperstone_cmpbi_local_simm() { check_delay_PC(); @@ -2288,7 +2509,7 @@ void hyperstone_device::op72() // cmpbi local,short imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op73() // cmpbi local,long imm +void hyperstone_device::hyperstone_cmpbi_local_limm() { const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; @@ -2347,7 +2568,7 @@ void hyperstone_device::op75() // andni global,long imm check_delay_PC(); uint32_t imm; - if (N_VALUE == 31) + if (N_OP_MASK == 0x10f) imm = 0x7fffffff; // bit 31 = 0, others = 1 else imm = extra_u; @@ -2369,7 +2590,7 @@ void hyperstone_device::op76() // andni local,short imm check_delay_PC(); uint32_t imm; - if (N_VALUE == 31) + if (N_OP_MASK == 0x10f) imm = 0x7fffffff; // bit 31 = 0, others = 1 else imm = immediate_values[m_op & 0x0f]; @@ -2395,7 +2616,7 @@ void hyperstone_device::op77() // andni local,long imm const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; uint32_t imm; - if (N_VALUE == 31) + if (N_OP_MASK == 0x10f) imm = 0x7fffffff; // bit 31 = 0, others = 1 else imm = extra_u; @@ -2476,61 +2697,72 @@ void hyperstone_device::hyperstone_ori_local_limm() // ori local,long imm m_icount -= m_clock_cycles_1; } -void hyperstone_device::op7c() +void hyperstone_device::hyperstone_xori_global_simm() { - regs_decode decode; - decode_immediate_u(decode); check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] ^ immediate_values[m_op & 0x0f]; + set_global_register(dst_code, dreg); - hyperstone_xori(decode); + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op7d() +void hyperstone_device::hyperstone_xori_global_limm() { - regs_decode decode; - DECODE_IMMEDIATE_S(decode); + const uint32_t extra_u = decode_immediate_s(); + check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] ^ extra_u; + set_global_register(dst_code, dreg); - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; - hyperstone_xori(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op7e() +void hyperstone_device::hyperstone_xori_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) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] ^ immediate_values[m_op & 0x0f]; + m_local_regs[dst_code] = dreg; - hyperstone_xori(decode); + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op7f() +void hyperstone_device::hyperstone_xori_local_limm() { - regs_decode decode; - DECODE_IMMEDIATE_S(decode); + const uint32_t extra_u = decode_immediate_s(); + check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] ^ extra_u; + m_local_regs[dst_code] = dreg; - hyperstone_xori(decode); + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; } @@ -2577,8 +2809,8 @@ void hyperstone_device::op81() decode.dst = DST_CODE; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; hyperstone_shrdi(decode); } @@ -2698,15 +2930,15 @@ void hyperstone_device::op87() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); decode.same_srcf_dst = 0; hyperstone_sar(decode); @@ -2804,29 +3036,131 @@ void hyperstone_device::op8f() // rol local,local -void hyperstone_device::op90() +void hyperstone_device::hyperstone_ldxx1_global_global() { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = next_1 & 0x3000; + + 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 = 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 srcf_code = src_code + 1; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code == SR_REGISTER) + { + switch (sub_type) + { + case 0x0000: // LDBS.A + m_global_regs[src_code] = (int32_t)(int8_t)READ_B(extra_s); + break; - 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_ldxx1(decode); + case 0x1000: // LDBU.A + m_global_regs[src_code] = READ_B(extra_s); + break; + + case 0x2000: + 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: + switch (extra_s & 3) + { + case 0: // LDW.A + m_global_regs[src_code] = READ_W(extra_s); + break; + case 1: // LDD.A + m_global_regs[src_code] = READ_W(extra_s); + m_global_regs[srcf_code] = READ_W(extra_s + 4); + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // LDW.IOA + m_global_regs[src_code] = IO_READ_W(extra_s); + break; + case 3: // LDD.IOA + m_global_regs[src_code] = IO_READ_W(extra_s); + m_global_regs[srcf_code] = IO_READ_W((extra_s & ~3) + 4); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + else + { + const uint32_t dreg = m_global_regs[dst_code]; + switch (sub_type) + { + case 0x0000: // LDBS.D + m_global_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); + break; + + case 0x1000: // LDBU.D + m_global_regs[src_code] = READ_B(dreg + extra_s); + break; + + case 0x2000: + 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: + switch (extra_s & 3) + { + case 0: // LDW.D + m_global_regs[src_code] = READ_W(dreg + (extra_s & ~1)); + break; + case 1: // LDD.D + m_global_regs[src_code] = READ_W(dreg + (extra_s & ~1)); + m_global_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4); + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // LDW.IOD + m_global_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + break; + case 3: // LDD.IOD + m_global_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + m_global_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op91() // ldxx1 global,local +void hyperstone_device::hyperstone_ldxx1_global_local() { uint16_t next_1 = READ_OP(PC); PC += 2; @@ -2948,7 +3282,7 @@ void hyperstone_device::op91() // ldxx1 global,local m_icount -= m_clock_cycles_1; } -void hyperstone_device::op92() +void hyperstone_device::hyperstone_ldxx1_local_global() { uint16_t next_1 = READ_OP(PC); PC += 2; @@ -3068,7 +3402,7 @@ void hyperstone_device::op92() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op93() +void hyperstone_device::hyperstone_ldxx1_local_local() { uint16_t next_1 = READ_OP(PC); PC += 2; @@ -3147,27 +3481,109 @@ void hyperstone_device::op93() m_icount -= m_clock_cycles_1; } -void hyperstone_device::op94() +void hyperstone_device::op94() // ldxx1 global,global { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = next_1 & 0x3000; + + 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 = 0; + const uint32_t dst_code = DST_CODE; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + if (dst_code < 2) + { + m_icount -= m_clock_cycles_1; + DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC)); + return; + } - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t src_code = SRC_CODE; + const uint32_t dreg = m_global_regs[dst_code]; - 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_ldxx2(decode); + switch (sub_type) + { + case 0x0000: // 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 + m_global_regs[src_code] = READ_B(dreg); + if(src_code != dst_code) + m_global_regs[dst_code] += extra_s; + break; + + case 0x2000: + if (extra_s & 1) // LDHS.N + m_global_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); + else // LDHU.N + m_global_regs[src_code] = READ_HW(dreg); + + if(src_code != dst_code) + m_global_regs[dst_code] += (extra_s & ~1); + break; + + case 0x3000: + switch (extra_s & 3) + { + case 0: // LDW.N + m_global_regs[src_code] = READ_W(dreg); + if(src_code != dst_code) + m_global_regs[dst_code] += extra_s & ~1; + break; + case 1: // LDD.N + m_global_regs[src_code] = READ_W(dreg); + m_global_regs[src_code + 1] = READ_W(dreg + 4); + + if (src_code != dst_code && (src_code + 1) != dst_code) + m_global_regs[dst_code] += extra_s & ~1; + + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // Reserved + DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC)); + break; + case 3: // LDW.S + if (dreg < SP) + m_global_regs[src_code] = READ_W(dreg); + else + m_global_regs[src_code] = m_local_regs[(dreg & 0xfc) >> 2]; + + if (src_code != dst_code) + m_global_regs[dst_code] += extra_s & ~3; + + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; } void hyperstone_device::op95() @@ -3211,56 +3627,56 @@ void hyperstone_device::op95() if (dst_code < 2) { DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC)); + m_icount -= m_clock_cycles_1; + return; } - else + + switch (sub_type) { - switch (sub_type) - { - case 0x0000: // LDBS.N - m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); - set_global_register(dst_code, dreg + extra_s); - break; + case 0x0000: // 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 - m_local_regs[src_code] = READ_B(dreg); - set_global_register(dst_code, dreg + extra_s); - break; + case 0x1000: // LDBU.N + m_local_regs[src_code] = READ_B(dreg); + set_global_register(dst_code, dreg + extra_s); + break; - case 0x2000: - if (extra_s & 1) // LDHS.N - m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); - else // LDHU.N - m_local_regs[src_code] = READ_HW(dreg); - set_global_register(dst_code, dreg + (extra_s & ~1)); - break; + case 0x2000: + if (extra_s & 1) // LDHS.N + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); + else // LDHU.N + m_local_regs[src_code] = READ_HW(dreg); + set_global_register(dst_code, dreg + (extra_s & ~1)); + break; - case 0x3000: - switch (extra_s & 3) - { - case 0: // LDW.N + case 0x3000: + switch (extra_s & 3) + { + case 0: // LDW.N + m_local_regs[src_code] = READ_W(dreg); + set_global_register(dst_code, dreg + (extra_s & ~1)); + break; + case 1: // LDD.N + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[srcf_code] = READ_W(dreg + 4); + 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_ldxx2. PC = %08X\n", PC)); + break; + case 3: // LDW.S + if (dreg < SP) m_local_regs[src_code] = READ_W(dreg); - set_global_register(dst_code, dreg + (extra_s & ~1)); - break; - case 1: // LDD.N - m_local_regs[src_code] = READ_W(dreg); - m_local_regs[srcf_code] = READ_W(dreg + 4); - 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_ldxx2. PC = %08X\n", PC)); - break; - case 3: // LDW.S - if (dreg < SP) - m_local_regs[src_code] = READ_W(dreg); - else - m_local_regs[src_code] = m_local_regs[(dreg & 0xfc) >> 2]; - set_global_register(dst_code, dreg + (extra_s & ~3)); - m_icount -= m_clock_cycles_2; // extra cycles - break; - } - break; - } + else + m_local_regs[src_code] = m_local_regs[(dreg & 0xfc) >> 2]; + 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; @@ -3279,8 +3695,8 @@ void hyperstone_device::op96() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -3379,24 +3795,129 @@ void hyperstone_device::op97() void hyperstone_device::op98() { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = next_1 & 0x3000; + + 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 = 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 dreg = m_global_regs[dst_code]; + const uint32_t sreg = ((src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]); + const uint32_t sregf = ((src_code == SR_REGISTER) ? 0 : m_global_regs[src_code + 1]); - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code == SR_REGISTER) + { + switch (sub_type) + { + case 0x0000: // STBS.A + // TODO: missing trap on range error + WRITE_B(extra_s, (uint8_t)sreg); + break; - 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_stxx1(decode); + case 0x1000: // STBU.A + WRITE_B(extra_s, (uint8_t)sreg); + break; + + case 0x2000: // STHS.A, STHU.A + WRITE_HW(extra_s, (uint16_t)sreg); + // TODO: missing trap on range error with STHS.A + break; + + case 0x3000: + switch (extra_s & 3) + { + case 0: // STW.A + WRITE_W(extra_s & ~1, sreg); + break; + case 1: // STD.A + extra_s &= ~1; + WRITE_W(extra_s, sreg); + WRITE_W(extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // STW.IOA + IO_WRITE_W(extra_s & ~3, sreg); + break; + case 3: // STD.IOA + extra_s &= ~3; + IO_WRITE_W(extra_s, sreg); + IO_WRITE_W(extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + else + { + switch (sub_type) + { + case 0x0000: // STBS.D + // TODO: missing trap on range error + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 0x1000: // STBU.D + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 0x2000: // 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: + switch (extra_s & 3) + { + case 0: // STW.D + WRITE_W(dreg + (extra_s & ~1), sreg); + break; + case 1: // STD.D + extra_s &= ~1; + WRITE_W(dreg + extra_s, sreg); + WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // STW.IOD + IO_WRITE_W(dreg + (extra_s & ~3), sreg); + break; + case 3: // STD.IOD + extra_s &= ~3; + IO_WRITE_W(dreg + extra_s, sreg); + IO_WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + + m_icount -= m_clock_cycles_1; } void hyperstone_device::op99() // stxx1 global,local @@ -3674,27 +4195,100 @@ void hyperstone_device::op9b() // stxx1 local,local void hyperstone_device::op9c() { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = next_1 & 0x3000; + + 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 = 0; - SREG = m_global_regs[decode.src]; - SREGF = m_global_regs[decode.src + 1]; + const uint32_t src_code = SRC_CODE; + uint32_t sreg = (src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]; + uint32_t sregf = (src_code == SR_REGISTER) ? 0 : m_global_regs[src_code + 1]; + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code]; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + if (dst_code < 2) + { + m_icount -= m_clock_cycles_1; + 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_stxx2(decode); + switch (sub_type) + { + case 0x0000: // 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 + WRITE_B(dreg, (uint8_t)sreg); + m_global_regs[dst_code] += extra_s; + break; + + case 0x2000: // 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: + switch (extra_s & 3) + { + case 0: // STW.N + WRITE_W(dreg, sreg); + m_global_regs[dst_code] += extra_s & ~1; + break; + case 1: // STD.N + WRITE_W(dreg, sreg); + m_global_regs[dst_code] += extra_s & ~1; + + if((src_code + 1) == dst_code) + 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 + 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; + m_global_regs[dst_code] += (extra_s & ~3); + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } } -void hyperstone_device::op9d() +void hyperstone_device::op9d() // stxx2 global,lobal { regs_decode decode; decode_dis(decode); @@ -3703,8 +4297,8 @@ void hyperstone_device::op9d() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -3716,26 +4310,92 @@ void hyperstone_device::op9d() hyperstone_stxx2(decode); } -void hyperstone_device::op9e() +void hyperstone_device::op9e() // stxx2 local,global { - regs_decode decode; - decode_dis(decode); + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = next_1 & 0x3000; + + 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 = 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; + const uint32_t sreg = (src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + switch (sub_type) + { + case 0x0000: // STBS.N + // TODO: missing trap on range error + WRITE_B(dreg, (uint8_t)sreg); + m_local_regs[dst_code] += extra_s; + break; - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_stxx2(decode); + case 0x1000: // STBU.N + WRITE_B(dreg, (uint8_t)sreg); + m_local_regs[dst_code] += extra_s; + break; + + case 0x2000: // 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: + switch (extra_s & 3) + { + case 0: // STW.N + WRITE_W(dreg, sreg); + m_local_regs[dst_code] += extra_s & ~1; + break; + case 1: // STD.N + WRITE_W(dreg, sreg); + m_local_regs[dst_code] += extra_s & ~1; + WRITE_W(dreg + 4, (src_code == SR_REGISTER) ? 0 : m_global_regs[src_code + 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; + m_local_regs[dst_code] += extra_s & ~3; + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; } void hyperstone_device::op9f() @@ -3828,34 +4488,31 @@ void hyperstone_device::op9f() -void hyperstone_device::opa0() +void hyperstone_device::hyperstone_shri_global() { - regs_decode decode; check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t dst_code = DST_CODE; - hyperstone_shri(decode); + uint32_t val = m_global_regs[dst_code]; + + SR &= ~(C_MASK | Z_MASK | N_MASK); + + const uint32_t n = N_VALUE; + if (n) + SR |= (val >> (n - 1)) & 1; + + val >>= n; + + m_global_regs[dst_code] = val; + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opa1() -{ - regs_decode decode; - check_delay_PC(); - decode.dst = DST_CODE; - - decode.dst_is_local = 0; - - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; - - hyperstone_shri(decode); -} - -void hyperstone_device::hyperstone_shri_local() // shri local,imm +void hyperstone_device::hyperstone_shri_local() { check_delay_PC(); @@ -3914,8 +4571,8 @@ void hyperstone_device::opa6() decode.dst = DST_CODE; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; hyperstone_sari(decode); } @@ -4049,8 +4706,8 @@ void hyperstone_device::opb1() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -4074,8 +4731,8 @@ void hyperstone_device::opb2() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4141,8 +4798,8 @@ void hyperstone_device::opb5() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; DREG = m_global_regs[decode.dst]; @@ -4166,8 +4823,8 @@ void hyperstone_device::opb6() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4175,54 +4832,251 @@ void hyperstone_device::opb6() hyperstone_muls(decode); } -void hyperstone_device::opb7() +void hyperstone_device::opb7() // muls local,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) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t sreg = m_local_regs[src_code]; - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + 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; + const uint32_t dreg = m_local_regs[dst_code]; - decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); - hyperstone_muls(decode); + 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::opb8() +void hyperstone_device::hyperstone_set_global() { - regs_decode decode; check_delay_PC(); - decode.dst = DST_CODE; - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; + const uint32_t dst_code = DST_CODE; + const uint32_t n = N_VALUE; - hyperstone_set(decode); + if (dst_code < 2) + { + m_icount -= m_clock_cycles_1; + return; + } + + switch (n) + { + // SETADR + case 0: + m_global_regs[dst_code] = (SP & 0xfffffe00) | (GET_FP << 2) | (((SP & 0x100) && (SIGN_BIT(SR) == 0)) ? 1 : 0); + break; + + // Reserved + case 1: + case 16: + case 17: + case 19: + DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC)); + break; + + // SETxx + case 2: + m_global_regs[dst_code] = 1; + break; + + case 3: + m_global_regs[dst_code] = 0; + break; + + case 4: + if (SR & (N_MASK | Z_MASK)) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 5: + if (SR & (N_MASK | Z_MASK)) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 6: + if (SR & N_MASK) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 7: + if (SR & N_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 8: + if (SR & (C_MASK | Z_MASK)) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 9: + if (SR & (C_MASK | Z_MASK)) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 10: + if (SR & C_MASK) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 11: + if (SR & C_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 12: + if (SR & Z_MASK) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 13: + if (SR & Z_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 14: + if (SR & V_MASK) + m_global_regs[dst_code] = 1; + else + m_global_regs[dst_code] = 0; + break; + + case 15: + if (SR & V_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = 1; + break; + + case 18: + m_global_regs[dst_code] = ~0; + break; + + case 20: + if (SR & (N_MASK | Z_MASK)) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 21: + if (SR & (N_MASK | Z_MASK)) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + + case 22: + if (SR & N_MASK) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 23: + if (SR & N_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + + case 24: + if (SR & (C_MASK | Z_MASK)) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 25: + if (SR & (C_MASK | Z_MASK)) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + + case 26: + if (SR & C_MASK) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 27: + if (SR & C_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + + case 28: + if (SR & Z_MASK) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 29: + if (SR & Z_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + + case 30: + if (SR & V_MASK) + m_global_regs[dst_code] = ~0; + else + m_global_regs[dst_code] = 0; + break; + + case 31: + if (SR & V_MASK) + m_global_regs[dst_code] = 0; + else + m_global_regs[dst_code] = ~0; + break; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opb9() -{ - regs_decode decode; - check_delay_PC(); - decode.dst = DST_CODE; - - decode.dst_is_local = 0; - DREG = m_global_regs[decode.dst]; - DREGF = m_global_regs[decode.dst + 1]; - - hyperstone_set(decode); -} - -void hyperstone_device::opba() +void hyperstone_device::hyperstone_set_local() { check_delay_PC(); @@ -4429,19 +5283,6 @@ void hyperstone_device::opba() m_icount -= m_clock_cycles_1; } -void hyperstone_device::opbb() -{ - regs_decode decode; - check_delay_PC(); - decode.dst = DST_CODE; - - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; - - hyperstone_set(decode); -} - void hyperstone_device::opbc() { regs_decode decode; @@ -4471,8 +5312,8 @@ void hyperstone_device::opbd() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 0; @@ -4497,8 +5338,8 @@ void hyperstone_device::opbe() SREGF = m_global_regs[decode.src + 1]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4672,15 +5513,15 @@ void hyperstone_device::opcf() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = (SRC_CODE == DST_CODE); - decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) % 64)); + decode.same_src_dstf = (SRC_CODE == ((DST_CODE + 1) & 0x3f)); decode.same_srcf_dst = 0; hyperstone_do(decode); @@ -4712,8 +5553,8 @@ void hyperstone_device::opd2() decode_source_noh(decode); decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4729,16 +5570,16 @@ void hyperstone_device::opd3() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_lddr(decode); } @@ -4751,8 +5592,8 @@ void hyperstone_device::opd4() decode_source_noh(decode); decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4768,20 +5609,20 @@ void hyperstone_device::opd5() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_ldwp(decode); } -void hyperstone_device::opd6() +void hyperstone_device::opd6() // lddp local,global { regs_decode decode; check_delay_PC(); @@ -4790,8 +5631,8 @@ void hyperstone_device::opd6() decode_source_noh(decode); decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4799,7 +5640,7 @@ void hyperstone_device::opd6() hyperstone_lddp(decode); } -void hyperstone_device::opd7() +void hyperstone_device::opd7() // lddp global,local { check_delay_PC(); @@ -4822,43 +5663,25 @@ void hyperstone_device::opd7() m_icount -= m_clock_cycles_2; } -void hyperstone_device::opd8() +void hyperstone_device::hyperstone_stwr_global() // stwr local,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) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = ((src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]); + WRITE_W(m_local_regs[(DST_CODE + GET_FP) & 0x3f], sreg); - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_stwr(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opd9() +void hyperstone_device::hyperstone_stwr_local() // stwr local,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) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + const uint32_t fp = GET_FP; + WRITE_W(m_local_regs[(DST_CODE + fp) & 0x3f], m_local_regs[(SRC_CODE + fp) & 0x3f]); - decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; - - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); - hyperstone_stwr(decode); + m_icount -= m_clock_cycles_1; } void hyperstone_device::opda() @@ -4870,8 +5693,8 @@ void hyperstone_device::opda() decode_source_noh(decode); decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -4887,35 +5710,33 @@ void hyperstone_device::opdb() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_stdr(decode); } -void hyperstone_device::opdc() +void hyperstone_device::opdc() // stwp global,local { - 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) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = ((src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]); - decode.same_src_dst = 0; - decode.same_src_dstf = 0; - decode.same_srcf_dst = 0; - hyperstone_stwp(decode); + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + WRITE_W(dreg, sreg); + m_local_regs[dst_code] += 4; + + m_icount -= m_clock_cycles_1; } void hyperstone_device::opdd() @@ -4926,16 +5747,16 @@ void hyperstone_device::opdd() decode.dst = DST_CODE; decode.src_is_local = 1; - SREG = m_local_regs[(decode.src + GET_FP) % 64]; - SREGF = m_local_regs[(decode.src + 1 + GET_FP) % 64]; + SREG = m_local_regs[(decode.src + GET_FP) & 0x3f]; + SREGF = m_local_regs[(decode.src + 1 + GET_FP) & 0x3f]; decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; - decode.same_srcf_dst = (((SRC_CODE + 1) % 64) == DST_CODE); + decode.same_srcf_dst = (((SRC_CODE + 1) & 0x3f) == DST_CODE); hyperstone_stwp(decode); } @@ -4948,8 +5769,8 @@ void hyperstone_device::opde() decode_source_noh(decode); decode.dst_is_local = 1; - DREG = m_local_regs[(decode.dst + GET_FP) % 64]; /* registers offset by frame pointer */ - DREGF = m_local_regs[(decode.dst + 1 + GET_FP) % 64]; + DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ + DREGF = m_local_regs[(decode.dst + 1 + GET_FP) & 0x3f]; decode.same_src_dst = 0; decode.same_src_dstf = 0; @@ -5076,10 +5897,17 @@ void hyperstone_device::ope6() void hyperstone_device::ope7() { - int32_t offset = decode_pcrel(); - check_delay_PC(); - if (!GET_C && !GET_Z) + if (SR & (C_MASK | Z_MASK)) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); execute_dbr(offset); + } m_icount -= m_clock_cycles_1; } @@ -5329,31 +6157,37 @@ void hyperstone_device::opef() // call, local source void hyperstone_device::opf0() { - int32_t offset = decode_pcrel(); - check_delay_PC(); - if (GET_V) - execute_br(offset); + if (SR & V_MASK) + { + execute_br(); + } else + { + ignore_pcrel(); + check_delay_PC(); m_icount -= m_clock_cycles_1; + } } void hyperstone_device::opf1() { - int32_t offset = decode_pcrel(); - check_delay_PC(); - if (!GET_V) - execute_br(offset); - else + if (SR & V_MASK) + { + ignore_pcrel(); + check_delay_PC(); m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } } void hyperstone_device::opf2() { if (SR & Z_MASK) { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } else { @@ -5373,9 +6207,7 @@ void hyperstone_device::opf3() } else { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } } @@ -5383,9 +6215,7 @@ void hyperstone_device::opf4() { if (SR & C_MASK) { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } else { @@ -5405,9 +6235,7 @@ void hyperstone_device::opf5() } else { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } } @@ -5415,9 +6243,7 @@ void hyperstone_device::opf6() { if (SR & (C_MASK | Z_MASK)) { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } else { @@ -5437,9 +6263,7 @@ void hyperstone_device::opf7() } else { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } } @@ -5447,9 +6271,7 @@ void hyperstone_device::opf8() { if (SR & N_MASK) { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } else { @@ -5469,9 +6291,7 @@ void hyperstone_device::opf9() } else { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } } @@ -5479,9 +6299,7 @@ void hyperstone_device::opfa() { if (SR & (N_MASK | Z_MASK)) { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } else { @@ -5501,33 +6319,6 @@ void hyperstone_device::opfb() } else { - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); + execute_br(); } } - -void hyperstone_device::opfc() -{ - const int32_t offset = decode_pcrel(); - check_delay_PC(); - execute_br(offset); -} - -void hyperstone_device::opfd() -{ - check_delay_PC(); - hyperstone_trap(); -} - -void hyperstone_device::opfe() -{ - check_delay_PC(); - hyperstone_trap(); -} - -void hyperstone_device::opff() -{ - check_delay_PC(); - hyperstone_trap(); -}