summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <therealmogminer@gmail.com>2020-06-22 12:12:28 +0200
committer mooglyguy <therealmogminer@gmail.com>2020-06-22 12:23:33 +0200
commit13fc94946564d6447f146e3193d1bf41ba658b5c (patch)
tree37b59339de48c78c41015d27d6d72daec1c6c37f
parentfc7f76dc12d3fc14768fcd1482ed1a21214ca7db (diff)
-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]
-rw-r--r--src/devices/cpu/arm7/arm7.cpp23
-rw-r--r--src/devices/cpu/arm7/arm7.h19
-rw-r--r--src/devices/machine/pxa255.cpp434
-rw-r--r--src/devices/machine/pxa255.h95
-rw-r--r--src/devices/machine/pxa255defs.h47
-rw-r--r--src/mame/drivers/zaurus.cpp67
-rw-r--r--src/mame/mame.lst1
7 files changed, 587 insertions, 99 deletions
diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp
index d76a54a3c91..608d84a8612 100644
--- a/src/devices/cpu/arm7/arm7.cpp
+++ b/src/devices/cpu/arm7/arm7.cpp
@@ -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;
}
diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h
index 3f6f9c290a5..80757afe13b 100644
--- a/src/devices/cpu/arm7/arm7.h
+++ b/src/devices/cpu/arm7/arm7.h
@@ -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)
diff --git a/src/devices/machine/pxa255.cpp b/src/devices/machine/pxa255.cpp
index 4c6c750afd3..e8710f7d891 100644
--- a/src/devices/machine/pxa255.cpp
+++ b/src/devices/machine/pxa255.cpp
@@ -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();
@@ -446,6 +449,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
pg. 138 to 142, PXA255 Processor Developers Manual [278693-002].pdf
@@ -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();
}
@@ -665,6 +757,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))
{
case PXA255_GPLR0:
@@ -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)
diff --git a/src/devices/machine/pxa255.h b/src/devices/machine/pxa255.h
index 8f1e90544fe..c90f676b5ee 100644
--- a/src/devices/machine/pxa255.h
+++ b/src/devices/machine/pxa255.h
@@ -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();
+
+ void set_irq_line(uint32_t line, int state);
- struct dma_regs_t
+ 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];
+ };
+
+ 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_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;
+ 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;
diff --git a/src/devices/machine/pxa255defs.h b/src/devices/machine/pxa255defs.h
index d2c38f474f1..b746f08d30a 100644
--- a/src/devices/machine/pxa255defs.h
+++ b/src/devices/machine/pxa255defs.h
@@ -214,6 +214,20 @@
/*
+ 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
pg. 138 to 142, PXA255 Processor Developers Manual [278693-002].pdf
@@ -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
diff --git a/src/mame/drivers/zaurus.cpp b/src/mame/drivers/zaurus.cpp
index 4a1cac86b38..8ca785c4901 100644
--- a/src/mame/drivers/zaurus.cpp
+++ b/src/mame/drivers/zaurus.cpp
@@ -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 )
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 58684d583fd..72d36d14478 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -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"