diff options
Diffstat (limited to 'src/mame/video/vrender0.cpp')
-rw-r--r-- | src/mame/video/vrender0.cpp | 171 |
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; +} |