diff options
author | mooglyguy <therealmogminer@gmail.com> | 2018-07-21 10:06:47 +0200 |
---|---|---|
committer | mooglyguy <therealmogminer@gmail.com> | 2018-07-21 10:07:00 +0200 |
commit | 4d0feb24861083f55b616f0df0baf2da7a97d441 (patch) | |
tree | 995c58df5bd74571939f636adc23fd3d01b40c91 | |
parent | eed782f1e3123685a1f368e51577629122542308 (diff) |
ps2sony: Checkpoint, nw
-rw-r--r-- | src/devices/cpu/mips/ps2vu.cpp | 64 | ||||
-rw-r--r-- | src/devices/cpu/mips/ps2vu.h | 9 | ||||
-rw-r--r-- | src/devices/video/ps2gif.cpp | 114 | ||||
-rw-r--r-- | src/devices/video/ps2gif.h | 30 | ||||
-rw-r--r-- | src/devices/video/ps2gs.cpp | 3 | ||||
-rw-r--r-- | src/devices/video/ps2gs.h | 7 | ||||
-rw-r--r-- | src/mame/drivers/ps2sony.cpp | 2 |
7 files changed, 190 insertions, 39 deletions
diff --git a/src/devices/cpu/mips/ps2vu.cpp b/src/devices/cpu/mips/ps2vu.cpp index fa4a1fd96b8..3af58884aba 100644 --- a/src/devices/cpu/mips/ps2vu.cpp +++ b/src/devices/cpu/mips/ps2vu.cpp @@ -13,6 +13,7 @@ #include "ps2vu.h" #include "ps2vif1.h" #include "video/ps2gs.h" +#include "video/ps2gif.h" #include "vudasm.h" #include "debugger.h" @@ -626,6 +627,8 @@ void sonyvu_device::execute_lower(const uint32_t op) const int rs = (op >> 11) & 31; const int rt = (op >> 16) & 31; const int dest = (op >> 21) & 15; + const int fsf = (op >> 21) & 3; + //const int ftf = (op >> 23) & 3; switch ((op >> 25) & 0x7f) { @@ -685,36 +688,44 @@ void sonyvu_device::execute_lower(const uint32_t op) printf("Unsupported VU instruction: FCGET\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; break; case 0x20: // B - printf("Unsupported VU instruction: B\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x21: // BAL if (rt) m_vcr[rt] = m_pc + 8; - m_delay_pc = (m_pc + (immediate_s11(op) * 8)) & m_mem_mask; + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x24: // JR m_delay_pc = m_vcr[rs] & m_mem_mask; break; case 0x25: // JALR - printf("Unsupported VU instruction: JALR\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if (rt) + m_vcr[rt] = m_pc + 8; + m_delay_pc = m_vcr[rs] & m_mem_mask; break; case 0x28: // IBEQ - printf("Unsupported VU instruction: IBEQ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if (m_vcr[rs] == m_vcr[rt]) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x29: // IBNE - printf("Unsupported VU instruction: IBNE\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if (m_vcr[rs] != m_vcr[rt]) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x2c: // IBLTZ - printf("Unsupported VU instruction: IBLTZ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if ((int16_t)m_vcr[rs] < 0) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x2d: // IBGTZ - printf("Unsupported VU instruction: IBGTZ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if ((int16_t)m_vcr[rs] > 0) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x2e: // IBLEZ - printf("Unsupported VU instruction: IBLEZ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if ((int16_t)m_vcr[rs] <= 0) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x2f: // IBGEZ - printf("Unsupported VU instruction: IBGEZ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if ((int16_t)m_vcr[rs] >= 0) + m_delay_pc = (m_pc + immediate_s11(op) * 8) & m_mem_mask; break; case 0x40: // SPECIAL { @@ -788,10 +799,22 @@ void sonyvu_device::execute_lower(const uint32_t op) printf("Unsupported VU instruction: WAITQ\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; break; case 0x3c: // MTIR - printf("Unsupported VU instruction: MTIR\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if (rt) + m_vcr[rt] = (uint16_t)*reinterpret_cast<uint32_t*>(&m_vfr[rs][fsf]); break; case 0x3d: // MFIR - printf("Unsupported VU instruction: MFIR\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + if (rt) + { + int32_t* base = reinterpret_cast<int32_t*>(m_vfr[rt]); + int32_t value = (int16_t)(m_vcr[rs] & 0xffff); + for (int field = 0; field < 4; field++) + { + if (BIT(op, 24-field)) + { + base[field] = value; + } + } + } break; case 0x3e: // ILWR printf("Unsupported VU instruction: ILWR\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; @@ -821,7 +844,7 @@ void sonyvu_device::execute_lower(const uint32_t op) printf("Unsupported VU instruction: XITOP\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; break; case 0x6c: // XGKICK - printf("Unsupported VU instruction: XGKICK\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; + execute_xgkick(rs); break; case 0x70: // ESADD printf("Unsupported VU instruction: ESADD\n"); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break; @@ -954,6 +977,11 @@ WRITE32_MEMBER(sonyvu0_device::vu1_reg_w) m_vu1_regs[offset] = data; } +void sonyvu0_device::execute_xgkick(uint32_t rs) +{ + fatalerror("Unsupported VU0 instruction: XGKICK\n"); +} + void sonyvu1_device::device_start() { sonyvu_device::device_start(); @@ -999,6 +1027,18 @@ void sonyvu_device::write_micro_mem(uint32_t address, uint64_t data) m_micro_mem[(address & m_mem_mask) >> 3] = data; } +void sonyvu1_device::execute_xgkick(uint32_t rs) +{ + if (m_gs->interface()->path1_available()) + { + m_gs->interface()->kick_path1(m_vcr[rs]); + } + else + { + m_pc -= 8; + } +} + void sonyvu_device::start(uint32_t address) { m_pc = address & m_mem_mask; diff --git a/src/devices/cpu/mips/ps2vu.h b/src/devices/cpu/mips/ps2vu.h index 542ce80e64e..3132fd2f939 100644 --- a/src/devices/cpu/mips/ps2vu.h +++ b/src/devices/cpu/mips/ps2vu.h @@ -81,6 +81,9 @@ public: void write_vu_mem(uint32_t address, uint32_t data); void write_micro_mem(uint32_t address, uint64_t data); float* vector_regs() { return m_v; } + uint64_t *micro_mem() { return &m_micro_mem[0]; } + uint32_t *vu_mem() { return &m_vu_mem[0]; } + uint32_t mem_mask() const { return m_mem_mask; } bool running() const { return m_running; } void start(uint32_t address); @@ -128,6 +131,8 @@ protected: void execute_upper(const uint32_t op); void execute_lower(const uint32_t op); + virtual void execute_xgkick(uint32_t rs) = 0; + static int16_t immediate_s11(const uint32_t op); // address spaces @@ -193,6 +198,8 @@ protected: void micro_map(address_map &map); void vu_map(address_map &map); + void execute_xgkick(uint32_t rs) override; + required_device<ps2_gs_device> m_gs; required_device<ps2_vif1_device> m_vif; @@ -218,6 +225,8 @@ protected: void micro_map(address_map &map); void vu_map(address_map &map); + void execute_xgkick(uint32_t rs) override; + DECLARE_READ32_MEMBER(vu1_reg_r); DECLARE_WRITE32_MEMBER(vu1_reg_w); diff --git a/src/devices/video/ps2gif.cpp b/src/devices/video/ps2gif.cpp index f95c6547500..def4f08e17f 100644 --- a/src/devices/video/ps2gif.cpp +++ b/src/devices/video/ps2gif.cpp @@ -17,7 +17,9 @@ DEFINE_DEVICE_TYPE(SONYPS2_GIF, ps2_gif_device, "ps2gif", "Playstation 2 GIF") ps2_gif_device::ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SONYPS2_GIF, tag, owner, clock) + , device_execute_interface(mconfig, *this) , m_gs(*this, finder_base::DUMMY_TAG) + , m_vu1(*this, finder_base::DUMMY_TAG) { } @@ -47,6 +49,10 @@ ps2_gif_device::tag_t::tag_t(const uint64_t hi, const uint64_t lo) void ps2_gif_device::device_start() { + set_icountptr(m_icount); + + save_item(NAME(m_icount)); + save_item(NAME(m_ctrl)); save_item(NAME(m_mode)); save_item(NAME(m_stat)); @@ -54,6 +60,10 @@ void ps2_gif_device::device_start() save_item(NAME(m_p3cnt)); save_item(NAME(m_p3tag)); save_item(NAME(m_p3mask)); + save_item(NAME(m_next_path3_hi)); + save_item(NAME(m_next_path3_lo)); + save_item(NAME(m_path3_available)); + save_item(NAME(m_vu_mem_address)); // TODO: Save current tag } @@ -72,7 +82,13 @@ void ps2_gif_device::gif_reset() m_p3cnt = 0; m_p3tag = 0; m_p3mask = false; - m_current_tag = tag_t(); + m_current_path1_tag = tag_t(); + m_current_path3_tag = tag_t(); + m_last_tag = tag_t(); + m_path3_available = true; + m_next_path3_hi = 0; + m_next_path3_lo = 0; + m_vu_mem_address = 0; } READ32_MEMBER(ps2_gif_device::read) @@ -103,22 +119,22 @@ READ32_MEMBER(ps2_gif_device::read) break; case 0x40/4: // GIF_TAG0 - ret = m_current_tag.word(0); + ret = m_last_tag.word(0); logerror("%s: Read: GIF_TAG0 (%08x)\n", machine().describe_context(), ret); break; case 0x50/4: // GIF_TAG1 - ret = m_current_tag.word(1); + ret = m_last_tag.word(1); logerror("%s: Read: GIF_TAG1 (%08x)\n", machine().describe_context(), ret); break; case 0x60/4: // GIF_TAG2 - ret = m_current_tag.word(2); + ret = m_last_tag.word(2); logerror("%s: Read: GIF_TAG2 (%08x)\n", machine().describe_context(), ret); break; case 0x70/4: // GIF_TAG3 - ret = m_current_tag.word(0); + ret = m_last_tag.word(0); logerror("%s: Read: GIF_TAG3 (%08x)\n", machine().describe_context(), ret); break; @@ -200,6 +216,37 @@ WRITE32_MEMBER(ps2_gif_device::write) } } +void ps2_gif_device::kick_path1(uint32_t address) +{ + m_vu_mem_address = address <<= 2; + + uint64_t hi, lo; + fetch_path1(hi, lo); + write_path1(hi, lo); +} + +void ps2_gif_device::fetch_path1(uint64_t &hi, uint64_t &lo) +{ + uint32_t *tag = &m_vu1->vu_mem()[m_vu_mem_address]; + lo = ((uint64_t)tag[0] << 32) | (uint64_t)tag[1]; + hi = ((uint64_t)tag[2] << 32) | (uint64_t)tag[3]; + m_vu_mem_address += 4; + m_vu_mem_address &= m_vu1->mem_mask() >> 2; +} + +void ps2_gif_device::write_path1(uint64_t hi, uint64_t lo) +{ + if (!m_current_path1_tag.valid()) + { + m_current_path1_tag = tag_t(hi, lo); + printf("Starting PATH1: %08x%08x%08x%08x\n", (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo); + return; + } + + printf("Processing PATH1: %08x%08x%08x%08x\n", (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo); + process_tag(m_current_path1_tag, hi, lo); +} + void ps2_gif_device::write_path3(uint64_t hi, uint64_t lo) { if (m_p3mask) @@ -207,36 +254,43 @@ void ps2_gif_device::write_path3(uint64_t hi, uint64_t lo) return; } - if (!m_current_tag.valid()) + if (!m_current_path3_tag.valid()) { - m_current_tag = tag_t(hi, lo); + m_current_path3_tag = tag_t(hi, lo); return; } - switch (m_current_tag.format()) + m_next_path3_hi = hi; + m_next_path3_lo = lo; + m_path3_available = false; +} + +void ps2_gif_device::process_tag(tag_t &tag, uint64_t hi, uint64_t lo) +{ + m_last_tag = tag; + switch (tag.format()) { case tag_t::format_t::FMT_PACKED: - if (m_current_tag.is_prim() && !m_current_tag.is_prim_output()) + if (tag.is_prim() && !tag.is_prim_output()) { - m_current_tag.set_prim_output(); - logerror("%s: PATH3: PACKED: Not yet implemented: PRIM\n", machine().describe_context()); + tag.set_prim_output(); + logerror("%s: GIF: PACKED: Not yet implemented: PRIM\n", machine().describe_context()); } - else if (m_current_tag.nloop()) + else if (tag.nloop()) { - const uint8_t reg = m_current_tag.reg(); + const uint8_t reg = tag.reg(); m_gs->write_packed(reg, hi, lo); - m_current_tag.next_reg(); + tag.next_reg(); } break; case tag_t::format_t::FMT_REGLIST: - logerror("%s: PATH3: Not yet implemented: REGLIST (%08x%08x%08x%08x)\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo); - m_current_tag.loop(); + logerror("%s: GIF: Not yet implemented: REGLIST (%08x%08x%08x%08x)\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo); + tag.loop(); break; default: - //logerror("%s: PATH3: Not yet implemented: IMAGE (%08x%08x%08x%08x)\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo); m_gs->regs_w(machine().dummy_space(), 0x54, lo); m_gs->regs_w(machine().dummy_space(), 0x54, hi); - m_current_tag.loop(); + tag.loop(); break; } } @@ -255,3 +309,27 @@ void ps2_gif_device::set_path3_mask(bool masked) { m_p3mask = masked; } + +void ps2_gif_device::execute_run() +{ + while (m_icount > 0) + { + if (m_current_path1_tag.valid()) + { + uint64_t hi, lo; + fetch_path1(hi, lo); + write_path1(hi, lo); + } + else if (!m_path3_available) + { + write_path3(m_next_path3_hi, m_next_path3_lo); + m_path3_available = false; + } + else + { + m_icount = 0; + break; + } + m_icount--; + } +} diff --git a/src/devices/video/ps2gif.h b/src/devices/video/ps2gif.h index 387e6f50e4c..2cd7215269e 100644 --- a/src/devices/video/ps2gif.h +++ b/src/devices/video/ps2gif.h @@ -17,15 +17,17 @@ #include "emu.h" class ps2_gs_device; +class sonyvu1_device; -class ps2_gif_device : public device_t +class ps2_gif_device : public device_t, public device_execute_interface { public: - template <typename T> - ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gs_tag) - : ps2_gif_device(mconfig, tag, owner, (uint32_t)0) + template <typename T, typename U> + ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&gs_tag, U &&vu1_tag) + : ps2_gif_device(mconfig, tag, owner, clock) { m_gs.set_tag(std::forward<T>(gs_tag)); + m_vu1.set_tag(std::forward<U>(vu1_tag)); } ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -33,12 +35,19 @@ public: DECLARE_READ32_MEMBER(read); DECLARE_WRITE32_MEMBER(write); + void kick_path1(uint32_t address); + void write_path1(uint64_t hi, uint64_t lo); void write_path3(uint64_t hi, uint64_t lo); void set_path3_mask(bool masked); + bool path1_available() const { return !m_current_path1_tag.valid(); } + bool path3_available() const { return m_path3_available; } protected: virtual void device_start() override; virtual void device_reset() override; + virtual void execute_run() override; + + void fetch_path1(uint64_t &hi, uint64_t &lo); void gif_reset(); @@ -87,6 +96,8 @@ protected: uint32_t m_words[4]; }; + void process_tag(tag_t &tag, uint64_t hi, uint64_t lo); + enum : uint32_t { CTRL_RST = (1 << 0), @@ -94,15 +105,24 @@ protected: }; required_device<ps2_gs_device> m_gs; + required_device<sonyvu1_device> m_vu1; + + int m_icount; uint32_t m_ctrl; uint32_t m_mode; uint32_t m_stat; - tag_t m_current_tag; // tag0..3 + tag_t m_current_path1_tag; + tag_t m_current_path3_tag; + tag_t m_last_tag; uint32_t m_cnt; uint32_t m_p3cnt; uint32_t m_p3tag; + uint64_t m_next_path3_hi; + uint64_t m_next_path3_lo; + bool m_path3_available; bool m_p3mask; + uint32_t m_vu_mem_address; }; DECLARE_DEVICE_TYPE(SONYPS2_GIF, ps2_gif_device) diff --git a/src/devices/video/ps2gs.cpp b/src/devices/video/ps2gs.cpp index 1e5957b1873..c529d5891b5 100644 --- a/src/devices/video/ps2gs.cpp +++ b/src/devices/video/ps2gs.cpp @@ -44,12 +44,13 @@ DEFINE_DEVICE_TYPE(SONYPS2_GS, ps2_gs_device, "ps2gs", "Playstation 2 GS") ps2_gs_device::ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SONYPS2_GS, tag, owner, clock) , m_intc(*this, finder_base::DUMMY_TAG) + , m_vu1(*this, finder_base::DUMMY_TAG) , m_gif(*this, "gif") { } MACHINE_CONFIG_START(ps2_gs_device::device_add_mconfig) - MCFG_DEVICE_ADD(m_gif, SONYPS2_GIF, DEVICE_SELF) + MCFG_DEVICE_ADD(m_gif, SONYPS2_GIF, clock(), DEVICE_SELF, m_vu1) MACHINE_CONFIG_END void ps2_gs_device::device_start() diff --git a/src/devices/video/ps2gs.h b/src/devices/video/ps2gs.h index 986041c675a..5d7e2836763 100644 --- a/src/devices/video/ps2gs.h +++ b/src/devices/video/ps2gs.h @@ -18,16 +18,18 @@ #include "machine/ps2intc.h" class ps2_gif_device; +class sonyvu1_device; class ps2_gs_device : public device_t { public: - template <typename T> + template <typename T, typename U> - ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&intc_tag) + ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&intc_tag, U &&vu1_tag) : ps2_gs_device(mconfig, tag, owner, clock) { m_intc.set_tag(std::forward<T>(intc_tag)); + m_vu1.set_tag(std::forward<U>(vu1_tag)); } ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -169,6 +171,7 @@ protected: }; required_device<ps2_intc_device> m_intc; + required_device<sonyvu1_device> m_vu1; required_device<ps2_gif_device> m_gif; std::unique_ptr<uint32_t[]> m_ram; diff --git a/src/mame/drivers/ps2sony.cpp b/src/mame/drivers/ps2sony.cpp index 7f35628d188..0af9d1e9540 100644 --- a/src/mame/drivers/ps2sony.cpp +++ b/src/mame/drivers/ps2sony.cpp @@ -750,7 +750,7 @@ MACHINE_CONFIG_START(ps2sony_state::ps2sony) MCFG_DEVICE_ADD(m_timer[3], SONYPS2_TIMER, 294912000/2, false) MCFG_DEVICE_ADD(m_intc, SONYPS2_INTC, m_maincpu) - MCFG_DEVICE_ADD(m_gs, SONYPS2_GS, 294912000/2, m_intc) + MCFG_DEVICE_ADD(m_gs, SONYPS2_GS, 294912000/2, m_intc, m_vu1) MCFG_DEVICE_ADD(m_dmac, SONYPS2_DMAC, 294912000/2, m_maincpu, m_ram, m_sif, m_gs, m_vu1) MCFG_DEVICE_ADD(m_sif, SONYPS2_SIF, m_intc) |