mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
iphone2g wip (nw) (#6226)
* iphone2g wip (nw) * fixup * fixup * fixup * iphone2g: hacky spi and non-existent timers (nw)
This commit is contained in:
parent
a5783544e8
commit
e6595b06a7
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
130
src/devices/machine/vic_pl192.cpp
Normal file
130
src/devices/machine/vic_pl192.cpp
Normal file
@ -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)
|
||||
{
|
||||
}
|
51
src/devices/machine/vic_pl192.h
Normal file
51
src/devices/machine/vic_pl192.h
Normal file
@ -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
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user