diff options
Diffstat (limited to 'src/devices/machine/pxa255.cpp')
-rw-r--r-- | src/devices/machine/pxa255.cpp | 2608 |
1 files changed, 1401 insertions, 1207 deletions
diff --git a/src/devices/machine/pxa255.cpp b/src/devices/machine/pxa255.cpp index 6bd82ec987c..1f1dff2e452 100644 --- a/src/devices/machine/pxa255.cpp +++ b/src/devices/machine/pxa255.cpp @@ -15,38 +15,260 @@ #include "screen.h" #include "speaker.h" -#define LOG_UNKNOWN (1 << 1) -#define LOG_I2S (1 << 2) -#define LOG_DMA (1 << 3) -#define LOG_OSTIMER (1 << 4) -#define LOG_INTC (1 << 5) -#define LOG_GPIO (1 << 6) -#define LOG_LCD_DMA (1 << 7) -#define LOG_LCD (1 << 8) -#define LOG_POWER (1 << 9) -#define LOG_RTC (1 << 10) -#define LOG_CLOCKS (1 << 11) +#define LOG_UNKNOWN (1U << 1) +#define LOG_I2S (1U << 2) +#define LOG_DMA (1U << 3) +#define LOG_OSTIMER (1U << 4) +#define LOG_INTC (1U << 5) +#define LOG_GPIO (1U << 6) +#define LOG_LCD_DMA (1U << 7) +#define LOG_LCD (1U << 8) +#define LOG_POWER (1U << 9) +#define LOG_RTC (1U << 10) +#define LOG_CLOCKS (1U << 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 (LOG_ALL) +#define VERBOSE (LOG_GPIO) #include "logmacro.h" DEFINE_DEVICE_TYPE(PXA255_PERIPHERALS, pxa255_periphs_device, "pxa255_periphs", "Intel XScale PXA255 Peripherals") -pxa255_periphs_device::pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +pxa255_periphs_device::pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, PXA255_PERIPHERALS, tag, owner, clock) - , m_gpio0_w(*this) - , m_gpio1_w(*this) - , m_gpio2_w(*this) - , m_gpio0_r(*this) - , m_gpio1_r(*this) - , m_gpio2_r(*this) + , m_gpio_w(*this) , m_maincpu(*this, finder_base::DUMMY_TAG) , m_dmadac(*this, "dac%u", 1U) , m_palette(*this, "palette") { } +void pxa255_periphs_device::map(address_map &map) +{ + map(0x00000000, 0x0000003f).rw(FUNC(pxa255_periphs_device::dma_dcsr_r), FUNC(pxa255_periphs_device::dma_dcsr_w)); + map(0x000000f0, 0x000000f3).rw(FUNC(pxa255_periphs_device::dma_dint_r), FUNC(pxa255_periphs_device::dma_dint_w)); + map(0x00000100, 0x0000019f).rw(FUNC(pxa255_periphs_device::dma_drcmr_r), FUNC(pxa255_periphs_device::dma_drcmr_w)); + map(0x00000200, 0x00000203).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<0>), FUNC(pxa255_periphs_device::dma_ddadr_w<0>)); + map(0x00000204, 0x00000207).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<0>), FUNC(pxa255_periphs_device::dma_dsadr_w<0>)); + map(0x00000208, 0x0000020b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<0>), FUNC(pxa255_periphs_device::dma_dtadr_w<0>)); + map(0x0000020c, 0x0000020f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<0>), FUNC(pxa255_periphs_device::dma_dcmd_w<0>)); + map(0x00000210, 0x00000213).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<1>), FUNC(pxa255_periphs_device::dma_ddadr_w<1>)); + map(0x00000214, 0x00000217).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<1>), FUNC(pxa255_periphs_device::dma_dsadr_w<1>)); + map(0x00000218, 0x0000021b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<1>), FUNC(pxa255_periphs_device::dma_dtadr_w<1>)); + map(0x0000021c, 0x0000021f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<1>), FUNC(pxa255_periphs_device::dma_dcmd_w<1>)); + map(0x00000220, 0x00000223).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<2>), FUNC(pxa255_periphs_device::dma_ddadr_w<2>)); + map(0x00000224, 0x00000227).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<2>), FUNC(pxa255_periphs_device::dma_dsadr_w<2>)); + map(0x00000228, 0x0000022b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<2>), FUNC(pxa255_periphs_device::dma_dtadr_w<2>)); + map(0x0000022c, 0x0000022f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<2>), FUNC(pxa255_periphs_device::dma_dcmd_w<2>)); + map(0x00000230, 0x00000233).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<3>), FUNC(pxa255_periphs_device::dma_ddadr_w<3>)); + map(0x00000234, 0x00000237).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<3>), FUNC(pxa255_periphs_device::dma_dsadr_w<3>)); + map(0x00000238, 0x0000023b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<3>), FUNC(pxa255_periphs_device::dma_dtadr_w<3>)); + map(0x0000023c, 0x0000023f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<3>), FUNC(pxa255_periphs_device::dma_dcmd_w<3>)); + map(0x00000240, 0x00000243).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<4>), FUNC(pxa255_periphs_device::dma_ddadr_w<4>)); + map(0x00000244, 0x00000247).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<4>), FUNC(pxa255_periphs_device::dma_dsadr_w<4>)); + map(0x00000248, 0x0000024b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<4>), FUNC(pxa255_periphs_device::dma_dtadr_w<4>)); + map(0x0000024c, 0x0000024f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<4>), FUNC(pxa255_periphs_device::dma_dcmd_w<4>)); + map(0x00000250, 0x00000253).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<5>), FUNC(pxa255_periphs_device::dma_ddadr_w<5>)); + map(0x00000254, 0x00000257).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<5>), FUNC(pxa255_periphs_device::dma_dsadr_w<5>)); + map(0x00000258, 0x0000025b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<5>), FUNC(pxa255_periphs_device::dma_dtadr_w<5>)); + map(0x0000025c, 0x0000025f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<5>), FUNC(pxa255_periphs_device::dma_dcmd_w<5>)); + map(0x00000260, 0x00000263).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<6>), FUNC(pxa255_periphs_device::dma_ddadr_w<6>)); + map(0x00000264, 0x00000267).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<6>), FUNC(pxa255_periphs_device::dma_dsadr_w<6>)); + map(0x00000268, 0x0000026b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<6>), FUNC(pxa255_periphs_device::dma_dtadr_w<6>)); + map(0x0000026c, 0x0000026f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<6>), FUNC(pxa255_periphs_device::dma_dcmd_w<6>)); + map(0x00000270, 0x00000273).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<7>), FUNC(pxa255_periphs_device::dma_ddadr_w<7>)); + map(0x00000274, 0x00000277).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<7>), FUNC(pxa255_periphs_device::dma_dsadr_w<7>)); + map(0x00000278, 0x0000027b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<7>), FUNC(pxa255_periphs_device::dma_dtadr_w<7>)); + map(0x0000027c, 0x0000027f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<7>), FUNC(pxa255_periphs_device::dma_dcmd_w<7>)); + map(0x00000280, 0x00000283).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<8>), FUNC(pxa255_periphs_device::dma_ddadr_w<8>)); + map(0x00000284, 0x00000287).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<8>), FUNC(pxa255_periphs_device::dma_dsadr_w<8>)); + map(0x00000288, 0x0000028b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<8>), FUNC(pxa255_periphs_device::dma_dtadr_w<8>)); + map(0x0000028c, 0x0000028f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<8>), FUNC(pxa255_periphs_device::dma_dcmd_w<8>)); + map(0x00000290, 0x00000293).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<9>), FUNC(pxa255_periphs_device::dma_ddadr_w<9>)); + map(0x00000294, 0x00000297).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<9>), FUNC(pxa255_periphs_device::dma_dsadr_w<9>)); + map(0x00000298, 0x0000029b).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<9>), FUNC(pxa255_periphs_device::dma_dtadr_w<9>)); + map(0x0000029c, 0x0000029f).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<9>), FUNC(pxa255_periphs_device::dma_dcmd_w<9>)); + map(0x000002a0, 0x000002a3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<10>), FUNC(pxa255_periphs_device::dma_ddadr_w<10>)); + map(0x000002a4, 0x000002a7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<10>), FUNC(pxa255_periphs_device::dma_dsadr_w<10>)); + map(0x000002a8, 0x000002ab).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<10>), FUNC(pxa255_periphs_device::dma_dtadr_w<10>)); + map(0x000002ac, 0x000002af).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<10>), FUNC(pxa255_periphs_device::dma_dcmd_w<10>)); + map(0x000002b0, 0x000002b3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<11>), FUNC(pxa255_periphs_device::dma_ddadr_w<11>)); + map(0x000002b4, 0x000002b7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<11>), FUNC(pxa255_periphs_device::dma_dsadr_w<11>)); + map(0x000002b8, 0x000002bb).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<11>), FUNC(pxa255_periphs_device::dma_dtadr_w<11>)); + map(0x000002bc, 0x000002bf).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<11>), FUNC(pxa255_periphs_device::dma_dcmd_w<11>)); + map(0x000002c0, 0x000002c3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<12>), FUNC(pxa255_periphs_device::dma_ddadr_w<12>)); + map(0x000002c4, 0x000002c7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<12>), FUNC(pxa255_periphs_device::dma_dsadr_w<12>)); + map(0x000002c8, 0x000002cb).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<12>), FUNC(pxa255_periphs_device::dma_dtadr_w<12>)); + map(0x000002cc, 0x000002cf).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<12>), FUNC(pxa255_periphs_device::dma_dcmd_w<12>)); + map(0x000002d0, 0x000002d3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<13>), FUNC(pxa255_periphs_device::dma_ddadr_w<13>)); + map(0x000002d4, 0x000002d7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<13>), FUNC(pxa255_periphs_device::dma_dsadr_w<13>)); + map(0x000002d8, 0x000002db).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<13>), FUNC(pxa255_periphs_device::dma_dtadr_w<13>)); + map(0x000002dc, 0x000002df).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<13>), FUNC(pxa255_periphs_device::dma_dcmd_w<13>)); + map(0x000002e0, 0x000002e3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<14>), FUNC(pxa255_periphs_device::dma_ddadr_w<14>)); + map(0x000002e4, 0x000002e7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<14>), FUNC(pxa255_periphs_device::dma_dsadr_w<14>)); + map(0x000002e8, 0x000002eb).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<14>), FUNC(pxa255_periphs_device::dma_dtadr_w<14>)); + map(0x000002ec, 0x000002ef).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<14>), FUNC(pxa255_periphs_device::dma_dcmd_w<14>)); + map(0x000002f0, 0x000002f3).rw(FUNC(pxa255_periphs_device::dma_ddadr_r<15>), FUNC(pxa255_periphs_device::dma_ddadr_w<15>)); + map(0x000002f4, 0x000002f7).rw(FUNC(pxa255_periphs_device::dma_dsadr_r<15>), FUNC(pxa255_periphs_device::dma_dsadr_w<15>)); + map(0x000002f8, 0x000002fb).rw(FUNC(pxa255_periphs_device::dma_dtadr_r<15>), FUNC(pxa255_periphs_device::dma_dtadr_w<15>)); + map(0x000002fc, 0x000002ff).rw(FUNC(pxa255_periphs_device::dma_dcmd_r<15>), FUNC(pxa255_periphs_device::dma_dcmd_w<15>)); + map(0x00900000, 0x00900003).rw(FUNC(pxa255_periphs_device::rtc_rcnr_r), FUNC(pxa255_periphs_device::rtc_rcnr_w)); + map(0x00900004, 0x00900007).rw(FUNC(pxa255_periphs_device::rtc_rtar_r), FUNC(pxa255_periphs_device::rtc_rtar_w)); + map(0x00900008, 0x0090000b).rw(FUNC(pxa255_periphs_device::rtc_rtsr_r), FUNC(pxa255_periphs_device::rtc_rtsr_w)); + map(0x0090000c, 0x0090000f).rw(FUNC(pxa255_periphs_device::rtc_rttr_r), FUNC(pxa255_periphs_device::rtc_rttr_w)); + map(0x00400000, 0x00400003).rw(FUNC(pxa255_periphs_device::i2s_sacr0_r), FUNC(pxa255_periphs_device::i2s_sacr0_w)); + map(0x00400004, 0x00400007).rw(FUNC(pxa255_periphs_device::i2s_sacr1_r), FUNC(pxa255_periphs_device::i2s_sacr1_w)); + map(0x0040000c, 0x0040000f).rw(FUNC(pxa255_periphs_device::i2s_sasr0_r), FUNC(pxa255_periphs_device::i2s_sasr0_w)); + map(0x00400014, 0x00400017).rw(FUNC(pxa255_periphs_device::i2s_saimr_r), FUNC(pxa255_periphs_device::i2s_saimr_w)); + map(0x00400018, 0x0040001b).rw(FUNC(pxa255_periphs_device::i2s_saicr_r), FUNC(pxa255_periphs_device::i2s_saicr_w)); + map(0x00400060, 0x00400063).rw(FUNC(pxa255_periphs_device::i2s_sadiv_r), FUNC(pxa255_periphs_device::i2s_sadiv_w)); + map(0x00400080, 0x00400083).rw(FUNC(pxa255_periphs_device::i2s_sadr_r), FUNC(pxa255_periphs_device::i2s_sadr_w)); + map(0x00a00000, 0x00a00003).rw(FUNC(pxa255_periphs_device::tmr_osmr_r<0>), FUNC(pxa255_periphs_device::tmr_osmr_w<0>)); + map(0x00a00004, 0x00a00007).rw(FUNC(pxa255_periphs_device::tmr_osmr_r<1>), FUNC(pxa255_periphs_device::tmr_osmr_w<1>)); + map(0x00a00008, 0x00a0000b).rw(FUNC(pxa255_periphs_device::tmr_osmr_r<2>), FUNC(pxa255_periphs_device::tmr_osmr_w<2>)); + map(0x00a0000c, 0x00a0000f).rw(FUNC(pxa255_periphs_device::tmr_osmr_r<3>), FUNC(pxa255_periphs_device::tmr_osmr_w<3>)); + map(0x00a00010, 0x00a00013).rw(FUNC(pxa255_periphs_device::tmr_oscr_r), FUNC(pxa255_periphs_device::tmr_oscr_w)); + map(0x00a00014, 0x00a00017).rw(FUNC(pxa255_periphs_device::tmr_ossr_r), FUNC(pxa255_periphs_device::tmr_ossr_w)); + map(0x00a00018, 0x00a0001b).rw(FUNC(pxa255_periphs_device::tmr_ower_r), FUNC(pxa255_periphs_device::tmr_ower_w)); + map(0x00a0001c, 0x00a0001f).rw(FUNC(pxa255_periphs_device::tmr_oier_r), FUNC(pxa255_periphs_device::tmr_oier_w)); + map(0x00d00000, 0x00d00003).rw(FUNC(pxa255_periphs_device::intc_icip_r), FUNC(pxa255_periphs_device::intc_icip_w)); + map(0x00d00004, 0x00d00007).rw(FUNC(pxa255_periphs_device::intc_icmr_r), FUNC(pxa255_periphs_device::intc_icmr_w)); + map(0x00d00008, 0x00d0000b).rw(FUNC(pxa255_periphs_device::intc_iclr_r), FUNC(pxa255_periphs_device::intc_iclr_w)); + map(0x00d0000c, 0x00d0000f).rw(FUNC(pxa255_periphs_device::intc_icfp_r), FUNC(pxa255_periphs_device::intc_icfp_w)); + map(0x00d00010, 0x00d00013).rw(FUNC(pxa255_periphs_device::intc_icpr_r), FUNC(pxa255_periphs_device::intc_icpr_w)); + map(0x00d00014, 0x00d00017).rw(FUNC(pxa255_periphs_device::intc_iccr_r), FUNC(pxa255_periphs_device::intc_iccr_w)); + map(0x00e00000, 0x00e00003).rw(FUNC(pxa255_periphs_device::gpio_gplr_r<0>), FUNC(pxa255_periphs_device::gpio_gplr_w<0>)); + map(0x00e00004, 0x00e00007).rw(FUNC(pxa255_periphs_device::gpio_gplr_r<1>), FUNC(pxa255_periphs_device::gpio_gplr_w<1>)); + map(0x00e00008, 0x00e0000b).rw(FUNC(pxa255_periphs_device::gpio_gplr_r<2>), FUNC(pxa255_periphs_device::gpio_gplr_w<2>)); + map(0x00e0000c, 0x00e0000f).rw(FUNC(pxa255_periphs_device::gpio_gpdr_r<0>), FUNC(pxa255_periphs_device::gpio_gpdr_w<0>)); + map(0x00e00010, 0x00e00013).rw(FUNC(pxa255_periphs_device::gpio_gpdr_r<1>), FUNC(pxa255_periphs_device::gpio_gpdr_w<1>)); + map(0x00e00014, 0x00e00017).rw(FUNC(pxa255_periphs_device::gpio_gpdr_r<2>), FUNC(pxa255_periphs_device::gpio_gpdr_w<2>)); + map(0x00e00018, 0x00e0001b).rw(FUNC(pxa255_periphs_device::gpio_gpsr_r<0>), FUNC(pxa255_periphs_device::gpio_gpsr_w<0>)); + map(0x00e0001c, 0x00e0001f).rw(FUNC(pxa255_periphs_device::gpio_gpsr_r<1>), FUNC(pxa255_periphs_device::gpio_gpsr_w<1>)); + map(0x00e00020, 0x00e00023).rw(FUNC(pxa255_periphs_device::gpio_gpsr_r<2>), FUNC(pxa255_periphs_device::gpio_gpsr_w<2>)); + map(0x00e00024, 0x00e00027).rw(FUNC(pxa255_periphs_device::gpio_gpcr_r<0>), FUNC(pxa255_periphs_device::gpio_gpcr_w<0>)); + map(0x00e00028, 0x00e0002b).rw(FUNC(pxa255_periphs_device::gpio_gpcr_r<1>), FUNC(pxa255_periphs_device::gpio_gpcr_w<1>)); + map(0x00e0002c, 0x00e0002f).rw(FUNC(pxa255_periphs_device::gpio_gpcr_r<2>), FUNC(pxa255_periphs_device::gpio_gpcr_w<2>)); + map(0x00e00030, 0x00e00033).rw(FUNC(pxa255_periphs_device::gpio_grer_r<0>), FUNC(pxa255_periphs_device::gpio_grer_w<0>)); + map(0x00e00034, 0x00e00037).rw(FUNC(pxa255_periphs_device::gpio_grer_r<1>), FUNC(pxa255_periphs_device::gpio_grer_w<1>)); + map(0x00e00038, 0x00e0003b).rw(FUNC(pxa255_periphs_device::gpio_grer_r<2>), FUNC(pxa255_periphs_device::gpio_grer_w<2>)); + map(0x00e0003c, 0x00e0003f).rw(FUNC(pxa255_periphs_device::gpio_gfer_r<0>), FUNC(pxa255_periphs_device::gpio_gfer_w<0>)); + map(0x00e00040, 0x00e00043).rw(FUNC(pxa255_periphs_device::gpio_gfer_r<1>), FUNC(pxa255_periphs_device::gpio_gfer_w<1>)); + map(0x00e00044, 0x00e00047).rw(FUNC(pxa255_periphs_device::gpio_gfer_r<2>), FUNC(pxa255_periphs_device::gpio_gfer_w<2>)); + map(0x00e00048, 0x00e0004b).rw(FUNC(pxa255_periphs_device::gpio_gedr_r<0>), FUNC(pxa255_periphs_device::gpio_gedr_w<0>)); + map(0x00e0004c, 0x00e0004f).rw(FUNC(pxa255_periphs_device::gpio_gedr_r<1>), FUNC(pxa255_periphs_device::gpio_gedr_w<1>)); + map(0x00e00050, 0x00e00053).rw(FUNC(pxa255_periphs_device::gpio_gedr_r<2>), FUNC(pxa255_periphs_device::gpio_gedr_w<2>)); + map(0x00e00054, 0x00e00057).rw(FUNC(pxa255_periphs_device::gpio_gafrl_r<0>), FUNC(pxa255_periphs_device::gpio_gafrl_w<0>)); + map(0x00e00058, 0x00e0005b).rw(FUNC(pxa255_periphs_device::gpio_gafru_r<0>), FUNC(pxa255_periphs_device::gpio_gafru_w<0>)); + map(0x00e0005c, 0x00e0005f).rw(FUNC(pxa255_periphs_device::gpio_gafrl_r<1>), FUNC(pxa255_periphs_device::gpio_gafrl_w<1>)); + map(0x00e00060, 0x00e00063).rw(FUNC(pxa255_periphs_device::gpio_gafru_r<1>), FUNC(pxa255_periphs_device::gpio_gafru_w<1>)); + map(0x00e00064, 0x00e00067).rw(FUNC(pxa255_periphs_device::gpio_gafrl_r<2>), FUNC(pxa255_periphs_device::gpio_gafrl_w<2>)); + map(0x00e00068, 0x00e0006b).rw(FUNC(pxa255_periphs_device::gpio_gafru_r<2>), FUNC(pxa255_periphs_device::gpio_gafru_w<2>)); + map(0x00f00000, 0x00f00003).rw(FUNC(pxa255_periphs_device::pwr_pmcr_r), FUNC(pxa255_periphs_device::pwr_pmcr_w)); + map(0x00f00004, 0x00f00007).rw(FUNC(pxa255_periphs_device::pwr_pssr_r), FUNC(pxa255_periphs_device::pwr_pssr_w)); + map(0x00f00008, 0x00f0000b).rw(FUNC(pxa255_periphs_device::pwr_pspr_r), FUNC(pxa255_periphs_device::pwr_pspr_w)); + map(0x00f0000c, 0x00f0000f).rw(FUNC(pxa255_periphs_device::pwr_pwer_r), FUNC(pxa255_periphs_device::pwr_pwer_w)); + map(0x00f00010, 0x00f00013).rw(FUNC(pxa255_periphs_device::pwr_prer_r), FUNC(pxa255_periphs_device::pwr_prer_w)); + map(0x00f00014, 0x00f00017).rw(FUNC(pxa255_periphs_device::pwr_pfer_r), FUNC(pxa255_periphs_device::pwr_pfer_w)); + map(0x00f00018, 0x00f0001b).rw(FUNC(pxa255_periphs_device::pwr_pedr_r), FUNC(pxa255_periphs_device::pwr_pedr_w)); + map(0x00f0001c, 0x00f0001f).rw(FUNC(pxa255_periphs_device::pwr_pcfr_r), FUNC(pxa255_periphs_device::pwr_pcfr_w)); + map(0x00f00020, 0x00f00023).rw(FUNC(pxa255_periphs_device::pwr_pgsr_r<0>), FUNC(pxa255_periphs_device::pwr_pgsr_w<0>)); + map(0x00f00024, 0x00f00027).rw(FUNC(pxa255_periphs_device::pwr_pgsr_r<1>), FUNC(pxa255_periphs_device::pwr_pgsr_w<1>)); + map(0x00f00028, 0x00f0002b).rw(FUNC(pxa255_periphs_device::pwr_pgsr_r<2>), FUNC(pxa255_periphs_device::pwr_pgsr_w<2>)); + map(0x00f00030, 0x00f00033).r(FUNC(pxa255_periphs_device::pwr_rcsr_r)); + map(0x00f00034, 0x00f00037).rw(FUNC(pxa255_periphs_device::pwr_pmfw_r), FUNC(pxa255_periphs_device::pwr_pmfw_w)); + map(0x01300000, 0x01300003).rw(FUNC(pxa255_periphs_device::clk_cccr_r), FUNC(pxa255_periphs_device::clk_cccr_w)); + map(0x01300004, 0x01300007).rw(FUNC(pxa255_periphs_device::clk_cken_r), FUNC(pxa255_periphs_device::clk_cken_w)); + map(0x01300008, 0x0130000b).rw(FUNC(pxa255_periphs_device::clk_oscc_r), FUNC(pxa255_periphs_device::clk_oscc_w)); + map(0x04000000, 0x04000003).rw(FUNC(pxa255_periphs_device::lcd_lccr_r<0>), FUNC(pxa255_periphs_device::lcd_lccr_w<0>)); + map(0x04000004, 0x04000007).rw(FUNC(pxa255_periphs_device::lcd_lccr_r<1>), FUNC(pxa255_periphs_device::lcd_lccr_w<1>)); + map(0x04000008, 0x0400000b).rw(FUNC(pxa255_periphs_device::lcd_lccr_r<2>), FUNC(pxa255_periphs_device::lcd_lccr_w<2>)); + map(0x0400000c, 0x0400000f).rw(FUNC(pxa255_periphs_device::lcd_lccr_r<3>), FUNC(pxa255_periphs_device::lcd_lccr_w<3>)); + map(0x04000020, 0x04000023).rw(FUNC(pxa255_periphs_device::lcd_fbr_r<0>), FUNC(pxa255_periphs_device::lcd_fbr_w<0>)); + map(0x04000024, 0x04000027).rw(FUNC(pxa255_periphs_device::lcd_fbr_r<1>), FUNC(pxa255_periphs_device::lcd_fbr_w<1>)); + map(0x04000038, 0x0400003b).rw(FUNC(pxa255_periphs_device::lcd_lcsr_r), FUNC(pxa255_periphs_device::lcd_lcsr_w)); + map(0x0400003c, 0x0400003f).rw(FUNC(pxa255_periphs_device::lcd_liidr_r), FUNC(pxa255_periphs_device::lcd_liidr_w)); + map(0x04000040, 0x04000043).rw(FUNC(pxa255_periphs_device::lcd_trgbr_r), FUNC(pxa255_periphs_device::lcd_trgbr_w)); + map(0x04000044, 0x04000047).rw(FUNC(pxa255_periphs_device::lcd_tcr_r), FUNC(pxa255_periphs_device::lcd_tcr_w)); + map(0x04000200, 0x04000203).rw(FUNC(pxa255_periphs_device::lcd_fdadr_r<0>), FUNC(pxa255_periphs_device::lcd_fdadr_w<0>)); + map(0x04000204, 0x04000207).rw(FUNC(pxa255_periphs_device::lcd_fsadr_r<0>), FUNC(pxa255_periphs_device::lcd_fsadr_w<0>)); + map(0x04000208, 0x0400020b).rw(FUNC(pxa255_periphs_device::lcd_fidr_r<0>), FUNC(pxa255_periphs_device::lcd_fidr_w<0>)); + map(0x0400020c, 0x0400020f).rw(FUNC(pxa255_periphs_device::lcd_ldcmd_r<0>), FUNC(pxa255_periphs_device::lcd_ldcmd_w<0>)); + map(0x04000210, 0x04000213).rw(FUNC(pxa255_periphs_device::lcd_fdadr_r<1>), FUNC(pxa255_periphs_device::lcd_fdadr_w<1>)); + map(0x04000214, 0x04000217).rw(FUNC(pxa255_periphs_device::lcd_fsadr_r<1>), FUNC(pxa255_periphs_device::lcd_fsadr_w<1>)); + map(0x04000218, 0x0400021b).rw(FUNC(pxa255_periphs_device::lcd_fidr_r<1>), FUNC(pxa255_periphs_device::lcd_fidr_w<1>)); + map(0x0400021c, 0x0400021f).rw(FUNC(pxa255_periphs_device::lcd_ldcmd_r<1>), FUNC(pxa255_periphs_device::lcd_ldcmd_w<1>)); +} + +void pxa255_periphs_device::device_start() +{ + for (int index = 0; index < 16; index++) + { + if (index != 3) + { + m_dma_regs.timer[index] = timer_alloc(FUNC(pxa255_periphs_device::dma_end_tick), this); + } + else + { + m_dma_regs.timer[index] = timer_alloc(FUNC(pxa255_periphs_device::audio_dma_end_tick), this); + } + } + + for (int index = 0; index < 4; index++) + { + m_ostimer_regs.timer[index] = timer_alloc(FUNC(pxa255_periphs_device::ostimer_match_tick), this); + } + + m_lcd_regs.dma[0].eof = timer_alloc(FUNC(pxa255_periphs_device::lcd_dma_eof_tick), this); + m_lcd_regs.dma[1].eof = timer_alloc(FUNC(pxa255_periphs_device::lcd_dma_eof_tick), this); + + m_lcd_palette = make_unique_clear<u32[]>(0x100); + m_lcd_framebuffer = make_unique_clear<u8[]>(0x100000); + m_samples = make_unique_clear<s16[]>(0x1000); + + m_rtc_regs.timer = timer_alloc(FUNC(pxa255_periphs_device::rtc_tick), this); +} + +void pxa255_periphs_device::device_reset() +{ + for (int index = 0; index < 16; index++) + { + 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_gpio_regs, 0, sizeof(m_gpio_regs)); + memset(&m_power_regs, 0, sizeof(m_power_regs)); + memset(&m_clk_regs, 0, sizeof(m_clk_regs)); +} + +void pxa255_periphs_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(60); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); + screen.set_size(1024, 1024); + screen.set_visarea(0, 295, 0, 479); + screen.set_screen_update(FUNC(pxa255_periphs_device::screen_update)); + + PALETTE(config, m_palette).set_entries(256); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + DMADAC(config, m_dmadac[0]).add_route(ALL_OUTPUTS, "lspeaker", 1.0); + DMADAC(config, m_dmadac[1]).add_route(ALL_OUTPUTS, "rspeaker", 1.0); +} + /* PXA255 Inter-Integrated-Circuit Sound (I2S) Controller @@ -55,88 +277,110 @@ pxa255_periphs_device::pxa255_periphs_device(const machine_config &mconfig, cons */ -uint32_t pxa255_periphs_device::i2s_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::i2s_sacr0_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.sacr0; + LOGMASKED(LOG_I2S, "%s: i2s_sacr0_r: Serial Audio Controller Global Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_sacr0_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_sacr0_r: Serial Audio Controller Global Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.sacr0 = data & 0x0000ff3d; +} + +u32 pxa255_periphs_device::i2s_sacr1_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.sacr1; + LOGMASKED(LOG_I2S, "%s: i2s_sacr1_r: Serial Audio Controller I2S/MSB-Justified Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_sacr1_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_sacr1_w: Serial Audio Controller I2S/MSB-Justified Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.sacr1 = data & 0x00000039; +} + +u32 pxa255_periphs_device::i2s_sasr0_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.sasr0; + LOGMASKED(LOG_I2S, "%s: i2s_sasr0_r: Serial Audio Controller I2S/MSB-Justified Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_sasr0_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_sasr0_w: Serial Audio Controller I2S/MSB-Justified Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.sasr0 = data & 0x0000ff7f; +} + +u32 pxa255_periphs_device::i2s_saimr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.saimr; + LOGMASKED(LOG_I2S, "%s: i2s_saimr_r: Serial Audio Interrupt Mask Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_saimr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_saimr_w: Serial Audio Interrupt Mask Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.saimr = data & 0x00000078; +} + +u32 pxa255_periphs_device::i2s_saicr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.saicr; + LOGMASKED(LOG_I2S, "%s: i2s_saimr_r: Serial Audio Interrupt Clear Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_saicr_w(offs_t offset, u32 data, u32 mem_mask) { - switch(PXA255_I2S_BASE_ADDR | (offset << 2)) + LOGMASKED(LOG_I2S, "%s: i2s_saicr_w: Serial Audio Interrupt Clear Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (m_i2s_regs.saicr & SAICR_ROR) { - case PXA255_SACR0: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Controller Global Control Register: %08x & %08x\n", m_i2s_regs.sacr0, mem_mask); - return m_i2s_regs.sacr0; - case PXA255_SACR1: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Controller I2S/MSB-Justified Control Register: %08x & %08x\n", m_i2s_regs.sacr1, mem_mask); - return m_i2s_regs.sacr1; - case PXA255_SASR0: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Controller I2S/MSB-Justified Status Register: %08x & %08x\n", m_i2s_regs.sasr0, mem_mask); - return m_i2s_regs.sasr0; - case PXA255_SAIMR: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Interrupt Mask Register: %08x & %08x\n", m_i2s_regs.saimr, mem_mask); - return m_i2s_regs.saimr; - case PXA255_SAICR: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Interrupt Clear Register: %08x & %08x\n", m_i2s_regs.saicr, mem_mask); - return m_i2s_regs.saicr; - case PXA255_SADIV: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Clock Divider Register: %08x & %08x\n", m_i2s_regs.sadiv, mem_mask); - return m_i2s_regs.sadiv; - case PXA255_SADR: - LOGMASKED(LOG_I2S, "pxa255_i2s_r: Serial Audio Data Register: %08x & %08x\n", m_i2s_regs.sadr, mem_mask); - return m_i2s_regs.sadr; - default: - LOGMASKED(LOG_I2S | LOG_UNKNOWN, "pxa255_i2s_r: Unknown address: %08x\n", PXA255_I2S_BASE_ADDR | (offset << 2)); - break; + m_i2s_regs.sasr0 &= ~SASR0_ROR; + } + if (m_i2s_regs.saicr & SAICR_TUR) + { + m_i2s_regs.sasr0 &= ~SASR0_TUR; } - return 0; } -void pxa255_periphs_device::i2s_w(offs_t offset, uint32_t data, uint32_t mem_mask) +u32 pxa255_periphs_device::i2s_sadiv_r(offs_t offset, u32 mem_mask) { - switch(PXA255_I2S_BASE_ADDR | (offset << 2)) + const u32 data = m_i2s_regs.sadiv; + LOGMASKED(LOG_I2S, "%s: i2s_sadiv_r: Serial Audio Clock Divider Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_sadiv_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_saicr_w: Serial Audio Clock Divider Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.sadiv = data & 0x0000007f; + for (int i = 0; i < 2; i++) { - case PXA255_SACR0: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Controller Global Control Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.sacr0 = data & 0x0000ff3d; - break; - case PXA255_SACR1: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Controller I2S/MSB-Justified Control Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.sacr1 = data & 0x00000039; - break; - case PXA255_SASR0: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Controller I2S/MSB-Justified Status Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.sasr0 = data & 0x0000ff7f; - break; - case PXA255_SAIMR: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Interrupt Mask Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.saimr = data & 0x00000078; - break; - case PXA255_SAICR: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Interrupt Clear Register: %08x & %08x\n", data, mem_mask); - if(m_i2s_regs.saicr & PXA255_SAICR_ROR) - { - m_i2s_regs.sasr0 &= ~PXA255_SASR0_ROR; - } - if(m_i2s_regs.saicr & PXA255_SAICR_TUR) - { - m_i2s_regs.sasr0 &= ~PXA255_SASR0_TUR; - } - break; - case PXA255_SADIV: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Clock Divider Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.sadiv = data & 0x0000007f; - for (int i = 0; i < 2; i++) - { - m_dmadac[i]->set_frequency(((double)147600000 / (double)m_i2s_regs.sadiv) / 256.0); - m_dmadac[i]->enable(1); - } - break; - case PXA255_SADR: - LOGMASKED(LOG_I2S, "pxa255_i2s_w: Serial Audio Data Register: %08x & %08x\n", data, mem_mask); - m_i2s_regs.sadr = data; - break; - default: - LOGMASKED(LOG_I2S | LOG_UNKNOWN, "pxa255_i2s_w: Unknown address: %08x = %08x & %08x\n", PXA255_I2S_BASE_ADDR | (offset << 2), data, mem_mask); - break; + m_dmadac[i]->set_frequency(((double)147600000 / (double)m_i2s_regs.sadiv) / 256.0); + m_dmadac[i]->enable(1); } } +u32 pxa255_periphs_device::i2s_sadr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_i2s_regs.sadr; + LOGMASKED(LOG_I2S, "%s: i2s_sadr_r: Serial Audio Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::i2s_sadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_I2S, "%s: i2s_sadr_r: Serial Audio Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2s_regs.sadr = data; +} + + /* PXA255 DMA controller @@ -150,7 +394,7 @@ void pxa255_periphs_device::dma_irq_check() int set_irq = 0; for (int channel = 0; channel < 16; channel++) { - if (m_dma_regs.dcsr[channel] & (PXA255_DCSR_ENDINTR | PXA255_DCSR_STARTINTR | PXA255_DCSR_BUSERRINTR)) + if (m_dma_regs.dcsr[channel] & (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR)) { m_dma_regs.dint |= 1 << channel; set_irq = 1; @@ -161,7 +405,7 @@ void pxa255_periphs_device::dma_irq_check() } } - set_irq_line(PXA255_INT_DMA, set_irq); + set_irq_line(INT_DMA, set_irq); } void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) @@ -174,7 +418,6 @@ void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) } // Load the next descriptor - address_space &space = m_maincpu->space(AS_PROGRAM); m_dma_regs.dsadr[channel] = space.read_dword(m_dma_regs.ddadr[channel] + 0x4); m_dma_regs.dtadr[channel] = space.read_dword(m_dma_regs.ddadr[channel] + 0x8); @@ -182,7 +425,7 @@ void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) m_dma_regs.ddadr[channel] = space.read_dword(m_dma_regs.ddadr[channel]); // Start our end-of-transfer timer - switch(channel) + switch (channel) { case 3: m_dma_regs.timer[channel]->adjust(attotime::from_hz((147600000 / m_i2s_regs.sadiv) / (4 * 64)) * (m_dma_regs.dcmd[channel] & 0x00001fff), channel); @@ -193,260 +436,222 @@ void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) } // Interrupt as necessary - if(m_dma_regs.dcmd[channel] & PXA255_DCMD_STARTIRQEN) + if (m_dma_regs.dcmd[channel] & DCMD_STARTIRQEN) { - m_dma_regs.dcsr[channel] |= PXA255_DCSR_STARTINTR; + m_dma_regs.dcsr[channel] |= DCSR_STARTINTR; } - m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_STOPSTATE; + m_dma_regs.dcsr[channel] &= ~DCSR_STOPSTATE; } -void pxa255_periphs_device::dma_end_tick(int channel) +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::audio_dma_end_tick) { - 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); + const u32 count = m_dma_regs.dcmd[3] & 0x00001fff; + u32 sadr = m_dma_regs.dsadr[3]; + s16 *out_samples = &m_samples[0]; + for (u32 index = 0; index < count; index += 4, sadr += 4) + { + const u32 word = space.read_dword(sadr); + *out_samples++ = (s16)(word >> 16); + *out_samples++ = (s16)(word & 0xffff); + } + + for (int index = 0; index < 2; index++) + { + m_dmadac[index]->flush(); + m_dmadac[index]->transfer(index, 2, 2, count/4, m_samples.get()); + } + + dma_finish(param); +} + +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::dma_end_tick) +{ address_space &space = m_maincpu->space(AS_PROGRAM); - switch (channel) + const u32 count = m_dma_regs.dcmd[param] & 0x00001fff; + u32 sadr = m_dma_regs.dsadr[param]; + u32 tadr = m_dma_regs.dtadr[param]; + + static const u32 s_inc_size[4] = { 0, 1, 2, 4 }; + const u32 inc_index = (m_dma_regs.dcmd[param] >> DCMD_SIZE_SHIFT) & DCMD_SIZE_MASK; + const u32 inc_val = s_inc_size[inc_index]; + const u32 sadr_inc = (m_dma_regs.dcmd[param] & DCMD_INCSRCADDR) ? inc_val : 0; + const u32 tadr_inc = (m_dma_regs.dcmd[param] & DCMD_INCTRGADDR) ? inc_val : 0; + + if (inc_val > 0) { - case 3: - for (uint32_t index = 0; index < count; index += 4) - { - m_words[index >> 2] = space.read_dword(sadr); - m_samples[(index >> 1) + 0] = (int16_t)(m_words[index >> 2] >> 16); - m_samples[(index >> 1) + 1] = (int16_t)(m_words[index >> 2] & 0xffff); - sadr += 4; - } - for (int index = 0; index < 2; index++) - { - m_dmadac[index]->flush(); - m_dmadac[index]->transfer(index, 2, 2, count/4, m_samples.get()); - } - break; - default: - for (uint32_t index = 0; index < count;) - { - switch (m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE) - { - case PXA255_DCMD_SIZE_8: - space.write_byte(tadr, space.read_byte(sadr)); - index++; - break; - case PXA255_DCMD_SIZE_16: - space.write_word(tadr, space.read_word(sadr)); - index += 2; - break; - case PXA255_DCMD_SIZE_32: - space.write_dword(tadr, space.read_dword(sadr)); - index += 4; - break; - default: - logerror( "pxa255_dma_dma_end: Unsupported DMA size\n" ); - break; - } - - if (m_dma_regs.dcmd[channel] & PXA255_DCMD_INCSRCADDR) - { - switch(m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE) - { - case PXA255_DCMD_SIZE_8: - sadr++; - break; - case PXA255_DCMD_SIZE_16: - sadr += 2; - break; - case PXA255_DCMD_SIZE_32: - sadr += 4; - break; - default: - break; - } - } - if(m_dma_regs.dcmd[channel] & PXA255_DCMD_INCTRGADDR) - { - switch(m_dma_regs.dcmd[channel] & PXA255_DCMD_SIZE) - { - case PXA255_DCMD_SIZE_8: - tadr++; - break; - case PXA255_DCMD_SIZE_16: - tadr += 2; - break; - case PXA255_DCMD_SIZE_32: - tadr += 4; - break; - default: - break; - } - } - } - break; + switch (inc_val) + { + case DCMD_SIZE_8: + for (u32 index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) + space.write_byte(tadr, space.read_byte(sadr)); + break; + case DCMD_SIZE_16: + for (u32 index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) + space.write_word(tadr, space.read_byte(sadr)); + break; + case DCMD_SIZE_32: + for (u32 index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) + space.write_dword(tadr, space.read_byte(sadr)); + break; + default: + LOGMASKED(LOG_DMA, "pxa255_dma_dma_end: Unsupported DMA size\n"); + break; + } } - if (m_dma_regs.dcmd[channel] & PXA255_DCMD_ENDIRQEN) + dma_finish(param); +} + +void pxa255_periphs_device::dma_finish(int channel) +{ + if (m_dma_regs.dcmd[channel] & DCMD_ENDIRQEN) { - m_dma_regs.dcsr[channel] |= PXA255_DCSR_ENDINTR; + m_dma_regs.dcsr[channel] |= DCSR_ENDINTR; } - if (!(m_dma_regs.ddadr[channel] & PXA255_DDADR_STOP) && (m_dma_regs.dcsr[channel] & PXA255_DCSR_RUN)) + if (!(m_dma_regs.ddadr[channel] & DDADR_STOP) && (m_dma_regs.dcsr[channel] & DCSR_RUN)) { - if (m_dma_regs.dcsr[channel] & PXA255_DCSR_RUN) + if (m_dma_regs.dcsr[channel] & DCSR_RUN) { dma_load_descriptor_and_start(channel); } else { - m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_RUN; - m_dma_regs.dcsr[channel] |= PXA255_DCSR_STOPSTATE; + m_dma_regs.dcsr[channel] &= ~DCSR_RUN; + m_dma_regs.dcsr[channel] |= DCSR_STOPSTATE; } } else { - m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_RUN; - m_dma_regs.dcsr[channel] |= PXA255_DCSR_STOPSTATE; + m_dma_regs.dcsr[channel] &= ~DCSR_RUN; + m_dma_regs.dcsr[channel] |= DCSR_STOPSTATE; } dma_irq_check(); } -uint32_t pxa255_periphs_device::dma_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::dma_dcsr_r(offs_t offset, u32 mem_mask) { - switch(PXA255_DMA_BASE_ADDR | (offset << 2)) - { - case PXA255_DCSR0: case PXA255_DCSR1: case PXA255_DCSR2: case PXA255_DCSR3: - case PXA255_DCSR4: case PXA255_DCSR5: case PXA255_DCSR6: case PXA255_DCSR7: - case PXA255_DCSR8: case PXA255_DCSR9: case PXA255_DCSR10: case PXA255_DCSR11: - case PXA255_DCSR12: case PXA255_DCSR13: case PXA255_DCSR14: case PXA255_DCSR15: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Channel Control/Status Register %d: %08x & %08x\n", offset, m_dma_regs.dcsr[offset], mem_mask); - return m_dma_regs.dcsr[offset]; - case PXA255_DINT: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Interrupt Register: %08x & %08x\n", m_dma_regs.dint, mem_mask); - return m_dma_regs.dint; - case PXA255_DRCMR0: case PXA255_DRCMR1: case PXA255_DRCMR2: case PXA255_DRCMR3: - case PXA255_DRCMR4: case PXA255_DRCMR5: case PXA255_DRCMR6: case PXA255_DRCMR7: - case PXA255_DRCMR8: case PXA255_DRCMR9: case PXA255_DRCMR10: case PXA255_DRCMR11: - case PXA255_DRCMR12: case PXA255_DRCMR13: case PXA255_DRCMR14: case PXA255_DRCMR15: - case PXA255_DRCMR16: case PXA255_DRCMR17: case PXA255_DRCMR18: case PXA255_DRCMR19: - case PXA255_DRCMR20: case PXA255_DRCMR21: case PXA255_DRCMR22: case PXA255_DRCMR23: - case PXA255_DRCMR24: case PXA255_DRCMR25: case PXA255_DRCMR26: case PXA255_DRCMR27: - case PXA255_DRCMR28: case PXA255_DRCMR29: case PXA255_DRCMR30: case PXA255_DRCMR31: - case PXA255_DRCMR32: case PXA255_DRCMR33: case PXA255_DRCMR34: case PXA255_DRCMR35: - case PXA255_DRCMR36: case PXA255_DRCMR37: case PXA255_DRCMR38: case PXA255_DRCMR39: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Request to Channel Map Register %d: %08x & %08x\n", offset - (0x100 >> 2), 0, mem_mask); - return m_dma_regs.drcmr[offset - (0x100 >> 2)]; - case PXA255_DDADR0: case PXA255_DDADR1: case PXA255_DDADR2: case PXA255_DDADR3: - case PXA255_DDADR4: case PXA255_DDADR5: case PXA255_DDADR6: case PXA255_DDADR7: - case PXA255_DDADR8: case PXA255_DDADR9: case PXA255_DDADR10: case PXA255_DDADR11: - case PXA255_DDADR12: case PXA255_DDADR13: case PXA255_DDADR14: case PXA255_DDADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Descriptor Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, 0, mem_mask); - return m_dma_regs.ddadr[(offset - (0x200 >> 2)) >> 2]; - case PXA255_DSADR0: case PXA255_DSADR1: case PXA255_DSADR2: case PXA255_DSADR3: - case PXA255_DSADR4: case PXA255_DSADR5: case PXA255_DSADR6: case PXA255_DSADR7: - case PXA255_DSADR8: case PXA255_DSADR9: case PXA255_DSADR10: case PXA255_DSADR11: - case PXA255_DSADR12: case PXA255_DSADR13: case PXA255_DSADR14: case PXA255_DSADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Source Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, 0, mem_mask); - return m_dma_regs.dsadr[(offset - (0x200 >> 2)) >> 2]; - case PXA255_DTADR0: case PXA255_DTADR1: case PXA255_DTADR2: case PXA255_DTADR3: - case PXA255_DTADR4: case PXA255_DTADR5: case PXA255_DTADR6: case PXA255_DTADR7: - case PXA255_DTADR8: case PXA255_DTADR9: case PXA255_DTADR10: case PXA255_DTADR11: - case PXA255_DTADR12: case PXA255_DTADR13: case PXA255_DTADR14: case PXA255_DTADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Target Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, 0, mem_mask); - return m_dma_regs.dtadr[(offset - (0x200 >> 2)) >> 2]; - case PXA255_DCMD0: case PXA255_DCMD1: case PXA255_DCMD2: case PXA255_DCMD3: - case PXA255_DCMD4: case PXA255_DCMD5: case PXA255_DCMD6: case PXA255_DCMD7: - case PXA255_DCMD8: case PXA255_DCMD9: case PXA255_DCMD10: case PXA255_DCMD11: - case PXA255_DCMD12: case PXA255_DCMD13: case PXA255_DCMD14: case PXA255_DCMD15: - LOGMASKED(LOG_DMA, "pxa255_dma_r: DMA Command Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, 0, mem_mask); - return m_dma_regs.dcmd[(offset - (0x200 >> 2)) >> 2]; - default: - LOGMASKED(LOG_DMA | LOG_UNKNOWN, "pxa255_dma_r: Unknown address: %08x\n", PXA255_DMA_BASE_ADDR | (offset << 2)); - break; - } - return 0; + const u32 data = m_dma_regs.dcsr[offset]; + LOGMASKED(LOG_DMA, "%s: dma_dcsr_r: DMA Channel Control/Status Register %d: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + return data; } -void pxa255_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::dma_dcsr_w(offs_t offset, u32 data, u32 mem_mask) { - switch (PXA255_DMA_BASE_ADDR | (offset << 2)) + LOGMASKED(LOG_DMA, "%s: dma_dcsr_w: DMA Channel Control/Status Register %d = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + m_dma_regs.dcsr[offset] &= ~(data & 0x00000007); + m_dma_regs.dcsr[offset] &= ~0x60000000; + m_dma_regs.dcsr[offset] |= data & 0x60000000; + if ((data & DCSR_RUN) && !(m_dma_regs.dcsr[offset] & DCSR_RUN)) { - case PXA255_DCSR0: case PXA255_DCSR1: case PXA255_DCSR2: case PXA255_DCSR3: - case PXA255_DCSR4: case PXA255_DCSR5: case PXA255_DCSR6: case PXA255_DCSR7: - case PXA255_DCSR8: case PXA255_DCSR9: case PXA255_DCSR10: case PXA255_DCSR11: - case PXA255_DCSR12: case PXA255_DCSR13: case PXA255_DCSR14: case PXA255_DCSR15: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Channel Control/Status Register %d: %08x & %08x\n", offset, data, mem_mask); - m_dma_regs.dcsr[offset] &= ~(data & 0x00000007); - m_dma_regs.dcsr[offset] &= ~0x60000000; - m_dma_regs.dcsr[offset] |= data & 0x60000000; - if ((data & PXA255_DCSR_RUN) && !(m_dma_regs.dcsr[offset] & PXA255_DCSR_RUN)) - { - m_dma_regs.dcsr[offset] |= PXA255_DCSR_RUN; - if (data & PXA255_DCSR_NODESCFETCH) - { - LOGMASKED(LOG_DMA, " No-Descriptor-Fetch mode is not supported.\n"); - break; - } - - dma_load_descriptor_and_start(offset); - } - else if(!(data & PXA255_DCSR_RUN)) - { - m_dma_regs.dcsr[offset] &= ~PXA255_DCSR_RUN; - } + m_dma_regs.dcsr[offset] |= DCSR_RUN; + if (data & DCSR_NODESCFETCH) + { + LOGMASKED(LOG_DMA, "%s: No-Descriptor-Fetch mode is not supported.\n", machine().describe_context()); + return; + } - dma_irq_check(); - break; - case PXA255_DINT: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Interrupt Register: %08x & %08x\n", data, mem_mask); - m_dma_regs.dint &= ~data; - break; - case PXA255_DRCMR0: case PXA255_DRCMR1: case PXA255_DRCMR2: case PXA255_DRCMR3: - case PXA255_DRCMR4: case PXA255_DRCMR5: case PXA255_DRCMR6: case PXA255_DRCMR7: - case PXA255_DRCMR8: case PXA255_DRCMR9: case PXA255_DRCMR10: case PXA255_DRCMR11: - case PXA255_DRCMR12: case PXA255_DRCMR13: case PXA255_DRCMR14: case PXA255_DRCMR15: - case PXA255_DRCMR16: case PXA255_DRCMR17: case PXA255_DRCMR18: case PXA255_DRCMR19: - case PXA255_DRCMR20: case PXA255_DRCMR21: case PXA255_DRCMR22: case PXA255_DRCMR23: - case PXA255_DRCMR24: case PXA255_DRCMR25: case PXA255_DRCMR26: case PXA255_DRCMR27: - case PXA255_DRCMR28: case PXA255_DRCMR29: case PXA255_DRCMR30: case PXA255_DRCMR31: - case PXA255_DRCMR32: case PXA255_DRCMR33: case PXA255_DRCMR34: case PXA255_DRCMR35: - case PXA255_DRCMR36: case PXA255_DRCMR37: case PXA255_DRCMR38: case PXA255_DRCMR39: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Request to Channel Map Register %d: %08x & %08x\n", offset - (0x100 >> 2), data, mem_mask); - m_dma_regs.drcmr[offset - (0x100 >> 2)] = data & 0x0000008f; - break; - case PXA255_DDADR0: case PXA255_DDADR1: case PXA255_DDADR2: case PXA255_DDADR3: - case PXA255_DDADR4: case PXA255_DDADR5: case PXA255_DDADR6: case PXA255_DDADR7: - case PXA255_DDADR8: case PXA255_DDADR9: case PXA255_DDADR10: case PXA255_DDADR11: - case PXA255_DDADR12: case PXA255_DDADR13: case PXA255_DDADR14: case PXA255_DDADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Descriptor Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, data, mem_mask); - m_dma_regs.ddadr[(offset - (0x200 >> 2)) >> 2] = data & 0xfffffff1; - break; - case PXA255_DSADR0: case PXA255_DSADR1: case PXA255_DSADR2: case PXA255_DSADR3: - case PXA255_DSADR4: case PXA255_DSADR5: case PXA255_DSADR6: case PXA255_DSADR7: - case PXA255_DSADR8: case PXA255_DSADR9: case PXA255_DSADR10: case PXA255_DSADR11: - case PXA255_DSADR12: case PXA255_DSADR13: case PXA255_DSADR14: case PXA255_DSADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Source Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, data, mem_mask); - m_dma_regs.dsadr[(offset - (0x200 >> 2)) >> 2] = data & 0xfffffffc; - break; - case PXA255_DTADR0: case PXA255_DTADR1: case PXA255_DTADR2: case PXA255_DTADR3: - case PXA255_DTADR4: case PXA255_DTADR5: case PXA255_DTADR6: case PXA255_DTADR7: - case PXA255_DTADR8: case PXA255_DTADR9: case PXA255_DTADR10: case PXA255_DTADR11: - case PXA255_DTADR12: case PXA255_DTADR13: case PXA255_DTADR14: case PXA255_DTADR15: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Target Address Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, data, mem_mask); - m_dma_regs.dtadr[(offset - (0x200 >> 2)) >> 2] = data & 0xfffffffc; - break; - case PXA255_DCMD0: case PXA255_DCMD1: case PXA255_DCMD2: case PXA255_DCMD3: - case PXA255_DCMD4: case PXA255_DCMD5: case PXA255_DCMD6: case PXA255_DCMD7: - case PXA255_DCMD8: case PXA255_DCMD9: case PXA255_DCMD10: case PXA255_DCMD11: - case PXA255_DCMD12: case PXA255_DCMD13: case PXA255_DCMD14: case PXA255_DCMD15: - LOGMASKED(LOG_DMA, "pxa255_dma_w: DMA Command Register %d: %08x & %08x\n", (offset - (0x200 >> 2)) >> 2, data, mem_mask); - m_dma_regs.dcmd[(offset - (0x200 >> 2)) >> 2] = data & 0xf067dfff; - break; - default: - LOGMASKED(LOG_DMA | LOG_UNKNOWN, "pxa255_dma_w: Unknown address: %08x = %08x & %08x\n", PXA255_DMA_BASE_ADDR | (offset << 2), data, mem_mask); - break; + dma_load_descriptor_and_start(offset); + } + else if (!(data & DCSR_RUN)) + { + m_dma_regs.dcsr[offset] &= ~DCSR_RUN; } + + dma_irq_check(); +} + +u32 pxa255_periphs_device::dma_dint_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.dint; + LOGMASKED(LOG_DMA, "%s: dma_dint_r: DMA Interrupt Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } +void pxa255_periphs_device::dma_dint_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_dint_w: DMA Interrupt Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_dma_regs.dint &= ~data; +} + +u32 pxa255_periphs_device::dma_drcmr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.drcmr[offset]; + LOGMASKED(LOG_DMA, "%s: dma_drcmr_r: DMA Request to Channel Map Register %d: %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + return data; +} + +void pxa255_periphs_device::dma_drcmr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_drcmr_w: DMA Request to Channel Map Register %d = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + m_dma_regs.drcmr[offset] = data & 0x0000008f; +} + +template <int Which> +u32 pxa255_periphs_device::dma_ddadr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.ddadr[Which]; + LOGMASKED(LOG_DMA, "%s: dma_ddadr_r: DMA Descriptor Address Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::dma_ddadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_ddadr_w: DMA Descriptor Address Register %d = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + m_dma_regs.ddadr[offset] = data & 0xfffffff1; +} + +template <int Which> +u32 pxa255_periphs_device::dma_dsadr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.dsadr[Which]; + LOGMASKED(LOG_DMA, "%s: dma_dsadr_r: DMA Source Address Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::dma_dsadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_dsadr_w: DMA Source Address Register %d = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + m_dma_regs.dsadr[offset] = data & 0xfffffffc; +} + +template <int Which> +u32 pxa255_periphs_device::dma_dtadr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.dtadr[Which]; + LOGMASKED(LOG_DMA, "%s: dma_dtadr_r: DMA Target Address Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::dma_dtadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_dtadr_w: DMA Target Address Register %d = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask); + m_dma_regs.dtadr[Which] = data & 0xfffffffc; +} + +template <int Which> +u32 pxa255_periphs_device::dma_dcmd_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_dma_regs.dcmd[Which]; + LOGMASKED(LOG_DMA, "%s: dma_dcmd_r: DMA Command Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::dma_dcmd_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_DMA, "%s: dma_dcmd_w: DMA Command Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_dma_regs.dcmd[offset] = data & 0xf067dfff; +} + + /* PXA255 Real-Time Clock @@ -455,13 +660,13 @@ void pxa255_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mas */ -void pxa255_periphs_device::rtc_tick() +TIMER_CALLBACK_MEMBER(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); + set_irq_line(INT_RTC_HZ, 1); } if (m_rtc_regs.rcnr == m_rtc_regs.rtar) @@ -469,73 +674,75 @@ void pxa255_periphs_device::rtc_tick() if (BIT(m_rtc_regs.rtsr, 2)) { m_rtc_regs.rtsr |= (1 << 0); - set_irq_line(PXA255_INT_RTC_ALARM, 1); + set_irq_line(INT_RTC_ALARM, 1); } } } -uint32_t pxa255_periphs_device::rtc_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::rtc_rcnr_r(offs_t offset, u32 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; + const u32 data = m_rtc_regs.rcnr; + LOGMASKED(LOG_RTC, "%s: rtc_rcnr_r: RTC Counter Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::rtc_rcnr_w(offs_t offset, u32 data, u32 mem_mask) { - switch(PXA255_RTC_BASE_ADDR | (offset << 2)) + LOGMASKED(LOG_RTC, "%s: rtc_rcnr_w: RTC Counter Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_rtc_regs.rcnr); +} + +u32 pxa255_periphs_device::rtc_rtar_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_rtc_regs.rtar; + LOGMASKED(LOG_RTC, "%s: rtc_rtar_r: RTC Alarm Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::rtc_rtar_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_RTC, "%s: rtc_rtar_w: RTC Alarm Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_rtc_regs.rtar); +} + +u32 pxa255_periphs_device::rtc_rtsr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_rtc_regs.rtsr; + LOGMASKED(LOG_RTC, "%s: rtc_rtsr_r: RTC Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::rtc_rtsr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_RTC, "%s: rtc_rtsr_w: RTC Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + const u32 old = m_rtc_regs.rtsr; + m_rtc_regs.rtsr &= ~(data & 0x00000003); + m_rtc_regs.rtsr &= ~0x0000000c; + m_rtc_regs.rtsr |= data & 0x0000000c; + const u32 diff = old ^ m_rtc_regs.rtsr; + if (BIT(diff, 1)) + set_irq_line(INT_RTC_HZ, 0); + if (BIT(diff, 0)) + set_irq_line(INT_RTC_ALARM, 0); +} + +u32 pxa255_periphs_device::rtc_rttr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_rtc_regs.rttr; + LOGMASKED(LOG_RTC, "%s: rtc_rttr_r: RTC Trim Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::rtc_rttr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_RTC, "%s: rtc_rttr_w: RTC Trim Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (!BIT(m_rtc_regs.rttr, 31)) { - 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; + COMBINE_DATA(&m_rtc_regs.rttr); } } + /* PXA255 OS Timer register @@ -546,124 +753,118 @@ void pxa255_periphs_device::rtc_w(offs_t offset, uint32_t data, uint32_t mem_mas void pxa255_periphs_device::ostimer_irq_check() { - set_irq_line(PXA255_INT_OSTIMER0, (m_ostimer_regs.oier & PXA255_OIER_E0) ? ((m_ostimer_regs.ossr & PXA255_OSSR_M0) ? 1 : 0) : 0); - //set_irq_line(PXA255_INT_OSTIMER1, (m_ostimer_regs.oier & PXA255_OIER_E1) ? ((m_ostimer_regs.ossr & PXA255_OSSR_M1) ? 1 : 0) : 0); - //set_irq_line(PXA255_INT_OSTIMER2, (m_ostimer_regs.oier & PXA255_OIER_E2) ? ((m_ostimer_regs.ossr & PXA255_OSSR_M2) ? 1 : 0) : 0); - //set_irq_line(PXA255_INT_OSTIMER3, (m_ostimer_regs.oier & PXA255_OIER_E3) ? ((m_ostimer_regs.ossr & PXA255_OSSR_M3) ? 1 : 0) : 0); + set_irq_line(INT_OSTIMER0, (m_ostimer_regs.oier & OIER_E0) ? ((m_ostimer_regs.ossr & OSSR_M0) ? 1 : 0) : 0); + //set_irq_line(INT_OSTIMER1, (m_ostimer_regs.oier & OIER_E1) ? ((m_ostimer_regs.ossr & OSSR_M1) ? 1 : 0) : 0); + //set_irq_line(INT_OSTIMER2, (m_ostimer_regs.oier & OIER_E2) ? ((m_ostimer_regs.ossr & OSSR_M2) ? 1 : 0) : 0); + //set_irq_line(INT_OSTIMER3, (m_ostimer_regs.oier & OIER_E3) ? ((m_ostimer_regs.ossr & OSSR_M3) ? 1 : 0) : 0); } -void pxa255_periphs_device::ostimer_match_tick(int channel) +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::ostimer_match_tick) { - m_ostimer_regs.ossr |= (1 << channel); - m_ostimer_regs.oscr = m_ostimer_regs.osmr[channel]; + m_ostimer_regs.ossr |= (1 << param); + m_ostimer_regs.oscr = m_ostimer_regs.osmr[param]; ostimer_irq_check(); } -uint32_t pxa255_periphs_device::ostimer_r(offs_t offset, uint32_t mem_mask) +template <int Which> +void pxa255_periphs_device::ostimer_update_interrupts() { - switch(PXA255_OSTMR_BASE_ADDR | (offset << 2)) + if ((m_ostimer_regs.oier & (OIER_E0 << Which)) && Which != 3) { - case PXA255_OSMR0: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Match Register 0: %08x & %08x\n", m_ostimer_regs.osmr[0], mem_mask); - return m_ostimer_regs.osmr[0]; - case PXA255_OSMR1: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Match Register 1: %08x & %08x\n", m_ostimer_regs.osmr[1], mem_mask); - return m_ostimer_regs.osmr[1]; - case PXA255_OSMR2: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Match Register 2: %08x & %08x\n", m_ostimer_regs.osmr[2], mem_mask); - return m_ostimer_regs.osmr[2]; - case PXA255_OSMR3: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Match Register 3: %08x & %08x\n", m_ostimer_regs.osmr[3], mem_mask); - return m_ostimer_regs.osmr[3]; - case PXA255_OSCR: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Count Register: %08x & %08x\n", m_ostimer_regs.oscr, mem_mask); - // free-running 3.something MHz counter. this is a complete hack. - m_ostimer_regs.oscr += 0x300; - return m_ostimer_regs.oscr; - case PXA255_OSSR: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Status Register: %08x & %08x\n", m_ostimer_regs.ossr, mem_mask); - return m_ostimer_regs.ossr; - case PXA255_OWER: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Watchdog Match Enable Register: %08x & %08x\n", m_ostimer_regs.ower, mem_mask); - return m_ostimer_regs.ower; - case PXA255_OIER: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_r: OS Timer Interrupt Enable Register: %08x & %08x\n", m_ostimer_regs.oier, mem_mask); - return m_ostimer_regs.oier; - default: - LOGMASKED(LOG_OSTIMER | LOG_UNKNOWN, "pxa255_ostimer_r: Unknown address: %08x\n", PXA255_OSTMR_BASE_ADDR | (offset << 2)); - break; + m_ostimer_regs.timer[Which]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[Which] - m_ostimer_regs.oscr), Which); } - return 0; } -void pxa255_periphs_device::ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::ostimer_update_count() { - switch(PXA255_OSTMR_BASE_ADDR | (offset << 2)) - { - case PXA255_OSMR0: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Match Register 0: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.osmr[0] = data; - if (m_ostimer_regs.oier & PXA255_OIER_E0) - { - m_ostimer_regs.timer[0]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[0] - m_ostimer_regs.oscr)); - } - break; - case PXA255_OSMR1: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Match Register 1: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.osmr[1] = data; - if (m_ostimer_regs.oier & PXA255_OIER_E1) - { - m_ostimer_regs.timer[1]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[1] - m_ostimer_regs.oscr), 1); - } - break; - case PXA255_OSMR2: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Match Register 2: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.osmr[2] = data; - if (m_ostimer_regs.oier & PXA255_OIER_E2) - { - m_ostimer_regs.timer[2]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[2] - m_ostimer_regs.oscr), 2); - } - break; - case PXA255_OSMR3: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Match Register 3: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.osmr[3] = data; - if (m_ostimer_regs.oier & PXA255_OIER_E3) - { - //m_ostimer_regs.timer[3]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[3] - m_ostimer_regs.oscr), 3); - } - break; - case PXA255_OSCR: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Count Register: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.oscr = data; - break; - case PXA255_OSSR: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Status Register: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.ossr &= ~data; - ostimer_irq_check(); - break; - case PXA255_OWER: - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Watchdog Enable Register: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.ower = data & 0x00000001; - break; - case PXA255_OIER: - { - LOGMASKED(LOG_OSTIMER, "pxa255_ostimer_w: OS Timer Interrupt Enable Register: %08x & %08x\n", data, mem_mask); - m_ostimer_regs.oier = data & 0x0000000f; - for (int index = 0; index < 4; index++) - { - if (m_ostimer_regs.oier & (1 << index)) - { - //m_ostimer_regs.timer[index]->adjust(attotime::from_hz(200000000) * m_ostimer_regs.osmr[index], index); - } - } - break; - } - default: - LOGMASKED(LOG_OSTIMER | LOG_UNKNOWN, "pxa255_ostimer_w: Unknown address: %08x = %08x & %08x\n", PXA255_OSTMR_BASE_ADDR | (offset << 2), data, mem_mask); - break; - } + const attotime time_delta = machine().time() - m_ostimer_regs.last_count_sync; + const uint64_t ticks_elapsed = time_delta.as_ticks(INTERNAL_OSC); + if (ticks_elapsed == 0ULL) // Accrue time until we can tick at least once + return; + + const uint32_t wrapped_ticks = (uint32_t)ticks_elapsed; + m_ostimer_regs.oscr += wrapped_ticks; + m_ostimer_regs.last_count_sync = machine().time(); + ostimer_update_interrupts<0>(); + ostimer_update_interrupts<1>(); + ostimer_update_interrupts<2>(); + ostimer_update_interrupts<3>(); +} + +template <int Which> +u32 pxa255_periphs_device::tmr_osmr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_ostimer_regs.osmr[Which]; + LOGMASKED(LOG_OSTIMER, "%s: tmr_osmr_r: OS Timer Match Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::tmr_osmr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_OSTIMER, "%s: pxa255_ostimer_w: OS Timer Match Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + ostimer_update_count(); + m_ostimer_regs.osmr[Which] = data; + ostimer_update_count(); + ostimer_update_interrupts<Which>(); +} + +u32 pxa255_periphs_device::tmr_oscr_r(offs_t offset, u32 mem_mask) +{ + ostimer_update_count(); + const u32 data = m_ostimer_regs.oscr; + LOGMASKED(LOG_OSTIMER, "%s: tmr_oscr_r: OS Timer Count Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return m_ostimer_regs.oscr; +} + +void pxa255_periphs_device::tmr_oscr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_OSTIMER, "%s: tmr_oscr_w: OS Timer Count Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_ostimer_regs.oscr = data; + m_ostimer_regs.last_count_sync = machine().time(); +} + +u32 pxa255_periphs_device::tmr_ossr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_ostimer_regs.ossr; + LOGMASKED(LOG_OSTIMER, "%s: tmr_ossr_r: OS Timer Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::tmr_ossr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_OSTIMER, "%s: tmr_ossr_w: OS Timer Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_ostimer_regs.ossr &= ~data; + ostimer_irq_check(); +} + +u32 pxa255_periphs_device::tmr_ower_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_ostimer_regs.ower; + LOGMASKED(LOG_OSTIMER, "%s: tmr_ower_r: OS Timer Watchdog Match Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::tmr_ower_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_OSTIMER, "%s: tmr_ower_w: OS Timer Watchdog Match Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_ostimer_regs.ower = data & 0x00000001; } +u32 pxa255_periphs_device::tmr_oier_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_ostimer_regs.oier; + LOGMASKED(LOG_OSTIMER, "%s: tmr_oier_r: OS Timer Interrupt Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::tmr_oier_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_OSTIMER, "%s: tmr_oier_w: OS Timer Interrupt Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_ostimer_regs.oier = data & 0x0000000f; +} + + /* PXA255 Interrupt registers @@ -680,73 +881,89 @@ void pxa255_periphs_device::update_interrupts() m_maincpu->set_input_line(ARM7_IRQ_LINE, m_intc_regs.icip ? ASSERT_LINE : CLEAR_LINE); } -void pxa255_periphs_device::set_irq_line(uint32_t line, int irq_state) +void pxa255_periphs_device::set_irq_line(u32 line, int irq_state) { m_intc_regs.icpr &= ~line; m_intc_regs.icpr |= irq_state ? line : 0; update_interrupts(); } -uint32_t pxa255_periphs_device::intc_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::intc_icip_r(offs_t offset, u32 mem_mask) { - switch (PXA255_INTC_BASE_ADDR | (offset << 2)) - { - case PXA255_ICIP: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller IRQ Pending Register: %08x & %08x\n", m_intc_regs.icip, mem_mask); - return m_intc_regs.icip; - case PXA255_ICMR: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller Mask Register: %08x & %08x\n", m_intc_regs.icmr, mem_mask); - return m_intc_regs.icmr; - case PXA255_ICLR: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller Level Register: %08x & %08x\n", m_intc_regs.iclr, mem_mask); - return m_intc_regs.iclr; - case PXA255_ICFP: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller FIQ Pending Register: %08x & %08x\n", m_intc_regs.icfp, mem_mask); - return m_intc_regs.icfp; - case PXA255_ICPR: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller Pending Register: %08x & %08x\n", m_intc_regs.icpr, mem_mask); - return m_intc_regs.icpr; - case PXA255_ICCR: - LOGMASKED(LOG_INTC, "pxa255_intc_r: Interrupt Controller Control Register: %08x & %08x\n", m_intc_regs.iccr, mem_mask); - return m_intc_regs.iccr; - default: - LOGMASKED(LOG_INTC | LOG_UNKNOWN, "pxa255_intc_r: Unknown address: %08x\n", PXA255_INTC_BASE_ADDR | (offset << 2)); - break; - } - return 0; + const u32 data = m_intc_regs.icip; + LOGMASKED(LOG_INTC, "%s: intc_icip_r: Interrupt Controller IRQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::intc_icip_w(offs_t offset, u32 data, u32 mem_mask) { - switch (PXA255_INTC_BASE_ADDR | (offset << 2)) - { - case PXA255_ICIP: - LOGMASKED(LOG_INTC, "pxa255_intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register: %08x & %08x\n", data, mem_mask); - break; - case PXA255_ICMR: - LOGMASKED(LOG_INTC, "pxa255_intc_w: Interrupt Controller Mask Register: %08x & %08x\n", data, mem_mask); - m_intc_regs.icmr = data & 0xfffe7f00; - break; - case PXA255_ICLR: - LOGMASKED(LOG_INTC, "pxa255_intc_w: Interrupt Controller Level Register: %08x & %08x\n", data, mem_mask); - m_intc_regs.iclr = data & 0xfffe7f00; - break; - case PXA255_ICFP: - LOGMASKED(LOG_INTC, "pxa255_intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register: %08x & %08x\n", data, mem_mask); - break; - case PXA255_ICPR: - LOGMASKED(LOG_INTC, "pxa255_intc_w: (Invalid Write) Interrupt Controller Pending Register: %08x & %08x\n", data, mem_mask); - break; - case PXA255_ICCR: - LOGMASKED(LOG_INTC, "pxa255_intc_w: Interrupt Controller Control Register: %08x & %08x\n", data, mem_mask); - m_intc_regs.iccr = data & 0x00000001; - break; - default: - LOGMASKED(LOG_INTC | LOG_UNKNOWN, "pxa255_intc_w: Unknown address: %08x = %08x & %08x\n", PXA255_INTC_BASE_ADDR | (offset << 2), data, mem_mask); - break; - } + LOGMASKED(LOG_INTC, "%s: intc_icip_w: (Invalid Write) Interrupt Controller IRQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); } +u32 pxa255_periphs_device::intc_icmr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_intc_regs.icmr; + LOGMASKED(LOG_INTC, "%s: intc_icmr_r: Interrupt Controller Mask Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::intc_icmr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_INTC, "%s: intc_icmr_w: Interrupt Controller Mask Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_intc_regs.icmr = data & 0xfffe7f00; +} + +u32 pxa255_periphs_device::intc_iclr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_intc_regs.iclr; + LOGMASKED(LOG_INTC, "%s: intc_iclr_r: Interrupt Controller Level Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::intc_iclr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_INTC, "%s: intc_iclr_w: Interrupt Controller Level Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_intc_regs.iclr = data & 0xfffe7f00; +} + +u32 pxa255_periphs_device::intc_icfp_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_intc_regs.icfp; + LOGMASKED(LOG_INTC, "%s: intc_icfp_r: Interrupt Controller FIQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::intc_icfp_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_INTC, "%s: intc_icfp_w: (Invalid Write) Interrupt Controller FIQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + +u32 pxa255_periphs_device::intc_icpr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_intc_regs.icpr; + LOGMASKED(LOG_INTC, "%s: intc_icpr_r: Interrupt Controller Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::intc_icpr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_INTC, "%s: intc_icpr_w: (Invalid Write) Interrupt Controller Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + +u32 pxa255_periphs_device::intc_iccr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_intc_regs.iccr; + LOGMASKED(LOG_INTC, "%s: intc_iccr_r: Interrupt Controller control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::intc_iccr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_INTC, "%s: intc_iccr_w: Interrupt Controller Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_intc_regs.iccr = data & 0x00000001; +} + + /* PXA255 General-Purpose I/O registers @@ -755,321 +972,358 @@ void pxa255_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma */ -void pxa255_periphs_device::gpio_bit_w(offs_t offset, uint8_t data, uint8_t mem_mask) +template <int Which> +void pxa255_periphs_device::update_gpio_outputs(const u32 old) { - const uint32_t val = (data != 0 ? 1 : 0); - LOGMASKED(LOG_GPIO, "pxa255: GPIO%d written: %d\n", offset, val); - if (offset < 32) + const u32 new_data = (m_gpio_regs.in_data[Which] & ~m_gpio_regs.gpdr[Which]) | (m_gpio_regs.out_data[Which] & m_gpio_regs.gpdr[Which]); + const u32 changed = old ^ new_data; + if (changed == 0) + return; + + for (u32 bit = 0; bit < 32; bit++) { - const uint32_t old = m_gpio_regs.gplr0; - m_gpio_regs.gplr0 &= ~(1 << offset); - m_gpio_regs.gplr0 |= (val << offset); + if (!BIT(changed, bit)) + continue; + LOGMASKED(LOG_GPIO, "Setting GPIO bit %d: %d\n", Which * 32 + bit, BIT(new_data, bit)); + m_gpio_w[Which * 32 + bit](BIT(new_data, bit)); + } +} + +template <int Which> +void pxa255_periphs_device::check_gpio_irqs(const u32 old) +{ + const u32 new_data = (m_gpio_regs.in_data[Which] & ~m_gpio_regs.gpdr[Which]) | (m_gpio_regs.out_data[Which] & m_gpio_regs.gpdr[Which]); + if (old == new_data) + return; + + const u32 rising = ~old & new_data; + const u32 falling = old & ~new_data; - LOGMASKED(LOG_GPIO, "pxa255: Old GPLR0 %08x, New GPLR0 %08x\n", old, m_gpio_regs.gplr0); + LOGMASKED(LOG_GPIO, "pxa255: Rising %08x, Falling %08x\n", rising, falling); - const uint32_t rising = ~old & m_gpio_regs.gplr0; - const uint32_t falling = old & ~m_gpio_regs.gplr0; + const u32 old_gedr = m_gpio_regs.gedr[Which]; + m_gpio_regs.gedr[Which] |= rising & m_gpio_regs.grer[Which]; + m_gpio_regs.gedr[Which] |= falling & m_gpio_regs.gfer[Which]; - LOGMASKED(LOG_GPIO, "pxa255: Rising %08x, Falling %08x\n", rising, falling); + LOGMASKED(LOG_GPIO, "pxa255: Old GEDR%d %08x, New GEDR%d %08x\n", Which, old_gedr, Which, m_gpio_regs.gedr[Which]); + const u32 changed_gedr = old_gedr ^ m_gpio_regs.gedr[Which]; + if (changed_gedr == 0) + return; - 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); + for (u32 bit = 0; bit < 32; bit++) + { + if (!BIT(changed_gedr, bit)) + continue; - 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 Pin %d\n", Which, bit); + if (Which == 0) { - 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); + if (bit > 1) + set_irq_line(INT_GPIO84_2, 1); + else if (bit == 1) + set_irq_line(INT_GPIO1, 1); else - set_irq_line(PXA255_INT_GPIO0, 1); + set_irq_line(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) + else if (Which == 1) + { + set_irq_line(INT_GPIO84_2, 1); + } + else if (Which == 2) { - LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset); - set_irq_line(PXA255_INT_GPIO84_2, 1); + set_irq_line(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; +template void pxa255_periphs_device::gpio_in<0>(int state); +template void pxa255_periphs_device::gpio_in<1>(int state); +template void pxa255_periphs_device::gpio_in<2>(int state); +template void pxa255_periphs_device::gpio_in<3>(int state); +template void pxa255_periphs_device::gpio_in<4>(int state); +template void pxa255_periphs_device::gpio_in<5>(int state); +template void pxa255_periphs_device::gpio_in<6>(int state); +template void pxa255_periphs_device::gpio_in<7>(int state); +template void pxa255_periphs_device::gpio_in<8>(int state); +template void pxa255_periphs_device::gpio_in<9>(int state); +template void pxa255_periphs_device::gpio_in<10>(int state); +template void pxa255_periphs_device::gpio_in<11>(int state); +template void pxa255_periphs_device::gpio_in<12>(int state); +template void pxa255_periphs_device::gpio_in<13>(int state); +template void pxa255_periphs_device::gpio_in<14>(int state); +template void pxa255_periphs_device::gpio_in<15>(int state); +template void pxa255_periphs_device::gpio_in<16>(int state); +template void pxa255_periphs_device::gpio_in<17>(int state); +template void pxa255_periphs_device::gpio_in<18>(int state); +template void pxa255_periphs_device::gpio_in<19>(int state); +template void pxa255_periphs_device::gpio_in<20>(int state); +template void pxa255_periphs_device::gpio_in<21>(int state); +template void pxa255_periphs_device::gpio_in<22>(int state); +template void pxa255_periphs_device::gpio_in<23>(int state); +template void pxa255_periphs_device::gpio_in<24>(int state); +template void pxa255_periphs_device::gpio_in<25>(int state); +template void pxa255_periphs_device::gpio_in<26>(int state); +template void pxa255_periphs_device::gpio_in<27>(int state); +template void pxa255_periphs_device::gpio_in<28>(int state); +template void pxa255_periphs_device::gpio_in<29>(int state); +template void pxa255_periphs_device::gpio_in<30>(int state); +template void pxa255_periphs_device::gpio_in<31>(int state); +template void pxa255_periphs_device::gpio_in<32>(int state); +template void pxa255_periphs_device::gpio_in<33>(int state); +template void pxa255_periphs_device::gpio_in<34>(int state); +template void pxa255_periphs_device::gpio_in<35>(int state); +template void pxa255_periphs_device::gpio_in<36>(int state); +template void pxa255_periphs_device::gpio_in<37>(int state); +template void pxa255_periphs_device::gpio_in<38>(int state); +template void pxa255_periphs_device::gpio_in<39>(int state); +template void pxa255_periphs_device::gpio_in<40>(int state); +template void pxa255_periphs_device::gpio_in<41>(int state); +template void pxa255_periphs_device::gpio_in<42>(int state); +template void pxa255_periphs_device::gpio_in<43>(int state); +template void pxa255_periphs_device::gpio_in<44>(int state); +template void pxa255_periphs_device::gpio_in<45>(int state); +template void pxa255_periphs_device::gpio_in<46>(int state); +template void pxa255_periphs_device::gpio_in<47>(int state); +template void pxa255_periphs_device::gpio_in<48>(int state); +template void pxa255_periphs_device::gpio_in<49>(int state); +template void pxa255_periphs_device::gpio_in<50>(int state); +template void pxa255_periphs_device::gpio_in<51>(int state); +template void pxa255_periphs_device::gpio_in<52>(int state); +template void pxa255_periphs_device::gpio_in<53>(int state); +template void pxa255_periphs_device::gpio_in<54>(int state); +template void pxa255_periphs_device::gpio_in<55>(int state); +template void pxa255_periphs_device::gpio_in<56>(int state); +template void pxa255_periphs_device::gpio_in<57>(int state); +template void pxa255_periphs_device::gpio_in<58>(int state); +template void pxa255_periphs_device::gpio_in<59>(int state); +template void pxa255_periphs_device::gpio_in<60>(int state); +template void pxa255_periphs_device::gpio_in<61>(int state); +template void pxa255_periphs_device::gpio_in<62>(int state); +template void pxa255_periphs_device::gpio_in<63>(int state); +template void pxa255_periphs_device::gpio_in<64>(int state); +template void pxa255_periphs_device::gpio_in<65>(int state); +template void pxa255_periphs_device::gpio_in<66>(int state); +template void pxa255_periphs_device::gpio_in<67>(int state); +template void pxa255_periphs_device::gpio_in<68>(int state); +template void pxa255_periphs_device::gpio_in<69>(int state); +template void pxa255_periphs_device::gpio_in<70>(int state); +template void pxa255_periphs_device::gpio_in<71>(int state); +template void pxa255_periphs_device::gpio_in<72>(int state); +template void pxa255_periphs_device::gpio_in<73>(int state); +template void pxa255_periphs_device::gpio_in<74>(int state); +template void pxa255_periphs_device::gpio_in<75>(int state); +template void pxa255_periphs_device::gpio_in<76>(int state); +template void pxa255_periphs_device::gpio_in<77>(int state); +template void pxa255_periphs_device::gpio_in<78>(int state); +template void pxa255_periphs_device::gpio_in<79>(int state); +template void pxa255_periphs_device::gpio_in<80>(int state); +template void pxa255_periphs_device::gpio_in<81>(int state); +template void pxa255_periphs_device::gpio_in<82>(int state); +template void pxa255_periphs_device::gpio_in<83>(int state); +template void pxa255_periphs_device::gpio_in<84>(int state); +template void pxa255_periphs_device::gpio_in<85>(int state); +template void pxa255_periphs_device::gpio_in<86>(int state); +template void pxa255_periphs_device::gpio_in<87>(int state); +template void pxa255_periphs_device::gpio_in<88>(int state); +template void pxa255_periphs_device::gpio_in<89>(int state); +template void pxa255_periphs_device::gpio_in<90>(int state); +template void pxa255_periphs_device::gpio_in<91>(int state); +template void pxa255_periphs_device::gpio_in<92>(int state); +template void pxa255_periphs_device::gpio_in<93>(int state); +template void pxa255_periphs_device::gpio_in<94>(int state); +template void pxa255_periphs_device::gpio_in<95>(int state); + +template <int Bit> +void pxa255_periphs_device::gpio_in(int state) +{ + LOGMASKED(LOG_GPIO, "pxa255: GPIO Pin %d written: %d\n", Bit, state); - 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); - } + const u32 which = Bit >> 5; + const u32 old = m_gpio_regs.in_data[which] & ~m_gpio_regs.gpdr[which]; + if (state) + m_gpio_regs.in_data[which] |= (1 << (Bit & 31)); + else + m_gpio_regs.in_data[which] &= ~(1 << (Bit & 31)); + + const u32 new_inputs = m_gpio_regs.in_data[which] & ~m_gpio_regs.gpdr[which]; + LOGMASKED(LOG_GPIO, "pxa255: Old GPIO Pin %d Input %08x, New GPIO Pin %d Input %08x\n", Bit, old, Bit, new_inputs); + + if (Bit < 32) + check_gpio_irqs<0>(old); + else if (Bit < 64) + check_gpio_irqs<1>(old); + else + check_gpio_irqs<2>(old); +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gplr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = (m_gpio_regs.in_data[Which] & ~m_gpio_regs.gpdr[Which]) | (m_gpio_regs.out_data[Which] & m_gpio_regs.gpdr[Which]); + LOGMASKED(LOG_GPIO, "%s: gpio_gplr_r: GPIO Pin-Level Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gplr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gplr_w: (Invalid Write) GPIO Pin-Level Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gpdr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.gpdr[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_gpdr_r: GPIO Pin Direction Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gpdr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gpdr_w: GPIO Pin Direction Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.gpdr[Which] = data; +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gpsr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = 0; + LOGMASKED(LOG_GPIO, "%s: gpio_gpsr_r: (Invalid Read) GPIO Pin Output Set Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gpsr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gpsr_w: GPIO Pin Output Set Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.out_data[Which] |= data & mem_mask; + const u32 set = data & mem_mask & m_gpio_regs.gpdr[Which]; + for (u32 i = 0; i < 32; i++) + { + if (BIT(set, i)) + m_gpio_w[Which * 32 + i](1); } } -uint32_t pxa255_periphs_device::gpio_r(offs_t offset, uint32_t mem_mask) +template <int Which> +u32 pxa255_periphs_device::gpio_gpcr_r(offs_t offset, u32 mem_mask) { - switch(PXA255_GPIO_BASE_ADDR | (offset << 2)) + const u32 data = 0; + LOGMASKED(LOG_GPIO, "%s: gpio_gpcr_r: (Invalid Read) GPIO Pin Output Clear Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gpcr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gpcr_w: GPIO Pin Output Clear Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.out_data[Which] &= ~(data & mem_mask); + const u32 cleared = data & mem_mask & m_gpio_regs.gpdr[Which]; + for (u32 i = 0; i < 32; i++) { - case PXA255_GPLR0: - { - const uint32_t value = (m_gpio_regs.gplr0 & m_gpio_regs.gpdr0) | m_gpio0_r(0, ~m_gpio_regs.gpdr0); - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin-Level Register 0: %08x & %08x\n", m_gpio_regs.gplr0, mem_mask); - return value; - } - case PXA255_GPLR1: - { - const uint32_t value = (m_gpio_regs.gplr1 & m_gpio_regs.gpdr1) | m_gpio1_r(0, ~m_gpio_regs.gpdr1); - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin-Level Register 1: %08x & %08x\n", m_gpio_regs.gplr1, mem_mask); - return value; - } - case PXA255_GPLR2: - { - const uint32_t value = (m_gpio_regs.gplr2 & m_gpio_regs.gpdr2) | m_gpio2_r(0, ~m_gpio_regs.gpdr2); - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin-Level Register 2: %08x & %08x\n", m_gpio_regs.gplr2, mem_mask); - return value; - } - case PXA255_GPDR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin Direction Register 0: %08x & %08x\n", m_gpio_regs.gpdr0, mem_mask); - return m_gpio_regs.gpdr0; - case PXA255_GPDR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin Direction Register 1: %08x & %08x\n", m_gpio_regs.gpdr1, mem_mask); - return m_gpio_regs.gpdr1; - case PXA255_GPDR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Pin Direction Register 2: %08x & %08x\n", m_gpio_regs.gpdr2, mem_mask); - return m_gpio_regs.gpdr2; - case PXA255_GPSR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 0: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GPSR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 1: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GPSR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 2: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GPCR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 0: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GPCR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 1: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GPCR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 2: %08x & %08x\n", machine().rand(), mem_mask); - return machine().rand(); - case PXA255_GRER0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 0: %08x & %08x\n", m_gpio_regs.grer0, mem_mask); - return m_gpio_regs.grer0; - case PXA255_GRER1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 1: %08x & %08x\n", m_gpio_regs.grer1, mem_mask); - return m_gpio_regs.grer1; - case PXA255_GRER2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 2: %08x & %08x\n", m_gpio_regs.grer2, mem_mask); - return m_gpio_regs.grer2; - case PXA255_GFER0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 0: %08x & %08x\n", m_gpio_regs.gfer0, mem_mask); - return m_gpio_regs.gfer0; - case PXA255_GFER1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 1: %08x & %08x\n", m_gpio_regs.gfer1, mem_mask); - return m_gpio_regs.gfer1; - case PXA255_GFER2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 2: %08x & %08x\n", m_gpio_regs.gfer2, mem_mask); - return m_gpio_regs.gfer2; - case PXA255_GEDR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Edge Detect Status Register 0: %08x & %08x\n", m_gpio_regs.gedr0, mem_mask); - return m_gpio_regs.gedr0; - case PXA255_GEDR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Edge Detect Status Register 1: %08x & %08x\n", m_gpio_regs.gedr1, mem_mask); - return m_gpio_regs.gedr1; - case PXA255_GEDR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Edge Detect Status Register 2: %08x & %08x\n", m_gpio_regs.gedr2, mem_mask); - return m_gpio_regs.gedr2; - case PXA255_GAFR0_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 0 Lower: %08x & %08x\n", m_gpio_regs.gafr0l, mem_mask); - return m_gpio_regs.gafr0l; - case PXA255_GAFR0_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 0 Upper: %08x & %08x\n", m_gpio_regs.gafr0u, mem_mask); - return m_gpio_regs.gafr0u; - case PXA255_GAFR1_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 1 Lower: %08x & %08x\n", m_gpio_regs.gafr1l, mem_mask); - return m_gpio_regs.gafr1l; - case PXA255_GAFR1_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 1 Upper: %08x & %08x\n", m_gpio_regs.gafr1u, mem_mask); - return m_gpio_regs.gafr1u; - case PXA255_GAFR2_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 2 Lower: %08x & %08x\n", m_gpio_regs.gafr2l, mem_mask); - return m_gpio_regs.gafr2l; - case PXA255_GAFR2_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_r: GPIO Alternate Function Register 2 Upper: %08x & %08x\n", m_gpio_regs.gafr2u, mem_mask); - return m_gpio_regs.gafr2u; - default: - LOGMASKED(LOG_GPIO | LOG_UNKNOWN, "pxa255_gpio_r: Unknown address: %08x\n", PXA255_GPIO_BASE_ADDR | (offset << 2)); - break; + if (BIT(cleared, i)) + m_gpio_w[Which * 32 + i](0); } - return 0; } -void pxa255_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask) +template <int Which> +u32 pxa255_periphs_device::gpio_grer_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.grer[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_grer_r: GPIO Rising Edge Detect Enable Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_grer_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_grer_w: GPIO Rising Edge Detect Enable Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.grer[Which] = data; +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gfer_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.gfer[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_grer_r: GPIO Falling Edge Detect Enable Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gfer_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gfer_w: GPIO Falling Edge Detect Enable Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.gfer[Which] = data; +} +template <int Which> +u32 pxa255_periphs_device::gpio_gedr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.gedr[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_gedr_r: GPIO Edge Detect Status Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gedr_w(offs_t offset, u32 data, u32 mem_mask) { - switch(PXA255_GPIO_BASE_ADDR | (offset << 2)) + LOGMASKED(LOG_GPIO, "%s: gpio_gedr_w: GPIO Edge Detect Status Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + const u32 old = m_gpio_regs.gedr[Which]; + m_gpio_regs.gedr[Which] &= ~data; + const u32 lowered = old & ~m_gpio_regs.gedr[Which]; + if (Which == 0) { - case PXA255_GPLR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 0: %08x & %08x\n", data, mem_mask); - break; - case PXA255_GPLR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 1: %08x & %08x\n", data, mem_mask); - break; - case PXA255_GPLR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 2: %08x & %08x\n", data, mem_mask); - break; - case PXA255_GPDR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Direction Register 0: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpdr0 = data; - break; - case PXA255_GPDR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Direction Register 1: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpdr1 = data; - break; - case PXA255_GPDR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Direction Register 2: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpdr2 = data; - break; - case PXA255_GPSR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Set Register 0: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr0 |= data & m_gpio_regs.gpdr0; - m_gpio0_w(0, data, m_gpio_regs.gpdr0); - break; - case PXA255_GPSR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Set Register 1: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr1 |= data & m_gpio_regs.gpdr1; - m_gpio1_w(0, data, m_gpio_regs.gpdr1); - break; - case PXA255_GPSR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Set Register 2: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr2 |= data & m_gpio_regs.gpdr2; - m_gpio2_w(0, data, m_gpio_regs.gpdr2); - break; - case PXA255_GPCR0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Clear Register 0: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr0 &= ~(data & m_gpio_regs.gpdr0); - m_gpio0_w(0, data, m_gpio_regs.gpdr0); - break; - case PXA255_GPCR1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Clear Register 1: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr1 &= ~(data & m_gpio_regs.gpdr1); - m_gpio1_w(0, data, m_gpio_regs.gpdr1); - break; - case PXA255_GPCR2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Pin Output Clear Register 2: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gpsr2 &= ~(data & m_gpio_regs.gpdr2); - m_gpio2_w(0, data, m_gpio_regs.gpdr2); - break; - case PXA255_GRER0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 0: %08x & %08x\n", data, mem_mask); - m_gpio_regs.grer0 = data; - break; - case PXA255_GRER1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 1: %08x & %08x\n", data, mem_mask); - m_gpio_regs.grer1 = data; - break; - case PXA255_GRER2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 2: %08x & %08x\n", data, mem_mask); - m_gpio_regs.grer2 = data; - break; - case PXA255_GFER0: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 0: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gfer0 = data; - break; - case PXA255_GFER1: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 1: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gfer1 = data; - break; - case PXA255_GFER2: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 2: %08x & %08x\n", data, mem_mask); - m_gpio_regs.gfer2 = data; - break; - case PXA255_GEDR0: + if (BIT(lowered, 0)) { - 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; + set_irq_line(INT_GPIO0, 0); + return; } - case PXA255_GEDR1: + else if (BIT(lowered, 1)) { - 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; + set_irq_line(INT_GPIO1, 0); + return; } - case PXA255_GEDR2: + else if (!(lowered & 0xfffffffc)) { - 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; + return; } - 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; - break; - case PXA255_GAFR0_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 0 Upper: %08x & %08x\n", m_gpio_regs.gafr0u, mem_mask); - m_gpio_regs.gafr0u = data; - break; - case PXA255_GAFR1_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 1 Lower: %08x & %08x\n", m_gpio_regs.gafr1l, mem_mask); - m_gpio_regs.gafr1l = data; - break; - case PXA255_GAFR1_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 1 Upper: %08x & %08x\n", m_gpio_regs.gafr1u, mem_mask); - m_gpio_regs.gafr1u = data; - break; - case PXA255_GAFR2_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 2 Lower: %08x & %08x\n", m_gpio_regs.gafr2l, mem_mask); - m_gpio_regs.gafr2l = data; - break; - case PXA255_GAFR2_U: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 2 Upper: %08x & %08x\n", m_gpio_regs.gafr2u, mem_mask); - m_gpio_regs.gafr2u = data; - break; - default: - LOGMASKED(LOG_GPIO | LOG_UNKNOWN, "pxa255_gpio_w: Unknown address: %08x = %08x & %08x\n", PXA255_GPIO_BASE_ADDR | (offset << 2), data, mem_mask); - break; } + + if (!m_gpio_regs.gedr[0] && !m_gpio_regs.gedr[1] && !m_gpio_regs.gedr[2]) + set_irq_line(INT_GPIO84_2, 0); +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gafrl_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.gafrl[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_gafrl_r: GPIO Alternate Function Register %d Lower: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; } +template <int Which> +void pxa255_periphs_device::gpio_gafrl_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gafrl_w: GPIO Alternate Function Register %d Lower = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.gafrl[Which] = data; +} + +template <int Which> +u32 pxa255_periphs_device::gpio_gafru_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_gpio_regs.gafru[Which]; + LOGMASKED(LOG_GPIO, "%s: gpio_gafru_r: GPIO Alternate Function Register %d Upper: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::gpio_gafru_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_GPIO, "%s: gpio_gafru_w: GPIO Alternate Function Register %d Upper = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_gpio_regs.gafru[Which] = data; +} + + /* PXA255 LCD Controller @@ -1078,8 +1332,34 @@ void pxa255_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma */ -void pxa255_periphs_device::lcd_load_dma_descriptor(address_space & space, uint32_t address, int channel) +u32 pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + for (int y = 0; y <= (m_lcd_regs.lccr[2] & LCCR2_LPP); y++) + { + u32 *dst = &bitmap.pix(y); + for (int x = 0; x <= (m_lcd_regs.lccr[1] & LCCR1_PPL); x++) + { + *dst++ = m_lcd_palette[m_lcd_framebuffer[y * ((m_lcd_regs.lccr[1] & LCCR1_PPL) + 1) + x]]; + } + } + return 0; +} + +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::lcd_dma_eof_tick) +{ + LOGMASKED(LOG_LCD_DMA, "End of frame callback\n" ); + if (m_lcd_regs.dma[param].ldcmd & LDCMD_EOFINT) + { + m_lcd_regs.liidr = m_lcd_regs.dma[param].fidr; + m_lcd_regs.lcsr |= LCSR_EOF; + } + lcd_check_load_next_branch(param); + lcd_irq_check(); +} + +void pxa255_periphs_device::lcd_load_dma_descriptor(u32 address, int channel) { + address_space & space = m_maincpu->space(AS_PROGRAM); m_lcd_regs.dma[channel].fdadr = space.read_dword(address); m_lcd_regs.dma[channel].fsadr = space.read_dword(address + 0x04); m_lcd_regs.dma[channel].fidr = space.read_dword(address + 0x08); @@ -1093,41 +1373,41 @@ void pxa255_periphs_device::lcd_load_dma_descriptor(address_space & space, uint3 void pxa255_periphs_device::lcd_irq_check() { - if(((m_lcd_regs.lcsr & PXA255_LCSR_BS) != 0 && (m_lcd_regs.lccr0 & PXA255_LCCR0_BM) == 0) || - ((m_lcd_regs.lcsr & PXA255_LCSR_EOF) != 0 && (m_lcd_regs.lccr0 & PXA255_LCCR0_EFM) == 0) || - ((m_lcd_regs.lcsr & PXA255_LCSR_SOF) != 0 && (m_lcd_regs.lccr0 & PXA255_LCCR0_SFM) == 0)) + if (((m_lcd_regs.lcsr & LCSR_BS) != 0 && (m_lcd_regs.lccr[0] & LCCR0_BM) == 0) || + ((m_lcd_regs.lcsr & LCSR_EOF) != 0 && (m_lcd_regs.lccr[0] & LCCR0_EFM) == 0) || + ((m_lcd_regs.lcsr & LCSR_SOF) != 0 && (m_lcd_regs.lccr[0] & LCCR0_SFM) == 0)) { - set_irq_line(PXA255_INT_LCD, 1); + set_irq_line(INT_LCD, 1); } else { - set_irq_line(PXA255_INT_LCD, 0); + set_irq_line(INT_LCD, 0); } } void pxa255_periphs_device::lcd_dma_kickoff(int channel) { - if(m_lcd_regs.dma[channel].fdadr != 0) + if (m_lcd_regs.dma[channel].fdadr != 0) { attotime period = attotime::from_hz(20000000) * (m_lcd_regs.dma[channel].ldcmd & 0x000fffff); m_lcd_regs.dma[channel].eof->adjust(period, channel); - if(m_lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_SOFINT) + if (m_lcd_regs.dma[channel].ldcmd & LDCMD_SOFINT) { m_lcd_regs.liidr = m_lcd_regs.dma[channel].fidr; - m_lcd_regs.lcsr |= PXA255_LCSR_SOF; + m_lcd_regs.lcsr |= LCSR_SOF; lcd_irq_check(); } - if(m_lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_PAL) + if (m_lcd_regs.dma[channel].ldcmd & LDCMD_PAL) { address_space &space = m_maincpu->space(AS_PROGRAM); int length = m_lcd_regs.dma[channel].ldcmd & 0x000fffff; int index = 0; for(index = 0; index < length; index += 2) { - uint16_t color = space.read_word((m_lcd_regs.dma[channel].fsadr &~ 1) + index); + u16 color = space.read_word((m_lcd_regs.dma[channel].fsadr &~ 1) + index); m_lcd_palette[index >> 1] = (((((color >> 11) & 0x1f) << 3) | (color >> 13)) << 16) | (((((color >> 5) & 0x3f) << 2) | ((color >> 9) & 0x3)) << 8) | (((color & 0x1f) << 3) | ((color >> 2) & 0x7)); m_palette->set_pen_color(index >> 1, (((color >> 11) & 0x1f) << 3) | (color >> 13), (((color >> 5) & 0x3f) << 2) | ((color >> 9) & 0x3), ((color & 0x1f) << 3) | ((color >> 2) & 0x7)); } @@ -1147,465 +1427,379 @@ void pxa255_periphs_device::lcd_dma_kickoff(int channel) void pxa255_periphs_device::lcd_check_load_next_branch(int channel) { - if(m_lcd_regs.fbr[channel] & 1) + if (m_lcd_regs.fbr[channel] & 1) { LOGMASKED(LOG_LCD_DMA, "lcd_check_load_next_branch: Taking branch\n" ); m_lcd_regs.fbr[channel] &= ~1; address_space &space = m_maincpu->space(AS_PROGRAM); - //m_lcd_regs.fbr[channel] = (space.read_dword(m_lcd_regs.fbr[channel] & 0xfffffff0) & 0xfffffff0) | (m_lcd_regs.fbr[channel] & 0x00000003); - //printf( "%08x\n", m_lcd_regs.fbr[channel] ); - lcd_load_dma_descriptor(space, m_lcd_regs.fbr[channel] & 0xfffffff0, 0); + lcd_load_dma_descriptor(m_lcd_regs.fbr[channel] & 0xfffffff0, 0); m_lcd_regs.fbr[channel] = (space.read_dword(m_lcd_regs.fbr[channel] & 0xfffffff0) & 0xfffffff0) | (m_lcd_regs.fbr[channel] & 0x00000003); lcd_dma_kickoff(0); - if(m_lcd_regs.fbr[channel] & 2) + if (m_lcd_regs.fbr[channel] & 2) { m_lcd_regs.fbr[channel] &= ~2; - if(!(m_lcd_regs.lccr0 & PXA255_LCCR0_BM)) + if (!(m_lcd_regs.lccr[0] & LCCR0_BM)) { - m_lcd_regs.lcsr |= PXA255_LCSR_BS; + m_lcd_regs.lcsr |= LCSR_BS; } } } else { - LOGMASKED(LOG_LCD_DMA, "pxa255_lcd_check_load_next_branch: Not taking branch\n" ); + LOGMASKED(LOG_LCD_DMA, "lcd_check_load_next_branch: Not taking branch\n" ); } } -void pxa255_periphs_device::lcd_dma_eof_tick(int channel) +template <int Which> +u32 pxa255_periphs_device::lcd_lccr_r(offs_t offset, u32 mem_mask) { - LOGMASKED(LOG_LCD_DMA, "End of frame callback\n" ); - if(m_lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_EOFINT) + const u32 data = m_lcd_regs.lccr[Which]; + LOGMASKED(LOG_LCD, "%s: lcd_lccr_r: LCD Control Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_lccr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_lccr_w: LCD Control Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + if (Which == 0) + m_lcd_regs.lccr[Which] = data & 0x00fffeff; + else + m_lcd_regs.lccr[Which] = data; +} + +template <int Which> +u32 pxa255_periphs_device::lcd_fbr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.fbr[Which]; + LOGMASKED(LOG_LCD, "%s: lcd_fbr_r: LCD Frame Branch Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_fbr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_lccr_w: LCD Frame Branch Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + m_lcd_regs.fbr[Which] = data & 0xfffffff3; + if (!m_lcd_regs.dma[Which].eof->enabled()) { - m_lcd_regs.liidr = m_lcd_regs.dma[channel].fidr; - m_lcd_regs.lcsr |= PXA255_LCSR_EOF; + LOGMASKED(LOG_LCD, "ch%d EOF timer is not enabled, taking branch now\n", Which); + lcd_check_load_next_branch(Which); + lcd_irq_check(); } - lcd_check_load_next_branch(channel); +} + +u32 pxa255_periphs_device::lcd_lcsr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.lcsr; + LOGMASKED(LOG_LCD, "%s: lcd_lcsr_r: LCD Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::lcd_lcsr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_lcsr_w: LCD Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_lcd_regs.lcsr &= ~data; lcd_irq_check(); } -uint32_t pxa255_periphs_device::lcd_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::lcd_liidr_r(offs_t offset, u32 mem_mask) { - switch(PXA255_LCD_BASE_ADDR | (offset << 2)) - { - case PXA255_LCCR0: // 0x44000000 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Control 0: %08x & %08x\n", m_lcd_regs.lccr0, mem_mask); - return m_lcd_regs.lccr0; - case PXA255_LCCR1: // 0x44000004 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Control 1: %08x & %08x\n", m_lcd_regs.lccr1, mem_mask); - return m_lcd_regs.lccr1; - case PXA255_LCCR2: // 0x44000008 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Control 2: %08x & %08x\n", m_lcd_regs.lccr2, mem_mask); - return m_lcd_regs.lccr2; - case PXA255_LCCR3: // 0x4400000c - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Control 3: %08x & %08x\n", m_lcd_regs.lccr3, mem_mask); - return m_lcd_regs.lccr3; - case PXA255_FBR0: // 0x44000020 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Frame Branch Register 0: %08x & %08x\n", m_lcd_regs.fbr[0], mem_mask); - return m_lcd_regs.fbr[0]; - case PXA255_FBR1: // 0x44000024 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Frame Branch Register 1: %08x & %08x\n", m_lcd_regs.fbr[1], mem_mask); - return m_lcd_regs.fbr[1]; - case PXA255_LCSR: // 0x44000038 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Status Register: %08x & %08x\n", m_lcd_regs.lcsr, mem_mask); - return m_lcd_regs.lcsr; - case PXA255_LIIDR: // 0x4400003c - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD Interrupt ID Register: %08x & %08x\n", m_lcd_regs.liidr, mem_mask); - return m_lcd_regs.liidr; - case PXA255_TRGBR: // 0x44000040 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: TMED RGB Seed Register: %08x & %08x\n", m_lcd_regs.trgbr, mem_mask); - return m_lcd_regs.trgbr; - case PXA255_TCR: // 0x44000044 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: TMED RGB Seed Register: %08x & %08x\n", m_lcd_regs.tcr, mem_mask); - return m_lcd_regs.tcr; - case PXA255_FDADR0: // 0x44000200 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame Descriptor Address Register 0: %08x & %08x\n", m_lcd_regs.dma[0].fdadr, mem_mask); - return m_lcd_regs.dma[0].fdadr; - case PXA255_FSADR0: // 0x44000204 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame Source Address Register 0: %08x & %08x\n", m_lcd_regs.dma[0].fsadr, mem_mask); - return m_lcd_regs.dma[0].fsadr; - case PXA255_FIDR0: // 0x44000208 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame ID Register 0: %08x & %08x\n", m_lcd_regs.dma[0].fidr, mem_mask); - return m_lcd_regs.dma[0].fidr; - case PXA255_LDCMD0: // 0x4400020c - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Command Register 0: %08x & %08x\n", m_lcd_regs.dma[0].ldcmd & 0xfff00000, mem_mask); - return m_lcd_regs.dma[0].ldcmd & 0xfff00000; - case PXA255_FDADR1: // 0x44000210 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame Descriptor Address Register 1: %08x & %08x\n", m_lcd_regs.dma[1].fdadr, mem_mask); - return m_lcd_regs.dma[1].fdadr; - case PXA255_FSADR1: // 0x44000214 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame Source Address Register 1: %08x & %08x\n", m_lcd_regs.dma[1].fsadr, mem_mask); - return m_lcd_regs.dma[1].fsadr; - case PXA255_FIDR1: // 0x44000218 - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Frame ID Register 1: %08x & %08x\n", m_lcd_regs.dma[1].fidr, mem_mask); - return m_lcd_regs.dma[1].fidr; - case PXA255_LDCMD1: // 0x4400021c - LOGMASKED(LOG_LCD, "pxa255_lcd_r: LCD DMA Command Register 1: %08x & %08x\n", m_lcd_regs.dma[1].ldcmd & 0xfff00000, mem_mask); - return m_lcd_regs.dma[1].ldcmd & 0xfff00000; - default: - LOGMASKED(LOG_LCD | LOG_UNKNOWN, "pxa255_lcd_r: Unknown address: %08x\n", PXA255_LCD_BASE_ADDR | (offset << 2)); - break; - } - return 0; + const u32 data = m_lcd_regs.liidr; + LOGMASKED(LOG_LCD, "%s: lcd_liidr_r: LCD Interrupt ID Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::lcd_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::lcd_liidr_w(offs_t offset, u32 data, u32 mem_mask) { - switch(PXA255_LCD_BASE_ADDR | (offset << 2)) - { - case PXA255_LCCR0: // 0x44000000 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Control 0: %08x & %08x\n", data, mem_mask); - m_lcd_regs.lccr0 = data & 0x00fffeff; - break; - case PXA255_LCCR1: // 0x44000004 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Control 1: %08x & %08x\n", data, mem_mask); - m_lcd_regs.lccr1 = data; - break; - case PXA255_LCCR2: // 0x44000008 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Control 2: %08x & %08x\n", data, mem_mask); - m_lcd_regs.lccr2 = data; - break; - case PXA255_LCCR3: // 0x4400000c - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Control 3: %08x & %08x\n", data, mem_mask); - m_lcd_regs.lccr3 = data; - break; - case PXA255_FBR0: // 0x44000020 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Frame Branch Register 0: %08x & %08x\n", data, mem_mask); - m_lcd_regs.fbr[0] = data & 0xfffffff3; - if(!m_lcd_regs.dma[0].eof->enabled()) - { - LOGMASKED(LOG_LCD, "ch0 EOF timer is not enabled, taking branch now\n" ); - lcd_check_load_next_branch(0); - lcd_irq_check(); - } - break; - case PXA255_FBR1: // 0x44000024 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Frame Branch Register 1: %08x & %08x\n", data, mem_mask); - m_lcd_regs.fbr[1] = data & 0xfffffff3; - if(!m_lcd_regs.dma[1].eof->enabled()) - { - LOGMASKED(LOG_LCD, "ch1 EOF timer is not enabled, taking branch now\n" ); - lcd_check_load_next_branch(1); - lcd_irq_check(); - } - break; - case PXA255_LCSR: // 0x44000038 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Controller Status Register: %08x & %08x\n", data, mem_mask); - m_lcd_regs.lcsr &= ~data; - lcd_irq_check(); - break; - case PXA255_LIIDR: // 0x4400003c - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD Controller Interrupt ID Register: %08x & %08x\n", data, mem_mask); - break; - case PXA255_TRGBR: // 0x44000040 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: TMED RGB Seed Register: %08x & %08x\n", data, mem_mask); - m_lcd_regs.trgbr = data & 0x00ffffff; - break; - case PXA255_TCR: // 0x44000044 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: TMED Control Register: %08x & %08x\n", data, mem_mask); - m_lcd_regs.tcr = data & 0x00004fff; - break; - case PXA255_FDADR0: // 0x44000200 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD DMA Frame Descriptor Address Register 0: %08x & %08x\n", data, mem_mask); - if(!m_lcd_regs.dma[0].eof->enabled()) - { - lcd_load_dma_descriptor(space, data & 0xfffffff0, 0); - } - else - { - m_lcd_regs.fbr[0] &= 0x00000003; - m_lcd_regs.fbr[0] |= data & 0xfffffff0; - } - break; - case PXA255_FSADR0: // 0x44000204 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame Source Address Register 0: %08x & %08x\n", data, mem_mask); - break; - case PXA255_FIDR0: // 0x44000208 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame ID Register 0: %08x & %08x\n", data, mem_mask); - break; - case PXA255_LDCMD0: // 0x4400020c - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Command Register 0: %08x & %08x\n", data, mem_mask); - break; - case PXA255_FDADR1: // 0x44000210 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: LCD DMA Frame Descriptor Address Register 1: %08x & %08x\n", data, mem_mask); - if(!m_lcd_regs.dma[1].eof->enabled()) - { - lcd_load_dma_descriptor(space, data & 0xfffffff0, 1); - } - else - { - m_lcd_regs.fbr[1] &= 0x00000003; - m_lcd_regs.fbr[1] |= data & 0xfffffff0; - } - break; - case PXA255_FSADR1: // 0x44000214 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame Source Address Register 1: %08x & %08x\n", data, mem_mask); - break; - case PXA255_FIDR1: // 0x44000218 - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame ID Register 1: %08x & %08x\n", data, mem_mask); - break; - case PXA255_LDCMD1: // 0x4400021c - LOGMASKED(LOG_LCD, "pxa255_lcd_w: (Invalid Write) LCD DMA Command Register 1: %08x & %08x\n", data, mem_mask); - break; - default: - LOGMASKED(LOG_LCD | LOG_UNKNOWN, "pxa255_lcd_w: Unknown address: %08x = %08x & %08x\n", PXA255_LCD_BASE_ADDR | (offset << 2), data, mem_mask); - break; - } + LOGMASKED(LOG_LCD, "%s: lcd_liidr_w: LCD Interrupt ID Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); } -uint32_t pxa255_periphs_device::power_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::lcd_trgbr_r(offs_t offset, u32 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; + const u32 data = m_lcd_regs.trgbr; + LOGMASKED(LOG_LCD, "%s: lcd_trgbr_r: TMED RGB Seed Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::lcd_trgbr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_trgbr_w: TMED RGB Seed Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_lcd_regs.trgbr = data & 0x00ffffff; +} + +u32 pxa255_periphs_device::lcd_tcr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.tcr; + LOGMASKED(LOG_LCD, "%s: lcd_tcr_r: TMED Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::lcd_tcr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_tcr_w: TMED Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_lcd_regs.tcr = data & 0x00004fff; } -void pxa255_periphs_device::power_w(offs_t offset, uint32_t data, uint32_t mem_mask) +template <int Which> +u32 pxa255_periphs_device::lcd_fdadr_r(offs_t offset, u32 mem_mask) { - switch(PXA255_POWER_BASE_ADDR | (offset << 2)) + const u32 data = m_lcd_regs.dma[Which].fdadr; + LOGMASKED(LOG_LCD, "%s: lcd_fdadr_r: LCD DMA Frame Descriptor Address Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_fdadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_fdadr_w: LCD DMA Frame Descriptor Address Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + if (!m_lcd_regs.dma[Which].eof->enabled()) { - 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; + lcd_load_dma_descriptor(data & 0xfffffff0, Which); + } + else + { + m_lcd_regs.fbr[Which] &= 0x00000003; + m_lcd_regs.fbr[Which] |= data & 0xfffffff0; } } +template <int Which> +u32 pxa255_periphs_device::lcd_fsadr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.dma[Which].fsadr; + LOGMASKED(LOG_LCD, "%s: lcd_fsadr_r: LCD DMA Frame Source Address Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_fsadr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_fsadr_w: (Ignored) LCD DMA Frame Source Address Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); +} + +template <int Which> +u32 pxa255_periphs_device::lcd_fidr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.dma[Which].fidr; + LOGMASKED(LOG_LCD, "%s: lcd_fidr_r: LCD DMA Frame ID Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_fidr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_fidr_w: (Ignored) LCD DMA Frame ID Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); +} + +template <int Which> +u32 pxa255_periphs_device::lcd_ldcmd_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_lcd_regs.dma[Which].ldcmd & 0xfff00000; + LOGMASKED(LOG_LCD, "%s: lcd_ldcmd_r: LCD DMA Command Register %d: %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); + return data; +} + +template <int Which> +void pxa255_periphs_device::lcd_ldcmd_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_ldcmd_w: (Ignored) LCD DMA Command Register %d = %08x & %08x\n", machine().describe_context(), Which, data, mem_mask); +} + + /* - PXA255 Clock controller - pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf + PXA255 Power Controller + + pg. 85 to 96, PXA255 Processor Developers Manual [278693-002].pdf */ -uint32_t pxa255_periphs_device::clocks_r(offs_t offset, uint32_t mem_mask) +u32 pxa255_periphs_device::pwr_pmcr_r(offs_t offset, u32 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; + const u32 data = m_power_regs.pmcr; + LOGMASKED(LOG_POWER, "%s: pwr_pmcr_r: Power Manager Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::clocks_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void pxa255_periphs_device::pwr_pmcr_w(offs_t offset, u32 data, u32 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; - } + LOGMASKED(LOG_POWER, "%s: pwr_pmcr_w: Power Manager Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pmcr); } -void pxa255_periphs_device::device_start() +u32 pxa255_periphs_device::pwr_pssr_r(offs_t offset, u32 mem_mask) { - for (int index = 0; index < 16; index++) - { - m_dma_regs.timer[index] = timer_alloc(TIMER_DMA0 + index); - } + const u32 data = m_power_regs.pssr; + LOGMASKED(LOG_POWER, "%s: pwr_pssr_r: Power Manager Sleep Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} - for (int index = 0; index < 4; index++) - { - m_ostimer_regs.timer[index] = timer_alloc(TIMER_OSTIMER0 + index); - } +void pxa255_periphs_device::pwr_pssr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pssr_w: Power Manager Sleep Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_power_regs.pssr &= ~(data & 0x00000037); +} - m_lcd_regs.dma[0].eof = timer_alloc(TIMER_LCD_EOF0); - m_lcd_regs.dma[1].eof = timer_alloc(TIMER_LCD_EOF0 + 1); +u32 pxa255_periphs_device::pwr_pspr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pspr; + LOGMASKED(LOG_POWER, "%s: pwr_pspr_r: Power Manager Scratch Pad Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} - m_lcd_palette = make_unique_clear<uint32_t[]>(0x100); - m_lcd_framebuffer = make_unique_clear<uint8_t[]>(0x100000); - m_words = make_unique_clear<uint32_t[]>(0x800); - m_samples = make_unique_clear<int16_t[]>(0x1000); +void pxa255_periphs_device::pwr_pspr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pspr_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pspr); +} - m_gpio0_w.resolve_safe(); - m_gpio1_w.resolve_safe(); - m_gpio2_w.resolve_safe(); - m_gpio0_r.resolve_safe(0xffffffff); - m_gpio1_r.resolve_safe(0xffffffff); - m_gpio2_r.resolve_safe(0xffffffff); +u32 pxa255_periphs_device::pwr_pwer_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pwer; + LOGMASKED(LOG_POWER, "%s: pwr_pwer_r: Power Manager Wake-Up Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} - m_rtc_regs.timer = timer_alloc(TIMER_RTC); +void pxa255_periphs_device::pwr_pwer_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pwer_w: Power Manager Wake-Up Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pwer); } -void pxa255_periphs_device::device_reset() +u32 pxa255_periphs_device::pwr_prer_r(offs_t offset, u32 mem_mask) { - for (int index = 0; index < 16; index++) - { - m_dma_regs.dcsr[index] = 0x00000008; - } + const u32 data = m_power_regs.prer; + LOGMASKED(LOG_POWER, "%s: pwr_prer_r: Power Manager GPIO Rising-Edge Detect Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} - 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)); +void pxa255_periphs_device::pwr_prer_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_prer_w: Power Manager GPIO Rising-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.prer); +} - memset(&m_intc_regs, 0, sizeof(m_intc_regs)); +u32 pxa255_periphs_device::pwr_pfer_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pfer; + LOGMASKED(LOG_POWER, "%s: pwr_pfer_r: Power Manager GPIO Falling-Edge Detect Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} - m_lcd_regs.trgbr = 0x00aa5500; - m_lcd_regs.tcr = 0x0000754f; +void pxa255_periphs_device::pwr_pfer_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pfer_w: Power Manager GPIO Falling-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pfer); +} - memset(&m_power_regs, 0, sizeof(m_power_regs)); - memset(&m_clocks_regs, 0, sizeof(m_clocks_regs)); +u32 pxa255_periphs_device::pwr_pedr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pedr; + LOGMASKED(LOG_POWER, "%s: pwr_pedr_r: Power Manager GPIO Edge Detect Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +void pxa255_periphs_device::pwr_pedr_w(offs_t offset, u32 data, u32 mem_mask) { - 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(); + LOGMASKED(LOG_POWER, "%s: pwr_pedr_w: Power Manager GPIO Edge-Detect Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_power_regs.pedr &= ~(data & 0x0000ffff); } -uint32_t pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 pxa255_periphs_device::pwr_pcfr_r(offs_t offset, u32 mem_mask) { - for (int y = 0; y <= (m_lcd_regs.lccr2 & PXA255_LCCR2_LPP); y++) - { - uint32_t *dst = &bitmap.pix(y); - for (int x = 0; x <= (m_lcd_regs.lccr1 & PXA255_LCCR1_PPL); x++) - { - *dst++ = m_lcd_palette[m_lcd_framebuffer[y * ((m_lcd_regs.lccr1 & PXA255_LCCR1_PPL) + 1) + x]]; - } - } - return 0; + const u32 data = m_power_regs.pcfr; + LOGMASKED(LOG_POWER, "%s: pwr_pcfr_r: Power Manager General Configuration Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; } -void pxa255_periphs_device::device_add_mconfig(machine_config &config) +void pxa255_periphs_device::pwr_pcfr_w(offs_t offset, u32 data, u32 mem_mask) { - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(1024, 1024); - screen.set_visarea(0, 295, 0, 479); - screen.set_screen_update(FUNC(pxa255_periphs_device::screen_update)); + LOGMASKED(LOG_POWER, "%s: pwr_pcfr_w: Power Manager General Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pcfr); +} - PALETTE(config, m_palette).set_entries(256); +template <int Which> +u32 pxa255_periphs_device::pwr_pgsr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pgsr[Which]; + LOGMASKED(LOG_POWER, "%s: pwr_pgsr_r: Power Manager GPIO Sleep State Register for GPIO%d-%d: %08x & %08x\n", machine().describe_context(), Which * 32, Which * 32 + 31, data, mem_mask); + return data; +} - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); +template <int Which> +void pxa255_periphs_device::pwr_pgsr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pgsr_w: Power Manager GPIO Sleep State Register for GPIO%d-%d = %08x & %08x\n", machine().describe_context(), Which * 32, Which * 32 + 31, data, mem_mask); + COMBINE_DATA(&m_power_regs.pgsr[Which]); +} - DMADAC(config, m_dmadac[0]).add_route(ALL_OUTPUTS, "lspeaker", 1.0); - DMADAC(config, m_dmadac[1]).add_route(ALL_OUTPUTS, "rspeaker", 1.0); +u32 pxa255_periphs_device::pwr_rcsr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.rcsr; + LOGMASKED(LOG_POWER, "%s: pwr_rcsr_r: Reset Controller Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +u32 pxa255_periphs_device::pwr_pmfw_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_power_regs.pmfw; + LOGMASKED(LOG_POWER, "%s: pwr_pmfw_r: Power Manager Fast Sleep Wake-Up Configuration Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::pwr_pmfw_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_POWER, "%s: pwr_pmfw_w: Power Manager Fast Sleep Wake-Up Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_power_regs.pmfw); +} + + +/* + PXA255 Clock controller + + pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +u32 pxa255_periphs_device::clk_cccr_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_clk_regs.cccr; + LOGMASKED(LOG_CLOCKS, "%s: clk_cccr_r: Core Clock Configuration Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::clk_cccr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_CLOCKS, "%s: clk_cccr_w: Core Clock Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_clk_regs.cccr); +} + +u32 pxa255_periphs_device::clk_cken_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_clk_regs.cken; + LOGMASKED(LOG_CLOCKS, "%s: clk_cken_r: Clock Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::clk_cken_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_CLOCKS, "%s: clk_cken_w: Clock Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_clk_regs.cken); +} + +u32 pxa255_periphs_device::clk_oscc_r(offs_t offset, u32 mem_mask) +{ + const u32 data = m_clk_regs.cccr; + LOGMASKED(LOG_CLOCKS, "%s: clk_oscc_r: Oscillator Configuration Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); + return data; +} + +void pxa255_periphs_device::clk_oscc_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_CLOCKS, "%s: clk_oscc_w: Oscillator Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (BIT(data, 1)) + { + m_clk_regs.oscc |= 0x00000003; + } } |