summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/arcade.lua4
-rw-r--r--src/devices/machine/vrender0.cpp576
-rw-r--r--src/devices/machine/vrender0.h124
-rw-r--r--src/mame/drivers/crospuzl.cpp441
-rw-r--r--src/mame/drivers/crystal.cpp1445
-rw-r--r--src/mame/drivers/ddz.cpp265
-rw-r--r--src/mame/drivers/menghong.cpp493
-rw-r--r--src/mame/drivers/nexus3d.cpp297
-rw-r--r--src/mame/drivers/psattack.cpp333
-rw-r--r--src/mame/drivers/trivrus.cpp417
-rw-r--r--src/mame/mame.lst24
-rw-r--r--src/mame/video/vrender0.cpp171
-rw-r--r--src/mame/video/vrender0.h43
14 files changed, 3326 insertions, 1319 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index 97dfa1465e2..488b9a56ce4 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -4124,3 +4124,15 @@ if (MACHINES["WTL3132"]~=null) then
MAME_DIR .. "src/devices/machine/wtl3132.h",
}
end
+
+---------------------------------------------------
+--
+--@src/devices/machine/vrender0.h,MACHINES["VRENDER0"] = true
+---------------------------------------------------
+
+if (MACHINES["VRENDER0"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/vrender0.cpp",
+ MAME_DIR .. "src/devices/machine/vrender0.h",
+ }
+end
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 04e871892ee..ee7352c9ba9 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -4650,6 +4650,10 @@ files {
MAME_DIR .. "src/mame/drivers/corona.cpp",
MAME_DIR .. "src/mame/drivers/cwheel.cpp",
MAME_DIR .. "src/mame/drivers/crystal.cpp",
+ MAME_DIR .. "src/mame/drivers/menghong.cpp",
+ MAME_DIR .. "src/mame/drivers/trivrus.cpp",
+ MAME_DIR .. "src/mame/drivers/crospuzl.cpp",
+ MAME_DIR .. "src/mame/drivers/psattack.cpp",
MAME_DIR .. "src/mame/video/vrender0.cpp",
MAME_DIR .. "src/mame/video/vrender0.h",
MAME_DIR .. "src/mame/drivers/cubeqst.cpp",
diff --git a/src/devices/machine/vrender0.cpp b/src/devices/machine/vrender0.cpp
new file mode 100644
index 00000000000..daf3a7f3f64
--- /dev/null
+++ b/src/devices/machine/vrender0.cpp
@@ -0,0 +1,576 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese, ElSemi
+/***************************************************************************
+
+ MagicEyes VRender0 SoC peripherals
+
+ Device by Angelo Salese
+ Based off original crystal.cpp by ElSemi
+
+ TODO:
+ - Improve encapsulation, still needs a few trampolines from host driver;
+ - Proper PIO emulation;
+ - Output CRTC border color;
+ - Add VCLK select;
+
+***************************************************************************/
+
+#include "emu.h"
+#include "vrender0.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(VRENDER0_SOC, vrender0soc_device, "vrender0", "MagicEyes VRender0 SoC")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vrender0soc_device - constructor
+//-------------------------------------------------
+
+vrender0soc_device::vrender0soc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, VRENDER0_SOC, tag, owner, clock),
+ m_host_cpu(*this, finder_base::DUMMY_TAG),
+ m_host_screen(*this, finder_base::DUMMY_TAG),
+ m_crtcregs(*this, "crtcregs"),
+ m_idleskip_cb(*this)
+{
+}
+
+void vrender0soc_device::regs_map(address_map &map)
+{
+// map(0x00000, 0x003ff) // System/General
+ map(0x00000, 0x00003).r(FUNC(vrender0soc_device::sysid_r));
+ map(0x00004, 0x00007).r(FUNC(vrender0soc_device::cfgr_r));
+ map(0x00010, 0x00017).noprw(); // watchdog
+// map(0x00400, 0x007ff) // Local Memory Controller
+// map(0x00800, 0x00bff) // DMA
+ map(0x00800, 0x00803).rw(FUNC(vrender0soc_device::dmac_r<0>), FUNC(vrender0soc_device::dmac_w<0>));
+ map(0x00804, 0x00807).rw(FUNC(vrender0soc_device::dmasa_r<0>), FUNC(vrender0soc_device::dmasa_w<0>));
+ map(0x00808, 0x0080b).rw(FUNC(vrender0soc_device::dmada_r<0>), FUNC(vrender0soc_device::dmada_w<0>));
+ map(0x0080c, 0x0080f).rw(FUNC(vrender0soc_device::dmatc_r<0>), FUNC(vrender0soc_device::dmatc_w<0>));
+ map(0x00810, 0x00813).rw(FUNC(vrender0soc_device::dmac_r<1>), FUNC(vrender0soc_device::dmac_w<1>));
+ map(0x00814, 0x00817).rw(FUNC(vrender0soc_device::dmasa_r<1>), FUNC(vrender0soc_device::dmasa_w<1>));
+ map(0x00818, 0x0081b).rw(FUNC(vrender0soc_device::dmada_r<1>), FUNC(vrender0soc_device::dmada_w<1>));
+ map(0x0081c, 0x0081f).rw(FUNC(vrender0soc_device::dmatc_r<1>), FUNC(vrender0soc_device::dmatc_w<1>));
+
+// map(0x00c00, 0x00fff) // Interrupt Controller
+ map(0x00c04, 0x00c07).rw(FUNC(vrender0soc_device::intvec_r), FUNC(vrender0soc_device::intvec_w));
+ map(0x00c08, 0x00c0b).rw(FUNC(vrender0soc_device::inten_r), FUNC(vrender0soc_device::inten_w));
+ map(0x00c0c, 0x00c0f).rw(FUNC(vrender0soc_device::intst_r), FUNC(vrender0soc_device::intst_w));
+// map(0x01000, 0x013ff) // UART
+// map(0x01400, 0x017ff) // Timer & Counter
+ map(0x01400, 0x01403).rw(FUNC(vrender0soc_device::tmcon_r<0>), FUNC(vrender0soc_device::tmcon_w<0>));
+ map(0x01404, 0x01407).rw(FUNC(vrender0soc_device::tmcnt_r<0>), FUNC(vrender0soc_device::tmcnt_w<0>)).umask32(0x0000ffff);
+ map(0x01408, 0x0140b).rw(FUNC(vrender0soc_device::tmcon_r<1>), FUNC(vrender0soc_device::tmcon_w<1>));
+ map(0x0140c, 0x0140f).rw(FUNC(vrender0soc_device::tmcnt_r<1>), FUNC(vrender0soc_device::tmcnt_w<1>)).umask32(0x0000ffff);
+ map(0x01410, 0x01413).rw(FUNC(vrender0soc_device::tmcon_r<2>), FUNC(vrender0soc_device::tmcon_w<2>));
+ map(0x01414, 0x01417).rw(FUNC(vrender0soc_device::tmcnt_r<2>), FUNC(vrender0soc_device::tmcnt_w<2>)).umask32(0x0000ffff);
+ map(0x01418, 0x0141b).rw(FUNC(vrender0soc_device::tmcon_r<3>), FUNC(vrender0soc_device::tmcon_w<3>));
+ map(0x0141c, 0x0141f).rw(FUNC(vrender0soc_device::tmcnt_r<3>), FUNC(vrender0soc_device::tmcnt_w<3>)).umask32(0x0000ffff);
+
+// map(0x01800, 0x01bff) // Pulse Width Modulation
+// map(0x02000, 0x023ff) // PIO (Port)
+// map(0x02004, 0x02007).rw(FUNC(vrender0soc_device::PIO_r), FUNC(vrender0soc_device::PIO_w)); // PIOLDAT
+// map(0x02008, 0x0200b) // PIOEDAT
+// map(0x02400, 0x027ff) // Peripheral Chip Select
+// map(0x02800, 0x02bff) // SIO
+// map(0x03400, 0x037ff) // CRT Controller
+ map(0x03400, 0x037ff).rw(FUNC(vrender0soc_device::crtc_r), FUNC(vrender0soc_device::crtc_w)).share("crtcregs");
+// map(0x04000, 0x043ff) // RAMDAC & PLL
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - device-specific machine
+// configuration addiitons
+//-------------------------------------------------
+
+void vrender0soc_device::device_add_mconfig(machine_config &config)
+{
+ // ...
+
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vrender0soc_device::device_start()
+{
+ m_host_space = &m_host_cpu->space(AS_PROGRAM);
+ m_idleskip_cb.resolve_safe();
+
+ for (int i = 0; i < 4; i++)
+ m_Timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vrender0soc_device::Timercb),this), (void*)(uintptr_t)i);
+
+ save_item(NAME(m_inten));
+ save_item(NAME(m_intst));
+ save_item(NAME(m_IntHigh));
+
+ save_pointer(NAME(m_timer_control), 4);
+ save_pointer(NAME(m_timer_count), 4);
+ save_item(NAME(m_dma[0].src));
+ save_item(NAME(m_dma[0].dst));
+ save_item(NAME(m_dma[0].size));
+ save_item(NAME(m_dma[0].ctrl));
+
+ save_item(NAME(m_dma[1].ctrl));
+ save_item(NAME(m_dma[1].src));
+ save_item(NAME(m_dma[1].dst));
+ save_item(NAME(m_dma[1].size));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vrender0soc_device::device_reset()
+{
+ // TODO: improve CRT defaults
+ m_crtcregs[1] = 0x00000022;
+
+ //m_FlipCount = 0;
+ m_IntHigh = 0;
+
+ m_dma[0].ctrl = 0;
+ m_dma[1].ctrl = 0;
+
+ for (int i = 0; i < 4; i++)
+ {
+ m_timer_control[i] = 0xff << 8;
+ m_Timer[i]->adjust(attotime::never);
+ }
+}
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+/*
+ *
+ * INT Controller
+ *
+ */
+
+READ32_MEMBER(vrender0soc_device::intvec_r)
+{
+ return (m_IntHigh & 7) << 8;
+}
+
+WRITE32_MEMBER(vrender0soc_device::intvec_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ m_intst &= ~(1 << (data & 0x1f));
+ if (!m_intst)
+ m_host_cpu->set_input_line(SE3208_INT, CLEAR_LINE);
+ }
+ if (ACCESSING_BITS_8_15)
+ m_IntHigh = (data >> 8) & 7;
+}
+
+READ32_MEMBER( vrender0soc_device::inten_r )
+{
+ return m_inten;
+}
+
+WRITE32_MEMBER( vrender0soc_device::inten_w )
+{
+ COMBINE_DATA(&m_inten);
+ // P'S Attack has a timer 0 irq service with no call to intvec_w but just this
+ m_intst &= m_inten;
+ if (!m_intst)
+ m_host_cpu->set_input_line(SE3208_INT, CLEAR_LINE);
+}
+
+READ32_MEMBER( vrender0soc_device::intst_r )
+{
+ return m_intst;
+}
+
+WRITE32_MEMBER( vrender0soc_device::intst_w )
+{
+ // TODO: contradicts with documentation, games writes to this?
+ // ...
+}
+
+void vrender0soc_device::IntReq( int num )
+{
+ if (m_inten & (1 << num))
+ {
+ m_intst |= (1 << num);
+ m_host_cpu->set_input_line(SE3208_INT, ASSERT_LINE);
+ }
+
+ m_idleskip_cb(ASSERT_LINE);
+}
+
+
+int vrender0soc_device::irq_callback()
+{
+ for (int i = 0; i < 32; ++i)
+ {
+ if (BIT(m_intst, i))
+ {
+ return (m_IntHigh << 5) | i;
+ }
+ }
+ return 0; //This should never happen
+}
+
+
+/*
+ *
+ * Timer
+ *
+ */
+
+
+void vrender0soc_device::TimerStart(int which)
+{
+ int PD = (m_timer_control[which] >> 8) & 0xff;
+ int TCV = m_timer_count[which] & 0xffff;
+ attotime period = attotime::from_hz(14318180 * 3) * ((PD + 1) * (TCV + 1)); // TODO : related to CPU clock
+ m_Timer[which]->adjust(period);
+
+// printf("timer %d start, PD = %x TCV = %x period = %s\n", which, PD, TCV, period.as_string());
+}
+
+TIMER_CALLBACK_MEMBER(vrender0soc_device::Timercb)
+{
+ int which = (int)(uintptr_t)ptr;
+ static const int num[] = { 0, 1, 9, 10 };
+
+ if (m_timer_control[which] & 2)
+ TimerStart(which);
+ else
+ m_timer_control[which] &= ~1;
+
+ IntReq(num[which]);
+}
+
+template<int Which>
+READ32_MEMBER(vrender0soc_device::tmcon_r)
+{
+ return m_timer_control[Which];
+}
+
+template<int Which>
+WRITE32_MEMBER(vrender0soc_device::tmcon_w)
+{
+ uint32_t old = m_timer_control[Which];
+ data = COMBINE_DATA(&m_timer_control[Which]);
+
+ if ((data ^ old) & 1)
+ {
+ if (data & 1)
+ {
+ TimerStart(Which);
+ }
+ else
+ {
+ // Timer stop
+ m_Timer[Which]->adjust(attotime::never);
+// printf("timer %d stop\n", Which);
+ }
+ }
+}
+
+template<int Which>
+READ16_MEMBER(vrender0soc_device::tmcnt_r)
+{
+ return m_timer_count[Which] & 0xffff;
+}
+
+template<int Which>
+WRITE16_MEMBER(vrender0soc_device::tmcnt_w)
+{
+ COMBINE_DATA(&m_timer_count[Which]);
+}
+
+/*
+ *
+ * DMA Controller
+ *
+ */
+
+// helper
+// bit 5 and bit 3 of the DMA control don't increment source/destination addresses if enabled.
+// At the time of writing P's Attack is the only SW that uses this feature,
+// in a work RAM to area $4500000 transfer, probably to extend something ...
+inline int vrender0soc_device::dma_setup_hold(uint8_t setting, uint8_t bitmask)
+{
+ return setting & bitmask ? 0 : (setting & 2) ? 4 : (1 << (setting & 1));
+}
+
+template<int Which> READ32_MEMBER(vrender0soc_device::dmasa_r) { return m_dma[Which].src; }
+template<int Which> WRITE32_MEMBER(vrender0soc_device::dmasa_w) { COMBINE_DATA(&m_dma[Which].src); }
+template<int Which> READ32_MEMBER(vrender0soc_device::dmada_r) { return m_dma[Which].dst; }
+template<int Which> WRITE32_MEMBER(vrender0soc_device::dmada_w) { COMBINE_DATA(&m_dma[Which].dst); }
+template<int Which> READ32_MEMBER(vrender0soc_device::dmatc_r) { return m_dma[Which].size; }
+template<int Which> WRITE32_MEMBER(vrender0soc_device::dmatc_w) { COMBINE_DATA(&m_dma[Which].size); }
+template<int Which> READ32_MEMBER(vrender0soc_device::dmac_r) { return m_dma[Which].ctrl; }
+template<int Which>
+WRITE32_MEMBER(vrender0soc_device::dmac_w)
+{
+ if (((data ^ m_dma[Which].ctrl) & (1 << 10)) && (data & (1 << 10))) //DMAOn
+ {
+ uint32_t const CTR = data;
+ uint32_t const SRC = m_dma[Which].src;
+ uint32_t const DST = m_dma[Which].dst;
+ uint32_t const CNT = m_dma[Which].size;
+ const int src_inc = dma_setup_hold(CTR, 0x20);
+ const int dst_inc = dma_setup_hold(CTR, 0x08);
+
+ if ((CTR & 0xd4) != 0)
+ popmessage("DMA%d with unhandled mode %02x, contact MAMEdev",Which,CTR);
+
+ if (CTR & 0x2) //32 bits
+ {
+ for (int i = 0; i < CNT; ++i)
+ {
+ uint32_t v = m_host_space->read_dword(SRC + i * src_inc);
+ m_host_space->write_dword(DST + i * dst_inc, v);
+ }
+ }
+ else if (CTR & 0x1) //16 bits
+ {
+ for (int i = 0; i < CNT; ++i)
+ {
+ uint16_t v = m_host_space->read_word(SRC + i * src_inc);
+ m_host_space->write_word(DST + i * dst_inc, v);
+ }
+ }
+ else //8 bits
+ {
+ for (int i = 0; i < CNT; ++i)
+ {
+ uint8_t v = m_host_space->read_byte(SRC + i * src_inc);
+ m_host_space->write_byte(DST + i * dst_inc, v);
+ }
+ }
+ data &= ~(1 << 10);
+ // TODO: insta-DMA
+ m_dma[Which].size = 0;
+ IntReq(7 + Which);
+ }
+ COMBINE_DATA(&m_dma[Which].ctrl);
+}
+
+READ32_MEMBER(vrender0soc_device::crtc_r)
+{
+ uint32_t res = m_crtcregs[offset];
+ uint32_t hdisp = (m_crtcregs[0x0c / 4] + 1);
+ uint32_t vdisp = (m_crtcregs[0x1c / 4] + 1);
+ switch (offset)
+ {
+ case 0: // CRTC Status / Mode
+ if (crt_is_interlaced()) // Interlace
+ vdisp <<= 1;
+
+ if (m_host_screen->vpos() <= vdisp) // Vertical display enable status
+ res |= 0x4000;
+
+ if (m_host_screen->hpos() > hdisp) // horizontal & vertical blank period
+ res &= ~0x2000;
+ else
+ res |= 0x2000;
+
+ break;
+ default:
+ break;
+ }
+ return res;
+}
+
+WRITE32_MEMBER(vrender0soc_device::crtc_w)
+{
+ if (((m_crtcregs[0] & 0x0100) == 0x0100) && (offset > 0)) // Write protect
+ return;
+
+ uint32_t old = m_crtcregs[offset];
+ switch (offset * 4)
+ {
+ case 0: // CRTC Status / Mode Register (CRTMOD)
+ mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
+ break;
+ case 0x04: // CRTC Timing Control Register (CRTTIM)
+ mem_mask &= ~0xffffc000; // Bit 31-14 Reserved
+ break;
+ case 0x08: // Horizontal Sync Width / Back Porch Register (HSWBP)
+ mem_mask &= ~0xffff0000; // Bit 31-16 Reserved
+ break;
+ case 0x0c: // Horizontal Display Total Register (HDISP)
+ mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
+ break;
+ case 0x10: // Horizontal Sync Front Porch Register (HSFP)
+ mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
+ break;
+ case 0x14: // Field Window Bound Register (FWINB)
+ mem_mask &= ~0xffff80c0; // Bit 31-15, 7-6 Reserved
+ break;
+ case 0x18: // Vertical Sync Back Porch Register (VSBP)
+ mem_mask &= ~0xffffff00; // Bit 31-8 Reserved
+ break;
+ case 0x1c: // Vertical Display Total Register (VDISP)
+ mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
+ break;
+ case 0x20: // Horizontal Total Register (HTOT)
+ mem_mask &= ~0xffffe000; // Bit 31-13 Reserved
+ if (BIT(data, 10) == 0) // enable bit
+ return;
+ break;
+ case 0x24: // Vertical Total Register (VTOT)
+ mem_mask &= ~0xfffff000; // Bit 31-12 Reserved
+ if (BIT(data, 11) == 0) // enable bit
+ return;
+ break;
+ case 0x28: // Horizontal Line Back Porch Register (HLBP)
+ mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
+ break;
+ case 0x2c: // CRT Display Start Address 0 Register (STAD0)
+ mem_mask &= ~0xffff8000; // Bit 31-15 Reserved
+ break;
+ case 0x30: // CRT Display Start Address 1 Register (STAD1)
+ mem_mask &= ~0xffff8000; // Bit 31-15 Reserved
+ break;
+ case 0x38: // Light Pen 0 X Register (LIGHT0X)
+ mem_mask &= ~0xfffff800; // Bit 31-11 Reserved
+ break;
+ case 0x3c: // Light Pen 0 Y Register (LIGHT0Y)
+ mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
+ break;
+ case 0x40: // Light Pen 1 X Register (LIGHT1X)
+ mem_mask &= ~0xfffff800; // Bit 31-11 Reserved
+ break;
+ case 0x44: // Light Pen 1 Y Register (LIGHT1Y)
+ mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
+ break;
+ case 0x48: // Light Pen Input Control Register (LIGHTC)
+ mem_mask &= ~0xfffffffc; // Bit 31-2 Reserved
+ break;
+ default:
+ return;
+ }
+ COMBINE_DATA(&m_crtcregs[offset]);
+ if (old ^ m_crtcregs[offset])
+ crtc_update();
+
+}
+
+inline bool vrender0soc_device::crt_is_interlaced()
+{
+ return (m_crtcregs[0x30 / 4] & 1) == 0;
+}
+
+bool vrender0soc_device::crt_active_vblank_irq()
+{
+ if (crt_is_interlaced() == false)
+ return true;
+
+ // bit 3 of CRTC reg -> select display start
+ return (m_host_screen->frame_number() & 1) ^ ((m_crtcregs[0] & 8) >> 3);
+}
+
+void vrender0soc_device::crtc_update()
+{
+ uint32_t hdisp = m_crtcregs[0x0c / 4] + 1;
+ uint32_t vdisp = m_crtcregs[0x1c / 4];
+ if (hdisp == 0 || vdisp == 0)
+ return;
+
+ bool interlace_mode = crt_is_interlaced();
+
+ if (interlace_mode)
+ vdisp <<= 1;
+
+ uint32_t htot = (m_crtcregs[0x20 / 4] & 0x3ff) + 1;
+ uint32_t vtot = (m_crtcregs[0x24 / 4] & 0x7ff);
+
+ // adjust htotal in case it's not setup by the game
+ // (datasheet mentions that it can be done automatically shrug):
+ // - the two Sealy games do that
+ // - Cross Puzzle sets up an HTotal of 400 with 640x480 display
+ // - donghaer writes a 0 to the htot when entering interlace mode
+ // TODO: we may as well just ditch reading from HTOTAL and VTOTAL and use these instead
+ if (htot <= 1 || htot <= hdisp)
+ {
+ uint32_t hbp = (m_crtcregs[0x08 / 4] & 0xff00) >> 8;
+ uint32_t hsw = (m_crtcregs[0x08 / 4] & 0xff);
+ uint32_t hsfp = m_crtcregs[0x10 / 4] & 0xff;
+ if (hbp == 0 && hsw == 0 && hsfp == 0)
+ return;
+
+ htot = hdisp + (hbp+1) + (hsw+1) + (hsfp+1);
+ m_crtcregs[0x20 / 4] = ((htot & 0x3ff) - 1);
+ }
+
+ // urachamu
+ if (vtot == 0)
+ {
+ uint32_t vbp = (m_crtcregs[0x08 / 4] & 0xff);
+ if (vbp == 0)
+ return;
+
+ vtot = vdisp + (vbp + 1);
+ m_crtcregs[0x24 / 4] = ((vtot & 0x7ff) - 1);
+ }
+
+ // TODO: the two Sealy games doesn't set this, eventually need to parametrize this one up
+ uint32_t pixel_clock = (BIT(m_crtcregs[0x04 / 4], 3)) ? 14318180 : 14318180*2;
+ if (BIT(m_crtcregs[0x04 / 4], 7))
+ pixel_clock *= 2;
+ // TODO: divider setting = 0 is reserved, guess it just desyncs the signal?
+ pixel_clock /= (m_crtcregs[0x04 / 4] & 7) + 1;
+
+ //printf("DCLK divider %d\n",(m_crtcregs[0x04 / 4] & 7) + 1);
+ //printf("VCLK select %d\n",(m_crtcregs[0x04 / 4] & 8));
+ //printf("CBCLK divider %d\n",((m_crtcregs[0x04 / 4] & 0x70) >> 4) + 1);
+ //printf("ivclk speed %d\n",(m_crtcregs[0x04 / 4] & 0x80));
+
+ if (interlace_mode == false)
+ {
+ vtot >>= 1;
+ vtot += 1;
+ }
+ //else
+ // pixel_clock >>= 1;
+
+
+ vtot += 9;
+
+ //printf("%dX%d %dX%d %d\n",htot, vtot, hdisp, vdisp, pixel_clock);
+
+ rectangle const visarea(0, hdisp - 1, 0, vdisp - 1);
+ m_host_screen->configure(htot, vtot, visarea, HZ_TO_ATTOSECONDS(pixel_clock) * vtot * htot);
+}
+
+// accessed by cross puzzle
+READ32_MEMBER(vrender0soc_device::sysid_r)
+{
+ // Device ID: VRender0+ -> 0x0a
+ // Revision Number -> 0x00
+ return 0x00000a00;
+}
+
+READ32_MEMBER(vrender0soc_device::cfgr_r)
+{
+ // TODO: this truly needs real HW verification
+ // -x-- ---- Main Clock select (0 -> External Clock)
+ // --xx x--- Reserved for Chip Test Mode
+ // ---- -xx- Local ROM Data Bus Width (01 -> 16 bit)
+ // ---- ---x Local Memory Bus Width (0 -> 16 bit)
+ return 0x00000002;
+}
diff --git a/src/devices/machine/vrender0.h b/src/devices/machine/vrender0.h
new file mode 100644
index 00000000000..46795ca6900
--- /dev/null
+++ b/src/devices/machine/vrender0.h
@@ -0,0 +1,124 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese, ElSemi
+/***************************************************************************
+
+ MagicEyes VRender0 SoC
+
+***************************************************************************/
+
+#ifndef MAME_MACHINE_VRENDER0_H
+#define MAME_MACHINE_VRENDER0_H
+
+#pragma once
+
+#include "cpu/se3208/se3208.h"
+#include "screen.h"
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vrender0soc_device
+
+class vrender0soc_device : public device_t
+{
+public:
+ // construction/destruction
+ vrender0soc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ void regs_map(address_map &map);
+ template<class T> void set_host_cpu_tag(T &&tag) { m_host_cpu.set_tag(std::forward<T>(tag)); }
+ template<class T> void set_host_screen_tag(T &&tag) { m_host_screen.set_tag(std::forward<T>(tag)); }
+ bool crt_is_blanked() { return ((m_crtcregs[0] & 0x0200) == 0x0200); }
+ bool crt_active_vblank_irq();
+ void IntReq( int num );
+ int irq_callback();
+ auto idleskip_cb() { return m_idleskip_cb.bind(); }
+ bool irq_pending() { return m_intst & m_inten; }
+
+protected:
+ // device-level overrides
+ //virtual void device_validity_check(validity_checker &valid) const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device <se3208_device> m_host_cpu;
+ required_device <screen_device> m_host_screen;
+ required_shared_ptr <uint32_t> m_crtcregs;
+ devcb_write_line m_idleskip_cb;
+
+ address_space *m_host_space;
+ // To move into SoC own device
+ // INTC
+ uint32_t m_inten;
+ DECLARE_READ32_MEMBER(inten_r);
+ DECLARE_WRITE32_MEMBER(inten_w);
+
+ DECLARE_READ32_MEMBER(intvec_r);
+ DECLARE_WRITE32_MEMBER(intvec_w);
+
+ uint8_t m_IntHigh;
+ uint32_t m_intst;
+ DECLARE_READ32_MEMBER(intst_r);
+ DECLARE_WRITE32_MEMBER(intst_w);
+
+ // Timer
+ template<int Which> DECLARE_WRITE32_MEMBER(tmcon_w);
+ template<int Which> DECLARE_READ32_MEMBER(tmcon_r);
+ template<int Which> DECLARE_WRITE16_MEMBER(tmcnt_w);
+ template<int Which> DECLARE_READ16_MEMBER(tmcnt_r);
+ TIMER_CALLBACK_MEMBER(Timercb);
+
+ uint32_t m_timer_control[4];
+ uint16_t m_timer_count[4];
+ emu_timer *m_Timer[4];
+ void TimerStart(int which);
+
+ // DMAC
+ template<int Which> DECLARE_READ32_MEMBER(dmac_r);
+ template<int Which> DECLARE_WRITE32_MEMBER(dmac_w);
+ template<int Which> DECLARE_READ32_MEMBER(dmatc_r);
+ template<int Which> DECLARE_WRITE32_MEMBER(dmatc_w);
+ template<int Which> DECLARE_READ32_MEMBER(dmasa_r);
+ template<int Which> DECLARE_WRITE32_MEMBER(dmasa_w);
+ template<int Which> DECLARE_READ32_MEMBER(dmada_r);
+ template<int Which> DECLARE_WRITE32_MEMBER(dmada_w);
+ inline int dma_setup_hold(uint8_t setting, uint8_t bitmask);
+ struct {
+ uint32_t src;
+ uint32_t dst;
+ uint32_t size;
+ uint32_t ctrl;
+ }m_dma[2];
+
+ // CRTC
+ DECLARE_READ32_MEMBER(crtc_r);
+ DECLARE_WRITE32_MEMBER(crtc_w);
+ void crtc_update();
+ inline bool crt_is_interlaced();
+
+ // Misc
+ DECLARE_READ32_MEMBER( sysid_r );
+ DECLARE_READ32_MEMBER( cfgr_r );
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(VRENDER0_SOC, vrender0soc_device)
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+
+#endif // MAME_MACHINE_VRENDER0_H
diff --git a/src/mame/drivers/crospuzl.cpp b/src/mame/drivers/crospuzl.cpp
new file mode 100644
index 00000000000..9523e4fb143
--- /dev/null
+++ b/src/mame/drivers/crospuzl.cpp
@@ -0,0 +1,441 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/****************************************************************************
+
+ Cross Puzzle
+
+ driver by Angelo Salese, based off original crystal.cpp by ElSemi
+
+ TODO:
+ - Dies at POST with a SPU error and no Flash memory available;
+ - RTC isn't DS1302
+
+
+=============================================================================
+
+ This PCB uses ADC 'Amazon-LF' SoC, EISC CPU core - However PCBs have been see
+ with a standard VRenderZERO+ MagicEyes EISC chip
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/se3208/se3208.h"
+#include "machine/ds1302.h"
+#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
+#include "sound/vrender0.h"
+#include "video/vrender0.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+
+#include <algorithm>
+
+#define IDLE_LOOP_SPEEDUP
+
+class crospuzl_state : public driver_device
+{
+public:
+ crospuzl_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_workram(*this, "workram"),
+ m_textureram(*this, "textureram"),
+ m_frameram(*this, "frameram"),
+ m_flash(*this, "flash"),
+ m_maincpu(*this, "maincpu"),
+ m_vr0soc(*this, "vr0soc"),
+ m_vr0vid(*this, "vr0vid"),
+ m_vr0snd(*this, "vr0snd"),
+ m_ds1302(*this, "rtc"),
+ m_screen(*this, "screen")
+ { }
+
+
+ void crospuzl(machine_config &config);
+
+private:
+
+ /* memory pointers */
+ required_shared_ptr<uint32_t> m_workram;
+ required_shared_ptr<uint32_t> m_textureram;
+ required_shared_ptr<uint32_t> m_frameram;
+ required_region_ptr<uint8_t> m_flash;
+
+ /* devices */
+ required_device<se3208_device> m_maincpu;
+ required_device<vrender0soc_device> m_vr0soc;
+ required_device<vr0video_device> m_vr0vid;
+ required_device<vr0sound_device> m_vr0snd;
+ required_device<ds1302_device> m_ds1302;
+ required_device<screen_device> m_screen;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
+#endif
+
+ uint32_t m_FlashCmd;
+ uint32_t m_crospuzl_addr;
+
+// DECLARE_WRITE32_MEMBER(Banksw_w);
+ DECLARE_READ8_MEMBER(FlashCmd_r);
+ DECLARE_WRITE32_MEMBER(FlashCmd_w);
+ DECLARE_WRITE32_MEMBER(flash_addr_w);
+
+ IRQ_CALLBACK_MEMBER(icallback);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void crospuzl_mem(address_map &map);
+
+ // PIO
+ DECLARE_READ32_MEMBER(PIOldat_r);
+ uint32_t m_PIO;
+ DECLARE_WRITE32_MEMBER(PIOldat_w);
+ DECLARE_READ32_MEMBER(PIOedat_r);
+};
+
+
+uint32_t crospuzl_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
+ {
+ bitmap.fill(0, cliprect);
+ return 0;
+ }
+
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
+}
+
+WRITE_LINE_MEMBER(crospuzl_state::screen_vblank)
+{
+ // rising edge
+ if (state)
+ {
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
+
+ m_vr0vid->execute_drawing();
+ }
+}
+
+IRQ_CALLBACK_MEMBER(crospuzl_state::icallback)
+{
+ return m_vr0soc->irq_callback();
+}
+
+WRITE32_MEMBER(crospuzl_state::FlashCmd_w)
+{
+ m_FlashCmd = data;
+}
+
+READ32_MEMBER(crospuzl_state::PIOedat_r)
+{
+ return machine().rand() & 0x04000000; // serial ready line
+}
+
+WRITE32_MEMBER(crospuzl_state::flash_addr_w)
+{
+ if (m_FlashCmd == 0x90)
+ m_crospuzl_addr = 0;
+ if (data)
+ m_crospuzl_addr = (data << 16);
+}
+
+READ8_MEMBER(crospuzl_state::FlashCmd_r)
+{
+ if ((m_FlashCmd & 0xff) == 0xff)
+ {
+ return 0xff;
+ }
+ if ((m_FlashCmd & 0xff) == 0x90)
+ {
+ const uint8_t id[5] = { 0xee, 0x81, 0x00, 0x00, 0x00 };
+ uint8_t res = id[m_crospuzl_addr];
+ m_crospuzl_addr ++;
+ m_crospuzl_addr %= 4;
+ return res;
+ }
+ if ((m_FlashCmd & 0xff) == 0x30)
+ {
+ uint8_t res = m_flash[m_crospuzl_addr];
+ m_crospuzl_addr++;
+ return res;
+ }
+ return 0;
+}
+
+READ32_MEMBER(crospuzl_state::PIOldat_r)
+{
+ return m_PIO;
+}
+
+// PIO Latched output DATa Register
+// TODO: change me
+WRITE32_MEMBER(crospuzl_state::PIOldat_w)
+{
+ uint32_t RST = data & 0x01000000;
+ uint32_t CLK = data & 0x02000000;
+ uint32_t DAT = data & 0x10000000;
+
+ m_ds1302->ce_w(RST ? 1 : 0);
+ m_ds1302->io_w(DAT ? 1 : 0);
+ m_ds1302->sclk_w(CLK ? 1 : 0);
+
+ COMBINE_DATA(&m_PIO);
+}
+
+void crospuzl_state::crospuzl_mem(address_map &map)
+{
+ map(0x00000000, 0x0007ffff).rom().nopw();
+
+ map(0x01500000, 0x01500000).r(FUNC(crospuzl_state::FlashCmd_r));
+ map(0x01500100, 0x01500103).w(FUNC(crospuzl_state::FlashCmd_w));
+ map(0x01500200, 0x01500203).w(FUNC(crospuzl_state::flash_addr_w));
+ map(0x01510000, 0x01510003).portr("IN0");
+ map(0x01511000, 0x01511003).portr("IN1");
+ map(0x01512000, 0x01512003).portr("IN2");
+ map(0x01513000, 0x01513003).portr("IN3");
+
+ map(0x01600000, 0x01607fff).ram().share("nvram");
+
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+ map(0x01802004, 0x01802007).rw(FUNC(crospuzl_state::PIOldat_r), FUNC(crospuzl_state::PIOldat_w));
+ map(0x01802008, 0x0180200b).r(FUNC(crospuzl_state::PIOedat_r));
+
+ map(0x02000000, 0x027fffff).ram().share("workram");
+
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
+ map(0x03800000, 0x03ffffff).ram().share("textureram");
+ map(0x04000000, 0x047fffff).ram().share("frameram");
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+
+// map(0x05000000, 0x05ffffff).bankr("mainbank");
+// map(0x05000000, 0x05000003).rw(FUNC(crospuzl_state::FlashCmd_r), FUNC(crospuzl_state::FlashCmd_w));
+}
+
+#ifdef IDLE_LOOP_SPEEDUP
+
+WRITE_LINE_MEMBER(crospuzl_state::idle_skip_resume_w)
+{
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
+}
+
+WRITE_LINE_MEMBER(crospuzl_state::idle_skip_speedup_w)
+{
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
+}
+#endif
+
+void crospuzl_state::machine_start()
+{
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
+
+
+#ifdef IDLE_LOOP_SPEEDUP
+ save_item(NAME(m_FlipCntRead));
+#endif
+
+// save_item(NAME(m_Bank));
+ save_item(NAME(m_FlashCmd));
+ save_item(NAME(m_PIO));
+}
+
+void crospuzl_state::machine_reset()
+{
+ m_FlashCmd = 0xff;
+ m_crospuzl_addr = 0;
+#ifdef IDLE_LOOP_SPEEDUP
+ m_FlipCntRead = 0;
+#endif
+}
+
+static INPUT_PORTS_START(crospuzl)
+ PORT_START("IN0")
+ PORT_DIPNAME( 0x0001, 0x0001, "DSW1" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0100, 0x0100, "DSW2" )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN1")
+ PORT_DIPNAME( 0x01, 0x01, "IN1" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN2")
+ PORT_DIPNAME( 0x01, 0x01, "IN2" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN3")
+ PORT_DIPNAME( 0x01, 0x01, "IN3" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("PCB-SW1")
+ PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+INPUT_PORTS_END
+
+void crospuzl_state::crospuzl(machine_config &config)
+{
+ SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
+ m_maincpu->set_addrmap(AS_PROGRAM, &crospuzl_state::crospuzl_mem);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(crospuzl_state::icallback));
+
+ NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
+ m_screen->set_screen_update(FUNC(crospuzl_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(crospuzl_state::screen_vblank));
+ m_screen->set_palette("palette");
+
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
+ VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(crospuzl_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(crospuzl_state::idle_skip_speedup_w));
+ #endif
+
+ PALETTE(config, "palette", palette_device::RGB_565);
+
+ DS1302(config, m_ds1302, 32.768_kHz_XTAL);
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ SOUND_VRENDER0(config, m_vr0snd, 0);
+ m_vr0snd->add_route(0, "lspeaker", 1.0);
+ m_vr0snd->add_route(1, "rspeaker", 1.0);
+}
+
+ROM_START( crospuzl )
+ ROM_REGION( 0x80010, "maincpu", 0 )
+ ROM_LOAD("en29lv040a.u5", 0x000000, 0x80010, CRC(d50e8500) SHA1(d681cd18cd0e48854c24291d417d2d6d28fe35c1) )
+
+ ROM_REGION( 0x8400010, "flash", ROMREGION_ERASEFF ) // NAND Flash
+ // mostly empty, but still looks good
+ ROM_LOAD("k9f1g08u0a.riser", 0x000000, 0x0020000, CRC(7f3c88c3) SHA1(db3169a7b4caab754e9d911998a2ece13c65ce5b) )
+ ROM_CONTINUE( 0x000000, 0x8400010-0x0020000 )
+ROM_END
+
+GAME( 200?, crospuzl, 0, crospuzl, crospuzl, crospuzl_state, empty_init, ROT0, "<unknown>", "Cross Puzzle", MACHINE_NOT_WORKING )
diff --git a/src/mame/drivers/crystal.cpp b/src/mame/drivers/crystal.cpp
index 23121983996..58fc5c8e9a7 100644
--- a/src/mame/drivers/crystal.cpp
+++ b/src/mame/drivers/crystal.cpp
@@ -116,121 +116,14 @@ Notes:
Note: there are 8 spaces total for FlashROMs. Only U1, U2 & U3 are populated in this cart.
-
-P's Attack (c) 2004 Uniana Co., Ltd
-
-+----------54321---654321--654321---------------------------+
-|VOL TICKET GUN_1P GUN_2P +---------|
-| | |
-+-+ | 256MB |
- | CC-DAC | Compact |
-+-+ EMUL* | Flash |
-| | |
-|5 +---+ +---------|
-|6 | | |
-|P | R | 25.1750MHz +--------------+|
-|I | A | | 42Pin* ||
-|N | M | +--------------+|
-| | | +--------------+|
-|C +---+ +------------+ | SYS ||
-|O | | +--------------+|
-|N +---+ | | |
-|N | | |VRenderZERO+| |
-|E SERVICE | R | | MagicEyes | +-------+ 62256* |
-|C | A | | | | RAM | |
-|T TEST | M | | | +-------+ 62256* |
-|O | | +------------+ |
-|R RESET +---+ |
-| 14.31818MHz |
-+-+ |
- | EEPROM |
-+-+ GAL DSW |
-| |
-| VGA PIC BAT3.6V* |
-+-----------------------------------------------------------+
-
-* denotes unpopulated device
-
-RAM are Samsung K4S641632H-TC75
-VGA is a standard PC 15 pin VGA connection
-DSW is 2 switch dipswitch (switches 3-8 are unpopulated)
-PIC is a Microchip PIC16C711-041/P (silkscreened on the PCB as COSTOM)
-SYS is a ST M27C160 EPROM (silkscreened on the PCB as SYSTEM_ROM_32M)
-GAL is a GAL16V8B (not dumped)
-EMUL is an unpopulated 8 pin connector
-EEPROM is a 93C86 16K 5.0v Serial EEPROM (2048x8-bit or 1024x16-bit)
-CC-DAC is a TDA1311A Stereo Continuous Calibration DAC
-
-
- P's Attack non JAMMA standard 56pin Edge Connector Pinout:
-
- 56pin Edge Connector
- Solder Side | Parts Side
-------------------------------------------------------------------
- GND | A | 1 | GND
- GND | B | 2 | GND
- +5 | C | 3 | +5
- +5 | D | 4 | +5
- Player 1 Start Lamp | E | 5 | Coin Lamp
- +12 | F | 6 | +12
------------- KEY ------------| G | 7 |------------ KEY -----------
- Player 2 Start Lamp | H | 8 | Coin Counter
- L Speaker (-) | J | 9 | L Speaker (+)
- R Speaker (-) | K | 10| R Speaker (+)
- Video Vertical Sync | L | 11|
- Video Green | M | 12| Video Red
- Video Sync | N | 13| Video Blue
- Service Switch | P | 14| Video GND
- Video Horizontal Sync | R | 15| Test Switch
- | S | 16| Coin Switch
- Start Player 2 | T | 17| Start Player 1
- | U | 18|
- | V | 19|
- | W | 20|
- | X | 21|
- | Y | 22|
- | a | 23|
- | b | 24|
- | d | 25|
- | e | 26|
- GND | f | 27| GND
- GND | g | 28| GND
-
-
-TICKET is a 5 pin connector:
-
- 1| LED
- 2| GND
- 3| OUT
- 4| IN
- 5| +12v
-
-GUN_xP are 6 pin gun connectors (pins 3-6 match the UNICO sytle guns):
-
- GUN-1P: Left (Blue) Gun Connector Pinout
-
- 1| GND
- 2| Solenoid
- 3| Sensor
- 4| +5V
- 5| Switch (Trigger)
- 6| GND
-
- GUN-2P: Right (Pink) Gun Connector Pinout
-
- 1| GND
- 2| Solenoid
- 3| Sensor
- 4| +5V
- 5| Switch (Trigger)
- 6| GND
-
*/
#include "emu.h"
#include "cpu/se3208/se3208.h"
#include "machine/ds1302.h"
#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
#include "sound/vrender0.h"
#include "video/vrender0.h"
#include "emupal.h"
@@ -240,25 +133,27 @@ GUN_xP are 6 pin gun connectors (pins 3-6 match the UNICO sytle guns):
#include <algorithm>
#define IDLE_LOOP_SPEEDUP
+// strip this define once we have actual credits from Smitdogg
+//#define ROGUE_CARTS
class crystal_state : public driver_device
{
public:
crystal_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
- m_sysregs(*this, "sysregs"),
m_workram(*this, "workram"),
- m_vidregs(*this, "vidregs"),
m_textureram(*this, "textureram"),
m_frameram(*this, "frameram"),
m_reset_patch(*this, "reset_patch"),
m_flash(*this, "flash"),
m_mainbank(*this, "mainbank"),
m_maincpu(*this, "maincpu"),
+ m_vr0soc(*this, "vr0soc"),
m_vr0vid(*this, "vr0vid"),
m_vr0snd(*this, "vr0snd"),
m_ds1302(*this, "rtc"),
- m_screen(*this, "screen")
+ m_screen(*this, "screen"),
+ m_eeprom(*this, "eeprom")
{ }
void init_topbladv();
@@ -266,447 +161,111 @@ public:
void init_crysking();
void init_evosocc();
void init_donghaer();
- void init_psattack();
+#ifdef ROGUE_CARTS
+ void init_maldaiza();
+#endif
- void crospuzl(machine_config &config);
void crystal(machine_config &config);
- void crzyddz2(machine_config &config);
- void trivrus(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
private:
/* memory pointers */
- required_shared_ptr<uint32_t> m_sysregs;
- uint32_t *m_crtcregs;
required_shared_ptr<uint32_t> m_workram;
- required_shared_ptr<uint32_t> m_vidregs;
required_shared_ptr<uint32_t> m_textureram;
required_shared_ptr<uint32_t> m_frameram;
- optional_shared_ptr<uint32_t> m_reset_patch; // not needed for trivrus
+ optional_shared_ptr<uint32_t> m_reset_patch;
optional_region_ptr<uint32_t> m_flash;
optional_memory_bank m_mainbank;
/* devices */
required_device<se3208_device> m_maincpu;
+ required_device<vrender0soc_device> m_vr0soc;
required_device<vr0video_device> m_vr0vid;
required_device<vr0sound_device> m_vr0snd;
required_device<ds1302_device> m_ds1302;
required_device<screen_device> m_screen;
+ optional_device<eeprom_serial_93cxx_device> m_eeprom;
#ifdef IDLE_LOOP_SPEEDUP
uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
#endif
uint32_t m_Bank;
uint32_t m_maxbank;
- uint8_t m_FlipCount;
- uint8_t m_IntHigh;
- emu_timer *m_Timer[4];
uint32_t m_FlashCmd;
- uint32_t m_PIO;
- uint32_t m_DMActrl[2];
- uint8_t m_OldPort4;
-
- uint32_t *TimerRegsPtr(int which) const;
- void TimerStart(int which);
-
- DECLARE_READ32_MEMBER(FlipCount_r);
- DECLARE_WRITE32_MEMBER(FlipCount_w);
- DECLARE_WRITE32_MEMBER(IntAck_w);
- template<int Which> DECLARE_WRITE32_MEMBER(Timer_w);
- template<int Which> DECLARE_READ32_MEMBER(Timer_r);
- template<int Which> DECLARE_READ32_MEMBER(DMA_r);
- template<int Which> DECLARE_WRITE32_MEMBER(DMA_w);
- DECLARE_READ32_MEMBER(crtc_r);
- DECLARE_WRITE32_MEMBER(crtc_w);
- void crtc_update();
-
- DECLARE_READ32_MEMBER(Input_r);
+
+ IRQ_CALLBACK_MEMBER(icallback);
+ DECLARE_READ32_MEMBER(system_input_r);
DECLARE_WRITE32_MEMBER(Banksw_w);
- DECLARE_READ32_MEMBER(PIO_r);
- DECLARE_WRITE32_MEMBER(PIO_w);
DECLARE_READ32_MEMBER(FlashCmd_r);
DECLARE_WRITE32_MEMBER(FlashCmd_w);
-
- DECLARE_READ8_MEMBER(trivrus_input_r);
- DECLARE_WRITE8_MEMBER(trivrus_input_w);
- uint8_t m_trivrus_input;
-
- DECLARE_READ32_MEMBER(crzyddz2_key_r);
- DECLARE_WRITE32_MEMBER(crzyddz2_PIO_w);
- uint8_t m_crzyddz2_prot;
+ DECLARE_WRITE32_MEMBER(coin_counters_w);
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
- TIMER_CALLBACK_MEMBER(Timercb);
- IRQ_CALLBACK_MEMBER(icallback);
- void IntReq( int num );
- inline void DMA_w( address_space &space, int which, uint32_t data, uint32_t mem_mask );
- void PatchReset( );
- uint16_t GetVidReg( address_space &space, uint16_t reg );
- void SetVidReg( address_space &space, uint16_t reg, uint16_t val );
- void crospuzl_mem(address_map &map);
+ void PatchReset();
void crystal_mem(address_map &map);
- void crzyddz2_mem(address_map &map);
- void internal_map(address_map &map);
- void trivrus_mem(address_map &map);
+
+ // PIO
+ DECLARE_READ32_MEMBER(PIOldat_r);
+ DECLARE_WRITE32_MEMBER(PIOldat_w);
+ DECLARE_READ32_MEMBER(PIOedat_r);
+ uint32_t m_PIO;
};
-void crystal_state::IntReq( int num )
+uint32_t crystal_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint32_t IntEn = space.read_dword(0x01800c08);
- uint32_t IntPend = space.read_dword(0x01800c0c);
- if (IntEn & (1 << num))
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
{
- IntPend |= (1 << num);
- space.write_dword(0x01800c0c, IntPend);
- m_maincpu->set_input_line(SE3208_INT, ASSERT_LINE);
+ bitmap.fill(0, cliprect);
+ return 0;
}
-#ifdef IDLE_LOOP_SPEEDUP
- m_FlipCntRead = 0;
- m_maincpu->resume(SUSPEND_REASON_SPIN);
-#endif
-}
-READ32_MEMBER(crystal_state::FlipCount_r)
-{
-#ifdef IDLE_LOOP_SPEEDUP
- uint32_t IntPend = space.read_dword(0x01800c0c);
- m_FlipCntRead++;
- if (m_FlipCntRead >= 16 && !IntPend && m_FlipCount != 0)
- m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
-#endif
- return ((uint32_t) m_FlipCount) << 16;
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
}
-WRITE32_MEMBER(crystal_state::FlipCount_w)
+WRITE_LINE_MEMBER(crystal_state::screen_vblank)
{
- if (ACCESSING_BITS_16_23)
+ // rising edge
+ if (state)
{
- int fc = (data >> 16) & 0xff;
- if (fc == 1)
- m_FlipCount++;
- else if (fc == 0)
- m_FlipCount = 0;
- }
-}
-
-WRITE32_MEMBER(crystal_state::IntAck_w)
-{
- uint32_t IntPend = space.read_dword(0x01800c0c);
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
- if (ACCESSING_BITS_0_7)
- {
- IntPend &= ~(1 << (data & 0x1f));
- space.write_dword(0x01800c0c, IntPend);
- if (!IntPend)
- m_maincpu->set_input_line(SE3208_INT, CLEAR_LINE);
+ m_vr0vid->execute_drawing();
}
- if (ACCESSING_BITS_8_15)
- m_IntHigh = (data >> 8) & 7;
}
IRQ_CALLBACK_MEMBER(crystal_state::icallback)
{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint32_t IntPend = space.read_dword(0x01800c0c);
-
- for (int i = 0; i < 32; ++i)
- {
- if (BIT(IntPend, i))
- {
- return (m_IntHigh << 5) | i;
- }
- }
- return 0; //This should never happen
-}
-
-uint32_t *crystal_state::TimerRegsPtr(int which) const
-{
- return &m_sysregs[0x1400/4 + which * 8/4];
-}
-
-void crystal_state::TimerStart(int which)
-{
- uint32_t *regs = TimerRegsPtr(which);
-
- int PD = (regs[0] >> 8) & 0xff;
- int TCV = regs[1] & 0xffff;
- attotime period = attotime::from_hz(14318180 * 3) * ((PD + 1) * (TCV + 1)); // TODO : related to CPU clock
- m_Timer[which]->adjust(period);
-
-// printf("timer %d start, PD = %x TCV = %x period = %s\n", which, PD, TCV, period.as_string());
-}
-
-TIMER_CALLBACK_MEMBER(crystal_state::Timercb)
-{
- int which = (int)(uintptr_t)ptr;
- static const int num[] = { 0, 1, 9, 10 };
-
- uint32_t *regs = TimerRegsPtr(which);
-
- if (regs[0] & 2)
- TimerStart(which);
- else
- regs[0] &= ~1;
-
- IntReq(num[which]);
+ return m_vr0soc->irq_callback();
}
-template<int Which>
-WRITE32_MEMBER(crystal_state::Timer_w)
-{
- uint32_t *regs = TimerRegsPtr(Which);
-
- uint32_t old = regs[0];
- data = COMBINE_DATA(&regs[0]);
- if ((data ^ old) & 1)
- {
- if (data & 1)
- {
- TimerStart(Which);
- }
- else
- {
- // Timer stop
- m_Timer[Which]->adjust(attotime::never);
-// printf("timer %d stop\n", Which);
- }
- }
-}
-
-template<int Which>
-READ32_MEMBER(crystal_state::Timer_r)
-{
- return *TimerRegsPtr(Which);
-}
-
-template<int Which>
-READ32_MEMBER(crystal_state::DMA_r)
-{
- return m_DMActrl[Which];
-}
-
-template<int Which>
-WRITE32_MEMBER(crystal_state::DMA_w)
-{
- if (((data ^ m_DMActrl[Which]) & (1 << 10)) && (data & (1 << 10))) //DMAOn
- {
- uint32_t const CTR = data;
- uint32_t const SRC = space.read_dword(0x01800804 + Which * 0x10);
- uint32_t const DST = space.read_dword(0x01800808 + Which * 0x10);
- uint32_t const CNT = space.read_dword(0x0180080C + Which * 0x10);
-
- if (CTR & 0x2) //32 bits
- {
- for (int i = 0; i < CNT; ++i)
- {
- uint32_t v = space.read_dword(SRC + i * 4);
- space.write_dword(DST + i * 4, v);
- }
- }
- else if (CTR & 0x1) //16 bits
- {
- for (int i = 0; i < CNT; ++i)
- {
- uint16_t v = space.read_word(SRC + i * 2);
- space.write_word(DST + i * 2, v);
- }
- }
- else //8 bits
- {
- for (int i = 0; i < CNT; ++i)
- {
- uint8_t v = space.read_byte(SRC + i);
- space.write_byte(DST + i, v);
- }
- }
- data &= ~(1 << 10);
- space.write_dword(0x0180080C + Which * 0x10, 0);
- IntReq(7 + Which);
- }
- COMBINE_DATA(&m_DMActrl[Which]);
-}
-
-READ32_MEMBER(crystal_state::crtc_r)
-{
- uint32_t res = m_crtcregs[offset];
- uint32_t hdisp = (m_crtcregs[0x0c / 4] + 1);
- uint32_t vdisp = (m_crtcregs[0x1c / 4] + 1);
- switch (offset)
- {
- case 0: // CRTC Status / Mode
- if ((m_crtcregs[0x30 / 4] & 1) == 0) // Interlace
- vdisp <<= 1;
-
- if (m_screen->vpos() <= vdisp) // Vertical display enable status
- res |= 0x4000;
-
- if (m_screen->hpos() > hdisp) // horizontal & vertical blank period
- res &= ~0x2000;
- else
- res |= 0x2000;
-
- break;
- default:
- break;
- }
- return res;
-}
-
-WRITE32_MEMBER(crystal_state::crtc_w)
-{
- if (((m_crtcregs[0] & 0x0100) == 0x0100) && (offset > 0)) // Write protect
- return;
-
- uint32_t old = m_crtcregs[offset];
- switch (offset * 4)
- {
- case 0: // CRTC Status / Mode Register (CRTMOD)
- mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
- break;
- case 0x04: // CRTC Timing Control Register (CRTTIM)
- mem_mask &= ~0xffffc000; // Bit 31-14 Reserved
- break;
- case 0x08: // Horizontal Sync Width / Back Porch Register (HSWBP)
- mem_mask &= ~0xffff0000; // Bit 31-16 Reserved
- break;
- case 0x0c: // Horizontal Display Total Register (HDISP)
- mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
- break;
- case 0x10: // Horizontal Sync Front Porch Register (HSFP)
- mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
- break;
- case 0x14: // Field Window Bound Register (FWINB)
- mem_mask &= ~0xffff80c0; // Bit 31-15, 7-6 Reserved
- break;
- case 0x18: // Vertical Sync Back Porch Register (VSBP)
- mem_mask &= ~0xffffff00; // Bit 31-8 Reserved
- break;
- case 0x1c: // Vertical Display Total Register (VDISP)
- mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
- break;
- case 0x20: // Horizontal Total Register (HTOT)
- mem_mask &= ~0xffffe000; // Bit 31-13 Reserved
- break;
- case 0x24: // Vertical Total Register (VTOT)
- mem_mask &= ~0xfffff000; // Bit 31-12 Reserved
- break;
- case 0x28: // Horizontal Line Back Porch Register (HLBP)
- mem_mask &= ~0xfffffc00; // Bit 31-10 Reserved
- break;
- case 0x2c: // CRT Display Start Address 0 Register (STAD0)
- mem_mask &= ~0xffff8000; // Bit 31-15 Reserved
- break;
- case 0x30: // CRT Display Start Address 1 Register (STAD1)
- mem_mask &= ~0xffff8000; // Bit 31-15 Reserved
- break;
- case 0x38: // Light Pen 0 X Register (LIGHT0X)
- mem_mask &= ~0xfffff800; // Bit 31-11 Reserved
- break;
- case 0x3c: // Light Pen 0 Y Register (LIGHT0Y)
- mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
- break;
- case 0x40: // Light Pen 1 X Register (LIGHT1X)
- mem_mask &= ~0xfffff800; // Bit 31-11 Reserved
- break;
- case 0x44: // Light Pen 1 Y Register (LIGHT1Y)
- mem_mask &= ~0xfffffe00; // Bit 31-9 Reserved
- break;
- case 0x48: // Light Pen Input Control Register (LIGHTC)
- mem_mask &= ~0xfffffffc; // Bit 31-2 Reserved
- break;
- default:
- return;
- }
- COMBINE_DATA(&m_crtcregs[offset]);
- if (((offset == (0xc / 4)) || (offset == (0x1c / 4)) || (offset == (0x30 / 4))) && (old ^ m_crtcregs[offset]))
- crtc_update();
-
-}
-
-void crystal_state::crtc_update()
+#ifdef IDLE_LOOP_SPEEDUP
+WRITE_LINE_MEMBER(crystal_state::idle_skip_resume_w)
{
- // TODO : Implement other CRTC parameters
- uint32_t hdisp = m_crtcregs[0x0c / 4] + 1;
- uint32_t vdisp = m_crtcregs[0x1c / 4] + 1;
- if ((m_crtcregs[0x30 / 4] & 1) == 0) // Interlace
- vdisp <<= 1;
-
- rectangle const visarea(0, hdisp - 1, 0, vdisp - 1);
- m_screen->configure(hdisp, vdisp, visarea, m_screen->frame_period().attoseconds());
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
}
-void crystal_state::internal_map(address_map &map)
+WRITE_LINE_MEMBER(crystal_state::idle_skip_speedup_w)
{
-// map(0x00000000, 0x00ffffff) // Local ROM
-// map(0x01000000, 0x010fffff) // Peripheral Device 0
-// map(0x01100000, 0x011fffff) // Peripheral Device 1
-// map(0x01200000, 0x012fffff) // Peripheral Device 2
-// map(0x01300000, 0x013fffff) // Peripheral Device 3
-// map(0x01400000, 0x014fffff) // Peripheral Device 4
-// map(0x01500000, 0x015fffff) // Peripheral Device 5
-// map(0x01600000, 0x016fffff) // Peripheral Device 6
-// map(0x01700000, 0x017fffff) // Peripheral Device 7
-// map(0x01800000, 0x01ffffff) // Internal Registers(VRender0, or Amazon)
-
- map(0x01800000, 0x0180ffff).ram().share("sysregs");
-// map(0x01800000, 0x018003ff) // System/General
-// map(0x01800400, 0x018007ff) // Local Memory Controller
-// map(0x01800800, 0x01800bff) // DMA
- map(0x01800800, 0x01800803).rw(FUNC(crystal_state::DMA_r<0>), FUNC(crystal_state::DMA_w<0>));
- map(0x01800810, 0x01800813).rw(FUNC(crystal_state::DMA_r<1>), FUNC(crystal_state::DMA_w<1>));
-// map(0x01800c00, 0x01800fff) // Interrupt Controller
- map(0x01800c04, 0x01800c07).w(FUNC(crystal_state::IntAck_w));
-// map(0x01801000, 0x018013ff) // UART
-// map(0x01801400, 0x018017ff) // Timer & Counter
- map(0x01801400, 0x01801403).rw(FUNC(crystal_state::Timer_r<0>), FUNC(crystal_state::Timer_w<0>));
- map(0x01801408, 0x0180140b).rw(FUNC(crystal_state::Timer_r<1>), FUNC(crystal_state::Timer_w<1>));
- map(0x01801410, 0x01801413).rw(FUNC(crystal_state::Timer_r<2>), FUNC(crystal_state::Timer_w<2>));
- map(0x01801418, 0x0180141b).rw(FUNC(crystal_state::Timer_r<3>), FUNC(crystal_state::Timer_w<3>));
-// map(0x01801800, 0x01801bff) // Pulse Width Modulation
-// map(0x01802000, 0x018023ff) // PIO (Port)
-// map(0x01802004, 0x01802007).rw(FUNC(crystal_state::PIO_r), FUNC(crystal_state::PIO_w)); // PIOLDAT
-// map(0x01802008, 0x0180200b) // PIOEDAT
-// map(0x01802400, 0x018027ff) // Peripheral Chip Select
-// map(0x01802800, 0x01802bff) // SIO
-// map(0x01803400, 0x018037ff) // CRT Controller
- map(0x01803400, 0x018037ff).rw(FUNC(crystal_state::crtc_r), FUNC(crystal_state::crtc_w));
-// map(0x01804000, 0x018043ff) // RAMDAC & PLL
-
-// map(0x02000000, 0x02ffffff).ram().share("workram"); // Local RAM/DRAM (Max.16MB)
-
- map(0x03000000, 0x0300ffff).ram().share("vidregs");
- map(0x030000a4, 0x030000a7).rw(FUNC(crystal_state::FlipCount_r), FUNC(crystal_state::FlipCount_w));
-// map(0x03800000, 0x03ffffff).ram().share("textureram"); // Texture Buffer Memory (Max.8MB)
-// map(0x04000000, 0x047fffff).ram().share("frameram"); // Frame Buffer Memory (Max.8MB)
- map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
-
-// map(0x05000000, 0x0fffffff) // Expansion ROM
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
}
+#endif
-
-READ32_MEMBER(crystal_state::Input_r)
+READ32_MEMBER(crystal_state::system_input_r)
{
- if (offset == 0)
- return ioport("P1_P2")->read();
- else if (offset == 1)
- return ioport("P3_P4")->read();
- else if( offset == 2)
- {
- uint8_t Port4 = ioport("SYSTEM")->read();
- if (!(Port4 & 0x10) && ((m_OldPort4 ^ Port4) & 0x10)) //coin buttons trigger IRQs
- IntReq(12);
- if (!(Port4 & 0x20) && ((m_OldPort4 ^ Port4) & 0x20))
- IntReq(19);
- m_OldPort4 = Port4;
- return /*dips*/ioport("DSW")->read() | (Port4 << 16);
- }
- return 0;
+ return ( ioport("SYSTEM")->read() << 16) | (ioport("DSW")->read()) | 0xff00ff00;
}
WRITE32_MEMBER(crystal_state::Banksw_w)
@@ -715,12 +274,13 @@ WRITE32_MEMBER(crystal_state::Banksw_w)
m_mainbank->set_entry(m_Bank);
}
-READ32_MEMBER(crystal_state::PIO_r)
+READ32_MEMBER(crystal_state::PIOldat_r)
{
return m_PIO;
}
-WRITE32_MEMBER(crystal_state::PIO_w)
+// PIO Latched output DATa Register
+WRITE32_MEMBER(crystal_state::PIOldat_w)
{
uint32_t RST = data & 0x01000000;
uint32_t CLK = data & 0x02000000;
@@ -730,14 +290,15 @@ WRITE32_MEMBER(crystal_state::PIO_w)
m_ds1302->io_w(DAT ? 1 : 0);
m_ds1302->sclk_w(CLK ? 1 : 0);
- if (m_ds1302->io_r())
- space.write_dword(0x01802008, space.read_dword(0x01802008) | 0x10000000);
- else
- space.write_dword(0x01802008, space.read_dword(0x01802008) & (~0x10000000));
-
COMBINE_DATA(&m_PIO);
}
+// PIO External DATa Register
+READ32_MEMBER(crystal_state::PIOedat_r)
+{
+ return m_ds1302->io_r() << 28;
+}
+
READ32_MEMBER(crystal_state::FlashCmd_r)
{
if ((m_FlashCmd & 0xff) == 0xff)
@@ -765,156 +326,46 @@ WRITE32_MEMBER(crystal_state::FlashCmd_w)
m_FlashCmd = data;
}
-void crystal_state::crystal_mem(address_map &map)
+WRITE32_MEMBER(crystal_state::coin_counters_w)
{
- internal_map(map);
- map(0x00000000, 0x0001ffff).rom().nopw();
-
- map(0x01200000, 0x0120000f).r(FUNC(crystal_state::Input_r));
- map(0x01280000, 0x01280003).w(FUNC(crystal_state::Banksw_w));
- map(0x01400000, 0x0140ffff).ram().share("nvram");
-
- map(0x01802004, 0x01802007).rw(FUNC(crystal_state::PIO_r), FUNC(crystal_state::PIO_w));
-
- map(0x02000000, 0x027fffff).ram().share("workram");
-
- map(0x03800000, 0x03ffffff).ram().share("textureram");
- map(0x04000000, 0x047fffff).ram().share("frameram");
-
- map(0x05000000, 0x05ffffff).bankr("mainbank");
- map(0x05000000, 0x05000003).rw(FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
-
- map(0x44414F4C, 0x44414F7F).ram().share("reset_patch");
-}
-
-// Trivia R Us
-// To do: touch panel, RTC
-
-READ8_MEMBER(crystal_state::trivrus_input_r)
-{
- switch (m_trivrus_input)
- {
- case 1: return ioport("IN1")->read();
- case 2: return ioport("IN2")->read();
- case 3: return ioport("IN3")->read();
- case 4: return ioport("IN4")->read();
- case 5: return ioport("IN5")->read();
- case 6: return ioport("DSW")->read();
- }
- logerror("%s: unknown input %02x read\n", machine().describe_context(), m_trivrus_input);
- return 0xff;
-}
-
-WRITE8_MEMBER(crystal_state::trivrus_input_w)
-{
- m_trivrus_input = data & 0xff;
-}
-
-void crystal_state::trivrus_mem(address_map &map)
-{
- internal_map(map);
- map(0x00000000, 0x0007ffff).rom().nopw();
-
-// 0x01280000 & 0x0000ffff (written at boot)
- map(0x01500000, 0x01500000).rw(FUNC(crystal_state::trivrus_input_r), FUNC(crystal_state::trivrus_input_w));
-// 0x01500010 & 0x000000ff = sec
-// 0x01500010 & 0x00ff0000 = min
-// 0x01500014 & 0x000000ff = hour
-// 0x01500014 & 0x00ff0000 = day
-// 0x01500018 & 0x000000ff = month
-// 0x0150001c & 0x000000ff = year - 2000
- map(0x01600000, 0x01607fff).ram().share("nvram");
-
- map(0x01802004, 0x01802007).rw(FUNC(crystal_state::PIO_r), FUNC(crystal_state::PIO_w));
-
- map(0x02000000, 0x027fffff).ram().share("workram");
-
- map(0x03800000, 0x03ffffff).ram().share("textureram");
- map(0x04000000, 0x047fffff).ram().share("frameram");
-
- map(0x05000000, 0x05ffffff).bankr("mainbank");
- map(0x05000000, 0x05000003).rw(FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
-
-// AM_RANGE(0x44414F4C, 0x44414F7F) AM_RAM AM_SHARE("reset_patch")
-}
-
-void crystal_state::crospuzl_mem(address_map &map)
-{
- trivrus_mem(map);
-
- map(0x01500000, 0x01500003).r(FUNC(crystal_state::FlashCmd_r));
- map(0x01500100, 0x01500103).w(FUNC(crystal_state::FlashCmd_w));
- map(0x01510000, 0x01510003).portr("IN0");
- map(0x01511000, 0x01511003).portr("IN1");
- map(0x01512000, 0x01512003).portr("IN2");
- map(0x01513000, 0x01513003).portr("IN3");
-}
-
-// Crazy Dou Di Zhu II
-// To do: HY04 (pic?) protection
-
-WRITE32_MEMBER(crystal_state::crzyddz2_PIO_w)
-{
- COMBINE_DATA(&m_PIO);
-
- if (ACCESSING_BITS_8_15)
+ if (ACCESSING_BITS_0_7)
{
- int mux = (m_PIO >> 8) & 0x1f;
- if (mux == 0x1f)
- {
- m_crzyddz2_prot = ((m_PIO >> 8) & 0xc0) ^ 0x40;
- logerror("%s: PIO = %08x, prot = %02x\n", machine().describe_context(), m_PIO, m_crzyddz2_prot);
- }
+ // Both signals are sent when setting is "1 shooter"
+ // Only evosocc and crysking allow the user to change this setting.
+ machine().bookkeeping().coin_counter_w(0, data & 1);
+ machine().bookkeeping().coin_counter_w(1, data & 2);
}
}
-READ32_MEMBER(crystal_state::crzyddz2_key_r)
+void crystal_state::crystal_mem(address_map &map)
{
- static const char *const key_names[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4" };
-
- int mux = (m_PIO >> 8) & 0x1f;
-
- uint8_t data = 0x3f;
- for (int i = 0; i < sizeof(key_names)/sizeof(key_names[0]); ++i)
- if (!BIT(mux,i))
- data = ioport(key_names[i])->read();
-
-/*
-crzyddz2 in out
- 00 40
- 40 00
- c0 80
-*/
-// m_crzyddz2_prot = (m_PIO >> 8) & 0xc0) ^ 0x40;
- m_crzyddz2_prot = (machine().rand() & 0xc0);
-
- return 0xffffff00 | data | m_crzyddz2_prot;
-}
+ map(0x00000000, 0x0001ffff).rom().nopw();
-void crystal_state::crzyddz2_mem(address_map &map)
-{
- internal_map(map);
- map(0x00000000, 0x00ffffff).rom().nopw();
+ map(0x01200000, 0x01200003).portr("P1_P2").w(FUNC(crystal_state::coin_counters_w));
+ map(0x01200004, 0x01200007).portr("P3_P4");
+ map(0x01200008, 0x0120000b).r(FUNC(crystal_state::system_input_r));
map(0x01280000, 0x01280003).w(FUNC(crystal_state::Banksw_w));
map(0x01400000, 0x0140ffff).ram().share("nvram");
- map(0x01500000, 0x01500003).portr("P1_P2");
- map(0x01500004, 0x01500007).r(FUNC(crystal_state::crzyddz2_key_r));
- map(0x01802004, 0x01802007).rw(FUNC(crystal_state::PIO_r), FUNC(crystal_state::crzyddz2_PIO_w));
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+ map(0x01802004, 0x01802007).rw(FUNC(crystal_state::PIOldat_r), FUNC(crystal_state::PIOldat_w));
+ map(0x01802008, 0x0180200b).r(FUNC(crystal_state::PIOedat_r));
- map(0x02000000, 0x027fffff).ram().share("workram");
+ // mirror is accessed by donghaer on later levels
+ map(0x02000000, 0x027fffff).mirror(0x00800000).ram().share("workram");
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
map(0x03800000, 0x03ffffff).ram().share("textureram");
map(0x04000000, 0x047fffff).ram().share("frameram");
-
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+
map(0x05000000, 0x05ffffff).bankr("mainbank");
map(0x05000000, 0x05000003).rw(FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
-// AM_RANGE(0x44414F4C, 0x44414F7F) AM_RAM AM_SHARE("reset_patch")
+ map(0x44414F4C, 0x44414F7F).ram().share("reset_patch");
}
-
void crystal_state::PatchReset( )
{
if (!m_reset_patch)
@@ -969,8 +420,8 @@ loop:
void crystal_state::machine_start()
{
- for (int i = 0; i < 4; i++)
- m_Timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(crystal_state::Timercb),this), (void*)(uintptr_t)i);
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
PatchReset();
@@ -992,162 +443,31 @@ void crystal_state::machine_start()
#ifdef IDLE_LOOP_SPEEDUP
save_item(NAME(m_FlipCntRead));
#endif
-
- save_item(NAME(m_Bank));
- save_item(NAME(m_FlipCount));
- save_item(NAME(m_IntHigh));
- save_item(NAME(m_FlashCmd));
- save_item(NAME(m_PIO));
- save_item(NAME(m_DMActrl));
- save_item(NAME(m_OldPort4));
- save_item(NAME(m_trivrus_input));
}
void crystal_state::machine_reset()
{
- std::fill_n(&m_sysregs[0], m_sysregs.bytes() / 4, 0);
- std::fill_n(&m_vidregs[0], m_vidregs.bytes() / 4, 0);
- m_crtcregs = &m_sysregs[0x3400/4];
- m_crtcregs[1] = 0x00000022;
-
- m_FlipCount = 0;
- m_IntHigh = 0;
m_Bank = 0;
m_mainbank->set_entry(m_Bank);
m_FlashCmd = 0xff;
- m_OldPort4 = 0;
- m_DMActrl[0] = 0;
- m_DMActrl[1] = 0;
-
- for (int i = 0; i < 4; i++)
- {
- *TimerRegsPtr(i) = 0xff << 8;
- m_Timer[i]->adjust(attotime::never);
- }
-
- m_vr0snd->set_areas(m_textureram, m_frameram);
#ifdef IDLE_LOOP_SPEEDUP
m_FlipCntRead = 0;
#endif
PatchReset();
-
- m_crzyddz2_prot = 0x00;
-}
-
-uint16_t crystal_state::GetVidReg( address_space &space, uint16_t reg )
-{
- return space.read_word(0x03000000 + reg);
-}
-
-void crystal_state::SetVidReg( address_space &space, uint16_t reg, uint16_t val )
-{
- space.write_word(0x03000000 + reg, val);
-}
-
-
-uint32_t crystal_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- if ((m_crtcregs[0] & 0x0200) == 0x0200) // Blank Screen
- {
- bitmap.fill(0, cliprect);
- return 0;
- }
-
- address_space &space = m_maincpu->space(AS_PROGRAM);
- int DoFlip;
-
- uint32_t B0 = 0x0;
- uint32_t B1 = (GetVidReg(space, 0x90) & 0x8000) ? 0x400000 : 0x100000;
- uint16_t *Front, *Back;
- uint16_t *Visible, *DrawDest;
- uint16_t *srcline;
- uint16_t head, tail;
- uint32_t width = cliprect.width();
-
- if (GetVidReg(space, 0x8e) & 1)
- {
- Front = (uint16_t*) (m_frameram + B1 / 4);
- Back = (uint16_t*) (m_frameram + B0 / 4);
- }
- else
- {
- Front = (uint16_t*) (m_frameram + B0 / 4);
- Back = (uint16_t*) (m_frameram + B1 / 4);
- }
-
- Visible = (uint16_t*) Front;
- // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros!
- DrawDest = reinterpret_cast<uint16_t *>(m_frameram.target());
-
-
- if (GetVidReg(space, 0x8c) & 0x80)
- DrawDest = Front;
- else
- DrawDest = Back;
-
-// DrawDest = Visible;
-
- srcline = (uint16_t *) DrawDest;
-
- DoFlip = 0;
- head = GetVidReg(space, 0x82);
- tail = GetVidReg(space, 0x80);
- while ((head & 0x7ff) != (tail & 0x7ff))
- {
- // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros!
- DoFlip = m_vr0vid->vrender0_ProcessPacket(0x03800000 + head * 64, DrawDest, reinterpret_cast<uint8_t*>(m_textureram.target()));
- head++;
- head &= 0x7ff;
- if (DoFlip)
- break;
- }
-
- if (DoFlip)
- SetVidReg(space, 0x8e, GetVidReg(space, 0x8e) ^ 1);
-
- srcline = (uint16_t *) Visible;
- uint32_t const dx = cliprect.left();
- for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
- std::copy_n(&srcline[(y * 1024) + dx], width, &bitmap.pix16(y, dx));
-
- return 0;
}
-WRITE_LINE_MEMBER(crystal_state::screen_vblank)
+INPUT_CHANGED_MEMBER(crystal_state::coin_inserted)
{
- // rising edge
- if (state)
+ if (oldval)
{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint16_t head, tail;
- int DoFlip = 0;
-
- head = GetVidReg(space, 0x82);
- tail = GetVidReg(space, 0x80);
- while ((head & 0x7ff) != (tail & 0x7ff))
- {
- uint16_t Packet0 = space.read_word(0x03800000 + head * 64);
- if (Packet0 & 0x81)
- DoFlip = 1;
- head++;
- head &= 0x7ff;
- if (DoFlip)
- break;
- }
- SetVidReg(space, 0x82, head);
- if (DoFlip)
- {
- if (m_FlipCount)
- m_FlipCount--;
-
- }
- IntReq(24); //VRender0 VBlank
+ uint8_t coin_chute = (uint8_t)(uintptr_t)param & 1;
+ m_vr0soc->IntReq(coin_chute ? 19 : 12);
}
}
-static INPUT_PORTS_START(crystal)
+static INPUT_PORTS_START( crystal )
PORT_START("P1_P2")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
@@ -1195,8 +515,8 @@ static INPUT_PORTS_START(crystal)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START3 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START4 )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, crystal_state, coin_inserted, 0)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, crystal_state, coin_inserted, 1)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_SERVICE_NO_TOGGLE( 0x80, IP_ACTIVE_LOW )
@@ -1227,319 +547,60 @@ static INPUT_PORTS_START(crystal)
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
+static INPUT_PORTS_START( topbladv )
+ PORT_INCLUDE( crystal )
+ PORT_MODIFY("P1_P2")
+ PORT_BIT( 0x000000f0, IP_ACTIVE_LOW, IPT_UNUSED )
-static INPUT_PORTS_START(officeye)
- PORT_START("P1_P2")
- PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Red") // RED
+ PORT_MODIFY("P3_P4")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ // TODO: coin 2 insertion is fuzzy, may be BTANB
+ PORT_MODIFY("SYSTEM")
+ PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1) PORT_CHANGED_MEMBER(DEVICE_SELF, crystal_state, coin_inserted, 0)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(1) PORT_CHANGED_MEMBER(DEVICE_SELF, crystal_state, coin_inserted, 1)
+ PORT_SERVICE_NO_TOGGLE( 0x40, IP_ACTIVE_LOW )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( urachamu )
+ PORT_INCLUDE( crystal )
+
+ // TODO: player 2 start doesn't work ingame, it only skip attract mode items,
+ // or be valid in test mode when prompted to press start
+ // lamps test also gives only p1 and p3, and after crediting up only p1 and p3 starts are lighted on ($01320000 address writes)
+ // I guess game is currently in 2 players mode, is there anything that enables 3 players mode?
+ // notice that this is valid for both urachamu and officeye
+ PORT_MODIFY("P1_P2")
+ PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Red")
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Green") // GREEN
+ PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Green")
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Blue") // BLUE
+ PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Blue")
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_UNKNOWN )
- //PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_START2 ) // where is start2?
- PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Red") // RED
+ PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Red")
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Red")
- PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Green") // GREEN
+ PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Green")
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 Green")
- PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Blue") // BLUE
+ PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Blue")
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Blue")
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_START3 )
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_START("P3_P4")
- PORT_BIT( 0x000000ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x00ff0000, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("SYSTEM")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE1 )
- PORT_SERVICE_NO_TOGGLE( 0x80, IP_ACTIVE_LOW )
+ PORT_MODIFY("P3_P4")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_START("DSW")
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Pause ) )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Test ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_MODIFY("SYSTEM")
+ PORT_BIT( 0x0000000f, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
-
-static INPUT_PORTS_START(trivrus)
- PORT_START("IN1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Left/True") PORT_CODE(KEYCODE_LEFT)
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
-
- PORT_START("IN2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Enter/Exit")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Next")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Right/False") PORT_CODE(KEYCODE_RIGHT)
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN3")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Sound")
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN4")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_OTHER )PORT_CODE(KEYCODE_9)
-
- PORT_START("IN5")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) // Free Game
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_SERVICE_NO_TOGGLE( 0x08, IP_ACTIVE_LOW ) // Setup
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("DSW")
- PORT_DIPNAME( 0x01, 0x01, "Interlace?" )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, "Serial?" )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // hangs at boot
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, "Touch Screen" )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START(crospuzl)
- PORT_START("IN0")
- PORT_DIPNAME( 0x01, 0x01, "DSW1" )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN1")
- PORT_DIPNAME( 0x01, 0x01, "IN1" )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN2")
- PORT_DIPNAME( 0x01, 0x01, "IN2" )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN3")
- PORT_DIPNAME( 0x01, 0x01, "IN3" )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("PCB-SW1")
- PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START(crzyddz2)
- PORT_START("P1_P2") // 1500002 & 1500000
- PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // up
- PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // down (next secret code)
- PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // left (inc secret code)
- PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // right (dec secret code)
- PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) // A
- PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) // B
- PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) // C (bet)
- PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) // D
- PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_START1 ) // start (secret code screen)
- PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // .. 2 (next secret code / stats)
- PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE ) // .. 1 (secret code screen / service mode)
- PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // .. 3 (inc secret code / credit)
- PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE3 ) // .. 4 (exit secret screen / clear credits)
- PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_SERVICE4 ) // (reset and clear ram?)
- PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- // 1500004 (multiplexed by 1802005)
- PORT_START("KEY0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_A )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_E )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_I )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_M )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) // kan
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) // start?
-
- PORT_START("KEY1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_B )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_F )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_J )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_N )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) // ?
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) // ? + C
-
- PORT_START("KEY2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_C )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_G )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_K )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) // chi
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) // ?
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
-
- PORT_START("KEY3")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_D )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_H )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_L )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) // pon
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
-
- PORT_START("KEY4")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) // ron
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) // ?
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) // big
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) // small + D
-INPUT_PORTS_END
-
-
void crystal_state::crystal(machine_config &config)
{
SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
@@ -1549,15 +610,21 @@ void crystal_state::crystal(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
- m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
- m_screen->set_size(640, 480);
- m_screen->set_visarea(0, 639, 0, 479);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
m_screen->set_screen_update(FUNC(crystal_state::screen_update));
m_screen->screen_vblank().set(FUNC(crystal_state::screen_vblank));
m_screen->set_palette("palette");
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(crystal_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(crystal_state::idle_skip_speedup_w));
+ #endif
PALETTE(config, "palette", palette_device::RGB_565);
@@ -1572,24 +639,6 @@ void crystal_state::crystal(machine_config &config)
}
-void crystal_state::trivrus(machine_config &config)
-{
- crystal(config);
- m_maincpu->set_addrmap(AS_PROGRAM, &crystal_state::trivrus_mem);
-}
-
-void crystal_state::crospuzl(machine_config &config)
-{
- crystal(config);
- m_maincpu->set_addrmap(AS_PROGRAM, &crystal_state::crospuzl_mem);
-}
-
-void crystal_state::crzyddz2(machine_config &config)
-{
- crystal(config);
- m_maincpu->set_addrmap(AS_PROGRAM, &crystal_state::crzyddz2_mem);
-}
-
#define CRYSBIOS \
ROM_REGION( 0x20000, "maincpu", 0 ) \
ROM_SYSTEM_BIOS( 0, "amg0110b", "AMG0110B PCB" ) \
@@ -1654,161 +703,53 @@ ROM_START( donghaer )
ROM_LOAD( "u2", 0x1000000, 0x1000000, CRC(6d82f1a5) SHA1(036bd45f0daac1ffeaa5ad9774fc1b56e3c75ff9) )
ROM_END
-ROM_START( trivrus )
- ROM_REGION( 0x80000, "maincpu", 0 )
- ROM_LOAD( "u4", 0x00000, 0x80000, CRC(2d2e9a11) SHA1(73e7b19a032eae21312ca80f8c42cc16725496a7) )
-
- ROM_REGION32_LE( 0x2000000, "flash", ROMREGION_ERASEFF ) // Flash
- ROM_LOAD( "u3", 0x000000, 0x1000010, CRC(ba901707) SHA1(e281ba07024cd19ef1ab72d2197014f7b1f4d30f) )
+#ifdef ROGUE_CARTS
+ROM_START( wulybuly )
+ CRYSBIOS
+
+ ROM_REGION( 0x4280, "pic", ROMREGION_ERASEFF ) // empty socket
+
+ ROM_REGION32_LE( 0x1000000, "flash", 0 ) // Flash
+ ROM_LOAD( "u1", 0x0000000, 0x1000000, CRC(7406f5db) SHA1(dd53afb08d0567241d08d2422c672d429ef9b78f) )
ROM_END
-ROM_START( crospuzl ) /* This PCB uses ADC 'Amazon-LF' SoC, EISC CPU core - However PCBs have been see with a standard VRenderZERO+ MagicEyes EISC chip */
- ROM_REGION( 0x80010, "maincpu", 0 )
- ROM_LOAD("en29lv040a.u5", 0x000000, 0x80010, CRC(d50e8500) SHA1(d681cd18cd0e48854c24291d417d2d6d28fe35c1) )
-
- ROM_REGION32_LE( 0x8400010, "flash", ROMREGION_ERASEFF ) // NAND Flash
- // mostly empty, but still looks good
- ROM_LOAD("k9f1g08u0a.riser", 0x000000, 0x8400010, CRC(7f3c88c3) SHA1(db3169a7b4caab754e9d911998a2ece13c65ce5b) )
+ROM_START( urachamu )
+ CRYSBIOS
+
+ ROM_REGION( 0x4280, "pic", ROMREGION_ERASEFF ) // empty socket
+
+ ROM_REGION32_LE( 0x4000000, "flash", 0 ) // Flash
+ ROM_LOAD( "u1", 0x0000000, 0x1000000, CRC(f341d6fc) SHA1(23ecd9f3e5e20fc2a293cc735c8c4d60d01b68c0) )
+ ROM_LOAD( "u2", 0x1000000, 0x1000000, CRC(ad81d61f) SHA1(5872c1d96e25d1b2a1b8a35c8ff163d67cfdabe4) )
+ ROM_LOAD( "u3", 0x2000000, 0x1000000, CRC(3c7e32a4) SHA1(8a26e745eccc00a2c622062c8ad027781dfc1969) )
+ ROM_LOAD( "u4", 0x3000000, 0x1000000, CRC(c5505627) SHA1(5229f435b4cf218d50ae4a4ae65a6ae13d7b7080) )
+
+ // without this game defaults in free play mode, with no demo sound and 0 lives count.
+ ROM_REGION( 0x10000, "nvram", 0 )
+ ROM_LOAD( "nvram", 0x00000, 0x10000, CRC(66df826d) SHA1(09260b76cb17082c841e7e37b89cb076e54ffb8d) )
ROM_END
-ROM_START( psattack )
- ROM_REGION( 0x200000, "maincpu", 0 )
- ROM_LOAD("5.sys", 0x000000, 0x200000, CRC(f09878e4) SHA1(25b8dbac47d3911615c8874746e420ece13e7181) )
-
- ROM_REGION( 0x4010, "pic16c711", 0 )
- ROM_LOAD("16c711.pic", 0x0000, 0x137b, CRC(617d8292) SHA1(d32d6054ce9db2e31efaf41015afcc78ed32f6aa) ) // raw dump
- ROM_LOAD("16c711.bin", 0x0000, 0x4010, CRC(b316693f) SHA1(eba1f75043bd415268eedfdb95c475e73c14ff86) ) // converted to binary
-
- DISK_REGION( "cfcard" )
- DISK_IMAGE_READONLY( "psattack", 0, SHA1(e99cd0dafc33ec13bf56061f81dc7c0a181594ee) )
-ROM_END
+ROM_START( maldaiza )
+ CRYSBIOS
+
+ ROM_REGION( 0x4280, "pic", ROMREGION_ERASEFF )
+ ROM_LOAD("maldaliza_pic16f84a.bin", 0x000000, 0x4280, NO_DUMP )
-ROM_START( ddz )
- ROM_REGION( 0xc00000, "maincpu", 0 )
- ROM_LOAD("ddz.001.rom", 0x000000, 0x400000, CRC(b379f823) SHA1(531885b35d668d22c75a9759994f4aca6eacb046) )
- ROM_LOAD("ddz.002.rom", 0x400000, 0x400000, CRC(285c744d) SHA1(2f8bc70825e55e3114015cb263e786df35cde275) )
- ROM_LOAD("ddz.003.rom", 0x800000, 0x400000, CRC(61c9b5c9) SHA1(0438417398403456a1c49408881797a94aa86f49) )
+ ROM_REGION32_LE( 0x4000000, "flash", 0 ) // Flash
+ ROM_LOAD( "u1", 0x0000000, 0x1000000, CRC(f484d12b) SHA1(29641cda9138b5bf02c2ece34f8289385fd2ba29) )
+ ROM_LOAD( "u2", 0x1000000, 0x1000000, CRC(86175ebf) SHA1(c1800f7339dafd3ec6c0302eebc8406582a46b04) ) // $ff filled
ROM_END
+#endif
+/* note on PIC protection from ElSemi (for actually emulating it instead of patching)
-/*
-招级疯斗 - "Zhaoji Fengdou" - "Crazy Class"
-
-Haze's notes:
-
-fwiw, it's probably same PCB as the non-working 'ddz' in MAME, but different game.
-
-there's some kind of encryption/scrambling going on, at the very least
-
-Code:
-
-
-Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
-
-0007BE60 00 00 00 99 03 AD AF 00 00 00 82 00 03 AD 64 63 ™ ­¯ ‚ ­dc
-0007BE70 62 61 39 38 37 36 35 34 33 32 31 30 00 4E 61 4E ba9876543210 NaN
-0007BE80 00 66 6E 49 02 0E 85 06 02 0E 84 04 02 0E 83 EA fnI … „ ƒê
-0007BE90 02 0E 83 D6 02 0E 83 C8 02 0E 84 58 02 0E 84 12 ƒÖ ƒÈ „X „
-0007BEA0 66 65 28 00 30 00 65 73 61 62 20 64 61 62 20 3A fe( 0 esab dab :
-0007BEB0 66 74 6E 69 72 70 66 76 20 6E 69 20 67 75 62 00 ftnirpfv ni gub
-0007BEC0 46 45 44 43 42 41 39 38 37 36 35 34 33 32 31 30 FEDCBA9876543210
-0007BED0 00 29 6C 6C 75 6E 2E 00 00 00 8F 8E 02 0E 89 DC )llun. Ž ‰Ü
-
-
-if you reverse the letters you get 'bug in vfprintf : bad base'
+The PIC uses a software UART bit banged on a single output pin of the main CPU:
+the data port is bit 0x20000000 on the PIO register, the same register where the EEPROM control lines are. The serial data is transmitted at 8 data bits, even parity, 1 stop bit. It's probably
+tricky to get it working properly because it doesn't rely on a clock signal, and so, the pic and main cpu must run in parallel, and the bit lengths must match. The pic bit delay routine is just a loop.
+also it seems that bit 0x40000000 is the PIC reset.
-so I suspect the data is in reverse order and maybe some blocks scrambled about.
*/
-
-ROM_START( crzclass ) // PCB marked MAH-JONG
- ROM_REGION( 0xc00000, "maincpu", 0 )
- ROM_LOAD("tjf-mahjong-rom1.bin", 0x000000, 0x400000, CRC(0a8af816) SHA1(9f292e847873078ed2b7584f463633cf9086c7e8) ) // SHARP LH28F320BJD-TTL80
- ROM_LOAD("tjf-mahjong-rom2.bin", 0x400000, 0x400000, CRC(2a04e84a) SHA1(189b16fd4314fd2a5f8a1214618b5db83f8ac59a) ) // SHARP LH28F320BJD-TTL80
- ROM_LOAD("tjf-mahjong-rom3.bin", 0x800000, 0x400000, CRC(1cacf3f9) SHA1(e6c88c98aeb7df4098f8e20f412018617005724d) ) // SHARP LH28F320BJD-TTL80
- // rom4 not populated
-ROM_END
-
-/***************************************************************************
-
-Crazy Dou Di Zhu II
-Sealy, 2006
-
-PCB Layout
-----------
-
-070405-fd-VER1.2
-|--------------------------------------|
-| PAL 27C322.U36 |
-| BATTERY|
-| M59PW1282 62256 14.31818MHz |
-| W9864G66 |
-| |
-|J VRENDERZERO+ |
-|A W9864G66 |
-|M W9864G66 |
-|M 8MHz |
-|A HY04 0260F8A |
-| 28.63636MHz |
-| |
-| VR1 TLDA1311 |
-| TDA1519|
-| 18WAY VOL 10WAY |
-|--------------------------------------|
-Notes:
- 0260F8A - unknown TQFP44
- HY04 - rebadged DIP8 PIC - type unknown *
- W9864G66 - Winbond 64MBit DRAM
- M59PW1282 - ST Microelectronics 128MBit SOP44 FlashROM.
- This is two 64MB SOP44 ROMs in one package
-
-* The pins are:
- 1 ground
- 2 nothing
- 3 data (only active for 1/4 second when the playing cards or "PASS" shows in game next to each player)
- 4 nothing
- 5 nothing
- 6 clock
- 7 +5V (could be VPP for programming voltage)
- 8 +5V
-
-***************************************************************************/
-
-ROM_START( crzyddz2 )
- ROM_REGION32_LE( 0x1000000, "flash", 0 ) // Flash
- ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(0f3a1987) SHA1(6cad943846c79db31226676c7391f32216cfff79) )
-
- ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASEFF )
- ROM_COPY( "flash", 0x000000, 0x000000, 0x1000000 ) // copy flash here
- ROM_LOAD( "27c322.u49", 0x000000, 0x0200000, CRC(b3177f39) SHA1(2a28bf8045bd2e053d88549b79fbc11f30ef9a32) ) // 1ST AND 2ND HALF IDENTICAL
- ROM_CONTINUE( 0x000000, 0x0200000 )
-
- ROM_REGION( 0x4280, "pic", 0 ) // hy04
- ROM_LOAD("hy04", 0x000000, 0x4280, NO_DUMP )
-ROM_END
-
-/***************************************************************************
-
-Meng Hong Lou (Dream of the Red Chamber)
-Sealy, 2004?
-
-Red PCB, very similar to crzyddz2
-
-***************************************************************************/
-
-ROM_START( menghong )
- ROM_REGION32_LE( 0x1000000, "flash", 0 ) // Flash
- ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(e24257c4) SHA1(569d79a61ff6d35100ba5727069363146df9e0b7) )
-
- ROM_REGION( 0x1000000, "maincpu", 0 )
- ROM_COPY( "flash", 0x000000, 0x000000, 0x1000000 ) // copy flash here
- ROM_LOAD( "060511_08-01-18.u49", 0x000000, 0x0200000, CRC(b0c12107) SHA1(b1753757bbdb7d996df563ac6abdc6b46676704b) ) // 27C160
-
- ROM_REGION( 0x4280, "pic", 0 ) // hy04
- ROM_LOAD("menghong_hy04", 0x000000, 0x4280, NO_DUMP )
-ROM_END
-
-
void crystal_state::init_crysking()
{
uint16_t *Rom = (uint16_t*) memregion("flash")->base();
@@ -1846,15 +787,6 @@ void crystal_state::init_evosocc()
Rom[WORD_XOR_LE(0x974ED2/2)] = 0x9001; //PUSH R0
}
-/* note on PIC protection from ElSemi (for actually emulating it instead of patching)
-
-The PIC uses a software UART bit banged on a single output pin of the main CPU:
-the data port is bit 0x20000000 on the PIO register, the same register where the EEPROM control lines are. The serial data is transmitted at 8 data bits, even parity, 1 stop bit. It's probably
-tricky to get it working properly because it doesn't rely on a clock signal, and so, the pic and main cpu must run in parallel, and the bit lengths must match. The pic bit delay routine is just a loop.
-also it seems that bit 0x40000000 is the PIC reset.
-
-*/
-
void crystal_state::init_topbladv()
{
// patches based on analysis of PIC dump
@@ -1926,23 +858,22 @@ void crystal_state::init_donghaer()
Rom[WORD_XOR_LE(0x19C72 / 2)] = 0x9001; // PUSH %R0
}
-void crystal_state::init_psattack()
+#ifdef ROGUE_CARTS
+void crystal_state::init_maldaiza()
{
+ //uint16_t *Rom = (uint16_t*)memregion("flash")->base();
+ // ...
}
+#endif
-
-GAME( 2001, crysbios, 0, crystal, crystal, crystal_state, empty_init, ROT0, "BrezzaSoft", "Crystal System BIOS", MACHINE_IS_BIOS_ROOT )
-GAME( 2001, crysking, crysbios, crystal, crystal, crystal_state, init_crysking, ROT0, "BrezzaSoft", "The Crystal of Kings", 0 )
-GAME( 2001, evosocc, crysbios, crystal, crystal, crystal_state, init_evosocc, ROT0, "Evoga", "Evolution Soccer", 0 )
-GAME( 2003, topbladv, crysbios, crystal, crystal, crystal_state, init_topbladv, ROT0, "SonoKong / Expotato", "Top Blade V", 0 )
-GAME( 2001, officeye, 0, crystal, officeye, crystal_state, init_officeye, ROT0, "Danbi", "Office Yeo In Cheon Ha (version 1.2)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // still has some instability issues
-GAME( 2001, donghaer, crysbios, crystal, crystal, crystal_state, init_donghaer, ROT0, "Danbi", "Donggul Donggul Haerong", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
-GAME( 2004?,menghong, 0, crzyddz2, crzyddz2, crystal_state, empty_init, ROT0, "Sealy", "Meng Hong Lou", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
-GAME( 2006, crzyddz2, 0, crzyddz2, crzyddz2, crystal_state, empty_init, ROT0, "Sealy", "Crazy Dou Di Zhu II", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
-GAME( 2009, trivrus, 0, trivrus, trivrus, crystal_state, empty_init, ROT0, "AGT", "Trivia R Us (v1.07)", 0 )
-GAME( 200?, crospuzl, 0, crospuzl, crospuzl, crystal_state, empty_init, ROT0, "<unknown>", "Cross Puzzle", MACHINE_NOT_WORKING )
-
-GAME( 2004, psattack, 0, crystal, crystal, crystal_state, init_psattack, ROT0, "Uniana", "P's Attack", MACHINE_IS_SKELETON ) // has a CF card instead of flash roms
-// looks like the same kind of hw from strings in the ROM, but scrambled / encrypted?
-GAME( 200?, ddz, 0, crystal, crystal, crystal_state, empty_init, ROT0, "IGS?", "Dou Di Zhu", MACHINE_IS_SKELETON )
-GAME( 200?, crzclass, 0, crystal, crystal, crystal_state, empty_init, ROT0, "TJF", "Zhaoji Fengdou", MACHINE_IS_SKELETON ) // 'Crazy Class'
+GAME( 2001, crysbios, 0, crystal, crystal, crystal_state, empty_init, ROT0, "BrezzaSoft", "Crystal System BIOS", MACHINE_IS_BIOS_ROOT )
+GAME( 2001, crysking, crysbios, crystal, crystal, crystal_state, init_crysking, ROT0, "BrezzaSoft", "The Crystal of Kings", 0 )
+GAME( 2001, evosocc, crysbios, crystal, crystal, crystal_state, init_evosocc, ROT0, "Evoga", "Evolution Soccer", 0 )
+GAME( 2001, officeye, 0, crystal, urachamu, crystal_state, init_officeye, ROT0, "Danbi", "Office Yeo In Cheon Ha (version 1.2)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // still has some instability issues
+GAME( 2001, donghaer, crysbios, crystal, crystal, crystal_state, init_donghaer, ROT0, "Danbi", "Donggul Donggul Haerong", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // 2 players mode has GFX issues
+GAME( 2003, topbladv, crysbios, crystal, topbladv, crystal_state, init_topbladv, ROT0, "SonoKong / Expotato", "Top Blade V", 0 )
+#ifdef ROGUE_CARTS
+GAME( 2002, urachamu, crysbios, crystal, urachamu, crystal_state, empty_init, ROT0, "GamToU", "Urachacha Mudaeri (Korea)", MACHINE_NOT_WORKING ) // lamps, not extensively tested
+GAME( 200?, wulybuly, crysbios, crystal, crystal, crystal_state, empty_init, ROT0, "<unknown>", "Wully Bully", MACHINE_NOT_WORKING ) // no actual graphics except offset text, confirmed to have no PIC protection so failing elsewhere
+GAME( 200?, maldaiza, crysbios, crystal, crystal, crystal_state, init_maldaiza, ROT0, "<unknown>", "Maldaliza", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // PIC hookup
+#endif
diff --git a/src/mame/drivers/ddz.cpp b/src/mame/drivers/ddz.cpp
new file mode 100644
index 00000000000..65ad5c5299a
--- /dev/null
+++ b/src/mame/drivers/ddz.cpp
@@ -0,0 +1,265 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/****************************************************************************
+
+ 招级疯斗 - "Zhaoji Fengdou" - "Crazy Class" HW
+
+ driver by Angelo Salese, based off original ddz.cpp by ElSemi
+
+ TODO:
+ - Decryption;
+
+=============================================================================
+
+Haze's notes:
+
+fwiw, it's probably same PCB as the non-working 'ddz' in MAME, but different game.
+
+there's some kind of encryption/scrambling going on, at the very least
+
+Code:
+
+
+Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
+
+0007BE60 00 00 00 99 03 AD AF 00 00 00 82 00 03 AD 64 63 ™ ­¯ ‚ ­dc
+0007BE70 62 61 39 38 37 36 35 34 33 32 31 30 00 4E 61 4E ba9876543210 NaN
+0007BE80 00 66 6E 49 02 0E 85 06 02 0E 84 04 02 0E 83 EA fnI … „ ƒê
+0007BE90 02 0E 83 D6 02 0E 83 C8 02 0E 84 58 02 0E 84 12 ƒÖ ƒÈ „X „
+0007BEA0 66 65 28 00 30 00 65 73 61 62 20 64 61 62 20 3A fe( 0 esab dab :
+0007BEB0 66 74 6E 69 72 70 66 76 20 6E 69 20 67 75 62 00 ftnirpfv ni gub
+0007BEC0 46 45 44 43 42 41 39 38 37 36 35 34 33 32 31 30 FEDCBA9876543210
+0007BED0 00 29 6C 6C 75 6E 2E 00 00 00 8F 8E 02 0E 89 DC )llun. Ž ‰Ü
+
+
+if you reverse the letters you get 'bug in vfprintf : bad base'
+
+so I suspect the data is in reverse order and maybe some blocks scrambled about.
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/se3208/se3208.h"
+#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
+#include "sound/vrender0.h"
+#include "video/vrender0.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+
+#include <algorithm>
+
+#define IDLE_LOOP_SPEEDUP
+
+class ddz_state : public driver_device
+{
+public:
+ ddz_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_workram(*this, "workram"),
+ m_textureram(*this, "textureram"),
+ m_frameram(*this, "frameram"),
+ m_ipl(*this, "ipl"),
+ m_encdata(*this, "enc_data"),
+ m_maincpu(*this, "maincpu"),
+ m_vr0soc(*this, "vr0soc"),
+ m_vr0vid(*this, "vr0vid"),
+ m_vr0snd(*this, "vr0snd"),
+ m_screen(*this, "screen")
+ { }
+
+
+ void init_ddz();
+ void ddz(machine_config &config);
+
+private:
+
+ /* memory pointers */
+ required_shared_ptr<uint32_t> m_workram;
+ required_shared_ptr<uint32_t> m_textureram;
+ required_shared_ptr<uint32_t> m_frameram;
+ required_region_ptr<uint8_t> m_ipl;
+ required_region_ptr<uint8_t> m_encdata;
+
+ /* devices */
+ required_device<se3208_device> m_maincpu;
+ required_device<vrender0soc_device> m_vr0soc;
+ required_device<vr0video_device> m_vr0vid;
+ required_device<vr0sound_device> m_vr0snd;
+ required_device<screen_device> m_screen;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
+#endif
+
+ IRQ_CALLBACK_MEMBER(icallback);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void ddz_mem(address_map &map);
+};
+
+uint32_t ddz_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
+ {
+ bitmap.fill(0, cliprect);
+ return 0;
+ }
+
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
+}
+
+WRITE_LINE_MEMBER(ddz_state::screen_vblank)
+{
+ // rising edge
+ if (state)
+ {
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
+
+ m_vr0vid->execute_drawing();
+ }
+}
+
+IRQ_CALLBACK_MEMBER(ddz_state::icallback)
+{
+ return m_vr0soc->irq_callback();
+}
+
+#ifdef IDLE_LOOP_SPEEDUP
+WRITE_LINE_MEMBER(ddz_state::idle_skip_resume_w)
+{
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
+}
+
+WRITE_LINE_MEMBER(ddz_state::idle_skip_speedup_w)
+{
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
+}
+#endif
+
+
+void ddz_state::ddz_mem(address_map &map)
+{
+ map(0x00000000, 0x00ffffff).rom().nopw().region("ipl", 0);
+
+// map(0x01500000, 0x01500003).portr("IN0");
+// map(0x01500004, 0x01500007).portr("IN1");
+// map(0x01500008, 0x0150000b).portr("IN2");
+
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+
+ map(0x02000000, 0x027fffff).ram().share("workram");
+
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
+ map(0x03800000, 0x03ffffff).ram().share("textureram");
+ map(0x04000000, 0x047fffff).ram().share("frameram");
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+}
+
+static INPUT_PORTS_START( ddz )
+ PORT_START("IN0")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN1")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN2")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+INPUT_PORTS_END
+
+void ddz_state::machine_start()
+{
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
+
+#ifdef IDLE_LOOP_SPEEDUP
+ save_item(NAME(m_FlipCntRead));
+#endif
+}
+
+void ddz_state::machine_reset()
+{
+#ifdef IDLE_LOOP_SPEEDUP
+ m_FlipCntRead = 0;
+#endif
+}
+
+void ddz_state::ddz(machine_config &config)
+{
+ SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
+ m_maincpu->set_addrmap(AS_PROGRAM, &ddz_state::ddz_mem);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(ddz_state::icallback));
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
+ m_screen->set_screen_update(FUNC(ddz_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(ddz_state::screen_vblank));
+ m_screen->set_palette("palette");
+
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
+ VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(ddz_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(ddz_state::idle_skip_speedup_w));
+ #endif
+
+ PALETTE(config, "palette", palette_device::RGB_565);
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ SOUND_VRENDER0(config, m_vr0snd, 0);
+ m_vr0snd->add_route(0, "lspeaker", 1.0);
+ m_vr0snd->add_route(1, "rspeaker", 1.0);
+}
+
+ROM_START( ddz )
+ ROM_REGION( 0x1000000, "ipl", ROMREGION_ERASEFF )
+
+ ROM_REGION( 0x1000000, "enc_data", ROMREGION_ERASEFF )
+ ROM_LOAD("ddz.001.rom", 0x000000, 0x400000, CRC(b379f823) SHA1(531885b35d668d22c75a9759994f4aca6eacb046) )
+ ROM_LOAD("ddz.002.rom", 0x400000, 0x400000, CRC(285c744d) SHA1(2f8bc70825e55e3114015cb263e786df35cde275) )
+ ROM_LOAD("ddz.003.rom", 0x800000, 0x400000, CRC(61c9b5c9) SHA1(0438417398403456a1c49408881797a94aa86f49) )
+ROM_END
+
+
+ROM_START( crzclass ) // PCB marked MAH-JONG
+ ROM_REGION( 0x1000000, "ipl", ROMREGION_ERASEFF )
+
+ ROM_REGION( 0x1000000, "enc_data", ROMREGION_ERASEFF )
+ ROM_LOAD("tjf-mahjong-rom1.bin", 0x000000, 0x400000, CRC(0a8af816) SHA1(9f292e847873078ed2b7584f463633cf9086c7e8) ) // SHARP LH28F320BJD-TTL80
+ ROM_LOAD("tjf-mahjong-rom2.bin", 0x400000, 0x400000, CRC(2a04e84a) SHA1(189b16fd4314fd2a5f8a1214618b5db83f8ac59a) ) // SHARP LH28F320BJD-TTL80
+ ROM_LOAD("tjf-mahjong-rom3.bin", 0x800000, 0x400000, CRC(1cacf3f9) SHA1(e6c88c98aeb7df4098f8e20f412018617005724d) ) // SHARP LH28F320BJD-TTL80
+ // rom4 not populated
+ROM_END
+
+void ddz_state::init_ddz()
+{
+ for(uint32_t x=0;x<m_encdata.bytes();x+=16)
+ {
+ // TBD
+ for(int y=0;y<16;y++)
+ m_ipl[x+(y)] = m_encdata[x+y];
+// m_ipl[x+(15-y)] = m_encdata[x+y];
+ }
+}
+
+GAME( 200?, ddz, 0, ddz, ddz, ddz_state, init_ddz, ROT0, "IGS?", "Dou Di Zhu", MACHINE_IS_SKELETON )
+GAME( 200?, crzclass, 0, ddz, ddz, ddz_state, init_ddz, ROT0, "TJF", "Zhaoji Fengdou", MACHINE_IS_SKELETON ) // 'Crazy Class'
+
diff --git a/src/mame/drivers/menghong.cpp b/src/mame/drivers/menghong.cpp
new file mode 100644
index 00000000000..20c061740fc
--- /dev/null
+++ b/src/mame/drivers/menghong.cpp
@@ -0,0 +1,493 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/****************************************************************************
+
+ Sealy HW running on VRender0+ SoC
+
+ driver by Angelo Salese, based off original crystal.cpp by ElSemi
+
+ TODO:
+ - HY04 protection (controls tile RNG at very least)
+ - 8bpp colors are washed, data from flash ROMs is XORed with contents
+ of NVRAM area 0x14000700-80f, might be shared with HY04 as well.
+ - EEPROM hookup;
+ - extract password code when entering test mode in-game;
+
+=============================================================================
+
+Crazy Dou Di Zhu II
+Sealy, 2006
+
+PCB Layout
+----------
+
+070405-fd-VER1.2
+|--------------------------------------|
+| PAL 27C322.U36 |
+| BATTERY|
+| M59PW1282 62256 14.31818MHz |
+| W9864G66 |
+| |
+|J VRENDERZERO+ |
+|A W9864G66 |
+|M W9864G66 |
+|M 8MHz |
+|A HY04 0260F8A |
+| 28.63636MHz |
+| |
+| VR1 TLDA1311 |
+| TDA1519|
+| 18WAY VOL 10WAY |
+|--------------------------------------|
+Notes:
+ 0260F8A - unknown TQFP44
+ HY04 - rebadged DIP8 PIC - type unknown *
+ W9864G66 - Winbond 64MBit DRAM
+ M59PW1282 - ST Microelectronics 128MBit SOP44 FlashROM.
+ This is two 64MB SOP44 ROMs in one package
+
+* The pins are:
+ 1 ground
+ 2 nothing
+ 3 data (only active for 1/4 second when the playing cards or "PASS" shows in game next to each player)
+ 4 nothing
+ 5 nothing
+ 6 clock
+ 7 +5V (could be VPP for programming voltage)
+ 8 +5V
+
+=====
+
+Meng Hong Lou (Dream of the Red Chamber)
+Sealy, 2004?
+
+Red PCB, very similar to crzyddz2
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/se3208/se3208.h"
+#include "machine/ds1302.h"
+#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
+#include "sound/vrender0.h"
+#include "video/vrender0.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+
+#include <algorithm>
+
+#define IDLE_LOOP_SPEEDUP
+
+class menghong_state : public driver_device
+{
+public:
+ menghong_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_workram(*this, "workram"),
+ m_textureram(*this, "textureram"),
+ m_frameram(*this, "frameram"),
+ m_flash(*this, "flash"),
+ m_mainbank(*this, "mainbank"),
+ m_maincpu(*this, "maincpu"),
+ m_vr0soc(*this, "vr0soc"),
+ m_vr0vid(*this, "vr0vid"),
+ m_vr0snd(*this, "vr0snd"),
+ m_ds1302(*this, "rtc"),
+ m_screen(*this, "screen"),
+ m_eeprom(*this, "eeprom")
+ { }
+
+
+ void crzyddz2(machine_config &config);
+
+private:
+ /* memory pointers */
+ required_shared_ptr<uint32_t> m_workram;
+ required_shared_ptr<uint32_t> m_textureram;
+ required_shared_ptr<uint32_t> m_frameram;
+ optional_region_ptr<uint32_t> m_flash;
+ optional_memory_bank m_mainbank;
+
+ /* devices */
+ required_device<se3208_device> m_maincpu;
+ required_device<vrender0soc_device> m_vr0soc;
+ required_device<vr0video_device> m_vr0vid;
+ required_device<vr0sound_device> m_vr0snd;
+ required_device<ds1302_device> m_ds1302;
+ required_device<screen_device> m_screen;
+ optional_device<eeprom_serial_93cxx_device> m_eeprom;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
+#endif
+
+ uint32_t m_Bank;
+ uint32_t m_maxbank;
+ uint32_t m_FlashCmd;
+
+ DECLARE_WRITE32_MEMBER(Banksw_w);
+ DECLARE_READ32_MEMBER(FlashCmd_r);
+ DECLARE_WRITE32_MEMBER(FlashCmd_w);
+
+ DECLARE_READ32_MEMBER(crzyddz2_key_r);
+
+ IRQ_CALLBACK_MEMBER(icallback);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void crzyddz2_mem(address_map &map);
+
+ // PIO
+ DECLARE_READ32_MEMBER(PIOldat_r);
+ DECLARE_WRITE32_MEMBER(PIOldat_w);
+ DECLARE_READ32_MEMBER(PIOedat_r);
+ uint32_t m_PIO;
+ DECLARE_WRITE32_MEMBER(crzyddz2_PIOldat_w);
+ DECLARE_READ32_MEMBER(crzyddz2_PIOedat_r);
+ uint8_t m_crzyddz2_prot;
+};
+
+
+
+uint32_t menghong_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
+ {
+ bitmap.fill(0, cliprect);
+ return 0;
+ }
+
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
+}
+
+WRITE_LINE_MEMBER(menghong_state::screen_vblank)
+{
+ // rising edge
+ if (state)
+ {
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
+
+ m_vr0vid->execute_drawing();
+ }
+}
+
+IRQ_CALLBACK_MEMBER(menghong_state::icallback)
+{
+ return m_vr0soc->irq_callback();
+}
+
+WRITE32_MEMBER(menghong_state::Banksw_w)
+{
+ m_Bank = (data >> 1) & 7;
+ m_mainbank->set_entry(m_Bank);
+}
+
+READ32_MEMBER(menghong_state::FlashCmd_r)
+{
+ if ((m_FlashCmd & 0xff) == 0xff)
+ {
+ if (m_Bank < m_maxbank)
+ {
+ uint32_t *ptr = (uint32_t*)(m_mainbank->base());
+ return ptr[0];
+ }
+ else
+ return 0xffffffff;
+ }
+ if ((m_FlashCmd & 0xff) == 0x90)
+ {
+ if (m_Bank < m_maxbank)
+ return 0x00180089; //Intel 128MBit
+ else
+ return 0xffffffff;
+ }
+ return 0;
+}
+
+WRITE32_MEMBER(menghong_state::FlashCmd_w)
+{
+ m_FlashCmd = data;
+}
+
+
+
+// Crazy Dou Di Zhu II
+// To do: HY04 (pic?) protection, 93C46 hookup
+
+READ32_MEMBER(menghong_state::PIOldat_r)
+{
+ return m_PIO;
+}
+
+WRITE32_MEMBER(menghong_state::crzyddz2_PIOldat_w)
+{
+ COMBINE_DATA(&m_PIO);
+ //uint32_t RST = data & 0x01000000;
+ //uint32_t CLK = data & 0x02000000;
+ //uint32_t DAT = data & 0x10000000;
+
+// m_eeprom->cs_write(RST ? 1 : 0);
+// m_eeprom->di_write(DAT ? 1 : 0);
+// m_eeprom->clk_write(CLK ? 1 : 0);
+
+ if (ACCESSING_BITS_8_15)
+ {
+ int mux = (m_PIO >> 8) & 0x1f;
+ if (mux == 0x1f)
+ {
+ m_crzyddz2_prot = ((m_PIO >> 8) & 0xc0) ^ 0x40;
+ logerror("%s: PIO = %08x, prot = %02x\n", machine().describe_context(), m_PIO, m_crzyddz2_prot);
+ }
+ }
+}
+
+READ32_MEMBER(menghong_state::crzyddz2_PIOedat_r)
+{
+ return 0;//m_eeprom->do_read();
+}
+
+READ32_MEMBER(menghong_state::crzyddz2_key_r)
+{
+ static const char *const key_names[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4" };
+
+ int mux = (m_PIO >> 8) & 0x1f;
+
+ uint8_t data = 0x3f;
+ for (int i = 0; i < sizeof(key_names)/sizeof(key_names[0]); ++i)
+ if (!BIT(mux,i))
+ data = ioport(key_names[i])->read();
+
+/*
+crzyddz2 in out
+ 00 40
+ 40 00
+ c0 80
+*/
+// menghong Sealy logo pal offset is at 0x3ea7400, relevant code is at 2086034
+// m_crzyddz2_prot = (m_PIO >> 8) & 0xc0) ^ 0x40;
+ m_crzyddz2_prot = (machine().rand() & 0xc0);
+
+ return 0xffffff00 | data | m_crzyddz2_prot;
+}
+
+void menghong_state::crzyddz2_mem(address_map &map)
+{
+ map(0x00000000, 0x003fffff).rom().nopw();
+
+ map(0x01280000, 0x01280003).w(FUNC(menghong_state::Banksw_w));
+ map(0x01400000, 0x0140ffff).ram().share("nvram");
+ map(0x01500000, 0x01500003).portr("P1_P2");
+ map(0x01500004, 0x01500007).r(FUNC(menghong_state::crzyddz2_key_r));
+
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+ map(0x01802004, 0x01802007).rw(FUNC(menghong_state::PIOldat_r), FUNC(menghong_state::crzyddz2_PIOldat_w));
+ map(0x01802008, 0x0180200b).r(FUNC(menghong_state::crzyddz2_PIOedat_r));
+
+ map(0x02000000, 0x027fffff).ram().share("workram");
+
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
+ map(0x03800000, 0x03ffffff).ram().share("textureram");
+ map(0x04000000, 0x047fffff).ram().share("frameram");
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+
+ map(0x05000000, 0x05ffffff).bankr("mainbank");
+ map(0x05000000, 0x05000003).rw(FUNC(menghong_state::FlashCmd_r), FUNC(menghong_state::FlashCmd_w));
+}
+
+#ifdef IDLE_LOOP_SPEEDUP
+
+WRITE_LINE_MEMBER(menghong_state::idle_skip_resume_w)
+{
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
+}
+
+WRITE_LINE_MEMBER(menghong_state::idle_skip_speedup_w)
+{
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
+}
+#endif
+
+void menghong_state::machine_start()
+{
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
+
+ if (m_mainbank)
+ {
+ m_maxbank = (m_flash) ? m_flash.bytes() / 0x1000000 : 0;
+ uint8_t *dummy_region = auto_alloc_array(machine(), uint8_t, 0x1000000);
+ std::fill_n(&dummy_region[0], 0x1000000, 0xff); // 0xff Filled at Unmapped area
+ uint8_t *ROM = (m_flash) ? (uint8_t *)&m_flash[0] : dummy_region;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((i < m_maxbank))
+ m_mainbank->configure_entry(i, ROM + i * 0x1000000);
+ else
+ m_mainbank->configure_entry(i, dummy_region);
+ }
+ }
+
+#ifdef IDLE_LOOP_SPEEDUP
+ save_item(NAME(m_FlipCntRead));
+
+#endif
+
+ save_item(NAME(m_Bank));
+ save_item(NAME(m_FlashCmd));
+ save_item(NAME(m_PIO));
+}
+
+void menghong_state::machine_reset()
+{
+ m_Bank = 0;
+ m_mainbank->set_entry(m_Bank);
+ m_FlashCmd = 0xff;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ m_FlipCntRead = 0;
+#endif
+
+ m_crzyddz2_prot = 0x00;
+}
+
+static INPUT_PORTS_START(crzyddz2)
+ PORT_START("P1_P2") // 1500002 & 1500000
+ PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // up
+ PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // down (next secret code)
+ PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // left (inc secret code)
+ PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // right (dec secret code)
+ PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) // A
+ PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) // B
+ PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) // C (bet)
+ PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) // D
+ PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_START1 ) // start (secret code screen)
+ PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // .. 2 (next secret code / stats)
+ PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE ) // .. 1 (secret code screen / service mode)
+ PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // .. 3 (inc secret code / credit)
+ PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE3 ) // .. 4 (exit secret screen / clear credits)
+ PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_SERVICE4 ) // (reset and clear ram?)
+ PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ // 1500004 (multiplexed by 1802005)
+ PORT_START("KEY0")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_A )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_E )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_I )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_M )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) // kan
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) // start?
+
+ PORT_START("KEY1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_B )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_F )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_J )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_N )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) // ?
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) // ? + C
+
+ PORT_START("KEY2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_C )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_G )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_K )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) // chi
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) // ?
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
+
+ PORT_START("KEY3")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_D )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_H )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_L )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) // pon
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
+
+ PORT_START("KEY4")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) // ron
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) // ?
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) // big
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) // small + D
+INPUT_PORTS_END
+
+void menghong_state::crzyddz2(machine_config &config)
+{
+ SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
+ m_maincpu->set_addrmap(AS_PROGRAM, &menghong_state::crzyddz2_mem);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(menghong_state::icallback));
+
+ NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
+ m_screen->set_screen_update(FUNC(menghong_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(menghong_state::screen_vblank));
+ m_screen->set_palette("palette");
+
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
+ VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(menghong_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(menghong_state::idle_skip_speedup_w));
+ #endif
+
+ PALETTE(config, "palette", palette_device::RGB_565);
+
+ DS1302(config, m_ds1302, 32.768_kHz_XTAL);
+ EEPROM_93C46_16BIT(config, "eeprom");
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ SOUND_VRENDER0(config, m_vr0snd, 0);
+ m_vr0snd->add_route(0, "lspeaker", 1.0);
+ m_vr0snd->add_route(1, "rspeaker", 1.0);
+}
+
+ROM_START( crzyddz2 )
+ ROM_REGION32_LE( 0x1000000, "flash", 0 ) // Flash
+ ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(0f3a1987) SHA1(6cad943846c79db31226676c7391f32216cfff79) )
+
+ ROM_REGION( 0x0400000, "maincpu", ROMREGION_ERASEFF )
+ //ROM_COPY( "flash", 0x000000, 0x000000, 0x1000000 ) // copy flash here
+ ROM_LOAD( "27c322.u49", 0x000000, 0x0400000, CRC(b3177f39) SHA1(2a28bf8045bd2e053d88549b79fbc11f30ef9a32) ) // 1ST AND 2ND HALF IDENTICAL
+
+ ROM_REGION( 0x4280, "pic", 0 ) // hy04
+ ROM_LOAD("hy04", 0x000000, 0x4280, NO_DUMP )
+ROM_END
+
+ROM_START( menghong )
+ ROM_REGION32_LE( 0x1000000, "flash", 0 ) // Flash
+ ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(e24257c4) SHA1(569d79a61ff6d35100ba5727069363146df9e0b7) )
+
+ ROM_REGION( 0x0400000, "maincpu", 0 )
+ //ROM_COPY( "flash", 0x000000, 0x000000, 0x1000000 ) // copy flash here
+ ROM_LOAD( "060511_08-01-18.u49", 0x0000000, 0x0200000, CRC(b0c12107) SHA1(b1753757bbdb7d996df563ac6abdc6b46676704b) ) // 27C160
+ ROM_RELOAD( 0x0200000, 0x0200000 )
+
+ ROM_REGION( 0x4280, "pic", 0 ) // hy04
+ ROM_LOAD("menghong_hy04", 0x000000, 0x4280, NO_DUMP )
+ROM_END
+
+GAME( 2004?,menghong, 0, crzyddz2, crzyddz2, menghong_state, empty_init, ROT0, "Sealy", "Meng Hong Lou", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
+GAME( 2006, crzyddz2, 0, crzyddz2, crzyddz2, menghong_state, empty_init, ROT0, "Sealy", "Crazy Dou Di Zhu II", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
diff --git a/src/mame/drivers/nexus3d.cpp b/src/mame/drivers/nexus3d.cpp
index 14d04558fd8..8462eb5f2f2 100644
--- a/src/mame/drivers/nexus3d.cpp
+++ b/src/mame/drivers/nexus3d.cpp
@@ -19,6 +19,7 @@
#include "machine/serflash.h"
#include "emupal.h"
#include "screen.h"
+#include "debugger.h"
//#include "machine/i2cmem.h"
@@ -29,97 +30,285 @@ class nexus3d_state : public driver_device
public:
nexus3d_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
- m_mainram(*this, "mainram"),
m_maincpu(*this, "maincpu"),
- m_serflash(*this, "flash")
+ m_mainram(*this, "mainram"),
+ m_fbram(*this, "fbram"),
+ m_serflash(*this, "flash"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette")
{ }
void nexus3d(machine_config &config);
- void init_nexus3d();
+ void init_acheart();
+ void init_acheartf();
private:
- required_shared_ptr<uint32_t> m_mainram;
required_device<cpu_device> m_maincpu;
+ required_shared_ptr<uint32_t> m_mainram;
+ required_shared_ptr<uint32_t> m_fbram;
required_device<serflash_device> m_serflash;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
- DECLARE_READ32_MEMBER(nexus3d_unk_r);
// DECLARE_READ32_MEMBER(nexus3d_unk2_r);
// DECLARE_READ32_MEMBER(nexus3d_unk3_r);
// DECLARE_WRITE32_MEMBER(nexus3d_unk2_w);
// DECLARE_WRITE32_MEMBER(nexus3d_unk3_w);
+ virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
- uint32_t screen_update_nexus3d(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
void nexus3d_map(address_map &map);
+
+ uint32_t m_intpend, m_intmask, m_intlevel;
+ DECLARE_READ32_MEMBER(int_pending_r);
+ DECLARE_WRITE32_MEMBER(int_ack_w);
+ DECLARE_READ32_MEMBER(int_level_r);
+ DECLARE_READ32_MEMBER(int_mask_r);
+ DECLARE_WRITE32_MEMBER(int_mask_w);
+ void IntReq(int level);
+
+ DECLARE_READ32_MEMBER(vrender3d_status_r);
+ DECLARE_WRITE32_MEMBER(rop_data_w);
+ DECLARE_WRITE16_MEMBER(rop_register_w);
+ DECLARE_READ16_MEMBER(rop_status_r);
+
+ DECLARE_READ32_MEMBER(timer_status_r);
+ DECLARE_WRITE32_MEMBER(timer_status_w);
+ DECLARE_READ32_MEMBER(timer_count_r);
+ DECLARE_WRITE32_MEMBER(timer_count_w);
+ uint32_t m_timer_status;
+ uint32_t m_timer_count;
+ emu_timer *m_timer;
+ TIMER_CALLBACK_MEMBER(timercb);
+ bool m_timer_irq;
+ bool m_timer_result;
+
+ DECLARE_READ32_MEMBER(crtc_vblank_r);
};
+void nexus3d_state::video_start()
+{
+ // ...
+}
+
+uint32_t nexus3d_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint16_t *fbram = reinterpret_cast<uint16_t *>(m_fbram.target());
+ const int width = 640;
+
+ uint16_t *visible = fbram + (m_screen->frame_number() & 1) * (0x96000/2);
+ uint32_t const dx = cliprect.left();
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
+ std::copy_n(&visible[(y * width) + dx], width, &bitmap.pix16(y, dx));
-READ32_MEMBER(nexus3d_state::nexus3d_unk_r)
+ return 0;
+}
+
+READ32_MEMBER(nexus3d_state::vrender3d_status_r)
+{
+ return (0xbf<<16) | m_screen->vpos();
+}
+
+void nexus3d_state::IntReq(int level)
{
- return machine().rand() ^ (machine().rand() << 16);
+ if (level != -1)
+ {
+ m_intlevel = level;
+ m_intpend |= 1 << level;
+ }
+ uint32_t inten = m_intmask ^ 0xffffffff;
+
+ if (m_intpend & inten)
+ m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE);
+ else
+ m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE);
}
-//READ32_MEMBER(nexus3d_state::nexus3d_unk2_r)
-//{
-// return 0x00000000;//machine().rand() ^ (machine().rand() << 16);
-//}
-//
-//READ32_MEMBER(nexus3d_state::nexus3d_unk3_r)
-//{
-// return 0x00000000;//machine().rand() ^ (machine().rand() << 16);
-//}
-//
-//WRITE32_MEMBER(nexus3d_state::nexus3d_unk2_w)
-//{
-//
-//}
-//
-//WRITE32_MEMBER(nexus3d_state::nexus3d_unk3_w)
-//{
-//
-//}
-void nexus3d_state::nexus3d_map(address_map &map)
+READ32_MEMBER(nexus3d_state::int_mask_r)
+{
+ return m_intmask;
+}
+
+WRITE32_MEMBER(nexus3d_state::int_mask_w)
{
- map(0x00000000, 0x003fffff).ram().share("mainram");
+ COMBINE_DATA(&m_intmask);
+}
+
+READ32_MEMBER(nexus3d_state::int_pending_r)
+{
+ return m_intpend;
+}
+
+WRITE32_MEMBER(nexus3d_state::int_ack_w)
+{
+ m_intpend &= ~data;
+ IntReq(-1);
+}
+
+READ32_MEMBER(nexus3d_state::int_level_r)
+{
+ return m_intlevel;
+}
- map(0x00400000, 0x01ffffff).ram(); // ?? uploads various data, + pointers to data in the 0x01ffxxxx range, might be video system related
+WRITE16_MEMBER(nexus3d_state::rop_register_w)
+{
+ //printf("%04x REG\n",data);
+}
+
+WRITE32_MEMBER(nexus3d_state::rop_data_w)
+{
+ //printf("%04x DATA\n",data);
+}
+
+READ16_MEMBER(nexus3d_state::rop_status_r)
+{
+ return machine().rand() & 0x1000;
+}
+
+READ32_MEMBER(nexus3d_state::timer_status_r)
+{
+ uint32_t res = (m_timer_status & ~0x30) | ((m_timer_irq == true) << 5) | ((m_timer_result == true) << 4);
+ return res;
+}
+
+WRITE32_MEMBER(nexus3d_state::timer_status_w)
+{
+ COMBINE_DATA(&m_timer_status);
+ //printf("%08x %08x\n",m_timer_status, m_timer_count);
+
+ if (m_timer_status & 0x20)
+ m_timer_irq = false;
+
+ if (m_timer_status & 8)
+ {
+ m_timer_result = false;
+ // TODO: unknown formula, should be counter / (bits 0-1 and maybe 2)
+ attotime period = attotime::from_hz(14318180 * 3);
+ m_timer->adjust(period);
+ }
+}
+
+READ32_MEMBER(nexus3d_state::timer_count_r)
+{
+ return m_timer_count;
+}
+
+WRITE32_MEMBER(nexus3d_state::timer_count_w)
+{
+ COMBINE_DATA(&m_timer_count);
+}
+
+TIMER_CALLBACK_MEMBER(nexus3d_state::timercb)
+{
+ m_timer_result = true;
+ m_timer_status &= ~8;
+ #if 0
+ if (m_timer_irq == false && m_timer_status & 0x10)
+ {
+ m_timer_irq = true;
+ // lv 10 (the only enabled irq at POST) should be UART
+ IntReq(?);
+ }
+ #endif
+}
+
+
+READ32_MEMBER(nexus3d_state::crtc_vblank_r)
+{
+ uint16_t res = (m_screen->vblank()<<1) | (m_screen->hblank()<<0);
+
+ return (res<<16);
+}
+
+void nexus3d_state::nexus3d_map(address_map &map)
+{
+ map(0x00000000, 0x01ffffff).ram().share("mainram");
+ map(0x02000000, 0x023fffff).ram().share("fbram"); // boundary tbd
+
+ map(0x03720000, 0x0373ffff).ram(); // 3d fifo, boundary tbd
+ map(0x046c0000, 0x046fffff).ram(); // """
+
+ map(0x60000000, 0x67ffffff).ram(); // color tables?
+
+ // actually USB hubs (prints "USB STRAGE" if 0)
+ map(0x8c000000, 0x8c000003).portr("IN0");
+ map(0x8c800000, 0x8c800003).portr("IN1");
+ map(0x8d000000, 0x8d000003).portr("IN2");
// flash
map(0x9C000000, 0x9C000003).r(m_serflash, FUNC(serflash_device::n3d_flash_r));
map(0x9C000010, 0x9C000013).w(m_serflash, FUNC(serflash_device::n3d_flash_cmd_w));
map(0x9C000018, 0x9C00001b).w(m_serflash, FUNC(serflash_device::n3d_flash_addr_w));
+ // read on irq 9 service, unknown purpose
+ map(0xc0000200, 0xc00002bf).nopr();
+
+ // on irq, acknowledge happens to both 800 and 810 ports
+ map(0xc0000800, 0xc0000803).nopw();
+ map(0xc0000808, 0xc000080b).rw(FUNC(nexus3d_state::int_mask_r), FUNC(nexus3d_state::int_mask_w));
+ map(0xc0000810, 0xc0000813).rw(FUNC(nexus3d_state::int_pending_r), FUNC(nexus3d_state::int_ack_w));
+ map(0xc0000814, 0xc0000817).r(FUNC(nexus3d_state::int_level_r));
+
// lots of accesses in this range
// 0xc00018xx seems CRTC related
// 0xc000091x loads a "gfx charset"?
-// AM_RANGE(0xC0000F44, 0xC0000F47) AM_READWRITE(nexus3d_unk2_r, nexus3d_unk2_w ) // often, status for something.
-// AM_RANGE(0xC0000F4C, 0xC0000F4f) AM_READWRITE(nexus3d_unk3_r, nexus3d_unk3_w ) // often
+ map(0xc0000910, 0xc0000913).w(FUNC(nexus3d_state::rop_data_w));
+ map(0xc000091c, 0xc000091f).w(FUNC(nexus3d_state::rop_register_w)).umask32(0xffff0000);
+
+ map(0xc0000d00, 0xc0000d03).rw(FUNC(nexus3d_state::timer_status_r), FUNC(nexus3d_state::timer_status_w));
+ map(0xc0000d04, 0xc0000d07).rw(FUNC(nexus3d_state::timer_count_r), FUNC(nexus3d_state::timer_count_w));
- map(0xE0000014, 0xE0000017).r(FUNC(nexus3d_state::nexus3d_unk_r)); // sits waiting for this
+ map(0xc0001844, 0xc0001847).r(FUNC(nexus3d_state::crtc_vblank_r));
+// map(0xc0000f40, 0xc0000f4f).ram();
+// map(0xC0000F44, 0xC0000F47) (nexus3d_unk2_r, nexus3d_unk2_w ) // often, status for something.
+ map(0xc0000f4c, 0xc0000f4f).r(FUNC(nexus3d_state::rop_status_r)).umask32(0xffff0000);
+
+ map(0xe0000014, 0xe0000017).r(FUNC(nexus3d_state::vrender3d_status_r));
+
+// map(0xe0000000, 0xe00000ff) General / Control registers
+// map(0xe0000300, 0xe00003ff) GTE constant vector registers
}
static INPUT_PORTS_START( nexus3d )
+ PORT_START("IN0")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
-INPUT_PORTS_END
+ PORT_START("IN1")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_START("IN2")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+INPUT_PORTS_END
-void nexus3d_state::video_start()
+void nexus3d_state::machine_start()
{
+ m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nexus3d_state::timercb),this), 0);
+
}
-uint32_t nexus3d_state::screen_update_nexus3d(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+void nexus3d_state::machine_reset()
{
- return 0;
+ // the first part of the flash ROM automatically gets copied to RAM
+ memcpy(m_mainram, memregion("flash")->base(), 4 * 1024);
}
-void nexus3d_state::machine_reset()
+WRITE_LINE_MEMBER(nexus3d_state::screen_vblank)
{
+ // rising edge
+ if (state)
+ {
+ // EXTINT1?
+ //IntReq(9);
+ IntReq(1);
+ }
}
void nexus3d_state::nexus3d(machine_config &config)
@@ -128,14 +317,13 @@ void nexus3d_state::nexus3d(machine_config &config)
ARM920T(config, m_maincpu, 200000000);
m_maincpu->set_addrmap(AS_PROGRAM, &nexus3d_state::nexus3d_map);
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
- screen.set_size(320, 256);
- screen.set_visarea(0, 320-1, 0, 256-1);
- screen.set_screen_update(FUNC(nexus3d_state::screen_update_nexus3d));
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_raw((XTAL(14'318'180)*2), 454*2, 0, 640, 262*2, 0, 480); // not accurate, needs CRTC understanding
+ m_screen->set_screen_update(FUNC(nexus3d_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(nexus3d_state::screen_vblank));
+ m_screen->set_palette("palette");
- PALETTE(config, "palette").set_entries(256);
+ PALETTE(config, "palette", palette_device::RGB_565);
SERFLASH(config, m_serflash, 0);
}
@@ -173,11 +361,20 @@ ROM_START( acheartf )
// ROM_LOAD( "qs1001a", 0x000000, 0x80000, CRC(d13c6407) SHA1(57b14f97c7d4f9b5d9745d3571a0b7115fbe3176) ) // missing from this set, but should be the same
ROM_END
-void nexus3d_state::init_nexus3d()
+void nexus3d_state::init_acheart()
{
- // the first part of the flash ROM automatically gets copied to RAM
- memcpy(m_mainram, memregion("flash")->base(), 4 * 1024);
+ // 0x1230 BL <vector>
+ // 0x1234 CMPS, #$0 <- if R0 = 1 then stops at 0x1244
+}
+
+void nexus3d_state::init_acheartf()
+{
+ // 0x1290 BL <vector>
+ // 0x1294 CMPS, #$0 <- if R0 = 1 then stops at 0x1244
+
+ // patch additional unknown check after $c0000a00
+ // 0x107c serial?
}
-GAME( 2005, acheart, 0, nexus3d, nexus3d, nexus3d_state, init_nexus3d, ROT0, "Examu", "Arcana Heart", MACHINE_IS_SKELETON )
-GAME( 2006, acheartf, 0, nexus3d, nexus3d, nexus3d_state, init_nexus3d, ROT0, "Examu", "Arcana Heart Full", MACHINE_IS_SKELETON )
+GAME( 2005, acheart, 0, nexus3d, nexus3d, nexus3d_state, init_acheart, ROT0, "Examu", "Arcana Heart", MACHINE_IS_SKELETON )
+GAME( 2006, acheartf, 0, nexus3d, nexus3d, nexus3d_state, init_acheartf, ROT0, "Examu", "Arcana Heart Full", MACHINE_IS_SKELETON )
diff --git a/src/mame/drivers/psattack.cpp b/src/mame/drivers/psattack.cpp
new file mode 100644
index 00000000000..751ad1b0e08
--- /dev/null
+++ b/src/mame/drivers/psattack.cpp
@@ -0,0 +1,333 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/****************************************************************************
+
+ P's Attack (c) 2004 Uniana
+
+ driver by Angelo Salese, based off original crystal.cpp by ElSemi
+
+ TODO:
+ - Compact Flash hookup;
+ - Enables wavetable IRQ;
+
+=============================================================================
+
+P's Attack (c) 2004 Uniana Co., Ltd
+
++----------54321---654321--654321---------------------------+
+|VOL TICKET GUN_1P GUN_2P +---------|
+| | |
++-+ | 256MB |
+ | CC-DAC | Compact |
++-+ EMUL* | Flash |
+| | |
+|5 +---+ +---------|
+|6 | | |
+|P | R | 25.1750MHz +--------------+|
+|I | A | | 42Pin* ||
+|N | M | +--------------+|
+| | | +--------------+|
+|C +---+ +------------+ | SYS ||
+|O | | +--------------+|
+|N +---+ | | |
+|N | | |VRenderZERO+| |
+|E SERVICE | R | | MagicEyes | +-------+ 62256* |
+|C | A | | | | RAM | |
+|T TEST | M | | | +-------+ 62256* |
+|O | | +------------+ |
+|R RESET +---+ |
+| 14.31818MHz |
++-+ |
+ | EEPROM |
++-+ GAL DSW |
+| |
+| VGA PIC BAT3.6V* |
++-----------------------------------------------------------+
+
+* denotes unpopulated device
+
+RAM are Samsung K4S641632H-TC75
+VGA is a standard PC 15 pin VGA connection
+DSW is 2 switch dipswitch (switches 3-8 are unpopulated)
+PIC is a Microchip PIC16C711-041/P (silkscreened on the PCB as COSTOM)
+SYS is a ST M27C160 EPROM (silkscreened on the PCB as SYSTEM_ROM_32M)
+GAL is a GAL16V8B (not dumped)
+EMUL is an unpopulated 8 pin connector
+EEPROM is a 93C86 16K 5.0v Serial EEPROM (2048x8-bit or 1024x16-bit)
+CC-DAC is a TDA1311A Stereo Continuous Calibration DAC
+
+
+ P's Attack non JAMMA standard 56pin Edge Connector Pinout:
+
+ 56pin Edge Connector
+ Solder Side | Parts Side
+------------------------------------------------------------------
+ GND | A | 1 | GND
+ GND | B | 2 | GND
+ +5 | C | 3 | +5
+ +5 | D | 4 | +5
+ Player 1 Start Lamp | E | 5 | Coin Lamp
+ +12 | F | 6 | +12
+------------ KEY ------------| G | 7 |------------ KEY -----------
+ Player 2 Start Lamp | H | 8 | Coin Counter
+ L Speaker (-) | J | 9 | L Speaker (+)
+ R Speaker (-) | K | 10| R Speaker (+)
+ Video Vertical Sync | L | 11|
+ Video Green | M | 12| Video Red
+ Video Sync | N | 13| Video Blue
+ Service Switch | P | 14| Video GND
+ Video Horizontal Sync | R | 15| Test Switch
+ | S | 16| Coin Switch
+ Start Player 2 | T | 17| Start Player 1
+ | U | 18|
+ | V | 19|
+ | W | 20|
+ | X | 21|
+ | Y | 22|
+ | a | 23|
+ | b | 24|
+ | d | 25|
+ | e | 26|
+ GND | f | 27| GND
+ GND | g | 28| GND
+
+
+TICKET is a 5 pin connector:
+
+ 1| LED
+ 2| GND
+ 3| OUT
+ 4| IN
+ 5| +12v
+
+GUN_xP are 6 pin gun connectors (pins 3-6 match the UNICO sytle guns):
+
+ GUN-1P: Left (Blue) Gun Connector Pinout
+
+ 1| GND
+ 2| Solenoid
+ 3| Sensor
+ 4| +5V
+ 5| Switch (Trigger)
+ 6| GND
+
+ GUN-2P: Right (Pink) Gun Connector Pinout
+
+ 1| GND
+ 2| Solenoid
+ 3| Sensor
+ 4| +5V
+ 5| Switch (Trigger)
+ 6| GND
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/se3208/se3208.h"
+#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
+#include "sound/vrender0.h"
+#include "video/vrender0.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+
+#include <algorithm>
+
+#define IDLE_LOOP_SPEEDUP
+
+class psattack_state : public driver_device
+{
+public:
+ psattack_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_workram(*this, "workram"),
+ m_textureram(*this, "textureram"),
+ m_frameram(*this, "frameram"),
+ m_maincpu(*this, "maincpu"),
+ m_vr0soc(*this, "vr0soc"),
+ m_vr0vid(*this, "vr0vid"),
+ m_vr0snd(*this, "vr0snd"),
+ m_screen(*this, "screen")
+ { }
+
+
+ void init_psattack();
+ void psattack(machine_config &config);
+
+private:
+
+ /* memory pointers */
+ required_shared_ptr<uint32_t> m_workram;
+ required_shared_ptr<uint32_t> m_textureram;
+ required_shared_ptr<uint32_t> m_frameram;
+
+ /* devices */
+ required_device<se3208_device> m_maincpu;
+ required_device<vrender0soc_device> m_vr0soc;
+ required_device<vr0video_device> m_vr0vid;
+ required_device<vr0sound_device> m_vr0snd;
+ required_device<screen_device> m_screen;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
+#endif
+
+ IRQ_CALLBACK_MEMBER(icallback);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void psattack_mem(address_map &map);
+};
+
+uint32_t psattack_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
+ {
+ bitmap.fill(0, cliprect);
+ return 0;
+ }
+
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
+}
+
+WRITE_LINE_MEMBER(psattack_state::screen_vblank)
+{
+ // rising edge
+ if (state)
+ {
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
+
+ m_vr0vid->execute_drawing();
+ }
+}
+
+IRQ_CALLBACK_MEMBER(psattack_state::icallback)
+{
+ return m_vr0soc->irq_callback();
+}
+
+#ifdef IDLE_LOOP_SPEEDUP
+WRITE_LINE_MEMBER(psattack_state::idle_skip_resume_w)
+{
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
+}
+
+WRITE_LINE_MEMBER(psattack_state::idle_skip_speedup_w)
+{
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
+}
+#endif
+
+
+void psattack_state::psattack_mem(address_map &map)
+{
+ map(0x00000000, 0x001fffff).rom().nopw();
+
+ // 0x1400c00, 0x1400c01 read cfcard memory (auto increment?)
+ // 0x1402800, 0x1402807 read/write regs?
+ // 0x1802410, 0x1802413 peripheral chip select for above
+ map(0x01500000, 0x01500003).portr("IN0");
+ map(0x01500004, 0x01500007).portr("IN1");
+ map(0x01500008, 0x0150000b).portr("IN2");
+ //0x0150000c is prolly eeprom
+
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+
+ map(0x02000000, 0x027fffff).ram().share("workram");
+
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
+ map(0x03800000, 0x03ffffff).ram().share("textureram");
+ map(0x04000000, 0x047fffff).ram().share("frameram");
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+}
+
+static INPUT_PORTS_START( psattack )
+ PORT_START("IN0")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN1")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN2")
+ PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+INPUT_PORTS_END
+
+void psattack_state::machine_start()
+{
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
+
+#ifdef IDLE_LOOP_SPEEDUP
+ save_item(NAME(m_FlipCntRead));
+#endif
+}
+
+void psattack_state::machine_reset()
+{
+#ifdef IDLE_LOOP_SPEEDUP
+ m_FlipCntRead = 0;
+#endif
+}
+
+void psattack_state::psattack(machine_config &config)
+{
+ SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
+ m_maincpu->set_addrmap(AS_PROGRAM, &psattack_state::psattack_mem);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(psattack_state::icallback));
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
+ m_screen->set_screen_update(FUNC(psattack_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(psattack_state::screen_vblank));
+ m_screen->set_palette("palette");
+
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
+ VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(psattack_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(psattack_state::idle_skip_speedup_w));
+ #endif
+
+ PALETTE(config, "palette", palette_device::RGB_565);
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ SOUND_VRENDER0(config, m_vr0snd, 0);
+ m_vr0snd->add_route(0, "lspeaker", 1.0);
+ m_vr0snd->add_route(1, "rspeaker", 1.0);
+}
+
+ROM_START( psattack )
+ ROM_REGION( 0x200000, "maincpu", 0 )
+ ROM_LOAD("5.sys", 0x000000, 0x200000, CRC(f09878e4) SHA1(25b8dbac47d3911615c8874746e420ece13e7181) )
+
+ ROM_REGION( 0x4010, "pic16c711", 0 )
+ ROM_LOAD("16c711.pic", 0x0000, 0x137b, CRC(617d8292) SHA1(d32d6054ce9db2e31efaf41015afcc78ed32f6aa) ) // raw dump
+ ROM_LOAD("16c711.bin", 0x0000, 0x4010, CRC(b316693f) SHA1(eba1f75043bd415268eedfdb95c475e73c14ff86) ) // converted to binary
+
+ DISK_REGION( "cfcard" )
+ DISK_IMAGE_READONLY( "psattack", 0, SHA1(e99cd0dafc33ec13bf56061f81dc7c0a181594ee) )
+ROM_END
+
+void psattack_state::init_psattack()
+{
+}
+
+GAME( 2004, psattack, 0, psattack, psattack, psattack_state, init_psattack, ROT0, "Uniana", "P's Attack", MACHINE_IS_SKELETON ) // has a CF card instead of flash roms
+
diff --git a/src/mame/drivers/trivrus.cpp b/src/mame/drivers/trivrus.cpp
new file mode 100644
index 00000000000..6f99eab4b14
--- /dev/null
+++ b/src/mame/drivers/trivrus.cpp
@@ -0,0 +1,417 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/****************************************************************************
+
+ Trivia R Us (c) 2009 AGT
+
+ driver by Angelo Salese, based off original crystal.cpp by ElSemi
+
+ TODO:
+ - touch panel;
+ - RTC;
+
+=============================================================================
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/se3208/se3208.h"
+#include "machine/ds1302.h"
+#include "machine/nvram.h"
+#include "machine/eepromser.h"
+#include "machine/vrender0.h"
+#include "sound/vrender0.h"
+#include "video/vrender0.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+
+#include <algorithm>
+
+#define IDLE_LOOP_SPEEDUP
+
+class trivrus_state : public driver_device
+{
+public:
+ trivrus_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_workram(*this, "workram"),
+ m_textureram(*this, "textureram"),
+ m_frameram(*this, "frameram"),
+ m_flash(*this, "flash"),
+ m_maincpu(*this, "maincpu"),
+ m_mainbank(*this, "mainbank"),
+ m_vr0soc(*this, "vr0soc"),
+ m_vr0vid(*this, "vr0vid"),
+ m_vr0snd(*this, "vr0snd"),
+ m_ds1302(*this, "rtc"),
+ m_screen(*this, "screen")
+ { }
+
+
+ void trivrus(machine_config &config);
+
+private:
+
+ /* memory pointers */
+ required_shared_ptr<uint32_t> m_workram;
+ required_shared_ptr<uint32_t> m_textureram;
+ required_shared_ptr<uint32_t> m_frameram;
+ required_region_ptr<uint32_t> m_flash;
+
+ /* devices */
+ required_device<se3208_device> m_maincpu;
+ optional_memory_bank m_mainbank;
+ required_device<vrender0soc_device> m_vr0soc;
+ required_device<vr0video_device> m_vr0vid;
+ required_device<vr0sound_device> m_vr0snd;
+ required_device<ds1302_device> m_ds1302;
+ required_device<screen_device> m_screen;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ uint8_t m_FlipCntRead;
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_resume_w);
+ DECLARE_WRITE_LINE_MEMBER(idle_skip_speedup_w);
+#endif
+
+ uint32_t m_FlashCmd;
+ uint32_t m_Bank;
+ uint32_t m_maxbank;
+
+ DECLARE_READ32_MEMBER(FlashCmd_r);
+ DECLARE_WRITE32_MEMBER(FlashCmd_w);
+ DECLARE_WRITE32_MEMBER(Banksw_w);
+
+ IRQ_CALLBACK_MEMBER(icallback);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void trivrus_mem(address_map &map);
+
+ // PIO
+ DECLARE_READ32_MEMBER(PIOldat_r);
+ uint32_t m_PIO;
+ DECLARE_WRITE32_MEMBER(PIOldat_w);
+ DECLARE_READ32_MEMBER(PIOedat_r);
+
+ DECLARE_READ8_MEMBER(trivrus_input_r);
+ DECLARE_WRITE8_MEMBER(trivrus_input_w);
+ uint8_t m_trivrus_input;
+};
+
+
+uint32_t trivrus_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_vr0soc->crt_is_blanked()) // Blank Screen
+ {
+ bitmap.fill(0, cliprect);
+ return 0;
+ }
+
+ m_vr0vid->screen_update(screen, bitmap, cliprect);
+ return 0;
+}
+
+WRITE_LINE_MEMBER(trivrus_state::screen_vblank)
+{
+ // rising edge
+ if (state)
+ {
+ if (m_vr0soc->crt_active_vblank_irq() == true)
+ m_vr0soc->IntReq(24); //VRender0 VBlank
+
+ m_vr0vid->execute_drawing();
+ }
+}
+
+IRQ_CALLBACK_MEMBER(trivrus_state::icallback)
+{
+ return m_vr0soc->irq_callback();
+}
+
+WRITE32_MEMBER(trivrus_state::FlashCmd_w)
+{
+ m_FlashCmd = data;
+}
+
+READ32_MEMBER(trivrus_state::PIOedat_r)
+{
+ return m_ds1302->io_r() << 28;
+}
+
+READ32_MEMBER(trivrus_state::PIOldat_r)
+{
+ return m_PIO;
+}
+
+// PIO Latched output DATa Register
+// TODO: change me
+WRITE32_MEMBER(trivrus_state::PIOldat_w)
+{
+ uint32_t RST = data & 0x01000000;
+ uint32_t CLK = data & 0x02000000;
+ uint32_t DAT = data & 0x10000000;
+
+ m_ds1302->ce_w(RST ? 1 : 0);
+ m_ds1302->io_w(DAT ? 1 : 0);
+ m_ds1302->sclk_w(CLK ? 1 : 0);
+
+ COMBINE_DATA(&m_PIO);
+}
+
+READ8_MEMBER(trivrus_state::trivrus_input_r)
+{
+ switch (m_trivrus_input)
+ {
+ case 1: return ioport("IN1")->read();
+ case 2: return ioport("IN2")->read();
+ case 3: return ioport("IN3")->read();
+ case 4: return ioport("IN4")->read();
+ case 5: return ioport("IN5")->read();
+ case 6: return ioport("DSW")->read();
+ }
+ logerror("%s: unknown input %02x read\n", machine().describe_context(), m_trivrus_input);
+ return 0xff;
+}
+
+WRITE8_MEMBER(trivrus_state::trivrus_input_w)
+{
+ m_trivrus_input = data & 0xff;
+}
+
+READ32_MEMBER(trivrus_state::FlashCmd_r)
+{
+ if ((m_FlashCmd & 0xff) == 0xff)
+ {
+ if (m_Bank < m_maxbank)
+ {
+ uint32_t *ptr = (uint32_t*)(m_mainbank->base());
+ return ptr[0];
+ }
+ else
+ return 0xffffffff;
+ }
+ if ((m_FlashCmd & 0xff) == 0x90)
+ {
+ if (m_Bank < m_maxbank)
+ return 0x00180089; //Intel 128MBit
+ else
+ return 0xffffffff;
+ }
+ return 0;
+}
+
+
+WRITE32_MEMBER(trivrus_state::Banksw_w)
+{
+ m_Bank = (data >> 1) & 7;
+ m_mainbank->set_entry(m_Bank);
+}
+
+void trivrus_state::trivrus_mem(address_map &map)
+{
+ map(0x00000000, 0x0007ffff).rom().nopw();
+
+// map(0x01280000, 0x01280003).w(FUNC(trivrus_state::Banksw_w));
+
+// 0x01280000 & 0x0000ffff (written at boot)
+ map(0x01500000, 0x01500000).rw(FUNC(trivrus_state::trivrus_input_r), FUNC(trivrus_state::trivrus_input_w));
+// 0x01500010 & 0x000000ff = sec
+// 0x01500010 & 0x00ff0000 = min
+// 0x01500014 & 0x000000ff = hour
+// 0x01500014 & 0x00ff0000 = day
+// 0x01500018 & 0x000000ff = month
+// 0x0150001c & 0x000000ff = year - 2000
+ map(0x01600000, 0x01607fff).ram().share("nvram");
+
+ map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
+ map(0x01802004, 0x01802007).rw(FUNC(trivrus_state::PIOldat_r), FUNC(trivrus_state::PIOldat_w));
+ map(0x01802008, 0x0180200b).r(FUNC(trivrus_state::PIOedat_r));
+
+ map(0x02000000, 0x027fffff).ram().share("workram");
+
+ map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
+ map(0x03800000, 0x03ffffff).ram().share("textureram");
+ map(0x04000000, 0x047fffff).ram().share("frameram");
+ map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
+
+ map(0x05000000, 0x05ffffff).bankr("mainbank");
+ map(0x05000000, 0x05000003).rw(FUNC(trivrus_state::FlashCmd_r), FUNC(trivrus_state::FlashCmd_w));
+}
+
+#ifdef IDLE_LOOP_SPEEDUP
+
+WRITE_LINE_MEMBER(trivrus_state::idle_skip_resume_w)
+{
+ m_FlipCntRead = 0;
+ m_maincpu->resume(SUSPEND_REASON_SPIN);
+}
+
+WRITE_LINE_MEMBER(trivrus_state::idle_skip_speedup_w)
+{
+ m_FlipCntRead++;
+ if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
+ m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
+}
+#endif
+
+void trivrus_state::machine_start()
+{
+ m_vr0vid->set_areas(reinterpret_cast<uint8_t*>(m_textureram.target()), reinterpret_cast<uint16_t*>(m_frameram.target()));
+ m_vr0snd->set_areas(m_textureram, m_frameram);
+
+ if (m_mainbank)
+ {
+ m_maxbank = (m_flash) ? m_flash.bytes() / 0x1000000 : 0;
+ uint8_t *dummy_region = auto_alloc_array(machine(), uint8_t, 0x1000000);
+ std::fill_n(&dummy_region[0], 0x1000000, 0xff); // 0xff Filled at Unmapped area
+ uint8_t *ROM = (m_flash) ? (uint8_t *)&m_flash[0] : dummy_region;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((i < m_maxbank))
+ m_mainbank->configure_entry(i, ROM + i * 0x1000000);
+ else
+ m_mainbank->configure_entry(i, dummy_region);
+ }
+ }
+
+#ifdef IDLE_LOOP_SPEEDUP
+ save_item(NAME(m_FlipCntRead));
+#endif
+
+ save_item(NAME(m_Bank));
+ save_item(NAME(m_FlashCmd));
+ save_item(NAME(m_PIO));
+ save_item(NAME(m_trivrus_input));
+}
+
+void trivrus_state::machine_reset()
+{
+ m_Bank = 0;
+ m_mainbank->set_entry(m_Bank);
+ m_FlashCmd = 0xff;
+
+#ifdef IDLE_LOOP_SPEEDUP
+ m_FlipCntRead = 0;
+#endif
+}
+
+static INPUT_PORTS_START(trivrus)
+ PORT_START("IN1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Left/True") PORT_CODE(KEYCODE_LEFT)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
+
+ PORT_START("IN2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Enter/Exit")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Next")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Right/False") PORT_CODE(KEYCODE_RIGHT)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN3")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Sound")
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN4")
+ PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_OTHER )PORT_CODE(KEYCODE_9)
+
+ PORT_START("IN5")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) // Free Game
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_SERVICE_NO_TOGGLE( 0x08, IP_ACTIVE_LOW ) // Setup
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("DSW")
+ PORT_DIPNAME( 0x01, 0x01, "Interlace?" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "Serial?" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // hangs at boot
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "Touch Screen" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+INPUT_PORTS_END
+
+void trivrus_state::trivrus(machine_config &config)
+{
+ SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
+ m_maincpu->set_addrmap(AS_PROGRAM, &trivrus_state::trivrus_mem);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(trivrus_state::icallback));
+
+ NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ // evolution soccer defaults
+ m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240);
+ m_screen->set_screen_update(FUNC(trivrus_state::screen_update));
+ m_screen->screen_vblank().set(FUNC(trivrus_state::screen_vblank));
+ m_screen->set_palette("palette");
+
+ VRENDER0_SOC(config, m_vr0soc, 0);
+ m_vr0soc->set_host_cpu_tag(m_maincpu);
+ m_vr0soc->set_host_screen_tag(m_screen);
+
+ VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
+ #ifdef IDLE_LOOP_SPEEDUP
+ m_vr0soc->idleskip_cb().set(FUNC(trivrus_state::idle_skip_resume_w));
+ m_vr0vid->idleskip_cb().set(FUNC(trivrus_state::idle_skip_speedup_w));
+ #endif
+
+ PALETTE(config, "palette", palette_device::RGB_565);
+
+ DS1302(config, m_ds1302, 32.768_kHz_XTAL);
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ SOUND_VRENDER0(config, m_vr0snd, 0);
+ m_vr0snd->add_route(0, "lspeaker", 1.0);
+ m_vr0snd->add_route(1, "rspeaker", 1.0);
+}
+
+ROM_START( trivrus )
+ ROM_REGION( 0x80000, "maincpu", 0 )
+ ROM_LOAD( "u4", 0x00000, 0x80000, CRC(2d2e9a11) SHA1(73e7b19a032eae21312ca80f8c42cc16725496a7) )
+
+ ROM_REGION32_LE( 0x2000000, "flash", ROMREGION_ERASEFF ) // Flash
+ ROM_LOAD( "u3", 0x000000, 0x1000010, CRC(ba901707) SHA1(e281ba07024cd19ef1ab72d2197014f7b1f4d30f) )
+ROM_END
+
+GAME( 2009, trivrus, 0, trivrus, trivrus, trivrus_state, empty_init, ROT0, "AGT", "Trivia R Us (v1.07)", 0 )
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 345c82e2fd0..de2326ce583 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -10894,6 +10894,9 @@ crospang // (c) 1998 F2 System
heuksun // (c) 1998 Oksan / F2 System
pitapat
+@source:crospuzl.cpp
+crospuzl //
+
@source:crshrace.cpp
crshrace // (c) 1993 Video System Co.
crshrace2 // (c) 1993 Video System Co.
@@ -10912,17 +10915,10 @@ wizzard //
@source:crystal.cpp
crysbios //
crysking // 2001 Brezzasoft. Crystal of the kings
-crzclass // 200? TJF
-crzyddz2 // 2006 Sealy
-ddz // 200?
donghaer //
evosocc // 2001 Evoga. Evolution Soccer
officeye //
-menghong // 2004? Sealy
-psattack // 2004 Uniana
topbladv // 2002 Sonokong. Top Blade V
-trivrus // 2009 AGT. Trivia R Us
-crospuzl //
@source:airraid.cpp
airraid // (c) 1987 Seibu Kaihatsu
@@ -11294,6 +11290,10 @@ wwfwfestub // bootleg
ddribble // GX690 (c) 1986
ddribblep // GX690 (c) 1986
+@source:ddz.cpp
+crzclass // 200? TJF
+ddz // 200?
+
@source:de_2.cpp
bttf_a20 //
bttf_a21 //
@@ -21439,6 +21439,10 @@ meijinsn // (c) 1986 SNK
@source:mekd2.cpp
mekd2 // 1977 Motorola Evaluation Kit
+@source:menghong.cpp
+crzyddz2 // 2006 Sealy
+menghong // 2004? Sealy
+
@source:mephisto_brikett.cpp
mephisto
mephisto2
@@ -33313,6 +33317,9 @@ i8580111 // IBM PS/2 8580-111 (Model 80)
@source:ps2sony.cpp
ps2 // Sony Playstation 2
+@source:psattack.cpp
+psattack // 2004 Uniana
+
@source:pse.cpp
bazooka // (c) 1976 PSE
bazookabr // (c) 1977 Taito do Brasil
@@ -38568,6 +38575,9 @@ vs4jc // 2004.09 Virtua Striker 4 (Japan) (Rev C)
@source:triplhnt.cpp
triplhnt // 008422-008791 1977/04 [6800]
+@source:trivrus.cpp
+trivrus // 2009 AGT. Trivia R Us
+
@source:trkfldch.cpp
trkfldch // (c) 2007 Konami
my1stddr // (c) 2006 Konami
diff --git a/src/mame/video/vrender0.cpp b/src/mame/video/vrender0.cpp
index dc937f1ff95..979c2996ad8 100644
--- a/src/mame/video/vrender0.cpp
+++ b/src/mame/video/vrender0.cpp
@@ -27,8 +27,92 @@ DEFINE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device, "vr0video", "MagicEyes VRend
vr0video_device::vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, VIDEO_VRENDER0, tag, owner, clock)
+ , device_video_interface(mconfig, *this)
, m_cpu(*this, finder_base::DUMMY_TAG)
+ , m_idleskip_cb(*this)
+
+{
+}
+
+void vr0video_device::regs_map(address_map &map)
+{
+ map(0x0080, 0x0081).rw(FUNC(vr0video_device::cmd_queue_front_r), FUNC(vr0video_device::cmd_queue_front_w));
+ map(0x0082, 0x0083).r(FUNC(vr0video_device::cmd_queue_rear_r));
+
+ map(0x008c, 0x008d).rw(FUNC(vr0video_device::render_control_r), FUNC(vr0video_device::render_control_w));
+ map(0x008e, 0x008f).r(FUNC(vr0video_device::display_bank_r));
+
+ map(0x0090, 0x0091).rw(FUNC(vr0video_device::bank1_select_r), FUNC(vr0video_device::bank1_select_w));
+ map(0x00a6, 0x00a7).rw(FUNC(vr0video_device::flip_count_r), FUNC(vr0video_device::flip_count_w));
+}
+
+READ16_MEMBER(vr0video_device::cmd_queue_front_r)
+{
+ return m_queue_front & 0x7ff;
+}
+
+WRITE16_MEMBER(vr0video_device::cmd_queue_front_w)
+{
+ COMBINE_DATA(&m_queue_front);
+}
+
+READ16_MEMBER(vr0video_device::cmd_queue_rear_r)
+{
+ return m_queue_rear & 0x7ff;
+}
+
+READ16_MEMBER(vr0video_device::render_control_r)
+{
+ return (m_draw_select<<7) | (m_render_reset<<3) | (m_render_start<<2) | (m_dither_mode);
+}
+
+WRITE16_MEMBER(vr0video_device::render_control_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ m_draw_select = BIT(data, 7);
+ m_render_reset = BIT(data, 3);
+ m_render_start = BIT(data, 2);
+ m_dither_mode = data & 3;
+
+ // initialize pipeline
+ // TODO: what happens if reset and start are both 1? Datasheet advises against it.
+ if (m_render_reset == true)
+ m_queue_front = m_queue_rear = 0;
+ }
+}
+
+READ16_MEMBER(vr0video_device::display_bank_r)
+{
+ return m_display_bank;
+}
+
+READ16_MEMBER(vr0video_device::bank1_select_r)
+{
+ return (m_bank1_select)<<15;
+}
+
+WRITE16_MEMBER(vr0video_device::bank1_select_w)
{
+ m_bank1_select = BIT(data,15);
+}
+
+READ16_MEMBER(vr0video_device::flip_count_r)
+{
+ m_idleskip_cb(m_flip_count != 0);
+ return m_flip_count;
+}
+
+WRITE16_MEMBER(vr0video_device::flip_count_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ int fc = (data) & 0xff;
+ if (fc == 1)
+ m_flip_count++;
+ else if (fc == 0)
+ m_flip_count = 0;
+ }
}
//-------------------------------------------------
@@ -37,6 +121,8 @@ vr0video_device::vr0video_device(const machine_config &mconfig, const char *tag,
void vr0video_device::device_start()
{
+ m_idleskip_cb.resolve_safe();
+
save_item(NAME(m_InternalPalette));
save_item(NAME(m_LastPalUpdate));
@@ -60,6 +146,22 @@ void vr0video_device::device_start()
save_item(NAME(m_RenderState.PixelFormat));
save_item(NAME(m_RenderState.Width));
save_item(NAME(m_RenderState.Height));
+
+ save_item(NAME(m_flip_count));
+ save_item(NAME(m_queue_rear));
+ save_item(NAME(m_queue_front));
+ save_item(NAME(m_bank1_select));
+ save_item(NAME(m_display_bank));
+ save_item(NAME(m_draw_select));
+ save_item(NAME(m_render_reset));
+ save_item(NAME(m_render_start));
+ save_item(NAME(m_dither_mode));
+}
+
+void vr0video_device::set_areas(uint8_t *textureram, uint16_t *frameram)
+{
+ m_textureram = textureram;
+ m_frameram = frameram;
}
//-------------------------------------------------
@@ -396,9 +498,13 @@ static const _DrawTemplate DrawTile[]=
#define Packet(i) space.read_word(PacketPtr + 2 * i)
//Returns true if the operation was a flip (sync or async)
-int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest, uint8_t *TEXTURE)
+// TODO: async loading actually doesn't stop rendering but just flips the render bank
+int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
{
+ // TODO: this need to be removed
address_space &space = m_cpu->space(AS_PROGRAM);
+ uint8_t *TEXTURE = m_textureram;
+
uint32_t Dx = Packet(1) & 0x3ff;
uint32_t Dy = Packet(2) & 0x1ff;
uint32_t Endx = Packet(3) & 0x3ff;
@@ -551,3 +657,66 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest,
}
return 0;
}
+
+void vr0video_device::execute_drawing()
+{
+ if (m_render_start == false)
+ return;
+
+ uint32_t B0 = 0x000000;
+ uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
+ uint16_t *DrawDest;
+ uint16_t *Front, *Back;
+ int DoFlip = 0;
+
+ if (m_display_bank & 1)
+ {
+ Front = (m_frameram + B1);
+ Back = (m_frameram + B0);
+ }
+ else
+ {
+ Front = (m_frameram + B0);
+ Back = (m_frameram + B1);
+ }
+
+ DrawDest = ((m_draw_select == true) ? Front : Back);
+
+ while ((m_queue_rear & 0x7ff) != (m_queue_front & 0x7ff))
+ {
+ DoFlip = vrender0_ProcessPacket(0x03800000 + m_queue_rear * 64, DrawDest);
+ m_queue_rear ++;
+ m_queue_rear &= 0x7ff;
+ if (DoFlip)
+ break;
+ }
+
+ if (DoFlip)
+ {
+ if (m_flip_count)
+ {
+ m_flip_count--;
+ m_display_bank ^= 1;
+ }
+ }
+}
+
+uint32_t vr0video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint16_t *Visible;
+ const uint32_t width = cliprect.width();
+
+ uint32_t B0 = 0x000000;
+ uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
+
+ if (m_display_bank & 1)
+ Visible = (m_frameram + B1);
+ else
+ Visible = (m_frameram + B0);
+
+ uint32_t const dx = cliprect.left();
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
+ std::copy_n(&Visible[(y * 1024) + dx], width, &bitmap.pix16(y, dx));
+
+ return 0;
+}
diff --git a/src/mame/video/vrender0.h b/src/mame/video/vrender0.h
index 5fb05fef8ff..5669c74e810 100644
--- a/src/mame/video/vrender0.h
+++ b/src/mame/video/vrender0.h
@@ -10,7 +10,8 @@
TYPE DEFINITIONS
***************************************************************************/
-class vr0video_device : public device_t
+class vr0video_device : public device_t,
+ public device_video_interface
{
public:
template <typename T> vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
@@ -21,7 +22,14 @@ public:
vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- int vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest, uint8_t *TEXTURE);
+ void set_areas(uint8_t *textureram, uint16_t *frameram);
+ void regs_map(address_map &map);
+ void execute_drawing();
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ auto idleskip_cb() { return m_idleskip_cb.bind(); }
+
+ DECLARE_READ16_MEMBER(flip_count_r);
+ DECLARE_WRITE16_MEMBER(flip_count_w);
protected:
// device-level overrides
@@ -29,6 +37,11 @@ protected:
virtual void device_reset() override;
private:
+ int vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest);
+
+ required_device<cpu_device> m_cpu;
+ devcb_write_line m_idleskip_cb;
+
struct RenderStateInfo
{
uint32_t Tx;
@@ -53,13 +66,35 @@ private:
uint32_t Height;
};
- // internal state
- required_device<cpu_device> m_cpu;
uint16_t m_InternalPalette[256];
uint32_t m_LastPalUpdate;
RenderStateInfo m_RenderState;
+
+ uint8_t *m_textureram;
+ uint16_t *m_frameram;
+
+ DECLARE_READ16_MEMBER( cmd_queue_front_r );
+ DECLARE_WRITE16_MEMBER( cmd_queue_front_w );
+
+ DECLARE_READ16_MEMBER( cmd_queue_rear_r );
+ uint16_t m_queue_rear, m_queue_front;
+
+ DECLARE_READ16_MEMBER( bank1_select_r );
+ DECLARE_WRITE16_MEMBER( bank1_select_w );
+ bool m_bank1_select;
+
+ DECLARE_READ16_MEMBER( display_bank_r );
+ uint8_t m_display_bank;
+
+ DECLARE_READ16_MEMBER( render_control_r );
+ DECLARE_WRITE16_MEMBER( render_control_w );
+ bool m_draw_select;
+ bool m_render_reset;
+ bool m_render_start;
+ uint8_t m_dither_mode;
+ uint8_t m_flip_count;
};
DECLARE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device)