diff --git a/src/emu/cpu/tms32082/dis32082.c b/src/emu/cpu/tms32082/dis32082.c index f5566044b37..98b1fa3a82b 100644 --- a/src/emu/cpu/tms32082/dis32082.c +++ b/src/emu/cpu/tms32082/dis32082.c @@ -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; diff --git a/src/emu/cpu/tms32082/mp_ops.c b/src/emu/cpu/tms32082/mp_ops.c index 89ac6595cd2..03292557cd3 100644 --- a/src/emu/cpu/tms32082/mp_ops.c +++ b/src/emu/cpu/tms32082/mp_ops.c @@ -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); } } diff --git a/src/emu/cpu/tms32082/tms32082.c b/src/emu/cpu/tms32082/tms32082.c index 5eae450b3f1..9c8996e6ff5 100644 --- a/src/emu/cpu/tms32082/tms32082.c +++ b/src/emu/cpu/tms32082/tms32082.c @@ -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) diff --git a/src/emu/cpu/tms32082/tms32082.h b/src/emu/cpu/tms32082/tms32082.h index 1acd65ddb6e..28fcfb36f59 100644 --- a/src/emu/cpu/tms32082/tms32082.h +++ b/src/emu/cpu/tms32082/tms32082.h @@ -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;