From edd20eaf7015e351da312af5d5de52243c1bad8a Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 3 Jul 2020 20:32:44 +0100 Subject: [PATCH] Add Monkey King 3B SoC skeleton and RS-70 system (#6906) New machines marked as NOT_WORKING ---------------------------------- RS-70 648-in-1 [David Shah] -mk3b: Added a skeleton driver for the Monkey King 3B SoC. [David Shah] --- scripts/target/mame/mess.lua | 1 + src/mame/drivers/monkey_king_3b.cpp | 252 ++++++++++++++++++++++++++++ src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + 4 files changed, 257 insertions(+) create mode 100644 src/mame/drivers/monkey_king_3b.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index eed568b9681..14e43e370ff 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -4016,6 +4016,7 @@ files { MAME_DIR .. "src/mame/drivers/actions_atj2279b.cpp", MAME_DIR .. "src/mame/drivers/pubint_storyreader.cpp", MAME_DIR .. "src/mame/drivers/magiceyes_pollux_vr3520f.cpp", + MAME_DIR .. "src/mame/drivers/monkey_king_3b.cpp", } createMESSProjects(_target, _subtarget, "ultimachine") diff --git a/src/mame/drivers/monkey_king_3b.cpp b/src/mame/drivers/monkey_king_3b.cpp new file mode 100644 index 00000000000..52cefa6447e --- /dev/null +++ b/src/mame/drivers/monkey_king_3b.cpp @@ -0,0 +1,252 @@ +// license:BSD-3-Clause +// copyright-holders:David Shah + +/* + +Monkey King SoCs (currently only 3B is supported) + +Presumably-custom ARM-based system-on-chips by Digital Media Cartridge (DMC). +Intended to run NES and Genesis emulators, primarily for ATgames systems. + +Sometimes abbreviated MK. It is a successor of the Titan SoC used in previous +emulation based ATgames systems. + +Monkey King and Monkey 2: Presumed custom. Used in some ATgames/Blaze +Genesis systems and the Atari Flashback Portable. + +Monkey King 3 and Monkey King 3B: Presumed custom. Used in the ATgames +BLAST system and the RS-70 648-in-1 "PS1 form factor" clone. Supports +HDMI output. + +Monkey King 3.6: not a custom part but a rebranded RK3036, usually +running a cut-down Android based OS. Used in newer ATgames systems. + +The typical configuration of the Monkey King SoCs (other than the +3.6) is with 8/16MB of SDRAM, NOR flash for the firmware and +built-in games, and a SD card for additional games. + +The RS-70 is notable for having a debug UART on the USB port +(serial TX on D+, 115200). It prints the following messages on boot: + + EXEC: Executing 'boot' with 0 args (ZLib ON)... + EXEC: Loading 'boot' at 0x18000000... + EXEC: Loaded 372272 bytes of 2097152 available. + +This is different from the serial output that this emulation model +currently produces. Perhaps one of the unimplemented IO is causing +it to go into some kind of debug mode. The log output produced by +this machine is: + + Modes:0x00000000 + PUT: Setting joystick to mode 0x0, timer to 250us + + ****************************************************** + MK FIRMWARE INFORMATION + Mode: 0xB4 + Build Time: May 8 2019 14:09:21 + CPU Clock: 240MHz + TFS Start: 0x8070000 + Video Buf: 0x6000000 + Stack Top: 0x3001EE8 + IWRAM Size: 32kB + EVRAM Size: 16384kB + Heap Size: 6144kB at 0x18200000 + Video Mode: 0 + Video Size: 1280x720x16bpp + ****************************************************** + +There are other strings in the ROM that imply there may be more serial +debug possibilities. + +TODO: + implement everything + add dumps of more Monkey King systems +*/ + +#include "emu.h" +#include "cpu/arm7/arm7.h" +#include "cpu/arm7/arm7core.h" +#include "emupal.h" +#include "screen.h" + +class mk3b_soc_state : public driver_device +{ +public: + mk3b_soc_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_iram0(*this, "iram0"), + m_iram3(*this, "iram3"), + m_sdram(*this, "sdram"), + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen") + { } + + void mk3b_soc(machine_config &config); + + void init_rs70(); + +private: + required_shared_ptr m_iram0, m_iram3; + required_shared_ptr m_sdram; + required_device m_maincpu; + required_device m_screen; + + virtual void machine_reset() override; + virtual void video_start() override; + uint32_t io4_r(offs_t offset, uint32_t mem_mask = ~0); + void io4_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + uint32_t io7_r(offs_t offset, uint32_t mem_mask = ~0); + void io7_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + uint32_t io10_r(offs_t offset, uint32_t mem_mask = ~0); + void io10_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + uint32_t screen_update_mk3b_soc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void map(address_map &map); + std::string debug_buf; +}; + + +void mk3b_soc_state::map(address_map &map) +{ + // 64MB external NOR flash + map(0x08000000, 0x0BFFFFFF).rom().share("norflash").region("norflash", 0x0);; + // unknown amount and configuration of internal RAM + map(0x00000000, 0x0000FFFF).ram().share("iram0"); + // This section of RAM seems to contain the stack + map(0x03000000, 0x0300FFFF).ram().share("iram3"); + + // 16MB of external SDRAM + map(0x18000000, 0x18FFFFFF).ram().share("sdram"); + // IO is totally unknown for now + map(0x04000000, 0x0400FFFF).rw(FUNC(mk3b_soc_state::io4_r), FUNC(mk3b_soc_state::io4_w)); + map(0x07000000, 0x0700FFFF).rw(FUNC(mk3b_soc_state::io7_r), FUNC(mk3b_soc_state::io7_w)); + map(0x10000000, 0x1000FFFF).rw(FUNC(mk3b_soc_state::io10_r), FUNC(mk3b_soc_state::io10_w)); +} + +static INPUT_PORTS_START( mk3b_soc ) + +INPUT_PORTS_END + +void mk3b_soc_state::video_start() +{ +} + +void mk3b_soc_state::machine_reset() +{ + // In practice, this will probably be done by a small + // internal boot ROM. + m_iram0[0] = 0xe59f0000; // ldr r0, [pc] + m_iram0[1] = 0xe12fff10; // bx, r0 + m_iram0[2] = 0x08000000; // target address +} + +uint32_t mk3b_soc_state::screen_update_mk3b_soc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +void mk3b_soc_state::mk3b_soc(machine_config &config) +{ + // type unknown (should actually have VFP?) + // debug output suggests 240MHz clock + ARM920T(config, m_maincpu, 240000000); + m_maincpu->set_addrmap(AS_PROGRAM, &mk3b_soc_state::map); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(60); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */); + m_screen->set_size(1280, 720); + m_screen->set_visarea(0, 1280-1, 0, 720-1); + m_screen->set_screen_update(FUNC(mk3b_soc_state::screen_update_mk3b_soc)); +} + +uint32_t mk3b_soc_state::io4_r(offs_t offset, uint32_t mem_mask) +{ + switch (offset) { + case 0x01: + return (m_screen->vblank() << 27) | m_screen->vblank(); // who knows? seems to need to toggle between 0 and 1 + default: + logerror("%s: IO 0x04 read 0x%04X\n", machine().describe_context(), offset); + return 0x00; + } +} + +void mk3b_soc_state::io4_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + logerror("%s: IO 0x04 write 0x%04X 0x%08X & 0x%08X\n", machine().describe_context(), offset, data, mem_mask); +} + + +uint32_t mk3b_soc_state::io7_r(offs_t offset, uint32_t mem_mask) +{ + switch (offset) { + case 0x21: // video size + return (1280 << 16) | (720); + default: + logerror("%s: IO 0x07 read 0x%04X\n", machine().describe_context(), offset); + return 0x00; + } +} + +void mk3b_soc_state::io7_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + logerror("%s: IO 0x07 write 0x%04X 0x%08X & 0x%08X\n", machine().describe_context(), offset, data, mem_mask); +} + +uint32_t mk3b_soc_state::io10_r(offs_t offset, uint32_t mem_mask) +{ + switch (offset) { + // Definitely not correct, but toggling somehow keeps things moving + case 0x148: + case 0x149: + return m_screen->vblank() ? 0x00000000 : 0xFFFFFFFF; + default: + logerror("%s: IO 0x10 read 0x%04X\n", machine().describe_context(), offset); + return 0x00; + } +} + +void mk3b_soc_state::io10_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch (offset) { + case 0x148: { // debug UART + char c = data & 0xFF; + logerror("%s: UART W: %c\n", machine().describe_context(), c); + if (c == '\n') { + logerror("%s: [DEBUG] %s\n", machine().describe_context(), debug_buf.c_str()); + debug_buf.clear(); + } else if (c != '\r') { + debug_buf += c; + } + break; + } + default: + logerror("%s: IO 0x10 write 0x%04X 0x%08X & 0x%08X\n", machine().describe_context(), offset, data, mem_mask); + } +} + +void mk3b_soc_state::init_rs70() +{ + // Uppermost address bit seems to be inverted + uint8_t *ROM = memregion("norflash")->base(); + int size = memregion("norflash")->bytes(); + + for (int i = 0; i < (size / 2); i++) { + std::swap(ROM[i], ROM[i + (size / 2)]); + } + // FIXME: Work around missing FPU for now + ROM[0x32f24] = 0x00; + ROM[0x32f25] = 0x00; + ROM[0x32f26] = 0x00; + ROM[0x32f27] = 0x00; +} + + +ROM_START( rs70_648 ) + ROM_REGION(0x04000000, "norflash", 0) + ROM_LOAD("s29gl512p.bin", 0x000000, 0x04000000, CRC(cb452bd7) SHA1(0b19a13a3d0b829725c10d64d7ff852ff5202ed0) ) +ROM_END + +CONS( 2019, rs70_648, 0, 0, mk3b_soc, mk3b_soc, mk3b_soc_state, init_rs70, "", "RS-70 648-in-1", MACHINE_IS_SKELETON ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ec2117f1c81..bc784375bfb 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -23148,6 +23148,9 @@ momokoe // (c) 1986 Jaleco (English text) monacogp // (c) 1980 Sega monacogpa // (c) 1980 Sega +@source:monkey_king_3b.cpp +rs70_648 // + @source:monon_color.cpp mononcol // (c) 2011 M&D diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 3e624ecbc95..da396e31736 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -587,6 +587,7 @@ mmd2.cpp mod8.cpp modellot.cpp molecular.cpp +monkey_king_3b.cpp monon_color.cpp monty.cpp mpc3000.cpp