Major refactoring of VRender0 SoC device [Angelo Salese] (#5527)

*    Improved encapsulation between video and machine SoC periperals;
*    Split up HWs in individual files where they don't belong to Crystal System HW, makes future development easier;
*    Untangled reads/writes to draw/display bankswitches from screen_update, now they can be unthrottled safely;
*    Added CRTC screen raw parameters;
*    Add DMA hold feature and clear irq on mask writes, specific for P's Attack;
*    Improved Cross Puzzle flash loading, currently failing at POST for a SPU error;

nexus3d.cpp: add some preliminary work, currently does some VRender3d pipeline fill with a debug trick [Angelo Salese]

(out of whatsnew)
Some stuff definitely needs fine graining, like removing the few lines that are still necessary to configure the VRender0 from driver files, which I'm gonna do in my next feature branch.
This commit is contained in:
Angelo Salese 2019-08-24 11:33:39 +02:00 committed by GitHub
parent 684e514e75
commit f5b2fd9ee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 3338 additions and 1331 deletions

View File

@ -4124,3 +4124,15 @@ if (MACHINES["WTL3132"]~=null) then
MAME_DIR .. "src/devices/machine/wtl3132.h", MAME_DIR .. "src/devices/machine/wtl3132.h",
} }
end 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

View File

@ -4650,6 +4650,10 @@ files {
MAME_DIR .. "src/mame/drivers/corona.cpp", MAME_DIR .. "src/mame/drivers/corona.cpp",
MAME_DIR .. "src/mame/drivers/cwheel.cpp", MAME_DIR .. "src/mame/drivers/cwheel.cpp",
MAME_DIR .. "src/mame/drivers/crystal.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.cpp",
MAME_DIR .. "src/mame/video/vrender0.h", MAME_DIR .. "src/mame/video/vrender0.h",
MAME_DIR .. "src/mame/drivers/cubeqst.cpp", MAME_DIR .. "src/mame/drivers/cubeqst.cpp",

View File

@ -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;
}

View File

@ -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

View File

@ -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 )

File diff suppressed because it is too large Load Diff

265
src/mame/drivers/ddz.cpp Normal file
View File

@ -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'

View File

@ -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 )

View File

