summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2019-08-24 11:33:39 +0200
committer GitHub <noreply@github.com>2019-08-24 11:33:39 +0200
commitf5b2fd9ee6ef6ced1eec7859494e82c375d9c8d2 (patch)
tree376877d72db797a972308e698c3f81beddf160b4
parent684e514e75a92addbb60656b9f82bb8754ef9ac6 (diff)
Major refactoring of VRender0 SoC device [Angelo Salese] (#5527)
* Improved encapsulation between video and machine SoC periperals; * Split up HWs in individual files where they don't belong to Crystal System HW, makes future development easier; * Untangled reads/writes to draw/display bankswitches from screen_update, now they can be unthrottled safely; * Added CRTC screen raw parameters; * Add DMA hold feature and clear irq on mask writes, specific for P's Attack; * Improved Cross Puzzle flash loading, currently failing at POST for a SPU error; nexus3d.cpp: add some preliminary work, currently does some VRender3d pipeline fill with a debug trick [Angelo Salese] (out of whatsnew) Some stuff definitely needs fine graining, like removing the few lines that are still necessary to configure the VRender0 from driver files, which I'm gonna do in my next feature branch.
-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)