tms32082: Internal address map + more opcodes.

This commit is contained in:
Ville Linde 2013-07-18 16:28:40 +00:00
parent 01d30659d8
commit 280c58d3c9
3 changed files with 175 additions and 5 deletions

View File

@ -11,13 +11,73 @@
#define OP_SIMM15() ((m_ir & 0x4000) ? (0xffffe000 | (m_ir & 0x7fff)) : (m_ir & 0x7fff))
#define OP_UIMM15() (m_ir & 0x7fff)
#define OP_BITNUM() ((m_ir >> 27) & 0x1f)
#define OP_ROTATE() (m_ir & 0x1f)
#define OP_ENDMASK() ((m_ir >> 5) & 0x1f)
#define OP_SRC1() (m_ir & 0x1f)
#define ROTATE_L(x, r) ((x << r) | (x >> (32-r)))
#define ROTATE_R(x, r) ((x >> r) | (x << (32-r)))
void tms32082_mp_device::execute_short_imm()
{
switch ((m_ir >> 15) & 0x7f)
{
case 0x04: // rdcr
{
int rd = OP_RD();
INT32 imm = OP_SIMM15();
UINT32 r = read_creg(imm);
if (rd)
m_reg[rd] = r;
break;
}
case 0x05: // swcr
{
int rd = OP_RD();
int rs = OP_RS();
INT32 imm = OP_SIMM15();
UINT32 r = read_creg(imm);
if (rd)
m_reg[rd] = r;
write_creg(imm, m_reg[rs]);
break;
}
case 0x0e: // shift.iz
{
int r = (m_ir & (1 << 10));
int inv = (m_ir & (1 << 11));
int rot = OP_ROTATE();
int source = m_reg[OP_RS()];
int rd = OP_RD();
UINT32 endmask = SHIFT_MASK[OP_ENDMASK()];
if (inv) endmask = ~endmask;
UINT32 shiftmask = SHIFT_MASK[rot];
UINT32 compmask = endmask & ~shiftmask;
UINT32 res = 0;
if (r) // right
{
res = (ROTATE_R(source, rot) & compmask) | (m_reg[rd] & ~compmask);
}
else // left
{
res = (ROTATE_L(source, rot) & compmask) | (m_reg[rd] & ~compmask);
}
if (rd)
m_reg[rd] = res;
break;
}
case 0x17: // or
{
int rd = OP_RD();
@ -29,6 +89,23 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x36:
case 0x32: // st
{
int rd = OP_RD();
int base = OP_BASE();
int m = m_ir & (1 << 17);
INT32 offset = OP_SIMM15();
UINT32 address = m_reg[base] + offset;
m_program->write_dword(address, m_reg[rd]);
if (m && base)
m_reg[base] = address;
break;
}
case 0x49: // bbz.a
{
int bitnum = OP_BITNUM();
@ -42,6 +119,30 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x4b: // bbo.a
{
int bitnum = OP_BITNUM();
INT32 offset = OP_SIMM15();
int rs = OP_RS();
if ((m_reg[rs] & (1 << bitnum)) != 0)
{
m_fetchpc = m_pc + (offset * 4);
}
break;
}
case 0x59: // addu
{
INT32 imm = OP_SIMM15();
int rd = OP_RD();
int rs = OP_RS();
if (rd)
m_reg[rd] = m_reg[rs] + imm;
break;
}
default:
fatalerror("tms32082_mp_device::execute_short_imm(): opcode %08X (%02X)", m_ir, (m_ir >> 15) & 0x7f);
}
@ -51,18 +152,21 @@ void tms32082_mp_device::execute_reg_long_imm()
{
UINT32 imm32 = 0;
if (m_ir & (1 << 12))
int has_imm = (m_ir & (1 << 12));
if (has_imm)
imm32 = fetch();
switch ((m_ir >> 12) & 0xff)
{
case 0x2e:
case 0x2f: // or
{
int rd = OP_RD();
int rs = OP_RS();
if (rd)
m_reg[rd] = m_reg[rs] | imm32;
m_reg[rd] = m_reg[rs] | (has_imm ? imm32 : m_reg[OP_SRC1()]);
break;
}
@ -75,7 +179,7 @@ void tms32082_mp_device::execute_reg_long_imm()
int base = OP_BASE();
int rd = OP_RD();
UINT32 address = m_reg[base] + (imm32 << shift);
UINT32 address = m_reg[base] + ((has_imm ? imm32 : m_reg[OP_SRC1()]) << shift);
if (rd)
{
m_reg[rd] = m_program->read_word(address);
@ -88,6 +192,23 @@ void tms32082_mp_device::execute_reg_long_imm()
break;
}
case 0x6d:
case 0x65: // st
{
int shift = (m_ir & (1 << 11)) ? 2 : 0;
int m = m_ir & (1 << 15);
int base = OP_BASE();
UINT32 address = m_reg[base] + ((has_imm ? imm32 : m_reg[OP_SRC1()]) << shift);
m_program->write_dword(address, m_reg[OP_RD()]);
if (m && base)
m_reg[base] = address;
break;
}
case 0x8a:
case 0x8b: // jsr.a
{
int link = OP_LINK();
@ -96,7 +217,7 @@ void tms32082_mp_device::execute_reg_long_imm()
if (link)
m_reg[link] = m_fetchpc;
m_fetchpc = m_reg[base] + (INT32)(imm32);
m_fetchpc = m_reg[base] + (has_imm ? imm32 : m_reg[OP_SRC1()]);
break;
}

View File

@ -13,11 +13,28 @@ extern CPU_DISASSEMBLE(tms32082_mp);
const device_type TMS32082_MP = &device_creator<tms32082_mp_device>;
// internal memory map
static ADDRESS_MAP_START(internal_map, AS_PROGRAM, 32, tms32082_mp_device)
AM_RANGE(0x01010000, 0x010107ff) AM_READWRITE(mp_param_r, mp_param_w)
ADDRESS_MAP_END
const UINT32 tms32082_mp_device::SHIFT_MASK[] =
{
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
0xffffffff
};
tms32082_mp_device::tms32082_mp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, TMS32082_MP, "TMS32082 MP", tag, owner, clock, "tms32082_mp", __FILE__)
, m_program_config("program", ENDIANNESS_BIG, 32, 32, 0)
, m_program_config("program", ENDIANNESS_BIG, 32, 32, 0, ADDRESS_MAP_NAME(internal_map))
{
}
@ -29,6 +46,19 @@ offs_t tms32082_mp_device::disasm_disassemble(char *buffer, offs_t pc, const UIN
READ32_MEMBER(tms32082_mp_device::mp_param_r)
{
printf("mp_param_w: %08X, %08X\n", offset, mem_mask);
return 0;
}
WRITE32_MEMBER(tms32082_mp_device::mp_param_w)
{
printf("mp_param_w: %08X, %08X, %08X\n", offset, data, mem_mask);
}
void tms32082_mp_device::device_start()
{
m_program = &space(AS_PROGRAM);
@ -113,6 +143,17 @@ void tms32082_mp_device::device_reset()
m_acc[3] = 0;
}
UINT32 tms32082_mp_device::read_creg(int reg)
{
printf("read_creg(): %08X\n", reg);
return 0;
}
void tms32082_mp_device::write_creg(int reg, UINT32 data)
{
printf("write_creg(): %08X, %08X\n", reg, data);
}
UINT32 tms32082_mp_device::fetch()
{
UINT32 w = m_direct->read_decrypted_dword(m_fetchpc);

View File

@ -50,6 +50,9 @@ public:
MP_ACC3,
};
DECLARE_READ32_MEMBER(mp_param_r);
DECLARE_WRITE32_MEMBER(mp_param_w);
protected:
// device level overrides
@ -82,6 +85,9 @@ protected:
address_space_config m_program_config;
static const UINT32 SHIFT_MASK[33];
UINT32 m_pc;
UINT32 m_fetchpc;
UINT32 m_reg[32];
@ -97,6 +103,8 @@ protected:
void execute();
void execute_short_imm();
void execute_reg_long_imm();
UINT32 read_creg(int reg);
void write_creg(int reg, UINT32 data);
};
extern const device_type TMS32082_MP;