@ -19,6 +19,7 @@
#include "machine/serflash.h" #include "machine/serflash.h"
#include "emupal.h" #include "emupal.h"
#include "screen.h" #include "screen.h"
#include "debugger.h"
//#include "machine/i2cmem.h" //#include "machine/i2cmem.h"
@ -29,97 +30,285 @@ class nexus3d_state : public driver_device
public: public:
nexus3d_state(const machine_config &mconfig, device_type type, const char *tag) nexus3d_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_mainram(*this, "mainram"),
m_maincpu(*this, "maincpu"), 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 nexus3d(machine_config &config);
void init_nexus3d(); void init_acheart();
void init_acheartf();
private: private:
required_shared_ptr<uint32_t> m_mainram;
required_device<cpu_device> m_maincpu; 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<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_unk2_r);
// DECLARE_READ32_MEMBER(nexus3d_unk3_r); // DECLARE_READ32_MEMBER(nexus3d_unk3_r);
// DECLARE_WRITE32_MEMBER(nexus3d_unk2_w); // DECLARE_WRITE32_MEMBER(nexus3d_unk2_w);
// DECLARE_WRITE32_MEMBER(nexus3d_unk3_w); // DECLARE_WRITE32_MEMBER(nexus3d_unk3_w);
virtual void machine_start() override;
virtual void machine_reset() override; virtual void machine_reset() override;
virtual void video_start() 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); 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()
READ32_MEMBER(nexus3d_state::nexus3d_unk_r)
{ {
return machine().rand() ^ (machine().rand() << 16); // ...
} }
//READ32_MEMBER(nexus3d_state::nexus3d_unk2_r) uint32_t nexus3d_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
//{ {
// return 0x00000000;//machine().rand() ^ (machine().rand() << 16); uint16_t *fbram = reinterpret_cast<uint16_t *>(m_fbram.target());
//} const int width = 640;
//
//READ32_MEMBER(nexus3d_state::nexus3d_unk3_r) uint16_t *visible = fbram + (m_screen->frame_number() & 1) * (0x96000/2);
//{
// return 0x00000000;//machine().rand() ^ (machine().rand() << 16); 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));
//WRITE32_MEMBER(nexus3d_state::nexus3d_unk2_w)
//{ return 0;
// }
//}
// READ32_MEMBER(nexus3d_state::vrender3d_status_r)
//WRITE32_MEMBER(nexus3d_state::nexus3d_unk3_w) {
//{ return (0xbf<<16) | m_screen->vpos();
// }
//}
void nexus3d_state::IntReq(int level)
{
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::int_mask_r)
{
return m_intmask;
}
WRITE32_MEMBER(nexus3d_state::int_mask_w)
{
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;
}
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) void nexus3d_state::nexus3d_map(address_map &map)
{ {
map(0x00000000, 0x003fffff).ram().share("mainram"); map(0x00000000, 0x01ffffff).ram().share("mainram");
map(0x02000000, 0x023fffff).ram().share("fbram"); // boundary tbd
map(0x00400000, 0x01ffffff).ram(); // ?? uploads various data, + pointers to data in the 0x01ffxxxx range, might be video system related 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 // flash
map(0x9C000000, 0x9C000003).r(m_serflash, FUNC(serflash_device::n3d_flash_r)); 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(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)); 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 // lots of accesses in this range
// 0xc00018xx seems CRTC related // 0xc00018xx seems CRTC related
// 0xc000091x loads a "gfx charset"? // 0xc000091x loads a "gfx charset"?
// AM_RANGE(0xC0000F44, 0xC0000F47) AM_READWRITE(nexus3d_unk2_r, nexus3d_unk2_w ) // often, status for something. map(0xc0000910, 0xc0000913).w(FUNC(nexus3d_state::rop_data_w));
// AM_RANGE(0xC0000F4C, 0xC0000F4f) AM_READWRITE(nexus3d_unk3_r, nexus3d_unk3_w ) // often map(0xc000091c, 0xc000091f).w(FUNC(nexus3d_state::rop_register_w)).umask32(0xffff0000);
map(0xE0000014, 0xE0000017).r(FUNC(nexus3d_state::nexus3d_unk_r)); // sits waiting for this 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(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 ) static INPUT_PORTS_START( nexus3d )
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 INPUT_PORTS_END
void nexus3d_state::machine_start()
void nexus3d_state::video_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)
{
return 0;
} }
void nexus3d_state::machine_reset() void nexus3d_state::machine_reset()
{ {
// the first part of the flash ROM automatically gets copied to RAM
memcpy(m_mainram, memregion("flash")->base(), 4 * 1024);
}
WRITE_LINE_MEMBER(nexus3d_state::screen_vblank)
{
// rising edge
if (state)
{
// EXTINT1?
//IntReq(9);
IntReq(1);
}
} }
void nexus3d_state::nexus3d(machine_config &config) void nexus3d_state::nexus3d(machine_config &config)
@ -128,14 +317,13 @@ void nexus3d_state::nexus3d(machine_config &config)
ARM920T(config, m_maincpu, 200000000); ARM920T(config, m_maincpu, 200000000);
m_maincpu->set_addrmap(AS_PROGRAM, &nexus3d_state::nexus3d_map); m_maincpu->set_addrmap(AS_PROGRAM, &nexus3d_state::nexus3d_map);
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_refresh_hz(60); m_screen->set_raw((XTAL(14'318'180)*2), 454*2, 0, 640, 262*2, 0, 480); // not accurate, needs CRTC understanding
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); m_screen->set_screen_update(FUNC(nexus3d_state::screen_update));
screen.set_size(320, 256); m_screen->screen_vblank().set(FUNC(nexus3d_state::screen_vblank));
screen.set_visarea(0, 320-1, 0, 256-1); m_screen->set_palette("palette");
screen.set_screen_update(FUNC(nexus3d_state::screen_update_nexus3d));
PALETTE(config, "palette").set_entries(256); PALETTE(config, "palette", palette_device::RGB_565);
SERFLASH(config, m_serflash, 0); 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_LOAD( "qs1001a", 0x000000, 0x80000, CRC(d13c6407) SHA1(57b14f97c7d4f9b5d9745d3571a0b7115fbe3176) ) // missing from this set, but should be the same
ROM_END ROM_END
void nexus3d_state::init_nexus3d() void nexus3d_state::init_acheart()
{ {
// the first part of the flash ROM automatically gets copied to RAM // 0x1230 BL <vector>
memcpy(m_mainram, memregion("flash")->base(), 4 * 1024); // 0x1234 CMPS, #$0 <- if R0 = 1 then stops at 0x1244
} }
GAME( 2005, acheart, 0, nexus3d, nexus3d, nexus3d_state, init_nexus3d, ROT0, "Examu", "Arcana Heart", MACHINE_IS_SKELETON ) void nexus3d_state::init_acheartf()
GAME( 2006, acheartf, 0, nexus3d, nexus3d, nexus3d_state, init_nexus3d, ROT0, "Examu", "Arcana Heart Full", MACHINE_IS_SKELETON ) {
// 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_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 )

View File

@ -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

View File

@ -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 )

