diff options
Diffstat (limited to 'src/devices/cpu/tms34010/34010ops.hxx')
-rw-r--r-- | src/devices/cpu/tms34010/34010ops.hxx | 201 |
1 files changed, 76 insertions, 125 deletions
diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx index 1c71439107e..bb4791d9d76 100644 --- a/src/devices/cpu/tms34010/34010ops.hxx +++ b/src/devices/cpu/tms34010/34010ops.hxx @@ -78,17 +78,20 @@ static const uint8_t fw_inc[32] = { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 void tms340x0_device::unimpl(uint16_t op) { - /* kludge for Super High Impact -- this doesn't seem to cause */ - /* an illegal opcode exception */ - if (space(AS_PROGRAM).read_word(m_pc - 0x10) == 0x0007) - return; + // Not all illegal opcodes cause TRAP 30 exceptions on TMS34010, and some games only work because of this: - /* 9 Ball Shootout calls to FFDF7468, expecting it */ - /* to execute the next instruction from FFDF7470 */ - /* but the instruction at FFDF7460 is an 0x0001 */ - if (space(AS_PROGRAM).read_word(m_pc - 0x10) == 0x0001) - return; + // 9 Ball Shootout calls to FFDF7468, expecting it + // to execute the next instruction from FFDF7470 + // but the instruction at FFDF7460 is an 0x0001 + + // Super High Impact executes 0x0007 at various entry points + logerror("TMS34010 reserved opcode %04Xh encountered at %08x\n", op, m_ppc); + COUNT_CYCLES(1); +} + +void tms340x0_device::illop(uint16_t op) +{ PUSH(m_pc); PUSH(m_st); RESET_ST(); @@ -96,15 +99,16 @@ void tms340x0_device::unimpl(uint16_t op) COUNT_UNKNOWN_CYCLES(16); /* extra check to prevent bad things */ +#if 0 if (m_pc == 0 || s_opcode_table[space(AS_PROGRAM).read_word(m_pc) >> 4] == &tms34010_device::unimpl) { set_input_line(INPUT_LINE_HALT, ASSERT_LINE); machine().debug_break(); } +#endif } - /*************************************************************************** X/Y OPERATIONS ***************************************************************************/ @@ -521,8 +525,7 @@ void tms340x0_device::dint(uint16_t op) int64_t dividend = ((uint64_t)*rd1 << 32) | (uint32_t)*rd2; \ int64_t quotient = dividend / *rs; \ int32_t remainder = dividend % *rs; \ - uint32_t signbits = (int32_t)quotient >> 31; \ - if (extract_64hi(quotient) != signbits) \ + if ((int64_t)(int32_t)quotient != quotient) \ { \ SET_V_LOG(1); \ } \ @@ -569,7 +572,7 @@ void tms340x0_device::divs_b(uint16_t op) { DIVS(B); } uint64_t dividend = ((uint64_t)*rd1 << 32) | (uint32_t)*rd2; \ uint64_t quotient = dividend / (uint32_t)*rs; \ uint32_t remainder = dividend % (uint32_t)*rs; \ - if (extract_64hi(quotient) != 0) \ + if (quotient > 0xffffffff) \ { \ SET_V_LOG(1); \ } \ @@ -736,8 +739,8 @@ void tms340x0_device::modu_b(uint16_t op) { MODU(B); } SET_Z_LOG(product == 0); \ SET_N_BIT(product >> 32, 31); \ \ - *rd1 = extract_64hi(product); \ - R##REG(DSTREG(op)|1) = extract_64lo(product); \ + *rd1 = (int32_t)(product >> 32); \ + R##REG(DSTREG(op)|1) = product & 0xffffffff; \ \ COUNT_CYCLES(20); \ } @@ -755,8 +758,8 @@ void tms340x0_device::mpys_b(uint16_t op) { MPYS(B); } product = mulu_32x32(m1, *rd1); \ SET_Z_LOG(product == 0); \ \ - *rd1 = extract_64hi(product); \ - R##REG(DSTREG(op)|1) = extract_64lo(product); \ + *rd1 = (int32_t)(product >> 32); \ + R##REG(DSTREG(op)|1) = product & 0xffffffff; \ \ COUNT_CYCLES(21); \ } @@ -2031,25 +2034,21 @@ New 34020 ops: SET_V_BIT_LO(b->x, 15); \ COUNT_CYCLES(1); \ } -void tms340x0_device::addxyi_a(uint16_t op) +void tms34020_device::addxyi_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } ADD_XYI(A); } -void tms340x0_device::addxyi_b(uint16_t op) +void tms34020_device::addxyi_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } ADD_XYI(B); } -void tms340x0_device::blmove(uint16_t op) +void tms34020_device::blmove(uint16_t op) { offs_t src = BREG(0); offs_t dst = BREG(2); offs_t bits = BREG(7); - if (!m_is_34020) { unimpl(op); return; } - bool S = op & (1 << 1); bool D = op & (1 << 0); @@ -2092,21 +2091,18 @@ void tms340x0_device::blmove(uint16_t op) m_pc -= 0x10; } -void tms340x0_device::cexec_l(uint16_t op) +void tms34020_device::cexec_l(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cexec_l\n"); } -void tms340x0_device::cexec_s(uint16_t op) +void tms34020_device::cexec_s(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cexec_s\n"); } -void tms340x0_device::clip(uint16_t op) +void tms34020_device::clip(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } XY daddr = DADDR_XY(); XY wstart = WSTART_XY(); XY wend = WEND_XY(); @@ -2163,75 +2159,63 @@ void tms340x0_device::clip(uint16_t op) COUNT_CYCLES(3); } -void tms340x0_device::cmovcg_a(uint16_t op) +void tms34020_device::cmovcg_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovcg_a\n"); } -void tms340x0_device::cmovcg_b(uint16_t op) +void tms34020_device::cmovcg_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovcg_b\n"); } -void tms340x0_device::cmovcm_f(uint16_t op) +void tms34020_device::cmovcm_f(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovcm_f\n"); } -void tms340x0_device::cmovcm_b(uint16_t op) +void tms34020_device::cmovcm_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovcm_b\n"); } -void tms340x0_device::cmovgc_a(uint16_t op) +void tms34020_device::cmovgc_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovgc_a\n"); } -void tms340x0_device::cmovgc_b(uint16_t op) +void tms34020_device::cmovgc_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovgc_b\n"); } -void tms340x0_device::cmovgc_a_s(uint16_t op) +void tms34020_device::cmovgc_a_s(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovgc_a_s\n"); } -void tms340x0_device::cmovgc_b_s(uint16_t op) +void tms34020_device::cmovgc_b_s(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovgc_b_s\n"); } -void tms340x0_device::cmovmc_f(uint16_t op) +void tms34020_device::cmovmc_f(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovmc_f\n"); } -void tms340x0_device::cmovmc_f_va(uint16_t op) +void tms34020_device::cmovmc_f_va(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovmc_f_va\n"); } -void tms340x0_device::cmovmc_f_vb(uint16_t op) +void tms34020_device::cmovmc_f_vb(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovmc_f_vb\n"); } -void tms340x0_device::cmovmc_b(uint16_t op) +void tms34020_device::cmovmc_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cmovmc_b\n"); } @@ -2245,127 +2229,106 @@ void tms340x0_device::cmovmc_b(uint16_t op) SET_NZCV_SUB(*rd,t,r); \ COUNT_CYCLES(1); \ } -void tms340x0_device::cmp_k_a(uint16_t op) +void tms34020_device::cmp_k_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } CMPK(A); } -void tms340x0_device::cmp_k_b(uint16_t op) +void tms34020_device::cmp_k_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } CMPK(B); } -void tms340x0_device::cvdxyl_a(uint16_t op) +void tms34020_device::cvdxyl_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvdxyl_a\n"); } -void tms340x0_device::cvdxyl_b(uint16_t op) +void tms34020_device::cvdxyl_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvdxyl_b\n"); } -void tms340x0_device::cvmxyl_a(uint16_t op) +void tms34020_device::cvmxyl_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvmxyl_a\n"); } -void tms340x0_device::cvmxyl_b(uint16_t op) +void tms34020_device::cvmxyl_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvmxyl_b\n"); } -void tms340x0_device::cvsxyl_a(uint16_t op) +void tms34020_device::cvsxyl_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvsxyl_a\n"); } -void tms340x0_device::cvsxyl_b(uint16_t op) +void tms34020_device::cvsxyl_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:cvsxyl_b\n"); } -void tms340x0_device::exgps_a(uint16_t op) +void tms34020_device::exgps_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:exgps_a\n"); } -void tms340x0_device::exgps_b(uint16_t op) +void tms34020_device::exgps_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:exgps_b\n"); } -void tms340x0_device::fline(uint16_t op) +void tms34020_device::fline(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:fline\n"); } -void tms340x0_device::fpixeq(uint16_t op) +void tms34020_device::fpixeq(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:fpixeq\n"); } -void tms340x0_device::fpixne(uint16_t op) +void tms34020_device::fpixne(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:fpixne\n"); } -void tms340x0_device::getps_a(uint16_t op) +void tms34020_device::getps_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:getps_a\n"); } -void tms340x0_device::getps_b(uint16_t op) +void tms34020_device::getps_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:getps_b\n"); } -void tms340x0_device::idle(uint16_t op) +void tms34020_device::idle(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:idle\n"); } -void tms340x0_device::linit(uint16_t op) +void tms34020_device::linit(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:linit\n"); } -void tms340x0_device::mwait(uint16_t op) +void tms34020_device::mwait(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } } -void tms340x0_device::pfill_xy(uint16_t op) +void tms34020_device::pfill_xy(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:pfill_xy\n"); } -void tms340x0_device::pixblt_l_m_l(uint16_t op) +void tms34020_device::pixblt_l_m_l(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:pixblt_l_m_l\n"); } -void tms340x0_device::retm(uint16_t op) +void tms34020_device::retm(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:retm\n"); } @@ -2388,8 +2351,8 @@ void tms340x0_device::retm(uint16_t op) COUNT_CYCLES(1); \ } -void tms340x0_device::rmo_a(uint16_t op) { RMO(A); } -void tms340x0_device::rmo_b(uint16_t op) { RMO(B); } +void tms34020_device::rmo_a(uint16_t op) { RMO(A); } +void tms34020_device::rmo_b(uint16_t op) { RMO(B); } #define RPIX(R) \ { \ @@ -2433,21 +2396,18 @@ void tms340x0_device::rmo_b(uint16_t op) { RMO(B); } R##REG(DSTREG(op)) = v; \ } -void tms340x0_device::rpix_a(uint16_t op) +void tms34020_device::rpix_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } RPIX(A); } -void tms340x0_device::rpix_b(uint16_t op) +void tms34020_device::rpix_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } RPIX(B); } -void tms340x0_device::setcdp(uint16_t op) +void tms34020_device::setcdp(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } off_t dptch = DPTCH(); // Check whether we're dealing with an even number @@ -2458,16 +2418,16 @@ void tms340x0_device::setcdp(uint16_t op) // .. only single bit set, pitch is power of two! case 1: { - m_convdp = 32 - count_leading_zeros(dptch); + m_convdp = 32 - count_leading_zeros_32(dptch); COUNT_CYCLES(4); return; } // .. two bits, we can decompose it to sum of two power of two numbers case 2: { - uint8_t first_one = count_leading_zeros(dptch); + uint8_t first_one = count_leading_zeros_32(dptch); uint8_t v1 = 32 - first_one; - uint8_t v2 = 32 - count_leading_zeros(dptch & ~(1 << (first_one - 1))); + uint8_t v2 = 32 - count_leading_zeros_32(dptch & ~(1 << (first_one - 1))); m_convdp = v2 | (v1 << 8); COUNT_CYCLES(6); @@ -2480,56 +2440,47 @@ void tms340x0_device::setcdp(uint16_t op) COUNT_CYCLES(3); } -void tms340x0_device::setcmp(uint16_t op) +void tms34020_device::setcmp(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:setcmp\n"); } -void tms340x0_device::setcsp(uint16_t op) +void tms34020_device::setcsp(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:setcsp\n"); } -void tms340x0_device::swapf_a(uint16_t op) +void tms34020_device::swapf_a(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:swapf_a\n"); } -void tms340x0_device::swapf_b(uint16_t op) +void tms34020_device::swapf_b(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:swapf_b\n"); } -void tms340x0_device::tfill_xy(uint16_t op) +void tms34020_device::tfill_xy(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:tfill_xy\n"); } -void tms340x0_device::trapl(uint16_t op) +void tms34020_device::trapl(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:trapl\n"); } -void tms340x0_device::vblt_b_l(uint16_t op) +void tms34020_device::vblt_b_l(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:vblt_b_l\n"); } -void tms340x0_device::vfill_l(uint16_t op) +void tms34020_device::vfill_l(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:vfill_l\n"); } -void tms340x0_device::vlcol(uint16_t op) +void tms34020_device::vlcol(uint16_t op) { - if (!m_is_34020) { unimpl(op); return; } logerror("020:vlcol\n"); } |