Add a driver for the original iPhone. (#3742)

* Add ARM1176JZF-S CPU device and a driver for the original iPhone.
This commit is contained in:
Melissa Goad 2018-07-14 09:24:48 -05:00 committed by Vas Crabb
parent cf34ccd3b4
commit 9540d7d944
7 changed files with 188 additions and 29 deletions

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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<cpu_device> m_maincpu;
required_shared_ptr<uint32_t> m_ram;
required_region_ptr<uint32_t> m_bios;
required_device<screen_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 )

View File

@ -15550,6 +15550,9 @@ ipc // intel
@source:ipds.cpp
ipds // intel
@source:iphone2g.cpp
iphone2g // (c) 2007 Apple
@source:iq151.cpp
iq151 //

View File

@ -316,6 +316,7 @@ interpro.cpp
intv.cpp
ipc.cpp
ipds.cpp
iphone2g.cpp
iq151.cpp
iqunlim.cpp
iris3130.cpp