From 75e9b213c3ab46156136942a4ce92c5c2a0c706a Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Sat, 26 Jul 2025 22:29:45 -0700 Subject: [PATCH 1/7] CD-i: Doubles Vertical Resolution Minimal code to double the vertical resolution for #13231 . The result is a slightly crisper looking image on most monitors due to better upscaling on images are have less oblique pixels. This was tested minimally and seems stable. Something closer to a proper interlaced image can be accomplished using the _PA bit, however current screen blanks between frames preventing the parity bit from being able to produce a correct interlace image yet. --- src/mame/philips/cdi.cpp | 2 +- src/mame/philips/mcd212.cpp | 12 ++++++++++-- src/mame/philips/mcd212.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/mame/philips/cdi.cpp b/src/mame/philips/cdi.cpp index 37f74a9b004fd..c25b0087ce2df 100644 --- a/src/mame/philips/cdi.cpp +++ b/src/mame/philips/cdi.cpp @@ -434,7 +434,7 @@ void cdi_state::cdimono1_base(machine_config &config) m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(14976000, 960, 0, 768, 312, 32, 312); + screen.set_raw(14976000*4, 960, 0, 768, 312*2, 32, 312*2); screen.set_video_attributes(VIDEO_UPDATE_SCANLINE); screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update)); diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index dc7623f31c37b..1b188b90404fc 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -965,12 +965,17 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma bool transparent_a[768]; bool transparent_b[768]; - int scanline = screen.vpos(); + if (screen.vpos() >= m_total_height) + { + return 0; // Do nothing on the extended rows. + } + int scanline = screen.vpos(); + // Process VSR and mix if we're in the visible region if (scanline >= m_ica_height) { - uint32_t *out = &bitmap.pix(scanline); + uint32_t *out = &bitmap.pix(((scanline-m_ica_height) << 1)+m_ica_height); bool draw_line = true; if (!BIT(m_dcr[0], DCR_FD_BIT) && BIT(m_csrw[0], CSR1W_ST_BIT)) @@ -1030,6 +1035,9 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma draw_cursor(out); } + // Duplicate lines. This is a placeholder for later interlace support. + uint32_t* out2 = &bitmap.pix(((scanline - m_ica_height) << 1) + m_ica_height + 1); + memcpy(out2, out, 768*4); } // Toggle frame parity at the end of the visible frame (even in non-interlaced mode). diff --git a/src/mame/philips/mcd212.h b/src/mame/philips/mcd212.h index fe81045abec57..378911f679713 100644 --- a/src/mame/philips/mcd212.h +++ b/src/mame/philips/mcd212.h @@ -139,6 +139,7 @@ class mcd212_device : public device_t, MC_OP_SHIFT = 20, CSR1R_PA = 0x20, // Parity + CSR1R_PA_BIT = 5, CSR1R_DA = 0x80, // Display Active CSR1W_BE = 0x0001, // Bus Error From aab6f3e854c9990af6c66b8a6c95c6fcf4be0643 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Sat, 26 Jul 2025 22:37:53 -0700 Subject: [PATCH 2/7] CD-i: Remove excess vertical resolution --- src/mame/philips/cdi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/philips/cdi.cpp b/src/mame/philips/cdi.cpp index c25b0087ce2df..aa0263fac6f67 100644 --- a/src/mame/philips/cdi.cpp +++ b/src/mame/philips/cdi.cpp @@ -434,7 +434,7 @@ void cdi_state::cdimono1_base(machine_config &config) m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(14976000*4, 960, 0, 768, 312*2, 32, 312*2); + screen.set_raw(14976000*4, 960, 0, 768, 312*2-32, 32, 312*2-32); screen.set_video_attributes(VIDEO_UPDATE_SCANLINE); screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update)); From de6ffb50f0c863b2816072f61d1d0afdf1a7e183 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Sat, 26 Jul 2025 22:48:02 -0700 Subject: [PATCH 3/7] Use 2x clock multiplier --- src/mame/philips/cdi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/philips/cdi.cpp b/src/mame/philips/cdi.cpp index aa0263fac6f67..b88d214807f57 100644 --- a/src/mame/philips/cdi.cpp +++ b/src/mame/philips/cdi.cpp @@ -434,7 +434,7 @@ void cdi_state::cdimono1_base(machine_config &config) m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(14976000*4, 960, 0, 768, 312*2-32, 32, 312*2-32); + screen.set_raw(14976000*2, 960, 0, 768, 312*2-32, 32, 312*2-32); screen.set_video_attributes(VIDEO_UPDATE_SCANLINE); screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update)); From d086478e13f2f48ddef0d231680575940d30ab04 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Sun, 27 Jul 2025 20:21:03 -0700 Subject: [PATCH 4/7] CD-i: Add Interlaced Graphics Fixes #13231 --- src/mame/philips/mcd212.cpp | 25 ++++++++++++++++--------- src/mame/philips/mcd212.h | 2 ++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index 1b188b90404fc..3437da621d98b 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -6,7 +6,7 @@ CD-i MCD212 Video Decoder and System Controller emulation ------------------- - written by Ryan Holtz + written by Ryan Holtz, Vincent.Halver ******************************************************************************* @@ -330,13 +330,13 @@ template void mcd212_device::process_ica() { uint16_t *ica = Path ? m_planeb.target() : m_planea.target(); - uint32_t addr = 0x200; - uint32_t cmd = 0; - const int max_to_process = m_ica_height * 120; + // LCT depends on the current frame parity + uint32_t addr = (BIT(m_csrr[0], CSR1R_PA_BIT) == 0) ? 0x200 : 0x202; + for (int i = 0; i < max_to_process; i++) { - cmd = ica[addr++] << 16; + uint32_t cmd = ica[addr++] << 16; cmd |= ica[addr++]; switch ((cmd & 0xff000000) >> 24) { @@ -975,7 +975,9 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma // Process VSR and mix if we're in the visible region if (scanline >= m_ica_height) { - uint32_t *out = &bitmap.pix(((scanline-m_ica_height) << 1)+m_ica_height); + uint32_t bitmap_line = ((scanline - m_ica_height) << 1) + m_ica_height; + uint32_t *out = &bitmap.pix(bitmap_line + (!BIT(m_csrr[0], CSR1R_PA_BIT))); + uint32_t* out2 = &bitmap.pix(bitmap_line + (BIT(m_csrr[0], CSR1R_PA_BIT))); bool draw_line = true; if (!BIT(m_dcr[0], DCR_FD_BIT) && BIT(m_csrw[0], CSR1W_ST_BIT)) @@ -1035,9 +1037,9 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma draw_cursor(out); } - // Duplicate lines. This is a placeholder for later interlace support. - uint32_t* out2 = &bitmap.pix(((scanline - m_ica_height) << 1) + m_ica_height + 1); - memcpy(out2, out, 768*4); + + memcpy(out2, m_interlace_field[scanline], 768 * sizeof(uint32_t)); + memcpy(m_interlace_field[scanline], out, 768 * sizeof(uint32_t)); } // Toggle frame parity at the end of the visible frame (even in non-interlaced mode). @@ -1128,6 +1130,9 @@ void mcd212_device::device_reset() m_ica_height = 32; m_total_height = 312; m_blink_time = 0; + for (int i = 0; i < 312; i++) { + std::fill_n(m_interlace_field[i], 768, 0); + } m_int_callback(CLEAR_LINE); @@ -1207,6 +1212,8 @@ void mcd212_device::device_start() save_item(NAME(m_blink_time)); save_item(NAME(m_blink_active)); + save_item(NAME(m_interlace_field)); + m_dca_timer = timer_alloc(FUNC(mcd212_device::dca_tick), this); m_dca_timer->adjust(attotime::never); diff --git a/src/mame/philips/mcd212.h b/src/mame/philips/mcd212.h index 378911f679713..0158c64c88c00 100644 --- a/src/mame/philips/mcd212.h +++ b/src/mame/philips/mcd212.h @@ -232,6 +232,8 @@ class mcd212_device : public device_t, required_shared_ptr m_planea; required_shared_ptr m_planeb; + uint32_t m_interlace_field[312][768]; + // internal state bool m_matte_flag[2][768]{}; int m_ica_height = 0; From ce5642f099a611fdf1ecbaa6d25fd2dbc8921cb3 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Mon, 28 Jul 2025 17:49:53 -0700 Subject: [PATCH 5/7] CD-i: Toggle Interlace Effect When the interlace bit is off, line-duplication is re-enabled. This ensures the interlace effect is only visible when the game declares the output to be interlaced. --- src/mame/philips/mcd212.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index 3437da621d98b..fcf4db885808a 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -1038,8 +1038,15 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma draw_cursor(out); } - memcpy(out2, m_interlace_field[scanline], 768 * sizeof(uint32_t)); - memcpy(m_interlace_field[scanline], out, 768 * sizeof(uint32_t)); + if (BIT(m_dcr[0], DCR_SM_BIT)) { + // Interlace Output + memcpy(out2, m_interlace_field[scanline], 768 * sizeof(uint32_t)); + memcpy(m_interlace_field[scanline], out, 768 * sizeof(uint32_t)); + } + else { + // Single Field Output (duplicate lines) + memcpy(out2, out, 768 * sizeof(uint32_t)); + } } // Toggle frame parity at the end of the visible frame (even in non-interlaced mode). From 00cff72de04335702f1d0ba84daf7189e9ccd5c7 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Tue, 29 Jul 2025 09:29:51 -0700 Subject: [PATCH 6/7] CD-i: Fix interlaced line offset In some cases, such as during startup, the line length of the interlaced line is impacted. This corrects the offset. --- src/mame/philips/mcd212.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index fcf4db885808a..48eed4e9753bd 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -667,6 +667,10 @@ void mcd212_device::mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t * if (icmB == ICM_CLUT4) { mosaic_count_b >>= 1; } + // If PAL and 'Standard' bit set, insert a 24px border on the left/right + uint32_t offset = (!BIT(m_dcr[0], DCR_CF_BIT) || BIT(m_csrw[0], CSR1W_ST_BIT)) ? 24 : 0; + std::fill_n(out, offset, s_4bpp_color[0]); + out += offset; for (int x = 0; x < width; x++) { @@ -994,12 +998,6 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if (draw_line) { - // If PAL and 'Standard' bit set, insert a 24px border on the left/right - if (!BIT(m_dcr[0], DCR_CF_BIT) || BIT(m_csrw[0], CSR1W_ST_BIT)) - { - std::fill_n(out, 24, s_4bpp_color[0]); - out += 24; - } process_vsr<0>(plane_a, transparent_a); process_vsr<1>(plane_b, transparent_b); From f9e9649f4f68a0d053f4cc2db6f5c4d81ed91101 Mon Sep 17 00:00:00 2001 From: "Vincent.Halver" Date: Fri, 1 Aug 2025 18:00:53 -0700 Subject: [PATCH 7/7] CD-i: Fix Interlace Clock Speed --- src/mame/philips/cdi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/philips/cdi.cpp b/src/mame/philips/cdi.cpp index b88d214807f57..6dd4e64162b49 100644 --- a/src/mame/philips/cdi.cpp +++ b/src/mame/philips/cdi.cpp @@ -434,7 +434,7 @@ void cdi_state::cdimono1_base(machine_config &config) m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(14976000*2, 960, 0, 768, 312*2-32, 32, 312*2-32); + screen.set_raw(960*(312*2-32)*50, 960, 0, 768, 312*2-32, 32, 312*2-32); screen.set_video_attributes(VIDEO_UPDATE_SCANLINE); screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update));