video/vrender0.cpp: More accurate VRender0 pipeline inner workings (#11057)

- Fixes donghaer split screen;
This commit is contained in:
Angelo Salese 2023-04-27 17:46:54 +02:00 committed by GitHub
parent 8d81957aa3
commit c4b3efa55c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 22 deletions

View File

@ -130,7 +130,8 @@ void vrender0soc_device::device_add_mconfig(machine_config &config)
m_screen->screen_vblank().set(FUNC(vrender0soc_device::screen_vblank));
m_screen->set_palette(m_palette);
VIDEO_VRENDER0(config, m_vr0vid, 14318180);
// runs at double speed wrt of the CPU clock
VIDEO_VRENDER0(config, m_vr0vid, DERIVED_CLOCK(2, 1));
PALETTE(config, m_palette, palette_device::RGB_565);
@ -713,8 +714,9 @@ WRITE_LINE_MEMBER(vrender0soc_device::screen_vblank)
if (state)
{
if (crt_active_vblank_irq() == true)
{
IntReq(24); //VRender0 VBlank
m_vr0vid->execute_flipping();
m_vr0vid->execute_flipping();
}
}
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:ElSemi
// copyright-holders:ElSemi, Angelo Salese
/*****************************************************************************************
VRENDER ZERO
VIDEO EMULATION By ElSemi
@ -160,6 +160,9 @@ void vr0video_device::device_start()
save_item(NAME(m_render_reset));
save_item(NAME(m_render_start));
save_item(NAME(m_dither_mode));
save_item(NAME(m_flip_sync));
m_pipeline_timer = timer_alloc(FUNC(vr0video_device::pipeline_cb), this);
}
void vr0video_device::set_areas(uint16_t *textureram, uint16_t *frameram)
@ -179,6 +182,8 @@ void vr0video_device::device_reset()
m_LastPalUpdate = 0xffffffff;
m_DisplayDest = m_DrawDest = m_frameram;
// 1100 objects per second at ~80 MHz
m_pipeline_timer->adjust(attotime::from_hz(this->clock() /1100), 0, attotime::from_hz(this->clock() / 1100));
}
/*****************************************************************************
@ -521,7 +526,7 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr)
if (Packet0 & 0x81) //Sync or ASync flip
{
m_LastPalUpdate = 0xffffffff; //Force update palette next frame
return 1;
return Packet0 & 0x81;
}
if (Packet0 & 0x200)
@ -667,6 +672,47 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr)
return 0;
}
TIMER_CALLBACK_MEMBER(vr0video_device::pipeline_cb)
{
if (m_render_start == false)
return;
// bail out if we encountered a flip sync command
// pipeline waits until it receives a vblank signal
if (m_flip_sync == true)
return;
if ((m_queue_rear & 0x7ff) == (m_queue_front & 0x7ff))
return;
int DoFlip = vrender0_ProcessPacket(m_queue_rear * 32);
m_queue_rear ++;
m_queue_rear &= 0x7ff;
if (DoFlip & 0x01)
m_flip_sync = true;
if (DoFlip & 0x80)
{
uint32_t B0 = 0x000000;
uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
uint16_t *Front, *Back;
if (m_display_bank & 1)
{
Front = (m_frameram + B1);
Back = (m_frameram + B0);
}
else
{
Front = (m_frameram + B0);
Back = (m_frameram + B1);
}
m_DrawDest = ((m_draw_select == true) ? Back : Front);
}
}
void vr0video_device::execute_flipping()
{
if (m_render_start == false)
@ -675,7 +721,6 @@ void vr0video_device::execute_flipping()
uint32_t B0 = 0x000000;
uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
uint16_t *Front, *Back;
int DoFlip = 0;
if (m_display_bank & 1)
{
@ -691,22 +736,11 @@ void vr0video_device::execute_flipping()
m_DrawDest = ((m_draw_select == true) ? Front : Back);
m_DisplayDest = Front;
while ((m_queue_rear & 0x7ff) != (m_queue_front & 0x7ff))
m_flip_sync = false;
if (m_flip_count)
{
DoFlip = vrender0_ProcessPacket(m_queue_rear * 32);
m_queue_rear ++;
m_queue_rear &= 0x7ff;
if (DoFlip)
break;
}
if (DoFlip)
{
if (m_flip_count)
{
m_flip_count--;
m_display_bank ^= 1;
}
m_flip_count--;
m_display_bank ^= 1;
}
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:ElSemi
// copyright-holders:ElSemi, Angelo Salese
#ifndef MAME_VIDEO_VRENDER0_H
#define MAME_VIDEO_VRENDER0_H
@ -93,6 +93,10 @@ private:
uint16_t *m_DrawDest; //!< frameram pointer to draw buffer area
uint16_t *m_DisplayDest; //!< frameram pointer to display buffer area
bool m_flip_sync = false;
emu_timer *m_pipeline_timer;
TIMER_CALLBACK_MEMBER(pipeline_cb);
};
DECLARE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device)

View File

@ -184,6 +184,7 @@ void psattack_state::cfcard_regs_w(offs_t offset, uint8_t data)
uint16_t psattack_state::cfcard_data_r()
{
// TODO: may not be it (pushes data into stack then never read it other than a comparison check from +0xfc)
return m_ata->cs0_r(0, 0x0000ffff);
}