diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..6891ccad5 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,47 @@ +name: Build SAME_CDi iOS dylib + +on: + workflow_dispatch: + +jobs: + build: + runs-on: macos-14 + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Xcode + run: | + sudo xcode-select -s /Applications/Xcode.app + xcodebuild -version + + - name: Install Dependencies + run: | + brew install coreutils + # MAME requires Python for build scripts (GENie) + echo "PYTHON_EXECUTABLE=python3" >> $GITHUB_ENV + + - name: Compile SAME_CDi Libretro Core (iOS arm64) + run: | + # Get iOS SDK path dynamically + IOS_SDK_PATH=$(xcrun --sdk iphoneos --show-sdk-path) + + # Run the Libretro Makefile with explicit iOS overrides + # Using SUBTARGET=arcade keeps compilation faster and prevents GitHub runner timeouts + make -f Makefile.libretro -j$(sysctl -n hw.ncpu) \ + platform=ios-arm64 \ + IOS_SDK_PATH="$IOS_SDK_PATH" + + - name: Locate and Rename Artifact + run: | + mkdir -p output/ + # Libretro cores traditionally output as mame_libretro_ios.dylib or similar + find . -name "*.dylib" -exec cp {} output/ \; + ls -la output/ + + - name: Upload Built Binaries + uses: actions/upload-artifact@v4 + with: + name: samecdi-libretro-ios + path: output/ diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml index 3138a3c4e..50871cca0 100644 --- a/android-project/app/src/main/AndroidManifest.xml +++ b/android-project/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ diff --git a/makefile b/makefile index 25c9108a5..735829134 100644 --- a/makefile +++ b/makefile @@ -1490,7 +1490,7 @@ endif ifeq (posix,$(SHELLTYPE)) $(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS) - @echo '#define BARE_BUILD_VERSION "0.239"' > $@ + @echo '#define BARE_BUILD_VERSION "0.287"' > $@ @echo '#define BARE_VCS_REVISION "$(NEW_GIT_VERSION)"' >> $@ @echo 'extern const char bare_build_version[];' >> $@ @echo 'extern const char bare_vcs_revision[];' >> $@ @@ -1500,7 +1500,7 @@ $(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS) @echo 'const char build_version[] = BARE_BUILD_VERSION " (" BARE_VCS_REVISION ")";' >> $@ else $(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS) - @echo #define BARE_BUILD_VERSION "0.239" > $@ + @echo #define BARE_BUILD_VERSION "0.287" > $@ @echo #define BARE_VCS_REVISION "$(NEW_GIT_VERSION)" >> $@ @echo extern const char bare_build_version[]; >> $@ @echo extern const char bare_vcs_revision[]; >> $@ diff --git a/src/mame/drivers/cdi.cpp b/src/mame/drivers/cdi.cpp index ee057381d..2d220fd29 100644 --- a/src/mame/drivers/cdi.cpp +++ b/src/mame/drivers/cdi.cpp @@ -68,9 +68,6 @@ #define CLOCK_A 30_MHz_XTAL #define LOG_DVC (1 << 1) -#define LOG_QUIZARD_READS (1 << 2) -#define LOG_QUIZARD_WRITES (1 << 3) -#define LOG_QUIZARD_OTHER (1 << 4) #define LOG_UART (1 << 5) #define VERBOSE (0) @@ -139,38 +136,6 @@ INPUT_PORTS_END static INPUT_PORTS_START( cdimono2 ) INPUT_PORTS_END -static INPUT_PORTS_START( quizard ) - PORT_START("P0") - PORT_DIPNAME( 0x07, 0x05, "Settings" ) - PORT_DIPSETTING( 0x00, "1 Coin, 0 Bonus Limit, 0 Bonus Number" ) - PORT_DIPSETTING( 0x01, "2 Coins, 0 Bonus Limit, 0 Bonus Number" ) - PORT_DIPSETTING( 0x02, "1 Coin, 2 Bonus Limit, 1 Bonus Number" ) - PORT_DIPSETTING( 0x03, "1 Coin, 3 Bonus Limit, 1 Bonus Number" ) - PORT_DIPSETTING( 0x04, "1 Coin, 5 Bonus Limit, 1 Bonus Number" ) - PORT_DIPSETTING( 0x05, "1 Coin, 5 Bonus Limit, 2 Bonus Number" ) - PORT_DIPSETTING( 0x06, "1 Coin, 10 Bonus Limit, 2 Bonus Number" ) - PORT_DIPSETTING( 0x07, "2 Coins, 4 Bonus Limit, 1 Bonus Number" ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0xc8, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("P1") - PORT_BIT( 0x1f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 ) - - PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Player 1 A") - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Player 1 B") - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Player 1 C") - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Player 2 A") - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Player 2 B") - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("Player 2 C") - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) -INPUT_PORTS_END - - /*************************** * Machine Initialization * ***************************/ @@ -182,21 +147,6 @@ void cdi_state::machine_reset() memcpy(dst, src, 0x8); } -void quizard_state::machine_start() -{ - save_item(NAME(m_mcu_rx_from_cpu)); - save_item(NAME(m_mcu_initial_byte)); -} - -void quizard_state::machine_reset() -{ - cdi_state::machine_reset(); - - m_mcu_rx_from_cpu = 0x00; - m_mcu_initial_byte = true; -} - - /*************************** * Wait-State Handling * ***************************/ @@ -247,82 +197,6 @@ void cdi_state::bus_error_w(offs_t offset, uint16_t data) } } - -/********************** -* Quizard Protection * -**********************/ - -void quizard_state::mcu_rtsn_from_cpu(int state) -{ -} - -void quizard_state::mcu_rx_from_cpu(uint8_t data) -{ - if (m_mcu_initial_byte) - { - m_mcu_initial_byte = false; - return; - } - - m_mcu_rx_from_cpu = data; - - m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - -uint8_t quizard_state::mcu_p0_r() -{ - const uint8_t data = m_inputs[0]->read(); - return data; -} - -uint8_t quizard_state::mcu_p1_r() -{ - uint8_t data = m_inputs[1]->read(); - if (BIT(~m_inputs[0]->read(), 4)) - data &= ~(1 << 4); - return data; -} - -uint8_t quizard_state::mcu_p2_r() -{ - const uint8_t data = m_inputs[2]->read(); - return data; -} - -uint8_t quizard_state::mcu_p3_r() -{ - return 0x04; -} - -void quizard_state::mcu_p0_w(uint8_t data) -{ -} - -void quizard_state::mcu_p1_w(uint8_t data) -{ -} - -void quizard_state::mcu_p2_w(uint8_t data) -{ -} - -void quizard_state::mcu_p3_w(uint8_t data) -{ - m_maincpu->uart_ctsn(BIT(data, 6)); -} - -void quizard_state::mcu_tx(uint8_t data) -{ - m_maincpu->uart_rx(data); -} - -uint8_t quizard_state::mcu_rx() -{ - uint8_t data = m_mcu_rx_from_cpu; - return data; -} - /************************* * DVC cartridge * *************************/ @@ -547,26 +421,6 @@ void cdi_state::cdimono1(machine_config &config) SOFTWARE_LIST(config, "cd_list").set_original("cdi").set_filter("!DVC"); } -void quizard_state::quizard(machine_config &config) -{ - cdimono1_base(config); - m_maincpu->set_addrmap(AS_PROGRAM, &quizard_state::cdimono1_mem); - m_maincpu->uart_rtsn_callback().set(FUNC(quizard_state::mcu_rtsn_from_cpu)); - m_maincpu->uart_tx_callback().set(FUNC(quizard_state::mcu_rx_from_cpu)); - - I8751(config, m_mcu, 8000000); - m_mcu->port_in_cb<0>().set(FUNC(quizard_state::mcu_p0_r)); - m_mcu->port_in_cb<1>().set(FUNC(quizard_state::mcu_p1_r)); - m_mcu->port_in_cb<2>().set(FUNC(quizard_state::mcu_p2_r)); - m_mcu->port_in_cb<3>().set(FUNC(quizard_state::mcu_p3_r)); - m_mcu->port_out_cb<0>().set(FUNC(quizard_state::mcu_p0_w)); - m_mcu->port_out_cb<1>().set(FUNC(quizard_state::mcu_p1_w)); - m_mcu->port_out_cb<2>().set(FUNC(quizard_state::mcu_p2_w)); - m_mcu->port_out_cb<3>().set(FUNC(quizard_state::mcu_p3_w)); - m_mcu->serial_tx_cb().set(FUNC(quizard_state::mcu_tx)); - m_mcu->serial_rx_cb().set(FUNC(quizard_state::mcu_rx)); -} - /************************* * Rom Load * *************************/ @@ -627,198 +481,6 @@ ROM_START( cdi490a ) ROM_LOAD( "vmpega.rom", 0x0000, 0x40000, CRC(db264e8b) SHA1(be407fbc102f1731a0862554855e963e5a47c17b) ) ROM_END -ROM_START( cdibios ) // for the quizard sets - ROM_REGION(0x80000, "maincpu", 0) - ROM_SYSTEM_BIOS( 0, "mcdi200", "Magnavox CD-i 200" ) - ROMX_LOAD( "cdi200.rom", 0x000000, 0x80000, CRC(40c4e6b9) SHA1(d961de803c89b3d1902d656ceb9ce7c02dccb40a), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "pcdi220", "Philips CD-i 220 F2" ) - ROMX_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e), ROM_BIOS(1) ) - - // The MCU dump below is taken from the cdi910. We still need a dump from a Mono-I board SLAVE MCU in case the revisions are different. - ROM_REGION(0x2000, "slave", 0) - ROM_LOAD( "zx405042p__cdi_slave_2.0__b43t__zzmk9213.mc68hc705c8a_withtestrom.7206", 0x0000, 0x2000, CRC(688cda63) SHA1(56d0acd7caad51c7de703247cd6d842b36173079) BAD_DUMP ) -ROM_END - -/* Quizard notes - - The MCU controls the protection sequence, which in turn controls the game display language. - Each Quizard game (1,2,3,4) requires its own MCU, you can upgrade between revisions by changing - just the CD, but not between games as a new MCU is required. - - MCU Notes: - i8751 MCU dumps confirmed good on original hardware - German language MCUs for Quizard 1 through 4 are dumped - Czech language MCU for Quizard 4 is dumped - Italian language MCU for Quizard 1 is known to exist (IT 11 L2, not dumped) - Alt. German language MCU for Quizard 2 is known to exist (DE 122 D3, not dumped) - -*/ - - -//******************************************************** -// Quizard (1) -//******************************************************** - -ROM_START( quizard ) /* CD-ROM printed ??/?? */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard18", 0, BAD_DUMP SHA1(ede873b22957f2a707bbd3039e962ef2ca5aedbd) ) - - ROM_REGION(0x1000, "mcu", 0) - ROM_LOAD( "de_11_d3.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) ) // German language -ROM_END - -ROM_START( quizard_17 ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard17", 0, BAD_DUMP SHA1(4bd698f076505b4e17be978481bce027eb47123b) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_11_d3.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) ) // German language -ROM_END - -ROM_START( quizard_12 ) /* CD-ROM printed 01/95 */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard12", 0, BAD_DUMP SHA1(6e41683b96b74e903040842aeb18437ad7813c82) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_11_d3.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) ) // German language -ROM_END - -ROM_START( quizard_10 ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - // software: BurnAtOnce 0.99.5 / CHDMAN 0.163 - // Drive: TS-L633R - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard10", 0, SHA1(5715db50f0d5ffe06f47c0943f4bf0481ab6048e) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_11_d3.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) ) // German language -ROM_END - - -//******************************************************** -// Quizard 2 -//******************************************************** - -ROM_START( quizard2 ) /* CD-ROM printed ??/?? */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard23", 0, BAD_DUMP SHA1(cd909d9a54275d6f2d36e03e83eea996e781b4d3) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "dn_122_d3.bin", 0x0000, 0x1000, CRC(d48063ea) SHA1(b512fa5e53f296a180340e09b53613dd1c0d38bc) ) // German language - DE 122 D3 known to exist -ROM_END - -ROM_START( quizard2_22 ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard22", 0, BAD_DUMP SHA1(03c8fdcf27ead6e221691111e8c679b551099543) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "dn_122_d3.bin", 0x0000, 0x1000, CRC(d48063ea) SHA1(b512fa5e53f296a180340e09b53613dd1c0d38bc) ) // German language - DE 122 D3 known to exist -ROM_END - - -//******************************************************** -// Quizard 3 -//******************************************************** - -ROM_START( quizard3 ) /* CD-ROM printed ??/?? */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard34", 0, BAD_DUMP SHA1(37ad49b72b5175afbb87141d57bc8604347fe032) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_132_d3.bin", 0x0000, 0x1000, CRC(8858251e) SHA1(2c1005a74bb6f0c2918dff4ab6326528eea48e1f) ) // German language -ROM_END - -ROM_START( quizard3a ) /* CD-ROM printed ??/?? */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard34", 0, BAD_DUMP SHA1(37ad49b72b5175afbb87141d57bc8604347fe032) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_132_a1.bin", 0x0000, 0x1000, CRC(313ac673) SHA1(cb0ee7e9a6eaa5f4d000f5ea99b7ee4c440b31d1) ) // German language - earlier version of MCU code -ROM_END - -ROM_START( quizard3_32 ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard32", 0, BAD_DUMP SHA1(31e9fa2169aa44d799c37170b238134ab738e1a1) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_132_d3.bin", 0x0000, 0x1000, CRC(8858251e) SHA1(2c1005a74bb6f0c2918dff4ab6326528eea48e1f) ) // German language -ROM_END - - -//******************************************************** -// Quizard 4 -//******************************************************** - -ROM_START( quizard4 ) /* CD-ROM printed 09/98 */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard4r42", 0, BAD_DUMP SHA1(a5d5c8950b4650b8753f9119dc7f1ccaa2aa5442) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_142_d3.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) ) // German language -ROM_END - -ROM_START( quizard4cz ) /* CD-ROM printed 09/98 */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard4r42", 0, BAD_DUMP SHA1(a5d5c8950b4650b8753f9119dc7f1ccaa2aa5442) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "ts142_cz1.bin", 0x0000, 0x1000, CRC(fdc1f457) SHA1(5169c4d2ea4073a854c3f619205161386c9af8af) ) // Czech language - works with all Quizard 4 versions -ROM_END - -ROM_START( quizard4_41 ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard4r41", 0, BAD_DUMP SHA1(2c0484c6545aac8e00b318328c6edce6f5dde43d) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_142_d3.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) ) // German language -ROM_END - -ROM_START( quizard4_40 ) /* CD-ROM printed 07/97 */ - ROM_REGION(0x80000, "maincpu", 0) - ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) ) - - DISK_REGION( "cdrom" ) - DISK_IMAGE_READONLY( "quizard4r40", 0, BAD_DUMP SHA1(288cc37a994e4f1cbd47aa8c92342879c6fc0b87) ) - - ROM_REGION(0x1000, "mcu", 0) // Intel D8751H MCU - ROM_LOAD( "de_142_d3.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) ) // German language -ROM_END - /************************* * Game driver(s) * @@ -830,25 +492,3 @@ CONS( 1991, cdimono1, 0, 0, cdimono1, cdi, cdi_state, empty_init, CONS( 1991, cdimono2, 0, 0, cdimono2, cdimono2, cdi_state, empty_init, "Philips", "CD-i (Mono-II) (NTSC)", MACHINE_NOT_WORKING ) CONS( 1991, cdi910, 0, 0, cdi910, cdimono2, cdi_state, empty_init, "Philips", "CD-i 910-17P Mini-MMC (PAL)", MACHINE_NOT_WORKING ) CONS( 1991, cdi490a, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i 490", MACHINE_NOT_WORKING ) - -// The Quizard games are retail CD-i units in a cabinet, with an additional JAMMA adapter and dongle for protection, hence being clones of the system. -/* YEAR NAME PARENT MACHINE INPUT DEVICE INIT MONITOR COMPANY FULLNAME */ -GAME( 1995, cdibios, 0, cdimono1, quizard, cdi_state, empty_init, ROT0, "Philips", "CD-i (Mono-I) (PAL) BIOS", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IS_BIOS_ROOT ) - -GAME( 1995, quizard, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.8, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND ) -GAME( 1995, quizard_17, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.7, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND ) -GAME( 1995, quizard_12, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.2, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND ) -GAME( 1995, quizard_10, quizard, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard (v1.0, German, i8751 DE 11 D3)", MACHINE_IMPERFECT_SOUND ) - -GAME( 1995, quizard2, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.3, German, i8751 DN 122 D3)", MACHINE_IMPERFECT_SOUND ) -GAME( 1995, quizard2_22, quizard2, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 2 (v2.2, German, i8751 DN 122 D3)", MACHINE_IMPERFECT_SOUND ) - -// Quizard 3 and 4 will hang after starting a game (CDIC issues?) -GAME( 1995, quizard3, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1995, quizard3a, quizard3, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.4, German, i8751 DE 132 A1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1996, quizard3_32, quizard3, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 3 (v3.2, German, i8751 DE 132 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) - -GAME( 1998, quizard4, cdibios, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, quizard4cz, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2, Czech, i8751 TS142 CZ1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, quizard4_41, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.1, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1997, quizard4_40, quizard4, quizard, quizard, quizard_state, empty_init, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.0, German, i8751 DE 142 D3)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/includes/cdi.h b/src/mame/includes/cdi.h index 69e8a8624..60ec6c760 100644 --- a/src/mame/includes/cdi.h +++ b/src/mame/includes/cdi.h @@ -1,8 +1,8 @@ // license:BSD-3-Clause // copyright-holders:Ryan Holtz -#ifndef MAME_INCLUDES_CDI_H -#define MAME_INCLUDES_CDI_H +#ifndef MAME_PHILIPS_CDI_H +#define MAME_PHILIPS_CDI_H #include "machine/scc68070.h" #include "machine/cdislavehle.h" @@ -11,6 +11,7 @@ #include "video/mcd212.h" #include "cpu/mcs51/mcs51.h" #include "cpu/m6805/m68hc05.h" +#include "diserial.h" #include "screen.h" /*----------- driver state -----------*/ @@ -23,11 +24,12 @@ class cdi_state : public driver_device , m_maincpu(*this, "maincpu") , m_main_rom(*this, "maincpu") , m_lcd(*this, "lcd") - , m_plane_ram(*this, "plane%u", 0U) , m_slave_hle(*this, "slave_hle") + , m_plane_ram(*this, "plane%u", 0U) , m_servo(*this, "servo") , m_slave(*this, "slave") , m_cdic(*this, "cdic") + , m_cdrom(*this, "cdrom") , m_mcd212(*this, "mcd212") , m_dmadac(*this, "dac%u", 1U) { } @@ -38,15 +40,6 @@ class cdi_state : public driver_device void cdi910(machine_config &config); protected: - virtual void machine_reset() override; - - void cdimono1_mem(address_map &map); - - required_device m_maincpu; - required_region_ptr m_main_rom; - optional_device m_lcd; - -private: enum servo_portc_bit_t { INV_JUC_OUT = (1 << 2), @@ -54,72 +47,38 @@ class cdi_state : public driver_device INV_CADDYSWITCH_IN = (1 << 7) }; - uint32_t screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - void cdi910_mem(address_map &map); - void cdimono2_mem(address_map &map); - void cdi070_cpuspace(address_map &map); - - template uint16_t plane_r(offs_t offset, uint16_t mem_mask = ~0); - template void plane_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - uint16_t main_rom_r(offs_t offset); - - uint16_t dvc_r(offs_t offset, uint16_t mem_mask = ~0); - void dvc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - uint16_t bus_error_r(offs_t offset); - void bus_error_w(offs_t offset, uint16_t data); - - required_shared_ptr_array m_plane_ram; + required_device m_maincpu; + required_region_ptr m_main_rom; + optional_device m_lcd; optional_device m_slave_hle; + required_shared_ptr_array m_plane_ram; optional_device m_servo; optional_device m_slave; optional_device m_cdic; + required_device m_cdrom; required_device m_mcd212; required_device_array m_dmadac; -}; -class quizard_state : public cdi_state -{ -public: - quizard_state(const machine_config &mconfig, device_type type, const char *tag) - : cdi_state(mconfig, type, tag) - , m_mcu(*this, "mcu") - , m_inputs(*this, "P%u", 0U) - { } + uint32_t screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + virtual void machine_reset() override ATTR_COLD; - void quizard(machine_config &config); + void cdimono1_mem(address_map &map) ATTR_COLD; -private: - virtual void machine_start() override; - virtual void machine_reset() override; + void cdi910_mem(address_map &map) ATTR_COLD; + void cdimono2_mem(address_map &map) ATTR_COLD; + void cdi070_cpuspace(address_map &map) ATTR_COLD; - uint8_t mcu_p0_r(); - uint8_t mcu_p1_r(); - uint8_t mcu_p2_r(); - uint8_t mcu_p3_r(); - void mcu_p0_w(uint8_t data); - void mcu_p1_w(uint8_t data); - void mcu_p2_w(uint8_t data); - void mcu_p3_w(uint8_t data); - void mcu_tx(uint8_t data); - uint8_t mcu_rx(); + template uint16_t plane_r(offs_t offset, uint16_t mem_mask = ~0); + template void plane_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void mcu_rx_from_cpu(uint8_t data); - void mcu_rtsn_from_cpu(int state); + uint16_t main_rom_r(offs_t offset); - required_device m_mcu; - required_ioport_array<3> m_inputs; + uint16_t dvc_r(offs_t offset, uint16_t mem_mask = ~0); + void dvc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint8_t m_mcu_rx_from_cpu; - bool m_mcu_initial_byte; + uint16_t bus_error_r(offs_t offset); + void bus_error_w(offs_t offset, uint16_t data); }; -// Quizard 2 language values: -// 0x2b1: Italian -// 0x001: French -// 0x188: German - -#endif // MAME_INCLUDES_CDI_H +#endif // MAME_PHILIPS_CDI_H diff --git a/src/mame/machine/cdicdic.cpp b/src/mame/machine/cdicdic.cpp index 1aea9112f..7c8cfd92a 100644 --- a/src/mame/machine/cdicdic.cpp +++ b/src/mame/machine/cdicdic.cpp @@ -517,48 +517,40 @@ void cdicdic_device::play_raw_group(const uint8_t *data) void cdicdic_device::play_xa_group(const uint8_t coding, const uint8_t *data) { - static const uint16_t s_4bit_header_offsets[8] = { 0, 1, 2, 3, 8, 9, 10, 11 }; - static const uint16_t s_8bit_header_offsets[4] = { 0, 1, 2, 3 }; - static const uint16_t s_4bit_data_offsets[8] = { 16, 16, 17, 17, 18, 18, 19, 19 }; - static const uint16_t s_8bit_data_offsets[4] = { 16, 17, 18, 19 }; + static const uint16_t HEADER_OFFSET_4BIT[8] = { 4, 5, 6, 7, 12, 13, 14, 15 }; + static const uint16_t HEADER_OFFSET_8BIT[4] = { 4, 5, 6, 7 }; + static const uint16_t DATA_OFFSET_4BIT[8] = { 16, 16, 17, 17, 18, 18, 19, 19 }; + static const uint16_t DATA_OFFSET_8BIT[4] = { 16, 17, 18, 19 }; int16_t samples[28]; + uint8_t num_samples = coding & CODING_8BPS ? 4 : 8; - switch (coding & (CODING_BPS_MASK | CODING_CHAN_MASK)) + for (uint8_t i = 0; i < num_samples; i++) { + switch (coding & (CODING_BPS_MASK | CODING_CHAN_MASK)) + { case CODING_4BPS | CODING_MONO: - for (uint8_t i = 0; i < 8; i++) - { - decode_4bit_xa_unit(0, data[s_4bit_header_offsets[i]], data + s_4bit_data_offsets[i], (i & 1) ? 4 : 0, samples); - m_dmadac[0]->transfer(0, 1, 1, 28, samples); - m_dmadac[1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_4bit_xa_unit(0, data[HEADER_OFFSET_4BIT[i]], data + DATA_OFFSET_4BIT[i], (i & 1) ? 4 : 0, samples); + m_dmadac[0]->transfer(0, 1, 1, 28, samples); + m_dmadac[1]->transfer(0, 1, 1, 28, samples); + break; case CODING_4BPS | CODING_STEREO: - for (uint8_t i = 0; i < 8; i++) - { - decode_4bit_xa_unit(i & 1, data[s_4bit_header_offsets[i]], data + s_4bit_data_offsets[i], (i & 1) ? 4 : 0, samples); - m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_4bit_xa_unit(i & 1, data[HEADER_OFFSET_4BIT[i]], data + DATA_OFFSET_4BIT[i], (i & 1) ? 4 : 0, samples); + m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); + break; case CODING_8BPS | CODING_MONO: - for (uint8_t i = 0; i < 4; i++) - { - decode_8bit_xa_unit(0, data[s_8bit_header_offsets[i]], data + s_8bit_data_offsets[i], samples); - m_dmadac[0]->transfer(0, 1, 1, 28, samples); - m_dmadac[1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_8bit_xa_unit(0, data[HEADER_OFFSET_8BIT[i]], data + DATA_OFFSET_8BIT[i], samples); + m_dmadac[0]->transfer(0, 1, 1, 28, samples); + m_dmadac[1]->transfer(0, 1, 1, 28, samples); + break; case CODING_8BPS | CODING_STEREO: - for (uint8_t i = 0; i < 4; i++) - { - decode_8bit_xa_unit(i & 1, data[s_8bit_header_offsets[i]], data + s_8bit_data_offsets[i], samples); - m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_8bit_xa_unit(i & 1, data[HEADER_OFFSET_8BIT[i]], data + DATA_OFFSET_8BIT[i], samples); + m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); + break; + } } } @@ -569,21 +561,27 @@ void cdicdic_device::play_cdda_sector(const uint8_t *data) m_dmadac[0]->set_volume(0x100); m_dmadac[1]->set_volume(0x100); - int16_t samples[2][2352/4]; - for (uint16_t i = 0; i < 2352/4; i++) + const int16_t NUM_SAMPLES = SECTOR_SIZE / 4; + int16_t samples[2][NUM_SAMPLES]; + for (uint16_t i = 0; i < NUM_SAMPLES; i++) { samples[0][i] = (int16_t)((data[(i * 4) + 1] << 8) | data[(i * 4) + 0]); samples[1][i] = (int16_t)((data[(i * 4) + 3] << 8) | data[(i * 4) + 2]); } - m_dmadac[0]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[0]); - m_dmadac[1]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[1]); + m_dmadac[0]->transfer(0, 1, 1, NUM_SAMPLES, samples[0]); + m_dmadac[1]->transfer(0, 1, 1, NUM_SAMPLES, samples[1]); } void cdicdic_device::play_audio_sector(const uint8_t coding, const uint8_t *data) { if ((coding & CODING_CHAN_MASK) > CODING_STEREO || (coding & CODING_BPS_MASK) == CODING_BPS_MPEG || (coding & CODING_RATE_MASK) == CODING_RATE_RESV) - return; + { + } + + if (coding & 0x40) + { + } int channels = 2; //offs_t buffer_length = 1; @@ -695,7 +693,7 @@ void cdicdic_device::process_audio_map() else { m_decode_addr = 0xffff; - m_audio_sector_counter = m_audio_format_sectors; + m_audio_sector_counter = 0; } if (was_decoding) @@ -1252,7 +1250,7 @@ void cdicdic_device::regs_w(offs_t offset, uint16_t data, uint16_t mem_mask) m_audio_format_sectors = 0; m_audio_sector_counter = 1; m_decoding_audio_map = true; - std::fill_n(&m_xa_last[0], 4, 0); + std::fill_n(m_xa_last, 4, 0); } break; @@ -1283,7 +1281,7 @@ void cdicdic_device::init_disc_read(uint8_t disc_mode) m_disc_command = m_command; m_disc_mode = disc_mode; m_curr_lba = lba_from_time(); - m_disc_spinup_counter = 1; + m_disc_spinup_counter = 6; } void cdicdic_device::cancel_disc_read() diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 023c1e8ca..527054aff 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -12,19 +12,5 @@ @source:cdi.cpp cdi490a // cdi910 // -cdibios // Base unit cdimono1 // Philips CD-i model 200 (Mono-I board, PAL) cdimono2 // Philips CD-i model 220 (Mono-II board, NTSC) -quizard // (c) TAB Austria 199? -quizard_10 // (c) TAB Austria 1996 -quizard_12 // (c) TAB Austria 1996 -quizard_17 // (c) TAB Austria 1996 -quizard2 // (c) TAB Austria 1995 -quizard2_22 // (c) TAB Austria 199? -quizard3 // (c) TAB Austria 1996 -quizard3_32 // (c) TAB Austria 1996 -quizard3a // (c) TAB Austria 1996 -quizard4 // (c) TAB Austria 1998 -quizard4_40 // (c) TAB Austria 1997 -quizard4_41 // (c) TAB Austria 1998 -quizard4cz // (c) TAB Austria 1998 diff --git a/src/mame/video/mcd212.cpp b/src/mame/video/mcd212.cpp index bf1436bbd..6d7ea671e 100644 --- a/src/mame/video/mcd212.cpp +++ b/src/mame/video/mcd212.cpp @@ -17,12 +17,12 @@ TODO: -- Unknown yet. +- QHY DYUV Image Decoder *******************************************************************************/ #include "emu.h" -#include "video/mcd212.h" +#include "mcd212.h" #include "screen.h" #define LOG_UNKNOWNS (1U << 1) @@ -42,178 +42,71 @@ // device type definition DEFINE_DEVICE_TYPE(MCD212, mcd212_device, "mcd212", "MCD212 VDSC") -inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_weight_factor(const uint32_t region_idx) +inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_weight_factor(const uint32_t matte_idx) { - return (uint8_t)((m_region_control[region_idx] & RC_WF) >> RC_WF_SHIFT); + return (uint8_t)((m_matte_control[matte_idx] & MC_WF) >> MC_WF_SHIFT); } -inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_region_op(const uint32_t region_idx) +inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_matte_op(const uint32_t matte_idx) { - return (m_region_control[region_idx] & RC_OP) >> RC_OP_SHIFT; + return (m_matte_control[matte_idx] & MC_OP) >> MC_OP_SHIFT; } -void mcd212_device::update_region_arrays() +void mcd212_device::update_matte_arrays() { - bool latched_rf[2] { false, false }; - uint8_t latched_wfa = m_weight_factor[0][0]; - uint8_t latched_wfb = m_weight_factor[1][0]; const int width = get_screen_width(); + const int num_mattes = BIT(m_image_coding_method, ICM_NM_BIT) ? 2 : 1; - if (BIT(m_image_coding_method, ICM_NR_BIT)) - { - if (get_region_op(0) == 0 && get_region_op(4) == 0) - { - std::fill_n(m_weight_factor[0], std::size(m_weight_factor[0]), latched_wfa); - std::fill_n(m_weight_factor[1], std::size(m_weight_factor[1]), latched_wfb); - std::fill_n(m_region_flag[0], std::size(m_region_flag[0]), false); - std::fill_n(m_region_flag[1], std::size(m_region_flag[1]), false); - return; - } + bool latched_mf[2]{ false, false }; + uint8_t latched_wf[2] = { m_weight_factor[0][0], m_weight_factor[1][0] }; + int matte_idx[2] = { 0, 4 }; - for (int x = 0; x < width; x++) + for (int x = 0; x < width; x++) + { + for (int matte = 0; matte < num_mattes; matte++) { - for (int flag = 0; flag < 2; flag++) + const int max_matte_id = ((num_mattes == 2) ? 4 : 8) + (matte ? 4 : 0); + if (matte_idx[matte] >= max_matte_id) { - for (int region = 0; region < 4; region++) - { - const int region_idx = (flag << 2) + region; - const uint32_t region_ctrl = m_region_control[region_idx]; - const uint32_t region_op = get_region_op(region_idx); - if (region_op == 0) - { - break; - } - if (x == (region_ctrl & RC_X)) - { - switch (region_op) - { - case 0: // End of region control for line - break; - case 1: - case 2: - case 3: // Not used - break; - case 4: // Change weight of plane A - latched_wfa = get_weight_factor(region_idx); - break; - case 5: // Not used - break; - case 6: // Change weight of plane B - latched_wfb = get_weight_factor(region_idx); - break; - case 7: // Not used - break; - case 8: // Reset region flag - latched_rf[flag] = false; - break; - case 9: // Set region flag - latched_rf[flag] = true; - break; - case 10: // Not used - case 11: // Not used - break; - case 12: // Reset region flag and change weight of plane A - latched_wfa = get_weight_factor(region_idx); - latched_rf[flag] = false; - break; - case 13: // Set region flag and change weight of plane A - latched_wfa = get_weight_factor(region_idx); - latched_rf[flag] = true; - break; - case 14: // Reset region flag and change weight of plane B - latched_wfb = get_weight_factor(region_idx); - latched_rf[flag] = false; - break; - case 15: // Set region flag and change weight of plane B - latched_wfb = get_weight_factor(region_idx); - latched_rf[flag] = true; - break; - } - } - } + continue; } - m_weight_factor[0][x] = latched_wfa; - m_weight_factor[1][x] = latched_wfb; - m_region_flag[0][x] = latched_rf[0]; - m_region_flag[1][x] = latched_rf[1]; - } - } - else - { - int region_idx = 0; - for (int x = 0; x < width; x++) - { - if (region_idx < 8) + const uint32_t matte_ctrl = m_matte_control[matte_idx[matte]]; + + if (x == (matte_ctrl & MC_X)) { - const int flag = BIT(m_region_control[region_idx], RC_RF_BIT); - const uint32_t region_ctrl = m_region_control[region_idx]; - const uint32_t region_op = get_region_op(region_idx); - if (region_op == 0) - { - std::fill_n(m_weight_factor[0] + x, std::size(m_weight_factor[0]) - x, latched_wfa); - std::fill_n(m_weight_factor[1] + x, std::size(m_weight_factor[1]) - x, latched_wfb); - std::fill_n(m_region_flag[0] + x, std::size(m_region_flag[0]) - x, latched_rf[0]); - std::fill_n(m_region_flag[1] + x, std::size(m_region_flag[1]) - x, latched_rf[1]); - return; - } - if (x == (region_ctrl & RC_X)) + const uint32_t matte_op = get_matte_op(matte_idx[matte]); + const int flag = (num_mattes == 2) ? matte : BIT(m_matte_control[matte_idx[matte]], MC_MF_BIT); + // See 5.10.2 Matte Commands. Changing the MF-bit inside a line is undefined. Greenbook says don't do it. + // Console validation shows the 220 reads and uses this value anyway. + switch (matte_op) { - switch (region_op) - { - case 0: // End of region control for line - break; - case 1: - case 2: - case 3: // Not used - break; - case 4: // Change weight of plane A - latched_wfa = get_weight_factor(region_idx); - break; - case 5: // Not used - break; - case 6: // Change weight of plane B - latched_wfb = get_weight_factor(region_idx); - break; - case 7: // Not used - break; - case 8: // Reset region flag - latched_rf[flag] = false; - break; - case 9: // Set region flag - latched_rf[flag] = true; - break; - case 10: // Not used - case 11: // Not used - break; - case 12: // Reset region flag and change weight of plane A - latched_wfa = get_weight_factor(region_idx); - latched_rf[flag] = false; - break; - case 13: // Set region flag and change weight of plane A - latched_wfa = get_weight_factor(region_idx); - latched_rf[flag] = true; - break; - case 14: // Reset region flag and change weight of plane B - latched_wfb = get_weight_factor(region_idx); - latched_rf[flag] = false; - break; - case 15: // Set region flag and change weight of plane B - latched_wfb = get_weight_factor(region_idx); - latched_rf[flag] = true; - break; - } - region_idx++; + case 0: // Disregard all commands in higher registers. See 5.10.2 + matte_idx[matte] = 8; + break; + case 1: case 2: case 3: case 5: case 7: case 10: case 11: // Not used + break; + case 4: case 6: // Change weight of plane (A or B) + latched_wf[BIT(matte_op, 1)] = get_weight_factor(matte_idx[matte]); + break; + case 8: case 9: // (Reset or Set) matte flag + latched_mf[flag] = BIT(matte_op, 0); + break; + case 12: case 13: case 14: case 15: // Change weight of plane (A or B) and (Reset or Set) matte flag + latched_wf[BIT(matte_op, 1)] = get_weight_factor(matte_idx[matte]); + latched_mf[flag] = BIT(matte_op, 0); + break; } + matte_idx[matte]++; } - m_weight_factor[0][x] = latched_wfa; - m_weight_factor[1][x] = latched_wfb; - m_region_flag[0][x] = latched_rf[0]; - m_region_flag[1][x] = latched_rf[1]; } + m_weight_factor[0][x] = latched_wf[0]; + m_weight_factor[1][x] = latched_wf[1]; + m_matte_flag[0][x] = latched_mf[0]; + m_matte_flag[1][x] = latched_mf[1]; } } -template +template void mcd212_device::set_register(uint8_t reg, uint32_t value) { switch (reg) @@ -227,86 +120,100 @@ 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); + 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: 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, 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, Path 0: Plane Order = %08x\n", machine().describe_context(), screen().vpos(), value & 7); m_plane_order = value & 0x00000007; } break; case 0xc3: // CLUT Bank Register - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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; - case 0xd0: // Region Control 0-7 + case 0xd0: // matte Control 0-7 case 0xd1: case 0xd2: case 0xd3: @@ -314,79 +221,85 @@ void mcd212_device::set_register(uint8_t reg, uint32_t value) case 0xd5: case 0xd6: case 0xd7: - m_region_control[reg & 7] = value; - update_region_arrays(); + LOGMASKED(LOG_REGISTERS, "%s: Scanline %d, Path %d: matte Control %d = %08x\n", machine().describe_context(), screen().vpos(), Path, reg & 7, value); + m_matte_control[reg & 7] = value; + update_matte_arrays(); break; case 0xd8: // Backdrop Color - if (Channel == 0) + if (Path == 0) { + 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, 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, 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, Path 0: Weight Factor A = %08x\n", machine().describe_context(), screen().vpos(), value); m_weight_factor[0][0] = (uint8_t)value; - update_region_arrays(); + update_matte_arrays(); } break; case 0xdc: // Weight Factor B - if (Channel == 1) + if (Path == 1) { + 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(); + update_matte_arrays(); } break; } } -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() @@ -405,10 +318,18 @@ int mcd212_device::get_border_width() return width; } -template +uint32_t mcd212_device::get_backdrop_plane() +{ + if (BIT(m_image_coding_method, ICM_EV_BIT)) + return 0; // External Video Background. Default to Black since there is no DVC. + else + return s_4bpp_color[m_backdrop_color]; +} + +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; @@ -421,53 +342,64 @@ 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 + 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 + 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: - 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: - 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 + 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: - 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: - 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 - 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: - 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(), Path); + while (processing && count < max) { cmd = dca[addr++] << 16; @@ -477,38 +409,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 + 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 + 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 + 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: - 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: - 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: - 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: - 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 - 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; } } @@ -518,323 +459,186 @@ void mcd212_device::process_dca() addr += (max - count) >> 1; } - m_dca[Channel] = addr * 2; + m_dca[Path] = addr * 2; } -template -static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte) +template +static inline uint8_t BYTE_TO_CLUT(int icm, uint8_t byte, bool clut_select) { switch (icm) { - case 1: - return byte; - case 3: - if (Channel == 1) - { - return 0x80 + (byte & 0x7f); - } - else - { - return byte & 0x7f; - } - case 4: - if (Channel == 0) - { - return byte & 0x7f; - } - break; - case 11: - if (Channel == 1) - { - return 0x80 + (byte & 0x0f); - } - else - { - return byte & 0x0f; - } - default: - break; + case 1: + return byte; + case 3: + return (Path ? 0x80 : 0) | (byte & 0x7f); + case 4: + if (Path == 0) + { + return (clut_select ? 0x80 : 0) | (byte & 0x7f); + } + break; + case 11: + return (Path ? 0x80 : 0) | (byte & 0x0f); + default: + break; } 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 -int mcd212_device::get_plane_width() -{ - const int width = get_screen_width(); - const uint8_t icm = get_icm(); - if (icm == ICM_CLUT4) - return width; - return width >> 1; -} - -template +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 *data2 = reinterpret_cast(!Path ? m_planeb.target() : m_planea.target()); + const uint8_t icm = get_icm(); + const uint8_t tp_ctrl = get_transparency_control(); + const int width = get_screen_width(); - uint32_t vsr = get_vsr(); + uint32_t vsr = get_vsr(); + uint32_t vsr2 = get_vsr(); - if (transp_ctrl == TCR_COND_1) + if (tp_ctrl == TCR_ALWAYS || !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[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; - const uint32_t dyuv_abs_start = m_dyuv_abs_start[Channel]; - const uint8_t start_y = (dyuv_abs_start >> 16) & 0x000000ff; - const uint8_t start_u = (dyuv_abs_start >> 8) & 0x000000ff; - const uint8_t start_v = (dyuv_abs_start >> 0) & 0x000000ff; + const uint32_t mask_bits = (~m_mask_color[Path]) & 0x00fcfcfc; + const uint32_t tp_color_match = m_transparent_color[Path] & mask_bits; + const uint8_t tp_ctrl_type = tp_ctrl & 0x07; - const uint32_t transparent_color = m_transparent_color[Channel]; - 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 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); + const bool use_rgb_tp_bit = (tp_ctrl_type == TCR_RGB); + const bool tp_check_parity = !BIT(tp_ctrl, 3); + const bool tp_always = ((tp_ctrl_type == TCR_ALWAYS) && tp_check_parity); + const int matte_flag_index = BIT(~tp_ctrl_type, 0); + const bool *const matte_flags = m_matte_flag[matte_flag_index]; + const bool use_matte_flag = (tp_ctrl_type >= TCR_MF0 && tp_ctrl_type <= TCR_MF1_KEY1); + const bool is_dyuv_rgb = (icm == ICM_DYUV) || ((icm == ICM_RGB555) && (Path == 1)); // DYUV and RGB do not have access to color key. + const bool use_color_key = !is_dyuv_rgb && ((tp_ctrl_type == TCR_KEY) || (tp_ctrl_type == TCR_MF0_KEY1) || (tp_ctrl_type == TCR_MF1_KEY1)); - bool done = false; - int x = 0; + 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]; - vsr++; - switch (m_ddr[Channel] & DDR_FT) + const uint8_t byte = data[(vsr++ & 0x0007ffff) ^ 1]; + uint32_t color0 = 0; + uint32_t color1 = 0; + bool rgb_tp_bit = false; + if (icm == ICM_DYUV) { - case DDR_FT_BMP: - case DDR_FT_BMP2: - case DDR_FT_MOSAIC: - if (icm == ICM_DYUV) - { - use_color_key = false; - - uint8_t y = start_y; - uint8_t u = start_u; - uint8_t v = start_v; - 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]; - - const uint8_t u0 = (u + u1) >> 1; - const uint8_t v0 = (v + v1) >> 1; - - uint32_t *limit_r = m_dyuv_limit_r_lut + y0 + 0xff; - uint32_t *limit_g = m_dyuv_limit_g_lut + y0 + 0xff; - uint32_t *limit_b = m_dyuv_limit_b_lut + y0 + 0xff; - - uint32_t entry = limit_r[m_dyuv_v_to_r[v0]] | limit_g[m_dyuv_u_to_g[u0] + m_dyuv_v_to_g[v0]] | limit_b[m_dyuv_u_to_b[u0]]; - pixels[x] = entry; - transparent[x] = (transp_always || (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 << 1]; - } - x += mosaic_factor; - } - else - { - x++; - } - - limit_r = m_dyuv_limit_r_lut + y1 + 0xff; - limit_g = m_dyuv_limit_g_lut + y1 + 0xff; - limit_b = m_dyuv_limit_b_lut + y1 + 0xff; - - entry = limit_r[m_dyuv_v_to_r[v1]] | limit_g[m_dyuv_u_to_g[u1] + m_dyuv_v_to_g[v1]] | limit_b[m_dyuv_u_to_b[u1]]; - pixels[x] = entry; - transparent[x] = (transp_always || (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]; - - 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: - if (byte & 0x80) - { - // Run length - uint8_t length = data[((vsr++) & 0x0007ffff) ^ 1]; - 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 - { - // 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++; - - if (x >= width) - { - done = true; - set_vsr(vsr); - } - } - break; + const uint8_t byte1 = data[(vsr++ & 0x0007ffff) ^ 1]; + const uint8_t y2 = y + m_delta_y_lut[byte]; + y = y2 + m_delta_y_lut[byte1]; + u += m_delta_uv_lut[byte]; + v += m_delta_uv_lut[byte1]; + + const uint32_t *limit_rgb = m_dyuv_limit_lut + y2 + 0x100; + const uint32_t *limit_rgb2 = m_dyuv_limit_lut + y + 0x100; + + color0 = (limit_rgb[m_dyuv_v_to_r[v]] << 16) | (limit_rgb[m_dyuv_u_to_g[u] + m_dyuv_v_to_g[v]] << 8) | limit_rgb[m_dyuv_u_to_b[u]]; + + const uint8_t byte2 = data[(vsr & 0x0007ffff) ^ 1]; // Peek ahead, for calculating the half-step. + const uint8_t byte3 = data[((vsr + 1) & 0x0007ffff) ^ 1]; + const uint8_t u8 = u + m_delta_uv_lut[byte2]; + const uint8_t v8 = v + m_delta_uv_lut[byte3]; + const uint8_t u6 = (u >> 1) + (u8 >> 1) + (u & u8 & 1); + const uint8_t v6 = (v >> 1) + (v8 >> 1) + (v & v8 & 1); + + color1 = (limit_rgb2[m_dyuv_v_to_r[v6]] << 16) | (limit_rgb2[m_dyuv_u_to_g[u6] + m_dyuv_v_to_g[v6]] << 8) | limit_rgb2[m_dyuv_u_to_b[u6]]; + + // TODO: Does not support QHY + pixels[x] = color0; + pixels[x + 1] = color0; + pixels[x + 2] = color1; + pixels[x + 3] = color1; + transparent[x ] = tp_always || (use_matte_flag && (matte_flags[x ] == tp_check_parity)); + transparent[x + 1] = tp_always || (use_matte_flag && (matte_flags[x + 1] == tp_check_parity)); + transparent[x + 2] = tp_always || (use_matte_flag && (matte_flags[x + 2] == tp_check_parity)); + transparent[x + 3] = tp_always || (use_matte_flag && (matte_flags[x + 3] == tp_check_parity)); + x += 4; } - } - - if (icm != ICM_CLUT4) - { - for (int i = width - 1; i >= 0; i--) + else { - pixels[i * 2] = pixels[i * 2 + 1] = pixels[i]; - transparent[i * 2] = transparent[i * 2 + 1] = transparent[i]; + bool clut_select = BIT(m_image_coding_method, ICM_CS_BIT); + if (icm == ICM_RGB555 && Path == 1) + { + const uint8_t byte1 = data2[(vsr2++ & 0x0007ffff) ^ 1]; + const uint8_t blue = (byte & 0b11111) << 3; + const uint8_t green = ((byte & 0b11100000) >> 2) + ((byte1 & 0b11) << 6); + const uint8_t red = (byte1 & 0b01111100) << 1; + rgb_tp_bit = (use_rgb_tp_bit && (BIT(byte1,7) == tp_check_parity)); + color1 = color0 = (uint32_t(red) << 16) | (uint32_t(green) << 8) | blue; + } + 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), clut_select)]; + color1 = m_clut[BYTE_TO_CLUT(icm, mask & byte, clut_select)]; + } + else + { + color1 = color0 = m_clut[BYTE_TO_CLUT(icm, byte, clut_select)]; + } + + int length_m = mosaic_enable ? (mosaic_factor * 2) : 2; + if (decodingMode == DDR_FT_RLE) + { + const uint16_t length = (byte & 0x80) ? data[((vsr++) & 0x0007ffff) ^ 1] : 1; + length_m = length ? (length * 2) : width; + } + + const bool color_match0 = ((mask_bits & color0) == tp_color_match) == tp_check_parity; + const bool color_match1 = ((mask_bits & color1) == tp_color_match) == tp_check_parity; + const int end = std::min(width, x + length_m); + for (int rl_index = x; rl_index < end; rl_index += 2) + { + pixels[rl_index ] = color0; + pixels[rl_index + 1] = color1; + transparent[rl_index ] = tp_always || rgb_tp_bit || (use_color_key && color_match0) || (use_matte_flag && (matte_flags[rl_index ] == tp_check_parity)); + transparent[rl_index + 1] = tp_always || rgb_tp_bit || (use_color_key && color_match1) || (use_matte_flag && (matte_flags[rl_index + 1] == tp_check_parity)); + } + x = end; } } + set_vsr(vsr); + set_vsr(vsr2); } const uint32_t mcd212_device::s_4bpp_color[16] = @@ -846,152 +650,110 @@ const uint32_t mcd212_device::s_4bpp_color[16] = template void mcd212_device::mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t *plane_b, bool *transparent_b, uint32_t *out) { - const uint32_t backdrop = s_4bpp_color[m_backdrop_color]; - const uint8_t mosaic_count_a = (m_mosaic_hold[0] & 0x0000ff) << 1; - const uint8_t mosaic_count_b = (m_mosaic_hold[1] & 0x0000ff) << 1; + const uint8_t icmA = get_icm<0>(); + const uint8_t icmB = get_icm<1>(); + uint16_t mosaic_count_a = (m_mosaic_hold[0] & 0x0000ff) << 1; + uint16_t mosaic_count_b = (m_mosaic_hold[1] & 0x0000ff) << 1; const int width = get_screen_width(); const int border_width = get_border_width(); uint8_t *weight_a = &m_weight_factor[0][0]; uint8_t *weight_b = &m_weight_factor[1][0]; - if (!(m_transparency_control & TCR_DISABLE_MX)) + // Console Verified. CLUT4 pixels are drawn in pairs during VSR. So the mosaic here is halved. + if (icmA == ICM_CLUT4) + mosaic_count_a >>= 1; + if (icmB == ICM_CLUT4) + mosaic_count_b >>= 1; + + for (int x = 0; x < width; x++) { - for (int x = 0; x < width; x++, weight_a++, transparent_a++, weight_b++, transparent_b++) + if (transparent_a[x] && transparent_b[x]) { - const uint8_t weight_a_cur = *weight_a; - const uint8_t weight_b_cur = *weight_b; - - const uint32_t plane_a_cur = plane_a[x]; - const uint32_t plane_b_cur = plane_b[x]; - - const int32_t plane_a_r = (int32_t)(uint8_t)(plane_a_cur >> 16); - const int32_t plane_b_r = (int32_t)(uint8_t)(plane_b_cur >> 16); - const int32_t plane_a_g = (int32_t)(uint8_t)(plane_a_cur >> 8); - const int32_t plane_b_g = (int32_t)(uint8_t)(plane_b_cur >> 8); - const int32_t plane_a_b = (int32_t)(uint8_t)plane_a_cur; - const int32_t plane_b_b = (int32_t)(uint8_t)plane_b_cur; - const int32_t weighted_a_r = (plane_a_r > 16) ? (((plane_a_r - 16) * weight_a_cur) >> 6) : 0; - const int32_t weighted_a_g = (plane_a_g > 16) ? (((plane_a_g - 16) * weight_a_cur) >> 6) : 0; - const int32_t weighted_a_b = (plane_a_b > 16) ? (((plane_a_b - 16) * weight_a_cur) >> 6) : 0; - const int32_t weighted_b_r = ((plane_b_r > 16) ? (((plane_b_r - 16) * weight_b_cur) >> 6) : 0) + weighted_a_r; - const int32_t weighted_b_g = ((plane_b_g > 16) ? (((plane_b_g - 16) * weight_b_cur) >> 6) : 0) + weighted_a_g; - const int32_t weighted_b_b = ((plane_b_b > 16) ? (((plane_b_b - 16) * weight_b_cur) >> 6) : 0) + weighted_a_b; - const uint8_t out_r = (weighted_b_r > 255) ? 255 : (uint8_t)weighted_b_r; - const uint8_t out_g = (weighted_b_g > 255) ? 255 : (uint8_t)weighted_b_g; - const uint8_t out_b = (weighted_b_b > 255) ? 255 : (uint8_t)weighted_b_b; - *out++ = 0xff000000 | (out_r << 16) | (out_g << 8) | out_b; + out[x] = get_backdrop_plane(); + continue; } - } - else - { - for (int x = 0; x < width; x++, weight_a++, transparent_a++, weight_b++, transparent_b++) + uint32_t plane_a_cur = MosaicA ? plane_a[x - (x % mosaic_count_a)] : plane_a[x]; + uint32_t plane_b_cur = MosaicB ? plane_b[x - (x % mosaic_count_b)] : plane_b[x]; + + if (transparent_a[x]) { - if (OrderAB) - { - if (!(*transparent_a)) - { - const uint32_t plane_a_cur = MosaicA ? plane_a[x - (x % mosaic_count_a)] : plane_a[x]; - const uint8_t weight_a_cur = *weight_a; - const int32_t plane_a_r = (int32_t)(uint8_t)(plane_a_cur >> 16); - const int32_t plane_a_g = (int32_t)(uint8_t)(plane_a_cur >> 8); - const int32_t plane_a_b = (int32_t)(uint8_t)plane_a_cur; - const uint8_t weighted_a_r = std::clamp(((plane_a_r > 16) ? (((plane_a_r - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_a_g = std::clamp(((plane_a_g > 16) ? (((plane_a_g - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_a_b = std::clamp(((plane_a_b > 16) ? (((plane_a_b - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - *out++ = 0xff000000 | (weighted_a_r << 16) | (weighted_a_g << 8) | weighted_a_b; - } - else if (!(*transparent_b)) - { - const uint32_t plane_b_cur = MosaicB ? plane_b[x - (x % mosaic_count_b)] : plane_b[x]; - const uint8_t weight_b_cur = *weight_b; - const int32_t plane_b_r = (int32_t)(uint8_t)(plane_b_cur >> 16); - const int32_t plane_b_g = (int32_t)(uint8_t)(plane_b_cur >> 8); - const int32_t plane_b_b = (int32_t)(uint8_t)plane_b_cur; - const uint8_t weighted_b_r = std::clamp(((plane_b_r > 16) ? (((plane_b_r - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_b_g = std::clamp(((plane_b_g > 16) ? (((plane_b_g - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_b_b = std::clamp(((plane_b_b > 16) ? (((plane_b_b - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - *out++ = 0xff000000 | (weighted_b_r << 16) | (weighted_b_g << 8) | weighted_b_b; - } - else - { - *out++ = backdrop; - } - } - else - { - if (!(*transparent_b)) - { - const uint32_t plane_b_cur = MosaicB ? plane_b[x - (x % mosaic_count_b)] : plane_b[x]; - const uint8_t weight_b_cur = *weight_b; - const int32_t plane_b_r = (int32_t)(uint8_t)(plane_b_cur >> 16); - const int32_t plane_b_g = (int32_t)(uint8_t)(plane_b_cur >> 8); - const int32_t plane_b_b = (int32_t)(uint8_t)plane_b_cur; - const uint8_t weighted_b_r = std::clamp(((plane_b_r > 16) ? (((plane_b_r - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_b_g = std::clamp(((plane_b_g > 16) ? (((plane_b_g - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_b_b = std::clamp(((plane_b_b > 16) ? (((plane_b_b - 16) * weight_b_cur) >> 6) : 0) + 16, 0, 255); - *out++ = 0xff000000 | (weighted_b_r << 16) | (weighted_b_g << 8) | weighted_b_b; - } - else if (!(*transparent_a)) - { - const uint32_t plane_a_cur = MosaicA ? plane_a[x - (x % mosaic_count_a)] : plane_a[x]; - const uint8_t weight_a_cur = *weight_a; - const int32_t plane_a_r = (int32_t)(uint8_t)(plane_a_cur >> 16); - const int32_t plane_a_g = (int32_t)(uint8_t)(plane_a_cur >> 8); - const int32_t plane_a_b = (int32_t)(uint8_t)plane_a_cur; - const uint8_t weighted_a_r = std::clamp(((plane_a_r > 16) ? (((plane_a_r - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_a_g = std::clamp(((plane_a_g > 16) ? (((plane_a_g - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - const uint8_t weighted_a_b = std::clamp(((plane_a_b > 16) ? (((plane_a_b - 16) * weight_a_cur) >> 6) : 0) + 16, 0, 255); - *out++ = 0xff000000 | (weighted_a_r << 16) | (weighted_a_g << 8) | weighted_a_b; - } - else - { - *out++ = backdrop; - } - } + plane_a_cur = 0; + } + else if (OrderAB && (m_transparency_control & TCR_DISABLE_MX)) + { + plane_b_cur = 0; } + + if (transparent_b[x]) + { + plane_b_cur = 0; + } + else if (!OrderAB && (m_transparency_control & TCR_DISABLE_MX)) + { + plane_a_cur = 0; + } + + const int32_t plane_a_r = 0xff & (plane_a_cur >> 16); + const int32_t plane_a_g = 0xff & (plane_a_cur >> 8); + const int32_t plane_a_b = 0xff & plane_a_cur; + const int32_t plane_b_r = 0xff & (plane_b_cur >> 16); + const int32_t plane_b_g = 0xff & (plane_b_cur >> 8); + const int32_t plane_b_b = 0xff & plane_b_cur; + + const int32_t weighted_a_r = std::clamp((std::clamp(plane_a_r - 16, 0, 255) * weight_a[x]) >> 6, 0, 255); + const int32_t weighted_a_g = std::clamp((std::clamp(plane_a_g - 16, 0, 255) * weight_a[x]) >> 6, 0, 255); + const int32_t weighted_a_b = std::clamp((std::clamp(plane_a_b - 16, 0, 255) * weight_a[x]) >> 6, 0, 255); + + const int32_t weighted_b_r = std::clamp((std::clamp(plane_b_r - 16, 0, 255) * weight_b[x]) >> 6, 0, 255); + const int32_t weighted_b_g = std::clamp((std::clamp(plane_b_g - 16, 0, 255) * weight_b[x]) >> 6, 0, 255); + const int32_t weighted_b_b = std::clamp((std::clamp(plane_b_b - 16, 0, 255) * weight_b[x]) >> 6, 0, 255); + + const uint8_t out_r = std::clamp(weighted_a_r + weighted_b_r + 16, 0, 255); + const uint8_t out_g = std::clamp(weighted_a_g + weighted_b_g + 16, 0, 255); + const uint8_t out_b = std::clamp(weighted_a_b + weighted_b_b + 16, 0, 255); + out[x] = 0xff000000 | (out_r << 16) | (out_g << 8) | out_b; } if (border_width) { - std::fill_n(out, border_width, 0xff101010); + std::fill_n(&out[width], border_width, s_4bpp_color[0]); } } void mcd212_device::draw_cursor(uint32_t *scanline) { - if (m_cursor_control & CURCNT_EN) + if (!(m_cursor_control & CURCNT_EN)) + return; // Cursor is Disabled + + uint8_t color_index = m_cursor_control & CURCNT_COLOR; + if (m_blink_active) + { + const bool invert = BIT(m_cursor_control, CURCNT_BLKC_SHIFT); + if (!invert) + return; // Normal Blink + else + color_index = color_index ^ 0x7; // Inverted Color Blink. MCD212 Section 7.5 + } + + const uint16_t cursor_x = m_cursor_position & 0x3ff; + const uint16_t cursor_y = ((m_cursor_position >> 12) & 0x3ff) + m_ica_height; + const int32_t y = screen().vpos() - cursor_y; + const int width = get_screen_width(); + + if ((0 <= y) && (y < 16)) { - uint16_t y = (uint16_t)screen().vpos(); - const uint16_t cursor_x = m_cursor_position & 0x3ff; - const uint16_t cursor_y = ((m_cursor_position >> 12) & 0x3ff) + m_ica_height; - if (y >= cursor_y && y < (cursor_y + 16)) + const uint32_t color = s_4bpp_color[color_index]; + const uint8_t resolution = (m_cursor_control & CURCNT_CUW) ? 1 : 2; + for (int x = 0; x < 16; x++) { - const int width = get_screen_width(); - uint32_t color = s_4bpp_color[m_cursor_control & CURCNT_COLOR]; - y -= cursor_y; - if (m_cursor_control & CURCNT_CUW) + if (BIT(m_cursor_pattern[y], 15 - x)) { - for (int x = cursor_x; x < cursor_x + 64 && x < width; x++) + for (uint32_t j = 0; j < resolution; j++) { - if (m_cursor_pattern[y] & (1 << (15 - ((x - cursor_x) >> 2)))) - { - scanline[x++] = color; - scanline[x++] = color; - scanline[x++] = color; - scanline[x] = color; - } - } - } - else - { - for (int x = cursor_x; x < cursor_x + 32 && x < width; x++) - { - if (m_cursor_pattern[y] & (1 << (15 - ((x - cursor_x) >> 1)))) - { - scanline[x++] = color; - scanline[x] = color; - } + const uint32_t index = cursor_x + x * resolution + j; + if (index < width) + scanline[index] = color; } } } @@ -1017,51 +779,61 @@ void mcd212_device::map(address_map &map) uint8_t mcd212_device::csr1_r() { + LOGMASKED(LOG_STATUS, "%s: Control/Status Register 1 Read: %02x\n", machine().describe_context(), m_csrr[0]); return m_csrr[0]; } void mcd212_device::csr1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Control/Status Register 1 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_csrw[0]); } uint16_t mcd212_device::dcr1_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Display Command Register 1 Read: %04x & %08x\n", machine().describe_context(), m_dcr[0], mem_mask); return m_dcr[0]; } void mcd212_device::dcr1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Display Command Register 1 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_dcr[0]); } uint16_t mcd212_device::vsr1_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Video Start Register 1 Read: %04x & %08x\n", machine().describe_context(), m_vsr[0], mem_mask); return m_vsr[0]; } void mcd212_device::vsr1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Video Start Register 1 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_vsr[0]); } uint16_t mcd212_device::ddr1_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Display Decoder Register 1 Read: %04x & %08x\n", machine().describe_context(), m_ddr[0], mem_mask); return m_ddr[0]; } void mcd212_device::ddr1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Display Decoder Register 1 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_ddr[0]); } uint16_t mcd212_device::dca1_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: DCA Pointer 1 Read: %04x & %08x\n", machine().describe_context(), m_dca[0], mem_mask); return m_dca[0]; } void mcd212_device::dca1_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: DCA Pointer 1 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_dca[0]); } @@ -1073,6 +845,7 @@ uint8_t mcd212_device::csr2_r() } const uint8_t data = m_csrr[1]; + LOGMASKED(LOG_STATUS, "%s: Status Register 2: %02x\n", machine().describe_context(), data); m_csrr[1] &= ~(CSR2R_IT1 | CSR2R_IT2); if (data & (CSR2R_IT1 | CSR2R_IT2)) @@ -1083,46 +856,55 @@ uint8_t mcd212_device::csr2_r() void mcd212_device::csr2_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Control/Status Register 2 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_csrw[1]); } uint16_t mcd212_device::dcr2_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Display Command Register 2 Read: %04x & %08x\n", machine().describe_context(), m_dcr[1], mem_mask); return m_dcr[1]; } void mcd212_device::dcr2_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Display Command Register 2 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_dcr[1]); } uint16_t mcd212_device::vsr2_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Video Start Register 2 Read: %04x & %08x\n", machine().describe_context(), m_vsr[1], mem_mask); return m_vsr[1]; } void mcd212_device::vsr2_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Video Start Register 2 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_vsr[1]); } uint16_t mcd212_device::ddr2_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: Display Decoder Register 2 Read: %04x & %08x\n", machine().describe_context(), m_ddr[1], mem_mask); return m_ddr[1]; } void mcd212_device::ddr2_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: Display Decoder Register 2 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_ddr[1]); } uint16_t mcd212_device::dca2_r(offs_t offset, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_READS, "%s: DCA Pointer 2 Read: %04x & %08x\n", machine().describe_context(), m_dca[1], mem_mask); return m_dca[1]; } void mcd212_device::dca2_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + LOGMASKED(LOG_MAIN_REG_WRITES, "%s: DCA Pointer 2 Write: %04x & %08x\n", machine().describe_context(), data, mem_mask); COMBINE_DATA(&m_dca[1]); } @@ -1142,6 +924,21 @@ TIMER_CALLBACK_MEMBER(mcd212_device::ica_tick) m_dca[1] = get_dcp<1>(); m_ica_timer->adjust(screen().time_until_pos(0, 0)); + + // Cursor Blink + m_blink_time += 5 + BIT(m_dcr[0], DCR_FD_BIT); // FD bit * 8... Page 4-3 MCD + // Adjust the blink time once per frame + if (!m_blink_active && (m_blink_time >= ((m_cursor_control & CURCNT_CON) >> CURCNT_CON_SHIFT) * 60)) + { + m_blink_active = true; + m_blink_time = 0; + } + // If blink off time is 0, immediately turn back on. + if (m_blink_active && (m_blink_time >= ((m_cursor_control & CURCNT_COF) >> CURCNT_COF_SHIFT) * 60)) + { + m_blink_active = false; + m_blink_time = 0; + } } TIMER_CALLBACK_MEMBER(mcd212_device::dca_tick) @@ -1179,7 +976,7 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma // If PAL and 'Standard' bit set, insert a 20-line border on the top/bottom if ((scanline - m_ica_height < 20) || (scanline >= (m_total_height - 20))) { - std::fill_n(out, 768, 0xff101010); + std::fill_n(out, 768, s_4bpp_color[0]); draw_line = false; } } @@ -1191,7 +988,7 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma // 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, 0xff101010); + std::fill_n(out, 24, s_4bpp_color[0]); out += 24; } @@ -1245,7 +1042,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. @@ -1254,8 +1051,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(); @@ -1271,11 +1068,11 @@ 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. - const int slot_cycle = (int)(machine().time().as_ticks(clock()) & 0xf); + const int slot_cycle = int(machine().time().as_ticks(clock()) & 0xf); if (slot_cycle >= 11) return 2; @@ -1310,16 +1107,17 @@ void mcd212_device::device_reset() m_cursor_position = 0; m_cursor_control = 0; std::fill_n(m_cursor_pattern, std::size(m_cursor_pattern), 0); - std::fill_n(m_region_control, 8, 0); + std::fill_n(m_matte_control, 8, 0); m_backdrop_color = 0; std::fill_n(m_mosaic_hold, 2, 0); std::fill_n(m_weight_factor[0], std::size(m_weight_factor[0]), 0); std::fill_n(m_weight_factor[1], std::size(m_weight_factor[1]), 0); - std::fill_n(m_region_flag[0], std::size(m_region_flag[0]), false); - std::fill_n(m_region_flag[1], std::size(m_region_flag[1]), false); + std::fill_n(m_matte_flag[0], std::size(m_matte_flag[0]), false); + std::fill_n(m_matte_flag[1], std::size(m_matte_flag[1]), false); m_ica_height = 32; m_total_height = 312; + m_blink_time = 0; m_int_callback(CLEAR_LINE); @@ -1365,12 +1163,10 @@ void mcd212_device::device_start() m_delta_uv_lut[d] = s_dyuv_deltas[d >> 4]; } - for (uint16_t w = 0; w < 3 * 0xff; w++) + for (uint16_t w = 0; w < 0x300; w++) { - const uint8_t limit = (w < 0xff + 16) ? 0 : w <= 16 + 2 * 0xff ? w - 0x10f : 0xff; - m_dyuv_limit_r_lut[w] = limit << 16; - m_dyuv_limit_g_lut[w] = limit << 8; - m_dyuv_limit_b_lut[w] = limit; + const uint8_t limit = (w < 0x100) ? 0 : (w < 0x200) ? (w - 0x100) : 0xff; + m_dyuv_limit_lut[w] = limit; } for (int16_t sw = 0; sw < 0x100; sw++) @@ -1381,10 +1177,6 @@ void mcd212_device::device_start() m_dyuv_v_to_r[sw] = (351 * (sw - 128)) / 256; } - save_item(NAME(m_region_flag[0])); - save_item(NAME(m_region_flag[1])); - save_item(NAME(m_ica_height)); - save_item(NAME(m_total_height)); save_item(NAME(m_csrr)); save_item(NAME(m_csrw)); save_item(NAME(m_dcr)); @@ -1403,12 +1195,19 @@ void mcd212_device::device_start() save_item(NAME(m_cursor_position)); save_item(NAME(m_cursor_control)); save_item(NAME(m_cursor_pattern)); - save_item(NAME(m_region_control)); + save_item(NAME(m_matte_control)); save_item(NAME(m_backdrop_color)); save_item(NAME(m_mosaic_hold)); save_item(NAME(m_weight_factor[0])); save_item(NAME(m_weight_factor[1])); + save_item(NAME(m_matte_flag)); + save_item(NAME(m_ica_height)); + save_item(NAME(m_total_height)); + + save_item(NAME(m_blink_time)); + save_item(NAME(m_blink_active)); + m_dca_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mcd212_device::dca_tick), this)); m_dca_timer->adjust(attotime::never); diff --git a/src/mame/video/mcd212.h b/src/mame/video/mcd212.h index 521207ef1..b8c4ae994 100644 --- a/src/mame/video/mcd212.h +++ b/src/mame/video/mcd212.h @@ -21,8 +21,8 @@ *******************************************************************************/ -#ifndef MAME_VIDEO_MCD212_H -#define MAME_VIDEO_MCD212_H +#ifndef MAME_PHILIPS_MCD212_H +#define MAME_PHILIPS_MCD212_H #pragma once @@ -49,12 +49,13 @@ class mcd212_device : public device_t, uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void map(address_map &map); + 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: + // device_t implementation // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; @@ -89,10 +90,11 @@ class mcd212_device : public device_t, { CURCNT_COLOR = 0x00000f, // Cursor color CURCNT_CUW = 0x008000, // Cursor width - CURCNT_COF = 0x070000, // Cursor off time CURCNT_COF_SHIFT = 16, - CURCNT_CON = 0x280000, // Cursor on time + CURCNT_COF = 0b111 << CURCNT_COF_SHIFT, // Cursor off time CURCNT_CON_SHIFT = 19, + CURCNT_CON = 0b111 << CURCNT_CON_SHIFT, // Cursor on time + CURCNT_BLKC_SHIFT = 22, CURCNT_BLKC = 0x400000, // Blink type CURCNT_EN = 0x800000, // Cursor enable @@ -101,40 +103,42 @@ class mcd212_device : public device_t, ICM_MODE2 = 0x000f00, // Plane 2 ICM_MODE2_SHIFT = 8, ICM_EV = 0x040000, // External video - ICM_NR = 0x080000, // Number of region flags - ICM_NR_BIT = 19, + ICM_EV_BIT = 18, + ICM_NM = 0x080000, // Number of Matte flags + ICM_NM_BIT = 19, ICM_CS = 0x400000, // CLUT select + ICM_CS_BIT = 22, TCR_TA = 0x00000f, // Plane A TCR_TB = 0x000f00, // Plane B TCR_TB_SHIFT = 8, - TCR_COND_1 = 0x0, // Transparent if: Always (Plane Disabled) - TCR_COND_KEY_1 = 0x1, // Transparent if: Color Key = True - TCR_COND_XLU_1 = 0x2, // Transparent if: Transparency Bit = 1 - TCR_COND_RF0_1 = 0x3, // Transparent if: Region Flag 0 = True - TCR_COND_RF1_1 = 0x4, // Transparent if: Region Flag 1 = True - TCR_COND_RF0KEY_1 = 0x5, // Transparent if: Region Flag 0 = True || Color Key = True - TCR_COND_RF1KEY_1 = 0x6, // Transparent if: Region Flag 1 = True || Color Key = True + TCR_ALWAYS = 0x0, // Transparent if: Always (Plane Disabled) + TCR_KEY = 0x1, // Transparent if: Color Key = True + TCR_RGB = 0x2, // Transparent if: Transparency Bit = 1 (RGB Only) + TCR_MF0 = 0x3, // Transparent if: Matte Flag 0 = True + TCR_MF1 = 0x4, // Transparent if: Matte Flag 1 = True + TCR_MF0_KEY1 = 0x5, // Transparent if: Matte Flag 0 = True || Color Key = True + TCR_MF1_KEY1 = 0x6, // Transparent if: Matte Flag 1 = True || Color Key = True TCR_COND_UNUSED0 = 0x7, // Unused - TCR_COND_0 = 0x8, // Transparent if: Never (No Transparent Area) - TCR_COND_KEY_0 = 0x9, // Transparent if: Color Key = False - TCR_COND_XLU_0 = 0xa, // Transparent if: Transparency Bit = 0 - TCR_COND_RF0_0 = 0xb, // Transparent if: Region Flag 0 = False - TCR_COND_RF1_0 = 0xc, // Transparent if: Region Flag 1 = False - TCR_COND_RF0KEY_0 = 0xd, // Transparent if: Region Flag 0 = False && Color Key = False - TCR_COND_RF1KEY_0 = 0xe, // Transparent if: Region Flag 1 = False && Color Key = False + TCR_NEVER = 0x8, // Transparent if: Never (No Transparent Area) + TCR_NOT_KEY = 0x9, // Transparent if: Color Key = False + TCR_NOT_RGB = 0xa, // Transparent if: Transparency Bit = 0 (RGB Only) + TCR_NOT_MF0 = 0xb, // Transparent if: Matte Flag 0 = False + TCR_NOT_MF1 = 0xc, // Transparent if: Matte Flag 1 = False + TCR_NOT_MF0_KEY = 0xd, // Transparent if: Matte Flag 0 = False || Color Key = False + TCR_NOT_MF1_KEY = 0xe, // Transparent if: Matte Flag 1 = False || Color Key = False TCR_COND_UNUSED1 = 0xf, // Unused TCR_DISABLE_MX = 0x800000, // Mix disable POR_AB = 0, // Plane A in front of Plane B POR_BA = 1, // Plane B in front of Plane A - RC_X = 0x0003ff, // X position - RC_WF = 0x00fc00, // Weight position - RC_WF_SHIFT = 10, - RC_RF_BIT = 16, // Region flag bit - RC_OP = 0xf00000, // Operation - RC_OP_SHIFT = 20, + MC_X = 0x0003ff, // X position + MC_WF = 0x00fc00, // Weight position + MC_WF_SHIFT = 10, + MC_MF_BIT = 16, // Matte flag bit + MC_OP = 0xf00000, // Operation + MC_OP_SHIFT = 20, CSR1R_PA = 0x20, // Parity CSR1R_DA = 0x80, // Display Active @@ -172,40 +176,38 @@ class mcd212_device : public device_t, ICM_OFF = 0x0, ICM_CLUT8 = 0x1, - ICM_RGB555 = 0x2, + ICM_RGB555 = 0x1, ICM_CLUT7 = 0x3, ICM_CLUT77 = 0x4, ICM_DYUV = 0x5, ICM_CLUT4 = 0xb }; - uint8_t m_csrr[2]; - uint16_t m_csrw[2]; - uint16_t m_dcr[2]; - uint16_t m_vsr[2]; - uint16_t m_ddr[2]; - uint16_t m_dcp[2]; - uint32_t m_dca[2]; - uint32_t m_clut[256]; - uint32_t m_image_coding_method; - uint32_t m_transparency_control; - uint32_t m_plane_order; - uint32_t m_clut_bank[2]; - uint32_t m_transparent_color[2]; - uint32_t m_mask_color[2]; - uint32_t m_dyuv_abs_start[2]; - uint32_t m_cursor_position; - uint32_t m_cursor_control; - uint32_t m_cursor_pattern[16]; - uint32_t m_region_control[8]; - uint32_t m_backdrop_color; - uint32_t m_mosaic_hold[2]; - uint8_t m_weight_factor[2][768]; + uint8_t m_csrr[2]{}; + uint16_t m_csrw[2]{}; + uint16_t m_dcr[2]{}; + uint16_t m_vsr[2]{}; + uint16_t m_ddr[2]{}; + uint16_t m_dcp[2]{}; + uint32_t m_dca[2]{}; + uint32_t m_clut[256]{}; + uint32_t m_image_coding_method = 0; + uint32_t m_transparency_control = 0; + uint32_t m_plane_order = 0; + uint32_t m_clut_bank[2]{}; + uint32_t m_transparent_color[2]{}; + uint32_t m_mask_color[2]{}; + uint32_t m_dyuv_abs_start[2]{}; + uint32_t m_cursor_position = 0; + uint32_t m_cursor_control = 0; + uint32_t m_cursor_pattern[16]{}; + uint32_t m_matte_control[8]{}; + uint32_t m_backdrop_color = 0; + uint32_t m_mosaic_hold[2]{}; + uint8_t m_weight_factor[2][768]{}; // DYUV color limit arrays. - uint32_t m_dyuv_limit_r_lut[3 * 0xff]; - uint32_t m_dyuv_limit_g_lut[3 * 0xff]; - uint32_t m_dyuv_limit_b_lut[3 * 0xff]; + uint32_t m_dyuv_limit_lut[0x300]; // DYUV delta-Y decoding array uint8_t m_delta_y_lut[0x100]; @@ -232,40 +234,44 @@ class mcd212_device : public device_t, required_shared_ptr m_planeb; // internal state - bool m_region_flag[2][768]; - int m_ica_height; - int m_total_height; - emu_timer *m_ica_timer; - emu_timer *m_dca_timer; + bool m_matte_flag[2][768]{}; + int m_ica_height = 0; + int m_total_height = 0; + emu_timer *m_ica_timer = nullptr; + emu_timer *m_dca_timer = nullptr; + + // Cursor State + uint16_t m_blink_time; // Counter that tracks how long since the last m_blink_active last changed. + bool m_blink_active = false; static const uint32_t s_4bpp_color[16]; - uint8_t get_weight_factor(const uint32_t region_idx); - uint8_t get_region_op(const uint32_t region_idx); - void update_region_arrays(); + uint8_t get_weight_factor(const uint32_t Matte_idx); + uint8_t get_matte_op(const uint32_t Matte_idx); + void update_matte_arrays(); int get_screen_width(); int get_border_width(); - template int get_plane_width(); + uint32_t get_backdrop_plane(); - 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); @@ -275,4 +281,4 @@ class mcd212_device : public device_t, // device type definition DECLARE_DEVICE_TYPE(MCD212, mcd212_device) -#endif // MAME_VIDEO_MCD212_H +#endif // MAME_PHILIPS_MCD212_H diff --git a/src/osd/libretro/libretro-internal/retro_init.cpp b/src/osd/libretro/libretro-internal/retro_init.cpp index eb7f65cff..af54aaa50 100644 --- a/src/osd/libretro/libretro-internal/retro_init.cpp +++ b/src/osd/libretro/libretro-internal/retro_init.cpp @@ -82,7 +82,7 @@ static char MgamePath[1024]; static char MparentPath[1024]; static char MgameName[512]; static char MsystemName[512]; -static char gameName[1024]; +static char gameName[4096]; static char forcedSystem[9] = "cdimono1"; // args for cores diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h index 4a06b7052..361da9b45 100644 --- a/src/osd/modules/lib/osdlib.h +++ b/src/osd/modules/lib/osdlib.h @@ -21,6 +21,7 @@ #include #include #include +#include /*----------------------------------------------------------------------------- osd_process_kill: kill the current process