mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
-arm7: Added placeholder devices for PXA250 and PXA270, and corrected PXA255 CPU ID. [Ryan Holtz]
-pxa255: Added preliminary support for RTC, clock, and power management registers. [Ryan Holtz] -zaurus: Added correct dumps for SL-5500 model. Renamed existing SL-5500 model to suspected model (SL-C500). [Ryan Holtz]
This commit is contained in:
parent
fc7f76dc12
commit
13fc949465
@ -66,7 +66,9 @@ DEFINE_DEVICE_TYPE(ARM920T, arm920t_cpu_device, "arm920t", "ARM92
|
||||
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(PXA250, pxa250_cpu_device, "pxa250", "Intel XScale PXA250")
|
||||
DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255")
|
||||
DEFINE_DEVICE_TYPE(PXA270, pxa270_cpu_device, "pxa270", "Intel XScale PXA270")
|
||||
DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110")
|
||||
DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036")
|
||||
|
||||
@ -236,13 +238,30 @@ igs036_cpu_device::igs036_cpu_device(const machine_config &mconfig, const char *
|
||||
{
|
||||
}
|
||||
|
||||
pxa250_cpu_device::pxa250_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: arm7_cpu_device(mconfig, PXA250, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E | ARCHFLAG_XSCALE, ENDIANNESS_LITTLE)
|
||||
{
|
||||
m_copro_id = ARM9_COPRO_ID_MFR_INTEL
|
||||
| ARM9_COPRO_ID_ARCH_V5TE
|
||||
| ARM9_COPRO_ID_PART_PXA250
|
||||
| ARM9_COPRO_ID_STEP_PXA255_A0;
|
||||
}
|
||||
|
||||
pxa255_cpu_device::pxa255_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: arm7_cpu_device(mconfig, PXA255, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E | ARCHFLAG_XSCALE, ENDIANNESS_LITTLE)
|
||||
{
|
||||
m_copro_id = ARM9_COPRO_ID_MFR_INTEL
|
||||
| ARM9_COPRO_ID_ARCH_V5TE
|
||||
| ARM9_COPRO_ID_PXA255_CORE_GEN_XSCALE
|
||||
| (3 << ARM9_COPRO_ID_PXA255_CORE_REV_SHIFT)
|
||||
| ARM9_COPRO_ID_PART_PXA255
|
||||
| ARM9_COPRO_ID_STEP_PXA255_A0;
|
||||
}
|
||||
|
||||
pxa270_cpu_device::pxa270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: arm7_cpu_device(mconfig, PXA270, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E | ARCHFLAG_XSCALE, ENDIANNESS_LITTLE)
|
||||
{
|
||||
m_copro_id = ARM9_COPRO_ID_MFR_INTEL
|
||||
| ARM9_COPRO_ID_ARCH_V5TE
|
||||
| ARM9_COPRO_ID_PART_PXA270
|
||||
| ARM9_COPRO_ID_STEP_PXA255_A0;
|
||||
}
|
||||
|
||||
|
@ -89,10 +89,12 @@ protected:
|
||||
ARM9_COPRO_ID_PART_ARM946 = 0x946 << 4,
|
||||
ARM9_COPRO_ID_PART_ARM920 = 0x920 << 4,
|
||||
ARM9_COPRO_ID_PART_ARM710 = 0x710 << 4,
|
||||
ARM9_COPRO_ID_PART_PXA250 = 0x200 << 4,
|
||||
ARM9_COPRO_ID_PART_PXA255 = 0x2d0 << 4,
|
||||
ARM9_COPRO_ID_PART_PXA270 = 0x411 << 4,
|
||||
ARM9_COPRO_ID_PART_GENERICARM7 = 0x700 << 4,
|
||||
|
||||
ARM9_COPRO_ID_PXA255_CORE_REV_SHIFT = 10,
|
||||
ARM9_COPRO_ID_PXA255_CORE_GEN_XSCALE = 0x01 << 13,
|
||||
|
||||
ARM9_COPRO_ID_ARCH_V4 = 0x01 << 16,
|
||||
ARM9_COPRO_ID_ARCH_V4T = 0x02 << 16,
|
||||
@ -691,6 +693,13 @@ public:
|
||||
igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class pxa250_cpu_device : public arm7_cpu_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
pxa250_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class pxa255_cpu_device : public arm7_cpu_device
|
||||
{
|
||||
public:
|
||||
@ -698,6 +707,12 @@ public:
|
||||
pxa255_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class pxa270_cpu_device : public arm7_cpu_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
pxa270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class sa1110_cpu_device : public arm7_cpu_device
|
||||
{
|
||||
@ -716,7 +731,9 @@ 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(PXA250, pxa250_cpu_device)
|
||||
DECLARE_DEVICE_TYPE(PXA255, pxa255_cpu_device)
|
||||
DECLARE_DEVICE_TYPE(PXA270, pxa270_cpu_device)
|
||||
DECLARE_DEVICE_TYPE(SA1110, sa1110_cpu_device)
|
||||
DECLARE_DEVICE_TYPE(IGS036, igs036_cpu_device)
|
||||
|
||||
|
@ -23,9 +23,12 @@
|
||||
#define LOG_GPIO (1 << 6)
|
||||
#define LOG_LCD_DMA (1 << 7)
|
||||
#define LOG_LCD (1 << 8)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_I2S | LOG_DMA | LOG_OSTIMER | LOG_INTC | LOG_GPIO | LOG_LCD_DMA | LOG_LCD)
|
||||
#define LOG_POWER (1 << 9)
|
||||
#define LOG_RTC (1 << 10)
|
||||
#define LOG_CLOCKS (1 << 11)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_I2S | LOG_DMA | LOG_OSTIMER | LOG_INTC | LOG_GPIO | LOG_LCD_DMA | LOG_LCD | LOG_POWER | LOG_RTC | LOG_CLOCKS)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#define VERBOSE (LOG_ALL)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(PXA255_PERIPHERALS, pxa255_periphs_device, "pxa255_periphs", "Intel XScale PXA255 Peripherals")
|
||||
@ -198,14 +201,14 @@ void pxa255_periphs_device::dma_load_descriptor_and_start(int channel)
|
||||
m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_STOPSTATE;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_dma_end)
|
||||
void pxa255_periphs_device::dma_end_tick(int channel)
|
||||
{
|
||||
uint32_t sadr = m_dma_regs.dsadr[param];
|
||||
uint32_t tadr = m_dma_regs.dtadr[param];
|
||||
uint32_t count = m_dma_regs.dcmd[param] & 0x00001fff;
|
||||
uint32_t sadr = m_dma_regs.dsadr[channel];
|
||||
uint32_t tadr = m_dma_regs.dtadr[channel];
|
||||
uint32_t count = m_dma_regs.dcmd[channel] & 0x00001fff;
|
||||
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
switch (param)
|
||||
switch (channel)
|
||||
{
|
||||
case 3:
|
||||
for (uint32_t index = 0; index < count; index += 4)
|
||||
@ -224,7 +227,7 @@ TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_dma_end)
|
||||
default:
|
||||
for (uint32_t index = 0; index < count;)
|
||||
{
|
||||
switch (m_dma_regs.dcmd[param] & PXA255_DCMD_SIZE)
|
||||
switch (m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE)
|
||||
{
|
||||
case PXA255_DCMD_SIZE_8:
|
||||
space.write_byte(tadr, space.read_byte(sadr));
|
||||
@ -243,9 +246,9 @@ TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_dma_end)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_dma_regs.dcmd[param] & PXA255_DCMD_INCSRCADDR)
|
||||
if (m_dma_regs.dcmd[channel] & PXA255_DCMD_INCSRCADDR)
|
||||
{
|
||||
switch(m_dma_regs.dcmd[param] & PXA255_DCMD_SIZE)
|
||||
switch(m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE)
|
||||
{
|
||||
case PXA255_DCMD_SIZE_8:
|
||||
sadr++;
|
||||
@ -260,9 +263,9 @@ TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_dma_end)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(m_dma_regs.dcmd[param] & PXA255_DCMD_INCTRGADDR)
|
||||
if(m_dma_regs.dcmd[channel] & PXA255_DCMD_INCTRGADDR)
|
||||
{
|
||||
switch(m_dma_regs.dcmd[param] & PXA255_DCMD_SIZE)
|
||||
switch(m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE)
|
||||
{
|
||||
case PXA255_DCMD_SIZE_8:
|
||||
tadr++;
|
||||
@ -281,27 +284,27 @@ TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_dma_end)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_dma_regs.dcmd[param] & PXA255_DCMD_ENDIRQEN)
|
||||
if (m_dma_regs.dcmd[channel] & PXA255_DCMD_ENDIRQEN)
|
||||
{
|
||||
m_dma_regs.dcsr[param] |= PXA255_DCSR_ENDINTR;
|
||||
m_dma_regs.dcsr[channel] |= PXA255_DCSR_ENDINTR;
|
||||
}
|
||||
|
||||
if (!(m_dma_regs.ddadr[param] & PXA255_DDADR_STOP) && (m_dma_regs.dcsr[param] & PXA255_DCSR_RUN))
|
||||
if (!(m_dma_regs.ddadr[channel] & PXA255_DDADR_STOP) && (m_dma_regs.dcsr[channel] & PXA255_DCSR_RUN))
|
||||
{
|
||||
if (m_dma_regs.dcsr[param] & PXA255_DCSR_RUN)
|
||||
if (m_dma_regs.dcsr[channel] & PXA255_DCSR_RUN)
|
||||
{
|
||||
dma_load_descriptor_and_start(param);
|
||||
dma_load_descriptor_and_start(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dma_regs.dcsr[param] &= ~PXA255_DCSR_RUN;
|
||||
m_dma_regs.dcsr[param] |= PXA255_DCSR_STOPSTATE;
|
||||
m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_RUN;
|
||||
m_dma_regs.dcsr[channel] |= PXA255_DCSR_STOPSTATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dma_regs.dcsr[param] &= ~PXA255_DCSR_RUN;
|
||||
m_dma_regs.dcsr[param] |= PXA255_DCSR_STOPSTATE;
|
||||
m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_RUN;
|
||||
m_dma_regs.dcsr[channel] |= PXA255_DCSR_STOPSTATE;
|
||||
}
|
||||
|
||||
dma_irq_check();
|
||||
@ -444,6 +447,95 @@ void pxa255_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mas
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
PXA255 Real-Time Clock
|
||||
|
||||
pg. 132 to 138, PXA255 Processor Developers Manual [278693-002].pdf
|
||||
|
||||
*/
|
||||
|
||||
void pxa255_periphs_device::rtc_tick()
|
||||
{
|
||||
m_rtc_regs.rcnr++;
|
||||
if (BIT(m_rtc_regs.rtsr, 3))
|
||||
{
|
||||
m_rtc_regs.rtsr |= (1 << 1);
|
||||
set_irq_line(PXA255_INT_RTC_HZ, 1);
|
||||
}
|
||||
|
||||
if (m_rtc_regs.rcnr == m_rtc_regs.rtar)
|
||||
{
|
||||
if (BIT(m_rtc_regs.rtsr, 2))
|
||||
{
|
||||
m_rtc_regs.rtsr |= (1 << 0);
|
||||
set_irq_line(PXA255_INT_RTC_ALARM, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pxa255_periphs_device::rtc_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_RTC_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_RCNR:
|
||||
LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Counter Register: %08x\n", machine().describe_context(), m_rtc_regs.rcnr);
|
||||
return m_rtc_regs.rcnr;
|
||||
case PXA255_RTAR:
|
||||
LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Alarm Register: %08x\n", machine().describe_context(), m_rtc_regs.rtar);
|
||||
return m_rtc_regs.rtar;
|
||||
case PXA255_RTSR:
|
||||
LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Status Register: %08x\n", machine().describe_context(), m_rtc_regs.rtsr);
|
||||
return m_rtc_regs.rtsr;
|
||||
case PXA255_RTTR:
|
||||
LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Trim Register: %08x\n", machine().describe_context(), m_rtc_regs.rttr);
|
||||
return m_rtc_regs.rttr;
|
||||
default:
|
||||
LOGMASKED(LOG_RTC | LOG_UNKNOWN, "pxa255 rtc_r: Unknown address: %08x\n", PXA255_RTC_BASE_ADDR | (offset << 2));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_RTC_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_RCNR:
|
||||
LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Counter Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_rtc_regs.rcnr);
|
||||
break;
|
||||
case PXA255_RTAR:
|
||||
LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Alarm Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_rtc_regs.rtar);
|
||||
break;
|
||||
case PXA255_RTSR:
|
||||
{
|
||||
LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
const uint32_t old = m_rtc_regs.rtsr;
|
||||
m_rtc_regs.rtsr &= ~(data & 0x00000003);
|
||||
m_rtc_regs.rtsr &= ~0x0000000c;
|
||||
m_rtc_regs.rtsr |= data & 0x0000000c;
|
||||
const uint32_t diff = old ^ m_rtc_regs.rtsr;
|
||||
if (BIT(diff, 1))
|
||||
set_irq_line(PXA255_INT_RTC_HZ, 0);
|
||||
if (BIT(diff, 0))
|
||||
set_irq_line(PXA255_INT_RTC_ALARM, 0);
|
||||
break;
|
||||
}
|
||||
case PXA255_RTTR:
|
||||
LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Trim Register (not yet implemented): %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
if (!BIT(m_rtc_regs.rttr, 31))
|
||||
{
|
||||
COMBINE_DATA(&m_rtc_regs.rttr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_RTC | LOG_UNKNOWN, "pxa255 rtc_w: Unknown address: %08x = %08x & %08x\n", PXA255_RTC_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
PXA255 OS Timer register
|
||||
@ -460,10 +552,10 @@ void pxa255_periphs_device::ostimer_irq_check()
|
||||
//set_irq_line(PXA255_INT_OSTIMER3, (m_ostimer_regs.oier & PXA255_OIER_E3) ? ((m_ostimer_regs.ossr & PXA255_OSSR_M3) ? 1 : 0) : 0);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(pxa255_periphs_device::ostimer_match)
|
||||
void pxa255_periphs_device::ostimer_match_tick(int channel)
|
||||
{
|
||||
m_ostimer_regs.ossr |= (1 << param);
|
||||
m_ostimer_regs.oscr = m_ostimer_regs.osmr[param];
|
||||
m_ostimer_regs.ossr |= (1 << channel);
|
||||
m_ostimer_regs.oscr = m_ostimer_regs.osmr[channel];
|
||||
ostimer_irq_check();
|
||||
}
|
||||
|
||||
@ -663,6 +755,77 @@ void pxa255_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
|
||||
*/
|
||||
|
||||
uint32_t pxa255_periphs_device::gpio_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
const uint32_t val = (data != 0 ? 1 : 0);
|
||||
LOGMASKED(LOG_GPIO, "pxa255: GPIO%d written: %d\n", offset, val);
|
||||
if (offset < 32)
|
||||
{
|
||||
const uint32_t old = m_gpio_regs.gplr0;
|
||||
m_gpio_regs.gplr0 &= ~(1 << offset);
|
||||
m_gpio_regs.gplr0 |= (val << offset);
|
||||
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Old GPLR0 %08x, New GPLR0 %08x\n", old, m_gpio_regs.gplr0);
|
||||
|
||||
const uint32_t rising = ~old & m_gpio_regs.gplr0;
|
||||
const uint32_t falling = old & ~m_gpio_regs.gplr0;
|
||||
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Rising %08x, Falling %08x\n", rising, falling);
|
||||
|
||||
const uint32_t old_gedr = m_gpio_regs.gedr0;
|
||||
m_gpio_regs.gedr0 |= (rising & m_gpio_regs.grer0);
|
||||
m_gpio_regs.gedr0 |= (falling & m_gpio_regs.gfer0);
|
||||
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Old GEDR0 %08x, New GEDR0 %08x\n", old_gedr, m_gpio_regs.gedr0);
|
||||
if (old_gedr != m_gpio_regs.gedr0)
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset);
|
||||
if (offset > 1)
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 1);
|
||||
else if (offset == 1)
|
||||
set_irq_line(PXA255_INT_GPIO1, 1);
|
||||
else
|
||||
set_irq_line(PXA255_INT_GPIO0, 1);
|
||||
}
|
||||
}
|
||||
else if (offset < 64)
|
||||
{
|
||||
const uint32_t old = m_gpio_regs.gplr1;
|
||||
m_gpio_regs.gplr1 &= ~(1 << (offset - 32));
|
||||
m_gpio_regs.gplr1 |= ~(val << (offset - 32));
|
||||
|
||||
const uint32_t rising = ~old & m_gpio_regs.gplr1;
|
||||
const uint32_t falling = old & ~m_gpio_regs.gplr1;
|
||||
|
||||
const uint32_t old_gedr = m_gpio_regs.gedr1;
|
||||
m_gpio_regs.gedr1 |= (rising & m_gpio_regs.grer1);
|
||||
m_gpio_regs.gedr1 |= (falling & m_gpio_regs.gfer1);
|
||||
if (old_gedr != m_gpio_regs.gedr1)
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset);
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 1);
|
||||
}
|
||||
}
|
||||
else if (offset < 85)
|
||||
{
|
||||
const uint32_t old = m_gpio_regs.gplr2;
|
||||
m_gpio_regs.gplr2 &= ~(1 << (offset - 64));
|
||||
m_gpio_regs.gplr2 |= ~(val << (offset - 64));
|
||||
|
||||
const uint32_t rising = ~old & m_gpio_regs.gplr2;
|
||||
const uint32_t falling = old & ~m_gpio_regs.gplr2;
|
||||
|
||||
const uint32_t old_gedr = m_gpio_regs.gedr2;
|
||||
m_gpio_regs.gedr2 |= (rising & m_gpio_regs.grer2);
|
||||
m_gpio_regs.gedr2 |= (falling & m_gpio_regs.gfer2);
|
||||
if (old_gedr != m_gpio_regs.gedr2)
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset);
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pxa255_periphs_device::gpio_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_GPIO_BASE_ADDR | (offset << 2))
|
||||
@ -844,17 +1007,39 @@ void pxa255_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
m_gpio_regs.gfer2 = data;
|
||||
break;
|
||||
case PXA255_GEDR0:
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 0: %08x & %08x\n", m_gpio_regs.gedr0, mem_mask);
|
||||
const uint32_t old = m_gpio_regs.gedr0;
|
||||
m_gpio_regs.gedr0 &= ~data;
|
||||
const uint32_t lowered = old & ~m_gpio_regs.gedr0;
|
||||
if (BIT(lowered, 0))
|
||||
set_irq_line(PXA255_INT_GPIO0, 0);
|
||||
else if (BIT(lowered, 1))
|
||||
set_irq_line(PXA255_INT_GPIO1, 0);
|
||||
else if ((lowered & 0xfffffffc) && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2)
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 0);
|
||||
break;
|
||||
}
|
||||
case PXA255_GEDR1:
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 1: %08x & %08x\n", m_gpio_regs.gedr1, mem_mask);
|
||||
const uint32_t old = m_gpio_regs.gedr1;
|
||||
m_gpio_regs.gedr1 &= ~data;
|
||||
const uint32_t lowered = old & !m_gpio_regs.gedr1;
|
||||
if (lowered && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2)
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 0);
|
||||
break;
|
||||
}
|
||||
case PXA255_GEDR2:
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 2: %08x & %08x\n", m_gpio_regs.gedr2, mem_mask);
|
||||
const uint32_t old = m_gpio_regs.gedr2;
|
||||
m_gpio_regs.gedr2 &= ~data;
|
||||
const uint32_t lowered = old & !m_gpio_regs.gedr2;
|
||||
if (lowered && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2)
|
||||
set_irq_line(PXA255_INT_GPIO84_2, 0);
|
||||
break;
|
||||
}
|
||||
case PXA255_GAFR0_L:
|
||||
LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 0 Lower: %08x & %08x\n", m_gpio_regs.gafr0l, mem_mask);
|
||||
m_gpio_regs.gafr0l = data;
|
||||
@ -987,15 +1172,15 @@ void pxa255_periphs_device::lcd_check_load_next_branch(int channel)
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(pxa255_periphs_device::lcd_dma_eof)
|
||||
void pxa255_periphs_device::lcd_dma_eof_tick(int channel)
|
||||
{
|
||||
LOGMASKED(LOG_LCD_DMA, "End of frame callback\n" );
|
||||
if(m_lcd_regs.dma[param].ldcmd & PXA255_LDCMD_EOFINT)
|
||||
if(m_lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_EOFINT)
|
||||
{
|
||||
m_lcd_regs.liidr = m_lcd_regs.dma[param].fidr;
|
||||
m_lcd_regs.liidr = m_lcd_regs.dma[channel].fidr;
|
||||
m_lcd_regs.lcsr |= PXA255_LCSR_EOF;
|
||||
}
|
||||
lcd_check_load_next_branch(param);
|
||||
lcd_check_load_next_branch(channel);
|
||||
lcd_irq_check();
|
||||
}
|
||||
|
||||
@ -1168,20 +1353,182 @@ void pxa255_periphs_device::lcd_w(address_space &space, offs_t offset, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
uin32_t pxa255_periphs_device::power_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_POWER_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_PMCR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Control Register: %08x\n", machine().describe_context(), m_power_regs.pmcr);
|
||||
return m_power_regs.pmcr;
|
||||
case PXA255_PSSR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Sleep Status Register: %08x\n", machine().describe_context(), m_power_regs.pssr);
|
||||
return m_power_regs.pssr;
|
||||
case PXA255_PSPR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Scratch Pad Register: %08x\n", machine().describe_context(), m_power_regs.pspr);
|
||||
return m_power_regs.pspr;
|
||||
case PXA255_PWER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Wake-up Enable Register: %08x\n", machine().describe_context(), m_power_regs.pwer);
|
||||
return m_power_regs.pwer;
|
||||
case PXA255_PRER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Rising-Edge Detect Enable Register: %08x\n", machine().describe_context(), m_power_regs.prer);
|
||||
return m_power_regs.prer;
|
||||
case PXA255_PFER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Falling-Edge Detect Enable Register: %08x\n", machine().describe_context(), m_power_regs.pfer);
|
||||
return m_power_regs.pfer;
|
||||
case PXA255_PEDR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Edge Detect Status Register: %08x\n", machine().describe_context(), m_power_regs.pedr);
|
||||
return m_power_regs.pedr;
|
||||
case PXA255_PCFR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager General Configuration Register: %08x\n", machine().describe_context(), m_power_regs.pcfr);
|
||||
return m_power_regs.pcfr;
|
||||
case PXA255_PGSR0:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[31-0]: %08x\n", machine().describe_context(), m_power_regs.pgsr0);
|
||||
return m_power_regs.pgsr0;
|
||||
case PXA255_PGSR1:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[63-32]: %08x\n", machine().describe_context(), m_power_regs.pgsr1);
|
||||
return m_power_regs.pgsr1;
|
||||
case PXA255_PGSR2:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[84-64]: %08x\n", machine().describe_context(), m_power_regs.pgsr2);
|
||||
return m_power_regs.pgsr2;
|
||||
case PXA255_RCSR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Reset Controller Status Register: %08x\n", machine().describe_context(), m_power_regs.rcsr);
|
||||
return m_power_regs.rcsr;
|
||||
case PXA255_PMFW:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Fast Sleep Walk-Up Configuration Register: %08x\n", machine().describe_context(), m_power_regs.pmfw);
|
||||
return m_power_regs.pmfw;
|
||||
default:
|
||||
LOGMASKED(LOG_POWER | LOG_UNKNOWN, "%s: power_r: Unknown address: %08x\n", machine().describe_context(), PXA255_POWER_BASE_ADDR | (offset << 2));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::power_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_POWER_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_PMCR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pmcr);
|
||||
break;
|
||||
case PXA255_PSSR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Sleep Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_power_regs.pssr &= ~(data & 0x00000037);
|
||||
break;
|
||||
case PXA255_PSPR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pspr);
|
||||
break;
|
||||
case PXA255_PWER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Wake-Up Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pwer);
|
||||
break;
|
||||
case PXA255_PRER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Rising-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.prer);
|
||||
break;
|
||||
case PXA255_PFER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Falling-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pfer);
|
||||
break;
|
||||
case PXA255_PEDR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Edge Detect Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_power_regs.pedr &= ~(data & 0x0000ffff);
|
||||
break;
|
||||
case PXA255_PCFR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager General Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pcfr);
|
||||
break;
|
||||
case PXA255_PGSR0:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pgsr0);
|
||||
break;
|
||||
case PXA255_PGSR1:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pgsr1);
|
||||
break;
|
||||
case PXA255_PGSR2:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pgsr2);
|
||||
break;
|
||||
case PXA255_PMFW:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Fast Sleep Walk-Up Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pmfw);
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_POWER | LOG_UNKNOWN, "%s: power_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PXA255_POWER_BASE_ADDR | (offset << 2),
|
||||
data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PXA255 Clock controller
|
||||
|
||||
pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf
|
||||
|
||||
*/
|
||||
|
||||
uint32_t pxa255_periphs_device::clocks_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_CLOCKS_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_CCCR:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Core Clock Configuration Register: %08x\n", machine().describe_context(), m_clocks_regs.cccr);
|
||||
return m_clocks_regs.cccr;
|
||||
case PXA255_CKEN:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Clock Enable Register: %08x\n", machine().describe_context(), m_clocks_regs.cken);
|
||||
return m_clocks_regs.cken;
|
||||
case PXA255_OSCC:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Oscillator Configuration Register: %08x\n", machine().describe_context(), m_clocks_regs.oscc);
|
||||
return BIT(m_clocks_regs.oscc, 0);
|
||||
default:
|
||||
LOGMASKED(LOG_CLOCKS | LOG_UNKNOWN, "%s: clocks_r: Unknown address: %08x\n", machine().describe_context(), PXA255_CLOCKS_BASE_ADDR | (offset << 2));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::clocks_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch(PXA255_CLOCKS_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_CCCR:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Core Clock Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_clocks_regs.cccr);
|
||||
break;
|
||||
case PXA255_CKEN:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Clock Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_clocks_regs.cken);
|
||||
break;
|
||||
case PXA255_OSCC:
|
||||
LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Oscillator Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
if (BIT(data, 1))
|
||||
{
|
||||
m_clocks_regs.oscc |= 0x00000003;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_CLOCKS | LOG_UNKNOWN, "%s: clocks_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PXA255_CLOCKS_BASE_ADDR | (offset << 2),
|
||||
data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::device_start()
|
||||
{
|
||||
for (int index = 0; index < 16; index++)
|
||||
{
|
||||
m_dma_regs.timer[index] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pxa255_periphs_device::dma_dma_end),this));
|
||||
m_dma_regs.timer[index] = timer_alloc(TIMER_DMA0 + index);
|
||||
}
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
{
|
||||
m_ostimer_regs.timer[index] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pxa255_periphs_device::ostimer_match),this));
|
||||
m_ostimer_regs.timer[index] = timer_alloc(TIMER_OSTIMER0 + index);
|
||||
}
|
||||
|
||||
m_lcd_regs.dma[0].eof = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pxa255_periphs_device::lcd_dma_eof),this));
|
||||
m_lcd_regs.dma[1].eof = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pxa255_periphs_device::lcd_dma_eof),this));
|
||||
m_lcd_regs.dma[0].eof = timer_alloc(TIMER_LCD_EOF0);
|
||||
m_lcd_regs.dma[1].eof = timer_alloc(TIMER_LCD_EOF0 + 1);
|
||||
|
||||
m_lcd_palette = make_unique_clear<uint32_t[]>(0x100);
|
||||
m_lcd_framebuffer = make_unique_clear<uint8_t[]>(0x100000);
|
||||
@ -1194,6 +1541,8 @@ void pxa255_periphs_device::device_start()
|
||||
m_gpio0_r.resolve_safe(0xffffffff);
|
||||
m_gpio1_r.resolve_safe(0xffffffff);
|
||||
m_gpio2_r.resolve_safe(0xffffffff);
|
||||
|
||||
m_rtc_regs.timer = timer_alloc(TIMER_RTC);
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::device_reset()
|
||||
@ -1203,10 +1552,31 @@ void pxa255_periphs_device::device_reset()
|
||||
m_dma_regs.dcsr[index] = 0x00000008;
|
||||
}
|
||||
|
||||
m_rtc_regs.rcnr = 0x00000000;
|
||||
m_rtc_regs.rtar = 0x00000000;
|
||||
m_rtc_regs.rtsr = 0x00000000;
|
||||
m_rtc_regs.rttr = 0x00007fff;
|
||||
m_rtc_regs.timer->adjust(attotime::from_hz(1));
|
||||
|
||||
memset(&m_intc_regs, 0, sizeof(m_intc_regs));
|
||||
|
||||
m_lcd_regs.trgbr = 0x00aa5500;
|
||||
m_lcd_regs.tcr = 0x0000754f;
|
||||
|
||||
memset(&m_power_regs, 0, sizeof(m_power_regs));
|
||||
memset(&m_clocks_regs, 0, sizeof(m_clocks_regs));
|
||||
}
|
||||
|
||||
void pxa255_periphs_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (id < TIMER_OSTIMER0)
|
||||
dma_end_tick(id);
|
||||
else if (id < TIMER_LCD_EOF0)
|
||||
ostimer_match_tick(id - TIMER_OSTIMER0);
|
||||
else if (id < TIMER_RTC)
|
||||
lcd_dma_eof_tick(id - TIMER_LCD_EOF0);
|
||||
else if (id == TIMER_RTC)
|
||||
rtc_tick();
|
||||
}
|
||||
|
||||
uint32_t pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
|
@ -37,25 +37,36 @@ public:
|
||||
auto gpio0_write() { return m_gpio0_w.bind(); }
|
||||
auto gpio0_read() { return m_gpio0_r.bind(); }
|
||||
|
||||
uint32_t i2s_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void i2s_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t dma_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void dma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t i2s_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void i2s_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t rtc_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t ostimer_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t intc_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void intc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
void gpio_bit_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
|
||||
uint32_t gpio_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t lcd_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void lcd_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
|
||||
void set_irq_line(uint32_t line, int state);
|
||||
uint32_t power_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void power_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t clocks_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void clocks_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) 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;
|
||||
|
||||
static const device_timer_id TIMER_DMA0 = 0;
|
||||
static const device_timer_id TIMER_OSTIMER0 = 16;
|
||||
static const device_timer_id TIMER_LCD_EOF0 = 20;
|
||||
static const device_timer_id TIMER_RTC = 22;
|
||||
|
||||
void dma_irq_check();
|
||||
void dma_load_descriptor_and_start(int channel);
|
||||
@ -68,11 +79,14 @@ protected:
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dma_dma_end);
|
||||
TIMER_CALLBACK_MEMBER(ostimer_match);
|
||||
TIMER_CALLBACK_MEMBER(lcd_dma_eof);
|
||||
void dma_end_tick(int channel);
|
||||
void ostimer_match_tick(int channel);
|
||||
void lcd_dma_eof_tick(int channel);
|
||||
void rtc_tick();
|
||||
|
||||
struct dma_regs_t
|
||||
void set_irq_line(uint32_t line, int state);
|
||||
|
||||
struct dma_regs
|
||||
{
|
||||
uint32_t dcsr[16];
|
||||
uint32_t pad0[44];
|
||||
@ -91,7 +105,7 @@ protected:
|
||||
emu_timer* timer[16];
|
||||
};
|
||||
|
||||
struct i2s_regs_t
|
||||
struct i2s_regs
|
||||
{
|
||||
uint32_t sacr0;
|
||||
uint32_t sacr1;
|
||||
@ -110,7 +124,16 @@ protected:
|
||||
uint32_t sadr;
|
||||
};
|
||||
|
||||
struct ostmr_regs_t
|
||||
struct rtc_regs
|
||||
{
|
||||
uint32_t rcnr;
|
||||
uint32_t rtar;
|
||||
uint32_t rtsr;
|
||||
uint32_t rttr;
|
||||
emu_timer *timer;
|
||||
};
|
||||
|
||||
struct ostmr_regs
|
||||
{
|
||||
uint32_t osmr[4];
|
||||
uint32_t oscr;
|
||||
@ -121,7 +144,7 @@ protected:
|
||||
emu_timer* timer[4];
|
||||
};
|
||||
|
||||
struct intc_regs_t
|
||||
struct intc_regs
|
||||
{
|
||||
uint32_t icip;
|
||||
uint32_t icmr;
|
||||
@ -131,7 +154,7 @@ protected:
|
||||
uint32_t iccr;
|
||||
};
|
||||
|
||||
struct gpio_regs_t
|
||||
struct gpio_regs
|
||||
{
|
||||
uint32_t gplr0; // GPIO Pin-Level
|
||||
uint32_t gplr1;
|
||||
@ -169,7 +192,7 @@ protected:
|
||||
uint32_t gafr2u;
|
||||
};
|
||||
|
||||
struct lcd_dma_regs_t
|
||||
struct lcd_dma_regs
|
||||
{
|
||||
uint32_t fdadr;
|
||||
uint32_t fsadr;
|
||||
@ -178,32 +201,56 @@ protected:
|
||||
emu_timer *eof;
|
||||
};
|
||||
|
||||
struct lcd_regs_t
|
||||
struct lcd_regs
|
||||
{
|
||||
uint32_t lccr0;
|
||||
uint32_t lccr1;
|
||||
uint32_t lccr2;
|
||||
uint32_t lccr3;
|
||||
uint32_t pad0[4];
|
||||
|
||||
uint32_t fbr[2];
|
||||
uint32_t pad1[4];
|
||||
|
||||
uint32_t lcsr;
|
||||
uint32_t liidr;
|
||||
uint32_t trgbr;
|
||||
uint32_t tcr;
|
||||
uint32_t pad2[110];
|
||||
|
||||
lcd_dma_regs_t dma[2];
|
||||
lcd_dma_regs dma[2];
|
||||
};
|
||||
|
||||
dma_regs_t m_dma_regs;
|
||||
i2s_regs_t m_i2s_regs;
|
||||
ostmr_regs_t m_ostimer_regs;
|
||||
intc_regs_t m_intc_regs;
|
||||
gpio_regs_t m_gpio_regs;
|
||||
lcd_regs_t m_lcd_regs;
|
||||
struct power_regs
|
||||
{
|
||||
uint32_t pmcr;
|
||||
uint32_t pssr;
|
||||
uint32_t pspr;
|
||||
uint32_t pwer;
|
||||
uint32_t prer;
|
||||
uint32_t pfer;
|
||||
uint32_t pedr;
|
||||
uint32_t pcfr;
|
||||
uint32_t pgsr0;
|
||||
uint32_t pgsr1;
|
||||
uint32_t pgsr2;
|
||||
uint32_t rcsr;
|
||||
uint32_t pmfw;
|
||||
};
|
||||
|
||||
struct clocks_regs
|
||||
{
|
||||
uint32_t cccr;
|
||||
uint32_t cken;
|
||||
uint32_t oscc;
|
||||
};
|
||||
|
||||
dma_regs m_dma_regs;
|
||||
i2s_regs m_i2s_regs;
|
||||
rtc_regs m_rtc_regs;
|
||||
ostmr_regs m_ostimer_regs;
|
||||
intc_regs m_intc_regs;
|
||||
gpio_regs m_gpio_regs;
|
||||
lcd_regs m_lcd_regs;
|
||||
power_regs m_power_regs;
|
||||
clocks_regs m_clocks_regs;
|
||||
|
||||
devcb_write32 m_gpio0_w;
|
||||
devcb_write32 m_gpio1_w;
|
||||
|
@ -212,6 +212,20 @@
|
||||
#define PXA255_SADIV (PXA255_I2S_BASE_ADDR + 0x00000060)
|
||||
#define PXA255_SADR (PXA255_I2S_BASE_ADDR + 0x00000080)
|
||||
|
||||
/*
|
||||
|
||||
PXA255 Real-Time Clock
|
||||
|
||||
pg. 132 to 138, PXA255 Processor Developers Manual [278693-002].pdf
|
||||
|
||||
*/
|
||||
|
||||
#define PXA255_RTC_BASE_ADDR (0x40900000)
|
||||
#define PXA255_RCNR (PXA255_RTC_BASE_ADDR + 0x00000000)
|
||||
#define PXA255_RTAR (PXA255_RTC_BASE_ADDR + 0x00000004)
|
||||
#define PXA255_RTSR (PXA255_RTC_BASE_ADDR + 0x00000008)
|
||||
#define PXA255_RTTR (PXA255_RTC_BASE_ADDR + 0x0000000c)
|
||||
|
||||
/*
|
||||
|
||||
PXA255 OS Timer register
|
||||
@ -376,4 +390,37 @@
|
||||
#define PXA255_FIDR1 (PXA255_LCD_BASE_ADDR + 0x00000218)
|
||||
#define PXA255_LDCMD1 (PXA255_LCD_BASE_ADDR + 0x0000021c)
|
||||
|
||||
/*
|
||||
PXA255 Power controller
|
||||
|
||||
pg. 85 to 96, PXA255 Processor Developers Manual [278693-002].pdf
|
||||
*/
|
||||
|
||||
#define PXA255_POWER_BASE_ADDR (0x40f00000)
|
||||
#define PXA255_PMCR (PXA255_POWER_BASE_ADDR + 0x00000000)
|
||||
#define PXA255_PSSR (PXA255_POWER_BASE_ADDR + 0x00000004)
|
||||
#define PXA255_PSPR (PXA255_POWER_BASE_ADDR + 0x00000008)
|
||||
#define PXA255_PWER (PXA255_POWER_BASE_ADDR + 0x0000000c)
|
||||
#define PXA255_PRER (PXA255_POWER_BASE_ADDR + 0x00000010)
|
||||
#define PXA255_PFER (PXA255_POWER_BASE_ADDR + 0x00000014)
|
||||
#define PXA255_PEDR (PXA255_POWER_BASE_ADDR + 0x00000018)
|
||||
#define PXA255_PCFR (PXA255_POWER_BASE_ADDR + 0x0000001c)
|
||||
#define PXA255_PGSR0 (PXA255_POWER_BASE_ADDR + 0x00000020)
|
||||
#define PXA255_PGSR1 (PXA255_POWER_BASE_ADDR + 0x00000024)
|
||||
#define PXA255_PGSR2 (PXA255_POWER_BASE_ADDR + 0x00000028)
|
||||
#define PXA255_RCSR (PXA255_POWER_BASE_ADDR + 0x00000030)
|
||||
#define PXA255_PMFW (PXA255_POWER_BASE_ADDR + 0x00000034)
|
||||
|
||||
/*
|
||||
PXA255 Clock controller
|
||||
|
||||
pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf
|
||||
|
||||
*/
|
||||
|
||||
#define PXA255_CLOCKS_BASE_ADDR (0x41300000)
|
||||
#define PXA255_CCCR (PXA255_CLOCKS_BASE_ADDR + 0x00000000)
|
||||
#define PXA255_CKEN (PXA255_CLOCKS_BASE_ADDR + 0x00000004)
|
||||
#define PXA255_OSCC (PXA255_CLOCKS_BASE_ADDR + 0x00000008)
|
||||
|
||||
#endif // MAME_MACHINE_PXA255DEFS
|
||||
|
@ -1426,6 +1426,7 @@ public:
|
||||
, m_pxa_periphs(*this, "pxa_periphs")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_ram(*this, "ram")
|
||||
, m_power(*this, "PWR")
|
||||
{ }
|
||||
|
||||
void zaurus_base(machine_config &config);
|
||||
@ -1434,6 +1435,8 @@ public:
|
||||
void zaurus_pxa255(machine_config &config);
|
||||
void zaurus_pxa270(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER( system_start );
|
||||
|
||||
private:
|
||||
// driver_device overrides
|
||||
virtual void machine_start() override;
|
||||
@ -1445,42 +1448,35 @@ private:
|
||||
required_device<pxa255_periphs_device> m_pxa_periphs;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_shared_ptr<uint32_t> m_ram;
|
||||
|
||||
uint8_t m_rtc_tick;
|
||||
uint32_t rtc_r(offs_t offset);
|
||||
void rtc_w(offs_t offset, uint32_t data);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(rtc_irq_callback);
|
||||
required_ioport m_power;
|
||||
};
|
||||
|
||||
|
||||
uint32_t zaurus_state::rtc_r(offs_t offset)
|
||||
{
|
||||
osd_printf_debug("%08x\n", offset << 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zaurus_state::rtc_w(offs_t offset, uint32_t data)
|
||||
{
|
||||
osd_printf_debug("%08x %08x\n", offset << 2, data);
|
||||
}
|
||||
|
||||
void zaurus_state::zaurus_map(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x001fffff).ram().region("firmware", 0);
|
||||
map(0x40900000, 0x4090000f).rw(FUNC(zaurus_state::rtc_r), FUNC(zaurus_state::rtc_w));
|
||||
map(0x40000000, 0x400002ff).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::dma_r), FUNC(pxa255_periphs_device::dma_w));
|
||||
map(0x40400000, 0x40400083).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::i2s_r), FUNC(pxa255_periphs_device::i2s_w));
|
||||
map(0x40900000, 0x4090000f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::rtc_r), FUNC(pxa255_periphs_device::rtc_w));
|
||||
map(0x40a00000, 0x40a0001f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::ostimer_r), FUNC(pxa255_periphs_device::ostimer_w));
|
||||
map(0x40d00000, 0x40d00017).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::intc_r), FUNC(pxa255_periphs_device::intc_w));
|
||||
map(0x40e00000, 0x40e0006b).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::gpio_r), FUNC(pxa255_periphs_device::gpio_w));
|
||||
map(0x40f00000, 0x40f00037).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::power_r), FUNC(pxa255_periphs_device::power_w));
|
||||
map(0x41300000, 0x4130000b).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::clocks_r), FUNC(pxa255_periphs_device::clocks_w));
|
||||
map(0x44000000, 0x4400021f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::lcd_r), FUNC(pxa255_periphs_device::lcd_w));
|
||||
map(0xa0000000, 0xa07fffff).ram().share("ram");
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER( zaurus_state::system_start )
|
||||
{
|
||||
m_pxa_periphs->gpio_bit_w(m_maincpu->space(AS_PROGRAM), 10, m_power->read());
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( zaurus )
|
||||
PORT_START("PWR")
|
||||
PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Start System") PORT_CHANGED_MEMBER(DEVICE_SELF, zaurus_state, system_start, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void zaurus_state::machine_start()
|
||||
{
|
||||
}
|
||||
@ -1489,27 +1485,9 @@ void zaurus_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Hack */
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(zaurus_state::rtc_irq_callback)
|
||||
{
|
||||
#if 1
|
||||
m_rtc_tick++;
|
||||
m_rtc_tick &= 1;
|
||||
|
||||
if(m_rtc_tick & 1)
|
||||
m_pxa_periphs->set_irq_line(PXA255_INT_RTC_HZ, 1);
|
||||
else
|
||||
m_pxa_periphs->set_irq_line(PXA255_INT_RTC_HZ, 0);
|
||||
#else
|
||||
(void)m_rtc_tick;
|
||||
#endif
|
||||
}
|
||||
|
||||
void zaurus_state::zaurus_base(machine_config &config)
|
||||
{
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &zaurus_state::zaurus_map);
|
||||
TIMER(config, "rtc_timer").configure_periodic(FUNC(zaurus_state::rtc_irq_callback), attotime::from_hz(XTAL(32'768)));
|
||||
}
|
||||
|
||||
void zaurus_state::zaurus_sa1110(machine_config &config)
|
||||
@ -1521,7 +1499,7 @@ void zaurus_state::zaurus_sa1110(machine_config &config)
|
||||
|
||||
void zaurus_state::zaurus_pxa250(machine_config &config)
|
||||
{
|
||||
PXA255(config, m_maincpu, PXA250_CLOCK); // TODO: Correct CPU type
|
||||
PXA250(config, m_maincpu, PXA250_CLOCK);
|
||||
PXA255_PERIPHERALS(config, m_pxa_periphs, PXA250_CLOCK, m_maincpu); // TODO: Correct peripherals
|
||||
zaurus_base(config);
|
||||
}
|
||||
@ -1535,7 +1513,7 @@ void zaurus_state::zaurus_pxa255(machine_config &config)
|
||||
|
||||
void zaurus_state::zaurus_pxa270(machine_config &config)
|
||||
{
|
||||
PXA255(config, m_maincpu, PXA270_CLOCK); // TODO: Correct CPU type
|
||||
PXA270(config, m_maincpu, PXA270_CLOCK);
|
||||
PXA255_PERIPHERALS(config, m_pxa_periphs, PXA270_CLOCK, m_maincpu); // TODO: Correct peripherals
|
||||
zaurus_base(config);
|
||||
}
|
||||
@ -1546,8 +1524,16 @@ void zaurus_state::zaurus_pxa270(machine_config &config)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/* was labeled SL-C500 */
|
||||
ROM_START( zsl5500 )
|
||||
ROM_REGION32_LE( 0x1000000, "firmware", ROMREGION_ERASE00 )
|
||||
ROM_SYSTEM_BIOS( 0, "2.58", "OS Pack 2.58" ) \
|
||||
ROMX_LOAD( "ospack-2.58", 0x0000000, 0x1000000, CRC(31c4d3ef) SHA1(a3b67fb45160bdb990e34dca5c389ed345c000c6), ROM_BIOS(0) )
|
||||
ROM_SYSTEM_BIOS( 1, "3.10", "OS Pack 3.10" ) \
|
||||
ROMX_LOAD( "ospack-3.10", 0x0000000, 0x1000000, CRC(12345678) SHA1(1234567812345678123456781234567812345678), ROM_BIOS(1) )
|
||||
ROM_END
|
||||
|
||||
/* was labeled SL-C500 */
|
||||
ROM_START( zslc500 )
|
||||
ROM_REGION32_LE( 0x200000, "firmware", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "sl-c500 v1.20,zimage.bin", 0x000000, 0x13c000, BAD_DUMP CRC(dc1c259f) SHA1(8150744196a72821ae792462d0381182274c2ce0) )
|
||||
ROM_END
|
||||
@ -1578,6 +1564,7 @@ ROM_START( zslc1000 )
|
||||
ROM_END
|
||||
|
||||
COMP( 2002, zsl5500, 0, 0, zaurus_sa1110, zaurus, zaurus_state, empty_init, "Sharp", "Zaurus SL-5500 \"Collie\"", MACHINE_IS_SKELETON )
|
||||
COMP( 2002, zslc500, 0, 0, zaurus_pxa250, zaurus, zaurus_state, empty_init, "Sharp", "Zaurus SL-C500", MACHINE_IS_SKELETON )
|
||||
COMP( 2002, zsl5600, 0, 0, zaurus_pxa250, zaurus, zaurus_state, empty_init, "Sharp", "Zaurus SL-5600 / SL-B500 \"Poodle\"", MACHINE_IS_SKELETON )
|
||||
COMP( 2003, zslc750, 0, 0, zaurus_pxa255, zaurus, zaurus_state, empty_init, "Sharp", "Zaurus SL-C750 \"Shepherd\" (Japan)", MACHINE_IS_SKELETON )
|
||||
COMP( 2004, zslc760, 0, 0, zaurus_pxa255, zaurus, zaurus_state, empty_init, "Sharp", "Zaurus SL-C760 \"Husky\" (Japan)", MACHINE_IS_SKELETON )
|
||||
|
@ -42066,6 +42066,7 @@ zapcomp // (1981) ZAP computer - Z80 Applications Proces
|
||||
|
||||
@source:zaurus.cpp
|
||||
zsl5500 // Sharp Zaurus SL-5500 "Collie"
|
||||
zslc500 // Sharp Zaurus SL-C500
|
||||
zsl5600 // Sharp Zaurus SL-5600 / SL-B500 "Poodle"
|
||||
zslc1000 // Sharp Zaurus SL-C1000 "Akita"
|
||||
zslc3000 // Sharp Zaurus SL-C3000 "Spitz"
|
||||
|
Loading…
Reference in New Issue
Block a user