From 5dd883a3bd67e556fb8b5668e0435079240fce89 Mon Sep 17 00:00:00 2001 From: Vincent-Halver Date: Sun, 19 Jan 2025 01:31:49 -0800 Subject: CD-i: Fix RLE (#13243) This change: 1. Fixes RLE encoding which was short by 50% 2. Simplifies code, reducing by >100 lines. 3. Renames Channel to Path to match the Green Book spec. 4. Adds TODO for QHY DYUV images. This image type can't be tested without 625 scanline resolution which is currently blocked. So this will remain a known gap until several other features are added. --- src/mame/philips/mcd212.cpp | 512 +++++++++++++++++--------------------------- src/mame/philips/mcd212.h | 32 +-- 2 files changed, 208 insertions(+), 336 deletions(-) diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index 29f041e7a5a..edebc8145bb 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -17,7 +17,7 @@ STATUS: TODO: -- Unknown yet. +- QHY DYUV Image Decoder *******************************************************************************/ @@ -213,7 +213,7 @@ void mcd212_device::update_region_arrays() } } -template +template void mcd212_device::set_register(uint8_t reg, uint32_t value) { switch (reg) @@ -227,96 +227,96 @@ void mcd212_device::set_register(uint8_t reg, uint32_t value) case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: { - const uint8_t clut_index = m_clut_bank[Channel] * 0x40 + (reg - 0x80); - LOGMASKED(LOG_CLUT, "%s: Channel %d: CLUT[%d] = %08x\n", machine().describe_context(), Channel, clut_index, value); + const uint8_t clut_index = m_clut_bank[Path] * 0x40 + (reg - 0x80); + LOGMASKED(LOG_CLUT, "%s: Path %d: CLUT[%d] = %08x\n", machine().describe_context(), Path, clut_index, value); m_clut[clut_index] = value & 0x00fcfcfc; } break; case 0xc0: // Image Coding Method - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Channel 0: Image Coding Method = %08x\n", machine().describe_context(), value); + LOGMASKED(LOG_REGISTERS, "%s: Path 0: Image Coding Method = %08x\n", machine().describe_context(), value); m_image_coding_method = value; } break; case 0xc1: // Transparency Control - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Transparency Control = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Transparency Control = %08x\n", machine().describe_context(), screen().vpos(), value); m_transparency_control = value; } break; case 0xc2: // Plane Order - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Plane Order = %08x\n", machine().describe_context(), screen().vpos(), value & 7); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Plane Order = %08x\n", machine().describe_context(), screen().vpos(), value & 7); m_plane_order = value & 0x00000007; } break; case 0xc3: // CLUT Bank Register - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel %d: CLUT Bank Register = %08x\n", machine().describe_context(), screen().vpos(), Channel, value & 3); - m_clut_bank[Channel] = Channel ? (2 | (value & 0x00000001)) : (value & 0x00000003); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path %d: CLUT Bank Register = %08x\n", machine().describe_context(), screen().vpos(), Path, value & 3); + m_clut_bank[Path] = Path ? (2 | (value & 0x00000001)) : (value & 0x00000003); break; case 0xc4: // Transparent Color A - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Transparent Color A = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Transparent Color A = %08x\n", machine().describe_context(), screen().vpos(), value); m_transparent_color[0] = value & 0x00fcfcfc; } break; case 0xc6: // Transparent Color B - if (Channel == 1) + if (Path == 1) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 1: Transparent Color B = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 1: Transparent Color B = %08x\n", machine().describe_context(), screen().vpos(), value); m_transparent_color[1] = value & 0x00fcfcfc; } break; case 0xc7: // Mask Color A - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Mask Color A = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Mask Color A = %08x\n", machine().describe_context(), screen().vpos(), value); m_mask_color[0] = value & 0x00fcfcfc; } break; case 0xc9: // Mask Color B - if (Channel == 1) + if (Path == 1) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 1: Mask Color B = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 1: Mask Color B = %08x\n", machine().describe_context(), screen().vpos(), value); m_mask_color[1] = value & 0x00fcfcfc; } break; case 0xca: // Delta YUV Absolute Start Value A - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Delta YUV Absolute Start Value A = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Delta YUV Absolute Start Value A = %08x\n", machine().describe_context(), screen().vpos(), value); m_dyuv_abs_start[0] = value; } break; case 0xcb: // Delta YUV Absolute Start Value B - if (Channel == 1) + if (Path == 1) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 1: Delta YUV Absolute Start Value B = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 1: Delta YUV Absolute Start Value B = %08x\n", machine().describe_context(), screen().vpos(), value); m_dyuv_abs_start[1] = value; } break; case 0xcd: // Cursor Position - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Cursor Position = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Cursor Position = %08x\n", machine().describe_context(), screen().vpos(), value); m_cursor_position = value; } break; case 0xce: // Cursor Control - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Cursor Control = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Cursor Control = %08x\n", machine().describe_context(), screen().vpos(), value); m_cursor_control = value; } break; case 0xcf: // Cursor Pattern - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Cursor Pattern[%d] = %04x\n", machine().describe_context(), screen().vpos(), (value >> 16) & 0x000f, value & 0x0000ffff); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Cursor Pattern[%d] = %04x\n", machine().describe_context(), screen().vpos(), (value >> 16) & 0x000f, value & 0x0000ffff); m_cursor_pattern[(value >> 16) & 0x000f] = value & 0x0000ffff; } break; @@ -328,43 +328,43 @@ void mcd212_device::set_register(uint8_t reg, uint32_t value) case 0xd5: case 0xd6: case 0xd7: - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel %d: Region Control %d = %08x\n", machine().describe_context(), screen().vpos(), Channel, reg & 7, value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path %d: Region Control %d = %08x\n", machine().describe_context(), screen().vpos(), Path, reg & 7, value); m_region_control[reg & 7] = value; update_region_arrays(); break; case 0xd8: // Backdrop Color - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Backdrop Color = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Backdrop Color = %08x\n", machine().describe_context(), screen().vpos(), value); m_backdrop_color = value; } break; case 0xd9: // Mosaic Pixel Hold Factor A - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Mosaic Pixel Hold Factor A = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Mosaic Pixel Hold Factor A = %08x\n", machine().describe_context(), screen().vpos(), value); m_mosaic_hold[0] = value; } break; case 0xda: // Mosaic Pixel Hold Factor B - if (Channel == 1) + if (Path == 1) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 1: Mosaic Pixel Hold Factor B = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 1: Mosaic Pixel Hold Factor B = %08x\n", machine().describe_context(), screen().vpos(), value); m_mosaic_hold[1] = value; } break; case 0xdb: // Weight Factor A - if (Channel == 0) + if (Path == 0) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 0: Weight Factor A = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 0: Weight Factor A = %08x\n", machine().describe_context(), screen().vpos(), value); m_weight_factor[0][0] = (uint8_t)value; update_region_arrays(); } break; case 0xdc: // Weight Factor B - if (Channel == 1) + if (Path == 1) { - LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Channel 1: Weight Factor B = %08x\n", machine().describe_context(), screen().vpos(), value); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path 1: Weight Factor B = %08x\n", machine().describe_context(), screen().vpos(), value); m_weight_factor[1][0] = (uint8_t)value; update_region_arrays(); } @@ -372,41 +372,41 @@ void mcd212_device::set_register(uint8_t reg, uint32_t value) } } -template +template inline ATTR_FORCE_INLINE uint32_t mcd212_device::get_vsr() { - return ((m_dcr[Channel] & 0x3f) << 16) | m_vsr[Channel]; + return ((m_dcr[Path] & 0x3f) << 16) | m_vsr[Path]; } -template +template inline ATTR_FORCE_INLINE void mcd212_device::set_vsr(uint32_t value) { - m_vsr[Channel] = value & 0x0000ffff; - m_dcr[Channel] &= 0xffc0; - m_dcr[Channel] |= (value >> 16) & 0x003f; + m_vsr[Path] = value & 0x0000ffff; + m_dcr[Path] &= 0xffc0; + m_dcr[Path] |= (value >> 16) & 0x003f; } -template +template inline ATTR_FORCE_INLINE void mcd212_device::set_dcp(uint32_t value) { - m_dcp[Channel] = value & 0x0000ffff; - m_ddr[Channel] &= 0xffc0; - m_ddr[Channel] |= (value >> 16) & 0x003f; + m_dcp[Path] = value & 0x0000ffff; + m_ddr[Path] &= 0xffc0; + m_ddr[Path] |= (value >> 16) & 0x003f; } -template +template inline ATTR_FORCE_INLINE uint32_t mcd212_device::get_dcp() { - return ((m_ddr[Channel] & 0x3f) << 16) | m_dcp[Channel]; + return ((m_ddr[Path] & 0x3f) << 16) | m_dcp[Path]; } -template +template inline ATTR_FORCE_INLINE void mcd212_device::set_display_parameters(uint8_t value) { - m_ddr[Channel] &= 0xf0ff; - m_ddr[Channel] |= (value & 0x0f) << 8; - m_dcr[Channel] &= 0xf7ff; - m_dcr[Channel] |= (value & 0x10) << 7; + m_ddr[Path] &= 0xf0ff; + m_ddr[Path] |= (value & 0x0f) << 8; + m_dcr[Path] &= 0xf7ff; + m_dcr[Path] |= (value & 0x10) << 7; } int mcd212_device::get_screen_width() @@ -425,10 +425,10 @@ int mcd212_device::get_border_width() return width; } -template +template void mcd212_device::process_ica() { - uint16_t *ica = Channel ? m_planeb.target() : m_planea.target(); + uint16_t *ica = Path ? m_planeb.target() : m_planea.target(); uint32_t addr = 0x200; uint32_t cmd = 0; @@ -441,63 +441,63 @@ void mcd212_device::process_ica() { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // STOP case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: STOP\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: STOP\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); return; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: // NOP case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: NOP\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: NOP\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // RELOAD DCP case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP: %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); - set_dcp(cmd & 0x003ffffc); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); + set_dcp(cmd & 0x003ffffc); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP and STOP: %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); - set_dcp(cmd & 0x003ffffc); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP and STOP: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); + set_dcp(cmd & 0x003ffffc); return; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD VSR (ICA) case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD VSR: %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD VSR: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); addr = (cmd & 0x0007ffff) / 2; break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD VSR and STOP: VSR = %05x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); - set_vsr(cmd & 0x003fffff); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD VSR and STOP: VSR = %05x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); + set_vsr(cmd & 0x003fffff); return; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: INTERRUPT\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); - m_csrr[1] |= 1 << (2 - Channel); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: INTERRUPT\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); + m_csrr[1] |= 1 << (2 - Path); if (m_csrr[1] & (CSR2R_IT1 | CSR2R_IT2)) m_int_callback(ASSERT_LINE); break; case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); - set_display_parameters(cmd & 0x1f); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); + set_display_parameters(cmd & 0x1f); break; default: - LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: SET REGISTER %02x = %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd >> 24, cmd & 0x00ffffff ); - set_register(cmd >> 24, cmd & 0x00ffffff); + LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: SET REGISTER %02x = %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd >> 24, cmd & 0x00ffffff ); + set_register(cmd >> 24, cmd & 0x00ffffff); break; } } } -template +template void mcd212_device::process_dca() { - uint16_t *dca = Channel ? m_planeb.target() : m_planea.target(); - uint32_t addr = (m_dca[Channel] & 0x0007ffff) / 2; + uint16_t *dca = Path ? m_planeb.target() : m_planea.target(); + uint32_t addr = (m_dca[Path] & 0x0007ffff) / 2; uint32_t cmd = 0; uint32_t count = 0; uint32_t max = 64; bool addr_changed = false; bool processing = true; - LOGMASKED(LOG_DCA, "Scanline %d: Processing DCA %d\n", screen().vpos(), Channel ); + LOGMASKED(LOG_DCA, "Scanline %d: Processing DCA %d\n", screen().vpos(), Path ); while (processing && count < max) { @@ -508,47 +508,47 @@ void mcd212_device::process_dca() { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // STOP case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: STOP\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: STOP\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); processing = false; break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: // NOP case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: NOP\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: NOP\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // RELOAD DCP case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP (NOP)\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP (NOP)\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP and STOP\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); - set_dcp(cmd & 0x003ffffc); - m_dca[Channel] = cmd & 0x0007fffc; + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DCP and STOP\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); + set_dcp(cmd & 0x003ffffc); + m_dca[Path] = cmd & 0x0007fffc; return; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD VSR case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR: %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); - set_vsr(cmd & 0x003fffff); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); + set_vsr(cmd & 0x003fffff); break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR and STOP: %06x\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel, cmd & 0x001fffff ); - set_vsr(cmd & 0x003fffff); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR and STOP: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff ); + set_vsr(cmd & 0x003fffff); processing = false; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: INTERRUPT\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); - m_csrr[1] |= 1 << (2 - Channel); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: INTERRUPT\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); + m_csrr[1] |= 1 << (2 - Path); if (m_csrr[1] & (CSR2R_IT1 | CSR2R_IT2)) m_int_callback(ASSERT_LINE); break; case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS - LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Channel * 0x200000, cmd, Channel ); - set_display_parameters(cmd & 0x1f); + LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path ); + set_display_parameters(cmd & 0x1f); break; default: - set_register(cmd >> 24, cmd & 0x00ffffff); + set_register(cmd >> 24, cmd & 0x00ffffff); break; } } @@ -558,10 +558,10 @@ void mcd212_device::process_dca() addr += (max - count) >> 1; } - m_dca[Channel] = addr * 2; + m_dca[Path] = addr * 2; } -template +template static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte) { switch (icm) @@ -569,7 +569,7 @@ static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte) case 1: return byte; case 3: - if (Channel == 1) + if (Path == 1) { return 0x80 + (byte & 0x7f); } @@ -578,13 +578,13 @@ static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte) return byte & 0x7f; } case 4: - if (Channel == 0) + if (Path == 0) { return byte & 0x7f; } break; case 11: - if (Channel == 1) + if (Path == 1) { return 0x80 + (byte & 0x0f); } @@ -598,275 +598,147 @@ static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte) return 0; } -template +template inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_transparency_control() { - return (m_transparency_control >> (Channel ? 8 : 0)) & 0x0f; + return (m_transparency_control >> (Path ? 8 : 0)) & 0x0f; } -template +template inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_icm() { - const uint32_t mask = Channel ? ICM_MODE2 : ICM_MODE1; - const uint32_t shift = Channel ? ICM_MODE2_SHIFT : ICM_MODE1_SHIFT; + const uint32_t mask = Path ? ICM_MODE2 : ICM_MODE1; + const uint32_t shift = Path ? ICM_MODE2_SHIFT : ICM_MODE1_SHIFT; return (m_image_coding_method & mask) >> shift; } -template +template inline ATTR_FORCE_INLINE bool mcd212_device::get_mosaic_enable() { - return (m_ddr[Channel] & DDR_FT) == DDR_FT_MOSAIC; + return (m_ddr[Path] & DDR_FT) == DDR_FT_MOSAIC; } -template +template inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_mosaic_factor() { - return 1 << (((m_ddr[Channel] & DDR_MT) >> DDR_MT_SHIFT) + 1); + return 1 << (((m_ddr[Path] & DDR_MT) >> DDR_MT_SHIFT) + 1); } -template +template int mcd212_device::get_plane_width() { const int width = get_screen_width(); - const uint8_t icm = get_icm(); + const uint8_t icm = get_icm(); if (icm == ICM_CLUT4) return width; return width >> 1; } -template -void mcd212_device::process_vsr(uint32_t *pixels, bool *transparent) +template +void mcd212_device::process_vsr(uint32_t* pixels, bool* transparent) { - const uint8_t *data = reinterpret_cast(Channel ? m_planeb.target() : m_planea.target()); - const uint8_t icm = get_icm(); - const uint8_t transp_ctrl = get_transparency_control(); - const int width = get_plane_width(); + const uint8_t* data = reinterpret_cast(Path ? m_planeb.target() : m_planea.target()); + const uint8_t icm = get_icm(); + const uint8_t transp_ctrl = get_transparency_control(); + const int width = get_screen_width(); - uint32_t vsr = get_vsr(); + uint32_t vsr = get_vsr(); - if (transp_ctrl == TCR_COND_1) + if (transp_ctrl == TCR_COND_1 || !icm || !vsr) { - std::fill_n(pixels, get_screen_width(), 0x00101010); + std::fill_n(pixels, get_screen_width(), s_4bpp_color[0]); std::fill_n(transparent, get_screen_width(), true); return; } - if (!icm || !vsr) - { - std::fill_n(pixels, get_screen_width(), 0x00101010); - return; - } + const uint32_t decodingMode = m_ddr[Path] & DDR_FT; - const uint8_t mosaic_enable = get_mosaic_enable(); - const uint8_t mosaic_factor = get_mosaic_factor(); + const uint8_t mosaic_enable = get_mosaic_enable(); + const uint8_t mosaic_factor = get_mosaic_factor(); - const uint32_t dyuv_abs_start = m_dyuv_abs_start[Channel]; + const uint32_t dyuv_abs_start = m_dyuv_abs_start[Path]; uint8_t y = (dyuv_abs_start >> 16) & 0x000000ff; - uint8_t u = (dyuv_abs_start >> 8) & 0x000000ff; - uint8_t v = (dyuv_abs_start >> 0) & 0x000000ff; + uint8_t u = (dyuv_abs_start >> 8) & 0x000000ff; + uint8_t v = (dyuv_abs_start >> 0) & 0x000000ff; - const uint32_t transparent_color = m_transparent_color[Channel]; + const uint32_t mask_bits = (~m_mask_color[Path]) & 0x00fcfcfc; + const uint32_t transp_match = m_transparent_color[Path] & mask_bits; const uint8_t transp_ctrl_masked = transp_ctrl & 0x07; const bool transp_always = (transp_ctrl_masked == TCR_COND_1); const bool invert_transp_condition = BIT(transp_ctrl, 3); const int region_flag_index = 1 - (transp_ctrl_masked & 1); - const bool *region_flags = m_region_flag[region_flag_index]; + const bool* region_flags = m_region_flag[region_flag_index]; const bool use_region_flag = (transp_ctrl_masked >= TCR_COND_RF0_1 && transp_ctrl_masked <= TCR_COND_RF1KEY_1); bool use_color_key = (transp_ctrl_masked == TCR_COND_KEY_1 || transp_ctrl_masked == TCR_COND_RF0KEY_1 || transp_ctrl_masked == TCR_COND_RF1KEY_1); - bool done = false; - int x = 0; - - LOGMASKED(LOG_VSR, "Scanline %d: VSR Channel %d, ICM (%02x), VSR (%08x)\n", screen().vpos(), Channel, icm, vsr); + LOGMASKED(LOG_VSR, "Scanline %d: VSR Path %d, ICM (%02x), VSR (%08x)\n", screen().vpos(), Path, icm, vsr); - while (!done) + for (uint32_t x = 0; x < width; ) { - uint8_t byte = data[(vsr & 0x0007ffff) ^ 1]; - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: VSR[%05x] = %02x\n", screen().vpos(), Channel, (vsr & 0x0007ffff), byte); - vsr++; - switch (m_ddr[Channel] & DDR_FT) + const uint8_t byte = data[(vsr++ & 0x0007ffff) ^ 1]; + uint32_t color0 = 0; + uint32_t color1 = 0; + if (icm == ICM_DYUV) { - case DDR_FT_BMP: - case DDR_FT_BMP2: - case DDR_FT_MOSAIC: - if ((m_ddr[Channel] & DDR_FT) == DDR_FT_BMP) - { - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: BMP\n", screen().vpos(), Channel); - } - else if ((m_ddr[Channel] & DDR_FT) == DDR_FT_BMP2) - { - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: BMP2\n", screen().vpos(), Channel); - } - else if ((m_ddr[Channel] & DDR_FT) == DDR_FT_MOSAIC) - { - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: MOSAIC\n", screen().vpos(), Channel); - } - - if (icm == ICM_DYUV) - { - use_color_key = false; - - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: DYUV\n", screen().vpos(), Channel); - for (; x < width; x++) - { - const uint8_t byte1 = data[(vsr++ & 0x0007ffff) ^ 1]; - const uint8_t u1 = u + m_delta_uv_lut[byte]; - const uint8_t y0 = y + m_delta_y_lut[byte]; - - const uint8_t v1 = v + m_delta_uv_lut[byte1]; - const uint8_t y1 = y0 + m_delta_y_lut[byte1]; - - // Midpoint Interpolation prevents rollover, against spec. - const uint8_t u0 = (u >> 1) + (u1 >> 1) + (u & u1 & 1); - const uint8_t v0 = (v >> 1) + (v1 >> 1) + (v & v1 & 1); - - uint32_t* limit_rgb = m_dyuv_limit_rgb_lut + y0 + 0x100; - - uint32_t entry = (limit_rgb[m_dyuv_v_to_r[v0]] << 16) | (limit_rgb[m_dyuv_u_to_g[u0] + m_dyuv_v_to_g[v0]] << 8) | limit_rgb[m_dyuv_u_to_b[u0]]; - pixels[x] = entry; - transparent[x] = (transp_always || (use_region_flag && region_flags[x << 1])) != invert_transp_condition; - - x++; - - limit_rgb = m_dyuv_limit_rgb_lut + y1 + 0x100; - - entry = (limit_rgb[m_dyuv_v_to_r[v1]] << 16) | (limit_rgb[m_dyuv_u_to_g[u1] + m_dyuv_v_to_g[v1]] << 8) | limit_rgb[m_dyuv_u_to_b[u1]]; - pixels[x] = entry; - transparent[x] = (transp_always || (use_region_flag && region_flags[x << 1])) != invert_transp_condition; - - byte = data[(vsr++ & 0x0007ffff) ^ 1]; - - y = y1; - u = u1; - v = v1; - } - set_vsr(vsr - 1); - } - else if (icm == ICM_CLUT8 || icm == ICM_CLUT7 || icm == ICM_CLUT77) - { - for (; x < width; x++) - { - uint32_t entry = m_clut[BYTE_TO_CLUT(icm, byte)]; - pixels[x] = entry; - transparent[x] = (transp_always || (use_color_key && (entry == transparent_color)) || (use_region_flag && region_flags[x << 1])) != invert_transp_condition; - if (mosaic_enable) - { - for (int mosaic_index = 1; mosaic_index < mosaic_factor && (x + mosaic_index) < width; mosaic_index++) - { - pixels[x + mosaic_index] = pixels[x]; - transparent[x + mosaic_index] = transparent[x]; - } - x += mosaic_factor - 1; - } - byte = data[(vsr & 0x0007ffff) ^ 1]; - vsr++; - } - set_vsr(vsr - 1); - } - else if (icm == ICM_CLUT4) - { - for (; x < width - 1; x += 2) - { - const uint32_t even_entry = m_clut[BYTE_TO_CLUT(icm, byte >> 4)]; - const uint32_t odd_entry = m_clut[BYTE_TO_CLUT(icm, byte)]; - const bool even_pre_transparent = transp_always || (use_color_key && (even_entry == transparent_color)); - const bool odd_pre_transparent = transp_always || (use_color_key && (odd_entry == transparent_color)); - if (mosaic_enable) - { - for (int mosaic_index = 0; mosaic_index < mosaic_factor && (x + mosaic_index) < (width - 1); mosaic_index += 2) - { - pixels[x + mosaic_index] = even_entry; - transparent[x + mosaic_index] = (even_pre_transparent || (use_region_flag && region_flags[x + mosaic_index])) != invert_transp_condition; - pixels[x + mosaic_index + 1] = odd_entry; - transparent[x + mosaic_index + 1] = (odd_pre_transparent || (use_region_flag && region_flags[x + mosaic_index + 1])) != invert_transp_condition; - } - x += mosaic_factor - 2; - } - else - { - pixels[x] = even_entry; - transparent[x] = (even_pre_transparent || (use_region_flag && region_flags[x])) != invert_transp_condition; - - pixels[x + 1] = odd_entry; - transparent[x + 1] = (odd_pre_transparent || (use_region_flag && region_flags[x + 1])) != invert_transp_condition; - } - byte = data[(vsr & 0x0007ffff) ^ 1]; - vsr++; - } - set_vsr(vsr - 1); - } - else - { - std::fill_n(pixels + x, width - x, 0x00101010); - std::fill_n(transparent + x, width - x, true); - } - done = true; - break; - case DDR_FT_RLE: - LOGMASKED(LOG_VSR, "Scanline %d: Chan %d: RLE\n", screen().vpos(), Channel); - if (byte & 0x80) - { - // Run length - uint8_t length = data[((vsr++) & 0x0007ffff) ^ 1]; - LOGMASKED(LOG_VSR, "Byte %02x w/ run length %02x at %d\n", byte, length, x); - const uint32_t entry = m_clut[BYTE_TO_CLUT(icm, byte & 0x7f)]; - const bool pre_transparent = (transp_always || (use_color_key && entry == transparent_color)); - if (!length) - { - // Go to the end of the line - std::fill_n(pixels + x, width - x, entry); - for (int transp_index = x; transp_index < width; transp_index++) - { - transparent[transp_index] = (pre_transparent || (use_region_flag && region_flags[transp_index << 1])) != invert_transp_condition; - } - done = true; - set_vsr(vsr); - } - else - { - int end = std::min(width, x + length); - std::fill_n(pixels + x, end - x, entry); - for (int transp_index = x; transp_index < end; transp_index++) - { - transparent[transp_index] = (pre_transparent || (use_region_flag && region_flags[transp_index << 1])) != invert_transp_condition; - } - x = end; - if (x >= width) - { - done = true; - set_vsr(vsr); - } - } - } - else - { - LOGMASKED(LOG_VSR, "Byte %02x, single at %d\n", byte, x); - // Single pixel - const uint32_t entry = m_clut[BYTE_TO_CLUT(icm, byte)]; - const bool pre_transparent = (transp_always || (use_color_key && entry == transparent_color)); - - pixels[x] = entry; - transparent[x] = (pre_transparent || (use_region_flag && region_flags[x << 1])) != invert_transp_condition; - x++; + const uint8_t byte1 = data[(vsr++ & 0x0007ffff) ^ 1]; + const uint8_t y2 = y + m_delta_y_lut[byte]; + const uint8_t y4 = y2 + m_delta_y_lut[byte1]; + + const uint8_t u4 = u + m_delta_uv_lut[byte]; + const uint8_t v4 = v + m_delta_uv_lut[byte1]; + const uint8_t u2 = (u >> 1) + (u4 >> 1) + (u & u4 & 1); + const uint8_t v2 = (v >> 1) + (v4 >> 1) + (v & v4 & 1); + + uint32_t* limit_rgb = m_dyuv_limit_lut + y2 + 0x100; + color0 = (limit_rgb[m_dyuv_v_to_r[v2]] << 16) | (limit_rgb[m_dyuv_u_to_g[u2] + m_dyuv_v_to_g[v2]] << 8) | limit_rgb[m_dyuv_u_to_b[u2]]; + limit_rgb = m_dyuv_limit_lut + y4 + 0x100; + color1 = (limit_rgb[m_dyuv_v_to_r[v4]] << 16) | (limit_rgb[m_dyuv_u_to_g[u4] + m_dyuv_v_to_g[v4]] << 8) | limit_rgb[m_dyuv_u_to_b[u4]]; + + y = y4; + u = u4; + v = v4; + // TODO: Does not support QHY + pixels[x] = color0; + pixels[x + 1] = color0; + pixels[x + 2] = color1; + pixels[x + 3] = color1; + transparent[x] = (transp_always || (use_region_flag && region_flags[x])) != invert_transp_condition; + transparent[x + 1] = (transp_always || (use_region_flag && region_flags[x + 1])) != invert_transp_condition; + transparent[x + 2] = (transp_always || (use_region_flag && region_flags[x + 2])) != invert_transp_condition; + transparent[x + 3] = (transp_always || (use_region_flag && region_flags[x + 3])) != invert_transp_condition; + x += 4; + continue; + } + else if (icm == ICM_CLUT4) + { + const uint8_t mask = (decodingMode == DDR_FT_RLE) ? 0x7 : 0xf; + color0 = m_clut[BYTE_TO_CLUT(icm, mask & (byte >> 4))]; + color1 = m_clut[BYTE_TO_CLUT(icm, mask & byte)]; + } + else { + color1 = color0 = m_clut[BYTE_TO_CLUT(icm, byte)]; + } - if (x >= width) - { - done = true; - set_vsr(vsr); - } - } - break; + int m_length = mosaic_enable ? mosaic_factor * 2 : 2; + if (decodingMode == DDR_FT_RLE) + { + const uint16_t length = (byte & 0x80) ? data[((vsr++) & 0x0007ffff) ^ 1] : 1; + m_length = length ? length * 2 : width; } - } - if (icm != ICM_CLUT4) - { - for (int i = width - 1; i >= 0; i--) + const bool color_match0 = (mask_bits & color0) == transp_match; + const bool color_match1 = (mask_bits & color1) == transp_match; + const int end = std::min(width, (int)x + m_length); + for (int rl_index = x; rl_index < end; rl_index += 2) { - pixels[i * 2] = pixels[i * 2 + 1] = pixels[i]; - transparent[i * 2] = transparent[i * 2 + 1] = transparent[i]; + pixels[rl_index] = color0; + transparent[rl_index] = (transp_always || (use_color_key && color_match0) || (use_region_flag && region_flags[rl_index])) != invert_transp_condition; + pixels[rl_index + 1] = color1; + transparent[rl_index + 1] = (transp_always || (use_color_key && color_match1) || (use_region_flag && region_flags[rl_index + 1])) != invert_transp_condition; } + x = end; } + set_vsr(vsr); } const uint32_t mcd212_device::s_4bpp_color[16] = @@ -1297,7 +1169,7 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma template int mcd212_device::ram_dtack_cycle_count<0>(); template int mcd212_device::ram_dtack_cycle_count<1>(); -template +template int mcd212_device::ram_dtack_cycle_count() { // Per MCD-212 documentation, it takes 4 CLKs (2 SCC68070 clocks) for a VRAM access during the System timing slot. @@ -1306,8 +1178,8 @@ int mcd212_device::ram_dtack_cycle_count() if (!BIT(m_dcr[0], DCR_DE_BIT)) return 2; - // No contending for Ch.1/Ch.2 timing slots if a relevant channel is disabled - if (!BIT(m_dcr[Channel], DCR_ICA_BIT)) + // No contending for Ch.1/Ch.2 timing slots if a relevant Path is disabled + if (!BIT(m_dcr[Path], DCR_ICA_BIT)) return 2; const int x = screen().hpos(); @@ -1323,7 +1195,7 @@ int mcd212_device::ram_dtack_cycle_count() return 2; // No contending for Ch.1/Ch.2 timing slots during the free-run area of DCA lines if DCA is disabled - if (!BIT(m_dcr[Channel], DCR_DCA_BIT) && x_outside_active_display) + if (!BIT(m_dcr[Path], DCR_DCA_BIT) && x_outside_active_display) return 2; // System access is restricted to the last 5 out of every 16 CLKs. @@ -1409,7 +1281,7 @@ void mcd212_device::device_start() for (uint16_t w = 0; w < 0x300; w++) { const uint8_t limit = (w < 0x100) ? 0 : (w < 0x200) ? (w - 0x100) : 0xff; - m_dyuv_limit_rgb_lut[w] = limit; + m_dyuv_limit_lut[w] = limit; } for (int16_t sw = 0; sw < 0x100; sw++) diff --git a/src/mame/philips/mcd212.h b/src/mame/philips/mcd212.h index 2b2a5047bef..7856cdc7f75 100644 --- a/src/mame/philips/mcd212.h +++ b/src/mame/philips/mcd212.h @@ -51,7 +51,7 @@ public: void map(address_map &map) ATTR_COLD; - template int ram_dtack_cycle_count(); + template int ram_dtack_cycle_count(); int rom_dtack_cycle_count(); protected: @@ -202,7 +202,7 @@ protected: uint8_t m_weight_factor[2][768]{}; // DYUV color limit arrays. - uint32_t m_dyuv_limit_rgb_lut[0x300]; + uint32_t m_dyuv_limit_lut[0x300]; // DYUV delta-Y decoding array uint8_t m_delta_y_lut[0x100]; @@ -243,26 +243,26 @@ protected: int get_screen_width(); int get_border_width(); - template int get_plane_width(); + template int get_plane_width(); - template void set_vsr(uint32_t value); - template uint32_t get_vsr(); + template void set_vsr(uint32_t value); + template uint32_t get_vsr(); - template void set_dcp(uint32_t value); - template uint32_t get_dcp(); + template void set_dcp(uint32_t value); + template uint32_t get_dcp(); - template void set_display_parameters(uint8_t value); + template void set_display_parameters(uint8_t value); - template void process_ica(); - template void process_dca(); + template void process_ica(); + template void process_dca(); - template uint8_t get_transparency_control(); - template uint8_t get_icm(); - template bool get_mosaic_enable(); - template uint8_t get_mosaic_factor(); - template void process_vsr(uint32_t *pixels, bool *transparent); + template uint8_t get_transparency_control(); + template uint8_t get_icm(); + template bool get_mosaic_enable(); + template uint8_t get_mosaic_factor(); + template void process_vsr(uint32_t *pixels, bool *transparent); - template void set_register(uint8_t reg, uint32_t value); + template void set_register(uint8_t reg, uint32_t value); template void mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t *plane_b, bool *transparent_b, uint32_t *out); -- cgit v1.2.3