diff options
-rw-r--r-- | scripts/src/machine.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 4 | ||||
-rw-r--r-- | src/devices/machine/vrender0.cpp | 576 | ||||
-rw-r--r-- | src/devices/machine/vrender0.h | 124 | ||||
-rw-r--r-- | src/mame/drivers/crospuzl.cpp | 441 | ||||
-rw-r--r-- | src/mame/drivers/crystal.cpp | 1445 | ||||
-rw-r--r-- | src/mame/drivers/ddz.cpp | 265 | ||||
-rw-r--r-- | src/mame/drivers/menghong.cpp | 493 | ||||
-rw-r--r-- | src/mame/drivers/nexus3d.cpp | 297 | ||||
-rw-r--r-- | src/mame/drivers/psattack.cpp | 333 | ||||
-rw-r--r-- | src/mame/drivers/trivrus.cpp | 417 | ||||
-rw-r--r-- | src/mame/mame.lst | 24 | ||||
-rw-r--r-- | src/mame/video/vrender0.cpp | 171 | ||||
-rw-r--r-- | src/mame/video/vrender0.h | 43 |
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(®s[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) |