mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
tms32082: more improvements
This commit is contained in:
parent
2998430da7
commit
0281277625
@ -34,6 +34,44 @@ static UINT32 fetch(void)
|
||||
return d;
|
||||
}
|
||||
|
||||
static char* get_creg_name(UINT32 reg)
|
||||
{
|
||||
static char buffer[64];
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0x0000: sprintf(buffer, "EPC"); break;
|
||||
case 0x0001: sprintf(buffer, "EIP"); break;
|
||||
case 0x0002: sprintf(buffer, "CONFIG"); break;
|
||||
case 0x0004: sprintf(buffer, "INTPEN"); break;
|
||||
case 0x0006: sprintf(buffer, "IE"); break;
|
||||
case 0x0008: sprintf(buffer, "FPST"); break;
|
||||
case 0x000a: sprintf(buffer, "PPERROR"); break;
|
||||
case 0x000d: sprintf(buffer, "PKTREQ"); break;
|
||||
case 0x000e: sprintf(buffer, "TCOUNT"); break;
|
||||
case 0x000f: sprintf(buffer, "TSCALE"); break;
|
||||
case 0x0010: sprintf(buffer, "FLTOP"); break;
|
||||
case 0x0011: sprintf(buffer, "FLTADR"); break;
|
||||
case 0x0012: sprintf(buffer, "FLTTAG"); break;
|
||||
case 0x0013: sprintf(buffer, "FLTDTL"); break;
|
||||
case 0x0014: sprintf(buffer, "FLTDTH"); break;
|
||||
case 0x0020: sprintf(buffer, "SYSSTK"); break;
|
||||
case 0x0021: sprintf(buffer, "SYSTMP"); break;
|
||||
case 0x0030: sprintf(buffer, "MPC"); break;
|
||||
case 0x0031: sprintf(buffer, "MIP"); break;
|
||||
case 0x0033: sprintf(buffer, "ECOMCNTL"); break;
|
||||
case 0x0034: sprintf(buffer, "ANASTAT"); break;
|
||||
case 0x0039: sprintf(buffer, "BRK1"); break;
|
||||
case 0x003a: sprintf(buffer, "BRK2"); break;
|
||||
case 0x4000: sprintf(buffer, "IN0P"); break;
|
||||
case 0x4001: sprintf(buffer, "IN1P"); break;
|
||||
case 0x4002: sprintf(buffer, "OUTP"); break;
|
||||
default: sprintf(buffer, "CR %04X\n", reg);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static offs_t tms32082_disasm_mp(char *buffer, offs_t pc, const UINT8 *oprom)
|
||||
{
|
||||
output = buffer;
|
||||
@ -63,18 +101,18 @@ static offs_t tms32082_disasm_mp(char *buffer, offs_t pc, const UINT8 *oprom)
|
||||
case 0x00: print("illop0 "); break;
|
||||
case 0x01: print("trap %d", UIMM15(uimm15)); break;
|
||||
case 0x02: print("cmnd 0x%04X", UIMM15(uimm15)); break;
|
||||
case 0x04: print("rdcr R%d, CR 0x%04X", rd, UIMM15(uimm15)); break;
|
||||
case 0x05: print("swcr CR 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
case 0x04: print("rdcr R%d, %s", rd, get_creg_name(UIMM15(uimm15))); break;
|
||||
case 0x05: print("swcr %s, R%d, R%d", get_creg_name(UIMM15(uimm15)), rs, rd); break;
|
||||
case 0x06: print("brcr 0x%04X", UIMM15(uimm15)); break;
|
||||
case 0x08: print("shift.dz %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x09: print("shift.dm %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0a: print("shift.ds %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0b: print("shift.ez %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0c: print("shift.em %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0d: print("shift.es %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0e: print("shift.iz %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x0f: print("shift.im %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x10: print("and 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
case 0x08: print("shift%s.dz %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x09: print("shift%s.dm %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0a: print("shift%s.ds %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0b: print("shift%s.ez %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0c: print("shift%s.em %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0d: print("shift%s.es %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0e: print("shift%s.iz %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x0f: print("shift%s.im %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x11: print("and 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
case 0x12: print("and.tf 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
case 0x14: print("and.ft 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
case 0x16: print("xor 0x%04X, R%d, R%d", UIMM15(uimm15), rs, rd); break;
|
||||
@ -152,20 +190,20 @@ static offs_t tms32082_disasm_mp(char *buffer, offs_t pc, const UINT8 *oprom)
|
||||
case 0x04: print("cmnd R%d", src1); break;
|
||||
case 0x05: print("cmnd 0x%08X", imm32); break;
|
||||
case 0x08: print("rdcr R%d, R%d", rd, src1); break;
|
||||
case 0x09: print("rdcr R%d, 0x%08X", rd, imm32); break;
|
||||
case 0x09: print("rdcr R%d, %s", rd, get_creg_name(imm32)); break;
|
||||
case 0x0a: print("swcr R%d, R%d, R%d", src1, rs, rd); break;
|
||||
case 0x0b: print("swcr 0x%08X, R%d, R%d", imm32, rs, rd); break;
|
||||
case 0x0b: print("swcr %s, R%d, R%d", get_creg_name(imm32), rs, rd); break;
|
||||
case 0x0c: print("brcr R%d", src1); break;
|
||||
case 0x0d: print("brcr 0x%08X", imm32); break;
|
||||
|
||||
case 0x10: print("shift.dz %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x12: print("shift.dm %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x14: print("shift.ds %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x16: print("shift.ez %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x18: print("shift.em %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x1a: print("shift.es %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x1c: print("shift.iz %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x1e: print("shift.im %d, %d, R%d, R%d", rotate, endmask, rs, rd); break;
|
||||
case 0x10: print("shift%s.dz %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x12: print("shift%s.dm %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x14: print("shift%s.ds %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x16: print("shift%s.ez %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x18: print("shift%s.em %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x1a: print("shift%s.es %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x1c: print("shift%s.iz %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
case 0x1e: print("shift%s.im %d, %d, R%d, R%d", (op & (1 << 10)) ? "r" : "l", rotate, endmask, rs, rd); break;
|
||||
|
||||
case 0x22: print("and R%d, R%d, R%d", src1, rs, rd); break;
|
||||
case 0x23: print("and 0x%08X, R%d, R%d", imm32, rs, rd); break;
|
||||
|
@ -18,6 +18,49 @@
|
||||
#define ROTATE_L(x, r) ((x << r) | (x >> (32-r)))
|
||||
#define ROTATE_R(x, r) ((x >> r) | (x << (32-r)))
|
||||
|
||||
#define CMP_OVERFLOW32(r, s, d) ((((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0)
|
||||
#define CMP_OVERFLOW16(r, s, d) ((((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0)
|
||||
#define CMP_OVERFLOW8(r, s, d) ((((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0)
|
||||
#define CARRY32(x) (((x) & (((UINT64)1) << 32)) ? 1 : 0)
|
||||
#define CARRY16(x) (((x) & 0x10000) ? 1 : 0)
|
||||
#define CARRY8(x) (((x) & 0x100) ? 1 : 0)
|
||||
#define SIGN32(x) (((x) & 0x80000000) ? 1 : 0)
|
||||
#define SIGN16(x) (((x) & 0x8000) ? 1 : 0)
|
||||
#define SIGN8(x) (((x) & 0x80) ? 1 : 0)
|
||||
|
||||
|
||||
|
||||
bool tms32082_mp_device::test_condition(int condition, UINT32 value)
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
case 0x00: return false; // never, byte
|
||||
case 0x01: return (INT8)(value) > 0; // greater than zero, byte
|
||||
case 0x02: return (INT8)(value) == 0; // equals zero, byte
|
||||
case 0x03: return (INT8)(value) >= 0; // greater than or equal to zero, byte
|
||||
case 0x04: return (INT8)(value) < 0; // less than zero, byte
|
||||
case 0x05: return (INT8)(value) != 0; // not equal to zero, byte
|
||||
case 0x06: return (INT8)(value) <= 0; // less than or equal to zero, byte
|
||||
case 0x07: return true; // always, byte
|
||||
case 0x08: return false; // never, word
|
||||
case 0x09: return (INT16)(value) > 0; // greater than zero, word
|
||||
case 0x0a: return (INT16)(value) == 0; // equals zero, word
|
||||
case 0x0b: return (INT16)(value) >= 0; // greater than or equal to zero, word
|
||||
case 0x0c: return (INT16)(value) < 0; // less than zero, word
|
||||
case 0x0d: return (INT16)(value) != 0; // not equal to zero, word
|
||||
case 0x0e: return (INT16)(value) <= 0; // less than or equal to zero, word
|
||||
case 0x0f: return true; // always, word
|
||||
case 0x10: return false; // never, dword
|
||||
case 0x11: return (INT32)(value) > 0; // greater than zero, dword
|
||||
case 0x12: return (INT32)(value) == 0; // equals zero, dword
|
||||
case 0x13: return (INT32)(value) >= 0; // greater than or equal to zero, dword
|
||||
case 0x14: return (INT32)(value) < 0; // less than zero, dword
|
||||
case 0x15: return (INT32)(value) != 0; // not equal to zero, dword
|
||||
case 0x16: return (INT32)(value) <= 0; // less than or equal to zero, dword
|
||||
case 0x17: return true; // always, dword
|
||||
default: return false; // reserved
|
||||
}
|
||||
}
|
||||
|
||||
void tms32082_mp_device::execute_short_imm()
|
||||
{
|
||||
@ -49,28 +92,60 @@ void tms32082_mp_device::execute_short_imm()
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0b: // shift.ez
|
||||
{
|
||||
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;
|
||||
|
||||
int shift = r ? 32-rot : rot;
|
||||
UINT32 shiftmask = SHIFT_MASK[shift ? shift : 32];
|
||||
UINT32 compmask = endmask & shiftmask;
|
||||
|
||||
UINT32 res = 0;
|
||||
if (r) // right
|
||||
{
|
||||
res = ROTATE_R(source, rot) & compmask;
|
||||
}
|
||||
else // left
|
||||
{
|
||||
res = ROTATE_L(source, rot) & compmask;
|
||||
}
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = res;
|
||||
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 end = OP_ENDMASK();
|
||||
UINT32 source = m_reg[OP_RS()];
|
||||
int rd = OP_RD();
|
||||
|
||||
UINT32 endmask = SHIFT_MASK[OP_ENDMASK()];
|
||||
UINT32 endmask = SHIFT_MASK[end ? end : 32];
|
||||
if (inv) endmask = ~endmask;
|
||||
|
||||
UINT32 shiftmask = SHIFT_MASK[rot];
|
||||
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);
|
||||
res = ROTATE_R(source, rot) & compmask;
|
||||
}
|
||||
else // left
|
||||
{
|
||||
res = (ROTATE_L(source, rot) & compmask) | (m_reg[rd] & ~compmask);
|
||||
res = ROTATE_L(source, rot) & compmask;
|
||||
}
|
||||
|
||||
if (rd)
|
||||
@ -78,6 +153,17 @@ void tms32082_mp_device::execute_short_imm()
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x11: // and
|
||||
{
|
||||
int rd = OP_RD();
|
||||
int rs = OP_RS();
|
||||
UINT32 imm = OP_UIMM15();
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = m_reg[rs] & imm;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x17: // or
|
||||
{
|
||||
int rd = OP_RD();
|
||||
@ -132,6 +218,88 @@ void tms32082_mp_device::execute_short_imm()
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4d: // bcnd.a
|
||||
{
|
||||
INT32 offset = OP_SIMM15();
|
||||
int code = OP_RD();
|
||||
int rs = OP_RS();
|
||||
|
||||
if (test_condition(code, m_reg[rs]))
|
||||
{
|
||||
m_fetchpc = m_pc + (offset * 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x50: // cmp
|
||||
{
|
||||
UINT32 src1 = OP_SIMM15();
|
||||
UINT32 src2 = m_reg[OP_RS()];
|
||||
int rd = OP_RD();
|
||||
|
||||
UINT16 src1_16 = (UINT16)(src1);
|
||||
UINT8 src1_8 = (UINT8)(src1);
|
||||
UINT16 src2_16 = (UINT16)(src2);
|
||||
UINT8 src2_8 = (UINT8)(src2);
|
||||
|
||||
UINT64 res32 = (UINT64)src1 - (UINT64)src2;
|
||||
int z32 = (res32 == 0) ? 1 : 0;
|
||||
int n32 = SIGN32(res32);
|
||||
int v32 = CMP_OVERFLOW32(res32, src2, src1);
|
||||
int c32 = CARRY32(res32);
|
||||
|
||||
UINT32 res16 = (UINT32)src1_16 - (UINT32)src2_16;
|
||||
int z16 = (res16 == 0) ? 1 : 0;
|
||||
int n16 = SIGN16(res16);
|
||||
int v16 = CMP_OVERFLOW16(res16, src2_16, src1_16);
|
||||
int c16 = CARRY16(res16);
|
||||
|
||||
UINT16 res8 = (UINT16)src1_8 - (UINT16)src2_8;
|
||||
int z8 = (res8 == 0) ? 1 : 0;
|
||||
int n8 = SIGN8(res8);
|
||||
int v8 = CMP_OVERFLOW8(res8, src2_8, src1_8);
|
||||
int c8 = CARRY8(res8);
|
||||
|
||||
UINT32 flags = 0;
|
||||
// 32-bits (bits 20-29)
|
||||
flags |= ((c32) & 1) << 29; // higher than or same (C)
|
||||
flags |= ((~c32) & 1) << 28; // lower than (~C)
|
||||
flags |= ((~c32|z32) & 1) << 27; // lower than or same (~C|Z)
|
||||
flags |= ((c32&~z32) & 1) << 26; // higher than (C&~Z)
|
||||
flags |= (((n32&v32)|(~n32&~v32)) & 1) << 25; // greater than or equal (N&V)|(~N&~V)
|
||||
flags |= (((n32&~v32)|(~n32&v32)) & 1) << 24; // less than (N&~V)|(~N&V)
|
||||
flags |= (((n32&~v32)|(~n32&v32)|(z32)) & 1) << 23; // less than or equal (N&~V)|(~N&V)|Z
|
||||
flags |= (((n32&v32&~z32)|(~n32&~v32&~z32)) & 1) << 22; // greater than (N&V&~Z)|(~N&~V&~Z)
|
||||
flags |= ((~z32) & 1) << 21; // not equal (~Z)
|
||||
flags |= ((z32) & 1) << 20; // equal (Z)
|
||||
// 16-bits (bits 10-19)
|
||||
flags |= ((c16) & 1) << 19; // higher than or same (C)
|
||||
flags |= ((~c16) & 1) << 18; // lower than (~C)
|
||||
flags |= ((~c16|z16) & 1) << 17; // lower than or same (~C|Z)
|
||||
flags |= ((c16&~z16) & 1) << 16; // higher than (C&~Z)
|
||||
flags |= (((n16&v16)|(~n16&~v16)) & 1) << 15; // greater than or equal (N&V)|(~N&~V)
|
||||
flags |= (((n16&~v16)|(~n16&v16)) & 1) << 14; // less than (N&~V)|(~N&V)
|
||||
flags |= (((n16&~v16)|(~n16&v16)|(z16)) & 1) << 13; // less than or equal (N&~V)|(~N&V)|Z
|
||||
flags |= (((n16&v16&~z16)|(~n16&~v16&~z16)) & 1) << 12; // greater than (N&V&~Z)|(~N&~V&~Z)
|
||||
flags |= ((~z16) & 1) << 11; // not equal (~Z)
|
||||
flags |= ((z16) & 1) << 10; // equal (Z)
|
||||
// 8-bits (bits 0-9)
|
||||
flags |= ((c8) & 1) << 9; // higher than or same (C)
|
||||
flags |= ((~c8) & 1) << 8; // lower than (~C)
|
||||
flags |= ((~c8|z8) & 1) << 7; // lower than or same (~C|Z)
|
||||
flags |= ((c8&~z8) & 1) << 6; // higher than (C&~Z)
|
||||
flags |= (((n8&v8)|(~n8&~v8)) & 1) << 5; // greater than or equal (N&V)|(~N&~V)
|
||||
flags |= (((n8&~v8)|(~n8&v8)) & 1) << 4; // less than (N&~V)|(~N&V)
|
||||
flags |= (((n8&~v8)|(~n8&v8)|(z8)) & 1) << 3; // less than or equal (N&~V)|(~N&V)|Z
|
||||
flags |= (((n8&v8&~z8)|(~n8&~v8&~z8)) & 1) << 2; // greater than (N&V&~Z)|(~N&~V&~Z)
|
||||
flags |= ((~z8) & 1) << 1; // not equal (~Z)
|
||||
flags |= ((z8) & 1) << 0; // equal (Z)
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = flags;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x59: // addu
|
||||
{
|
||||
INT32 imm = OP_SIMM15();
|
||||
@ -144,7 +312,7 @@ void tms32082_mp_device::execute_short_imm()
|
||||
}
|
||||
|
||||
default:
|
||||
fatalerror("tms32082_mp_device::execute_short_imm(): opcode %08X (%02X)", m_ir, (m_ir >> 15) & 0x7f);
|
||||
fatalerror("execute_short_imm(): %08X: opcode %08X (%02X)", m_pc, m_ir, (m_ir >> 15) & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +327,57 @@ void tms32082_mp_device::execute_reg_long_imm()
|
||||
|
||||
switch ((m_ir >> 12) & 0xff)
|
||||
{
|
||||
case 0x04: // cmnd
|
||||
{
|
||||
UINT32 data = has_imm ? imm32 : m_reg[OP_SRC1()];
|
||||
|
||||
printf("CMND %08X\n", data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x16: // shift.ez
|
||||
{
|
||||
int r = (m_ir & (1 << 10));
|
||||
int inv = (m_ir & (1 << 11));
|
||||
int rot = m_reg[OP_ROTATE()];
|
||||
int end = OP_ENDMASK();
|
||||
UINT32 source = m_reg[OP_RS()];
|
||||
int rd = OP_RD();
|
||||
|
||||
UINT32 endmask = end ? SHIFT_MASK[end ? end : 32] : m_reg[OP_ROTATE()+1];
|
||||
if (inv) endmask = ~endmask;
|
||||
|
||||
int shift = r ? 32-rot : rot;
|
||||
UINT32 shiftmask = SHIFT_MASK[shift ? shift : 32];
|
||||
UINT32 compmask = endmask & shiftmask;
|
||||
|
||||
UINT32 res = 0;
|
||||
if (r) // right
|
||||
{
|
||||
res = ROTATE_R(source, rot) & compmask;
|
||||
}
|
||||
else // left
|
||||
{
|
||||
res = ROTATE_L(source, rot) & compmask;
|
||||
}
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = res;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x24:
|
||||
case 0x25: // and.tf
|
||||
{
|
||||
int rd = OP_RD();
|
||||
int rs = OP_RS();
|
||||
UINT32 src1 = has_imm ? imm32 : m_reg[OP_SRC1()];
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = src1 & ~(m_reg[rs]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2e:
|
||||
case 0x2f: // or
|
||||
{
|
||||
@ -180,12 +399,11 @@ void tms32082_mp_device::execute_reg_long_imm()
|
||||
int rd = OP_RD();
|
||||
|
||||
UINT32 address = m_reg[base] + ((has_imm ? imm32 : m_reg[OP_SRC1()]) << shift);
|
||||
UINT32 r = m_program->read_word(address);
|
||||
if (r & 0x8000) r |= 0xffff0000;
|
||||
|
||||
if (rd)
|
||||
{
|
||||
m_reg[rd] = m_program->read_word(address);
|
||||
if (m_reg[rd] & 0x8000)
|
||||
m_reg[rd] |= 0xffff0000;
|
||||
}
|
||||
m_reg[rd] = r;
|
||||
|
||||
if (m && base)
|
||||
m_reg[base] = address;
|
||||
@ -208,6 +426,24 @@ void tms32082_mp_device::execute_reg_long_imm()
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x88:
|
||||
case 0x89: // jsr
|
||||
{
|
||||
int link = OP_LINK();
|
||||
int base = OP_BASE();
|
||||
|
||||
if (link)
|
||||
m_reg[link] = m_fetchpc + 4;
|
||||
|
||||
UINT32 address = m_reg[base] + (has_imm ? imm32 : m_reg[OP_SRC1()]);
|
||||
|
||||
m_pc = m_fetchpc;
|
||||
delay_slot();
|
||||
|
||||
m_fetchpc = address;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8a:
|
||||
case 0x8b: // jsr.a
|
||||
{
|
||||
@ -221,8 +457,19 @@ void tms32082_mp_device::execute_reg_long_imm()
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xb2:
|
||||
case 0xb3: // addu
|
||||
{
|
||||
int rd = OP_RD();
|
||||
int rs = OP_RS();
|
||||
|
||||
if (rd)
|
||||
m_reg[rd] = m_reg[rs] + (has_imm ? imm32 : m_reg[OP_SRC1()]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatalerror("tms32082_mp_device::execute_reg_long_imm(): opcode %08X (%02X)", m_ir, (m_ir >> 12) & 0xff);
|
||||
fatalerror("execute_reg_long_imm(): %08X: opcode %08X (%02X)", m_pc, m_ir, (m_ir >> 12) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,77 @@ 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;
|
||||
//printf("mp_param_w: %08X, %08X\n", offset, mem_mask);
|
||||
return m_param_ram[offset];
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(tms32082_mp_device::mp_param_w)
|
||||
{
|
||||
printf("mp_param_w: %08X, %08X, %08X\n", offset, data, mem_mask);
|
||||
//printf("mp_param_w: %08X, %08X, %08X\n", offset, data, mem_mask);
|
||||
|
||||
COMBINE_DATA(&m_param_ram[offset]);
|
||||
|
||||
if (offset == 0x3f)
|
||||
{
|
||||
// initiate Transfer Controller operation
|
||||
// TODO: move TC functionality to separate device
|
||||
UINT32 address = data;
|
||||
|
||||
UINT32 next_entry = m_program->read_dword(address + 0);
|
||||
UINT32 pt_options = m_program->read_dword(address + 4);
|
||||
UINT32 src_addr = m_program->read_dword(address + 8);
|
||||
UINT32 dst_addr = m_program->read_dword(address + 12);
|
||||
UINT32 src_b_count = m_program->read_word(address + 16);
|
||||
UINT32 src_a_count = m_program->read_word(address + 18);
|
||||
UINT32 dst_b_count = m_program->read_word(address + 20);
|
||||
UINT32 dst_a_count = m_program->read_word(address + 22);
|
||||
UINT32 src_c_count = m_program->read_dword(address + 24);
|
||||
UINT32 dst_c_count = m_program->read_dword(address + 28);
|
||||
UINT32 src_b_pitch = m_program->read_dword(address + 32);
|
||||
UINT32 dst_b_pitch = m_program->read_dword(address + 36);
|
||||
UINT32 src_c_pitch = m_program->read_dword(address + 40);
|
||||
UINT32 dst_c_pitch = m_program->read_dword(address + 44);
|
||||
|
||||
printf("TC operation:\n");
|
||||
printf(" Next entry: %08X\n", next_entry);
|
||||
printf(" PT options: %08X\n", pt_options);
|
||||
printf(" SRC addr: %08X\n", src_addr);
|
||||
printf(" DST addr: %08X\n", dst_addr);
|
||||
printf(" SRC count A: %04X, B: %04X\n", src_a_count, src_b_count);
|
||||
printf(" DST count A: %04X, B: %04X\n", dst_a_count, dst_b_count);
|
||||
printf(" SRC count C: %08X\n", src_c_count);
|
||||
printf(" DST count C: %08X\n", dst_c_count);
|
||||
printf(" SRC B pitch: %08X\n", src_b_pitch);
|
||||
printf(" DST B pitch: %08X\n", dst_b_pitch);
|
||||
printf(" SRC C pitch: %08X\n", src_c_pitch);
|
||||
printf(" DST C pitch: %08X\n", dst_c_pitch);
|
||||
|
||||
if (pt_options != 0x80000000)
|
||||
fatalerror("TC transfer, options = %08X\n", pt_options);
|
||||
|
||||
for (int ic = 0; ic <= src_c_count; ic++)
|
||||
{
|
||||
UINT32 c_src_offset = ic * src_c_pitch;
|
||||
UINT32 c_dst_offset = ic * dst_c_pitch;
|
||||
|
||||
for (int ib = 0; ib <= src_b_count; ib++)
|
||||
{
|
||||
UINT32 b_src_offset = ib * src_b_pitch;
|
||||
UINT32 b_dst_offset = ib * dst_b_pitch;
|
||||
|
||||
for (int ia = 0; ia < src_a_count; ia++)
|
||||
{
|
||||
UINT32 src = src_addr + c_src_offset + b_src_offset + ia;
|
||||
UINT32 dst = dst_addr + c_dst_offset + b_dst_offset + ia;
|
||||
|
||||
UINT32 data = m_program->read_byte(src);
|
||||
m_program->write_byte(dst, data);
|
||||
|
||||
//printf("%08X: %02X -> %08X\n", src, data, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,6 +175,8 @@ void tms32082_mp_device::device_start()
|
||||
|
||||
state_add(STATE_GENPC, "curpc", m_pc).noshow();
|
||||
|
||||
m_param_ram = auto_alloc_array(machine(), UINT32, 0x800);
|
||||
|
||||
m_program = &space(AS_PROGRAM);
|
||||
m_direct = &m_program->direct();
|
||||
|
||||
@ -145,7 +211,15 @@ void tms32082_mp_device::device_reset()
|
||||
|
||||
UINT32 tms32082_mp_device::read_creg(int reg)
|
||||
{
|
||||
printf("read_creg(): %08X\n", reg);
|
||||
switch (reg)
|
||||
{
|
||||
case 0xa: // PPERROR
|
||||
return 0;
|
||||
|
||||
default:
|
||||
printf("read_creg(): %08X\n", reg);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -161,6 +235,15 @@ UINT32 tms32082_mp_device::fetch()
|
||||
return w;
|
||||
}
|
||||
|
||||
void tms32082_mp_device::delay_slot()
|
||||
{
|
||||
debugger_instruction_hook(this, m_pc);
|
||||
m_ir = fetch();
|
||||
execute();
|
||||
|
||||
m_icount--;
|
||||
}
|
||||
|
||||
void tms32082_mp_device::execute_run()
|
||||
{
|
||||
while (m_icount > 0)
|
||||
|
@ -94,17 +94,21 @@ protected:
|
||||
UINT64 m_acc[4];
|
||||
UINT32 m_ir;
|
||||
|
||||
UINT32 *m_param_ram;
|
||||
|
||||
int m_icount;
|
||||
|
||||
address_space *m_program;
|
||||
direct_read_data* m_direct;
|
||||
|
||||
UINT32 fetch();
|
||||
void delay_slot();
|
||||
void execute();
|
||||
void execute_short_imm();
|
||||
void execute_reg_long_imm();
|
||||
UINT32 read_creg(int reg);
|
||||
void write_creg(int reg, UINT32 data);
|
||||
bool test_condition(int condition, UINT32 value);
|
||||
};
|
||||
|
||||
extern const device_type TMS32082_MP;
|
||||
|
Loading…
Reference in New Issue
Block a user