tms32082: more MP opcodes (nw)

This commit is contained in:
Ville Linde 2013-08-10 17:39:27 +00:00
parent 2ef54e2487
commit bfaded856a
2 changed files with 159 additions and 3 deletions

View File

@ -186,6 +186,14 @@ void tms32082_mp_device::execute_short_imm()
{
switch ((m_ir >> 15) & 0x7f)
{
case 0x02: // cmnd
{
UINT32 data = OP_UIMM15();
processor_command(data);
break;
}
case 0x04: // rdcr
{
int rd = OP_RD();
@ -212,6 +220,25 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x06: // brcr
{
int cr = OP_UIMM15();
if (cr == 0x0001)
{
// ignore jump to EIP because of how we emulate the pipeline
}
else
{
UINT32 data = read_creg(cr);
m_fetchpc = data & ~3;
m_ie = (m_ie & ~1) | (data & 1); // global interrupt mask from creg
// TODO: user/supervisor latch from creg
}
break;
}
case 0x08: // shift.dz
{
int r = (m_ir & (1 << 10));
@ -303,6 +330,36 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x0c: // shift.em
{
int r = (m_ir & (1 << 10));
int inv = (m_ir & (1 << 11));
int rot = OP_ROTATE();
int end = OP_ENDMASK();
UINT32 source = m_reg[OP_RS()];
int rd = OP_RD();
UINT32 endmask = SHIFT_MASK[end ? end : 32];
if (inv) endmask = ~endmask;
UINT32 shiftmask = SHIFT_MASK[r ? 32-rot : 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 0x0d: // shift.es
{
int r = (m_ir & (1 << 10));
@ -654,6 +711,24 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x4a: // bbo
{
int bitnum = OP_BITNUM() ^ 0x1f;
INT32 offset = OP_SIMM15();
int rs = OP_RS();
if ((m_reg[rs] & (1 << bitnum)) != 0)
{
UINT32 address = m_pc + (offset * 4);
m_pc = m_fetchpc;
delay_slot();
m_fetchpc = address;
}
break;
}
case 0x4b: // bbo.a
{
int bitnum = OP_BITNUM() ^ 0x1f;
@ -709,6 +784,19 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x58: // add
{
INT32 imm = OP_SIMM15();
int rd = OP_RD();
int rs = OP_RS();
if (rd)
m_reg[rd] = m_reg[rs] + imm;
// TODO: integer overflow exception
break;
}
case 0x59: // addu
{
INT32 imm = OP_SIMM15();
@ -720,6 +808,19 @@ void tms32082_mp_device::execute_short_imm()
break;
}
case 0x5a: // sub
{
INT32 imm = OP_SIMM15();
int rd = OP_RD();
int rs = OP_RS();
if (rd)
m_reg[rd] = imm - m_reg[rs];
// TODO: integer overflow exception
break;
}
case 0x5b: // subu
{
INT32 imm = OP_SIMM15();
@ -950,6 +1051,26 @@ void tms32082_mp_device::execute_reg_long_imm()
break;
}
case 0x58:
case 0x59:
case 0x50:
case 0x51: // ld.ub
{
int m = m_ir & (1 << 15);
int base = OP_BASE();
int rd = OP_RD();
UINT32 address = m_reg[base] + (has_imm ? imm32 : m_reg[OP_SRC1()]);
UINT32 r = (UINT8)(m_program->read_byte(address));
if (rd)
m_reg[rd] = r;
if (m && base)
m_reg[base] = address;
break;
}
case 0x5a:
case 0x5b:
case 0x52:
@ -1175,8 +1296,8 @@ void tms32082_mp_device::execute_reg_long_imm()
else
{
// destination accumulator
if (pd != 3)
fatalerror("vrnd pd = %d\n", pd);
if (pd != 1)
fatalerror("vrnd pd = %d at %08X\n", pd, m_pc);
m_facc[acc] = source;
}

View File

@ -22,6 +22,12 @@ const device_type TMS32082_PP = &device_creator<tms32082_pp_device>;
// internal memory map
static ADDRESS_MAP_START(mp_internal_map, AS_PROGRAM, 32, tms32082_mp_device)
AM_RANGE(0x00000000, 0x00000fff) AM_RAM AM_SHARE("pp0_data0")
AM_RANGE(0x00001000, 0x00001fff) AM_RAM AM_SHARE("pp1_data0")
AM_RANGE(0x00008000, 0x00008fff) AM_RAM AM_SHARE("pp0_data1")
AM_RANGE(0x00009000, 0x00009fff) AM_RAM AM_SHARE("pp1_data1")
AM_RANGE(0x01000000, 0x01000fff) AM_RAM AM_SHARE("pp0_param")
AM_RANGE(0x01001000, 0x01001fff) AM_RAM AM_SHARE("pp1_param")
AM_RANGE(0x01010000, 0x010107ff) AM_READWRITE(mp_param_r, mp_param_w)
ADDRESS_MAP_END
@ -273,18 +279,33 @@ void tms32082_mp_device::processor_command(UINT32 command)
// PP0
if (command & 1)
{
if (command & 0x20004000)
if (command & 0x00004000)
{
// simulate PP behavior for now...
m_program->write_dword(0x00000084, 3);
}
}
// PP1
if (command & 2)
{
if (command & 0x00004000)
{
// simulate PP behavior for now...
m_program->write_dword(0x00001014, 3);
}
}
}
UINT32 tms32082_mp_device::read_creg(int reg)
{
switch (reg)
{
case 0x0: // EPC
return m_epc;
case 0x1: // EIP
return m_eip;
case 0x4: // INTPEN
return m_intpen;
@ -314,6 +335,14 @@ void tms32082_mp_device::write_creg(int reg, UINT32 data)
{
switch (reg)
{
case 0x0: // EPC
m_epc = data;
break;
case 0x1: // EIP
m_eip = data;
break;
case 0x4: // INTPEN
{
for (int i=0; i < 32; i++)
@ -437,6 +466,12 @@ void tms32082_mp_device::execute_run()
// internal memory map
static ADDRESS_MAP_START(pp_internal_map, AS_PROGRAM, 32, tms32082_pp_device)
AM_RANGE(0x00000000, 0x00000fff) AM_RAM AM_SHARE("pp0_data0")
AM_RANGE(0x00001000, 0x00001fff) AM_RAM AM_SHARE("pp1_data0")
AM_RANGE(0x00008000, 0x00008fff) AM_RAM AM_SHARE("pp0_data1")
AM_RANGE(0x00009000, 0x00009fff) AM_RAM AM_SHARE("pp1_data1")
AM_RANGE(0x01000000, 0x01000fff) AM_RAM AM_SHARE("pp0_param")
AM_RANGE(0x01001000, 0x01001fff) AM_RAM AM_SHARE("pp1_param")
ADDRESS_MAP_END
tms32082_pp_device::tms32082_pp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)