From f5c4d82aa78d1c2b7be2858c157548030a398c0b Mon Sep 17 00:00:00 2001 From: qufb <93520295+qufb@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:34:42 +0000 Subject: mattel/pixtermu.cpp: Added a skeleton Mattel Pixter Multi-Media driver and software list. (#12013) New systems marked not working ----------------------- Mattel Pixter Multi-Media [QUFB] New software list items marked not working (pixter_cart.xml) ------------------------------------------------ Alphabet Forest [QUFB] Clifford - The Big Red Dog [QUFB] Cyberchase [QUFB] Mazes, Puzzles & Games [QUFB] SpongeBob SquarePants - Math Adventure [QUFB] --- hash/pixter_cart.xml | 72 +++++++++++++ src/mame/mame.lst | 3 + src/mame/mattel/pixtermu.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 327 insertions(+) create mode 100644 hash/pixter_cart.xml create mode 100644 src/mame/mattel/pixtermu.cpp diff --git a/hash/pixter_cart.xml b/hash/pixter_cart.xml new file mode 100644 index 00000000000..68c9fddec43 --- /dev/null +++ b/hash/pixter_cart.xml @@ -0,0 +1,72 @@ + + + + + + + Alphabet Forest + 2004 + Fisher-Price + + + + + + + + + + Clifford - The Big Red Dog + 2004 + Fisher-Price + + + + + + + + + + SpongeBob SquarePants - Math Adventure + 2004 + Fisher-Price + + + + + + + + + + Mazes, Puzzles & Games + 2004 + Fisher-Price + + + + + + + + + + Cyberchase + 200? + Fisher-Price + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index fa8412ffecf..4e9945ece0d 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -24815,6 +24815,9 @@ intvsrs // Intellivision (Sears License) - 19?? @source:mattel/juicebox.cpp juicebox // +@source:mattel/pixtermu.cpp +pixtermu // + @source:maygay/maygay1bsw.cpp m1albsq // Albert Square (Maygay) m1albsq1 // diff --git a/src/mame/mattel/pixtermu.cpp b/src/mame/mattel/pixtermu.cpp new file mode 100644 index 00000000000..2e969ea13c9 --- /dev/null +++ b/src/mame/mattel/pixtermu.cpp @@ -0,0 +1,252 @@ +// license:BSD-3-Clause +// copyright-holders:QUFB +/****************************************************************************** + + Skeleton driver for Pixter Multi-Media. + + Currently hangs after reset: + + - If executing boot ROM, with boot configuration set to load NOR Flash or SRAM, it will reach an infinite loop at 0x1f0; + - If executing nCS1 ROM, it will wait indefinitely due to unimplemented timer controls; + + References: + + - https://elinux.org/Pixter_Multimedia + - https://www.nxp.com/docs/en/data-sheet/LH79524_525_N.pdf + - https://www.nxp.com/docs/en/user-guide/LH79524-LH79525_UG_V1_3.pdf + - https://lh79525.wordpress.com/ + + Hardware + -------- + + Model H4651/J4287/J4288: + + - PCB Revision: PT1543A-BGA-4F2C 2005/04/30 Rev 4.2b + - CPU: Sharp LH79524-NOE (ARM720T) + - RAM: ICSI IC42S16100-7T (2MB each, 4MB total) + - ROM: Chip-On-Board, selected by pin CS1 + + JTAG + ---- + + To place the LH79524 into ARM ICE debug mode you will need to connect TEST1 via a 4.7K Ohm resistor to ground. + + Pinout: + + - D2: nTRST (Reset Input) + - P4: TMS (Mode Select Input) + - T3: TCK (Clock Input) + - T1: TDI (Serial Data Input) + - P3: TDO (Data Serial Output) + - TEST1: ARM ICE debug mode + +*******************************************************************************/ + +#include "emu.h" + +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" +#include "cpu/arm7/arm7.h" +#include "cpu/arm7/arm7core.h" + +#include "softlist_dev.h" + +namespace { + +class pixter_multimedia_state : public driver_device +{ +public: + pixter_multimedia_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_cart(*this, "cartslot") + , m_maincpu(*this, "maincpu") + , m_ndcs0(*this, "ndcs0") + , m_internal_sram(*this, "internal_sram") + , m_apb(*this, "apb", 0x27000, ENDIANNESS_LITTLE) + , m_remap_view(*this, "remap") + { } + + void pixter_multimedia(machine_config &config); + +private: + // Remap Control, mapped at 0xfffe2008, offset 0x22008/4 + static inline constexpr uint32_t APB_REMAP = 34818; + // Power-up Boot Configuration, mapped at 0xfffe6000, offset 0x26000/4 + static inline constexpr uint32_t APB_PBC = 38912; + // nCS1 Override, mapped at 0xfffe6004, offset 0x26004/4 + static inline constexpr uint32_t APB_CS1OV = 38913; + // External Peripheral Mapping, mapped at 0xfffe6008, offset 0x26008/4 + static inline constexpr uint32_t APB_EPM = 38914; + + virtual void machine_start() override; + virtual void machine_reset() override; + + DEVICE_IMAGE_LOAD_MEMBER(cart_load); + void arm7_map(address_map &map); + void apb_bridge_w(offs_t offset, uint32_t data, uint32_t mem_mask); + void apb_remap(uint32_t data); + + required_device m_cart; + required_device m_maincpu; + required_shared_ptr m_ndcs0; + required_shared_ptr m_internal_sram; + memory_share_creator m_apb; + memory_view m_remap_view; +}; + +void pixter_multimedia_state::apb_remap(uint32_t data) +{ + // User's Guide - 1.6 Memory Interface Architecture + if (data == 0) { + m_remap_view.select((m_apb[APB_PBC] & 0b0100) && (m_apb[APB_CS1OV] & 0b1) ? 0 : 3); + } else if (data < 3) { + m_remap_view.select(data); + } else { + logerror("Unexpected remap %d\n", data); + } +} + +void pixter_multimedia_state::machine_start() +{ + if (m_cart->exists()) { + memory_region *const cart_rom = m_cart->memregion("rom"); + device_generic_cart_interface::install_non_power_of_two<0>( + cart_rom->bytes(), + 0x03ff'ffff, + 0, + 0x4800'0000, + [this, cart_rom] (offs_t begin, offs_t end, offs_t mirror, offs_t src) { + m_maincpu->space(AS_PROGRAM).install_rom(begin, end, mirror, cart_rom->base() + src); + }); + } +} + +void pixter_multimedia_state::machine_reset() +{ + m_apb[APB_PBC] = 0b0000; // Boot from NOR Flash or SRAM, 16-bit data bus width, nBLEx LOW for reads + m_apb[APB_CS1OV] = 0b0; // nCS1 is routed for normal operation + m_apb[APB_EPM] = 0b1111; // All external devices are accessible following reset + + m_apb[APB_REMAP] = 0b00; // Map nCS1 + apb_remap(m_apb[APB_REMAP]); +} + +DEVICE_IMAGE_LOAD_MEMBER(pixter_multimedia_state::cart_load) +{ + uint64_t length; + memory_region *cart_rom = nullptr; + if (m_cart->loaded_through_softlist()) { + cart_rom = m_cart->memregion("rom"); + if (!cart_rom) { + return std::make_pair(image_error::BADSOFTWARE, "Software list item has no 'rom' data area"); + } + length = cart_rom->bytes(); + } else { + length = m_cart->length(); + } + + if (!length) { + return std::make_pair(image_error::INVALIDLENGTH, "Cartridges must not be empty"); + } + if (length & 3) { + return std::make_pair(image_error::INVALIDLENGTH, "Unsupported cartridge size (must be a multiple of 4 bytes)"); + } + + if (!m_cart->loaded_through_softlist()) { + cart_rom = machine().memory().region_alloc(m_cart->subtag("rom"), length, 4, ENDIANNESS_LITTLE); + if (!cart_rom) { + return std::make_pair(std::errc::not_enough_memory, std::string()); + } + + uint32_t *const base = reinterpret_cast(cart_rom->base()); + if (m_cart->fread(base, length) != length) { + return std::make_pair(std::errc::io_error, "Error reading cartridge file"); + } + + if (ENDIANNESS_NATIVE != ENDIANNESS_LITTLE) { + for (uint64_t i = 0; (length / 4) > i; ++i) + base[i] = swapendian_int32(base[i]); + } + } + + return std::make_pair(std::error_condition(), std::string()); +} + +void pixter_multimedia_state::arm7_map(address_map &map) +{ + // Remap Bank + map(0x0000'0000, 0x003f'ffff).view(m_remap_view); + m_remap_view[0](0x0000'0000, 0x0000'1fff).rom().region("bootrom", 0); + m_remap_view[1](0x0000'0000, 0x003f'ffff).ram().share("ndcs0"); + m_remap_view[2](0x0000'0000, 0x0000'3fff).ram().share("internal_sram"); + m_remap_view[3](0x0000'0000, 0x003f'ffff).rom().region("ncs1", 0); + + // External SRAM + map(0x2000'0000, 0x203f'ffff).ram().share("ndcs0"); + // nCS0 (Unused NAND Flash?) + // map(0x40000000, 0x403fffff) + // nCS1 (Chip-On-Board ROM) + map(0x4400'0000, 0x443f'ffff).mirror(0x03c0'0000).rom().region("ncs1", 0); + // nCS2 (Cart ROM) + // map(0x4800'0000, 0x483f'ffff) + // nCS3 (Unused?) + // map(0x4c00'0000, 0x4c3f'ffff) + + // Internal SRAM + map(0x6000'0000, 0x6000'3fff).mirror(0x0fff'c000).ram().share("internal_sram"); + + // Boot ROM + map(0x8000'0000, 0x8000'1fff).rom().region("bootrom", 0); + + // APB Bridge + map(0xfffc'0000, 0xfffe'6fff).ram().share("apb").w(FUNC(pixter_multimedia_state::apb_bridge_w)); + // External Memory Control + map(0xffff'1000, 0xffff'1fff).ram(); + // Color LCD Control + map(0xffff'4000, 0xffff'4fff).ram(); + // USB Device + map(0xffff'5000, 0xffff'5fff).ram(); + // Interrupt Vector Control + map(0xffff'f000, 0xffff'ffff).ram(); +} + +void pixter_multimedia_state::apb_bridge_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + if (offset == m_apb[APB_REMAP]) { + apb_remap(data); + } + + COMBINE_DATA(&m_apb[offset]); +} + +static INPUT_PORTS_START( pixter_multimedia ) +INPUT_PORTS_END + +void pixter_multimedia_state::pixter_multimedia(machine_config &config) +{ + // User's Guide - 1.3 Clock Strategy - AHB Fast CPU Clock (FCLK) + ARM7(config, m_maincpu, 76'205'000); + m_maincpu->set_addrmap(AS_PROGRAM, &pixter_multimedia_state::arm7_map); + + GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "pixter_cart"); + m_cart->set_endian(ENDIANNESS_LITTLE); + m_cart->set_width(GENERIC_ROM32_WIDTH); + m_cart->set_device_load(FUNC(pixter_multimedia_state::cart_load)); + m_cart->set_must_be_loaded(false); + + SOFTWARE_LIST(config, "cart_list").set_original("pixter_cart"); +} + +ROM_START( pixtermu ) + ROM_REGION32_LE( 0x400000, "ncs1", 0 ) + ROM_LOAD( "cs1.bin", 0x00000000, 0x400000, CRC(9d06745a) SHA1(c85ffd1777ffee4e99e5a208e3707a39b0dfc3aa) ) + + ROM_REGION32_LE( 0x2000, "bootrom", 0 ) + ROM_LOAD( "lh79524.bootrom.bin", 0x00000000, 0x2000, CRC(5314a9e3) SHA1(23ed1914c7e7cc875cbb9f9b3d511a60a7324abd) ) +ROM_END + +} // anonymous namespace + + +// year, name, parent, compat, machine, input, class, init, company, fullname, flags +CONS( 2005, pixtermu, 0, 0, pixter_multimedia, pixter_multimedia, pixter_multimedia_state, empty_init, "Mattel", "Pixter Multi-Media", MACHINE_IS_SKELETON ) -- cgit v1.2.3