tms34010: Clarify that not all illegal opcodes are actually trapped; separate TMS34020 emulation better

This commit is contained in:
AJR 2021-11-06 19:29:37 -04:00
parent 730d4fa362
commit 74004a24e3
4 changed files with 1693 additions and 947 deletions

View File

@ -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
***************************************************************************/
@ -2031,25 +2035,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 +2092,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 +2160,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 +2230,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 +2352,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 +2397,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
@ -2480,56 +2441,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");
}

File diff suppressed because it is too large Load Diff

View File

@ -228,14 +228,14 @@ inline void tms340x0_device::RESET_ST()
}
/* shortcuts for reading opcodes */
uint32_t tms34010_device::ROPCODE()
uint16_t tms34010_device::ROPCODE()
{
uint32_t pc = m_pc;
m_pc += 2 << 3;
return m_cache.read_word(pc);
}
uint32_t tms34020_device::ROPCODE()
uint16_t tms34020_device::ROPCODE()
{
uint32_t pc = m_pc;
m_pc += 2 << 3;
@ -887,7 +887,7 @@ void tms340x0_device::execute_run()
uint16_t op;
m_ppc = m_pc;
op = ROPCODE();
(this->*s_opcode_table[op >> 4])(op);
execute_op(op);
} while (m_icount > 0);
}
else
@ -898,12 +898,22 @@ void tms340x0_device::execute_run()
m_ppc = m_pc;
debugger_instruction_hook(m_pc);
op = ROPCODE();
(this->*s_opcode_table[op >> 4])(op);
execute_op(op);
} while (m_icount > 0);
}
m_executing = false;
}
void tms34010_device::execute_op(uint16_t op)
{
(this->*s_opcode_table[op >> 4])(op);
}
void tms34020_device::execute_op(uint16_t op)
{
(this->*s_opcode_table[op >> 4])(op);
}
/***************************************************************************

View File

@ -277,7 +277,6 @@ protected:
typedef uint32_t (tms340x0_device::*raster_op_func)(uint32_t newpix, uint32_t oldpix);
typedef void (tms340x0_device::*wfield_func)(offs_t offset, uint32_t data);
typedef uint32_t (tms340x0_device::*rfield_func)(offs_t offset);
typedef void (tms340x0_device::*opcode_func)(uint16_t op);
typedef uint32_t (tms340x0_device::*pixel_op_func)(uint32_t, uint32_t, uint32_t);
typedef void (tms340x0_device::*pixblt_op_func)(int, int);
typedef void (tms340x0_device::*pixblt_b_op_func)(int);
@ -286,7 +285,6 @@ protected:
static const wfield_func s_wfield_functions[32];
static const rfield_func s_rfield_functions[64];
static const opcode_func s_opcode_table[65536 >> 4];
static const pixel_op_func s_pixel_op_table[32];
static const uint8_t s_pixel_op_timing_table[33];
static const pixblt_op_func s_pixblt_op_table[];
@ -360,7 +358,8 @@ protected:
virtual void TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) = 0;
void SET_ST(uint32_t st);
void RESET_ST();
virtual uint32_t ROPCODE() = 0;
virtual uint16_t ROPCODE() = 0;
virtual void execute_op(uint16_t op) = 0;
virtual int16_t PARAM_WORD() = 0;
virtual int32_t PARAM_LONG() = 0;
virtual int16_t PARAM_WORD_NO_INC() = 0;
@ -520,6 +519,7 @@ protected:
uint32_t rfield_s_30(offs_t offset);
uint32_t rfield_s_31(offs_t offset);
void unimpl(uint16_t op);
void illop(uint16_t op);
void pixblt_l_l(uint16_t op); /* 0f00 */
void pixblt_l_xy(uint16_t op); /* 0f20 */
void pixblt_xy_l(uint16_t op); /* 0f40 */
@ -837,59 +837,6 @@ protected:
void rev_a(uint16_t op); /* 0020 */
void rev_b(uint16_t op); /* 0030 */
void trap(uint16_t op); /* 0900/10 */
void addxyi_a(uint16_t op);
void addxyi_b(uint16_t op);
void blmove(uint16_t op);
void cexec_l(uint16_t op);
void cexec_s(uint16_t op);
void clip(uint16_t op);
void cmovcg_a(uint16_t op);
void cmovcg_b(uint16_t op);
void cmovcm_f(uint16_t op);
void cmovcm_b(uint16_t op);
void cmovgc_a(uint16_t op);
void cmovgc_b(uint16_t op);
void cmovgc_a_s(uint16_t op);
void cmovgc_b_s(uint16_t op);
void cmovmc_f(uint16_t op);
void cmovmc_f_va(uint16_t op);
void cmovmc_f_vb(uint16_t op);
void cmovmc_b(uint16_t op);
void cmp_k_a(uint16_t op);
void cmp_k_b(uint16_t op);
void cvdxyl_a(uint16_t op);
void cvdxyl_b(uint16_t op);
void cvmxyl_a(uint16_t op);
void cvmxyl_b(uint16_t op);
void cvsxyl_a(uint16_t op);
void cvsxyl_b(uint16_t op);
void exgps_a(uint16_t op);
void exgps_b(uint16_t op);
void fline(uint16_t op);
void fpixeq(uint16_t op);
void fpixne(uint16_t op);
void getps_a(uint16_t op);
void getps_b(uint16_t op);
void idle(uint16_t op);
void linit(uint16_t op);
void mwait(uint16_t op);
void pfill_xy(uint16_t op);
void pixblt_l_m_l(uint16_t op);
void retm(uint16_t op);
void rmo_a(uint16_t op);
void rmo_b(uint16_t op);
void rpix_a(uint16_t op);
void rpix_b(uint16_t op);
void setcdp(uint16_t op);
void setcmp(uint16_t op);
void setcsp(uint16_t op);
void swapf_a(uint16_t op);
void swapf_b(uint16_t op);
void tfill_xy(uint16_t op);
void trapl(uint16_t op);
void vblt_b_l(uint16_t op);
void vfill_l(uint16_t op);
void vlcol(uint16_t op);
int apply_window(const char *inst_name,int srcbpp, uint32_t *srcaddr, XY *dst, int *dx, int *dy);
int compute_fill_cycles(int left_partials, int right_partials, int full_words, int op_timing);
int compute_pixblt_cycles(int left_partials, int right_partials, int full_words, int op_timing);
@ -1026,7 +973,8 @@ protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
void internal_regs_map(address_map &map);
virtual uint32_t ROPCODE() override;
virtual uint16_t ROPCODE() override;
virtual void execute_op(uint16_t op) override;
virtual int16_t PARAM_WORD() override;
virtual int32_t PARAM_LONG() override;
virtual int16_t PARAM_WORD_NO_INC() override;
@ -1036,7 +984,11 @@ protected:
virtual void TMS34010_WRMEM_WORD(offs_t A, uint32_t V) override;
virtual void TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) override;
typedef void (tms34010_device::*opcode_func)(uint16_t op);
private:
static const opcode_func s_opcode_table[65536 >> 4];
memory_access<32, 1, 3, ENDIANNESS_LITTLE>::cache m_cache;
memory_access<32, 1, 3, ENDIANNESS_LITTLE>::specific m_program;
};
@ -1061,7 +1013,8 @@ protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
void internal_regs_map(address_map &map);
virtual uint32_t ROPCODE() override;
virtual uint16_t ROPCODE() override;
virtual void execute_op(uint16_t op) override;
virtual int16_t PARAM_WORD() override;
virtual int32_t PARAM_LONG() override;
virtual int16_t PARAM_WORD_NO_INC() override;
@ -1071,7 +1024,65 @@ protected:
virtual void TMS34010_WRMEM_WORD(offs_t A, uint32_t V) override;
virtual void TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) override;
typedef void (tms34020_device::*opcode_func)(uint16_t op);
void addxyi_a(uint16_t op);
void addxyi_b(uint16_t op);
void blmove(uint16_t op);
void cexec_l(uint16_t op);
void cexec_s(uint16_t op);
void clip(uint16_t op);
void cmovcg_a(uint16_t op);
void cmovcg_b(uint16_t op);
void cmovcm_f(uint16_t op);
void cmovcm_b(uint16_t op);
void cmovgc_a(uint16_t op);
void cmovgc_b(uint16_t op);
void cmovgc_a_s(uint16_t op);
void cmovgc_b_s(uint16_t op);
void cmovmc_f(uint16_t op);
void cmovmc_f_va(uint16_t op);
void cmovmc_f_vb(uint16_t op);
void cmovmc_b(uint16_t op);
void cmp_k_a(uint16_t op);
void cmp_k_b(uint16_t op);
void cvdxyl_a(uint16_t op);
void cvdxyl_b(uint16_t op);
void cvmxyl_a(uint16_t op);
void cvmxyl_b(uint16_t op);
void cvsxyl_a(uint16_t op);
void cvsxyl_b(uint16_t op);
void exgps_a(uint16_t op);
void exgps_b(uint16_t op);
void fline(uint16_t op);
void fpixeq(uint16_t op);
void fpixne(uint16_t op);
void getps_a(uint16_t op);
void getps_b(uint16_t op);
void idle(uint16_t op);
void linit(uint16_t op);
void mwait(uint16_t op);
void pfill_xy(uint16_t op);
void pixblt_l_m_l(uint16_t op);
void retm(uint16_t op);
void rmo_a(uint16_t op);
void rmo_b(uint16_t op);
void rpix_a(uint16_t op);
void rpix_b(uint16_t op);
void setcdp(uint16_t op);
void setcmp(uint16_t op);
void setcsp(uint16_t op);
void swapf_a(uint16_t op);
void swapf_b(uint16_t op);
void tfill_xy(uint16_t op);
void trapl(uint16_t op);
void vblt_b_l(uint16_t op);
void vfill_l(uint16_t op);
void vlcol(uint16_t op);
private:
static const opcode_func s_opcode_table[65536 >> 4];
memory_access<32, 2, 3, ENDIANNESS_LITTLE>::cache m_cache;
memory_access<32, 2, 3, ENDIANNESS_LITTLE>::specific m_program;
};