summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/midtunit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/midtunit.cpp')
-rw-r--r--src/mame/video/midtunit.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/mame/video/midtunit.cpp b/src/mame/video/midtunit.cpp
index 303e374f5fe..20dc6b836d3 100644
--- a/src/mame/video/midtunit.cpp
+++ b/src/mame/video/midtunit.cpp
@@ -12,6 +12,8 @@
#include "midtunit.ipp"
#include "screen.h"
#include "midtview.ipp"
+#include "emuopts.h" // Used by MIDTUNIT_LOG_PNG
+#include "png.h" // Used by MIDTUNIT_LOG_PNG
DEFINE_DEVICE_TYPE(MIDTUNIT_VIDEO, midtunit_video_device, "tunitvid", "Midway T-Unit Video")
DEFINE_DEVICE_TYPE(MIDWUNIT_VIDEO, midwunit_video_device, "wunitvid", "Midway W-Unit Video")
@@ -65,6 +67,9 @@ void midtunit_video_device::device_start()
#if DEBUG_MIDTUNIT_BLITTER
m_debug_videoram = std::make_unique<uint16_t[]>(0x100000/2);
#endif
+#if MIDTUNIT_LOG_PNG
+ m_logged_rom = std::make_unique<uint64_t[]>(0x4000000);
+#endif
m_dma_timer = timer_alloc(TIMER_DMA);
@@ -682,6 +687,17 @@ WRITE16_MEMBER(midtunit_video_device::midtunit_dma_w)
m_dma_state.endskip = m_dma_register[DMA_LRSKIP];
}
+#if MIDTUNIT_LOG_PNG
+ if (command & 0x80)
+ {
+ log_bitmap(command, bpp ? bpp : 8, true);
+ }
+ else
+ {
+ log_bitmap(command, bpp ? bpp : 8, false);
+ }
+#endif
+
/* then draw */
if (m_dma_state.xstep == 0x100 && m_dma_state.ystep == 0x100)
{
@@ -741,3 +757,157 @@ TMS340X0_SCANLINE_IND16_CB_MEMBER(midxunit_video_device::scanline_update)
for (int x = params->heblnk; x < params->hsblnk; x++)
dest[x] = src[fulladdr++ & 0x1ff] & 0x7fff;
}
+
+#if MIDTUNIT_LOG_PNG
+void midtunit_video_device::log_bitmap(int command, int bpp, bool Skip)
+{
+ const uint32_t raw_offset = m_dma_register[DMA_OFFSETLO] | (m_dma_register[DMA_OFFSETHI] << 16);
+ if (m_logged_rom[raw_offset >> 6] & (1ULL << (raw_offset & 0x3f)))
+ return;
+
+ int Zero = PIXEL_SKIP;
+ int NonZero = PIXEL_SKIP;
+ switch (command & 0xf)
+ {
+ case 1: Zero = PIXEL_COPY; NonZero = PIXEL_SKIP; break;
+ case 2: Zero = PIXEL_SKIP; NonZero = PIXEL_COPY; break;
+ case 3: Zero = PIXEL_COPY; NonZero = PIXEL_COPY; break;
+ case 4: Zero = PIXEL_COLOR; NonZero = PIXEL_SKIP; break;
+ case 5: Zero = PIXEL_COLOR; NonZero = PIXEL_SKIP; break;
+ case 6: Zero = PIXEL_COLOR; NonZero = PIXEL_COPY; break;
+ case 7: Zero = PIXEL_COLOR; NonZero = PIXEL_COPY; break;
+ case 8: Zero = PIXEL_SKIP; NonZero = PIXEL_COLOR; break;
+ case 9: Zero = PIXEL_COPY; NonZero = PIXEL_COLOR; break;
+ case 10: Zero = PIXEL_SKIP; NonZero = PIXEL_COLOR; break;
+ case 11: Zero = PIXEL_COPY; NonZero = PIXEL_COLOR; break;
+ case 12: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
+ case 13: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
+ case 14: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
+ case 15: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
+ default: return;
+ }
+
+ emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+
+ char name_buf[256];
+ snprintf(name_buf, 255, "0x%08x.png", raw_offset);
+ auto const filerr = file.open(name_buf);
+ if (filerr != osd_file::error::NONE)
+ {
+ return;
+ }
+
+ m_logged_rom[raw_offset >> 6] |= 1ULL << (raw_offset & 0x3f);
+
+ m_log_bitmap.allocate(m_dma_state.width, m_dma_state.height);
+ m_log_bitmap.fill(0);
+
+ uint8_t *base = m_dma_state.gfxrom;
+ uint32_t offset = m_dma_state.offset;
+ uint16_t pal = m_dma_state.palette;
+ uint16_t color = pal | m_dma_state.color;
+ int mask = (1 << bpp) - 1;
+
+ /* loop over the height */
+ for (int y = 0; y < m_dma_state.height; y++)
+ {
+ int startskip = m_dma_state.startskip;
+ int endskip = m_dma_state.endskip;
+ int width = m_dma_state.width;
+ int ix = 0;
+ int tx;
+ uint32_t o = offset;
+ int pre, post;
+
+ /* handle skipping */
+ if (Skip)
+ {
+ uint8_t value = EXTRACTGEN(0xff);
+ o += 8;
+
+ /* adjust for preskip */
+ pre = (value & 0x0f) << m_dma_state.preskip;
+ tx = pre;
+ ix += tx;
+
+ /* adjust for postskip */
+ post = ((value >> 4) & 0x0f) << m_dma_state.postskip;
+ width -= post;
+ endskip -= post;
+ }
+
+ /* handle start skip */
+ if (ix < startskip)
+ {
+ tx = (startskip - ix);
+ ix += tx;
+ o += tx * bpp;
+ }
+
+ /* handle end skip */
+ if (width > m_dma_state.width - m_dma_state.endskip)
+ width = m_dma_state.width - m_dma_state.endskip;
+
+ bitmap_rgb32::pixel_t *d = &m_log_bitmap.pix(y, ix);
+
+ /* determine destination pointer */
+
+ /* loop until we draw the entire width */
+ while (ix < width)
+ {
+ /* special case similar handling of zero/non-zero */
+ if (Zero == NonZero)
+ {
+ if (Zero == PIXEL_COLOR)
+ *d = m_palette->palette()->entry_list_raw()[color];
+ else if (Zero == PIXEL_COPY)
+ *d = m_palette->palette()->entry_list_raw()[(EXTRACTGEN(mask)) | pal];
+ }
+
+ /* otherwise, read the pixel and look */
+ else
+ {
+ int pixel = (EXTRACTGEN(mask));
+
+ /* non-zero pixel case */
+ if (pixel)
+ {
+ if (NonZero == PIXEL_COLOR)
+ *d = m_palette->palette()->entry_list_raw()[color];
+ else if (NonZero == PIXEL_COPY)
+ *d = m_palette->palette()->entry_list_raw()[pixel | pal];
+ }
+
+ /* zero pixel case */
+ else
+ {
+ if (Zero == PIXEL_COLOR)
+ *d = m_palette->palette()->entry_list_raw()[color];
+ else if (Zero == PIXEL_COPY)
+ *d = m_palette->palette()->entry_list_raw()[pal];
+ }
+ }
+
+ /* advance to the next pixel */
+ ix++;
+ d++;
+ o += bpp;
+ }
+
+ /* advance to the next row */
+ width = m_dma_state.width;
+ if (Skip)
+ {
+ offset += 8;
+ width -= pre + post;
+ if (width > 0) offset += width * bpp;
+ }
+ else
+ {
+ offset += width * bpp;
+ }
+ }
+
+ png_write_bitmap(file, nullptr, m_log_bitmap, 0, nullptr);
+}
+#endif \ No newline at end of file