View File

@ -10894,6 +10894,9 @@ crospang // (c) 1998 F2 System
heuksun // (c) 1998 Oksan / F2 System heuksun // (c) 1998 Oksan / F2 System
pitapat pitapat
@source:crospuzl.cpp
crospuzl //
@source:crshrace.cpp @source:crshrace.cpp
crshrace // (c) 1993 Video System Co. crshrace // (c) 1993 Video System Co.
crshrace2 // (c) 1993 Video System Co. crshrace2 // (c) 1993 Video System Co.
@ -10912,17 +10915,10 @@ wizzard //
@source:crystal.cpp @source:crystal.cpp
crysbios // crysbios //
crysking // 2001 Brezzasoft. Crystal of the kings crysking // 2001 Brezzasoft. Crystal of the kings
crzclass // 200? TJF
crzyddz2 // 2006 Sealy
ddz // 200?
donghaer // donghaer //
evosocc // 2001 Evoga. Evolution Soccer evosocc // 2001 Evoga. Evolution Soccer
officeye // officeye //
menghong // 2004? Sealy
psattack // 2004 Uniana
topbladv // 2002 Sonokong. Top Blade V topbladv // 2002 Sonokong. Top Blade V
trivrus // 2009 AGT. Trivia R Us
crospuzl //
@source:airraid.cpp @source:airraid.cpp
airraid // (c) 1987 Seibu Kaihatsu airraid // (c) 1987 Seibu Kaihatsu
@ -11294,6 +11290,10 @@ wwfwfestub // bootleg
ddribble // GX690 (c) 1986 ddribble // GX690 (c) 1986
ddribblep // GX690 (c) 1986 ddribblep // GX690 (c) 1986
@source:ddz.cpp
crzclass // 200? TJF
ddz // 200?
@source:de_2.cpp @source:de_2.cpp
bttf_a20 // bttf_a20 //
bttf_a21 // bttf_a21 //
@ -21439,6 +21439,10 @@ meijinsn // (c) 1986 SNK
@source:mekd2.cpp @source:mekd2.cpp
mekd2 // 1977 Motorola Evaluation Kit mekd2 // 1977 Motorola Evaluation Kit
@source:menghong.cpp
crzyddz2 // 2006 Sealy
menghong // 2004? Sealy
@source:mephisto_brikett.cpp @source:mephisto_brikett.cpp
mephisto mephisto
mephisto2 mephisto2
@ -33313,6 +33317,9 @@ i8580111 // IBM PS/2 8580-111 (Model 80)
@source:ps2sony.cpp @source:ps2sony.cpp
ps2 // Sony Playstation 2 ps2 // Sony Playstation 2
@source:psattack.cpp
psattack // 2004 Uniana
@source:pse.cpp @source:pse.cpp
bazooka // (c) 1976 PSE bazooka // (c) 1976 PSE
bazookabr // (c) 1977 Taito do Brasil bazookabr // (c) 1977 Taito do Brasil
@ -38568,6 +38575,9 @@ vs4jc // 2004.09 Virtua Striker 4 (Japan) (Rev C)
@source:triplhnt.cpp @source:triplhnt.cpp
triplhnt // 008422-008791 1977/04 [6800] triplhnt // 008422-008791 1977/04 [6800]
@source:trivrus.cpp
trivrus // 2009 AGT. Trivia R Us
@source:trkfldch.cpp @source:trkfldch.cpp
trkfldch // (c) 2007 Konami trkfldch // (c) 2007 Konami
my1stddr // (c) 2006 Konami my1stddr // (c) 2006 Konami

