summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/vrender0.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/vrender0.cpp')
-rw-r--r--src/mame/video/vrender0.cpp171
1 files changed, 170 insertions, 1 deletions
diff --git a/src/mame/video/vrender0.cpp b/src/mame/video/vrender0.cpp
index dc937f1ff95..979c2996ad8 100644
--- a/src/mame/video/vrender0.cpp
+++ b/src/mame/video/vrender0.cpp
@@ -27,8 +27,92 @@ DEFINE_DEVICE_TYPE(VIDEO_VRENDER0, vr0video_device, "vr0video", "MagicEyes VRend
vr0video_device::vr0video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, VIDEO_VRENDER0, tag, owner, clock)
+ , device_video_interface(mconfig, *this)
, m_cpu(*this, finder_base::DUMMY_TAG)
+ , m_idleskip_cb(*this)
+
+{
+}
+
+void vr0video_device::regs_map(address_map &map)
+{
+ map(0x0080, 0x0081).rw(FUNC(vr0video_device::cmd_queue_front_r), FUNC(vr0video_device::cmd_queue_front_w));
+ map(0x0082, 0x0083).r(FUNC(vr0video_device::cmd_queue_rear_r));
+
+ map(0x008c, 0x008d).rw(FUNC(vr0video_device::render_control_r), FUNC(vr0video_device::render_control_w));
+ map(0x008e, 0x008f).r(FUNC(vr0video_device::display_bank_r));
+
+ map(0x0090, 0x0091).rw(FUNC(vr0video_device::bank1_select_r), FUNC(vr0video_device::bank1_select_w));
+ map(0x00a6, 0x00a7).rw(FUNC(vr0video_device::flip_count_r), FUNC(vr0video_device::flip_count_w));
+}
+
+READ16_MEMBER(vr0video_device::cmd_queue_front_r)
+{
+ return m_queue_front & 0x7ff;
+}
+
+WRITE16_MEMBER(vr0video_device::cmd_queue_front_w)
+{
+ COMBINE_DATA(&m_queue_front);
+}
+
+READ16_MEMBER(vr0video_device::cmd_queue_rear_r)
+{
+ return m_queue_rear & 0x7ff;
+}
+
+READ16_MEMBER(vr0video_device::render_control_r)
+{
+ return (m_draw_select<<7) | (m_render_reset<<3) | (m_render_start<<2) | (m_dither_mode);
+}
+
+WRITE16_MEMBER(vr0video_device::render_control_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ m_draw_select = BIT(data, 7);
+ m_render_reset = BIT(data, 3);
+ m_render_start = BIT(data, 2);
+ m_dither_mode = data & 3;
+
+ // initialize pipeline
+ // TODO: what happens if reset and start are both 1? Datasheet advises against it.
+ if (m_render_reset == true)
+ m_queue_front = m_queue_rear = 0;
+ }
+}
+
+READ16_MEMBER(vr0video_device::display_bank_r)
+{
+ return m_display_bank;
+}
+
+READ16_MEMBER(vr0video_device::bank1_select_r)
+{
+ return (m_bank1_select)<<15;
+}
+
+WRITE16_MEMBER(vr0video_device::bank1_select_w)
{
+ m_bank1_select = BIT(data,15);
+}
+
+READ16_MEMBER(vr0video_device::flip_count_r)
+{
+ m_idleskip_cb(m_flip_count != 0);
+ return m_flip_count;
+}
+
+WRITE16_MEMBER(vr0video_device::flip_count_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ int fc = (data) & 0xff;
+ if (fc == 1)
+ m_flip_count++;
+ else if (fc == 0)
+ m_flip_count = 0;
+ }
}
//-------------------------------------------------
@@ -37,6 +121,8 @@ vr0video_device::vr0video_device(const machine_config &mconfig, const char *tag,
void vr0video_device::device_start()
{
+ m_idleskip_cb.resolve_safe();
+
save_item(NAME(m_InternalPalette));
save_item(NAME(m_LastPalUpdate));
@@ -60,6 +146,22 @@ void vr0video_device::device_start()
save_item(NAME(m_RenderState.PixelFormat));
save_item(NAME(m_RenderState.Width));
save_item(NAME(m_RenderState.Height));
+
+ save_item(NAME(m_flip_count));
+ save_item(NAME(m_queue_rear));
+ save_item(NAME(m_queue_front));
+ save_item(NAME(m_bank1_select));
+ save_item(NAME(m_display_bank));
+ save_item(NAME(m_draw_select));
+ save_item(NAME(m_render_reset));
+ save_item(NAME(m_render_start));
+ save_item(NAME(m_dither_mode));
+}
+
+void vr0video_device::set_areas(uint8_t *textureram, uint16_t *frameram)
+{
+ m_textureram = textureram;
+ m_frameram = frameram;
}
//-------------------------------------------------
@@ -396,9 +498,13 @@ static const _DrawTemplate DrawTile[]=
#define Packet(i) space.read_word(PacketPtr + 2 * i)
//Returns true if the operation was a flip (sync or async)
-int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest, uint8_t *TEXTURE)
+// TODO: async loading actually doesn't stop rendering but just flips the render bank
+int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest)
{
+ // TODO: this need to be removed
address_space &space = m_cpu->space(AS_PROGRAM);
+ uint8_t *TEXTURE = m_textureram;
+
uint32_t Dx = Packet(1) & 0x3ff;
uint32_t Dy = Packet(2) & 0x1ff;
uint32_t Endx = Packet(3) & 0x3ff;
@@ -551,3 +657,66 @@ int vr0video_device::vrender0_ProcessPacket(uint32_t PacketPtr, uint16_t *Dest,
}
return 0;
}
+
+void vr0video_device::execute_drawing()
+{
+ if (m_render_start == false)
+ return;
+
+ uint32_t B0 = 0x000000;
+ uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
+ uint16_t *DrawDest;
+ uint16_t *Front, *Back;
+ int DoFlip = 0;
+
+ if (m_display_bank & 1)
+ {
+ Front = (m_frameram + B1);
+ Back = (m_frameram + B0);
+ }
+ else
+ {
+ Front = (m_frameram + B0);
+ Back = (m_frameram + B1);
+ }
+
+ DrawDest = ((m_draw_select == true) ? Front : Back);
+
+ while ((m_queue_rear & 0x7ff) != (m_queue_front & 0x7ff))
+ {
+ DoFlip = vrender0_ProcessPacket(0x03800000 + m_queue_rear * 64, DrawDest);
+ m_queue_rear ++;
+ m_queue_rear &= 0x7ff;
+ if (DoFlip)
+ break;
+ }
+
+ if (DoFlip)
+ {
+ if (m_flip_count)
+ {
+ m_flip_count--;
+ m_display_bank ^= 1;
+ }
+ }
+}
+
+uint32_t vr0video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint16_t *Visible;
+ const uint32_t width = cliprect.width();
+
+ uint32_t B0 = 0x000000;
+ uint32_t B1 = (m_bank1_select == true ? 0x400000 : 0x100000)/2;
+
+ if (m_display_bank & 1)
+ Visible = (m_frameram + B1);
+ else
+ Visible = (m_frameram + B0);
+
+ uint32_t const dx = cliprect.left();
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
+ std::copy_n(&Visible[(y * 1024) + dx], width, &bitmap.pix16(y, dx));
+
+ return 0;
+}