From 5c063c15a04c3eb09116d1bd402e497512c1f531 Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 29 Apr 2023 09:52:51 -0400 Subject: kpython: Change CPU to PS/2 Emotion Engine --- src/devices/cpu/mips/mips3.cpp | 139 ++++++++++++++++++++++++++++++----------- src/devices/cpu/mips/mips3.h | 61 +++++++++++++----- src/mame/konami/kpython.cpp | 35 ++++++++++- 3 files changed, 181 insertions(+), 54 deletions(-) diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index fa245e00135..529f82b6d30 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -123,7 +123,8 @@ DEFINE_DEVICE_TYPE(R5000BE, r5000be_device, "r5000be", "MIPS R5000 (big)") DEFINE_DEVICE_TYPE(R5000LE, r5000le_device, "r5000le", "MIPS R5000 (little)") DEFINE_DEVICE_TYPE(VR5500BE, vr5500be_device, "vr5500be", "NEC VR5500 (big)") DEFINE_DEVICE_TYPE(VR5500LE, vr5500le_device, "vr5500le", "NEC VR5500 (little)") -DEFINE_DEVICE_TYPE(R5900LE, r5900le_device, "r5900le", "Emotion Engine Core") +DEFINE_DEVICE_TYPE(R5900BE, r5900be_device, "r5900be", "Emotion Engine Core (big)") +DEFINE_DEVICE_TYPE(R5900LE, r5900le_device, "r5900le", "Emotion Engine Core (little)") DEFINE_DEVICE_TYPE(QED5271BE, qed5271be_device, "qed5271be", "MIPS QED5271 (big)") DEFINE_DEVICE_TYPE(QED5271LE, qed5271le_device, "qed5271le", "MIPS QED5271 (little)") DEFINE_DEVICE_TYPE(RM7000BE, rm7000be_device, "rm7000be", "MIPS RM7000 (big)") @@ -369,7 +370,7 @@ void mips3_device::check_irqs() generate_exception(EXCEPTION_INTERRUPT, 0); } -void r5900le_device::check_irqs() +void r5900_device::check_irqs() { if ((CAUSE & SR & 0xfc00) && (SR & SR_IE) && (SR & SR_EIE) && !(SR & (SR_EXL | SR_ERL))) generate_exception(EXCEPTION_INTERRUPT, 0); @@ -730,7 +731,7 @@ void mips3_device::device_start() set_icountptr(m_core->icount); } -void r5900le_device::device_start() +void r5900_device::device_start() { mips3_device::device_start(); #if USE_ABI_REG_NAMES @@ -1170,7 +1171,7 @@ std::unique_ptr mips3_device::create_disassembler() return std::make_unique(); } -std::unique_ptr r5900le_device::create_disassembler() +std::unique_ptr r5900_device::create_disassembler() { return std::make_unique(); } @@ -1695,36 +1696,36 @@ inline void r4650_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t (*m_memory.write_qword_masked)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data, mem_mask); } -inline void r5900le_device::WBYTE(offs_t address, uint8_t data) +inline void r5900_device::WBYTE(offs_t address, uint8_t data) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_byte)(*m_program, address, data); else mips3_device::WBYTE(address, data); } -inline void r5900le_device::WHALF(offs_t address, uint16_t data) +inline void r5900_device::WHALF(offs_t address, uint16_t data) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_word)(*m_program, address, data); else mips3_device::WHALF(address, data); } -inline void r5900le_device::WWORD(offs_t address, uint32_t data) +inline void r5900_device::WWORD(offs_t address, uint32_t data) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword)(*m_program, address, data); else mips3_device::WWORD(address, data); } -inline void r5900le_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) +inline void r5900_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask); else mips3_device::WWORD_MASKED(address, data, mem_mask); } -inline void r5900le_device::WDOUBLE(offs_t address, uint64_t data) { +inline void r5900_device::WDOUBLE(offs_t address, uint64_t data) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword)(*m_program, address, data); else mips3_device::WDOUBLE(address, data); } -inline void r5900le_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) +inline void r5900_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) { if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask); else mips3_device::WDOUBLE_MASKED(address, data, mem_mask); @@ -1762,7 +1763,39 @@ inline void r5900le_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat } } -inline bool r5900le_device::RBYTE(offs_t address, uint32_t *result) { +inline void r5900be_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo) +{ + if (address >= 0x70000000 && address < 0x70004000) + { + (*m_memory.write_qword)(*m_program, address, data_hi); + (*m_memory.write_qword)(*m_program, address + 8, data_lo); + return; + } + + const uint32_t tlbval = vtlb_table()[address >> 12]; + if (tlbval & WRITE_ALLOWED) + { + (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_hi); + (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_lo); + } + else + { + if(tlbval & READ_ALLOWED) + { + generate_tlb_exception(EXCEPTION_TLBMOD, address); + } + else if(tlbval & FLAG_FIXED) + { + generate_tlb_exception(EXCEPTION_TLBSTORE, address); + } + else + { + generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address); + } + } +} + +inline bool r5900_device::RBYTE(offs_t address, uint32_t *result) { if (address >= 0x70000000 && address < 0x70004000) { *result = (*m_memory.read_byte)(*m_program, address); return true; @@ -1770,7 +1803,7 @@ inline bool r5900le_device::RBYTE(offs_t address, uint32_t *result) { return mips3_device::RBYTE(address, result); } -inline bool r5900le_device::RHALF(offs_t address, uint32_t *result) +inline bool r5900_device::RHALF(offs_t address, uint32_t *result) { if (address >= 0x70000000 && address < 0x70004000) { @@ -1780,7 +1813,7 @@ inline bool r5900le_device::RHALF(offs_t address, uint32_t *result) return mips3_device::RHALF(address, result); } -inline bool r5900le_device::RWORD(offs_t address, uint32_t *result, bool insn) +inline bool r5900_device::RWORD(offs_t address, uint32_t *result, bool insn) { if (address >= 0x70000000 && address < 0x70004000) { @@ -1790,7 +1823,7 @@ inline bool r5900le_device::RWORD(offs_t address, uint32_t *result, bool insn) return mips3_device::RWORD(address, result, insn); } -inline bool r5900le_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) +inline bool r5900_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) { if (address >= 0x70000000 && address < 0x70004000) { @@ -1800,7 +1833,7 @@ inline bool r5900le_device::RWORD_MASKED(offs_t address, uint32_t *result, uint3 return mips3_device::RWORD_MASKED(address, result, mem_mask); } -inline bool r5900le_device::RDOUBLE(offs_t address, uint64_t *result) +inline bool r5900_device::RDOUBLE(offs_t address, uint64_t *result) { if (address >= 0x70000000 && address < 0x70004000) { @@ -1810,7 +1843,7 @@ inline bool r5900le_device::RDOUBLE(offs_t address, uint64_t *result) return mips3_device::RDOUBLE(address, result); } -inline bool r5900le_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) +inline bool r5900_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) { if (address >= 0x70000000 && address < 0x70004000) { @@ -1852,6 +1885,38 @@ inline bool r5900le_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t return true; } +inline bool r5900be_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo) +{ + if (address >= 0x70000000 && address < 0x70004000) + { + *result_hi = (*m_memory.read_qword)(*m_program, address); + *result_lo = (*m_memory.read_qword)(*m_program, address + 8); + return true; + } + + const uint32_t tlbval = vtlb_table()[address >> 12]; + if (tlbval & READ_ALLOWED) + { + *result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); + *result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff)); + } + else + { + if(tlbval & FLAG_FIXED) + { + generate_tlb_exception(EXCEPTION_TLBLOAD, address); + } + else + { + generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address); + } + *result_hi = 0; + *result_lo = 0; + return false; + } + return true; +} + /*************************************************************************** @@ -3069,7 +3134,7 @@ inline void mips3_device::set_cop2_creg(int idx, uint64_t val) m_core->vfr[idx][0] = val; } -inline void r5900le_device::handle_dmfc2(uint32_t op) +inline void r5900_device::handle_dmfc2(uint32_t op) { // QMFC2 if (!RTREG) @@ -3087,7 +3152,7 @@ inline void r5900le_device::handle_dmfc2(uint32_t op) m_core->rh[rt] = ((uint64_t)rtval[3] << 32) | rtval[2]; } -inline void r5900le_device::handle_dmtc2(uint32_t op) +inline void r5900_device::handle_dmtc2(uint32_t op) { // QMTC2 uint32_t rt = RTREG; @@ -3099,23 +3164,23 @@ inline void r5900le_device::handle_dmtc2(uint32_t op) } } -inline uint64_t r5900le_device::get_cop2_reg(int idx) +inline uint64_t r5900_device::get_cop2_reg(int idx) { return reinterpret_cast(m_core->vfr[idx])[0]; } -inline void r5900le_device::set_cop2_reg(int idx, uint64_t val) +inline void r5900_device::set_cop2_reg(int idx, uint64_t val) { reinterpret_cast(m_core->vfr[idx])[0] = (uint32_t)val; } -inline uint64_t r5900le_device::get_cop2_creg(int idx) +inline uint64_t r5900_device::get_cop2_creg(int idx) { logerror("%s: CFC2: Getting ccr[%d] (%08x)\n", machine().describe_context(), idx, m_core->vcr[idx]); return m_core->vcr[idx]; } -inline void r5900le_device::set_cop2_creg(int idx, uint64_t val) +inline void r5900_device::set_cop2_creg(int idx, uint64_t val) { if (idx < 16) { @@ -3227,7 +3292,7 @@ void mips3_device::handle_extra_cop2(uint32_t op) VU0/1 (COP2) EXECUTION HANDLING (R5900) ***************************************************************************/ -void r5900le_device::handle_extra_cop2(uint32_t op) +void r5900_device::handle_extra_cop2(uint32_t op) { // TODO: Flags, rounding... const int rd = (op >> 6) & 31; @@ -3690,7 +3755,7 @@ void mips3_device::handle_mult(uint32_t op) m_core->icount -= 3; } -void r5900le_device::handle_mult(uint32_t op) +void r5900_device::handle_mult(uint32_t op) { mips3_device::handle_mult(op); if (RDREG) RDVAL64 = LOVAL64; @@ -3704,7 +3769,7 @@ void mips3_device::handle_multu(uint32_t op) m_core->icount -= 3; } -void r5900le_device::handle_multu(uint32_t op) +void r5900_device::handle_multu(uint32_t op) { mips3_device::handle_multu(op); if (RDREG) RDVAL64 = LOVAL64; @@ -3844,7 +3909,7 @@ void mips3_device::handle_idt(uint32_t op) } } -void r5900le_device::handle_extra_base(uint32_t op) +void r5900_device::handle_extra_base(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -3873,7 +3938,7 @@ void r5900le_device::handle_extra_base(uint32_t op) } } -void r5900le_device::handle_extra_special(uint32_t op) +void r5900_device::handle_extra_special(uint32_t op) { const int rs = (op >> 21) & 31; const int rd = (op >> 11) & 31; @@ -3892,7 +3957,7 @@ void r5900le_device::handle_extra_special(uint32_t op) } } -void r5900le_device::handle_extra_regimm(uint32_t op) +void r5900_device::handle_extra_regimm(uint32_t op) { switch (op & 63) { @@ -3908,7 +3973,7 @@ void r5900le_device::handle_extra_regimm(uint32_t op) } } -void r5900le_device::handle_extra_cop0(uint32_t op) +void r5900_device::handle_extra_cop0(uint32_t op) { switch (op & 0x01ffffff) { @@ -3926,7 +3991,7 @@ void r5900le_device::handle_extra_cop0(uint32_t op) } } -void r5900le_device::handle_extra_cop1(uint32_t op) +void r5900_device::handle_extra_cop1(uint32_t op) { switch (op & 0x3f) { @@ -3941,7 +4006,7 @@ void r5900le_device::handle_extra_cop1(uint32_t op) } } -void r5900le_device::handle_idt(uint32_t op) +void r5900_device::handle_idt(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -4165,7 +4230,7 @@ void r5900le_device::handle_idt(uint32_t op) } } -void r5900le_device::handle_mmi0(uint32_t op) +void r5900_device::handle_mmi0(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -4624,7 +4689,7 @@ void r5900le_device::handle_mmi0(uint32_t op) } } -void r5900le_device::handle_mmi1(uint32_t op) +void r5900_device::handle_mmi1(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -4988,7 +5053,7 @@ void r5900le_device::handle_mmi1(uint32_t op) } } -void r5900le_device::handle_mmi2(uint32_t op) +void r5900_device::handle_mmi2(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -5115,7 +5180,7 @@ void r5900le_device::handle_mmi2(uint32_t op) } } -void r5900le_device::handle_mmi3(uint32_t op) +void r5900_device::handle_mmi3(uint32_t op) { const int rs = (op >> 21) & 31; const int rt = (op >> 16) & 31; @@ -5214,7 +5279,7 @@ void mips3_device::handle_sdc2(uint32_t op) WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); } -void r5900le_device::handle_ldc2(uint32_t op) +void r5900_device::handle_ldc2(uint32_t op) { /* LQC2 */ const uint32_t base = SIMMVAL + RSVAL32; @@ -5226,7 +5291,7 @@ void r5900le_device::handle_ldc2(uint32_t op) } } -void r5900le_device::handle_sdc2(uint32_t op) +void r5900_device::handle_sdc2(uint32_t op) { /* SQC2 */ const uint32_t base = SIMMVAL + RSVAL32; diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index cb78b56e8f3..18c0d60bbc6 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -49,6 +49,7 @@ DECLARE_DEVICE_TYPE(QED5271LE, qed5271le_device) DECLARE_DEVICE_TYPE(RM7000BE, rm7000be_device) DECLARE_DEVICE_TYPE(RM7000LE, rm7000le_device) DECLARE_DEVICE_TYPE(R5900LE, r5900le_device) +DECLARE_DEVICE_TYPE(R5900BE, r5900be_device) /*************************************************************************** @@ -873,23 +874,15 @@ public: } }; -class r5900le_device : public mips3_device { -public: +class r5900_device : public mips3_device { +protected: // construction/destruction - template - r5900le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&vu0_tag) - : r5900le_device(mconfig, tag, owner, clock) - { - m_vu0.set_tag(std::forward(vu0_tag)); - } - - r5900le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mips3_device(mconfig, R5900LE, tag, owner, clock, MIPS3_TYPE_R5900, ENDIANNESS_LITTLE, 64) + r5900_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness) + : mips3_device(mconfig, type, tag, owner, clock, MIPS3_TYPE_R5900, endianness, 64) , m_vu0(*this, finder_base::DUMMY_TAG) { } -protected: virtual void device_start() override; // device_disasm_interface overrides @@ -908,8 +901,8 @@ protected: void WDOUBLE(offs_t address, uint64_t data) override; void WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) override; - bool RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo); - void WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo); + virtual bool RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo) = 0; + virtual void WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo) = 0; uint64_t get_cop2_reg(int idx) override; void set_cop2_reg(int idx, uint64_t val) override; @@ -939,6 +932,46 @@ protected: required_device m_vu0; }; +class r5900le_device : public r5900_device { +public: + // construction/destruction + template + r5900le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&vu0_tag) + : r5900le_device(mconfig, tag, owner, clock) + { + m_vu0.set_tag(std::forward(vu0_tag)); + } + + r5900le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : r5900_device(mconfig, R5900LE, tag, owner, clock, ENDIANNESS_LITTLE) + { + } + +protected: + bool RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo) override; + void WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo) override; +}; + +class r5900be_device : public r5900_device { +public: + // construction/destruction + template + r5900be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&vu0_tag) + : r5900be_device(mconfig, tag, owner, clock) + { + m_vu0.set_tag(std::forward(vu0_tag)); + } + + r5900be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : r5900_device(mconfig, R5900BE, tag, owner, clock, ENDIANNESS_BIG) + { + } + +protected: + bool RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo) override; + void WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo) override; +}; + class qed5271be_device : public mips3_device { public: // construction/destruction diff --git a/src/mame/konami/kpython.cpp b/src/mame/konami/kpython.cpp index 2891ef7175a..68448973d6e 100644 --- a/src/mame/konami/kpython.cpp +++ b/src/mame/konami/kpython.cpp @@ -166,9 +166,15 @@ Notes: #include "emu.h" #include "cpu/mips/mips3.h" #include "cpu/mips/mips1.h" +#include "cpu/mips/ps2vu.h" +#include "cpu/mips/ps2vif1.h" //#include "cpu/h8/h83664.h" //#include "machine/ds2430.h" +#include "machine/ps2dma.h" +#include "machine/ps2intc.h" +#include "machine/ps2sif.h" #include "machine/timekpr.h" +#include "video/ps2gs.h" #include "emupal.h" #include "screen.h" @@ -181,7 +187,14 @@ public: kpython_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_dmac(*this, "dmac") + , m_intc(*this, "intc") + , m_sif(*this, "sif") + , m_gs(*this, "gs") + , m_vu0(*this, "vu0") + , m_vu1(*this, "vu1") , m_m48t58(*this, "m48t58") + , m_ram(*this, "ram") { } void kpython(machine_config &config); @@ -192,8 +205,15 @@ private: void ps2_map(address_map &map); // devices - required_device m_maincpu; + required_device m_maincpu; + required_device m_dmac; + required_device m_intc; + required_device m_sif; + required_device m_gs; + required_device m_vu0; + required_device m_vu1; required_device m_m48t58; + required_shared_ptr m_ram; // driver_device overrides virtual void video_start() override; @@ -211,7 +231,7 @@ uint32_t kpython_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma void kpython_state::ps2_map(address_map &map) { - map(0x00000000, 0x01ffffff).ram(); // 32 MB RAM in consumer PS2s, do these have more? + map(0x00000000, 0x01ffffff).ram().share(m_ram); // 32 MB RAM in consumer PS2s, do these have more? map(0x1fc00000, 0x1fdfffff).rom().region("bios", 0); } @@ -220,11 +240,20 @@ INPUT_PORTS_END void kpython_state::kpython(machine_config &config) { - R5000BE(config, m_maincpu, 294000000); // imported from namcops2.c driver + R5900BE(config, m_maincpu, 294'912'000, m_vu0); + m_maincpu->set_force_no_drc(true); m_maincpu->set_icache_size(16384); m_maincpu->set_dcache_size(16384); m_maincpu->set_addrmap(AS_PROGRAM, &kpython_state::ps2_map); + SONYPS2_VU0(config, m_vu0, 294'912'000, m_vu1); + SONYPS2_VU1(config, m_vu1, 294'912'000, m_gs); + + SONYPS2_INTC(config, m_intc, m_maincpu); + SONYPS2_GS(config, m_gs, 294912000/2, m_intc, m_vu1); + SONYPS2_DMAC(config, m_dmac, 294912000/2, m_maincpu, m_ram, m_sif, m_gs, m_vu1); + SONYPS2_SIF(config, m_sif, m_intc); + //H83664(config, m_io_mcu, 14000000); // from filter board //DS2430(config, m_ds2430); -- cgit v1.2.3