View File

@ -27,16 +27,102 @@ 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) 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_t(mconfig, VIDEO_VRENDER0, tag, owner, clock)
, device_video_interface(mconfig, *this)
, m_cpu(*this, finder_base::DUMMY_TAG) , 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;
}
}
//------------------------------------------------- //-------------------------------------------------
// device_start - device-specific startup // device_start - device-specific startup
//------------------------------------------------- //-------------------------------------------------
void vr0video_device::device_start() void vr0video_device::device_start()
{ {
m_idleskip_cb.resolve_safe();
save_item(NAME(m_InternalPalette)); save_item(NAME(m_InternalPalette));
save_item(NAME(m_LastPalUpdate)); 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.PixelFormat));
save_item(NAME(m_RenderState.Width)); save_item(NAME(m_RenderState.Width));
save_item(NAME(m_RenderState.Height)); 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) #define Packet(i) space.read_word(PacketPtr + 2 * i)
//Returns true if the operation was a flip (sync or async) //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); address_space &space = m_cpu->space(AS_PROGRAM);
uint8_t *TEXTURE = m_textureram;
uint32_t Dx = Packet(1) & 0x3ff; uint32_t Dx = Packet(1) & 0x3ff;
uint32_t Dy = Packet(2) & 0x1ff; uint32_t Dy = Packet(2) & 0x1ff;
uint32_t Endx = Packet(3) & 0x3ff; uint32_t Endx = Packet(3) & 0x3ff;
@ -551,3 +657,66 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest,
} }
return 0; 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;
}

View File

@ -10,7 +10,8 @@
TYPE DEFINITIONS TYPE DEFINITIONS
***************************************************************************/ ***************************************************************************/
class vr0video_device : public device_t class vr0video_device : public device_t,
public device_video_interface
{ {
public: public:
template <typename T> vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag) 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); 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: protected:
// device-level overrides // device-level overrides
@ -29,6 +37,11 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
private: private:
int vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest);
required_device<cpu_device> m_cpu;
devcb_write_line m_idleskip_cb;
struct RenderStateInfo struct RenderStateInfo
{ {
uint32_t Tx; uint32_t Tx;
@ -53,13 +66,35 @@ private:
uint32_t Height; uint32_t Height;
}; };
// internal state
required_device<cpu_device> m_cpu;
uint16_t m_InternalPalette[256]; uint16_t m_InternalPalette[256];
uint32_t m_LastPalUpdate; uint32_t m_LastPalUpdate;
RenderStateInfo m_RenderState; 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) DECLARE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device)