summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-07-05 19:04:39 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-07-05 19:04:50 +0200
commitf3ccd1f7f2fa8d8eef77a8ef1cfd69398e3a21fb (patch)
treeba0120e48f64ffefde6299b04c7e0c0731600ce6 /src/devices/cpu
parent8fe31f857d3d17ba4da11a5f84bfde768456d63d (diff)
-ps2sony: Various DMA and SIF bug fixes, initial OSDSYS ELF transfers to IOP now, but EE and IOP hang immediately thereafter. nw
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/mips/mips3.cpp75
-rw-r--r--src/devices/cpu/mips/mips3.h4
-rw-r--r--src/devices/cpu/mips/mips3com.h2
-rw-r--r--src/devices/cpu/mips/mips3dsm.cpp42
-rw-r--r--src/devices/cpu/mips/mips3dsm.h4
-rw-r--r--src/devices/cpu/mips/r3000.cpp1
6 files changed, 113 insertions, 15 deletions
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index 021b81293b8..5cb9b147d05 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -248,6 +248,10 @@ void mips3_device::generate_exception(int exception, int backup)
offset = 0;
exception = (exception - EXCEPTION_TLBLOAD_FILL) + EXCEPTION_TLBLOAD;
}
+ else if (exception == EXCEPTION_INTERRUPT && m_flavor == MIPS3_TYPE_R5900)
+ {
+ offset = 0x200;
+ }
/* set the exception PC */
m_core->cpr[0][COP0_EPC] = m_core->pc;
@@ -309,6 +313,7 @@ void mips3_device::generate_tlb_exception(int exception, offs_t address)
void mips3_device::invalid_instruction(uint32_t op)
{
+ printf("Invalid instruction! %08x\n", op);
generate_exception(EXCEPTION_INVALIDOP, 1);
}
@@ -320,7 +325,8 @@ void mips3_device::invalid_instruction(uint32_t op)
void mips3_device::check_irqs()
{
- if ((CAUSE & SR & 0xfc00) && (SR & SR_IE) && !(SR & SR_EXL) && !(SR & SR_ERL))
+ bool ie = (SR & SR_IE) && ((SR & SR_EIE) || m_flavor != MIPS3_TYPE_R5900);
+ if ((CAUSE & SR & 0xfc00) && ie && !(SR & SR_EXL) && !(SR & SR_ERL))
generate_exception(EXCEPTION_INTERRUPT, 0);
}
@@ -1778,13 +1784,17 @@ void mips3_device::handle_cop0(uint32_t op)
case 0x10: /* RFE */ invalid_instruction(op); break;
case 0x18: /* ERET logerror("ERET\n"); */ m_core->pc = m_core->cpr[0][COP0_EPC]; SR &= ~SR_EXL; check_irqs(); m_lld_value ^= 0xffffffff; m_ll_value ^= 0xffffffff; break;
case 0x20: /* WAIT */ break;
- default: invalid_instruction(op); break;
+ default: handle_extra_cop0(op); break;
}
break;
default: invalid_instruction(op); break;
}
}
+void mips3_device::handle_extra_cop0(uint32_t op)
+{
+ invalid_instruction(op);
+}
/***************************************************************************
@@ -2097,12 +2107,6 @@ void mips3_device::handle_cop1_fr0(uint32_t op)
FDVALD_FR0 = 1.0 / sqrt(FSVALD_FR0);
break;
- case 0x18: /* R5900 */
- if (m_flavor != MIPS3_TYPE_R5900)
- break;
- m_core->acc = FSVALS_FR0 + FTVALS_FR0;
- break;
-
case 0x20:
if (IS_INTEGRAL(op))
{
@@ -2206,13 +2210,17 @@ void mips3_device::handle_cop1_fr0(uint32_t op)
break;
default:
- fprintf(stderr, "cop1 %X\n", op);
+ handle_extra_cop1(op);
break;
}
break;
}
}
+void mips3_device::handle_extra_cop1(uint32_t op)
+{
+ invalid_instruction(op);
+}
void mips3_device::handle_cop1_fr1(uint32_t op)
{
@@ -3358,9 +3366,42 @@ void r5900le_device::handle_extra_regimm(uint32_t op)
}
}
+void r5900le_device::handle_extra_cop0(uint32_t op)
+{
+ switch (op & 0x01ffffff)
+ {
+ case 0x38: /* EI */
+ if ((SR & (SR_EXL | SR_ERL | SR_EDI)) || ((SR & SR_KSU_MASK) == SR_KSU_KERNEL))
+ SR |= SR_EIE;
+ break;
+ case 0x39: /* DI */
+ if ((SR & (SR_EXL | SR_ERL | SR_EDI)) || ((SR & SR_KSU_MASK) == SR_KSU_KERNEL))
+ SR &= ~SR_EIE;
+ break;
+ default:
+ invalid_instruction(op);
+ break;
+ }
+}
+
+void r5900le_device::handle_extra_cop1(uint32_t op)
+{
+ switch (op & 0x3f)
+ {
+ case 0x18: /* ADDA.S */
+ m_core->acc = FSVALS_FR0 + FTVALS_FR0;
+ break;
+
+ case 0x1c: /* MADD.S */
+ m_core->acc += FSVALS_FR1 * FTVALS_FR1;
+ FDVALS_FR1 = m_core->acc;
+ break;
+ }
+}
+
void r5900le_device::handle_idt(uint32_t op)
{
- //const int rs = (op >> 21) & 31;
+ const int rs = (op >> 21) & 31;
//const int rt = (op >> 16) & 31;
const int rd = (op >> 11) & 31;
@@ -3373,7 +3414,13 @@ void r5900le_device::handle_idt(uint32_t op)
printf("Unsupported instruction: MADDU @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
break;
case 0x04: /* PLZCW */
- printf("Unsupported instruction: PLZCW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
+ if (rd)
+ {
+ const uint64_t rsval = m_core->r[rs];
+ const uint64_t hi = (uint32_t)(count_leading_zeros((uint32_t)(rsval >> 32)) - 1);
+ const uint64_t lo = (uint32_t)(count_leading_zeros((uint32_t)rsval) - 1);
+ m_core->r[rd] = (hi << 32) | lo;
+ }
break;
case 0x08: /* MMI0 */
handle_mmi0(op);
@@ -3387,7 +3434,8 @@ void r5900le_device::handle_idt(uint32_t op)
m_core->icount--;
break;
case 0x11: /* MTHI1 */
- printf("Unsupported instruction: MTHI1 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
+ m_core->rh[REG_HI] = m_core->r[rs];
+ m_core->icount--;
break;
case 0x12: /* MFLO1 */
if (rd)
@@ -3395,7 +3443,8 @@ void r5900le_device::handle_idt(uint32_t op)
m_core->icount--;
break;
case 0x13: /* MTLO1 */
- printf("Unsupported instruction: MTLO1 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
+ m_core->rh[REG_LO] = m_core->r[rs];
+ m_core->icount--;
break;
case 0x18: /* MULT1 */
{
diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h
index b896235c85a..cdc6edfaa0d 100644
--- a/src/devices/cpu/mips/mips3.h
+++ b/src/devices/cpu/mips/mips3.h
@@ -544,6 +544,8 @@ private:
virtual void handle_extra_base(uint32_t op);
virtual void handle_extra_special(uint32_t op);
virtual void handle_extra_regimm(uint32_t op);
+ virtual void handle_extra_cop0(uint32_t op);
+ virtual void handle_extra_cop1(uint32_t op);
virtual void handle_extra_cop2(uint32_t op);
virtual void handle_idt(uint32_t op);
virtual void handle_ldc2(uint32_t op);
@@ -804,6 +806,8 @@ protected:
void handle_extra_base(uint32_t op) override;
void handle_extra_special(uint32_t op) override;
void handle_extra_regimm(uint32_t op) override;
+ void handle_extra_cop0(uint32_t op) override;
+ void handle_extra_cop1(uint32_t op) override;
void handle_extra_cop2(uint32_t op) override;
void handle_idt(uint32_t op) override;
void handle_mmi0(uint32_t op);
diff --git a/src/devices/cpu/mips/mips3com.h b/src/devices/cpu/mips/mips3com.h
index 9365deff603..96fc9c28b09 100644
--- a/src/devices/cpu/mips/mips3com.h
+++ b/src/devices/cpu/mips/mips3com.h
@@ -124,7 +124,9 @@
#define SR_IMEX4 0x00004000
#define SR_IMEX5 0x00008000
#define SR_DE 0x00010000
+#define SR_EIE 0x00010000 /* R5900/EE only, Enable IE bit */
#define SR_CE 0x00020000
+#define SR_EDI 0x00020000 /* R5900/EE only, EI/DI instruction enable */
#define SR_CH 0x00040000
#define SR_SR 0x00100000
#define SR_TS 0x00200000
diff --git a/src/devices/cpu/mips/mips3dsm.cpp b/src/devices/cpu/mips/mips3dsm.cpp
index c93e8166344..a0bb46456ec 100644
--- a/src/devices/cpu/mips/mips3dsm.cpp
+++ b/src/devices/cpu/mips/mips3dsm.cpp
@@ -182,6 +182,12 @@ uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &s
return flags;
}
+uint32_t mips3_disassembler::dasm_extra_cop0(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff);
+ return 0;
+}
+
uint32_t mips3_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream)
{
const char *const format_table[] =
@@ -258,13 +264,19 @@ uint32_t mips3_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &s
case 0x3d: util::stream_format(stream, "c.nge.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
case 0x3e: util::stream_format(stream, "c.le.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
case 0x3f: util::stream_format(stream, "c.ngt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
+ default: dasm_extra_cop1(pc, op, stream); break;
}
break;
}
return flags;
}
+uint32_t mips3_disassembler::dasm_extra_cop1(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff);
+ return 0;
+}
+
uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream)
{
const char *const format3_table[] =
@@ -416,6 +428,32 @@ uint32_t mips3_disassembler::dasm_extra_special(uint32_t pc, uint32_t op, std::o
return 0;
}
+uint32_t ee_disassembler::dasm_extra_cop0(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ switch (op & 0x01ffffff)
+ {
+ case 0x38: util::stream_format(stream, "ei"); break;
+ case 0x39: util::stream_format(stream, "di"); break;
+ default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
+ }
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_extra_cop1(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int fd = (op >> 6) & 31;
+ const int fs = (op >> 11) & 31;
+ const int ft = (op >> 16) & 31;
+
+ switch (op & 0x3f)
+ {
+ case 0x18: util::stream_format(stream, "adda.s %s,%s", cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x1c: util::stream_format(stream, "madd.s %s,%s,%s", cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ return 0;
+}
+
uint32_t ee_disassembler::dasm_extra_cop2(uint32_t pc, uint32_t op, std::ostream &stream)
{
const int rd = (op >> 6) & 31;
@@ -578,7 +616,7 @@ uint32_t ee_disassembler::dasm_idt(uint32_t pc, uint32_t op, std::ostream &strea
else
util::stream_format(stream, "maddu %s,%s", reg[rs], reg[rt]);
break;
- case 0x04: util::stream_format(stream, "plzcw ?"); break;
+ case 0x04: util::stream_format(stream, "plzcw %s,%s", reg[rd], reg[rs]); break;
case 0x08: flags = dasm_mmi0(pc, op, stream); break;
case 0x09: flags = dasm_mmi2(pc, op, stream); break;
case 0x10: util::stream_format(stream, "mfhi1 %s", reg[rd]); break;
diff --git a/src/devices/cpu/mips/mips3dsm.h b/src/devices/cpu/mips/mips3dsm.h
index 1edaa69843d..8797a1b00c3 100644
--- a/src/devices/cpu/mips/mips3dsm.h
+++ b/src/devices/cpu/mips/mips3dsm.h
@@ -33,6 +33,8 @@ protected:
virtual uint32_t dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream);
virtual uint32_t dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream);
virtual uint32_t dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_extra_cop0(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_extra_cop1(uint32_t pc, uint32_t op, std::ostream &stream);
virtual uint32_t dasm_extra_cop2(uint32_t pc, uint32_t op, std::ostream &stream);
uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream);
uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream);
@@ -54,6 +56,8 @@ protected:
uint32_t dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream) override;
uint32_t dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream) override;
uint32_t dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_extra_cop0(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_extra_cop1(uint32_t pc, uint32_t op, std::ostream &stream) override;
uint32_t dasm_extra_cop2(uint32_t pc, uint32_t op, std::ostream &stream) override;
uint32_t dasm_idt(uint32_t pc, uint32_t op, std::ostream &stream) override;
uint32_t dasm_mmi(uint32_t pc, uint32_t op, std::ostream &stream);
diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp
index 377aebbc854..8c458e5e6bc 100644
--- a/src/devices/cpu/mips/r3000.cpp
+++ b/src/devices/cpu/mips/r3000.cpp
@@ -1092,6 +1092,7 @@ void r3000_device::execute_run()
fflush(stdout);
}
*/
+
// instruction fetch
m_op = readop(m_pc);