summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Melissa Goad <mszoopers@protonmail.com>2020-01-29 09:13:48 -0600
committer GitHub <noreply@github.com>2020-01-29 10:13:48 -0500
commite6595b06a7781e5e9e3bc8a7957d4fa0ae50682c (patch)
tree85ff6b64d8173bf1d016d47035603b4bd38cecad
parenta5783544e8026ebbca60e1ec0490ae4a075b9263 (diff)
iphone2g wip (nw) (#6226)
* iphone2g wip (nw) * fixup * fixup * fixup * iphone2g: hacky spi and non-existent timers (nw)
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/cpu/arm7/arm7.cpp48
-rw-r--r--src/devices/cpu/arm7/arm7.h8
-rw-r--r--src/devices/cpu/arm7/arm7core.h2
-rw-r--r--src/devices/machine/vic_pl192.cpp130
-rw-r--r--src/devices/machine/vic_pl192.h51
-rw-r--r--src/mame/drivers/iphone2g.cpp236
8 files changed, 478 insertions, 10 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index f04cb88e031..d831ac381ca 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -3132,6 +3132,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/vic_pl192.h,MACHINES["VIC_PL192"] = true
+---------------------------------------------------
+
+if (MACHINES["VIC_PL192"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/vic_pl192.cpp",
+ MAME_DIR .. "src/devices/machine/vic_pl192.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/wd_fdc.h,MACHINES["WD_FDC"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index be51e22809e..945f1ee1fc2 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -672,6 +672,7 @@ MACHINES["UPD71071"] = true
MACHINES["UPD765"] = true
MACHINES["FDC_PLL"] = true
MACHINES["V3021"] = true
+MACHINES["VIC_PL192"] = true
MACHINES["WD_FDC"] = true
MACHINES["WD1000"] = true
MACHINES["WD1010"] = true
diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp
index 76eefbb44d3..0637c42ddc4 100644
--- a/src/devices/cpu/arm7/arm7.cpp
+++ b/src/devices/cpu/arm7/arm7.cpp
@@ -42,7 +42,7 @@ TODO:
#define LOG_COPRO_UNKNOWN (1 << 4)
#define LOG_COPRO_RESERVED (1 << 5)
-#define VERBOSE (0)
+#define VERBOSE (0) //(LOG_MMU | LOG_COPRO_READS | LOG_COPRO_WRITES)
#include "logmacro.h"
#define PRINT_HAPYFSH2 (0)
@@ -726,7 +726,6 @@ void arm946es_cpu_device::device_start()
save_item(NAME(DTCM));
}
-
void arm7_cpu_device::state_export(const device_state_entry &entry)
{
switch (entry.index())
@@ -787,6 +786,11 @@ void arm7_cpu_device::device_reset()
m_impstate.cache_dirty = true;
}
+void arm1176jzf_s_cpu_device::device_reset()
+{
+ arm7_cpu_device::device_reset();
+ m_control = 0x00050078;
+}
#define UNEXECUTED() \
m_r[eR15] += 4; \
@@ -1413,7 +1417,7 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
#if ARM7_MMU_ENABLE_HACK
if (((data & COPRO_CTRL_MMU_EN) != 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) == 0))
{
- >m_mmu_enable_addr = R15;
+ m_mmu_enable_addr = R15;
}
if (((data & COPRO_CTRL_MMU_EN) == 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) != 0))
{
@@ -1778,6 +1782,44 @@ void arm7_cpu_device::arm7_dt_w_callback(uint32_t insn, uint32_t *prn)
}
}
+READ32_MEMBER( arm1176jzf_s_cpu_device::arm7_rt_r_callback )
+{
+ uint32_t opcode = offset;
+ uint8_t crn = (opcode & INSN_COPRO_CREG) >> INSN_COPRO_CREG_SHIFT;
+ uint8_t op1 = (opcode & INSN_COPRO_OP1) >> INSN_COPRO_OP1_SHIFT;
+ uint8_t op2 = (opcode & INSN_COPRO_OP2) >> INSN_COPRO_OP2_SHIFT;
+ uint8_t crm = opcode & INSN_COPRO_OP3;
+ uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT;
+ uint32_t data = 0;
+
+// printf("arm7946: copro %d write %x to cReg %d op2 %d op3 %d (mask %08x)\n", cpnum, data, cReg, op2, op3, mem_mask);
+
+ if (cpnum == 15)
+ {
+ if(crn == 0 && op1 == 0 && crm == 0 && op2 == 0) data = 0x410FB767; //ARM1176JZF-S Main ID.
+ if(crn == 1 && op1 == 0 && crm == 0 && op2 == 0) data = m_control;
+ }
+
+ return data;
+}
+
+WRITE32_MEMBER( arm1176jzf_s_cpu_device::arm7_rt_w_callback )
+{
+ uint32_t opcode = offset;
+ uint8_t crn = (opcode & INSN_COPRO_CREG) >> INSN_COPRO_CREG_SHIFT;
+ uint8_t op1 = (opcode & INSN_COPRO_OP1) >> INSN_COPRO_OP1_SHIFT;
+ uint8_t op2 = (opcode & INSN_COPRO_OP2) >> INSN_COPRO_OP2_SHIFT;
+ uint8_t crm = opcode & INSN_COPRO_OP3;
+ uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT;
+
+// printf("arm7946: copro %d write %x to cReg %d op2 %d op3 %d (mask %08x)\n", cpnum, data, cReg, op2, op3, mem_mask);
+
+ if (cpnum == 15)
+ {
+ LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback: CP15 CRn %02x Op1 %02x CRm %02x Op2 %02x data %08x\n", crn, op1, crm, op2, data);
+ if(crn == 1 && op1 == 0 && crm == 0 && op2 == 0) m_control = data;
+ }
+}
/***************************************************************************
* Default Memory Handlers
diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h
index 938950cc9d8..5a7ca665b6f 100644
--- a/src/devices/cpu/arm7/arm7.h
+++ b/src/devices/cpu/arm7/arm7.h
@@ -179,7 +179,7 @@ protected:
uint32_t m_domainAccessControl;
uint8_t m_decoded_access_control[16];
- uint8_t m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
+ uint8_t m_archRev; // ARM architecture revision (3, 4, 5, and 6 are valid)
uint32_t m_archFlags; // architecture flags
uint32_t m_vectorbase;
@@ -674,6 +674,12 @@ 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);
+
+ virtual DECLARE_READ32_MEMBER( arm7_rt_r_callback ) override;
+ virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ) override;
+
+protected:
+ virtual void device_reset() override;
};
class igs036_cpu_device : public arm946es_cpu_device
diff --git a/src/devices/cpu/arm7/arm7core.h b/src/devices/cpu/arm7/arm7core.h
index a6a7838bed4..320638ce626 100644
--- a/src/devices/cpu/arm7/arm7core.h
+++ b/src/devices/cpu/arm7/arm7core.h
@@ -356,12 +356,14 @@ static const int sRegisterTable[ARM7_NUM_MODES][18] =
#define INSN_RD_SHIFT 12
#define INSN_COND_SHIFT 28
+#define INSN_COPRO_OP1 ((uint32_t) 0x00e00000u)
#define INSN_COPRO_N ((uint32_t) 0x00100000u)
#define INSN_COPRO_CREG ((uint32_t) 0x000f0000u)
#define INSN_COPRO_AREG ((uint32_t) 0x0000f000u)
#define INSN_COPRO_CPNUM ((uint32_t) 0x00000f00u)
#define INSN_COPRO_OP2 ((uint32_t) 0x000000e0u)
#define INSN_COPRO_OP3 ((uint32_t) 0x0000000fu)
+#define INSN_COPRO_OP1_SHIFT 21
#define INSN_COPRO_N_SHIFT 20
#define INSN_COPRO_CREG_SHIFT 16
#define INSN_COPRO_AREG_SHIFT 12
diff --git a/src/devices/machine/vic_pl192.cpp b/src/devices/machine/vic_pl192.cpp
new file mode 100644
index 00000000000..7eda1220987
--- /dev/null
+++ b/src/devices/machine/vic_pl192.cpp
@@ -0,0 +1,130 @@
+// license:BSD-3-Clause
+// copyright-holders:Melissa Goad
+
+// ARM PrimeCell PL192 VIC emulation
+
+#include "emu.h"
+#include "machine/bankdev.h"
+#include "machine/vic_pl192.h"
+
+#define LOG_GENERAL (1U << 0)
+
+#define VERBOSE (LOG_GENERAL)
+#include "logmacro.h"
+
+void vic_pl192_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if(u32 intrs = (raw_intr | soft_intr) & intr_en)
+ {
+ if(intrs & intr_select) m_out_fiq_func(1);
+ else m_out_fiq_func(0);
+
+ if(intrs & ~intr_select) m_out_irq_func(1);
+ else m_out_irq_func(0);
+ }
+}
+
+void vic_pl192_device::set_irq_line(int irq, int state)
+{
+ u32 mask = (1 << irq);
+
+ if(state)
+ {
+ raw_intr |= mask;
+ }
+ else
+ {
+ raw_intr &= ~mask;
+ }
+
+ timer_set(attotime::zero, TIMER_CHECK_IRQ);
+}
+
+void vic_pl192_device::map(address_map &map)
+{
+ map(0x000, 0x003).lr32([this](offs_t offset){ return raw_intr & ~intr_select; }, "irq_status"); //IRQ_STATUS
+ map(0x004, 0x007).lr32([this](offs_t offset){ return raw_intr & intr_select; }, "fiq_status"); //FIQ_STATUS
+ map(0x008, 0x00b).lr32([this](offs_t offset){ return raw_intr; }, "raw_intr");
+ map(0x00c, 0x00f).lrw32(NAME([this](offs_t offset){ return intr_select; }), NAME([this](offs_t offset, u32 data){ intr_select = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); }));
+ map(0x010, 0x013).lrw32(NAME([this](offs_t offset){ return intr_en; }), NAME([this](offs_t offset, u32 data){ intr_en = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); }));
+ map(0x014, 0x017).lw32([this](u32 data){ intr_en &= ~data; }, "intr_en_clear");
+ map(0x018, 0x01b).lrw32(NAME([this](offs_t offset){ return soft_intr; }), NAME([this](offs_t offset, u32 data){ soft_intr = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); }));
+ map(0x01c, 0x01f).lw32([this](u32 data){ soft_intr &= ~data; }, "soft_intr_clear");
+ map(0x020, 0x020).lrw8(NAME([this](offs_t offset){ return protection; }), NAME([this](offs_t offset, u8 data){ protection = data & 1; })).umask32(0x000000ff);
+ map(0x024, 0x025).lrw8(NAME([this](offs_t offset){ return sw_priority_mask; }), NAME([this](offs_t offset, u16 data){ sw_priority_mask = data; })).umask32(0x0000ffff);
+ map(0x028, 0x028).lrw8(NAME([this](offs_t offset){ return daisy_priority; }), NAME([this](offs_t offset, u8 data){ daisy_priority = data & 0xf; })).umask32(0x000000ff);
+ map(0x100, 0x17f).lrw32(NAME([this](offs_t offset){ return vectaddr[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; }));
+ map(0x200, 0x27f).lrw8(NAME([this](offs_t offset){ return vectprio[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectprio[(offset & 0x7c) >> 2] = data & 0xf; }));
+ map(0xf00, 0xf03).lrw32(NAME([this](offs_t offset){ return vicaddress; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; }));
+ map(0xfe0, 0xfe0).lr8([this](offs_t offset){ return periph_id[0]; }, "periph_id0").umask32(0x000000ff);
+ map(0xfe4, 0xfe4).lr8([this](offs_t offset){ return periph_id[1]; }, "periph_id1").umask32(0x000000ff);
+ map(0xfe8, 0xfe8).lr8([this](offs_t offset){ return periph_id[2]; }, "periph_id2").umask32(0x000000ff);
+ map(0xfec, 0xfec).lr8([this](offs_t offset){ return periph_id[3]; }, "periph_id3").umask32(0x000000ff);
+ map(0xff0, 0xff0).lr8([this](offs_t offset){ return pcell_id[0]; }, "pcell_id0").umask32(0x000000ff);
+ map(0xff4, 0xff4).lr8([this](offs_t offset){ return pcell_id[1]; }, "pcell_id1").umask32(0x000000ff);
+ map(0xff8, 0xff8).lr8([this](offs_t offset){ return pcell_id[2]; }, "pcell_id2").umask32(0x000000ff);
+ map(0xffc, 0xffc).lr8([this](offs_t offset){ return pcell_id[3]; }, "pcell_id3").umask32(0x000000ff);
+}
+
+device_memory_interface::space_config_vector vic_pl192_device::memory_space_config() const
+{
+ return space_config_vector{
+ std::make_pair(0, &m_mmio_config)
+ };
+}
+
+void vic_pl192_device::device_resolve_objects()
+{
+ // resolve callbacks
+ m_out_irq_func.resolve_safe();
+ m_out_fiq_func.resolve_safe();
+}
+
+void vic_pl192_device::device_start()
+{
+ save_item(NAME(raw_intr));
+ save_item(NAME(intr_select));
+ save_item(NAME(intr_en));
+ save_item(NAME(soft_intr));
+ save_item(NAME(vectaddr));
+ save_item(NAME(vicaddress));
+ save_item(NAME(protection));
+ save_item(NAME(sw_priority_mask));
+ save_item(NAME(daisy_priority));
+ save_item(NAME(vectprio));
+}
+
+void vic_pl192_device::device_reset()
+{
+ raw_intr = intr_select = intr_en = soft_intr = vicaddress = protection = 0;
+ sw_priority_mask = 0xffff;
+ daisy_priority = 0xf;
+
+ for(int i = 0; i < 32; i++)
+ {
+ vectaddr[i] = 0;
+ }
+
+ for(int i = 0; i < 32; i++)
+ {
+ vectprio[i] = 0xf;
+ }
+}
+
+DEFINE_DEVICE_TYPE(PL192_VIC, vic_pl192_device, "vic_pl192", "ARM PL192 VIC")
+
+vic_pl192_device::vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , m_mmio_config("mmio", ENDIANNESS_LITTLE, 32, 32, 0)
+ , m_out_irq_func(*this)
+ , m_out_fiq_func(*this)
+ , periph_id{0x92, 0x11, 0x04, 0x00}
+ , pcell_id{0x0d, 0xf0, 0x05, 0xb1}
+{
+}
+
+vic_pl192_device::vic_pl192_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : vic_pl192_device(mconfig, PL192_VIC, tag, owner, clock)
+{
+} \ No newline at end of file
diff --git a/src/devices/machine/vic_pl192.h b/src/devices/machine/vic_pl192.h
new file mode 100644
index 00000000000..79a40bd38ee
--- /dev/null
+++ b/src/devices/machine/vic_pl192.h
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Melissa Goad
+
+// ARM PrimeCell PL192 VIC emulation
+
+#ifndef MAME_MACHINE_VIC_PL192_H
+#define MAME_MACHINE_VIC_PL192_H
+
+class vic_pl192_device : public device_t, public device_memory_interface
+{
+public:
+ vic_pl192_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0);
+
+ auto out_irq_cb() { return m_out_irq_func.bind(); }
+ auto out_fiq_cb() { return m_out_fiq_func.bind(); }
+
+ template<unsigned IRQ>
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { set_irq_line(IRQ, state); }
+
+ void map(address_map &map);
+
+protected:
+ vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ virtual space_config_vector memory_space_config() const override;
+
+private:
+ static constexpr device_timer_id TIMER_CHECK_IRQ = 0;
+
+ void set_irq_line(int irq, int state);
+
+ address_space_config m_mmio_config;
+
+ devcb_write_line m_out_irq_func;
+ devcb_write_line m_out_fiq_func;
+ u32 raw_intr, intr_select, intr_en, soft_intr, vectaddr[32], vicaddress;
+ int protection;
+ u16 sw_priority_mask;
+ u8 daisy_priority, vectprio[32];
+ u8 periph_id[4], pcell_id[4];
+};
+
+DECLARE_DEVICE_TYPE(PL192_VIC, vic_pl192_device)
+
+#endif // MAME_MACHINE_VIC_PL192_H \ No newline at end of file
diff --git a/src/mame/drivers/iphone2g.cpp b/src/mame/drivers/iphone2g.cpp
index 868f520884f..7a6e3e0dd49 100644
--- a/src/mame/drivers/iphone2g.cpp
+++ b/src/mame/drivers/iphone2g.cpp
@@ -10,14 +10,212 @@
#include "emu.h"
#include "cpu/arm7/arm7.h"
+#include "cpu/arm7/arm7core.h"
+#include "machine/bankdev.h"
+#include "machine/vic_pl192.h"
#include "screen.h"
+class iphone2g_spi_device : public device_t, public device_memory_interface
+{
+public:
+ iphone2g_spi_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0);
+
+ auto out_irq_cb() { return m_out_irq_func.bind(); }
+
+ void map(address_map &map);
+
+protected:
+ iphone2g_spi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ virtual space_config_vector memory_space_config() const override;
+
+private:
+ static constexpr device_timer_id TIMER_SEND_IRQ = 0;
+
+ address_space_config m_mmio_config;
+
+ devcb_write_line m_out_irq_func;
+
+ u8 cmd, tx_data;
+ u32 ctrl;
+ u16 status;
+};
+
+DECLARE_DEVICE_TYPE(IPHONE2G_SPI, iphone2g_spi_device)
+
+void iphone2g_spi_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_out_irq_func(1);
+}
+
+void iphone2g_spi_device::map(address_map &map)
+{
+ map(0x00,0x03).lrw32(NAME([this](offs_t offset){ return ctrl; }), NAME([this](offs_t offset, u32 data){
+ if(data & 1)
+ {
+ status |= 0xfff2;
+ cmd = tx_data;
+ timer_set(attotime::from_hz(1'000), TIMER_SEND_IRQ);
+ }
+ ctrl = data;
+ }));
+ map(0x08, 0x09).lr16([this](offs_t offset){ return status; }, "status").umask32(0x0000ffff);
+ map(0x10, 0x10).lrw8(NAME([this](offs_t offset){ return tx_data; }), NAME([this](offs_t offset, u8 data){ tx_data = data; })).umask32(0x000000ff);
+ map(0x20, 0x20).lr8([this](offs_t offset){
+ // FIXME: make this less hacky
+ switch(cmd)
+ {
+ case 0x95: return 0x01;
+ case 0xda: return 0x71;
+ case 0xdb: return 0xc2;
+ case 0xdc: return 0x00;
+ }
+ return 0;
+ }, "rx_data");
+}
+
+device_memory_interface::space_config_vector iphone2g_spi_device::memory_space_config() const
+{
+ return space_config_vector{
+ std::make_pair(0, &m_mmio_config)
+ };
+}
+
+void iphone2g_spi_device::device_resolve_objects()
+{
+ // resolve callbacks
+ m_out_irq_func.resolve_safe();
+}
+
+void iphone2g_spi_device::device_start()
+{
+ save_item(NAME(cmd));
+ save_item(NAME(ctrl));
+ save_item(NAME(tx_data));
+ save_item(NAME(status));
+}
+
+void iphone2g_spi_device::device_reset()
+{
+ cmd = ctrl= status = tx_data = 0;
+}
+
+DEFINE_DEVICE_TYPE(IPHONE2G_SPI, iphone2g_spi_device, "iphone2g_spi", "iPhone 2G SPI controller")
+
+iphone2g_spi_device::iphone2g_spi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , m_mmio_config("mmio", ENDIANNESS_LITTLE, 32, 32, 0)
+ , m_out_irq_func(*this)
+{
+}
+
+iphone2g_spi_device::iphone2g_spi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : iphone2g_spi_device(mconfig, IPHONE2G_SPI, tag, owner, clock)
+{
+}
+
+class iphone2g_timer_device : public device_t, public device_memory_interface
+{
+public:
+ iphone2g_timer_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0);
+
+ auto out_irq_cb() { return m_out_irq_func.bind(); }
+
+ void map(address_map &map);
+ void timer_map(address_map &map);
+
+protected:
+ iphone2g_timer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ virtual space_config_vector memory_space_config() const override;
+
+private:
+ static constexpr device_timer_id TIMER_TICK = 0;
+
+ address_space_config m_mmio_config;
+
+ devcb_write_line m_out_irq_func;
+
+ struct timer
+ {
+ u16 config;
+ u8 state;
+ u32 count_buffer[2], count;
+ } timers[7];
+
+ u64 ticks;
+};
+
+DECLARE_DEVICE_TYPE(IPHONE2G_TIMER, iphone2g_timer_device)
+
+void iphone2g_timer_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_out_irq_func(1);
+}
+
+void iphone2g_timer_device::map(address_map &map)
+{
+}
+
+device_memory_interface::space_config_vector iphone2g_timer_device::memory_space_config() const
+{
+ return space_config_vector{
+ std::make_pair(0, &m_mmio_config)
+ };
+}
+
+void iphone2g_timer_device::device_resolve_objects()
+{
+ // resolve callbacks
+ m_out_irq_func.resolve_safe();
+}
+
+void iphone2g_timer_device::device_start()
+{
+}
+
+void iphone2g_timer_device::device_reset()
+{
+}
+
+DEFINE_DEVICE_TYPE(IPHONE2G_TIMER, iphone2g_timer_device, "iphone2g_timer", "iPhone 2G timers")
+
+iphone2g_timer_device::iphone2g_timer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , m_mmio_config("mmio", ENDIANNESS_LITTLE, 32, 32, 0)
+ , m_out_irq_func(*this)
+{
+}
+
+iphone2g_timer_device::iphone2g_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : iphone2g_timer_device(mconfig, IPHONE2G_SPI, tag, owner, clock)
+{
+}
+
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_vic0(*this, "vic0"),
+ m_vic1(*this, "vic1"),
+ m_spi(*this, {"spi0", "spi1", "spi2"}),
+ m_timers(*this, "timers"),
m_ram(*this, "ram"),
m_bios(*this, "bios"),
m_screen(*this, "screen")
@@ -33,7 +231,11 @@ protected:
private:
required_device<cpu_device> m_maincpu;
- required_shared_ptr<uint32_t> m_ram;
+ required_device<vic_pl192_device> m_vic0;
+ required_device<vic_pl192_device> m_vic1;
+ required_device_array<iphone2g_spi_device, 3> m_spi;
+ required_device<iphone2g_timer_device> m_timers;
+ optional_shared_ptr<uint32_t> m_ram;
required_region_ptr<uint32_t> m_bios;
required_device<screen_device> m_screen;
@@ -62,15 +264,19 @@ READ32_MEMBER(iphone2g_state::clock1_r)
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();
+ map(0x00000000, 0x0000ffff).mirror(0x20000000).rom().region("bios", 0); /* BIOS */
+ map(0x22000000, 0x224fffff).ram(); /* SRAM */
+ map(0x38e00000, 0x38e00fff).m(m_vic0, FUNC(vic_pl192_device::map));
+ map(0x38e01000, 0x38e01fff).m(m_vic1, FUNC(vic_pl192_device::map));
+ map(0x3c300000, 0x3c3000ff).m(m_spi[0], FUNC(iphone2g_spi_device::map));
+ map(0x3c500000, 0x3c500fff).r(FUNC(iphone2g_state::clock1_r)).nopw();
+ map(0x3ce00000, 0x3ce000ff).m(m_spi[1], FUNC(iphone2g_spi_device::map));
+ map(0x3d200000, 0x3d2000ff).m(m_spi[2], FUNC(iphone2g_spi_device::map));
}
void iphone2g_state::machine_start()
{
- std::copy_n(m_bios.target(), m_bios.length(), m_ram.target());
+ //std::copy_n(m_bios.target(), m_bios.length(), m_ram.target());
}
void iphone2g_state::machine_reset()
@@ -83,6 +289,24 @@ void iphone2g_state::iphone2g(machine_config &config)
ARM1176JZF_S(config, m_maincpu, XTAL(12'000'000) * 103 / 3); //412 MHz, downclocked from 600 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &iphone2g_state::mem_map);
+ PL192_VIC(config, m_vic0);
+ m_vic0->out_irq_cb().set_inputline("maincpu", ARM7_IRQ_LINE);
+ m_vic0->out_fiq_cb().set_inputline("maincpu", ARM7_FIRQ_LINE);
+
+ IPHONE2G_SPI(config, m_spi[0], XTAL(12'000'000));
+ m_spi[0]->out_irq_cb().set(m_vic0, FUNC(vic_pl192_device::irq_w<0x09>));
+
+ IPHONE2G_SPI(config, m_spi[1], XTAL(12'000'000));
+ m_spi[1]->out_irq_cb().set(m_vic0, FUNC(vic_pl192_device::irq_w<0x0a>));
+
+ IPHONE2G_SPI(config, m_spi[2], XTAL(12'000'000));
+ m_spi[2]->out_irq_cb().set(m_vic0, FUNC(vic_pl192_device::irq_w<0x0b>));
+
+ IPHONE2G_TIMER(config, m_timers, XTAL(12'000'000));
+ m_timers->out_irq_cb().set(m_vic0, FUNC(vic_pl192_device::irq_w<0x07>));
+
+ PL192_VIC(config, m_vic1);
+
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(XTAL(12'000'000), 320, 0, 320, 480, 0, 480); //Complete guess
m_screen->set_screen_update(FUNC(iphone2g_state::screen_update));