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 @@ -3130,6 +3130,18 @@ if (MACHINES["V3021"]~=null) then } 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 + 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 m_maincpu; - required_shared_ptr m_ram; + required_device m_vic0; + required_device m_vic1; + required_device_array m_spi; + required_device m_timers; + optional_shared_ptr m_ram; required_region_ptr m_bios; required_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));