diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index e6b9f0cb8fa..28d3431abee 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -3000,7 +3000,6 @@ if (MACHINES["PXA255"]~=null) then files { MAME_DIR .. "src/devices/machine/pxa255.cpp", MAME_DIR .. "src/devices/machine/pxa255.h", - MAME_DIR .. "src/devices/machine/pxa255defs.h", } end diff --git a/src/devices/machine/pxa255.cpp b/src/devices/machine/pxa255.cpp index 482f1d3bf15..1f1dff2e452 100644 --- a/src/devices/machine/pxa255.cpp +++ b/src/devices/machine/pxa255.cpp @@ -28,1471 +28,175 @@ #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, 0xffffffff) - , m_gpio1_r(*this, 0xffffffff) - , m_gpio2_r(*this, 0xffffffff) + , m_gpio_w(*this) , m_maincpu(*this, finder_base::DUMMY_TAG) , m_dmadac(*this, "dac%u", 1U) , m_palette(*this, "palette") { } -/* - - PXA255 Inter-Integrated-Circuit Sound (I2S) Controller - - pg. 489 to 504, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -uint32_t pxa255_periphs_device::i2s_r(offs_t offset, uint32_t mem_mask) +void pxa255_periphs_device::map(address_map &map) { - switch (PXA255_I2S_BASE_ADDR | (offset << 2)) - { - 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; - } - return 0; -} - -void pxa255_periphs_device::i2s_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (PXA255_I2S_BASE_ADDR | (offset << 2)) - { - 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; - } -} - -/* - - PXA255 DMA controller - - pg. 151 to 182, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -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)) - { - m_dma_regs.dint |= 1 << channel; - set_irq = 1; - } - else - { - m_dma_regs.dint &= ~(1 << channel); - } - } - - set_irq_line(PXA255_INT_DMA, set_irq); -} - -void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) -{ - // Shut down any transfers that are currently going on, software should be smart enough to check if a - // transfer is running before starting another one on the same channel. - if (m_dma_regs.timer[channel]->enabled()) - { - m_dma_regs.timer[channel]->adjust(attotime::never); - } - - // 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); - m_dma_regs.dcmd[channel] = space.read_dword(m_dma_regs.ddadr[channel] + 0xc); - m_dma_regs.ddadr[channel] = space.read_dword(m_dma_regs.ddadr[channel]); - - // Start our end-of-transfer timer - 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); - break; - default: - m_dma_regs.timer[channel]->adjust(attotime::from_hz(100000000) * (m_dma_regs.dcmd[channel] & 0x00001fff), channel); - break; - } - - // Interrupt as necessary - if (m_dma_regs.dcmd[channel] & PXA255_DCMD_STARTIRQEN) - { - m_dma_regs.dcsr[channel] |= PXA255_DCSR_STARTINTR; - } - - m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_STOPSTATE; -} - -TIMER_CALLBACK_MEMBER(pxa255_periphs_device::audio_dma_end_tick) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - const uint32_t count = m_dma_regs.dcmd[3] & 0x00001fff; - uint32_t sadr = m_dma_regs.dsadr[3]; - - int16_t *out_samples = &m_samples[0]; - for (uint32_t index = 0; index < count; index += 4, sadr += 4) - { - const uint32_t word = space.read_dword(sadr); - *out_samples++ = (int16_t)(word >> 16); - *out_samples++ = (int16_t)(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); - const uint32_t count = m_dma_regs.dcmd[param] & 0x00001fff; - uint32_t sadr = m_dma_regs.dsadr[param]; - uint32_t tadr = m_dma_regs.dtadr[param]; - - static const uint32_t s_inc_size[4] = { 0, 1, 2, 4 }; - const uint32_t inc_index = (m_dma_regs.dcmd[param] >> PXA255_DCMD_SIZE_SHIFT) & PXA255_DCMD_SIZE_MASK; - const uint32_t inc_val = s_inc_size[inc_index]; - const uint32_t sadr_inc = (m_dma_regs.dcmd[param] & PXA255_DCMD_INCSRCADDR) ? inc_val : 0; - const uint32_t tadr_inc = (m_dma_regs.dcmd[param] & PXA255_DCMD_INCTRGADDR) ? inc_val : 0; - - if (inc_val > 0) - { - switch (inc_val) - { - case PXA255_DCMD_SIZE_8: - for (uint32_t index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) - space.write_byte(tadr, space.read_byte(sadr)); - break; - case PXA255_DCMD_SIZE_16: - for (uint32_t index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) - space.write_word(tadr, space.read_byte(sadr)); - break; - case PXA255_DCMD_SIZE_32: - for (uint32_t index = 0; index < count; index += inc_val, sadr += sadr_inc, tadr += tadr_inc) - space.write_dword(tadr, space.read_byte(sadr)); - break; - default: - logerror( "pxa255_dma_dma_end: Unsupported DMA size\n" ); - break; - } - } - - dma_finish(param); -} - -void pxa255_periphs_device::dma_finish(int channel) -{ - if (m_dma_regs.dcmd[channel] & PXA255_DCMD_ENDIRQEN) - { - m_dma_regs.dcsr[channel] |= PXA255_DCSR_ENDINTR; - } - - if (!(m_dma_regs.ddadr[channel] & PXA255_DDADR_STOP) && (m_dma_regs.dcsr[channel] & PXA255_DCSR_RUN)) - { - if (m_dma_regs.dcsr[channel] & PXA255_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; - } - } - else - { - m_dma_regs.dcsr[channel] &= ~PXA255_DCSR_RUN; - m_dma_regs.dcsr[channel] |= PXA255_DCSR_STOPSTATE; - } - - dma_irq_check(); -} - -uint32_t pxa255_periphs_device::dma_r(offs_t offset, uint32_t 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; -} - -void pxa255_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t 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_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; - } - - 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; - } -} - -/* - - PXA255 Real-Time Clock - - pg. 132 to 138, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -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); - } - - if (m_rtc_regs.rcnr == m_rtc_regs.rtar) - { - if (BIT(m_rtc_regs.rtsr, 2)) - { - m_rtc_regs.rtsr |= (1 << 0); - set_irq_line(PXA255_INT_RTC_ALARM, 1); - } - } -} - -uint32_t pxa255_periphs_device::rtc_r(offs_t offset, uint32_t mem_mask) -{ - switch (PXA255_RTC_BASE_ADDR | (offset << 2)) - { - case PXA255_RCNR: - LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Counter Register: %08x\n", machine().describe_context(), m_rtc_regs.rcnr); - return m_rtc_regs.rcnr; - case PXA255_RTAR: - LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Alarm Register: %08x\n", machine().describe_context(), m_rtc_regs.rtar); - return m_rtc_regs.rtar; - case PXA255_RTSR: - LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Status Register: %08x\n", machine().describe_context(), m_rtc_regs.rtsr); - return m_rtc_regs.rtsr; - case PXA255_RTTR: - LOGMASKED(LOG_RTC, "%s: pxa255 rtc_r: RTC Trim Register: %08x\n", machine().describe_context(), m_rtc_regs.rttr); - return m_rtc_regs.rttr; - default: - LOGMASKED(LOG_RTC | LOG_UNKNOWN, "pxa255 rtc_r: Unknown address: %08x\n", PXA255_RTC_BASE_ADDR | (offset << 2)); - break; - } - return 0; -} - -void pxa255_periphs_device::rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (PXA255_RTC_BASE_ADDR | (offset << 2)) - { - case PXA255_RCNR: - LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Counter Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_rtc_regs.rcnr); - break; - case PXA255_RTAR: - LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Alarm Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_rtc_regs.rtar); - break; - case PXA255_RTSR: - { - LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask); - const uint32_t old = m_rtc_regs.rtsr; - m_rtc_regs.rtsr &= ~(data & 0x00000003); - m_rtc_regs.rtsr &= ~0x0000000c; - m_rtc_regs.rtsr |= data & 0x0000000c; - const uint32_t diff = old ^ m_rtc_regs.rtsr; - if (BIT(diff, 1)) - set_irq_line(PXA255_INT_RTC_HZ, 0); - if (BIT(diff, 0)) - set_irq_line(PXA255_INT_RTC_ALARM, 0); - break; - } - case PXA255_RTTR: - LOGMASKED(LOG_RTC, "pxa255 rtc_w: RTC Trim Register (not yet implemented): %08x & %08x\n", machine().describe_context(), data, mem_mask); - if (!BIT(m_rtc_regs.rttr, 31)) - { - COMBINE_DATA(&m_rtc_regs.rttr); - } - break; - default: - LOGMASKED(LOG_RTC | LOG_UNKNOWN, "pxa255 rtc_w: Unknown address: %08x = %08x & %08x\n", PXA255_RTC_BASE_ADDR | (offset << 2), data, mem_mask); - break; - } -} - -/* - - PXA255 OS Timer register - - pg. 138 to 142, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -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); -} - -TIMER_CALLBACK_MEMBER(pxa255_periphs_device::ostimer_match_tick) -{ - 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) -{ - switch (PXA255_OSTMR_BASE_ADDR | (offset << 2)) - { - 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; - } - return 0; -} - -void pxa255_periphs_device::ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - 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), 0); - } - 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; - } -} - -/* - - PXA255 Interrupt registers - - pg. 124 to 132, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -void pxa255_periphs_device::update_interrupts() -{ - m_intc_regs.icfp = (m_intc_regs.icpr & m_intc_regs.icmr) & m_intc_regs.iclr; - m_intc_regs.icip = (m_intc_regs.icpr & m_intc_regs.icmr) & (~m_intc_regs.iclr); - m_maincpu->set_input_line(ARM7_FIRQ_LINE, m_intc_regs.icfp ? ASSERT_LINE : CLEAR_LINE); - 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) -{ - 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) -{ - 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; -} - -void pxa255_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t 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; - } -} - -/* - - PXA255 General-Purpose I/O registers - - pg. 105 to 124, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -void pxa255_periphs_device::gpio_bit_w(offs_t offset, uint8_t data, uint8_t mem_mask) -{ - const uint32_t val = (data != 0 ? 1 : 0); - LOGMASKED(LOG_GPIO, "pxa255: GPIO%d written: %d\n", offset, val); - if (offset < 32) - { - const uint32_t old = m_gpio_regs.gplr0; - m_gpio_regs.gplr0 &= ~(1 << offset); - m_gpio_regs.gplr0 |= (val << offset); - - LOGMASKED(LOG_GPIO, "pxa255: Old GPLR0 %08x, New GPLR0 %08x\n", old, m_gpio_regs.gplr0); - - const uint32_t rising = ~old & m_gpio_regs.gplr0; - const uint32_t falling = old & ~m_gpio_regs.gplr0; - - LOGMASKED(LOG_GPIO, "pxa255: Rising %08x, Falling %08x\n", rising, falling); - - const uint32_t old_gedr = m_gpio_regs.gedr0; - m_gpio_regs.gedr0 |= (rising & m_gpio_regs.grer0); - m_gpio_regs.gedr0 |= (falling & m_gpio_regs.gfer0); - - LOGMASKED(LOG_GPIO, "pxa255: Old GEDR0 %08x, New GEDR0 %08x\n", old_gedr, m_gpio_regs.gedr0); - if (old_gedr != m_gpio_regs.gedr0) - { - LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset); - if (offset > 1) - set_irq_line(PXA255_INT_GPIO84_2, 1); - else if (offset == 1) - set_irq_line(PXA255_INT_GPIO1, 1); - else - set_irq_line(PXA255_INT_GPIO0, 1); - } - } - else if (offset < 64) - { - const uint32_t old = m_gpio_regs.gplr1; - m_gpio_regs.gplr1 &= ~(1 << (offset - 32)); - m_gpio_regs.gplr1 |= ~(val << (offset - 32)); - - const uint32_t rising = ~old & m_gpio_regs.gplr1; - const uint32_t falling = old & ~m_gpio_regs.gplr1; - - const uint32_t old_gedr = m_gpio_regs.gedr1; - m_gpio_regs.gedr1 |= (rising & m_gpio_regs.grer1); - m_gpio_regs.gedr1 |= (falling & m_gpio_regs.gfer1); - if (old_gedr != m_gpio_regs.gedr1) - { - LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset); - set_irq_line(PXA255_INT_GPIO84_2, 1); - } - } - else if (offset < 85) - { - const uint32_t old = m_gpio_regs.gplr2; - m_gpio_regs.gplr2 &= ~(1 << (offset - 64)); - m_gpio_regs.gplr2 |= ~(val << (offset - 64)); - - const uint32_t rising = ~old & m_gpio_regs.gplr2; - const uint32_t falling = old & ~m_gpio_regs.gplr2; - - const uint32_t old_gedr = m_gpio_regs.gedr2; - m_gpio_regs.gedr2 |= (rising & m_gpio_regs.grer2); - m_gpio_regs.gedr2 |= (falling & m_gpio_regs.gfer2); - if (old_gedr != m_gpio_regs.gedr2) - { - LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d\n", offset); - set_irq_line(PXA255_INT_GPIO84_2, 1); - } - } -} - -uint32_t pxa255_periphs_device::gpio_r(offs_t offset, uint32_t mem_mask) -{ - switch (PXA255_GPIO_BASE_ADDR | (offset << 2)) - { - case PXA255_GPLR0: - { - 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; - } - return 0; -} - -void pxa255_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (PXA255_GPIO_BASE_ADDR | (offset << 2)) - { - 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: - { - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 0: %08x & %08x\n", m_gpio_regs.gedr0, mem_mask); - const uint32_t old = m_gpio_regs.gedr0; - m_gpio_regs.gedr0 &= ~data; - const uint32_t lowered = old & ~m_gpio_regs.gedr0; - if (BIT(lowered, 0)) - set_irq_line(PXA255_INT_GPIO0, 0); - else if (BIT(lowered, 1)) - set_irq_line(PXA255_INT_GPIO1, 0); - else if ((lowered & 0xfffffffc) && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2) - set_irq_line(PXA255_INT_GPIO84_2, 0); - break; - } - case PXA255_GEDR1: - { - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 1: %08x & %08x\n", m_gpio_regs.gedr1, mem_mask); - const uint32_t old = m_gpio_regs.gedr1; - m_gpio_regs.gedr1 &= ~data; - const uint32_t lowered = old & !m_gpio_regs.gedr1; - if (lowered && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2) - set_irq_line(PXA255_INT_GPIO84_2, 0); - break; - } - case PXA255_GEDR2: - { - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Edge Detect Status Register 2: %08x & %08x\n", m_gpio_regs.gedr2, mem_mask); - const uint32_t old = m_gpio_regs.gedr2; - m_gpio_regs.gedr2 &= ~data; - const uint32_t lowered = old & !m_gpio_regs.gedr2; - if (lowered && !m_gpio_regs.gedr0 && !m_gpio_regs.gedr1 && !m_gpio_regs.gedr2) - set_irq_line(PXA255_INT_GPIO84_2, 0); - break; - } - case PXA255_GAFR0_L: - LOGMASKED(LOG_GPIO, "pxa255_gpio_w: GPIO Alternate Function Register 0 Lower: %08x & %08x\n", m_gpio_regs.gafr0l, mem_mask); - m_gpio_regs.gafr0l = data; - 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; - } -} - -/* - - PXA255 LCD Controller - - pg. 265 to 310, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -void pxa255_periphs_device::lcd_load_dma_descriptor(address_space & space, uint32_t address, int channel) -{ - 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); - m_lcd_regs.dma[channel].ldcmd = space.read_dword(address + 0x0c); - LOGMASKED(LOG_LCD_DMA, "lcd_load_dma_descriptor, address = %08x, channel = %d\n", address, channel); - LOGMASKED(LOG_LCD_DMA, " DMA Frame Descriptor: %08x\n", m_lcd_regs.dma[channel].fdadr ); - LOGMASKED(LOG_LCD_DMA, " DMA Frame Source Address: %08x\n", m_lcd_regs.dma[channel].fsadr ); - LOGMASKED(LOG_LCD_DMA, " DMA Frame ID: %08x\n", m_lcd_regs.dma[channel].fidr ); - LOGMASKED(LOG_LCD_DMA, " DMA Command: %08x\n", m_lcd_regs.dma[channel].ldcmd ); -} - -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)) - { - set_irq_line(PXA255_INT_LCD, 1); - } - else - { - set_irq_line(PXA255_INT_LCD, 0); - } -} - -void pxa255_periphs_device::lcd_dma_kickoff(int channel) -{ - 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) - { - m_lcd_regs.liidr = m_lcd_regs.dma[channel].fidr; - m_lcd_regs.lcsr |= PXA255_LCSR_SOF; - lcd_irq_check(); - } - - if (m_lcd_regs.dma[channel].ldcmd & PXA255_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); - 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)); - } - } - else - { - 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++) - { - m_lcd_framebuffer[index] = space.read_byte(m_lcd_regs.dma[channel].fsadr + index); - } - } - } -} - -void pxa255_periphs_device::lcd_check_load_next_branch(int channel) -{ - 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); - 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) - { - m_lcd_regs.fbr[channel] &= ~2; - if (!(m_lcd_regs.lccr0 & PXA255_LCCR0_BM)) - { - m_lcd_regs.lcsr |= PXA255_LCSR_BS; - } - } - } - else - { - LOGMASKED(LOG_LCD_DMA, "pxa255_lcd_check_load_next_branch: Not taking branch\n" ); - } -} - -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 & PXA255_LDCMD_EOFINT) - { - m_lcd_regs.liidr = m_lcd_regs.dma[param].fidr; - m_lcd_regs.lcsr |= PXA255_LCSR_EOF; - } - lcd_check_load_next_branch(param); - lcd_irq_check(); -} - -uint32_t pxa255_periphs_device::lcd_r(offs_t offset, uint32_t 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; -} - -void pxa255_periphs_device::lcd_w(address_space &space, offs_t offset, uint32_t data, uint32_t 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; - } -} - -uint32_t pxa255_periphs_device::power_r(offs_t offset, uint32_t mem_mask) -{ - switch (PXA255_POWER_BASE_ADDR | (offset << 2)) - { - case PXA255_PMCR: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Control Register: %08x\n", machine().describe_context(), m_power_regs.pmcr); - return m_power_regs.pmcr; - case PXA255_PSSR: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Sleep Status Register: %08x\n", machine().describe_context(), m_power_regs.pssr); - return m_power_regs.pssr; - case PXA255_PSPR: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Scratch Pad Register: %08x\n", machine().describe_context(), m_power_regs.pspr); - return m_power_regs.pspr; - case PXA255_PWER: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Wake-up Enable Register: %08x\n", machine().describe_context(), m_power_regs.pwer); - return m_power_regs.pwer; - case PXA255_PRER: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Rising-Edge Detect Enable Register: %08x\n", machine().describe_context(), m_power_regs.prer); - return m_power_regs.prer; - case PXA255_PFER: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Falling-Edge Detect Enable Register: %08x\n", machine().describe_context(), m_power_regs.pfer); - return m_power_regs.pfer; - case PXA255_PEDR: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Edge Detect Status Register: %08x\n", machine().describe_context(), m_power_regs.pedr); - return m_power_regs.pedr; - case PXA255_PCFR: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager General Configuration Register: %08x\n", machine().describe_context(), m_power_regs.pcfr); - return m_power_regs.pcfr; - case PXA255_PGSR0: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[31-0]: %08x\n", machine().describe_context(), m_power_regs.pgsr0); - return m_power_regs.pgsr0; - case PXA255_PGSR1: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[63-32]: %08x\n", machine().describe_context(), m_power_regs.pgsr1); - return m_power_regs.pgsr1; - case PXA255_PGSR2: - LOGMASKED(LOG_POWER, "%s: power_r: Power Manager GPIO Sleep State Register for GP[84-64]: %08x\n", machine().describe_context(), m_power_regs.pgsr2); - return m_power_regs.pgsr2; - case PXA255_RCSR: - LOGMASKED(LOG_POWER, "%s: power_r: Reset Controller Status Register: %08x\n", machine().describe_context(), m_power_regs.rcsr); - return m_power_regs.rcsr; - case PXA255_PMFW: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Fast Sleep Walk-Up Configuration Register: %08x\n", machine().describe_context(), m_power_regs.pmfw); - return m_power_regs.pmfw; - default: - LOGMASKED(LOG_POWER | LOG_UNKNOWN, "%s: power_r: Unknown address: %08x\n", machine().describe_context(), PXA255_POWER_BASE_ADDR | (offset << 2)); - break; - } - return 0; -} - -void pxa255_periphs_device::power_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (PXA255_POWER_BASE_ADDR | (offset << 2)) - { - case PXA255_PMCR: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pmcr); - break; - case PXA255_PSSR: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Sleep Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_power_regs.pssr &= ~(data & 0x00000037); - break; - case PXA255_PSPR: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pspr); - break; - case PXA255_PWER: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Wake-Up Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pwer); - break; - case PXA255_PRER: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Rising-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.prer); - break; - case PXA255_PFER: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Falling-Edge Detect Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pfer); - break; - case PXA255_PEDR: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Edge Detect Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_power_regs.pedr &= ~(data & 0x0000ffff); - break; - case PXA255_PCFR: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager General Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pcfr); - break; - case PXA255_PGSR0: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pgsr0); - break; - case PXA255_PGSR1: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pgsr1); - break; - case PXA255_PGSR2: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager GPIO Sleep State Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pgsr2); - break; - case PXA255_PMFW: - LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Fast Sleep Walk-Up Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_power_regs.pmfw); - break; - default: - LOGMASKED(LOG_POWER | LOG_UNKNOWN, "%s: power_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PXA255_POWER_BASE_ADDR | (offset << 2), - data, mem_mask); - break; - } -} - -/* - PXA255 Clock controller - - pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -uint32_t pxa255_periphs_device::clocks_r(offs_t offset, uint32_t mem_mask) -{ - switch (PXA255_CLOCKS_BASE_ADDR | (offset << 2)) - { - case PXA255_CCCR: - LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Core Clock Configuration Register: %08x\n", machine().describe_context(), m_clocks_regs.cccr); - return m_clocks_regs.cccr; - case PXA255_CKEN: - LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Clock Enable Register: %08x\n", machine().describe_context(), m_clocks_regs.cken); - return m_clocks_regs.cken; - case PXA255_OSCC: - LOGMASKED(LOG_CLOCKS, "%s: clocks_r: Oscillator Configuration Register: %08x\n", machine().describe_context(), m_clocks_regs.oscc); - return BIT(m_clocks_regs.oscc, 0); - default: - LOGMASKED(LOG_CLOCKS | LOG_UNKNOWN, "%s: clocks_r: Unknown address: %08x\n", machine().describe_context(), PXA255_CLOCKS_BASE_ADDR | (offset << 2)); - break; - } - return 0; -} - -void pxa255_periphs_device::clocks_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (PXA255_CLOCKS_BASE_ADDR | (offset << 2)) - { - case PXA255_CCCR: - LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Core Clock Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_clocks_regs.cccr); - break; - case PXA255_CKEN: - LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Clock Enable Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_clocks_regs.cken); - break; - case PXA255_OSCC: - LOGMASKED(LOG_CLOCKS, "%s: clocks_w: Oscillator Configuration Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); - if (BIT(data, 1)) - { - m_clocks_regs.oscc |= 0x00000003; - } - break; - default: - LOGMASKED(LOG_CLOCKS | LOG_UNKNOWN, "%s: clocks_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PXA255_CLOCKS_BASE_ADDR | (offset << 2), - data, mem_mask); - break; - } + 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() @@ -1517,9 +221,9 @@ void pxa255_periphs_device::device_start() 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(0x100); - m_lcd_framebuffer = make_unique_clear(0x100000); - m_samples = make_unique_clear(0x1000); + m_lcd_palette = make_unique_clear(0x100); + m_lcd_framebuffer = make_unique_clear(0x100000); + m_samples = make_unique_clear(0x1000); m_rtc_regs.timer = timer_alloc(FUNC(pxa255_periphs_device::rtc_tick), this); } @@ -1542,21 +246,9 @@ void pxa255_periphs_device::device_reset() 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_clocks_regs, 0, sizeof(m_clocks_regs)); -} - -uint32_t pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - 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; + memset(&m_clk_regs, 0, sizeof(m_clk_regs)); } void pxa255_periphs_device::device_add_mconfig(machine_config &config) @@ -1576,3 +268,1538 @@ void pxa255_periphs_device::device_add_mconfig(machine_config &config) 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 + + pg. 489 to 504, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +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) +{ + 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) + { + m_i2s_regs.sasr0 &= ~SASR0_ROR; + } + if (m_i2s_regs.saicr & SAICR_TUR) + { + m_i2s_regs.sasr0 &= ~SASR0_TUR; + } +} + +u32 pxa255_periphs_device::i2s_sadiv_r(offs_t offset, u32 mem_mask) +{ + 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++) + { + 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 + + pg. 151 to 182, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +void pxa255_periphs_device::dma_irq_check() +{ + int set_irq = 0; + for (int channel = 0; channel < 16; channel++) + { + if (m_dma_regs.dcsr[channel] & (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR)) + { + m_dma_regs.dint |= 1 << channel; + set_irq = 1; + } + else + { + m_dma_regs.dint &= ~(1 << channel); + } + } + + set_irq_line(INT_DMA, set_irq); +} + +void pxa255_periphs_device::dma_load_descriptor_and_start(int channel) +{ + // Shut down any transfers that are currently going on, software should be smart enough to check if a + // transfer is running before starting another one on the same channel. + if (m_dma_regs.timer[channel]->enabled()) + { + m_dma_regs.timer[channel]->adjust(attotime::never); + } + + // 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); + m_dma_regs.dcmd[channel] = space.read_dword(m_dma_regs.ddadr[channel] + 0xc); + m_dma_regs.ddadr[channel] = space.read_dword(m_dma_regs.ddadr[channel]); + + // Start our end-of-transfer timer + 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); + break; + default: + m_dma_regs.timer[channel]->adjust(attotime::from_hz(100000000) * (m_dma_regs.dcmd[channel] & 0x00001fff), channel); + break; + } + + // Interrupt as necessary + if (m_dma_regs.dcmd[channel] & DCMD_STARTIRQEN) + { + m_dma_regs.dcsr[channel] |= DCSR_STARTINTR; + } + + m_dma_regs.dcsr[channel] &= ~DCSR_STOPSTATE; +} + +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::audio_dma_end_tick) +{ + 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); + 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) + { + 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; + } + } + + dma_finish(param); +} + +void pxa255_periphs_device::dma_finish(int channel) +{ + if (m_dma_regs.dcmd[channel] & DCMD_ENDIRQEN) + { + m_dma_regs.dcsr[channel] |= DCSR_ENDINTR; + } + + if (!(m_dma_regs.ddadr[channel] & DDADR_STOP) && (m_dma_regs.dcsr[channel] & DCSR_RUN)) + { + if (m_dma_regs.dcsr[channel] & DCSR_RUN) + { + dma_load_descriptor_and_start(channel); + } + else + { + m_dma_regs.dcsr[channel] &= ~DCSR_RUN; + m_dma_regs.dcsr[channel] |= DCSR_STOPSTATE; + } + } + else + { + m_dma_regs.dcsr[channel] &= ~DCSR_RUN; + m_dma_regs.dcsr[channel] |= DCSR_STOPSTATE; + } + + dma_irq_check(); +} + +u32 pxa255_periphs_device::dma_dcsr_r(offs_t offset, u32 mem_mask) +{ + 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_dcsr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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)) + { + 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_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 +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 +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 +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 +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 +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 +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 +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 +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 + + pg. 132 to 138, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +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(INT_RTC_HZ, 1); + } + + if (m_rtc_regs.rcnr == m_rtc_regs.rtar) + { + if (BIT(m_rtc_regs.rtsr, 2)) + { + m_rtc_regs.rtsr |= (1 << 0); + set_irq_line(INT_RTC_ALARM, 1); + } + } +} + +u32 pxa255_periphs_device::rtc_rcnr_r(offs_t offset, u32 mem_mask) +{ + 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_rcnr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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)) + { + COMBINE_DATA(&m_rtc_regs.rttr); + } +} + + +/* + + PXA255 OS Timer register + + pg. 138 to 142, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +void pxa255_periphs_device::ostimer_irq_check() +{ + 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); +} + +TIMER_CALLBACK_MEMBER(pxa255_periphs_device::ostimer_match_tick) +{ + m_ostimer_regs.ossr |= (1 << param); + m_ostimer_regs.oscr = m_ostimer_regs.osmr[param]; + ostimer_irq_check(); +} + +template +void pxa255_periphs_device::ostimer_update_interrupts() +{ + if ((m_ostimer_regs.oier & (OIER_E0 << Which)) && Which != 3) + { + m_ostimer_regs.timer[Which]->adjust(attotime::from_hz(3846400) * (m_ostimer_regs.osmr[Which] - m_ostimer_regs.oscr), Which); + } +} + +void pxa255_periphs_device::ostimer_update_count() +{ + 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 +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 +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(); +} + +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 + + pg. 124 to 132, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +void pxa255_periphs_device::update_interrupts() +{ + m_intc_regs.icfp = (m_intc_regs.icpr & m_intc_regs.icmr) & m_intc_regs.iclr; + m_intc_regs.icip = (m_intc_regs.icpr & m_intc_regs.icmr) & (~m_intc_regs.iclr); + m_maincpu->set_input_line(ARM7_FIRQ_LINE, m_intc_regs.icfp ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(ARM7_IRQ_LINE, m_intc_regs.icip ? ASSERT_LINE : CLEAR_LINE); +} + +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(); +} + +u32 pxa255_periphs_device::intc_icip_r(offs_t offset, u32 mem_mask) +{ + 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_icip_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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 + + pg. 105 to 124, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +template +void pxa255_periphs_device::update_gpio_outputs(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]); + const u32 changed = old ^ new_data; + if (changed == 0) + return; + + for (u32 bit = 0; bit < 32; bit++) + { + 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 +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: Rising %08x, Falling %08x\n", rising, falling); + + 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: 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; + + for (u32 bit = 0; bit < 32; bit++) + { + if (!BIT(changed_gedr, bit)) + continue; + + LOGMASKED(LOG_GPIO, "pxa255: Edge detected on GPIO%d Pin %d\n", Which, bit); + if (Which == 0) + { + if (bit > 1) + set_irq_line(INT_GPIO84_2, 1); + else if (bit == 1) + set_irq_line(INT_GPIO1, 1); + else + set_irq_line(INT_GPIO0, 1); + } + else if (Which == 1) + { + set_irq_line(INT_GPIO84_2, 1); + } + else if (Which == 2) + { + set_irq_line(INT_GPIO84_2, 1); + } + } +} + +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 +void pxa255_periphs_device::gpio_in(int state) +{ + LOGMASKED(LOG_GPIO, "pxa255: GPIO Pin %d written: %d\n", Bit, state); + + 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 +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 +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 +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 +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 +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 +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); + } +} + +template +u32 pxa255_periphs_device::gpio_gpcr_r(offs_t offset, u32 mem_mask) +{ + 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 +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++) + { + if (BIT(cleared, i)) + m_gpio_w[Which * 32 + i](0); + } +} + +template +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 +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 +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 +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 +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 +void pxa255_periphs_device::gpio_gedr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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) + { + if (BIT(lowered, 0)) + { + set_irq_line(INT_GPIO0, 0); + return; + } + else if (BIT(lowered, 1)) + { + set_irq_line(INT_GPIO1, 0); + return; + } + else if (!(lowered & 0xfffffffc)) + { + return; + } + } + + if (!m_gpio_regs.gedr[0] && !m_gpio_regs.gedr[1] && !m_gpio_regs.gedr[2]) + set_irq_line(INT_GPIO84_2, 0); +} + +template +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 +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 +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 +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 + + pg. 265 to 310, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +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); + m_lcd_regs.dma[channel].ldcmd = space.read_dword(address + 0x0c); + LOGMASKED(LOG_LCD_DMA, "lcd_load_dma_descriptor, address = %08x, channel = %d\n", address, channel); + LOGMASKED(LOG_LCD_DMA, " DMA Frame Descriptor: %08x\n", m_lcd_regs.dma[channel].fdadr ); + LOGMASKED(LOG_LCD_DMA, " DMA Frame Source Address: %08x\n", m_lcd_regs.dma[channel].fsadr ); + LOGMASKED(LOG_LCD_DMA, " DMA Frame ID: %08x\n", m_lcd_regs.dma[channel].fidr ); + LOGMASKED(LOG_LCD_DMA, " DMA Command: %08x\n", m_lcd_regs.dma[channel].ldcmd ); +} + +void pxa255_periphs_device::lcd_irq_check() +{ + 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(INT_LCD, 1); + } + else + { + set_irq_line(INT_LCD, 0); + } +} + +void pxa255_periphs_device::lcd_dma_kickoff(int channel) +{ + 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 & LDCMD_SOFINT) + { + m_lcd_regs.liidr = m_lcd_regs.dma[channel].fidr; + m_lcd_regs.lcsr |= LCSR_SOF; + lcd_irq_check(); + } + + 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) + { + 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)); + } + } + else + { + 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++) + { + m_lcd_framebuffer[index] = space.read_byte(m_lcd_regs.dma[channel].fsadr + index); + } + } + } +} + +void pxa255_periphs_device::lcd_check_load_next_branch(int channel) +{ + 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); + 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) + { + m_lcd_regs.fbr[channel] &= ~2; + if (!(m_lcd_regs.lccr[0] & LCCR0_BM)) + { + m_lcd_regs.lcsr |= LCSR_BS; + } + } + } + else + { + LOGMASKED(LOG_LCD_DMA, "lcd_check_load_next_branch: Not taking branch\n" ); + } +} + +template +u32 pxa255_periphs_device::lcd_lccr_r(offs_t offset, u32 mem_mask) +{ + 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 +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 +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 +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()) + { + LOGMASKED(LOG_LCD, "ch%d EOF timer is not enabled, taking branch now\n", Which); + lcd_check_load_next_branch(Which); + lcd_irq_check(); + } +} + +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(); +} + +u32 pxa255_periphs_device::lcd_liidr_r(offs_t offset, u32 mem_mask) +{ + 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_liidr_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOGMASKED(LOG_LCD, "%s: lcd_liidr_w: LCD Interrupt ID Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); +} + +u32 pxa255_periphs_device::lcd_trgbr_r(offs_t offset, u32 mem_mask) +{ + 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; +} + +template +u32 pxa255_periphs_device::lcd_fdadr_r(offs_t offset, u32 mem_mask) +{ + 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 +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()) + { + lcd_load_dma_descriptor(data & 0xfffffff0, Which); + } + else + { + m_lcd_regs.fbr[Which] &= 0x00000003; + m_lcd_regs.fbr[Which] |= data & 0xfffffff0; + } +} + +template +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 +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 +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 +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 +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 +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 Power Controller + + pg. 85 to 96, PXA255 Processor Developers Manual [278693-002].pdf + +*/ + +u32 pxa255_periphs_device::pwr_pmcr_r(offs_t offset, u32 mem_mask) +{ + 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::pwr_pmcr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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); +} + +u32 pxa255_periphs_device::pwr_pssr_r(offs_t offset, u32 mem_mask) +{ + 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; +} + +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); +} + +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; +} + +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); +} + +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; +} + +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); +} + +u32 pxa255_periphs_device::pwr_prer_r(offs_t offset, u32 mem_mask) +{ + 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; +} + +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); +} + +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; +} + +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); +} + +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::pwr_pedr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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); +} + +u32 pxa255_periphs_device::pwr_pcfr_r(offs_t offset, u32 mem_mask) +{ + 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::pwr_pcfr_w(offs_t offset, u32 data, u32 mem_mask) +{ + 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); +} + +template +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; +} + +template +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]); +} + +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; + } +} diff --git a/src/devices/machine/pxa255.h b/src/devices/machine/pxa255.h index 75eadbac2c5..3cc9b43c8a9 100644 --- a/src/devices/machine/pxa255.h +++ b/src/devices/machine/pxa255.h @@ -19,253 +19,461 @@ #include "sound/dmadac.h" #include "emupal.h" -#include "pxa255defs.h" - class pxa255_periphs_device : public device_t { public: template - pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag) + pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&cpu_tag) : pxa255_periphs_device(mconfig, tag, owner, clock) { m_maincpu.set_tag(std::forward(cpu_tag)); } - pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + pxa255_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - auto gpio0_write() { return m_gpio0_w.bind(); } - auto gpio0_read() { return m_gpio0_r.bind(); } - auto gpio1_write() { return m_gpio1_w.bind(); } - auto gpio1_read() { return m_gpio1_r.bind(); } - auto gpio2_write() { return m_gpio2_w.bind(); } - auto gpio2_read() { return m_gpio2_r.bind(); } + template auto gpio_out() { return m_gpio_w[Bit].bind(); } + template void gpio_in(int state); - uint32_t dma_r(offs_t offset, uint32_t mem_mask = ~0); - void dma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t i2s_r(offs_t offset, uint32_t mem_mask = ~0); - void i2s_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t rtc_r(offs_t offset, uint32_t mem_mask = ~0); - void rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t ostimer_r(offs_t offset, uint32_t mem_mask = ~0); - void ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t intc_r(offs_t offset, uint32_t mem_mask = ~0); - void intc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void gpio_bit_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0); - uint32_t gpio_r(offs_t offset, uint32_t mem_mask = ~0); - void gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t lcd_r(offs_t offset, uint32_t mem_mask = ~0); - void lcd_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t power_r(offs_t offset, uint32_t mem_mask = ~0); - void power_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t clocks_r(offs_t offset, uint32_t mem_mask = ~0); - void clocks_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + void map(address_map &map); + + // gpio_bit_w protected: virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; + static constexpr u32 INTERNAL_OSC = 3686400; + + // DMA Hardware void dma_irq_check(); void dma_load_descriptor_and_start(int channel); - void ostimer_irq_check(); - void update_interrupts(); - void lcd_load_dma_descriptor(address_space & space, uint32_t address, int channel); - void lcd_irq_check(); - void lcd_dma_kickoff(int channel); - void lcd_check_load_next_branch(int channel); - - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - TIMER_CALLBACK_MEMBER(dma_end_tick); TIMER_CALLBACK_MEMBER(audio_dma_end_tick); - TIMER_CALLBACK_MEMBER(ostimer_match_tick); - TIMER_CALLBACK_MEMBER(lcd_dma_eof_tick); - TIMER_CALLBACK_MEMBER(rtc_tick); - + TIMER_CALLBACK_MEMBER(dma_end_tick); void dma_finish(int channel); - void set_irq_line(uint32_t line, int state); + + u32 dma_dcsr_r(offs_t offset, u32 mem_mask); + void dma_dcsr_w(offs_t offset, u32 data, u32 mem_mask); + u32 dma_dint_r(offs_t offset, u32 mem_mask); + void dma_dint_w(offs_t offset, u32 data, u32 mem_mask); + u32 dma_drcmr_r(offs_t offset, u32 mem_mask); + void dma_drcmr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 dma_ddadr_r(offs_t offset, u32 mem_mask); + template void dma_ddadr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 dma_dsadr_r(offs_t offset, u32 mem_mask); + template void dma_dsadr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 dma_dtadr_r(offs_t offset, u32 mem_mask); + template void dma_dtadr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 dma_dcmd_r(offs_t offset, u32 mem_mask); + template void dma_dcmd_w(offs_t offset, u32 data, u32 mem_mask); + + enum dma_bits_t : u32 + { + DCSR_BUSERRINTR = 1u << 0, + DCSR_STARTINTR = 1u << 1, + DCSR_ENDINTR = 1u << 2, + DCSR_STOPSTATE = 1u << 3, + DCSR_REQPEND = 1u << 8, + DCSR_STOPIRQ = 1u << 29, + DCSR_NODESCFETCH = 1u << 30, + DCSR_RUN = 1u << 31, + + DDADR_STOP = 1u << 0, + + DCMD_INCSRCADDR = 1u << 31, + DCMD_INCTRGADDR = 1u << 30, + DCMD_STARTIRQEN = 1u << 22, + DCMD_ENDIRQEN = 1u << 21, + DCMD_SIZE_SHIFT = 16, + DCMD_SIZE_MASK = 3, + DCMD_SIZE_0 = 0, + DCMD_SIZE_8 = 1, + DCMD_SIZE_16 = 2, + DCMD_SIZE_32 = 3 + }; struct dma_regs { - uint32_t dcsr[16]; - uint32_t pad0[44]; + u32 dcsr[16]; + u32 dint; + u32 drcmr[40]; - uint32_t dint; - uint32_t pad1[3]; - - uint32_t drcmr[40]; - uint32_t pad2[24]; - - uint32_t ddadr[16]; - uint32_t dsadr[16]; - uint32_t dtadr[16]; - uint32_t dcmd[16]; + u32 ddadr[16]; + u32 dsadr[16]; + u32 dtadr[16]; + u32 dcmd[16]; emu_timer* timer[16]; }; - struct i2s_regs - { - uint32_t sacr0; - uint32_t sacr1; - uint32_t pad0; + dma_regs m_dma_regs; - uint32_t sasr0; - uint32_t pad1; - - uint32_t saimr; - uint32_t saicr; - uint32_t pad2[17]; - - uint32_t sadiv; - uint32_t pad3[6]; - - uint32_t sadr; - }; + // RTC Hardware + TIMER_CALLBACK_MEMBER(rtc_tick); + u32 rtc_rcnr_r(offs_t offset, u32 mem_mask); + void rtc_rcnr_w(offs_t offset, u32 data, u32 mem_mask); + u32 rtc_rtar_r(offs_t offset, u32 mem_mask); + void rtc_rtar_w(offs_t offset, u32 data, u32 mem_mask); + u32 rtc_rtsr_r(offs_t offset, u32 mem_mask); + void rtc_rtsr_w(offs_t offset, u32 data, u32 mem_mask); + u32 rtc_rttr_r(offs_t offset, u32 mem_mask); + void rtc_rttr_w(offs_t offset, u32 data, u32 mem_mask); struct rtc_regs { - uint32_t rcnr; - uint32_t rtar; - uint32_t rtsr; - uint32_t rttr; + u32 rcnr; + u32 rtar; + u32 rtsr; + u32 rttr; emu_timer *timer; }; + rtc_regs m_rtc_regs; + + // I2S (Audio) Hardware + u32 i2s_sacr0_r(offs_t offset, u32 mem_mask); + void i2s_sacr0_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_sacr1_r(offs_t offset, u32 mem_mask); + void i2s_sacr1_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_sasr0_r(offs_t offset, u32 mem_mask); + void i2s_sasr0_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_saimr_r(offs_t offset, u32 mem_mask); + void i2s_saimr_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_saicr_r(offs_t offset, u32 mem_mask); + void i2s_saicr_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_sadiv_r(offs_t offset, u32 mem_mask); + void i2s_sadiv_w(offs_t offset, u32 data, u32 mem_mask); + u32 i2s_sadr_r(offs_t offset, u32 mem_mask); + void i2s_sadr_w(offs_t offset, u32 data, u32 mem_mask); + + enum i2s_bits_t : u32 + { + SASR0_TNF = 1u << 0, + SASR0_RNE = 1u << 1, + SASR0_BSY = 1u << 2, + SASR0_TFS = 1u << 3, + SASR0_RFS = 1u << 4, + SASR0_TUR = 1u << 5, + SASR0_ROR = 1u << 6, + SASR0_TFL = 15u << 8, + SASR0_RFL = 15u << 12, + + SAICR_TUR = 1u << 5, + SAICR_ROR = 1u << 6, + }; + + struct i2s_regs + { + u32 sacr0; + u32 sacr1; + u32 sasr0; + u32 saimr; + u32 saicr; + u32 sadiv; + u32 sadr; + }; + + i2s_regs m_i2s_regs; + + // Timer Hardware + void ostimer_irq_check(); + TIMER_CALLBACK_MEMBER(ostimer_match_tick); + template void ostimer_update_interrupts(); + void ostimer_update_count(); + + template u32 tmr_osmr_r(offs_t offset, u32 mem_mask); + template void tmr_osmr_w(offs_t offset, u32 data, u32 mem_mask); + u32 tmr_oscr_r(offs_t offset, u32 mem_mask); + void tmr_oscr_w(offs_t offset, u32 data, u32 mem_mask); + u32 tmr_ossr_r(offs_t offset, u32 mem_mask); + void tmr_ossr_w(offs_t offset, u32 data, u32 mem_mask); + u32 tmr_ower_r(offs_t offset, u32 mem_mask); + void tmr_ower_w(offs_t offset, u32 data, u32 mem_mask); + u32 tmr_oier_r(offs_t offset, u32 mem_mask); + void tmr_oier_w(offs_t offset, u32 data, u32 mem_mask); + + enum tmr_bits_t : u32 + { + OSSR_M0 = 1u << 0, + OSSR_M1 = 1u << 1, + OSSR_M2 = 1u << 2, + OSSR_M3 = 1u << 3, + + OIER_E0 = 1u << 0, + OIER_E1 = 1u << 1, + OIER_E2 = 1u << 2, + OIER_E3 = 1u << 3 + }; + struct ostmr_regs { - uint32_t osmr[4]; - uint32_t oscr; - uint32_t ossr; - uint32_t ower; - uint32_t oier; + u32 osmr[4]; + u32 oscr; + u32 ossr; + u32 ower; + u32 oier; emu_timer* timer[4]; + attotime last_count_sync; }; + ostmr_regs m_ostimer_regs; + + // Interrupt Hardware + enum intc_bits_t : u32 + { + INT_HUART = 1u << 7, + INT_GPIO0 = 1u << 8, + INT_GPIO1 = 1u << 9, + INT_GPIO84_2 = 1u << 10, + INT_USB = 1u << 11, + INT_PMU = 1u << 12, + INT_I2S = 1u << 13, + INT_AC97 = 1u << 14, + INT_NETWORK = 1u << 16, + INT_LCD = 1u << 17, + INT_I2C = 1u << 18, + INT_ICP = 1u << 19, + INT_STUART = 1u << 20, + INT_BTUART = 1u << 21, + INT_FFUART = 1u << 22, + INT_MMC = 1u << 23, + INT_SSP = 1u << 24, + INT_DMA = 1u << 25, + INT_OSTIMER0 = 1u << 26, + INT_OSTIMER1 = 1u << 27, + INT_OSTIMER2 = 1u << 28, + INT_OSTIMER3 = 1u << 29, + INT_RTC_HZ = 1u << 30, + INT_RTC_ALARM = 1u << 31 + }; + + void update_interrupts(); + u32 intc_icip_r(offs_t offset, u32 mem_mask); + void intc_icip_w(offs_t offset, u32 data, u32 mem_mask); + u32 intc_icmr_r(offs_t offset, u32 mem_mask); + void intc_icmr_w(offs_t offset, u32 data, u32 mem_mask); + u32 intc_iclr_r(offs_t offset, u32 mem_mask); + void intc_iclr_w(offs_t offset, u32 data, u32 mem_mask); + u32 intc_icfp_r(offs_t offset, u32 mem_mask); + void intc_icfp_w(offs_t offset, u32 data, u32 mem_mask); + u32 intc_icpr_r(offs_t offset, u32 mem_mask); + void intc_icpr_w(offs_t offset, u32 data, u32 mem_mask); + u32 intc_iccr_r(offs_t offset, u32 mem_mask); + void intc_iccr_w(offs_t offset, u32 data, u32 mem_mask); + struct intc_regs { - uint32_t icip; - uint32_t icmr; - uint32_t iclr; - uint32_t icfp; - uint32_t icpr; - uint32_t iccr; + u32 icip; + u32 icmr; + u32 iclr; + u32 icfp; + u32 icpr; + u32 iccr; }; + intc_regs m_intc_regs; + + // GPIO Hardware + template void update_gpio_outputs(const u32 old); + template void check_gpio_irqs(const u32 old); + template u32 gpio_gplr_r(offs_t offset, u32 mem_mask); + template void gpio_gplr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gpdr_r(offs_t offset, u32 mem_mask); + template void gpio_gpdr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gpsr_r(offs_t offset, u32 mem_mask); + template void gpio_gpsr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gpcr_r(offs_t offset, u32 mem_mask); + template void gpio_gpcr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_grer_r(offs_t offset, u32 mem_mask); + template void gpio_grer_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gfer_r(offs_t offset, u32 mem_mask); + template void gpio_gfer_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gedr_r(offs_t offset, u32 mem_mask); + template void gpio_gedr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gafrl_r(offs_t offset, u32 mem_mask); + template void gpio_gafrl_w(offs_t offset, u32 data, u32 mem_mask); + template u32 gpio_gafru_r(offs_t offset, u32 mem_mask); + template void gpio_gafru_w(offs_t offset, u32 data, u32 mem_mask); + struct gpio_regs { - uint32_t gplr0; // GPIO Pin-Level - uint32_t gplr1; - uint32_t gplr2; + u32 gpdr[3]; + u32 gpsr[3]; + u32 gpcr[3]; + u32 grer[3]; + u32 gfer[3]; + u32 gedr[3]; + u32 gafrl[3]; + u32 gafru[3]; + u32 out_data[3]; // Output data + u32 in_data[3]; // Input data + }; - uint32_t gpdr0; - uint32_t gpdr1; - uint32_t gpdr2; + gpio_regs m_gpio_regs; - uint32_t gpsr0; - uint32_t gpsr1; - uint32_t gpsr2; + // LCD Hardware + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - uint32_t gpcr0; - uint32_t gpcr1; - uint32_t gpcr2; + TIMER_CALLBACK_MEMBER(lcd_dma_eof_tick); + void lcd_load_dma_descriptor(u32 address, int channel); + void lcd_irq_check(); + void lcd_dma_kickoff(int channel); + void lcd_check_load_next_branch(int channel); - uint32_t grer0; - uint32_t grer1; - uint32_t grer2; + template u32 lcd_lccr_r(offs_t offset, u32 mem_mask); + template void lcd_lccr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 lcd_fbr_r(offs_t offset, u32 mem_mask); + template void lcd_fbr_w(offs_t offset, u32 data, u32 mem_mask); + u32 lcd_lcsr_r(offs_t offset, u32 mem_mask); + void lcd_lcsr_w(offs_t offset, u32 data, u32 mem_mask); + u32 lcd_liidr_r(offs_t offset, u32 mem_mask); + void lcd_liidr_w(offs_t offset, u32 data, u32 mem_mask); + u32 lcd_trgbr_r(offs_t offset, u32 mem_mask); + void lcd_trgbr_w(offs_t offset, u32 data, u32 mem_mask); + u32 lcd_tcr_r(offs_t offset, u32 mem_mask); + void lcd_tcr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 lcd_fdadr_r(offs_t offset, u32 mem_mask); + template void lcd_fdadr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 lcd_fsadr_r(offs_t offset, u32 mem_mask); + template void lcd_fsadr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 lcd_fidr_r(offs_t offset, u32 mem_mask); + template void lcd_fidr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 lcd_ldcmd_r(offs_t offset, u32 mem_mask); + template void lcd_ldcmd_w(offs_t offset, u32 data, u32 mem_mask); - uint32_t gfer0; - uint32_t gfer1; - uint32_t gfer2; + enum lcd_bits_t : u32 + { + LCCR0_ENB = 1u << 0, + LCCR0_CMS = 1u << 1, + LCCR0_SDS = 1u << 2, + LCCR0_LDM = 1u << 3, + LCCR0_SFM = 1u << 4, + LCCR0_IUM = 1u << 5, + LCCR0_EFM = 1u << 6, + LCCR0_PAS = 1u << 7, + LCCR0_DPD = 1u << 9, + LCCR0_DIS = 1u << 10, + LCCR0_QDM = 1u << 11, + LCCR0_PDD = 0xff << 12, + LCCR0_BM = 1u << 20, + LCCR0_OUM = 1u << 21, - uint32_t gedr0; - uint32_t gedr1; - uint32_t gedr2; + LCCR1_PPL = 0x000003ff, - uint32_t gafr0l; - uint32_t gafr0u; - uint32_t gafr1l; - uint32_t gafr1u; - uint32_t gafr2l; - uint32_t gafr2u; + LCCR2_LPP = 0x000003ff, + + LCSR_LDD = 1u << 0, + LCSR_SOF = 1u << 1, + LCSR_BER = 1u << 2, + LCSR_ABC = 1u << 3, + LCSR_IUL = 1u << 4, + LCSR_IUU = 1u << 5, + LCSR_OU = 1u << 6, + LCSR_QD = 1u << 7, + LCSR_EOF = 1u << 8, + LCSR_BS = 1u << 9, + LCSR_SINT = 1u << 10, + + LDCMD_EOFINT = 1u << 21, + LDCMD_SOFINT = 1u << 22, + LDCMD_PAL = 1u << 26 }; struct lcd_dma_regs { - uint32_t fdadr; - uint32_t fsadr; - uint32_t fidr; - uint32_t ldcmd; + u32 fdadr; + u32 fsadr; + u32 fidr; + u32 ldcmd; emu_timer *eof; }; struct lcd_regs { - uint32_t lccr0; - uint32_t lccr1; - uint32_t lccr2; - uint32_t lccr3; + u32 lccr[4]; - uint32_t fbr[2]; + u32 fbr[2]; - uint32_t lcsr; - uint32_t liidr; - uint32_t trgbr; - uint32_t tcr; + u32 lcsr; + u32 liidr; + u32 trgbr; + u32 tcr; lcd_dma_regs dma[2]; }; + lcd_regs m_lcd_regs; + + // Power Management Hardware + u32 pwr_pmcr_r(offs_t offset, u32 mem_mask); + void pwr_pmcr_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pssr_r(offs_t offset, u32 mem_mask); + void pwr_pssr_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pspr_r(offs_t offset, u32 mem_mask); + void pwr_pspr_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pwer_r(offs_t offset, u32 mem_mask); + void pwr_pwer_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_prer_r(offs_t offset, u32 mem_mask); + void pwr_prer_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pfer_r(offs_t offset, u32 mem_mask); + void pwr_pfer_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pedr_r(offs_t offset, u32 mem_mask); + void pwr_pedr_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_pcfr_r(offs_t offset, u32 mem_mask); + void pwr_pcfr_w(offs_t offset, u32 data, u32 mem_mask); + template u32 pwr_pgsr_r(offs_t offset, u32 mem_mask); + template void pwr_pgsr_w(offs_t offset, u32 data, u32 mem_mask); + u32 pwr_rcsr_r(offs_t offset, u32 mem_mask); + u32 pwr_pmfw_r(offs_t offset, u32 mem_mask); + void pwr_pmfw_w(offs_t offset, u32 data, u32 mem_mask); + struct power_regs { - uint32_t pmcr; - uint32_t pssr; - uint32_t pspr; - uint32_t pwer; - uint32_t prer; - uint32_t pfer; - uint32_t pedr; - uint32_t pcfr; - uint32_t pgsr0; - uint32_t pgsr1; - uint32_t pgsr2; - uint32_t rcsr; - uint32_t pmfw; + u32 pmcr; + u32 pssr; + u32 pspr; + u32 pwer; + u32 prer; + u32 pfer; + u32 pedr; + u32 pcfr; + u32 pgsr[3]; + u32 rcsr; + u32 pmfw; }; - struct clocks_regs - { - uint32_t cccr; - uint32_t cken; - uint32_t oscc; - }; - - dma_regs m_dma_regs; - i2s_regs m_i2s_regs; - rtc_regs m_rtc_regs; - ostmr_regs m_ostimer_regs; - intc_regs m_intc_regs; - gpio_regs m_gpio_regs; - lcd_regs m_lcd_regs; power_regs m_power_regs; - clocks_regs m_clocks_regs; - devcb_write32 m_gpio0_w; - devcb_write32 m_gpio1_w; - devcb_write32 m_gpio2_w; - devcb_read32 m_gpio0_r; - devcb_read32 m_gpio1_r; - devcb_read32 m_gpio2_r; + // System Clock Hardware + u32 clk_cccr_r(offs_t offset, u32 mem_mask); + void clk_cccr_w(offs_t offset, u32 data, u32 mem_mask); + u32 clk_cken_r(offs_t offset, u32 mem_mask); + void clk_cken_w(offs_t offset, u32 data, u32 mem_mask); + u32 clk_oscc_r(offs_t offset, u32 mem_mask); + void clk_oscc_w(offs_t offset, u32 data, u32 mem_mask); + + struct clk_regs + { + u32 cccr; + u32 cken; + u32 oscc; + }; + + clk_regs m_clk_regs; + + void set_irq_line(u32 line, int state); + + devcb_write_line::array<96> m_gpio_w; required_device m_maincpu; required_device_array m_dmadac; required_device m_palette; - std::unique_ptr m_lcd_palette; // 0x100 - std::unique_ptr m_lcd_framebuffer; // 0x100000 - std::unique_ptr m_samples; // 0x1000 + std::unique_ptr m_lcd_palette; // 0x100 + std::unique_ptr m_lcd_framebuffer; // 0x100000 + std::unique_ptr m_samples; // 0x1000 }; DECLARE_DEVICE_TYPE(PXA255_PERIPHERALS, pxa255_periphs_device) diff --git a/src/devices/machine/pxa255defs.h b/src/devices/machine/pxa255defs.h deleted file mode 100644 index 424eeb0c53c..00000000000 --- a/src/devices/machine/pxa255defs.h +++ /dev/null @@ -1,427 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz -/************************************************************************** - * - * Intel XScale PXA255 peripheral emulation defines - * - **************************************************************************/ - -#ifndef MAME_MACHINE_PXA255DEFS -#define MAME_MACHINE_PXA255DEFS - -#pragma once - -/* - PXA255 DMA controller - - pg. 151 to 182, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_DMA_BASE_ADDR (0x40000000) -#define PXA255_DCSR0 (PXA255_DMA_BASE_ADDR + 0x00000000) -#define PXA255_DCSR1 (PXA255_DMA_BASE_ADDR + 0x00000004) -#define PXA255_DCSR2 (PXA255_DMA_BASE_ADDR + 0x00000008) -#define PXA255_DCSR3 (PXA255_DMA_BASE_ADDR + 0x0000000c) -#define PXA255_DCSR4 (PXA255_DMA_BASE_ADDR + 0x00000010) -#define PXA255_DCSR5 (PXA255_DMA_BASE_ADDR + 0x00000014) -#define PXA255_DCSR6 (PXA255_DMA_BASE_ADDR + 0x00000018) -#define PXA255_DCSR7 (PXA255_DMA_BASE_ADDR + 0x0000001c) -#define PXA255_DCSR8 (PXA255_DMA_BASE_ADDR + 0x00000020) -#define PXA255_DCSR9 (PXA255_DMA_BASE_ADDR + 0x00000024) -#define PXA255_DCSR10 (PXA255_DMA_BASE_ADDR + 0x00000028) -#define PXA255_DCSR11 (PXA255_DMA_BASE_ADDR + 0x0000002c) -#define PXA255_DCSR12 (PXA255_DMA_BASE_ADDR + 0x00000030) -#define PXA255_DCSR13 (PXA255_DMA_BASE_ADDR + 0x00000034) -#define PXA255_DCSR14 (PXA255_DMA_BASE_ADDR + 0x00000038) -#define PXA255_DCSR15 (PXA255_DMA_BASE_ADDR + 0x0000003c) - #define PXA255_DCSR_RUN (0x80000000) - #define PXA255_DCSR_NODESCFETCH (0x40000000) - #define PXA255_DCSR_STOPIRQ (0x20000000) - #define PXA255_DCSR_REQPEND (0x00000100) - #define PXA255_DCSR_STOPSTATE (0x00000008) - #define PXA255_DCSR_ENDINTR (0x00000004) - #define PXA255_DCSR_STARTINTR (0x00000002) - #define PXA255_DCSR_BUSERRINTR (0x00000001) -#define PXA255_DINT (PXA255_DMA_BASE_ADDR + 0x000000f0) -#define PXA255_DRCMR0 (PXA255_DMA_BASE_ADDR + 0x00000100) -#define PXA255_DRCMR1 (PXA255_DMA_BASE_ADDR + 0x00000104) -#define PXA255_DRCMR2 (PXA255_DMA_BASE_ADDR + 0x00000108) -#define PXA255_DRCMR3 (PXA255_DMA_BASE_ADDR + 0x0000010c) -#define PXA255_DRCMR4 (PXA255_DMA_BASE_ADDR + 0x00000110) -#define PXA255_DRCMR5 (PXA255_DMA_BASE_ADDR + 0x00000114) -#define PXA255_DRCMR6 (PXA255_DMA_BASE_ADDR + 0x00000118) -#define PXA255_DRCMR7 (PXA255_DMA_BASE_ADDR + 0x0000011c) -#define PXA255_DRCMR8 (PXA255_DMA_BASE_ADDR + 0x00000120) -#define PXA255_DRCMR9 (PXA255_DMA_BASE_ADDR + 0x00000124) -#define PXA255_DRCMR10 (PXA255_DMA_BASE_ADDR + 0x00000128) -#define PXA255_DRCMR11 (PXA255_DMA_BASE_ADDR + 0x0000012c) -#define PXA255_DRCMR12 (PXA255_DMA_BASE_ADDR + 0x00000130) -#define PXA255_DRCMR13 (PXA255_DMA_BASE_ADDR + 0x00000134) -#define PXA255_DRCMR14 (PXA255_DMA_BASE_ADDR + 0x00000138) -#define PXA255_DRCMR15 (PXA255_DMA_BASE_ADDR + 0x0000013c) -#define PXA255_DRCMR16 (PXA255_DMA_BASE_ADDR + 0x00000140) -#define PXA255_DRCMR17 (PXA255_DMA_BASE_ADDR + 0x00000144) -#define PXA255_DRCMR18 (PXA255_DMA_BASE_ADDR + 0x00000148) -#define PXA255_DRCMR19 (PXA255_DMA_BASE_ADDR + 0x0000014c) -#define PXA255_DRCMR20 (PXA255_DMA_BASE_ADDR + 0x00000150) -#define PXA255_DRCMR21 (PXA255_DMA_BASE_ADDR + 0x00000154) -#define PXA255_DRCMR22 (PXA255_DMA_BASE_ADDR + 0x00000158) -#define PXA255_DRCMR23 (PXA255_DMA_BASE_ADDR + 0x0000015c) -#define PXA255_DRCMR24 (PXA255_DMA_BASE_ADDR + 0x00000160) -#define PXA255_DRCMR25 (PXA255_DMA_BASE_ADDR + 0x00000164) -#define PXA255_DRCMR26 (PXA255_DMA_BASE_ADDR + 0x00000168) -#define PXA255_DRCMR27 (PXA255_DMA_BASE_ADDR + 0x0000016c) -#define PXA255_DRCMR28 (PXA255_DMA_BASE_ADDR + 0x00000170) -#define PXA255_DRCMR29 (PXA255_DMA_BASE_ADDR + 0x00000174) -#define PXA255_DRCMR30 (PXA255_DMA_BASE_ADDR + 0x00000178) -#define PXA255_DRCMR31 (PXA255_DMA_BASE_ADDR + 0x0000017c) -#define PXA255_DRCMR32 (PXA255_DMA_BASE_ADDR + 0x00000180) -#define PXA255_DRCMR33 (PXA255_DMA_BASE_ADDR + 0x00000184) -#define PXA255_DRCMR34 (PXA255_DMA_BASE_ADDR + 0x00000188) -#define PXA255_DRCMR35 (PXA255_DMA_BASE_ADDR + 0x0000018c) -#define PXA255_DRCMR36 (PXA255_DMA_BASE_ADDR + 0x00000190) -#define PXA255_DRCMR37 (PXA255_DMA_BASE_ADDR + 0x00000194) -#define PXA255_DRCMR38 (PXA255_DMA_BASE_ADDR + 0x00000198) -#define PXA255_DRCMR39 (PXA255_DMA_BASE_ADDR + 0x0000019c) -#define PXA255_DDADR0 (PXA255_DMA_BASE_ADDR + 0x00000200) -#define PXA255_DSADR0 (PXA255_DMA_BASE_ADDR + 0x00000204) -#define PXA255_DTADR0 (PXA255_DMA_BASE_ADDR + 0x00000208) -#define PXA255_DCMD0 (PXA255_DMA_BASE_ADDR + 0x0000020c) -#define PXA255_DDADR1 (PXA255_DMA_BASE_ADDR + 0x00000210) -#define PXA255_DSADR1 (PXA255_DMA_BASE_ADDR + 0x00000214) -#define PXA255_DTADR1 (PXA255_DMA_BASE_ADDR + 0x00000218) -#define PXA255_DCMD1 (PXA255_DMA_BASE_ADDR + 0x0000021c) -#define PXA255_DDADR2 (PXA255_DMA_BASE_ADDR + 0x00000220) -#define PXA255_DSADR2 (PXA255_DMA_BASE_ADDR + 0x00000224) -#define PXA255_DTADR2 (PXA255_DMA_BASE_ADDR + 0x00000228) -#define PXA255_DCMD2 (PXA255_DMA_BASE_ADDR + 0x0000022c) -#define PXA255_DDADR3 (PXA255_DMA_BASE_ADDR + 0x00000230) -#define PXA255_DSADR3 (PXA255_DMA_BASE_ADDR + 0x00000234) -#define PXA255_DTADR3 (PXA255_DMA_BASE_ADDR + 0x00000238) -#define PXA255_DCMD3 (PXA255_DMA_BASE_ADDR + 0x0000023c) -#define PXA255_DDADR4 (PXA255_DMA_BASE_ADDR + 0x00000240) -#define PXA255_DSADR4 (PXA255_DMA_BASE_ADDR + 0x00000244) -#define PXA255_DTADR4 (PXA255_DMA_BASE_ADDR + 0x00000248) -#define PXA255_DCMD4 (PXA255_DMA_BASE_ADDR + 0x0000024c) -#define PXA255_DDADR5 (PXA255_DMA_BASE_ADDR + 0x00000250) -#define PXA255_DSADR5 (PXA255_DMA_BASE_ADDR + 0x00000254) -#define PXA255_DTADR5 (PXA255_DMA_BASE_ADDR + 0x00000258) -#define PXA255_DCMD5 (PXA255_DMA_BASE_ADDR + 0x0000025c) -#define PXA255_DDADR6 (PXA255_DMA_BASE_ADDR + 0x00000260) -#define PXA255_DSADR6 (PXA255_DMA_BASE_ADDR + 0x00000264) -#define PXA255_DTADR6 (PXA255_DMA_BASE_ADDR + 0x00000268) -#define PXA255_DCMD6 (PXA255_DMA_BASE_ADDR + 0x0000026c) -#define PXA255_DDADR7 (PXA255_DMA_BASE_ADDR + 0x00000270) -#define PXA255_DSADR7 (PXA255_DMA_BASE_ADDR + 0x00000274) -#define PXA255_DTADR7 (PXA255_DMA_BASE_ADDR + 0x00000278) -#define PXA255_DCMD7 (PXA255_DMA_BASE_ADDR + 0x0000027c) -#define PXA255_DDADR8 (PXA255_DMA_BASE_ADDR + 0x00000280) -#define PXA255_DSADR8 (PXA255_DMA_BASE_ADDR + 0x00000284) -#define PXA255_DTADR8 (PXA255_DMA_BASE_ADDR + 0x00000288) -#define PXA255_DCMD8 (PXA255_DMA_BASE_ADDR + 0x0000028c) -#define PXA255_DDADR9 (PXA255_DMA_BASE_ADDR + 0x00000290) -#define PXA255_DSADR9 (PXA255_DMA_BASE_ADDR + 0x00000294) -#define PXA255_DTADR9 (PXA255_DMA_BASE_ADDR + 0x00000298) -#define PXA255_DCMD9 (PXA255_DMA_BASE_ADDR + 0x0000029c) -#define PXA255_DDADR10 (PXA255_DMA_BASE_ADDR + 0x000002a0) -#define PXA255_DSADR10 (PXA255_DMA_BASE_ADDR + 0x000002a4) -#define PXA255_DTADR10 (PXA255_DMA_BASE_ADDR + 0x000002a8) -#define PXA255_DCMD10 (PXA255_DMA_BASE_ADDR + 0x000002ac) -#define PXA255_DDADR11 (PXA255_DMA_BASE_ADDR + 0x000002b0) -#define PXA255_DSADR11 (PXA255_DMA_BASE_ADDR + 0x000002b4) -#define PXA255_DTADR11 (PXA255_DMA_BASE_ADDR + 0x000002b8) -#define PXA255_DCMD11 (PXA255_DMA_BASE_ADDR + 0x000002bc) -#define PXA255_DDADR12 (PXA255_DMA_BASE_ADDR + 0x000002c0) -#define PXA255_DSADR12 (PXA255_DMA_BASE_ADDR + 0x000002c4) -#define PXA255_DTADR12 (PXA255_DMA_BASE_ADDR + 0x000002c8) -#define PXA255_DCMD12 (PXA255_DMA_BASE_ADDR + 0x000002cc) -#define PXA255_DDADR13 (PXA255_DMA_BASE_ADDR + 0x000002d0) -#define PXA255_DSADR13 (PXA255_DMA_BASE_ADDR + 0x000002d4) -#define PXA255_DTADR13 (PXA255_DMA_BASE_ADDR + 0x000002d8) -#define PXA255_DCMD13 (PXA255_DMA_BASE_ADDR + 0x000002dc) -#define PXA255_DDADR14 (PXA255_DMA_BASE_ADDR + 0x000002e0) -#define PXA255_DSADR14 (PXA255_DMA_BASE_ADDR + 0x000002e4) -#define PXA255_DTADR14 (PXA255_DMA_BASE_ADDR + 0x000002e8) -#define PXA255_DCMD14 (PXA255_DMA_BASE_ADDR + 0x000002ec) -#define PXA255_DDADR15 (PXA255_DMA_BASE_ADDR + 0x000002f0) - #define PXA255_DDADR_STOP (0x00000001) -#define PXA255_DSADR15 (PXA255_DMA_BASE_ADDR + 0x000002f4) -#define PXA255_DTADR15 (PXA255_DMA_BASE_ADDR + 0x000002f8) -#define PXA255_DCMD15 (PXA255_DMA_BASE_ADDR + 0x000002fc) - #define PXA255_DCMD_INCSRCADDR (0x80000000) - #define PXA255_DCMD_INCTRGADDR (0x40000000) - #define PXA255_DCMD_FLOWSRC (0x20000000) - #define PXA255_DCMD_FLOWTRG (0x10000000) - #define PXA255_DCMD_STARTIRQEN (0x00400000) - #define PXA255_DCMD_ENDIRQEN (0x00200000) - #define PXA255_DCMD_ENDIAN (0x00040000) - #define PXA255_DCMD_SIZE_SHIFT (16) - #define PXA255_DCMD_SIZE_MASK (0x00000003) - #define PXA255_DCMD_SIZE_0 (0x00000000) - #define PXA255_DCMD_SIZE_8 (0x00000001) - #define PXA255_DCMD_SIZE_16 (0x00000002) - #define PXA255_DCMD_SIZE_32 (0x00000003) - #define PXA255_DCMD_WIDTH (0x0000c000) - #define PXA255_DCMD_WIDTH_0 (0x00000000) - #define PXA255_DCMD_WIDTH_1 (0x00004000) - #define PXA255_DCMD_WIDTH_2 (0x00008000) - #define PXA255_DCMD_WIDTH_4 (0x0000c000) - -/* - - PXA255 Inter-Integrated-Circuit Sound (I2S) Controller - - pg. 489 to 504, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_I2S_BASE_ADDR (0x40400000) -#define PXA255_SACR0 (PXA255_I2S_BASE_ADDR + 0x00000000) - #define PXA255_SACR0_ENB (0x00000001) // Enable I2S function: 0 = Disable, 1 = Enable - #define PXA255_SACR0_BCKD (0x00000004) // Input/Output direction of BITCLK: 0 = Input, 1 = Output - #define PXA255_SACR0_RST (0x00000008) // Reset FIFO Logic and all registers: 0 = Not Reset, 1 = Reset is active - #define PXA255_SACR0_EFWR (0x00000010) // Special-purpose FIFO Write/Read Enable: 0 = Disable, 1 = Enable - #define PXA255_SACR0_STRF (0x00000020) // Select Transmit or Receive FIFO for EFWR-based special-purpose function: 0 = Xmit FIFO, 1 = Recv FIFO - #define PXA255_SACR0_TFTH (0x00000f00) // Transmit FIFO interrupt or DMA threshold - #define PXA255_SACR0_TFTH_S (8) - #define PXA255_SACR0_RFTH (0x0000f000) // Receive FIFO interrupt or DMA threshold - #define PXA255_SACR0_RFTH_S (12) -#define PXA255_SACR1 (PXA255_I2S_BASE_ADDR + 0x00000004) - #define PXA255_SACR1_AMSL (0x00000001) // Alternate Mode: 0 = I2S Operation Mode, 1 = MSB-Justified Operation Mode - #define PXA255_SACR1_DREC (0x00000008) // Disable Recording: 0 = Recording Function is enabled, 1 = Recording Function is disabled - #define PXA255_SACR1_DRPL (0x00000010) // Disable Replaying: 0 = Replaying Function is enabled, 1 = Recording Function is disabled - #define PXA255_SACR1_ENLBF (0x00000020) // Enable I2S/MSB Interface Loopback -#define PXA255_SASR0 (PXA255_I2S_BASE_ADDR + 0x0000000c) - #define PXA255_SASR0_TNF (0x00000001) - #define PXA255_SASR0_RNE (0x00000002) - #define PXA255_SASR0_BSY (0x00000004) - #define PXA255_SASR0_TFS (0x00000008) - #define PXA255_SASR0_RFS (0x00000010) - #define PXA255_SASR0_TUR (0x00000020) - #define PXA255_SASR0_ROR (0x00000040) - #define PXA255_SASR0_TFL (0x00000f00) - #define PXA255_SASR0_RFL (0x0000f000) -#define PXA255_SAIMR (PXA255_I2S_BASE_ADDR + 0x00000014) - #define PXA255_SAIMR_TFS (0x00000008) - #define PXA255_SAIMR_RFS (0x00000010) - #define PXA255_SAIMR_TUR (0x00000020) - #define PXA255_SAIMR_ROR (0x00000040) -#define PXA255_SAICR (PXA255_I2S_BASE_ADDR + 0x00000018) - #define PXA255_SAICR_TUR (0x00000020) - #define PXA255_SAICR_ROR (0x00000040) -#define PXA255_SADIV (PXA255_I2S_BASE_ADDR + 0x00000060) -#define PXA255_SADR (PXA255_I2S_BASE_ADDR + 0x00000080) - -/* - - PXA255 Real-Time Clock - - pg. 132 to 138, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_RTC_BASE_ADDR (0x40900000) -#define PXA255_RCNR (PXA255_RTC_BASE_ADDR + 0x00000000) -#define PXA255_RTAR (PXA255_RTC_BASE_ADDR + 0x00000004) -#define PXA255_RTSR (PXA255_RTC_BASE_ADDR + 0x00000008) -#define PXA255_RTTR (PXA255_RTC_BASE_ADDR + 0x0000000c) - -/* - - PXA255 OS Timer register - - pg. 138 to 142, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_OSTMR_BASE_ADDR (0x40a00000) -#define PXA255_OSMR0 (PXA255_OSTMR_BASE_ADDR + 0x00000000) -#define PXA255_OSMR1 (PXA255_OSTMR_BASE_ADDR + 0x00000004) -#define PXA255_OSMR2 (PXA255_OSTMR_BASE_ADDR + 0x00000008) -#define PXA255_OSMR3 (PXA255_OSTMR_BASE_ADDR + 0x0000000c) -#define PXA255_OSCR (PXA255_OSTMR_BASE_ADDR + 0x00000010) -#define PXA255_OSSR (PXA255_OSTMR_BASE_ADDR + 0x00000014) - #define PXA255_OSSR_M0 (0x00000001) - #define PXA255_OSSR_M1 (0x00000002) - #define PXA255_OSSR_M2 (0x00000004) - #define PXA255_OSSR_M3 (0x00000008) -#define PXA255_OWER (PXA255_OSTMR_BASE_ADDR + 0x00000018) -#define PXA255_OIER (PXA255_OSTMR_BASE_ADDR + 0x0000001c) - #define PXA255_OIER_E0 (0x00000001) - #define PXA255_OIER_E1 (0x00000002) - #define PXA255_OIER_E2 (0x00000004) - #define PXA255_OIER_E3 (0x00000008) - -/* - - PXA255 Interrupt registers - - pg. 124 to 132, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_INTC_BASE_ADDR (0x40d00000) -#define PXA255_ICIP (PXA255_INTC_BASE_ADDR + 0x00000000) -#define PXA255_ICMR (PXA255_INTC_BASE_ADDR + 0x00000004) -#define PXA255_ICLR (PXA255_INTC_BASE_ADDR + 0x00000008) -#define PXA255_ICFP (PXA255_INTC_BASE_ADDR + 0x0000000c) -#define PXA255_ICPR (PXA255_INTC_BASE_ADDR + 0x00000010) -#define PXA255_ICCR (PXA255_INTC_BASE_ADDR + 0x00000014) - -#define PXA255_INT_HUART (1 << 7) -#define PXA255_INT_GPIO0 (1 << 8) -#define PXA255_INT_GPIO1 (1 << 9) -#define PXA255_INT_GPIO84_2 (1 << 10) -#define PXA255_INT_USB (1 << 11) -#define PXA255_INT_PMU (1 << 12) -#define PXA255_INT_I2S (1 << 13) -#define PXA255_INT_AC97 (1 << 14) -#define PXA255_INT_NETWORK (1 << 16) -#define PXA255_INT_LCD (1 << 17) -#define PXA255_INT_I2C (1 << 18) -#define PXA255_INT_ICP (1 << 19) -#define PXA255_INT_STUART (1 << 20) -#define PXA255_INT_BTUART (1 << 21) -#define PXA255_INT_FFUART (1 << 22) -#define PXA255_INT_MMC (1 << 23) -#define PXA255_INT_SSP (1 << 24) -#define PXA255_INT_DMA (1 << 25) -#define PXA255_INT_OSTIMER0 (1 << 26) -#define PXA255_INT_OSTIMER1 (1 << 27) -#define PXA255_INT_OSTIMER2 (1 << 28) -#define PXA255_INT_OSTIMER3 (1 << 29) -#define PXA255_INT_RTC_HZ (1 << 30) -#define PXA255_INT_RTC_ALARM (1 << 31) - -/* - - PXA255 General-Purpose I/O registers - - pg. 105 to 124, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_GPIO_BASE_ADDR (0x40e00000) -#define PXA255_GPLR0 (PXA255_GPIO_BASE_ADDR + 0x00000000) -#define PXA255_GPLR1 (PXA255_GPIO_BASE_ADDR + 0x00000004) -#define PXA255_GPLR2 (PXA255_GPIO_BASE_ADDR + 0x00000008) -#define PXA255_GPDR0 (PXA255_GPIO_BASE_ADDR + 0x0000000c) -#define PXA255_GPDR1 (PXA255_GPIO_BASE_ADDR + 0x00000010) -#define PXA255_GPDR2 (PXA255_GPIO_BASE_ADDR + 0x00000014) -#define PXA255_GPSR0 (PXA255_GPIO_BASE_ADDR + 0x00000018) -#define PXA255_GPSR1 (PXA255_GPIO_BASE_ADDR + 0x0000001c) -#define PXA255_GPSR2 (PXA255_GPIO_BASE_ADDR + 0x00000020) -#define PXA255_GPCR0 (PXA255_GPIO_BASE_ADDR + 0x00000024) -#define PXA255_GPCR1 (PXA255_GPIO_BASE_ADDR + 0x00000028) -#define PXA255_GPCR2 (PXA255_GPIO_BASE_ADDR + 0x0000002c) -#define PXA255_GRER0 (PXA255_GPIO_BASE_ADDR + 0x00000030) -#define PXA255_GRER1 (PXA255_GPIO_BASE_ADDR + 0x00000034) -#define PXA255_GRER2 (PXA255_GPIO_BASE_ADDR + 0x00000038) -#define PXA255_GFER0 (PXA255_GPIO_BASE_ADDR + 0x0000003c) -#define PXA255_GFER1 (PXA255_GPIO_BASE_ADDR + 0x00000040) -#define PXA255_GFER2 (PXA255_GPIO_BASE_ADDR + 0x00000044) -#define PXA255_GEDR0 (PXA255_GPIO_BASE_ADDR + 0x00000048) -#define PXA255_GEDR1 (PXA255_GPIO_BASE_ADDR + 0x0000004c) -#define PXA255_GEDR2 (PXA255_GPIO_BASE_ADDR + 0x00000050) -#define PXA255_GAFR0_L (PXA255_GPIO_BASE_ADDR + 0x00000054) -#define PXA255_GAFR0_U (PXA255_GPIO_BASE_ADDR + 0x00000058) -#define PXA255_GAFR1_L (PXA255_GPIO_BASE_ADDR + 0x0000005c) -#define PXA255_GAFR1_U (PXA255_GPIO_BASE_ADDR + 0x00000060) -#define PXA255_GAFR2_L (PXA255_GPIO_BASE_ADDR + 0x00000064) -#define PXA255_GAFR2_U (PXA255_GPIO_BASE_ADDR + 0x00000068) - -/* - - PXA255 LCD Controller - - pg. 265 to 310, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_LCD_BASE_ADDR (0x44000000) -#define PXA255_LCCR0 (PXA255_LCD_BASE_ADDR + 0x00000000) - #define PXA255_LCCR0_OUM (0x00200000) - #define PXA255_LCCR0_BM (0x00100000) - #define PXA255_LCCR0_PDD (0x000ff000) - #define PXA255_LCCR0_QDM (0x00000800) - #define PXA255_LCCR0_DIS (0x00000400) - #define PXA255_LCCR0_DPD (0x00000200) - #define PXA255_LCCR0_PAS (0x00000080) - #define PXA255_LCCR0_EFM (0x00000040) - #define PXA255_LCCR0_IUM (0x00000020) - #define PXA255_LCCR0_SFM (0x00000010) - #define PXA255_LCCR0_LDM (0x00000008) - #define PXA255_LCCR0_SDS (0x00000004) - #define PXA255_LCCR0_CMS (0x00000002) - #define PXA255_LCCR0_ENB (0x00000001) -#define PXA255_LCCR1 (PXA255_LCD_BASE_ADDR + 0x00000004) - #define PXA255_LCCR1_PPL (0x000003ff) -#define PXA255_LCCR2 (PXA255_LCD_BASE_ADDR + 0x00000008) - #define PXA255_LCCR2_LPP (0x000003ff) -#define PXA255_LCCR3 (PXA255_LCD_BASE_ADDR + 0x0000000c) -#define PXA255_FBR0 (PXA255_LCD_BASE_ADDR + 0x00000020) - #define PXA255_FBR_BAR (0x00000001) - #define PXA255_FBR_BINT (0x00000003) -#define PXA255_FBR1 (PXA255_LCD_BASE_ADDR + 0x00000024) -#define PXA255_LCSR (PXA255_LCD_BASE_ADDR + 0x00000038) - #define PXA255_LCSR_LDD (0x00000001) - #define PXA255_LCSR_SOF (0x00000002) - #define PXA255_LCSR_BER (0x00000004) - #define PXA255_LCSR_ABC (0x00000008) - #define PXA255_LCSR_IUL (0x00000010) - #define PXA255_LCSR_IUU (0x00000020) - #define PXA255_LCSR_OU (0x00000040) - #define PXA255_LCSR_QD (0x00000080) - #define PXA255_LCSR_EOF (0x00000100) - #define PXA255_LCSR_BS (0x00000200) - #define PXA255_LCSR_SINT (0x00000400) -#define PXA255_LIIDR (PXA255_LCD_BASE_ADDR + 0x0000003c) -#define PXA255_TRGBR (PXA255_LCD_BASE_ADDR + 0x00000040) -#define PXA255_TCR (PXA255_LCD_BASE_ADDR + 0x00000044) -#define PXA255_FDADR0 (PXA255_LCD_BASE_ADDR + 0x00000200) -#define PXA255_FSADR0 (PXA255_LCD_BASE_ADDR + 0x00000204) -#define PXA255_FIDR0 (PXA255_LCD_BASE_ADDR + 0x00000208) -#define PXA255_LDCMD0 (PXA255_LCD_BASE_ADDR + 0x0000020c) - #define PXA255_LDCMD_EOFINT (0x00200000) - #define PXA255_LDCMD_SOFINT (0x00400000) - #define PXA255_LDCMD_PAL (0x04000000) -#define PXA255_FDADR1 (PXA255_LCD_BASE_ADDR + 0x00000210) -#define PXA255_FSADR1 (PXA255_LCD_BASE_ADDR + 0x00000214) -#define PXA255_FIDR1 (PXA255_LCD_BASE_ADDR + 0x00000218) -#define PXA255_LDCMD1 (PXA255_LCD_BASE_ADDR + 0x0000021c) - -/* - PXA255 Power controller - - pg. 85 to 96, PXA255 Processor Developers Manual [278693-002].pdf -*/ - -#define PXA255_POWER_BASE_ADDR (0x40f00000) -#define PXA255_PMCR (PXA255_POWER_BASE_ADDR + 0x00000000) -#define PXA255_PSSR (PXA255_POWER_BASE_ADDR + 0x00000004) -#define PXA255_PSPR (PXA255_POWER_BASE_ADDR + 0x00000008) -#define PXA255_PWER (PXA255_POWER_BASE_ADDR + 0x0000000c) -#define PXA255_PRER (PXA255_POWER_BASE_ADDR + 0x00000010) -#define PXA255_PFER (PXA255_POWER_BASE_ADDR + 0x00000014) -#define PXA255_PEDR (PXA255_POWER_BASE_ADDR + 0x00000018) -#define PXA255_PCFR (PXA255_POWER_BASE_ADDR + 0x0000001c) -#define PXA255_PGSR0 (PXA255_POWER_BASE_ADDR + 0x00000020) -#define PXA255_PGSR1 (PXA255_POWER_BASE_ADDR + 0x00000024) -#define PXA255_PGSR2 (PXA255_POWER_BASE_ADDR + 0x00000028) -#define PXA255_RCSR (PXA255_POWER_BASE_ADDR + 0x00000030) -#define PXA255_PMFW (PXA255_POWER_BASE_ADDR + 0x00000034) - -/* - PXA255 Clock controller - - pg. 96 to 100, PXA255 Processor Developers Manual [278693-002].pdf - -*/ - -#define PXA255_CLOCKS_BASE_ADDR (0x41300000) -#define PXA255_CCCR (PXA255_CLOCKS_BASE_ADDR + 0x00000000) -#define PXA255_CKEN (PXA255_CLOCKS_BASE_ADDR + 0x00000004) -#define PXA255_OSCC (PXA255_CLOCKS_BASE_ADDR + 0x00000008) - -#endif // MAME_MACHINE_PXA255DEFS diff --git a/src/mame/misc/39in1.cpp b/src/mame/misc/39in1.cpp index 874d1763514..da0b1f90e94 100644 --- a/src/mame/misc/39in1.cpp +++ b/src/mame/misc/39in1.cpp @@ -62,6 +62,7 @@ public: , m_eeprom(*this, "eeprom") , m_ram(*this, "ram") , m_mcu_ipt(*this, "MCUIPT") + , m_dsw(*this, "DSW") { } void _39in1(machine_config &config); @@ -83,49 +84,50 @@ public: void init_plutus(); void init_pokrwild(); + DECLARE_INPUT_CHANGED_MEMBER(set_flip_dip); + DECLARE_INPUT_CHANGED_MEMBER(set_res_dip); + DECLARE_INPUT_CHANGED_MEMBER(set_hiscore_dip); + +protected: + virtual void machine_reset() override; + private: - uint32_t m_seed; - uint32_t m_magic; - uint32_t m_state; - uint32_t m_mcu_ipt_pc; + u32 m_seed; + u32 m_magic; + u32 m_state; + u32 m_mcu_ipt_pc; required_device m_maincpu; required_device m_pxa_periphs; - required_device m_eeprom; - required_shared_ptr m_ram; + required_device m_eeprom; + required_shared_ptr m_ram; required_ioport m_mcu_ipt; + required_ioport m_dsw; - uint32_t eeprom_r(); - void eeprom_w(uint32_t data, uint32_t mem_mask = ~0); - - uint32_t _39in1_cpld_r(offs_t offset); - void _39in1_cpld_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t _39in1_prot_cheater_r(); + u32 cpld_r(offs_t offset); + void cpld_w(offs_t offset, u32 data, u32 mem_mask = ~0); + u32 prot_cheater_r(); void _39in1_map(address_map &map); void base_map(address_map &map); - void decrypt(uint8_t xor00, uint8_t xor02, uint8_t xor04, uint8_t xor08, uint8_t xor10, uint8_t xor20, uint8_t xor40, uint8_t xor80, uint8_t bit7, uint8_t bit6, uint8_t bit5, uint8_t bit4, uint8_t bit3, uint8_t bit2, uint8_t bit1, uint8_t bit0); - void further_decrypt(uint8_t xor400, uint8_t xor800, uint8_t xor1000, uint8_t xor2000, uint8_t xor4000, uint8_t xor8000); + void decrypt(u8 xor00, u8 xor02, u8 xor04, u8 xor08, u8 xor10, u8 xor20, u8 xor40, u8 xor80, u8 bit7, u8 bit6, u8 bit5, u8 bit4, u8 bit3, u8 bit2, u8 bit1, u8 bit0); + void further_decrypt(u8 xor400, u8 xor800, u8 xor1000, u8 xor2000, u8 xor4000, u8 xor8000); }; - -uint32_t _39in1_state::eeprom_r() +void _39in1_state::machine_reset() { - return (m_eeprom->do_read() << 5) | (1 << 1); // Must be on. Probably a DIP switch. + m_pxa_periphs->gpio_in<1>(1); + + const u32 dsw = m_dsw->read(); + m_pxa_periphs->gpio_in<53>(BIT(dsw, 0)); + m_pxa_periphs->gpio_in<54>(BIT(dsw, 1)); + m_pxa_periphs->gpio_in<56>(BIT(dsw, 2)); + + m_eeprom->di_write(ASSERT_LINE); } -void _39in1_state::eeprom_w(uint32_t data, uint32_t mem_mask) -{ - if (BIT(mem_mask, 2)) - m_eeprom->cs_write(ASSERT_LINE); - if (BIT(mem_mask, 3)) - m_eeprom->clk_write(BIT(data, 3) ? ASSERT_LINE : CLEAR_LINE); - if (BIT(mem_mask, 4)) - m_eeprom->di_write(BIT(data, 4)); -} - -uint32_t _39in1_state::_39in1_cpld_r(offs_t offset) +u32 _39in1_state::cpld_r(offs_t offset) { // if (m_maincpu->pc() != m_mcu_ipt_pc) printf("CPLD read @ %x (PC %x state %d)\n", offset, m_maincpu->pc(), m_state); @@ -160,8 +162,8 @@ uint32_t _39in1_state::_39in1_cpld_r(offs_t offset) } else if (m_state == 2) // 29c0: 53 ac 0c 2b a2 07 e6 be 31 { - uint32_t seed = m_seed; - uint32_t magic = m_magic; + u32 seed = m_seed; + u32 magic = m_magic; magic = ( (((~(seed >> 16)) ^ (magic >> 1)) & 0x01) | (((~((seed >> 19) << 1)) ^ ((magic >> 5) << 1)) & 0x02) | @@ -180,7 +182,7 @@ uint32_t _39in1_state::_39in1_cpld_r(offs_t offset) return 0; } -void _39in1_state::_39in1_cpld_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void _39in1_state::cpld_w(offs_t offset, u32 data, u32 mem_mask) { if (mem_mask == 0xffff) { @@ -207,7 +209,7 @@ void _39in1_state::_39in1_cpld_w(offs_t offset, uint32_t data, uint32_t mem_mask #endif } -uint32_t _39in1_state::_39in1_prot_cheater_r() +u32 _39in1_state::prot_cheater_r() { return 0x37; } @@ -216,12 +218,7 @@ void _39in1_state::base_map(address_map &map) { map(0x00000000, 0x0007ffff).rom(); map(0x00400000, 0x007fffff).rom().region("data", 0); - map(0x40000000, 0x400002ff).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::dma_r), FUNC(pxa255_periphs_device::dma_w)); - map(0x40400000, 0x40400083).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::i2s_r), FUNC(pxa255_periphs_device::i2s_w)); - map(0x40a00000, 0x40a0001f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::ostimer_r), FUNC(pxa255_periphs_device::ostimer_w)); - map(0x40d00000, 0x40d00017).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::intc_r), FUNC(pxa255_periphs_device::intc_w)); - map(0x40e00000, 0x40e0006b).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::gpio_r), FUNC(pxa255_periphs_device::gpio_w)); - map(0x44000000, 0x4400021f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::lcd_r), FUNC(pxa255_periphs_device::lcd_w)); + map(0x40000000, 0x47ffffff).m(m_pxa_periphs, FUNC(pxa255_periphs_device::map)); map(0xa0000000, 0xa07fffff).ram().share("ram"); } @@ -229,8 +226,8 @@ void _39in1_state::_39in1_map(address_map &map) { base_map(map); - map(0x04000000, 0x047fffff).rw(FUNC(_39in1_state::_39in1_cpld_r), FUNC(_39in1_state::_39in1_cpld_w)); - map(0xa0151648, 0xa015164b).r(FUNC(_39in1_state::_39in1_prot_cheater_r)); + map(0x04000000, 0x047fffff).rw(FUNC(_39in1_state::cpld_r), FUNC(_39in1_state::cpld_w)); + map(0xa0151648, 0xa015164b).r(FUNC(_39in1_state::prot_cheater_r)); } static INPUT_PORTS_START( 39in1 ) @@ -271,23 +268,35 @@ static INPUT_PORTS_START( 39in1 ) // The following dips apply to 39in1 and 48in1. 60in1 is the same but the last unused dipsw#4 is test mode off/on. PORT_START("DSW") // 1x 4-position DIP switch labelled SW3 - PORT_DIPNAME( 0x01, 0x01, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW3:1") + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW3:1") PORT_CHANGED_MEMBER(DEVICE_SELF, _39in1_state, set_flip_dip, 0) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, "Display Mode" ) PORT_DIPLOCATION("SW3:2") + PORT_DIPNAME( 0x02, 0x00, "Display Mode" ) PORT_DIPLOCATION("SW3:2") PORT_CHANGED_MEMBER(DEVICE_SELF, _39in1_state, set_res_dip, 0) PORT_DIPSETTING( 0x02, "VGA 31.5kHz" ) PORT_DIPSETTING( 0x00, "CGA 15.75kHz" ) - PORT_DIPNAME( 0x04, 0x04, "High Score Saver" ) PORT_DIPLOCATION("SW3:3") + PORT_DIPNAME( 0x04, 0x04, "High Score Saver" ) PORT_DIPLOCATION("SW3:3") PORT_CHANGED_MEMBER(DEVICE_SELF, _39in1_state, set_hiscore_dip, 0) PORT_DIPSETTING( 0x04, "Disabled" ) PORT_DIPSETTING( 0x00, "Enabled" ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW3:4") - PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END -void _39in1_state::decrypt(uint8_t xor00, uint8_t xor02, uint8_t xor04, uint8_t xor08, uint8_t xor10, uint8_t xor20, uint8_t xor40, uint8_t xor80, uint8_t bit7, uint8_t bit6, uint8_t bit5, uint8_t bit4, uint8_t bit3, uint8_t bit2, uint8_t bit1, uint8_t bit0) +INPUT_CHANGED_MEMBER(_39in1_state::set_flip_dip) { - uint8_t *rom = memregion("maincpu")->base(); + m_pxa_periphs->gpio_in<53>(BIT(m_dsw->read(), 0)); +} + +INPUT_CHANGED_MEMBER(_39in1_state::set_res_dip) +{ + m_pxa_periphs->gpio_in<54>(BIT(m_dsw->read(), 1)); +} + +INPUT_CHANGED_MEMBER(_39in1_state::set_hiscore_dip) +{ + m_pxa_periphs->gpio_in<56>(BIT(m_dsw->read(), 2)); +} + +void _39in1_state::decrypt(u8 xor00, u8 xor02, u8 xor04, u8 xor08, u8 xor10, u8 xor20, u8 xor40, u8 xor80, u8 bit7, u8 bit6, u8 bit5, u8 bit4, u8 bit3, u8 bit2, u8 bit1, u8 bit0) +{ + u8 *rom = memregion("maincpu")->base(); for (int i = 0; i < 0x80000; i += 2) { @@ -310,9 +319,9 @@ void _39in1_state::decrypt(uint8_t xor00, uint8_t xor02, uint8_t xor04, uint8_t } } -void _39in1_state::further_decrypt(uint8_t xor400, uint8_t xor800, uint8_t xor1000, uint8_t xor2000, uint8_t xor4000, uint8_t xor8000) // later versions have more conditional XORs +void _39in1_state::further_decrypt(u8 xor400, u8 xor800, u8 xor1000, u8 xor2000, u8 xor4000, u8 xor8000) // later versions have more conditional XORs { - uint8_t *rom = memregion("maincpu")->base(); + u8 *rom = memregion("maincpu")->base(); for (int i = 0; i < 0x80000; i += 2) { @@ -353,12 +362,13 @@ void _39in1_state::base(machine_config &config) PXA255(config, m_maincpu, 200'000'000); m_maincpu->set_addrmap(AS_PROGRAM, &_39in1_state::base_map); - EEPROM_93C66_16BIT(config, "eeprom"); + EEPROM_93C66_16BIT(config, m_eeprom); + m_eeprom->do_callback().set(m_pxa_periphs, FUNC(pxa255_periphs_device::gpio_in<5>)); PXA255_PERIPHERALS(config, m_pxa_periphs, 200'000'000, m_maincpu); - m_pxa_periphs->gpio0_write().set(FUNC(_39in1_state::eeprom_w)); - m_pxa_periphs->gpio0_read().set(FUNC(_39in1_state::eeprom_r)); - m_pxa_periphs->gpio1_read().set_ioport("DSW").lshift(21); + m_pxa_periphs->gpio_out<4>().set(m_eeprom, FUNC(eeprom_serial_93c66_16bit_device::di_write)); + m_pxa_periphs->gpio_out<2>().set(m_eeprom, FUNC(eeprom_serial_93c66_16bit_device::cs_write)); + m_pxa_periphs->gpio_out<3>().set(m_eeprom, FUNC(eeprom_serial_93c66_16bit_device::clk_write)); } void _39in1_state::_39in1(machine_config &config) diff --git a/src/mame/sharp/zaurus.cpp b/src/mame/sharp/zaurus.cpp index 0f1661f8eb1..2e75ee639ab 100644 --- a/src/mame/sharp/zaurus.cpp +++ b/src/mame/sharp/zaurus.cpp @@ -1505,15 +1505,7 @@ void zaurus_sa_state::main_map(address_map &map) void zaurus_pxa_state::main_map(address_map &map) { map(0x00000000, 0x001fffff).rom().region("firmware", 0); - map(0x40000000, 0x400002ff).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::dma_r), FUNC(pxa255_periphs_device::dma_w)); - map(0x40400000, 0x40400083).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::i2s_r), FUNC(pxa255_periphs_device::i2s_w)); - map(0x40900000, 0x4090000f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::rtc_r), FUNC(pxa255_periphs_device::rtc_w)); - map(0x40a00000, 0x40a0001f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::ostimer_r), FUNC(pxa255_periphs_device::ostimer_w)); - map(0x40d00000, 0x40d00017).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::intc_r), FUNC(pxa255_periphs_device::intc_w)); - map(0x40e00000, 0x40e0006b).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::gpio_r), FUNC(pxa255_periphs_device::gpio_w)); - map(0x40f00000, 0x40f00037).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::power_r), FUNC(pxa255_periphs_device::power_w)); - map(0x41300000, 0x4130000b).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::clocks_r), FUNC(pxa255_periphs_device::clocks_w)); - map(0x44000000, 0x4400021f).rw(m_pxa_periphs, FUNC(pxa255_periphs_device::lcd_r), FUNC(pxa255_periphs_device::lcd_w)); + map(0x40000000, 0x47ffffff).m(m_pxa_periphs, FUNC(pxa255_periphs_device::map)); map(0xa0000000, 0xa07fffff).ram().share("ram"); } @@ -1527,7 +1519,7 @@ void zaurus_sa_state::device_reset_after_children() INPUT_CHANGED_MEMBER( zaurus_pxa_state::system_start ) { - m_pxa_periphs->gpio_bit_w(10, m_power->read()); + m_pxa_periphs->gpio_in<10>(BIT(m_power->read(), 0)); } static INPUT_PORTS_START( zaurus_sa )