mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
Various improvements over Vrender0 based systems [Angelo Salese] (#5580)
* Made some experimental work with menghong based HW, allowing crzyddz2 to boot and improving menghong colors; * Internalize video and audio components inside the SoC; * Wrote a preliminary UART subdevice; * Made external video clock to be settable by the host driver;
This commit is contained in:
parent
5aa10d4f7d
commit
11f9727726
@ -4145,6 +4145,8 @@ end
|
||||
if (MACHINES["VRENDER0"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/vrender0.cpp",
|
||||
MAME_DIR .. "src/devices/machine/vr0uart.cpp",
|
||||
MAME_DIR .. "src/devices/machine/vrender0.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
220
src/devices/machine/vr0uart.cpp
Normal file
220
src/devices/machine/vr0uart.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Angelo Salese
|
||||
/***************************************************************************
|
||||
|
||||
MagicEyes VRender0 UART sub-device
|
||||
|
||||
Device by Angelo Salese
|
||||
|
||||
TODO:
|
||||
- The only current example (Trivia R Us touchscreen) expects to read
|
||||
stuff before transmitting anything, except for loopback test and a
|
||||
signal break enabling at POST (!?).
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "vrender0.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(VRENDER0_UART, vr0uart_device, "vr0uart", "MagicEyes VRender0 UART")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// vr0uart_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
vr0uart_device::vr0uart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, VRENDER0_UART, tag, owner, clock),
|
||||
device_serial_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
void vr0uart_device::regs_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x03).rw(FUNC(vr0uart_device::control_r), FUNC(vr0uart_device::control_w));
|
||||
map(0x04, 0x07).r(FUNC(vr0uart_device::status_r));
|
||||
map(0x08, 0x0b).w(FUNC(vr0uart_device::transmit_buffer_w));
|
||||
map(0x0c, 0x0f).r(FUNC(vr0uart_device::receive_buffer_r));
|
||||
map(0x10, 0x13).rw(FUNC(vr0uart_device::baud_rate_div_r), FUNC(vr0uart_device::baud_rate_div_w));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void vr0uart_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_ucon));
|
||||
save_item(NAME(m_ubdr));
|
||||
save_item(NAME(m_ustat));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void vr0uart_device::device_reset()
|
||||
{
|
||||
m_ucon = 0x001;
|
||||
m_ubdr = 1;
|
||||
m_urxb_fifo.clear();
|
||||
|
||||
update_serial_config();
|
||||
}
|
||||
|
||||
inline void vr0uart_device::tx_send_byte(uint8_t val)
|
||||
{
|
||||
transmit_register_setup(val);
|
||||
m_ustat |= 0x20;
|
||||
}
|
||||
|
||||
inline uint32_t vr0uart_device::calculate_baud_rate()
|
||||
{
|
||||
uint32_t div_rate = ((m_ubdr & 0xffff) + 1) * 16;
|
||||
// TODO: external / internal serial clock config
|
||||
return (this->clock() / 2) / div_rate;
|
||||
}
|
||||
|
||||
void vr0uart_device::update_serial_config()
|
||||
{
|
||||
const parity_t parity_modes[4] = { PARITY_NONE, PARITY_NONE, PARITY_EVEN, PARITY_ODD };
|
||||
|
||||
uint8_t word_length = m_ucon & 1 ? 8 : 7;
|
||||
parity_t parity_mode = parity_modes[(m_ucon & 0xc) >> 2];
|
||||
stop_bits_t stop_bits = m_ucon & 2 ? STOP_BITS_2 : STOP_BITS_1;
|
||||
|
||||
set_data_frame(1, word_length, parity_mode, stop_bits);
|
||||
|
||||
if (m_ucon & 0x100) // UART Enable
|
||||
{
|
||||
uint32_t clock_rate = calculate_baud_rate();
|
||||
set_rcv_rate(clock_rate);
|
||||
set_tra_rate(clock_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_rcv_rate(0);
|
||||
set_tra_rate(0);
|
||||
}
|
||||
}
|
||||
|
||||
void vr0uart_device::tra_callback()
|
||||
{
|
||||
int bit = transmit_register_get_data_bit();
|
||||
m_ustat |= 0x40;
|
||||
m_parent->write_line_tx(m_channel_num, bit);
|
||||
}
|
||||
|
||||
void vr0uart_device::tra_complete()
|
||||
{
|
||||
m_ustat &= ~0x60;
|
||||
m_parent->IntReq(m_channel_num ? 18 : 15);
|
||||
}
|
||||
|
||||
void vr0uart_device::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
if (is_receive_parity_error())
|
||||
m_ustat |= 2;
|
||||
if (is_receive_framing_error())
|
||||
m_ustat |= 4;
|
||||
|
||||
if (!m_urxb_fifo.full())
|
||||
{
|
||||
// TODO: break detection
|
||||
m_urxb_fifo.enqueue(get_received_char());
|
||||
}
|
||||
else
|
||||
m_ustat |= 1; // overrun
|
||||
|
||||
if (m_ucon & 0x20 && m_ustat & 0xf)
|
||||
m_parent->IntReq(m_channel_num ? 16 : 13);
|
||||
else
|
||||
m_parent->IntReq(m_channel_num ? 17 : 14);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
/*
|
||||
* ---x ---- ---- UART enable
|
||||
* ---- x--- ---- Loopback Test
|
||||
* ---- -x-- ---- Send Break mode
|
||||
* ---- --x- ---- Generate interrupt on break or error
|
||||
* ---- ---x ---- Serial Clock selection (1=external)
|
||||
* ---- ---- xx-- Parity Mode (0x=No Parity, 10=Even, 11=Odd)
|
||||
* ---- ---- --x- Stop Bits (1=2 bits, 0=1 Bit)
|
||||
* ---- ---- ---x Word Length (1=8 bits, 0=7 bits)
|
||||
*/
|
||||
READ32_MEMBER( vr0uart_device::control_r )
|
||||
{
|
||||
return m_ucon;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( vr0uart_device::control_w )
|
||||
{
|
||||
COMBINE_DATA(&m_ucon);
|
||||
update_serial_config();
|
||||
}
|
||||
|
||||
/*
|
||||
* xxxx ---- ---- Receive FIFO count
|
||||
* ---- -x-- ---- Tx buffer not empty, Tx holding data
|
||||
* ---- --x- ---- Tx buffer not empty
|
||||
* ---- ---x ---- Rx buffer not empty
|
||||
* ---- ---- x--- Break detect
|
||||
* ---- ---- -x-- Frame error
|
||||
* ---- ---- --x- Parity error
|
||||
* ---- ---- ---x Overrun Error
|
||||
*/
|
||||
READ32_MEMBER( vr0uart_device::status_r )
|
||||
{
|
||||
uint32_t res = m_ustat;
|
||||
if (!m_urxb_fifo.empty())
|
||||
{
|
||||
res |= 0x10;
|
||||
res |= (m_urxb_fifo.queue_length() << 8);
|
||||
}
|
||||
// Break detect and errors are cleared by reading this
|
||||
m_ustat &= ~0xf;
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( vr0uart_device::transmit_buffer_w )
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
tx_send_byte(data & 0xff);
|
||||
}
|
||||
|
||||
READ32_MEMBER( vr0uart_device::receive_buffer_r )
|
||||
{
|
||||
// TODO: unknown value & behaviour attempting to read this on empty FIFO (stall?)
|
||||
uint8_t res = 0;
|
||||
|
||||
if (ACCESSING_BITS_0_7 && !m_urxb_fifo.empty())
|
||||
res = m_urxb_fifo.dequeue();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
READ32_MEMBER( vr0uart_device::baud_rate_div_r )
|
||||
{
|
||||
return m_ubdr;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( vr0uart_device::baud_rate_div_w )
|
||||
{
|
||||
COMBINE_DATA(&m_ubdr);
|
||||
update_serial_config();
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
#include "vrender0.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
@ -39,9 +38,15 @@ DEFINE_DEVICE_TYPE(VRENDER0_SOC, vrender0soc_device, "vrender0", "MagicEyes VRen
|
||||
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_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_vr0vid(*this, "vr0vid"),
|
||||
m_vr0snd(*this, "vr0snd"),
|
||||
m_lspeaker(*this, "lspeaker"),
|
||||
m_rspeaker(*this, "rspeaker"),
|
||||
m_uart(*this, "uart%u", 0),
|
||||
m_crtcregs(*this, "crtcregs"),
|
||||
m_idleskip_cb(*this)
|
||||
write_tx{ { *this }, { *this } }
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,6 +72,8 @@ void vrender0soc_device::regs_map(address_map &map)
|
||||
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(0x01000, 0x0101f).m(m_uart[0], FUNC(vr0uart_device::regs_map));
|
||||
map(0x01020, 0x0103f).m(m_uart[1], FUNC(vr0uart_device::regs_map));
|
||||
// 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);
|
||||
@ -88,6 +95,13 @@ void vrender0soc_device::regs_map(address_map &map)
|
||||
// map(0x04000, 0x043ff) // RAMDAC & PLL
|
||||
}
|
||||
|
||||
void vrender0soc_device::audiovideo_map(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x0000ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
|
||||
map(0x00800000, 0x00ffffff).rw(FUNC(vrender0soc_device::textureram_r), FUNC(vrender0soc_device::textureram_w));
|
||||
map(0x01000000, 0x017fffff).rw(FUNC(vrender0soc_device::frameram_r), FUNC(vrender0soc_device::frameram_w));
|
||||
map(0x01800000, 0x01800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - device-specific machine
|
||||
@ -96,8 +110,29 @@ void vrender0soc_device::regs_map(address_map &map)
|
||||
|
||||
void vrender0soc_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
// ...
|
||||
for (required_device<vr0uart_device> &uart : m_uart)
|
||||
VRENDER0_UART(config, uart, 3579500);
|
||||
|
||||
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(vrender0soc_device::screen_update));
|
||||
m_screen->screen_vblank().set(FUNC(vrender0soc_device::screen_vblank));
|
||||
m_screen->set_palette(m_palette);
|
||||
|
||||
VIDEO_VRENDER0(config, m_vr0vid, 14318180);
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_vr0vid->idleskip_cb().set(FUNC(vrender0soc_device::idle_skip_speedup_w));
|
||||
#endif
|
||||
|
||||
PALETTE(config, m_palette, palette_device::RGB_565);
|
||||
|
||||
SPEAKER(config, m_lspeaker).front_left();
|
||||
SPEAKER(config, m_rspeaker).front_right();
|
||||
|
||||
SOUND_VRENDER0(config, m_vr0snd, 0);
|
||||
m_vr0snd->add_route(0, m_lspeaker, 1.0);
|
||||
m_vr0snd->add_route(1, m_rspeaker, 1.0);
|
||||
}
|
||||
|
||||
|
||||
@ -107,12 +142,29 @@ void vrender0soc_device::device_add_mconfig(machine_config &config)
|
||||
|
||||
void vrender0soc_device::device_start()
|
||||
{
|
||||
int i;
|
||||
m_textureram = auto_alloc_array_clear(machine(), uint16_t, 0x00800000/2);
|
||||
m_frameram = auto_alloc_array_clear(machine(), uint16_t, 0x00800000/2);
|
||||
|
||||
m_vr0vid->set_areas(m_textureram, m_frameram);
|
||||
m_vr0snd->set_areas(m_textureram, m_frameram);
|
||||
m_host_space = &m_host_cpu->space(AS_PROGRAM);
|
||||
m_idleskip_cb.resolve_safe();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (this->clock() == 0)
|
||||
fatalerror("%s: bus clock not setup properly",this->tag());
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
m_Timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vrender0soc_device::Timercb),this), (void*)(uintptr_t)i);
|
||||
|
||||
for (auto &cb : write_tx)
|
||||
cb.resolve_safe();
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
m_uart[i]->set_channel_num(i);
|
||||
m_uart[i]->set_parent(this);
|
||||
}
|
||||
|
||||
save_item(NAME(m_inten));
|
||||
save_item(NAME(m_intst));
|
||||
save_item(NAME(m_IntHigh));
|
||||
@ -128,8 +180,19 @@ void vrender0soc_device::device_start()
|
||||
save_item(NAME(m_dma[1].src));
|
||||
save_item(NAME(m_dma[1].dst));
|
||||
save_item(NAME(m_dma[1].size));
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
save_item(NAME(m_FlipCntRead));
|
||||
#endif
|
||||
}
|
||||
|
||||
void vrender0soc_device::write_line_tx(int port, uint8_t value)
|
||||
{
|
||||
//printf("callback %d %02x\n",port,value);
|
||||
write_tx[port & 1](value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
@ -138,7 +201,7 @@ void vrender0soc_device::device_start()
|
||||
void vrender0soc_device::device_reset()
|
||||
{
|
||||
// TODO: improve CRT defaults
|
||||
m_crtcregs[1] = 0x00000022;
|
||||
m_crtcregs[1] = 0x0000002a;
|
||||
|
||||
//m_FlipCount = 0;
|
||||
m_IntHigh = 0;
|
||||
@ -151,6 +214,10 @@ void vrender0soc_device::device_reset()
|
||||
m_timer_control[i] = 0xff << 8;
|
||||
m_Timer[i]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_FlipCntRead = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -158,6 +225,32 @@ void vrender0soc_device::device_reset()
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
/*
|
||||
*
|
||||
* Texture/FrameRAM 16-bit trampolines
|
||||
*
|
||||
*/
|
||||
|
||||
READ16_MEMBER(vrender0soc_device::textureram_r)
|
||||
{
|
||||
return m_textureram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(vrender0soc_device::textureram_w)
|
||||
{
|
||||
COMBINE_DATA(&m_textureram[offset]);
|
||||
}
|
||||
|
||||
READ16_MEMBER(vrender0soc_device::frameram_r)
|
||||
{
|
||||
return m_frameram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(vrender0soc_device::frameram_w)
|
||||
{
|
||||
COMBINE_DATA(&m_frameram[offset]);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* INT Controller
|
||||
@ -214,7 +307,9 @@ void vrender0soc_device::IntReq( int num )
|
||||
m_host_cpu->set_input_line(SE3208_INT, ASSERT_LINE);
|
||||
}
|
||||
|
||||
m_idleskip_cb(ASSERT_LINE);
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
idle_skip_resume_w(ASSERT_LINE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +337,8 @@ 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
|
||||
// TODO: documentation claims this is bus clock, may be slower than the CPU itself
|
||||
attotime period = attotime::from_hz(this->clock()) * ((PD + 1) * (TCV + 1));
|
||||
m_Timer[which]->adjust(period);
|
||||
|
||||
// printf("timer %d start, PD = %x TCV = %x period = %s\n", which, PD, TCV, period.as_string());
|
||||
@ -369,6 +465,12 @@ WRITE32_MEMBER(vrender0soc_device::dmac_w)
|
||||
COMBINE_DATA(&m_dma[Which].ctrl);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* CRT Controller
|
||||
*
|
||||
*/
|
||||
|
||||
READ32_MEMBER(vrender0soc_device::crtc_r)
|
||||
{
|
||||
uint32_t res = m_crtcregs[offset];
|
||||
@ -380,10 +482,10 @@ READ32_MEMBER(vrender0soc_device::crtc_r)
|
||||
if (crt_is_interlaced()) // Interlace
|
||||
vdisp <<= 1;
|
||||
|
||||
if (m_host_screen->vpos() <= vdisp) // Vertical display enable status
|
||||
if (m_screen->vpos() <= vdisp) // Vertical display enable status
|
||||
res |= 0x4000;
|
||||
|
||||
if (m_host_screen->hpos() > hdisp) // horizontal & vertical blank period
|
||||
if (m_screen->hpos() > hdisp) // horizontal & vertical blank period
|
||||
res &= ~0x2000;
|
||||
else
|
||||
res |= 0x2000;
|
||||
@ -397,7 +499,7 @@ READ32_MEMBER(vrender0soc_device::crtc_r)
|
||||
|
||||
WRITE32_MEMBER(vrender0soc_device::crtc_w)
|
||||
{
|
||||
if (((m_crtcregs[0] & 0x0100) == 0x0100) && (offset > 0)) // Write protect
|
||||
if (((m_crtcregs[0] & 0x0100) == 0x0100) && (offset > 0) && (offset < 0x28/4)) // Write protect
|
||||
return;
|
||||
|
||||
uint32_t old = m_crtcregs[offset];
|
||||
@ -481,7 +583,7 @@ bool vrender0soc_device::crt_active_vblank_irq()
|
||||
return true;
|
||||
|
||||
// bit 3 of CRTC reg -> select display start even/odd fields
|
||||
return (m_host_screen->frame_number() & 1) ^ ((m_crtcregs[0] & 8) >> 3);
|
||||
return (m_screen->frame_number() & 1) ^ ((m_crtcregs[0] & 8) >> 3);
|
||||
}
|
||||
|
||||
void vrender0soc_device::crtc_update()
|
||||
@ -528,8 +630,11 @@ void vrender0soc_device::crtc_update()
|
||||
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;
|
||||
// ext vclk set up by Sealy games in menghong.cpp
|
||||
uint32_t pixel_clock = (BIT(m_crtcregs[0x04 / 4], 3)) ? 14318180 : m_ext_vclk;
|
||||
if (pixel_clock == 0)
|
||||
fatalerror("%s: Accessing external vclk in CRTC parameters, please set it up via setter in config\n",this->tag());
|
||||
|
||||
if (BIT(m_crtcregs[0x04 / 4], 7))
|
||||
pixel_clock *= 2;
|
||||
// TODO: divider setting = 0 is reserved, guess it just desyncs the signal?
|
||||
@ -554,7 +659,7 @@ void vrender0soc_device::crtc_update()
|
||||
//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);
|
||||
m_screen->configure(htot, vtot, visarea, HZ_TO_ATTOSECONDS(pixel_clock) * vtot * htot);
|
||||
}
|
||||
|
||||
// accessed by cross puzzle
|
||||
@ -562,15 +667,70 @@ READ32_MEMBER(vrender0soc_device::sysid_r)
|
||||
{
|
||||
// Device ID: VRender0+ -> 0x0a
|
||||
// Revision Number -> 0x00
|
||||
logerror("%s: read SYSID\n",this->tag());
|
||||
return 0x00000a00;
|
||||
}
|
||||
|
||||
READ32_MEMBER(vrender0soc_device::cfgr_r)
|
||||
{
|
||||
// TODO: this truly needs real HW verification
|
||||
// TODO: this truly needs real HW verification,
|
||||
// only Cross Puzzle reads this so far so leaving a logerror
|
||||
// -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;
|
||||
logerror("%s: read CFGR\n",this->tag());
|
||||
return 0x00000041;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Video configuration
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t vrender0soc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if (crt_is_blanked()) // Blank Screen
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: chip can do superimposing, cfr. TCOL register in CRTC
|
||||
m_vr0vid->screen_update(screen, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(vrender0soc_device::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
if (crt_active_vblank_irq() == true)
|
||||
IntReq(24); //VRender0 VBlank
|
||||
|
||||
m_vr0vid->execute_flipping();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Hacks
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
WRITE_LINE_MEMBER(vrender0soc_device::idle_skip_resume_w)
|
||||
{
|
||||
m_FlipCntRead = 0;
|
||||
m_host_cpu->resume(SUSPEND_REASON_SPIN);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(vrender0soc_device::idle_skip_speedup_w)
|
||||
{
|
||||
m_FlipCntRead++;
|
||||
if (m_FlipCntRead >= 16 && irq_pending() == false && state == ASSERT_LINE)
|
||||
m_host_cpu->suspend(SUSPEND_REASON_SPIN, 1);
|
||||
}
|
||||
#endif
|
||||
|
@ -13,6 +13,19 @@
|
||||
|
||||
#include "cpu/se3208/se3208.h"
|
||||
#include "screen.h"
|
||||
#include "video/vrender0.h"
|
||||
#include "sound/vrender0.h"
|
||||
#include "emupal.h"
|
||||
#include "speaker.h"
|
||||
#include "diserial.h"
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define IDLE_LOOP_SPEEDUP
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
@ -24,7 +37,57 @@
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> vrender0soc_device
|
||||
// ======================> vr0uart_device
|
||||
|
||||
class vrender0soc_device;
|
||||
|
||||
class vr0uart_device : public device_t,
|
||||
public device_serial_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
vr0uart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void regs_map(address_map &map);
|
||||
void set_channel_num(int ch) { m_channel_num = ch; }
|
||||
void set_parent(vrender0soc_device *parent) { m_parent = parent; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
DECLARE_READ32_MEMBER( control_r );
|
||||
DECLARE_WRITE32_MEMBER( control_w );
|
||||
DECLARE_READ32_MEMBER( baud_rate_div_r );
|
||||
DECLARE_WRITE32_MEMBER( baud_rate_div_w );
|
||||
DECLARE_READ32_MEMBER( status_r );
|
||||
DECLARE_WRITE32_MEMBER( transmit_buffer_w );
|
||||
DECLARE_READ32_MEMBER( receive_buffer_r );
|
||||
TIMER_CALLBACK_MEMBER( break_timer_cb );
|
||||
|
||||
uint32_t m_ucon; // control
|
||||
uint32_t m_ubdr; // baud rate
|
||||
uint32_t m_ustat; // status
|
||||
util::fifo<uint8_t, 16> m_urxb_fifo; // receive FIFO
|
||||
|
||||
void update_serial_config();
|
||||
inline uint32_t calculate_baud_rate();
|
||||
|
||||
virtual void tra_callback() override;
|
||||
virtual void tra_complete() override;
|
||||
virtual void rcv_complete() override;
|
||||
|
||||
inline void tx_send_byte(uint8_t val);
|
||||
int m_channel_num;
|
||||
vrender0soc_device *m_parent;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(VRENDER0_UART, vr0uart_device)
|
||||
|
||||
|
||||
class vrender0soc_device : public device_t
|
||||
{
|
||||
@ -33,15 +96,19 @@ public:
|
||||
vrender0soc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void regs_map(address_map &map);
|
||||
void audiovideo_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)); }
|
||||
void set_external_vclk(const uint32_t vclk) { m_ext_vclk = vclk; }
|
||||
void set_external_vclk(const XTAL vclk) { m_ext_vclk = vclk.value(); }
|
||||
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; }
|
||||
|
||||
bool irq_pending() { return m_intst; }
|
||||
void write_line_tx(int port, uint8_t value);
|
||||
template <int Port> auto tx_callback() { return write_tx[Port].bind(); }
|
||||
template <int Port> DECLARE_WRITE_LINE_MEMBER(rx_w) { m_uart[Port]->rx_w((uint8_t)state); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
//virtual void device_validity_check(validity_checker &valid) const override;
|
||||
@ -51,12 +118,22 @@ protected:
|
||||
|
||||
private:
|
||||
required_device <se3208_device> m_host_cpu;
|
||||
required_device <screen_device> m_host_screen;
|
||||
required_device <screen_device> m_screen;
|
||||
required_device <palette_device> m_palette;
|
||||
required_device <vr0video_device> m_vr0vid;
|
||||
required_device <vr0sound_device> m_vr0snd;
|
||||
required_device <speaker_device> m_lspeaker;
|
||||
required_device <speaker_device> m_rspeaker;
|
||||
required_device_array <vr0uart_device, 2> m_uart;
|
||||
required_shared_ptr <uint32_t> m_crtcregs;
|
||||
devcb_write_line m_idleskip_cb;
|
||||
|
||||
uint16_t *m_textureram;
|
||||
uint16_t *m_frameram;
|
||||
|
||||
address_space *m_host_space;
|
||||
// To move into SoC own device
|
||||
uint32_t m_ext_vclk;
|
||||
|
||||
devcb_write_line write_tx[2];
|
||||
|
||||
// INTC
|
||||
uint32_t m_inten;
|
||||
DECLARE_READ32_MEMBER(inten_r);
|
||||
@ -108,6 +185,21 @@ private:
|
||||
// Misc
|
||||
DECLARE_READ32_MEMBER( sysid_r );
|
||||
DECLARE_READ32_MEMBER( cfgr_r );
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
|
||||
DECLARE_READ16_MEMBER( textureram_r );
|
||||
DECLARE_WRITE16_MEMBER( textureram_w );
|
||||
DECLARE_READ16_MEMBER( frameram_r );
|
||||
DECLARE_WRITE16_MEMBER( frameram_w );
|
||||
|
||||
// Hacks
|
||||
#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
|
||||
};
|
||||
|
||||
|
||||
|
@ -149,10 +149,10 @@ WRITE32_MEMBER(vr0sound_device::vr0_snd_write)
|
||||
}
|
||||
|
||||
|
||||
void vr0sound_device::set_areas(uint32_t *texture, uint32_t *frame)
|
||||
void vr0sound_device::set_areas(uint16_t *texture, uint16_t *frame)
|
||||
{
|
||||
m_TexBase=texture;
|
||||
m_FBBase=frame;
|
||||
m_TexBase=(int16_t *)texture;
|
||||
m_FBBase=(int16_t *)frame;
|
||||
}
|
||||
|
||||
|
||||
@ -170,9 +170,9 @@ void vr0sound_device::VR0_RenderAudio(int nsamples, stream_sample_t *l, stream_s
|
||||
|
||||
|
||||
if(CT1&0x20)
|
||||
SAMPLES=(int16_t *)m_TexBase;
|
||||
SAMPLES = m_TexBase;
|
||||
else
|
||||
SAMPLES=(int16_t *)m_FBBase;
|
||||
SAMPLES = m_FBBase;
|
||||
|
||||
if(CLK)
|
||||
div=((30<<16)|0x8000)/(CLK+1);
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
DECLARE_READ32_MEMBER( vr0_snd_read );
|
||||
DECLARE_WRITE32_MEMBER( vr0_snd_write );
|
||||
|
||||
void set_areas(uint32_t *texture, uint32_t *frame);
|
||||
void set_areas(uint16_t *texture, uint16_t *frame);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -32,8 +32,8 @@ protected:
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
private:
|
||||
uint32_t *m_TexBase;
|
||||
uint32_t *m_FBBase;
|
||||
int16_t *m_TexBase;
|
||||
int16_t *m_FBBase;
|
||||
uint32_t m_SOUNDREGS[0x10000/4];
|
||||
sound_stream *m_stream;
|
||||
|
||||
|
@ -7,12 +7,17 @@
|
||||
driver by Angelo Salese, based off original crystal.cpp by ElSemi
|
||||
|
||||
TODO:
|
||||
- Dies at POST with a SPU error;
|
||||
- Hooking up serflash_device instead of the custom implementation here
|
||||
- Dies at POST with a SPU error,
|
||||
supposedly it should print a "running system." instead of "Ok" at the
|
||||
end of the POST routine.
|
||||
Update: it tries to load a "sdata.bin" file, which is nowhere to be found in the dump.
|
||||
Considering also that first $20000 block is empty and loading the flash linearly gives
|
||||
the reference memory size but then game isn't detected at all.
|
||||
- Hooking up nand_device instead of the custom implementation here
|
||||
makes the game to print having all memory available and no game
|
||||
detected, fun
|
||||
- I2C RTC interface should be correct but still doesn't work, sending
|
||||
unrecognized slave address 0x30 (device type might be wrong as well)
|
||||
unrecognized slave address 0x30 (device type might be wrong as well)
|
||||
|
||||
Notes:
|
||||
- Game enables UART1 receive irq, if that irq is enable it just prints
|
||||
@ -30,31 +35,21 @@
|
||||
#include "machine/pcf8583.h"
|
||||
#include "machine/nvram.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_rtc(*this, "rtc"),
|
||||
m_screen(*this, "screen")
|
||||
m_rtc(*this, "rtc")
|
||||
{ }
|
||||
|
||||
|
||||
@ -64,23 +59,12 @@ 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<pcf8583_device> m_rtc;
|
||||
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
|
||||
|
||||
uint8_t m_FlashCmd;
|
||||
uint8_t m_FlashPrevCommand;
|
||||
@ -96,8 +80,6 @@ private:
|
||||
|
||||
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
|
||||
@ -111,30 +93,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
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();
|
||||
@ -142,7 +100,8 @@ IRQ_CALLBACK_MEMBER(crospuzl_state::icallback)
|
||||
|
||||
READ32_MEMBER(crospuzl_state::PIOedat_r)
|
||||
{
|
||||
// TODO: this doesn't work with regular serflash_device
|
||||
// TODO: this needs fixing in serflash_device
|
||||
// (has a laconic constant for the ready line)
|
||||
return (m_rtc->sda_r() << 19)
|
||||
| (machine().rand() & 0x04000000); // serial ready line
|
||||
}
|
||||
@ -161,7 +120,7 @@ READ8_MEMBER(crospuzl_state::FlashCmd_r)
|
||||
// and the standard claims that the ID is 7 + 1 parity bit.
|
||||
// TODO: Retrieve ID from actual HW service mode screen.
|
||||
// const uint8_t id[5] = { 0xee, 0x81, 0x00, 0x15, 0x00 };
|
||||
const uint8_t id[5] = { 0xec, 0xf1, 0x00, 0x15, 0x00 };
|
||||
const uint8_t id[5] = { 0xec, 0xf1, 0x00, 0x95, 0x40 };
|
||||
uint8_t res = id[m_FlashAddr];
|
||||
m_FlashAddr ++;
|
||||
m_FlashAddr %= 5;
|
||||
@ -246,41 +205,14 @@ void crospuzl_state::crospuzl_mem(address_map &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));
|
||||
map(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
|
||||
// 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));
|
||||
@ -293,9 +225,6 @@ void crospuzl_state::machine_reset()
|
||||
m_FlashAddr = 0;
|
||||
m_FlashShift = 0;
|
||||
m_FlashPrevCommand = 0xff;
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_FlipCntRead = 0;
|
||||
#endif
|
||||
m_ddr = 0xffffffff;
|
||||
}
|
||||
|
||||
@ -433,49 +362,31 @@ INPUT_PORTS_END
|
||||
|
||||
void crospuzl_state::crospuzl(machine_config &config)
|
||||
{
|
||||
SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
|
||||
SE3208(config, m_maincpu, 14318180 * 3); // FIXME: 72 MHz-ish
|
||||
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);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3); // FIXME: 72 MHz-ish
|
||||
m_vr0soc->set_host_cpu_tag(m_maincpu);
|
||||
m_vr0soc->set_host_screen_tag(m_screen);
|
||||
m_vr0soc->set_external_vclk(14318180 * 2); // Unknown clock, should output ~70 Hz?
|
||||
|
||||
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);
|
||||
// ROM strings have references to a K9FXX08 device
|
||||
// TODO: use this device, in machine/smartmed.h (has issues with is_busy() emulation)
|
||||
// NAND(config, m_nand, 0);
|
||||
// m_nand->set_nand_type(nand_device::chip::K9F1G08U0B); // TODO: exact flavor
|
||||
|
||||
PCF8583(config, m_rtc, 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_REGION( 0x8400010, "flash", ROMREGION_ERASE00 ) // NAND Flash
|
||||
ROM_LOAD("k9f1g08u0a.riser", 0x00000, 0x8400010, BAD_DUMP CRC(7f3c88c3) SHA1(db3169a7b4caab754e9d911998a2ece13c65ce5b) )
|
||||
ROM_COPY( "flash", 0x20000, 0x00000, 0x20000 )
|
||||
ROM_END
|
||||
|
||||
GAME( 200?, crospuzl, 0, crospuzl, crospuzl, crospuzl_state, empty_init, ROT0, "<unknown>", "Cross Puzzle", MACHINE_NOT_WORKING )
|
||||
|
@ -141,33 +141,21 @@ Notes:
|
||||
#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 crystal_state : public driver_device
|
||||
{
|
||||
public:
|
||||
crystal_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_reset_patch(*this, "reset_patch"),
|
||||
m_flash(*this, "flash"),
|
||||
m_mainbank(*this, "mainbank"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_vr0soc(*this, "vr0soc"),
|
||||
m_vr0vid(*this, "vr0vid"),
|
||||
m_vr0snd(*this, "vr0snd"),
|
||||
m_ds1302(*this, "rtc"),
|
||||
m_screen(*this, "screen"),
|
||||
m_eeprom(*this, "eeprom")
|
||||
{ }
|
||||
|
||||
@ -184,8 +172,6 @@ public:
|
||||
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_shared_ptr<uint32_t> m_reset_patch;
|
||||
optional_region_ptr<uint32_t> m_flash;
|
||||
|
||||
@ -194,18 +180,9 @@ private:
|
||||
/* 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;
|
||||
@ -219,8 +196,6 @@ private:
|
||||
|
||||
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 PatchReset();
|
||||
void crystal_mem(address_map &map);
|
||||
|
||||
@ -231,51 +206,11 @@ private:
|
||||
uint32_t m_PIO;
|
||||
};
|
||||
|
||||
uint32_t crystal_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(crystal_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(crystal_state::icallback)
|
||||
{
|
||||
return m_vr0soc->irq_callback();
|
||||
}
|
||||
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
WRITE_LINE_MEMBER(crystal_state::idle_skip_resume_w)
|
||||
{
|
||||
m_FlipCntRead = 0;
|
||||
m_maincpu->resume(SUSPEND_REASON_SPIN);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(crystal_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
|
||||
|
||||
READ32_MEMBER(crystal_state::system_input_r)
|
||||
{
|
||||
return ( ioport("SYSTEM")->read() << 16) | (ioport("DSW")->read()) | 0xff00ff00;
|
||||
@ -368,10 +303,7 @@ void crystal_state::crystal_mem(address_map &map)
|
||||
// mirror is accessed by donghaer on later levels
|
||||
map(0x02000000, 0x027fffff).mirror(0x00800000).ram().share("workram");
|
||||
|
||||
map(0x03000000, 0x0300ffff).m(m_vr0vid, FUNC(vr0video_device::regs_map));
|
||||
map(0x03800000, 0x03ffffff).ram().share("textureram");
|
||||
map(0x04000000, 0x047fffff).ram().share("frameram");
|
||||
map(0x04800000, 0x04800fff).rw(m_vr0snd, FUNC(vr0sound_device::vr0_snd_read), FUNC(vr0sound_device::vr0_snd_write));
|
||||
map(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
|
||||
map(0x05000000, 0x05ffffff).bankr("mainbank");
|
||||
map(0x05000000, 0x05000003).rw(FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
|
||||
@ -433,9 +365,6 @@ loop:
|
||||
|
||||
void crystal_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);
|
||||
|
||||
PatchReset();
|
||||
|
||||
if (m_mainbank)
|
||||
@ -452,10 +381,6 @@ void crystal_state::machine_start()
|
||||
m_mainbank->configure_entry(i, dummy_region);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
save_item(NAME(m_FlipCntRead));
|
||||
#endif
|
||||
}
|
||||
|
||||
void crystal_state::machine_reset()
|
||||
@ -464,10 +389,6 @@ void crystal_state::machine_reset()
|
||||
m_mainbank->set_entry(m_Bank);
|
||||
m_FlashCmd = 0xff;
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_FlipCntRead = 0;
|
||||
#endif
|
||||
|
||||
PatchReset();
|
||||
}
|
||||
|
||||
@ -636,33 +557,10 @@ void crystal_state::crystal(machine_config &config)
|
||||
|
||||
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(crystal_state::screen_update));
|
||||
m_screen->screen_vblank().set(FUNC(crystal_state::screen_vblank));
|
||||
m_screen->set_palette("palette");
|
||||
|
||||
VRENDER0_SOC(config, m_vr0soc, 0);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3);
|
||||
m_vr0soc->set_host_cpu_tag(m_maincpu);
|
||||
m_vr0soc->set_host_screen_tag(m_screen);
|
||||
|
||||
VIDEO_VRENDER0(config, m_vr0vid, 14318180, m_maincpu);
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_vr0soc->idleskip_cb().set(FUNC(crystal_state::idle_skip_resume_w));
|
||||
m_vr0vid->idleskip_cb().set(FUNC(crystal_state::idle_skip_speedup_w));
|
||||
#endif
|
||||
|
||||
PALETTE(config, "palette", palette_device::RGB_565);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,15 +59,10 @@ 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")
|
||||
m_vr0soc(*this, "vr0soc")
|
||||
{ }
|
||||
|
||||
|
||||
@ -78,78 +73,25 @@ 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);
|
||||
@ -162,10 +104,7 @@ void ddz_state::ddz_mem(address_map &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));
|
||||
map(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( ddz )
|
||||
@ -181,19 +120,12 @@ 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)
|
||||
@ -202,31 +134,8 @@ void ddz_state::ddz(machine_config &config)
|
||||
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);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3);
|
||||
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 )
|
||||
|
@ -7,11 +7,13 @@
|
||||
driver by Angelo Salese, based off original crystal.cpp by ElSemi
|
||||
|
||||
TODO:
|
||||
- HY04 protection (controls tile RNG at very least)
|
||||
- HY04 protection (controls tile RNG, 8bpp colors, a few program flow bits)
|
||||
- 8bpp colors are washed, data from flash ROMs is XORed with contents
|
||||
of NVRAM area 0x14000700-80f, might be shared with HY04 as well.
|
||||
of NVRAM area 0x1400070b-80f in menghong, might be shared with
|
||||
HY04 as well.
|
||||
- EEPROM hookup;
|
||||
- extract password code when entering test mode in-game;
|
||||
- extract password code when entering test mode in-game (assuming the
|
||||
0x485 workaround isn't enough);
|
||||
|
||||
=============================================================================
|
||||
|
||||
@ -71,60 +73,44 @@ Red PCB, very similar to crzyddz2
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/vrender0.h"
|
||||
#include "sound/vrender0.h"
|
||||
#include "video/vrender0.h"
|
||||
#include "machine/timer.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_nvram(*this, "nvram"),
|
||||
m_ds1302(*this, "rtc"),
|
||||
m_screen(*this, "screen"),
|
||||
m_eeprom(*this, "eeprom")
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_prot_data(*this, "pic_data")
|
||||
{ }
|
||||
|
||||
|
||||
void crzyddz2(machine_config &config);
|
||||
void menghong(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<nvram_device> m_nvram;
|
||||
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
|
||||
required_region_ptr <uint8_t> m_prot_data;
|
||||
|
||||
uint32_t m_Bank;
|
||||
uint32_t m_maxbank;
|
||||
@ -140,46 +126,25 @@ private:
|
||||
|
||||
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 menghong_mem(address_map &map);
|
||||
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;
|
||||
|
||||
DECLARE_READ8_MEMBER(menghong_shared_r);
|
||||
DECLARE_WRITE8_MEMBER(menghong_shared_w);
|
||||
DECLARE_READ8_MEMBER(crzyddz2_shared_r);
|
||||
DECLARE_WRITE8_MEMBER(crzyddz2_shared_w);
|
||||
uint8_t *m_sharedram;
|
||||
};
|
||||
|
||||
|
||||
|
||||
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();
|
||||
@ -223,6 +188,73 @@ WRITE32_MEMBER(menghong_state::FlashCmd_w)
|
||||
// Crazy Dou Di Zhu II
|
||||
// To do: HY04 (pic?) protection, 93C46 hookup
|
||||
|
||||
READ8_MEMBER(menghong_state::menghong_shared_r)
|
||||
{
|
||||
return m_sharedram[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(menghong_state::menghong_shared_w)
|
||||
{
|
||||
m_sharedram[offset] = data;
|
||||
|
||||
if (offset == 0x2a0)
|
||||
{
|
||||
if (data == 0x09)
|
||||
{
|
||||
// enables game settings by pressing start on password screen
|
||||
m_sharedram[0x485] = 0x02;
|
||||
|
||||
// start at 0x140071b, up to 0x806, rolls back at 0x70c
|
||||
// we conveniently use an handcrafted ROM here, created by guessing colors from
|
||||
// transparencies and shading.
|
||||
// This will be useful for comparison when the actual PIC data will be extracted.
|
||||
for (int i=0;i<0x100;i++)
|
||||
m_sharedram[i+0x70c] = m_prot_data[i];
|
||||
|
||||
// MCU also has a part in providing RNG
|
||||
// hold service1 while selecting makes the user select "a set" (location in NVRAM tbd)
|
||||
// 0x14005ca player 1 tiles
|
||||
// 0x14005d9 player 1 discard pond
|
||||
// 0x14005f9 available tiles
|
||||
// 0x14005a5 cpu tiles
|
||||
// 0x14005b4 cpu discard pond
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(menghong_state::crzyddz2_shared_r)
|
||||
{
|
||||
return m_sharedram[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(menghong_state::crzyddz2_shared_w)
|
||||
{
|
||||
m_sharedram[offset] = data;
|
||||
|
||||
// State machine is unconfirmed
|
||||
if (offset == 0x7e3)
|
||||
{
|
||||
switch(data)
|
||||
{
|
||||
case 0x00:
|
||||
m_sharedram[0x650] = 0x00; // prints 93c46 error otherwise
|
||||
m_sharedram[0x651] = 0x03; // PC=2012188
|
||||
break;
|
||||
case 0xbb:
|
||||
// this actually affects color again, game checksums the NVRAM contents
|
||||
// at PC=0x2011f9a, expecting a value of 0x7ebe otherwise locks up
|
||||
// after Sealy logo. Every single value is added to the routine and left
|
||||
// shifted by 1 (including the two values above)
|
||||
for(int i=0;i<0x3f;i++)
|
||||
m_sharedram[i+0x652] = 0xff;
|
||||
m_sharedram[0x691] = 0x9b;
|
||||
break;
|
||||
// additional locking protection is also applied with RNG feature
|
||||
// PC=0x2036756 tight loops if R1=0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(menghong_state::PIOldat_r)
|
||||
{
|
||||
return m_PIO;
|
||||
@ -279,14 +311,16 @@ crzyddz2 in out
|
||||
return 0xffffff00 | data | m_crzyddz2_prot;
|
||||
}
|
||||
|
||||
void menghong_state::crzyddz2_mem(address_map &map)
|
||||
void menghong_state::menghong_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(0x01400000, 0x0140ffff).ram().share("nvram");
|
||||
map(0x01400000, 0x0140ffff).rw(FUNC(menghong_state::menghong_shared_r), FUNC(menghong_state::menghong_shared_w));
|
||||
map(0x01500000, 0x01500003).portr("P1_P2");
|
||||
map(0x01500004, 0x01500007).r(FUNC(menghong_state::crzyddz2_key_r));
|
||||
map(0x01500008, 0x0150000b).portr("SYSTEM");
|
||||
|
||||
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));
|
||||
@ -294,36 +328,22 @@ void menghong_state::crzyddz2_mem(address_map &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));
|
||||
map(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
|
||||
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)
|
||||
void menghong_state::crzyddz2_mem(address_map &map)
|
||||
{
|
||||
m_FlipCntRead = 0;
|
||||
m_maincpu->resume(SUSPEND_REASON_SPIN);
|
||||
menghong_mem(map);
|
||||
map(0x01400000, 0x0140ffff).rw(FUNC(menghong_state::crzyddz2_shared_r), FUNC(menghong_state::crzyddz2_shared_w));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
m_sharedram = auto_alloc_array_clear(machine(), uint8_t, 0x10000);
|
||||
|
||||
if (m_mainbank)
|
||||
{
|
||||
m_maxbank = (m_flash) ? m_flash.bytes() / 0x1000000 : 0;
|
||||
@ -339,11 +359,6 @@ void menghong_state::machine_start()
|
||||
}
|
||||
}
|
||||
|
||||
#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));
|
||||
@ -355,10 +370,6 @@ void menghong_state::machine_reset()
|
||||
m_mainbank->set_entry(m_Bank);
|
||||
m_FlashCmd = 0xff;
|
||||
|
||||
#ifdef IDLE_LOOP_SPEEDUP
|
||||
m_FlipCntRead = 0;
|
||||
#endif
|
||||
|
||||
m_crzyddz2_prot = 0x00;
|
||||
}
|
||||
|
||||
@ -374,14 +385,42 @@ static INPUT_PORTS_START(crzyddz2)
|
||||
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( 0x00010000, IP_ACTIVE_LOW, IPT_START1 ) // start (secret code screen)
|
||||
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Operator Mode")
|
||||
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE ) // .. 1 (secret code screen / service mode)
|
||||
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // not service mode
|
||||
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Clear RAM")
|
||||
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("SYSTEM")
|
||||
PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_DIPNAME( 0x010000, 0x010000, "DSWA" )
|
||||
PORT_DIPSETTING( 0x010000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x020000, 0x020000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x020000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x040000, 0x040000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x040000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x080000, 0x080000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x080000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x100000, 0x100000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x100000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x200000, 0x200000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x200000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x400000, 0x400000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x400000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x800000, 0x800000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x800000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x000000, DEF_STR( On ) )
|
||||
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
// 1500004 (multiplexed by 1802005)
|
||||
@ -426,68 +465,58 @@ static INPUT_PORTS_START(crzyddz2)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) // small + D
|
||||
INPUT_PORTS_END
|
||||
|
||||
void menghong_state::crzyddz2(machine_config &config)
|
||||
void menghong_state::menghong(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_addrmap(AS_PROGRAM, &menghong_state::menghong_mem);
|
||||
m_maincpu->set_irq_acknowledge_callback(FUNC(menghong_state::icallback));
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
|
||||
// HY04 running at 8 MHz
|
||||
|
||||
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");
|
||||
// NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
|
||||
|
||||
VRENDER0_SOC(config, m_vr0soc, 0);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3);
|
||||
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);
|
||||
m_vr0soc->set_external_vclk(28636360); // Assumed from the only available XTal on PCB
|
||||
|
||||
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
|
||||
void menghong_state::crzyddz2(machine_config &config)
|
||||
{
|
||||
menghong(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &menghong_state::crzyddz2_mem);
|
||||
}
|
||||
|
||||
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_REGION( 0x0100, "pic_data", ROMREGION_ERASEFF )
|
||||
ROM_LOAD("hy04_fake_data.bin", 0, 0x100, BAD_DUMP CRC(73cc964b) SHA1(39d223c550e38c97135322e43ccabb70f04964b9) )
|
||||
ROM_END
|
||||
|
||||
GAME( 2004?,menghong, 0, crzyddz2, crzyddz2, menghong_state, empty_init, ROT0, "Sealy", "Meng Hong Lou", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
|
||||
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_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_REGION( 0x0100, "pic_data", ROMREGION_ERASEFF )
|
||||
ROM_END
|
||||
|
||||
|
||||
GAME( 2004?,menghong, 0, menghong, 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 )
|
||||
|
@ -8,7 +8,10 @@
|
||||
|
||||
TODO:
|
||||
- Compact Flash hookup;
|
||||
- Enables wavetable IRQ;
|
||||
- Requires timed based FIFO renderer, loops until both rear and front
|
||||
are equal.
|
||||
- Enables wavetable IRQ, even if so far no channel enables the submask;
|
||||
- Unemulated 93C86 EEPROM device;
|
||||
|
||||
=============================================================================
|
||||
|
||||
@ -127,15 +130,9 @@ GUN_xP are 6 pin gun connectors (pins 3-6 match the UNICO sytle guns):
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/vrender0.h"
|
||||
#include "sound/vrender0.h"
|
||||
#include "video/vrender0.h"
|
||||
#include "machine/ataintf.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define IDLE_LOOP_SPEEDUP
|
||||
|
||||
class psattack_state : public driver_device
|
||||
{
|
||||
@ -143,13 +140,9 @@ 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")
|
||||
m_ata(*this, "ata")
|
||||
{ }
|
||||
|
||||
|
||||
@ -160,75 +153,51 @@ 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
|
||||
required_device<ata_interface_device> m_ata;
|
||||
|
||||
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);
|
||||
|
||||
DECLARE_READ16_MEMBER(cfcard_data_r);
|
||||
DECLARE_READ8_MEMBER(cfcard_regs_r);
|
||||
DECLARE_WRITE8_MEMBER(cfcard_regs_w);
|
||||
DECLARE_WRITE32_MEMBER(output_w);
|
||||
};
|
||||
|
||||
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)
|
||||
// TODO: wrong, likely PIC protected too
|
||||
READ8_MEMBER( psattack_state::cfcard_regs_r )
|
||||
{
|
||||
m_FlipCntRead = 0;
|
||||
m_maincpu->resume(SUSPEND_REASON_SPIN);
|
||||
return m_ata->read_cs0(offset & 7, 0x000000ff);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(psattack_state::idle_skip_speedup_w)
|
||||
WRITE8_MEMBER( psattack_state::cfcard_regs_w )
|
||||
{
|
||||
m_FlipCntRead++;
|
||||
if (m_FlipCntRead >= 16 && m_vr0soc->irq_pending() == false && state == ASSERT_LINE)
|
||||
m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
|
||||
m_ata->write_cs0(offset & 7, 0x000000ff);
|
||||
}
|
||||
#endif
|
||||
|
||||
READ16_MEMBER( psattack_state::cfcard_data_r )
|
||||
{
|
||||
return m_ata->read_cs0(0, 0x0000ffff);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( psattack_state::output_w )
|
||||
{
|
||||
// suppress logging for now
|
||||
if (data)
|
||||
logerror("output_w: %08x & %08x\n",data,mem_mask);
|
||||
}
|
||||
|
||||
void psattack_state::psattack_mem(address_map &map)
|
||||
{
|
||||
@ -236,20 +205,21 @@ void psattack_state::psattack_mem(address_map &map)
|
||||
|
||||
// 0x1400c00, 0x1400c01 read cfcard memory (auto increment?)
|
||||
// 0x1402800, 0x1402807 read/write regs?
|
||||
// 0x1802410, 0x1802413 peripheral chip select for above
|
||||
map(0x01500000, 0x01500003).portr("IN0");
|
||||
// cf card interface
|
||||
map(0x01400c00, 0x01400c01).r(FUNC(psattack_state::cfcard_data_r));
|
||||
map(0x01402800, 0x01402807).rw(FUNC(psattack_state::cfcard_regs_r), FUNC(psattack_state::cfcard_regs_w));
|
||||
|
||||
map(0x01500000, 0x01500003).portr("IN0").w(FUNC(psattack_state::output_w));
|
||||
map(0x01500004, 0x01500007).portr("IN1");
|
||||
map(0x01500008, 0x0150000b).portr("IN2");
|
||||
//0x0150000c is prolly eeprom
|
||||
// 0x0150000c is prolly eeprom
|
||||
|
||||
map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
|
||||
// map(0x01802410, 0x01802413) peripheral chip select for cf?
|
||||
|
||||
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(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( psattack )
|
||||
@ -265,19 +235,12 @@ 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)
|
||||
@ -286,31 +249,13 @@ void psattack_state::psattack(machine_config &config)
|
||||
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");
|
||||
// PIC16C711
|
||||
|
||||
VRENDER0_SOC(config, m_vr0soc, 0);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3);
|
||||
m_vr0soc->set_host_cpu_tag(m_maincpu);
|
||||
m_vr0soc->set_host_screen_tag(m_screen);
|
||||
m_vr0soc->set_external_vclk(XTAL(25'175'000)); // assumed from the only available XTal on PCB
|
||||
|
||||
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);
|
||||
ATA_INTERFACE(config, m_ata).options(ata_devices, "hdd", nullptr, true);
|
||||
}
|
||||
|
||||
ROM_START( psattack )
|
||||
@ -321,8 +266,8 @@ ROM_START( psattack )
|
||||
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) )
|
||||
DISK_REGION( "ata:0:hdd:image" )
|
||||
DISK_IMAGE( "psattack", 0, SHA1(e99cd0dafc33ec13bf56061f81dc7c0a181594ee) )
|
||||
ROM_END
|
||||
|
||||
void psattack_state::init_psattack()
|
||||
|
@ -1,14 +1,17 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Angelo Salese
|
||||
// copyright-holders:Luca Elia, Angelo Salese
|
||||
/****************************************************************************
|
||||
|
||||
Trivia R Us (c) 2009 AGT
|
||||
|
||||
driver by Angelo Salese, based off original crystal.cpp by ElSemi
|
||||
original mods on this driver by Luca Elia
|
||||
|
||||
TODO:
|
||||
- touch panel;
|
||||
- RTC;
|
||||
- touch panel, according to service mode can be generic, atouch or 3M
|
||||
(microtouch?). It interfaces thru UART0 port;
|
||||
- RTC (unknown type);
|
||||
- Split romset or add a slot option supporting debug terminal mode;
|
||||
|
||||
=============================================================================
|
||||
|
||||
@ -16,36 +19,26 @@
|
||||
|
||||
#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 "machine/microtch.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")
|
||||
m_microtouch(*this, "microtouch")
|
||||
{ }
|
||||
|
||||
|
||||
@ -55,24 +48,13 @@ 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
|
||||
required_device<microtouch_device> m_microtouch;
|
||||
|
||||
uint32_t m_FlashCmd;
|
||||
uint32_t m_Bank;
|
||||
@ -86,8 +68,6 @@ private:
|
||||
|
||||
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
|
||||
@ -101,31 +81,6 @@ private:
|
||||
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();
|
||||
@ -138,26 +93,19 @@ WRITE32_MEMBER(trivrus_state::FlashCmd_w)
|
||||
|
||||
READ32_MEMBER(trivrus_state::PIOedat_r)
|
||||
{
|
||||
return m_ds1302->io_r() << 28;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -214,16 +162,19 @@ void trivrus_state::trivrus_mem(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x0007ffff).rom().nopw();
|
||||
|
||||
// map(0x01280000, 0x01280003).w(FUNC(trivrus_state::Banksw_w));
|
||||
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
|
||||
// reads occurs by SELECTING the given register on successive ODD addresses then reading at 0x01500011
|
||||
// bit 0 of 1500010 looks some kind of busy flag (game tight loops if on)
|
||||
// on write:
|
||||
// 0x01500010 = sec
|
||||
// 0x01500012 = min
|
||||
// 0x01500014 = hour
|
||||
// 0x01500016 = day
|
||||
// 0x01500018 = month
|
||||
// 0x0150001c = year - 2000
|
||||
// all regs are in BCD format
|
||||
map(0x01600000, 0x01607fff).ram().share("nvram");
|
||||
|
||||
map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map));
|
||||
@ -232,36 +183,15 @@ void trivrus_state::trivrus_mem(address_map &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));
|
||||
map(0x03000000, 0x04ffffff).m(m_vr0soc, FUNC(vrender0soc_device::audiovideo_map));
|
||||
|
||||
map(0x05000000, 0x05ffffff).bankr("mainbank");
|
||||
map(0x05000000, 0x05000003).rw(FUNC(trivrus_state::FlashCmd_r), FUNC(trivrus_state::FlashCmd_w));
|
||||
// 0x06000000 accessed during POST during above check then discarded, probably a debug left-over
|
||||
}
|
||||
|
||||
#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;
|
||||
@ -277,10 +207,6 @@ void trivrus_state::machine_start()
|
||||
}
|
||||
}
|
||||
|
||||
#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));
|
||||
@ -292,31 +218,27 @@ 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)
|
||||
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_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Up")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Left/True")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("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( 0x01, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("Enter/Exit")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON5 ) 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( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Right/False")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2) // with 1 impulse it misses often
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("IN3")
|
||||
@ -325,30 +247,30 @@ static INPUT_PORTS_START(trivrus)
|
||||
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( 0x20, IP_ACTIVE_LOW, IPT_BUTTON7 ) 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_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("IN5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) // Free Game
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Free Game Switch")
|
||||
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_SERVICE_NO_TOGGLE( 0x08, IP_ACTIVE_LOW ) PORT_NAME("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_DIPNAME( 0x01, 0x01, "Monitor Type" )
|
||||
PORT_DIPSETTING( 0x01, "VGA" )
|
||||
PORT_DIPSETTING( 0x00, "Normal" )
|
||||
PORT_DIPNAME( 0x02, 0x02, "UART Monitor Mode" ) // communicates via UART0 port to an unknown device (presumably a terminal, unemulated)
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // hangs at boot
|
||||
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 ) )
|
||||
@ -371,39 +293,19 @@ INPUT_PORTS_END
|
||||
|
||||
void trivrus_state::trivrus(machine_config &config)
|
||||
{
|
||||
SE3208(config, m_maincpu, 14318180 * 3); // TODO : different between each PCBs
|
||||
SE3208(config, m_maincpu, 14318180 * 3); // unknown clock
|
||||
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);
|
||||
VRENDER0_SOC(config, m_vr0soc, 14318180 * 3);
|
||||
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);
|
||||
m_vr0soc->set_external_vclk(28636360);
|
||||
m_vr0soc->tx_callback<0>().set(m_microtouch, FUNC(microtouch_device::rx));
|
||||
|
||||
// TODO: 3M from service mode, most likely wrong?
|
||||
MICROTOUCH(config, m_microtouch, 9600).stx().set(m_vr0soc, FUNC(vrender0soc_device::rx_w<0>));
|
||||
}
|
||||
|
||||
ROM_START( trivrus )
|
||||
|
@ -1,10 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:ElSemi
|
||||
#include "emu.h"
|
||||
#include "vrender0.h"
|
||||
|
||||
|
||||
/***********************************
|
||||
/*****************************************************************************************
|
||||
VRENDER ZERO
|
||||
VIDEO EMULATION By ElSemi
|
||||
|
||||
@ -16,8 +12,17 @@
|
||||
It supports alphablend with programmable factors per channel and for source and dest
|
||||
color.
|
||||
|
||||
************************************/
|
||||
TODO:
|
||||
- Dither Mode;
|
||||
- Draw select to Front buffer is untested, speculatively gonna be used for raster
|
||||
effects;
|
||||
- screen_update doesn't honor CRT Display Start registers,
|
||||
so far only psattack changes it on-the-fly, for unknown reasons;
|
||||
|
||||
*****************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "vrender0.h"
|
||||
|
||||
/*****************************************************************************
|
||||
DEVICE INTERFACE
|
||||
@ -28,7 +33,6 @@ DEFINE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device, "vr0video", "MagicEyes VRend
|
||||
vr0video_device::vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, VIDEO_VRENDER0, tag, owner, clock)
|
||||
, device_video_interface(mconfig, *this)
|
||||
, m_cpu(*this, finder_base::DUMMY_TAG)
|
||||
, m_idleskip_cb(*this)
|
||||
|
||||
{
|
||||
@ -158,9 +162,10 @@ void vr0video_device::device_start()
|
||||
save_item(NAME(m_dither_mode));
|
||||
}
|
||||
|
||||
void vr0video_device::set_areas(uint8_t *textureram, uint16_t *frameram)
|
||||
void vr0video_device::set_areas(uint16_t *textureram, uint16_t *frameram)
|
||||
{
|
||||
m_textureram = textureram;
|
||||
m_textureram = (uint8_t *)textureram;
|
||||
m_packetram = textureram;
|
||||
m_frameram = frameram;
|
||||
}
|
||||
|
||||
@ -172,6 +177,8 @@ void vr0video_device::device_reset()
|
||||
{
|
||||
memset(m_InternalPalette, 0, sizeof(m_InternalPalette));
|
||||
m_LastPalUpdate = 0xffffffff;
|
||||
|
||||
m_DisplayDest = m_DrawDest = m_frameram;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -495,22 +502,21 @@ static const _DrawTemplate DrawTile[]=
|
||||
TILENAME(16,1,2),
|
||||
};
|
||||
|
||||
#define Packet(i) space.read_word(PacketPtr + 2 * i)
|
||||
|
||||
//Returns true if the operation was a flip (sync or async)
|
||||
// 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)
|
||||
int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr)
|
||||
{
|
||||
// TODO: this need to be removed
|
||||
address_space &space = m_cpu->space(AS_PROGRAM);
|
||||
uint16_t *Packet = m_packetram;
|
||||
uint8_t *TEXTURE = m_textureram;
|
||||
|
||||
uint32_t Dx = Packet(1) & 0x3ff;
|
||||
uint32_t Dy = Packet(2) & 0x1ff;
|
||||
uint32_t Endx = Packet(3) & 0x3ff;
|
||||
uint32_t Endy = Packet(4) & 0x1ff;
|
||||
Packet += PacketPtr;
|
||||
|
||||
uint32_t Dx = Packet[1] & 0x3ff;
|
||||
uint32_t Dy = Packet[2] & 0x1ff;
|
||||
uint32_t Endx = Packet[3] & 0x3ff;
|
||||
uint32_t Endy = Packet[4] & 0x1ff;
|
||||
uint32_t Mode = 0;
|
||||
uint16_t Packet0 = Packet(0);
|
||||
uint16_t Packet0 = Packet[0];
|
||||
|
||||
if (Packet0 & 0x81) //Sync or ASync flip
|
||||
{
|
||||
@ -520,8 +526,8 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
|
||||
if (Packet0 & 0x200)
|
||||
{
|
||||
m_RenderState.Tx = Packet(5) | ((Packet(6) & 0x1f) << 16);
|
||||
m_RenderState.Ty = Packet(7) | ((Packet(8) & 0x1f) << 16);
|
||||
m_RenderState.Tx = Packet[5] | ((Packet[6] & 0x1f) << 16);
|
||||
m_RenderState.Ty = Packet[7] | ((Packet[8] & 0x1f) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -530,10 +536,10 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
}
|
||||
if (Packet0 & 0x400)
|
||||
{
|
||||
m_RenderState.Txdx = Packet(9) | ((Packet(10) & 0x1f) << 16);
|
||||
m_RenderState.Tydx = Packet(11) | ((Packet(12) & 0x1f) << 16);
|
||||
m_RenderState.Txdy = Packet(13) | ((Packet(14) & 0x1f) << 16);
|
||||
m_RenderState.Tydy = Packet(15) | ((Packet(16) & 0x1f) << 16);
|
||||
m_RenderState.Txdx = Packet[9] | ((Packet[10] & 0x1f) << 16);
|
||||
m_RenderState.Tydx = Packet[11] | ((Packet[12] & 0x1f) << 16);
|
||||
m_RenderState.Txdy = Packet[13] | ((Packet[14] & 0x1f) << 16);
|
||||
m_RenderState.Tydy = Packet[15] | ((Packet[16] & 0x1f) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -544,25 +550,25 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
}
|
||||
if (Packet0 & 0x800)
|
||||
{
|
||||
m_RenderState.SrcAlphaColor = Packet(17) | ((Packet(18) & 0xff) << 16);
|
||||
m_RenderState.SrcBlend = (Packet(18) >> 8) & 0x3f;
|
||||
m_RenderState.DstAlphaColor = Packet(19) | ((Packet(20) & 0xff) << 16);
|
||||
m_RenderState.DstBlend = (Packet(20) >> 8) & 0x3f;
|
||||
m_RenderState.SrcAlphaColor = Packet[17] | ((Packet[18] & 0xff) << 16);
|
||||
m_RenderState.SrcBlend = (Packet[18] >> 8) & 0x3f;
|
||||
m_RenderState.DstAlphaColor = Packet[19] | ((Packet[20] & 0xff) << 16);
|
||||
m_RenderState.DstBlend = (Packet[20] >> 8) & 0x3f;
|
||||
}
|
||||
if (Packet0 & 0x1000)
|
||||
m_RenderState.ShadeColor = Packet(21) | ((Packet(22) & 0xff) << 16);
|
||||
m_RenderState.ShadeColor = Packet[21] | ((Packet[22] & 0xff) << 16);
|
||||
if (Packet0 & 0x2000)
|
||||
m_RenderState.TransColor = Packet(23) | ((Packet(24) & 0xff) << 16);
|
||||
m_RenderState.TransColor = Packet[23] | ((Packet[24] & 0xff) << 16);
|
||||
if (Packet0 & 0x4000)
|
||||
{
|
||||
m_RenderState.TileOffset = Packet(25);
|
||||
m_RenderState.FontOffset = Packet(26);
|
||||
m_RenderState.PalOffset = Packet(27) >> 3;
|
||||
m_RenderState.PaletteBank = (Packet(28) >> 8) & 0xf;
|
||||
m_RenderState.TextureMode = Packet(28) & 0x1000;
|
||||
m_RenderState.PixelFormat = (Packet(28) >> 6) & 3;
|
||||
m_RenderState.Width = 8 << ((Packet(28) >> 0) & 0x7);
|
||||
m_RenderState.Height = 8 << ((Packet(28) >> 3) & 0x7);
|
||||
m_RenderState.TileOffset = Packet[25];
|
||||
m_RenderState.FontOffset = Packet[26];
|
||||
m_RenderState.PalOffset = Packet[27] >> 3;
|
||||
m_RenderState.PaletteBank = (Packet[28] >> 8) & 0xf;
|
||||
m_RenderState.TextureMode = Packet[28] & 0x1000;
|
||||
m_RenderState.PixelFormat = (Packet[28] >> 6) & 3;
|
||||
m_RenderState.Width = 8 << ((Packet[28] >> 0) & 0x7);
|
||||
m_RenderState.Height = 8 << ((Packet[28] >> 3) & 0x7);
|
||||
}
|
||||
|
||||
if (Packet0 & 0x40 && m_RenderState.PalOffset != m_LastPalUpdate)
|
||||
@ -574,6 +580,8 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
{
|
||||
uint32_t p = Pal[i];
|
||||
uint16_t v = RGB32TO16(p);
|
||||
// TODO: this is most likely an artifact of not emulating the dither modes,
|
||||
// and it's wrong anyway: topbladv gameplay fighters sports a slighty visible square shadow block.
|
||||
if ((v == Trans && p != m_RenderState.TransColor) || v == NOTRANSCOLOR) //Error due to conversion. caused transparent
|
||||
{
|
||||
if ((v & 0x1f) != 0x1f)
|
||||
@ -608,7 +616,7 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
Quad.w = 1 + Endx - Dx;
|
||||
Quad.h = 1 + Endy - Dy;
|
||||
|
||||
Quad.Dest = (uint16_t*) Dest;
|
||||
Quad.Dest = m_DrawDest;
|
||||
Quad.Dest = Quad.Dest + Dx + (Dy * Quad.Pitch);
|
||||
|
||||
Quad.Tx = m_RenderState.Tx;
|
||||
@ -647,6 +655,7 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
Quad.Pal = m_InternalPalette + (m_RenderState.PaletteBank * 16);
|
||||
else
|
||||
Quad.Pal = m_InternalPalette;
|
||||
|
||||
if (m_RenderState.TextureMode) //Tiled
|
||||
DrawTile[m_RenderState.PixelFormat + 4 * Mode](&Quad);
|
||||
else
|
||||
@ -658,14 +667,13 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vr0video_device::execute_drawing()
|
||||
void vr0video_device::execute_flipping()
|
||||
{
|
||||
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;
|
||||
|
||||
@ -680,11 +688,12 @@ void vr0video_device::execute_drawing()
|
||||
Back = (m_frameram + B1);
|
||||
}
|
||||
|
||||
DrawDest = ((m_draw_select == true) ? Front : Back);
|
||||
m_DrawDest = ((m_draw_select == true) ? Front : Back);
|
||||
m_DisplayDest = Front;
|
||||
|
||||
while ((m_queue_rear & 0x7ff) != (m_queue_front & 0x7ff))
|
||||
{
|
||||
DoFlip = vrender0_ProcessPacket(0x03800000 + m_queue_rear * 64, DrawDest);
|
||||
DoFlip = vrender0_ProcessPacket(m_queue_rear * 32);
|
||||
m_queue_rear ++;
|
||||
m_queue_rear &= 0x7ff;
|
||||
if (DoFlip)
|
||||
@ -703,20 +712,11 @@ void vr0video_device::execute_drawing()
|
||||
|
||||
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));
|
||||
std::copy_n(&m_DisplayDest[(y * 1024) + dx], width, &bitmap.pix16(y, dx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,17 +14,11 @@ class vr0video_device : public device_t,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
template <typename T> vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
|
||||
: vr0video_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
m_cpu.set_tag(std::forward<T>(cpu_tag));
|
||||
}
|
||||
|
||||
vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_areas(uint8_t *textureram, uint16_t *frameram);
|
||||
void set_areas(uint16_t *textureram, uint16_t *frameram);
|
||||
void regs_map(address_map &map);
|
||||
void execute_drawing();
|
||||
void execute_flipping();
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
auto idleskip_cb() { return m_idleskip_cb.bind(); }
|
||||
|
||||
@ -37,9 +31,8 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
int vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest);
|
||||
int vrender0_ProcessPacket(uint32_t PacketPtr);
|
||||
|
||||
required_device<cpu_device> m_cpu;
|
||||
devcb_write_line m_idleskip_cb;
|
||||
|
||||
struct RenderStateInfo
|
||||
@ -73,6 +66,7 @@ private:
|
||||
RenderStateInfo m_RenderState;
|
||||
|
||||
uint8_t *m_textureram;
|
||||
uint16_t *m_packetram;
|
||||
uint16_t *m_frameram;
|
||||
|
||||
DECLARE_READ16_MEMBER( cmd_queue_front_r );
|
||||
@ -83,18 +77,22 @@ private:
|
||||
|
||||
DECLARE_READ16_MEMBER( bank1_select_r );
|
||||
DECLARE_WRITE16_MEMBER( bank1_select_w );
|
||||
bool m_bank1_select;
|
||||
bool m_bank1_select; //!< Select framebuffer bank1 address
|
||||
|
||||
DECLARE_READ16_MEMBER( display_bank_r );
|
||||
uint8_t m_display_bank;
|
||||
uint8_t m_display_bank; //!< Current 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;
|
||||
bool m_draw_select; //!< If true, device draws to Front buffer instead of Back
|
||||
bool m_render_reset; //!< Reset pipeline FIFO
|
||||
bool m_render_start; //!< Enable pipeline processing
|
||||
uint8_t m_dither_mode; //!< applied on RGB888 to RGB565 conversions (00: 2x2, 01:4x4, 1x disable)
|
||||
uint8_t m_flip_count; //!< number of framebuffer "syncs" loaded in the parameter RAM,
|
||||
//!< a.k.a. how many full (vblank) buffers are ready for the device to parse.
|
||||
|
||||
uint16_t *m_DrawDest; //!< frameram pointer to draw buffer area
|
||||
uint16_t *m_DisplayDest; //!< frameram pointer to display buffer area
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device)
|
||||
|
Loading…
Reference in New Issue
Block a user