summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/sed1356.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/sed1356.cpp')
-rw-r--r--src/devices/video/sed1356.cpp187
1 files changed, 179 insertions, 8 deletions
diff --git a/src/devices/video/sed1356.cpp b/src/devices/video/sed1356.cpp
index ffa63122981..e27eae12c78 100644
--- a/src/devices/video/sed1356.cpp
+++ b/src/devices/video/sed1356.cpp
@@ -1046,22 +1046,174 @@ void sed1356_device::bitblt_solid_fill()
}
}
+uint16_t sed1356_device::bitblt_rop(const uint8_t rop, const uint16_t s, const uint16_t d)
+{
+ switch (rop & 0x0f)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return ~(s | d);
+ case 2:
+ return ~s & d;
+ case 3:
+ return ~s;
+ case 4:
+ return s | ~d;
+ case 5:
+ return ~d;
+ case 6:
+ return s ^d;
+ case 7:
+ return ~s | ~d;
+ case 8:
+ return s & d;
+ case 9:
+ return ~(s ^ d);
+ case 10:
+ return d;
+ case 11:
+ return ~s | d;
+ case 12:
+ return s;
+ case 13:
+ return s | ~d;
+ case 14:
+ return s | d;
+ case 15:
+ return 0xffff;
+ }
+ return 0;
+}
+
+void sed1356_device::bitblt_async_advance(uint32_t &addr)
+{
+ m_bitblt_x++;
+ if (m_bitblt_x > m_bitblt_width)
+ {
+ m_bitblt_x = 0;
+ m_bitblt_y++;
+ if (!BIT(m_bitblt_ctrl[0], BBCTRL0_DSTLIN_BIT))
+ {
+ addr -= (m_bitblt_width << 1);
+ addr += (m_bitblt_mem_offset << 1);
+ }
+ if (m_bitblt_y > m_bitblt_height)
+ {
+ m_bitblt_ctrl[0] &= ~(1 << BBCTRL0_ACTIVE_BIT);
+ m_bitblt_ctrl[0] &= ~(1 << BBCTRL0_ANY_BIT);
+ }
+ }
+ else
+ {
+ addr += 2;
+ }
+}
+
+void sed1356_device::bitblt_write_continue(const uint16_t s)
+{
+ uint16_t *dstp = (uint16_t*)&m_vram[m_bitblt_curr_dst_addr >> 2];
+ if (m_bitblt_curr_dst_addr & 2)
+ dstp++;
+
+ *dstp = bitblt_rop(m_bitblt_rop, s, *dstp);
+
+ bitblt_async_advance(m_bitblt_curr_dst_addr);
+}
+
+void sed1356_device::bitblt_write()
+{
+ m_bitblt_ctrl[0] |= (1 << BBCTRL0_ACTIVE_BIT);
+ m_bitblt_x = 0;
+ m_bitblt_y = 0;
+ m_bitblt_curr_dst_addr = m_bitblt_dst_addr;
+}
+
+uint16_t sed1356_device::bitblt_read_continue()
+{
+ const uint16_t *srcp = (uint16_t*)&m_vram[m_bitblt_curr_src_addr >> 2];
+ if (m_bitblt_curr_src_addr & 2)
+ srcp++;
+
+ const uint16_t data = *srcp;
+
+ bitblt_async_advance(m_bitblt_curr_src_addr);
+
+ return data;
+}
+
+void sed1356_device::bitblt_read()
+{
+ m_bitblt_ctrl[0] |= (1 << BBCTRL0_ACTIVE_BIT);
+ m_bitblt_ctrl[0] |= (1 << BBCTRL0_ANY_BIT);
+ m_bitblt_x = 0;
+ m_bitblt_y = 0;
+ m_bitblt_curr_src_addr = m_bitblt_src_addr;
+}
+
+template <bool SrcLinear, bool DstLinear>
+void sed1356_device::bitblt_move_negative()
+{
+ uint16_t *srcp = (uint16_t*)&m_vram[m_bitblt_src_addr >> 2];
+ if (m_bitblt_src_addr & 2)
+ srcp++;
+
+ uint16_t *dstp = (uint16_t*)&m_vram[m_bitblt_dst_addr >> 2];
+ if (m_bitblt_dst_addr & 2)
+ dstp++;
+
+ for (int32_t y = (int32_t)m_bitblt_height; y >= 0; y--)
+ {
+ for (int32_t x = (int32_t)m_bitblt_width; x >= 0; x--)
+ {
+ const uint16_t s = (SrcLinear ? *srcp : srcp[x]);
+ const uint16_t d = (DstLinear ? *dstp : dstp[x]);
+
+ *dstp = bitblt_rop(m_bitblt_rop, s, d);
+
+ if (SrcLinear)
+ srcp++;
+ if (DstLinear)
+ dstp++;
+ }
+
+ if (!SrcLinear)
+ srcp += m_bitblt_mem_offset;
+ if (!DstLinear)
+ dstp += m_bitblt_mem_offset;
+ }
+}
+
void sed1356_device::bitblt_execute_command()
{
switch (m_bitblt_op)
{
case 0:
- LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Write BitBLT with ROP\n");
+ LOGMASKED(LOG_BITBLT_OP, "bitblt: Write BitBLT with ROP\n");
+ bitblt_write();
return;
case 1:
- LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Read BitBLT\n");
+ LOGMASKED(LOG_BITBLT_OP, "bitblt: Read BitBLT\n");
+ bitblt_read();
return;
case 2:
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in + direction with ROP\n");
return;
case 3:
- LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in - direction with ROP\n");
+ {
+ LOGMASKED(LOG_BITBLT_OP, "bitblt: Move BitBLT in - direction with ROP\n");
+ const bool srclin = BIT(m_bitblt_ctrl[0], BBCTRL0_SRCLIN_BIT);
+ const bool dstlin = BIT(m_bitblt_ctrl[0], BBCTRL0_DSTLIN_BIT);
+ if (srclin && dstlin)
+ bitblt_move_negative<true, true>();
+ else if (srclin)
+ bitblt_move_negative<true, false>();
+ else if (dstlin)
+ bitblt_move_negative<false, true>();
+ else
+ bitblt_move_negative<false, false>();
return;
+ }
case 4:
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Transparent Write BitBLT\n");
return;
@@ -1432,15 +1584,34 @@ void sed1356_device::mplug_data_w(offs_t offset, uint8_t data)
}
-uint8_t sed1356_device::bitblt_data_r(offs_t offset)
+uint16_t sed1356_device::bitblt_data_r(offs_t offset)
{
- LOGMASKED(LOG_BITBLT_RD, "%s: (not implemented) bitblt_data_r[%06x]: %02x\n", machine().describe_context(), 0x100000 + offset, 0);
- return 0;
+ uint16_t data = 0;
+ if (BIT(m_bitblt_ctrl[0], BBCTRL0_ACTIVE_BIT) && m_bitblt_op == 1)
+ {
+ data = bitblt_read_continue();
+ }
+
+ LOGMASKED(LOG_BITBLT_RD, "%s: bitblt_data_r[%06x]: %04x\n", machine().describe_context(), 0x100000 + (offset << 1), data);
+ return data;
}
-void sed1356_device::bitblt_data_w(offs_t offset, uint8_t data)
+void sed1356_device::bitblt_data_w(offs_t offset, uint16_t data)
{
- LOGMASKED(LOG_BITBLT_WR, "%s: (not implemented) bitblt_data_w[%06x]: %02x\n", machine().describe_context(), 0x100000 + offset, data);
+ LOGMASKED(LOG_BITBLT_WR, "%s: bitblt_data_w[%06x]: %04x\n", machine().describe_context(), 0x100000 + (offset << 1), data);
+ if (BIT(m_bitblt_ctrl[0], BBCTRL0_ACTIVE_BIT))
+ {
+ switch (m_bitblt_op)
+ {
+ case 0: // Write BitBLT with ROP
+ bitblt_write_continue(data);
+ return;
+ case 4: // Transparent Write BitBLT
+ return;
+ default:
+ return;
+ }
+ }
}
void sed1356_device::device_start()