mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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.
This commit is contained in:
parent
cf1d2eef0a
commit
5dd883a3bd
@ -17,7 +17,7 @@ STATUS:
|
||||
|
||||
TODO:
|
||||
|
||||
- Unknown yet.
|
||||
- QHY DYUV Image Decoder
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
@ -213,7 +213,7 @@ void mcd212_device::update_region_arrays()
|
||||
}
|
||||
}
|
||||
|
||||
template <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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<Channel>(cmd & 0x003ffffc);
|
||||
LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DCP: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff );
|
||||
set_dcp<Path>(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<Channel>(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<Path>(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<Channel>(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<Path>(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<Channel>(cmd & 0x1f);
|
||||
LOGMASKED(LOG_ICA, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path );
|
||||
set_display_parameters<Path>(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<Channel>(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<Path>(cmd >> 24, cmd & 0x00ffffff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <int Channel>
|
||||
template <int Path>
|
||||
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<Channel>(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<Path>(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<Channel>(cmd & 0x003fffff);
|
||||
LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD VSR: %06x\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path, cmd & 0x001fffff );
|
||||
set_vsr<Path>(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<Channel>(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<Path>(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<Channel>(cmd & 0x1f);
|
||||
LOGMASKED(LOG_DCA, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", (addr - 2) * 2 + Path * 0x200000, cmd, Path );
|
||||
set_display_parameters<Path>(cmd & 0x1f);
|
||||
break;
|
||||
default:
|
||||
set_register<Channel>(cmd >> 24, cmd & 0x00ffffff);
|
||||
set_register<Path>(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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
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 <int Channel>
|
||||
template <int Path>
|
||||
int mcd212_device::get_plane_width()
|
||||
{
|
||||
const int width = get_screen_width();
|
||||
const uint8_t icm = get_icm<Channel>();
|
||||
const uint8_t icm = get_icm<Path>();
|
||||
if (icm == ICM_CLUT4)
|
||||
return width;
|
||||
return width >> 1;
|
||||
}
|
||||
|
||||
template <int Channel>
|
||||
void mcd212_device::process_vsr(uint32_t *pixels, bool *transparent)
|
||||
template <int Path>
|
||||
void mcd212_device::process_vsr(uint32_t* pixels, bool* transparent)
|
||||
{
|
||||
const uint8_t *data = reinterpret_cast<uint8_t *>(Channel ? m_planeb.target() : m_planea.target());
|
||||
const uint8_t icm = get_icm<Channel>();
|
||||
const uint8_t transp_ctrl = get_transparency_control<Channel>();
|
||||
const int width = get_plane_width<Channel>();
|
||||
const uint8_t* data = reinterpret_cast<uint8_t*>(Path ? m_planeb.target() : m_planea.target());
|
||||
const uint8_t icm = get_icm<Path>();
|
||||
const uint8_t transp_ctrl = get_transparency_control<Path>();
|
||||
const int width = get_screen_width();
|
||||
|
||||
uint32_t vsr = get_vsr<Channel>();
|
||||
uint32_t vsr = get_vsr<Path>();
|
||||
|
||||
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<Channel>();
|
||||
const uint8_t mosaic_factor = get_mosaic_factor<Channel>();
|
||||
const uint8_t mosaic_enable = get_mosaic_enable<Path>();
|
||||
const uint8_t mosaic_factor = get_mosaic_factor<Path>();
|
||||
|
||||
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 Path %d, ICM (%02x), VSR (%08x)\n", screen().vpos(), Path, icm, vsr);
|
||||
|
||||
LOGMASKED(LOG_VSR, "Scanline %d: VSR Channel %d, ICM (%02x), VSR (%08x)\n", screen().vpos(), Channel, 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);
|
||||
}
|
||||
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];
|
||||
|
||||
if (icm == ICM_DYUV)
|
||||
{
|
||||
use_color_key = false;
|
||||
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);
|
||||
|
||||
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];
|
||||
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]];
|
||||
|
||||
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<Channel>(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<Channel>(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<Channel>(vsr - 1);
|
||||
}
|
||||
else if (icm == ICM_CLUT4)
|
||||
{
|
||||
for (; x < width - 1; x += 2)
|
||||
{
|
||||
const uint32_t even_entry = m_clut[BYTE_TO_CLUT<Channel>(icm, byte >> 4)];
|
||||
const uint32_t odd_entry = m_clut[BYTE_TO_CLUT<Channel>(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<Channel>(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<Channel>(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<Channel>(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<Channel>(vsr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_VSR, "Byte %02x, single at %d\n", byte, x);
|
||||
// Single pixel
|
||||
const uint32_t entry = m_clut[BYTE_TO_CLUT<Channel>(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++;
|
||||
|
||||
if (x >= width)
|
||||
{
|
||||
done = true;
|
||||
set_vsr<Channel>(vsr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (icm != ICM_CLUT4)
|
||||
{
|
||||
for (int i = width - 1; i >= 0; i--)
|
||||
else if (icm == ICM_CLUT4)
|
||||
{
|
||||
pixels[i * 2] = pixels[i * 2 + 1] = pixels[i];
|
||||
transparent[i * 2] = transparent[i * 2 + 1] = transparent[i];
|
||||
const uint8_t mask = (decodingMode == DDR_FT_RLE) ? 0x7 : 0xf;
|
||||
color0 = m_clut[BYTE_TO_CLUT<Path>(icm, mask & (byte >> 4))];
|
||||
color1 = m_clut[BYTE_TO_CLUT<Path>(icm, mask & byte)];
|
||||
}
|
||||
else {
|
||||
color1 = color0 = m_clut[BYTE_TO_CLUT<Path>(icm, byte)];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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[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<Path>(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 <int Channel>
|
||||
template <int Path>
|
||||
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++)
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
void map(address_map &map) ATTR_COLD;
|
||||
|
||||
template <int Channel> int ram_dtack_cycle_count();
|
||||
template <int Path> 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 Channel> int get_plane_width();
|
||||
template <int Path> int get_plane_width();
|
||||
|
||||
template <int Channel> void set_vsr(uint32_t value);
|
||||
template <int Channel> uint32_t get_vsr();
|
||||
template <int Path> void set_vsr(uint32_t value);
|
||||
template <int Path> uint32_t get_vsr();
|
||||
|
||||
template <int Channel> void set_dcp(uint32_t value);
|
||||
template <int Channel> uint32_t get_dcp();
|
||||
template <int Path> void set_dcp(uint32_t value);
|
||||
template <int Path> uint32_t get_dcp();
|
||||
|
||||
template <int Channel> void set_display_parameters(uint8_t value);
|
||||
template <int Path> void set_display_parameters(uint8_t value);
|
||||
|
||||
template <int Channel> void process_ica();
|
||||
template <int Channel> void process_dca();
|
||||
template <int Path> void process_ica();
|
||||
template <int Path> void process_dca();
|
||||
|
||||
template <int Channel> uint8_t get_transparency_control();
|
||||
template <int Channel> uint8_t get_icm();
|
||||
template <int Channel> bool get_mosaic_enable();
|
||||
template <int Channel> uint8_t get_mosaic_factor();
|
||||
template <int Channel> void process_vsr(uint32_t *pixels, bool *transparent);
|
||||
template <int Path> uint8_t get_transparency_control();
|
||||
template <int Path> uint8_t get_icm();
|
||||
template <int Path> bool get_mosaic_enable();
|
||||
template <int Path> uint8_t get_mosaic_factor();
|
||||
template <int Path> void process_vsr(uint32_t *pixels, bool *transparent);
|
||||
|
||||
template <int Channel> void set_register(uint8_t reg, uint32_t value);
|
||||
template <int Path> void set_register(uint8_t reg, uint32_t value);
|
||||
|
||||
template <bool MosaicA, bool MosaicB, bool OrderAB> void mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t *plane_b, bool *transparent_b, uint32_t *out);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user