From 9540d7d944bd604efec8a7eef23c4275e36104db Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 14 Jul 2018 09:24:48 -0500 Subject: Add a driver for the original iPhone. (#3742) * Add ARM1176JZF-S CPU device and a driver for the original iPhone. --- scripts/target/mame/mess.lua | 1 + src/devices/cpu/arm7/arm7.cpp | 51 +++++++++++++++------ src/devices/cpu/arm7/arm7.h | 54 ++++++++++++++++------ src/devices/cpu/arm7/arm7ops.cpp | 9 +++- src/mame/drivers/iphone2g.cpp | 98 ++++++++++++++++++++++++++++++++++++++++ src/mame/mame.lst | 3 ++ src/mame/mess.flt | 1 + 7 files changed, 188 insertions(+), 29 deletions(-) create mode 100644 src/mame/drivers/iphone2g.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index af69b2af3cf..4d9c6302392 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1533,6 +1533,7 @@ files { MAME_DIR .. "src/mame/machine/macpci.cpp", MAME_DIR .. "src/mame/machine/cuda.cpp", MAME_DIR .. "src/mame/machine/cuda.h", + MAME_DIR .. "src/mame/drivers/iphone2g.cpp", } createMESSProjects(_target, _subtarget, "applied") diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 41705bd9b85..43ddd3ec3e6 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -45,22 +45,24 @@ void (*arm7_coproc_dt_r_callback)(arm_state *arm, uint32_t insn, uint32_t *prn, void (*arm7_coproc_dt_w_callback)(arm_state *arm, uint32_t insn, uint32_t *prn, void (*write32)(arm_state *arm, uint32_t addr, uint32_t data)); -DEFINE_DEVICE_TYPE(ARM7, arm7_cpu_device, "arm7_le", "ARM7 (little)") -DEFINE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device, "arm7_be", "ARM7 (big)") -DEFINE_DEVICE_TYPE(ARM7500, arm7500_cpu_device, "arm7500", "ARM7500") -DEFINE_DEVICE_TYPE(ARM9, arm9_cpu_device, "arm9", "ARM9") -DEFINE_DEVICE_TYPE(ARM920T, arm920t_cpu_device, "arm920t", "ARM920T") -DEFINE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device, "arm946es", "ARM946ES") -DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255") -DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110") -DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036") +DEFINE_DEVICE_TYPE(ARM7, arm7_cpu_device, "arm7_le", "ARM7 (little)") +DEFINE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device, "arm7_be", "ARM7 (big)") +DEFINE_DEVICE_TYPE(ARM7500, arm7500_cpu_device, "arm7500", "ARM7500") +DEFINE_DEVICE_TYPE(ARM9, arm9_cpu_device, "arm9", "ARM9") +DEFINE_DEVICE_TYPE(ARM920T, arm920t_cpu_device, "arm920t", "ARM920T") +DEFINE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device, "arm946es", "ARM946ES") +DEFINE_DEVICE_TYPE(ARM11, arm11_cpu_device, "arm11", "ARM11") +DEFINE_DEVICE_TYPE(ARM1176JZF_S, arm1176jzf_s_cpu_device, "arm1176jzf_s", "ARM1176JZF-S") +DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255") +DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110") +DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036") arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, ARM7, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_LITTLE) { } -arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness) +arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", endianness, 32, 32, 0) , m_prefetch_word0_shift(endianness == ENDIANNESS_LITTLE ? 0 : 16) @@ -109,7 +111,7 @@ arm9_cpu_device::arm9_cpu_device(const machine_config &mconfig, const char *tag, } -arm9_cpu_device::arm9_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness) +arm9_cpu_device::arm9_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness) : arm7_cpu_device(mconfig, type, tag, owner, clock, archRev, archFlags, endianness) { uint32_t arch = ARM9_COPRO_ID_ARCH_V4; @@ -147,9 +149,6 @@ arm920t_cpu_device::arm920t_cpu_device(const machine_config &mconfig, const char | 0; // Stepping } - - - arm946es_cpu_device::arm946es_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : arm9_cpu_device(mconfig, type, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE), cp15_control(0x78) @@ -176,6 +175,30 @@ arm946es_cpu_device::arm946es_cpu_device(const machine_config &mconfig, const ch { } +arm11_cpu_device::arm11_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm11_cpu_device(mconfig, ARM9, tag, owner, clock, 6, ARCHFLAG_T | ARCHFLAG_E | ARCHFLAG_K, ENDIANNESS_LITTLE) +{ +} + + +arm11_cpu_device::arm11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness) + : arm9_cpu_device(mconfig, type, tag, owner, clock, archRev, archFlags, endianness) +{ + uint32_t arch = ARM9_COPRO_ID_ARCH_V6; + + m_copro_id = ARM9_COPRO_ID_MFR_ARM | arch | (0xB00 << 4); +} + +arm1176jzf_s_cpu_device::arm1176jzf_s_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm11_cpu_device(mconfig, ARM1176JZF_S, tag, owner, clock, 6, ARCHFLAG_T | ARCHFLAG_E | ARCHFLAG_K, ENDIANNESS_LITTLE) +{ + m_copro_id = ARM9_COPRO_ID_MFR_ARM + | ARM9_COPRO_ID_SPEC_REV0 + | ARM9_COPRO_ID_ARCH_CPUID + | ARM9_COPRO_ID_PART_ARM1176JZF_S + | ARM9_COPRO_ID_STEP_ARM1176JZF_S_R0P7; +} + // unknown configuration, but uses MPU not MMU, so closer to ARM946ES igs036_cpu_device::igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm946es_cpu_device(mconfig, IGS036, tag, owner, clock) diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index dfb6fad6eaa..d7d66766664 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -68,7 +68,9 @@ protected: ARCHFLAG_MMU = 8, // has on-board MMU (traditional ARM style like the SA1110) ARCHFLAG_SA = 16, // StrongARM extensions (enhanced TLB) ARCHFLAG_XSCALE = 32, // XScale extensions (CP14, enhanced TLB) - ARCHFLAG_MODE26 = 64 // supports 26-bit backwards compatibility mode + ARCHFLAG_MODE26 = 64, // supports 26-bit backwards compatibility mode + ARCHFLAG_K = 128, // enhanced MMU extensions present (only for v6) + ARCHFLAG_T2 = 256, //Thumb-2 present }; enum @@ -83,6 +85,10 @@ protected: ARM9_COPRO_ID_STEP_ARM946_A0 = 1, + ARM9_COPRO_ID_STEP_ARM1176JZF_S_R0P0 = 0, + ARM9_COPRO_ID_STEP_ARM1176JZF_S_R0P7 = 7, + + ARM9_COPRO_ID_PART_ARM1176JZF_S = 0xB76 << 4, ARM9_COPRO_ID_PART_SA1110 = 0xB11 << 4, ARM9_COPRO_ID_PART_ARM946 = 0x946 << 4, ARM9_COPRO_ID_PART_ARM920 = 0x920 << 4, @@ -97,6 +103,9 @@ protected: ARM9_COPRO_ID_ARCH_V5 = 0x03 << 16, ARM9_COPRO_ID_ARCH_V5T = 0x04 << 16, ARM9_COPRO_ID_ARCH_V5TE = 0x05 << 16, + ARM9_COPRO_ID_ARCH_V5TEJ = 0x06 << 16, + ARM9_COPRO_ID_ARCH_V6 = 0x07 << 16, + ARM9_COPRO_ID_ARCH_CPUID = 0x0F << 16, ARM9_COPRO_ID_SPEC_REV0 = 0x00 << 20, ARM9_COPRO_ID_SPEC_REV1 = 0x01 << 20, @@ -106,7 +115,7 @@ protected: ARM9_COPRO_ID_MFR_INTEL = 0x69 << 24 }; - arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness); + arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness); void postload(); @@ -175,7 +184,7 @@ protected: uint8_t m_decoded_access_control[16]; uint8_t m_archRev; // ARM architecture revision (3, 4, and 5 are valid) - uint8_t m_archFlags; // architecture flags + uint32_t m_archFlags; // architecture flags uint32_t m_vectorbase; @@ -598,7 +607,7 @@ public: arm9_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - arm9_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness); + arm9_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness); }; @@ -641,6 +650,23 @@ private: void RefreshDTCM(); }; +class arm11_cpu_device : public arm9_cpu_device +{ +public: + // construction/destruction + arm11_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + arm11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness); +}; + +class arm1176jzf_s_cpu_device : public arm11_cpu_device +{ +public: + // construction/destruction + arm1176jzf_s_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + class igs036_cpu_device : public arm946es_cpu_device { public: @@ -663,14 +689,16 @@ public: sa1110_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -DECLARE_DEVICE_TYPE(ARM7, arm7_cpu_device) -DECLARE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device) -DECLARE_DEVICE_TYPE(ARM7500, arm7500_cpu_device) -DECLARE_DEVICE_TYPE(ARM9, arm9_cpu_device) -DECLARE_DEVICE_TYPE(ARM920T, arm920t_cpu_device) -DECLARE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device) -DECLARE_DEVICE_TYPE(PXA255, pxa255_cpu_device) -DECLARE_DEVICE_TYPE(SA1110, sa1110_cpu_device) -DECLARE_DEVICE_TYPE(IGS036, igs036_cpu_device) +DECLARE_DEVICE_TYPE(ARM7, arm7_cpu_device) +DECLARE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device) +DECLARE_DEVICE_TYPE(ARM7500, arm7500_cpu_device) +DECLARE_DEVICE_TYPE(ARM9, arm9_cpu_device) +DECLARE_DEVICE_TYPE(ARM920T, arm920t_cpu_device) +DECLARE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device) +DECLARE_DEVICE_TYPE(ARM11, arm11_cpu_device) +DECLARE_DEVICE_TYPE(ARM1176JZF_S, arm1176jzf_s_cpu_device) +DECLARE_DEVICE_TYPE(PXA255, pxa255_cpu_device) +DECLARE_DEVICE_TYPE(SA1110, sa1110_cpu_device) +DECLARE_DEVICE_TYPE(IGS036, igs036_cpu_device) #endif // MAME_CPU_ARM7_ARM7_H diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index 0ad73f96b51..ab5bd9243aa 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -1564,7 +1564,12 @@ void arm7_cpu_device::arm9ops_1(uint32_t insn) else if ((insn & 0x00ff00f0) == 0x00010000) /* set endianness (SETEND) */ { // unsupported (armv6 onwards only) - arm9ops_undef(insn); + if (m_archRev < 6) arm9ops_undef(insn); + else + { + uint32_t new_cpsr = GET_CPSR & ~(1 << 9); + set_cpsr(new_cpsr | (insn & (1 << 9))); + } R15 += 4; } else @@ -1580,7 +1585,7 @@ void arm7_cpu_device::arm9ops_57(uint32_t insn) if ((insn & 0x0070f000) == 0x0050f000) { // unsupported (armv6 onwards only) - arm9ops_undef(insn); + if(m_archRev < 6) arm9ops_undef(insn); R15 += 4; } else diff --git a/src/mame/drivers/iphone2g.cpp b/src/mame/drivers/iphone2g.cpp new file mode 100644 index 00000000000..6b6cedf37df --- /dev/null +++ b/src/mame/drivers/iphone2g.cpp @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:Melissa Goad +/*************************************************************************** + + iphone2g.cpp + + Driver file to handle emulation of the original iPhone + +***************************************************************************/ + +#include "emu.h" +#include "cpu/arm7/arm7.h" +#include "screen.h" + +class iphone2g_state : public driver_device +{ +public: + iphone2g_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_ram(*this, "ram"), + m_bios(*this, "bios"), + m_screen(*this, "screen") + { } + + void iphone2g(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + + DECLARE_READ32_MEMBER(clock1_r); + +private: + required_device m_maincpu; + required_shared_ptr m_ram; + required_region_ptr m_bios; + required_device m_screen; + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void mem_map(address_map &map); +}; + +uint32_t iphone2g_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +READ32_MEMBER(iphone2g_state::clock1_r) +{ + uint32_t ret = 0; + switch(offset) + { + case 0x40/4: ret = 1; break; //boot rom needs this to not infinite loop at startup. + } + + logerror("%s: Clock1 read: offset %08x data %08x\n", machine().describe_context(), offset << 2, ret); + + return ret; +} + +void iphone2g_state::mem_map(address_map &map) +{ + map(0x00000000, 0x07FFFFFF).mirror(0x18000000).ram().share("ram"); /* DRAM */ + map(0x20000000, 0x2000FFFF).rom().region("bios", 0); /* BIOS */ + map(0x22000000, 0x224FFFFF).ram(); /* SRAM */ + map(0x3C500000, 0x3C500FFF).r(FUNC(iphone2g_state::clock1_r)).nopw(); +} + +void iphone2g_state::machine_start() +{ + std::copy_n(m_bios.target(), m_bios.length(), m_ram.target()); +} + +void iphone2g_state::machine_reset() +{ +} + +MACHINE_CONFIG_START(iphone2g_state::iphone2g) + + /* Basic machine hardware */ + MCFG_DEVICE_ADD(m_maincpu, ARM1176JZF_S, XTAL(12'000'000) * 103 / 3) //412 MHz, downclocked from 600 MHz + MCFG_DEVICE_PROGRAM_MAP(mem_map) + + MCFG_SCREEN_ADD(m_screen, RASTER) + MCFG_SCREEN_RAW_PARAMS(XTAL(12'000'000), 320, 0, 320, 480, 0, 480) //Complete guess + MCFG_SCREEN_UPDATE_DRIVER(iphone2g_state, screen_update) +MACHINE_CONFIG_END + +ROM_START(iphone2g) + ROM_REGION32_LE(0x10000, "bios", 0) + ROM_LOAD("s5l8900-bootrom.bin", 0x00000, 0x10000, CRC(beb15cd1) SHA1(079a3acab577eb52cc349ea811af3cbd5d01b8f5)) +ROM_END + +/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ +// console section +CONS( 2007, iphone2g, 0, 0, iphone2g, 0, iphone2g_state, empty_init, "Apple", "iPhone (A1203)", MACHINE_IS_SKELETON ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 19b2e549b2b..be6618fe919 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -15550,6 +15550,9 @@ ipc // intel @source:ipds.cpp ipds // intel +@source:iphone2g.cpp +iphone2g // (c) 2007 Apple + @source:iq151.cpp iq151 // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 81d8ccc3be7..9ef836bde20 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -316,6 +316,7 @@ interpro.cpp intv.cpp ipc.cpp ipds.cpp +iphone2g.cpp iq151.cpp iqunlim.cpp iris3130.cpp -- cgit v1.2.3