Fleshed out some Intel PXA255 peripherals. 39in1 now kicks off a palette DMA and a framebuffer DMA, services the resulting interrupts, and repeats, but does not yet write any palette data or framebuffer data other than 0. [MooglyGuy]

This commit is contained in:
Ryan Holtz 2009-07-25 09:48:51 +00:00
parent 93dbc795f0
commit b5aacf68ce

View File

@ -22,30 +22,932 @@
#include "driver.h"
#include "video/generic.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
static UINT32 counter_timer;
#define VERBOSE_LEVEL ( 3 )
// free-running 3.something MHz counter. this is a complete hack.
static READ32_HANDLER( os_timer_counter_r )
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... )
{
UINT32 ret;
ret = counter_timer;
counter_timer += 0x300;
return ret;
if( VERBOSE_LEVEL >= n_level )
{
va_list v;
char buf[32768];
va_start( v, s_fmt );
vsprintf( buf, s_fmt, v );
va_end( v );
logerror( "%s: %s", cpuexec_describe_context(machine), buf );
}
}
// intel docs says nothing's here, but code at e4010 begs to differ
static READ32_HANDLER( unknown_r )
/*
PXA255 DMA registers (placeholder)
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)
/* More DMA registers TODO */
static READ32_HANDLER( pxa255_dma_r )
{
return 2; // TST #$2
verboselog( space->machine, 0, "pxa255_dma_r: Placeholder functionality. Read: %08x & %08x\n", PXA255_DMA_BASE_ADDR | (offset << 2), mem_mask );
/* TODO: Everything placeholder, DCSR3 just needs to flag that it's ready to accept data so everything boots. */
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:
return 0x00000008; // Report channel as stopped
default:
break;
}
return 0;
}
/*
PXA255 OS Timer registers
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)
typedef struct
{
UINT32 osmr0;
UINT32 osmr1;
UINT32 osmr2;
UINT32 osmr3;
UINT32 oscr;
UINT32 ossr;
UINT32 ower;
UINT32 oier;
} PXA255_OSTMR_Regs;
static PXA255_OSTMR_Regs ostimer_regs;
static READ32_HANDLER( pxa255_ostimer_r )
{
switch(PXA255_OSTMR_BASE_ADDR | (offset << 2))
{
case PXA255_OSMR0:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Match Register 0: %08x & %08x\n", ostimer_regs.osmr0, mem_mask );
return ostimer_regs.osmr0;
case PXA255_OSMR1:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Match Register 1: %08x & %08x\n", ostimer_regs.osmr1, mem_mask );
return ostimer_regs.osmr1;
case PXA255_OSMR2:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Match Register 2: %08x & %08x\n", ostimer_regs.osmr2, mem_mask );
return ostimer_regs.osmr2;
case PXA255_OSMR3:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Match Register 3: %08x & %08x\n", ostimer_regs.osmr3, mem_mask );
return ostimer_regs.osmr3;
case PXA255_OSCR:
verboselog( space->machine, 4, "pxa255_ostimer_r: OS Timer Count Register: %08x & %08x\n", ostimer_regs.oscr, mem_mask );
// free-running 3.something MHz counter. this is a complete hack.
ostimer_regs.oscr += 0x300;
return ostimer_regs.oscr;
case PXA255_OSSR:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Status Register: %08x & %08x\n", ostimer_regs.ossr, mem_mask );
return ostimer_regs.ossr;
case PXA255_OWER:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Watchdog Match Enable Register: %08x & %08x\n", ostimer_regs.ower, mem_mask );
return ostimer_regs.ower;
case PXA255_OIER:
verboselog( space->machine, 3, "pxa255_ostimer_r: OS Timer Interrupt Enable Register: %08x & %08x\n", ostimer_regs.oier, mem_mask );
return ostimer_regs.oier;
default:
verboselog( space->machine, 0, "pxa255_ostimer_r: Unknown address: %08x\n", PXA255_OSTMR_BASE_ADDR | (offset << 2));
break;
}
return 0;
}
static WRITE32_HANDLER( pxa255_ostimer_w )
{
switch(PXA255_OSTMR_BASE_ADDR | (offset << 2))
{
case PXA255_OSMR0:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Match Register 0: %08x & %08x\n", data, mem_mask );
ostimer_regs.osmr0 = data;
break;
case PXA255_OSMR1:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Match Register 1: %08x & %08x\n", data, mem_mask );
ostimer_regs.osmr1 = data;
break;
case PXA255_OSMR2:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Match Register 2: %08x & %08x\n", data, mem_mask );
ostimer_regs.osmr2 = data;
break;
case PXA255_OSMR3:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Match Register 3: %08x & %08x\n", data, mem_mask );
ostimer_regs.osmr3 = data;
break;
case PXA255_OSCR:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Count Register: %08x & %08x\n", data, mem_mask );
ostimer_regs.oscr = data;
break;
case PXA255_OSSR:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Status Register: %08x & %08x\n", data, mem_mask );
ostimer_regs.ossr &= ~data;
break;
case PXA255_OWER:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Watchdog Enable Register: %08x & %08x\n", data, mem_mask );
ostimer_regs.ower = data & 0x00000001;
break;
case PXA255_OIER:
verboselog( space->machine, 3, "pxa255_ostimer_w: OS Timer Interrupt Enable Register: %08x & %08x\n", data, mem_mask );
ostimer_regs.oier = data & 0x0000000f;
break;
default:
verboselog( space->machine, 0, "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
*/
#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)
typedef struct
{
UINT32 icip;
UINT32 icmr;
UINT32 iclr;
UINT32 icfp;
UINT32 icpr;
UINT32 iccr;
} PXA255_INTC_Regs;
static PXA255_INTC_Regs intc_regs;
static void pxa255_update_interrupts(running_machine *machine)
{
intc_regs.icfp = (intc_regs.icpr & intc_regs.icmr) & intc_regs.iclr;
intc_regs.icip = (intc_regs.icpr & intc_regs.icmr) & (~intc_regs.iclr);
cputag_set_input_line(machine, "maincpu", ARM7_FIRQ_LINE, intc_regs.icfp ? ASSERT_LINE : CLEAR_LINE);
cputag_set_input_line(machine, "maincpu", ARM7_IRQ_LINE, intc_regs.icip ? ASSERT_LINE : CLEAR_LINE);
}
static void pxa255_set_irq_line(running_machine *machine, UINT32 line, int state)
{
intc_regs.icpr &= ~line;
intc_regs.icpr |= state ? line : 0;
pxa255_update_interrupts(machine);
}
static READ32_HANDLER( pxa255_intc_r )
{
switch(PXA255_INTC_BASE_ADDR | (offset << 2))
{
case PXA255_ICIP:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller IRQ Pending Register: %08x & %08x\n", intc_regs.icip, mem_mask );
return intc_regs.icip;
case PXA255_ICMR:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller Mask Register: %08x & %08x\n", intc_regs.icmr, mem_mask );
return intc_regs.icmr;
case PXA255_ICLR:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller Level Register: %08x & %08x\n", intc_regs.iclr, mem_mask );
return intc_regs.iclr;
case PXA255_ICFP:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller FIQ Pending Register: %08x & %08x\n", intc_regs.icfp, mem_mask );
return intc_regs.icfp;
case PXA255_ICPR:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller Pending Register: %08x & %08x\n", intc_regs.icpr, mem_mask );
return intc_regs.icpr;
case PXA255_ICCR:
verboselog( space->machine, 3, "pxa255_intc_r: Interrupt Controller Control Register: %08x & %08x\n", intc_regs.iccr, mem_mask );
return intc_regs.iccr;
default:
verboselog( space->machine, 0, "pxa255_intc_r: Unknown address: %08x\n", PXA255_INTC_BASE_ADDR | (offset << 2));
break;
}
return 0;
}
static WRITE32_HANDLER( pxa255_intc_w )
{
switch(PXA255_INTC_BASE_ADDR | (offset << 2))
{
case PXA255_ICIP:
verboselog( space->machine, 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register: %08x & %08x\n", data, mem_mask );
break;
case PXA255_ICMR:
verboselog( space->machine, 3, "pxa255_intc_w: Interrupt Controller Mask Register: %08x & %08x\n", data, mem_mask );
intc_regs.icmr = data & 0xfffe7f00;
break;
case PXA255_ICLR:
verboselog( space->machine, 3, "pxa255_intc_w: Interrupt Controller Level Register: %08x & %08x\n", data, mem_mask );
intc_regs.iclr = data & 0xfffe7f00;
break;
case PXA255_ICFP:
verboselog( space->machine, 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register: %08x & %08x\n", data, mem_mask );
break;
case PXA255_ICPR:
verboselog( space->machine, 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller Pending Register: %08x & %08x\n", data, mem_mask );
break;
case PXA255_ICCR:
verboselog( space->machine, 3, "pxa255_intc_w: Interrupt Controller Control Register: %08x & %08x\n", data, mem_mask );
intc_regs.iccr = data & 0x00000001;
break;
default:
verboselog( space->machine, 0, "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
*/
#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)
typedef struct
{
UINT32 gplr0; // GPIO Pin-Leve
UINT32 gplr1;
UINT32 gplr2;
UINT32 gpdr0;
UINT32 gpdr1;
UINT32 gpdr2;
UINT32 gpsr0;
UINT32 gpsr1;
UINT32 gpsr2;
UINT32 gpcr0;
UINT32 gpcr1;
UINT32 gpcr2;
UINT32 grer0;
UINT32 grer1;
UINT32 grer2;
UINT32 gfer0;
UINT32 gfer1;
UINT32 gfer2;
UINT32 gedr0;
UINT32 gedr1;
UINT32 gedr2;
UINT32 gafr0l;
UINT32 gafr0u;
UINT32 gafr1l;
UINT32 gafr1u;
UINT32 gafr2l;
UINT32 gafr2u;
} PXA255_GPIO_Regs;
static PXA255_GPIO_Regs gpio_regs;
static READ32_HANDLER( pxa255_gpio_r )
{
switch(PXA255_GPIO_BASE_ADDR | (offset << 2))
{
case PXA255_GPLR0:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Pin-Level Register 0: %08x & %08x\n", gpio_regs.gplr0 | (1 << 1), mem_mask );
return gpio_regs.gplr0 | (1 << 1); // Must be on. Probably a DIP switch.
case PXA255_GPLR1:
verboselog( space->machine, 3, "pxa255_gpio_r: *Not Yet Implemented* GPIO Pin-Level Register 1: %08x & %08x\n", gpio_regs.gplr1, mem_mask );
return gpio_regs.gplr1;
case PXA255_GPLR2:
verboselog( space->machine, 3, "pxa255_gpio_r: *Not Yet Implemented* GPIO Pin-Level Register 2: %08x & %08x\n", gpio_regs.gplr2, mem_mask );
return gpio_regs.gplr2;
case PXA255_GPDR0:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Pin Direction Register 0: %08x & %08x\n", gpio_regs.gpdr0, mem_mask );
return gpio_regs.gpdr0;
case PXA255_GPDR1:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Pin Direction Register 1: %08x & %08x\n", gpio_regs.gpdr1, mem_mask );
return gpio_regs.gpdr1;
case PXA255_GPDR2:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Pin Direction Register 2: %08x & %08x\n", gpio_regs.gpdr2, mem_mask );
return gpio_regs.gpdr2;
case PXA255_GPSR0:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 0: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GPSR1:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 1: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GPSR2:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Set Register 2: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GPCR0:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 0: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GPCR1:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 1: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GPCR2:
verboselog( space->machine, 3, "pxa255_gpio_r: (Invalid Read) GPIO Pin Output Clear Register 2: %08x & %08x\n", mame_rand(space->machine), mem_mask );
return mame_rand(space->machine);
case PXA255_GRER0:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 0: %08x & %08x\n", gpio_regs.grer0, mem_mask );
return gpio_regs.grer0;
case PXA255_GRER1:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 1: %08x & %08x\n", gpio_regs.grer1, mem_mask );
return gpio_regs.grer1;
case PXA255_GRER2:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Rising Edge Detect Enable Register 2: %08x & %08x\n", gpio_regs.grer2, mem_mask );
return gpio_regs.grer2;
case PXA255_GFER0:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 0: %08x & %08x\n", gpio_regs.gfer0, mem_mask );
return gpio_regs.gfer0;
case PXA255_GFER1:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 1: %08x & %08x\n", gpio_regs.gfer1, mem_mask );
return gpio_regs.gfer1;
case PXA255_GFER2:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Falling Edge Detect Enable Register 2: %08x & %08x\n", gpio_regs.gfer2, mem_mask );
return gpio_regs.gfer2;
case PXA255_GEDR0:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Edge Detect Status Register 0: %08x & %08x\n", gpio_regs.gedr0, mem_mask );
return gpio_regs.gedr0;
case PXA255_GEDR1:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Edge Detect Status Register 1: %08x & %08x\n", gpio_regs.gedr1, mem_mask );
return gpio_regs.gedr1;
case PXA255_GEDR2:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Edge Detect Status Register 2: %08x & %08x\n", gpio_regs.gedr2, mem_mask );
return gpio_regs.gedr2;
case PXA255_GAFR0_L:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 0 Lower: %08x & %08x\n", gpio_regs.gafr0l, mem_mask );
return gpio_regs.gafr0l;
case PXA255_GAFR0_U:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 0 Upper: %08x & %08x\n", gpio_regs.gafr0u, mem_mask );
return gpio_regs.gafr0u;
case PXA255_GAFR1_L:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 1 Lower: %08x & %08x\n", gpio_regs.gafr1l, mem_mask );
return gpio_regs.gafr1l;
case PXA255_GAFR1_U:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 1 Upper: %08x & %08x\n", gpio_regs.gafr1u, mem_mask );
return gpio_regs.gafr1u;
case PXA255_GAFR2_L:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 2 Lower: %08x & %08x\n", gpio_regs.gafr2l, mem_mask );
return gpio_regs.gafr2l;
case PXA255_GAFR2_U:
verboselog( space->machine, 3, "pxa255_gpio_r: GPIO Alternate Function Register 2 Upper: %08x & %08x\n", gpio_regs.gafr2u, mem_mask );
return gpio_regs.gafr2u;
default:
verboselog( space->machine, 0, "pxa255_gpio_r: Unknown address: %08x\n", PXA255_GPIO_BASE_ADDR | (offset << 2));
break;
}
return 0;
}
static WRITE32_HANDLER( pxa255_gpio_w )
{
switch(PXA255_GPIO_BASE_ADDR | (offset << 2))
{
case PXA255_GPLR0:
verboselog( space->machine, 3, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 0: %08x & %08x\n", data, mem_mask );
break;
case PXA255_GPLR1:
verboselog( space->machine, 3, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 1: %08x & %08x\n", data, mem_mask );
break;
case PXA255_GPLR2:
verboselog( space->machine, 3, "pxa255_gpio_w: (Invalid Write) GPIO Pin-Level Register 2: %08x & %08x\n", data, mem_mask );
break;
case PXA255_GPDR0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Direction Register 0: %08x & %08x\n", data, mem_mask );
gpio_regs.gpdr0 = data;
break;
case PXA255_GPDR1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Direction Register 1: %08x & %08x\n", data, mem_mask );
gpio_regs.gpdr1 = data;
break;
case PXA255_GPDR2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Direction Register 2: %08x & %08x\n", data, mem_mask );
gpio_regs.gpdr2 = data;
break;
case PXA255_GPSR0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Set Register 0: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr0 |= data & gpio_regs.gpdr0;
break;
case PXA255_GPSR1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Set Register 1: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr1 |= data & gpio_regs.gpdr1;
break;
case PXA255_GPSR2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Set Register 2: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr2 |= data & gpio_regs.gpdr2;
break;
case PXA255_GPCR0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Clear Register 0: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr0 &= ~(data & gpio_regs.gpdr0);
break;
case PXA255_GPCR1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Clear Register 1: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr1 &= ~(data & gpio_regs.gpdr1);
break;
case PXA255_GPCR2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Pin Output Clear Register 2: %08x & %08x\n", data, mem_mask );
gpio_regs.gpsr2 &= ~(data & gpio_regs.gpdr2);
break;
case PXA255_GRER0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 0: %08x & %08x\n", data, mem_mask );
gpio_regs.grer0 = data;
break;
case PXA255_GRER1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 1: %08x & %08x\n", data, mem_mask );
gpio_regs.grer1 = data;
break;
case PXA255_GRER2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Rising Edge Detect Enable Register 2: %08x & %08x\n", data, mem_mask );
gpio_regs.grer2 = data;
break;
case PXA255_GFER0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 0: %08x & %08x\n", data, mem_mask );
gpio_regs.gfer0 = data;
break;
case PXA255_GFER1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 1: %08x & %08x\n", data, mem_mask );
gpio_regs.gfer1 = data;
break;
case PXA255_GFER2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Falling Edge Detect Enable Register 2: %08x & %08x\n", data, mem_mask );
gpio_regs.gfer2 = data;
break;
case PXA255_GEDR0:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Edge Detect Status Register 0: %08x & %08x\n", gpio_regs.gedr0, mem_mask );
gpio_regs.gedr0 &= ~data;
break;
case PXA255_GEDR1:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Edge Detect Status Register 1: %08x & %08x\n", gpio_regs.gedr1, mem_mask );
gpio_regs.gedr1 &= ~data;
break;
case PXA255_GEDR2:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Edge Detect Status Register 2: %08x & %08x\n", gpio_regs.gedr2, mem_mask );
gpio_regs.gedr2 &= ~data;
break;
case PXA255_GAFR0_L:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 0 Lower: %08x & %08x\n", gpio_regs.gafr0l, mem_mask );
gpio_regs.gafr0l = data;
break;
case PXA255_GAFR0_U:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 0 Upper: %08x & %08x\n", gpio_regs.gafr0u, mem_mask );
gpio_regs.gafr0u = data;
break;
case PXA255_GAFR1_L:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 1 Lower: %08x & %08x\n", gpio_regs.gafr1l, mem_mask );
gpio_regs.gafr1l = data;
break;
case PXA255_GAFR1_U:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 1 Upper: %08x & %08x\n", gpio_regs.gafr1u, mem_mask );
gpio_regs.gafr1u = data;
break;
case PXA255_GAFR2_L:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 2 Lower: %08x & %08x\n", gpio_regs.gafr2l, mem_mask );
gpio_regs.gafr2l = data;
break;
case PXA255_GAFR2_U:
verboselog( space->machine, 3, "pxa255_gpio_w: GPIO Alternate Function Register 2 Upper: %08x & %08x\n", gpio_regs.gafr2u, mem_mask );
gpio_regs.gafr2u = data;
break;
default:
verboselog( space->machine, 0, "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
*/
#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_LCCR2 (PXA255_LCD_BASE_ADDR + 0x00000008)
#define PXA255_LCCR3 (PXA255_LCD_BASE_ADDR + 0x0000000c)
#define PXA255_FBR0 (PXA255_LCD_BASE_ADDR + 0x00000020)
#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_SOFINT (0x00400000)
#define PXA255_LDCMD_EOFINT (0x00200000)
#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)
typedef struct
{
UINT32 fdadr;
UINT32 fsadr;
UINT32 fidr;
UINT32 ldcmd;
emu_timer *eof;
} PXA255_LCD_DMA_Regs;
typedef struct
{
UINT32 lccr0;
UINT32 lccr1;
UINT32 lccr2;
UINT32 lccr3;
UINT32 pad0[4];
UINT32 fbr0;
UINT32 fbr1;
UINT32 pad1[4];
UINT32 lcsr;
UINT32 liidr;
UINT32 trgbr;
UINT32 tcr;
UINT32 pad2[110];
PXA255_LCD_DMA_Regs dma[2];
} PXA255_LCD_Regs;
static PXA255_LCD_Regs lcd_regs;
static void pxa255_lcd_initiate_dma(const address_space* space, UINT32 address, int channel)
{
lcd_regs.dma[channel].fdadr = memory_read_dword_32le(space, address);
lcd_regs.dma[channel].fsadr = memory_read_dword_32le(space, address + 0x04);
lcd_regs.dma[channel].fidr = memory_read_dword_32le(space, address + 0x08);
lcd_regs.dma[channel].ldcmd = memory_read_dword_32le(space, address + 0x0c);
verboselog( space->machine, 3, "pxa255_lcd_initiate_dma, address = %08x, channel = %d\n", address, channel);
verboselog( space->machine, 3, " DMA Frame Descriptor: %08x\n", lcd_regs.dma[channel].fdadr );
verboselog( space->machine, 3, " DMA Frame Source Address: %08x\n", lcd_regs.dma[channel].fsadr );
verboselog( space->machine, 3, " DMA Frame ID: %08x\n", lcd_regs.dma[channel].fidr );
verboselog( space->machine, 3, " DMA Command: %08x\n", lcd_regs.dma[channel].ldcmd );
}
static void pxa255_lcd_irq_check(running_machine *machine)
{
if(((lcd_regs.lcsr & PXA255_LCSR_BS) != 0 && (lcd_regs.lccr0 & PXA255_LCCR0_BM) == 0) ||
((lcd_regs.lcsr & PXA255_LCSR_EOF) != 0 && (lcd_regs.lccr0 & PXA255_LCCR0_EFM) == 0) ||
((lcd_regs.lcsr & PXA255_LCSR_SOF) != 0 && (lcd_regs.lccr0 & PXA255_LCCR0_SFM) == 0))
{
pxa255_set_irq_line(machine, PXA255_INT_LCD, 1);
}
else
{
pxa255_set_irq_line(machine, PXA255_INT_LCD, 0);
}
}
static READ32_HANDLER( pxa255_lcd_r )
{
switch(PXA255_LCD_BASE_ADDR | (offset << 2))
{
case PXA255_LCCR0: // 0x44000000
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Control 0: %08x & %08x\n", lcd_regs.lccr0, mem_mask );
return lcd_regs.lccr0;
case PXA255_LCCR1: // 0x44000004
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Control 1: %08x & %08x\n", lcd_regs.lccr1, mem_mask );
return lcd_regs.lccr1;
case PXA255_LCCR2: // 0x44000008
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Control 2: %08x & %08x\n", lcd_regs.lccr2, mem_mask );
return lcd_regs.lccr2;
case PXA255_LCCR3: // 0x4400000c
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Control 3: %08x & %08x\n", lcd_regs.lccr3, mem_mask );
return lcd_regs.lccr3;
case PXA255_FBR0: // 0x44000020
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Frame Branch Register 0: %08x & %08x\n", lcd_regs.fbr0, mem_mask );
return lcd_regs.fbr0;
case PXA255_FBR1: // 0x44000024
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Frame Branch Register 1: %08x & %08x\n", lcd_regs.fbr1, mem_mask );
return lcd_regs.fbr1;
case PXA255_LCSR: // 0x44000038
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Status Register: %08x & %08x\n", lcd_regs.lcsr, mem_mask );
return lcd_regs.lcsr;
case PXA255_LIIDR: // 0x4400003c
verboselog( space->machine, 3, "pxa255_lcd_r: LCD Interrupt ID Register: %08x & %08x\n", lcd_regs.liidr, mem_mask );
return lcd_regs.liidr;
case PXA255_TRGBR: // 0x44000040
verboselog( space->machine, 3, "pxa255_lcd_r: TMED RGB Seed Register: %08x & %08x\n", lcd_regs.trgbr, mem_mask );
return lcd_regs.trgbr;
case PXA255_TCR: // 0x44000044
verboselog( space->machine, 3, "pxa255_lcd_r: TMED RGB Seed Register: %08x & %08x\n", lcd_regs.tcr, mem_mask );
return lcd_regs.tcr;
case PXA255_FDADR0: // 0x44000200
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame Descriptor Address Register 0: %08x & %08x\n", lcd_regs.dma[0].fdadr, mem_mask );
return lcd_regs.dma[0].fdadr;
case PXA255_FSADR0: // 0x44000204
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame Source Address Register 0: %08x & %08x\n", lcd_regs.dma[0].fsadr, mem_mask );
return lcd_regs.dma[0].fsadr;
case PXA255_FIDR0: // 0x44000208
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame ID Register 0: %08x & %08x\n", lcd_regs.dma[0].fidr, mem_mask );
return lcd_regs.dma[0].fidr;
case PXA255_LDCMD0: // 0x4400020c
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Command Register 0: %08x & %08x\n", lcd_regs.dma[0].ldcmd & 0xfff00000, mem_mask );
return lcd_regs.dma[0].ldcmd & 0xfff00000;
case PXA255_FDADR1: // 0x44000210
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame Descriptor Address Register 1: %08x & %08x\n", lcd_regs.dma[1].fdadr, mem_mask );
return lcd_regs.dma[1].fdadr;
case PXA255_FSADR1: // 0x44000214
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame Source Address Register 1: %08x & %08x\n", lcd_regs.dma[1].fsadr, mem_mask );
return lcd_regs.dma[1].fsadr;
case PXA255_FIDR1: // 0x44000218
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Frame ID Register 1: %08x & %08x\n", lcd_regs.dma[1].fidr, mem_mask );
return lcd_regs.dma[1].fidr;
case PXA255_LDCMD1: // 0x4400021c
verboselog( space->machine, 3, "pxa255_lcd_r: LCD DMA Command Register 1: %08x & %08x\n", lcd_regs.dma[1].ldcmd & 0xfff00000, mem_mask );
return lcd_regs.dma[1].ldcmd & 0xfff00000;
default:
verboselog( space->machine, 0, "pxa255_lcd_r: Unknown address: %08x\n", PXA255_LCD_BASE_ADDR | (offset << 2));
break;
}
return 0;
}
static WRITE32_HANDLER( pxa255_lcd_w )
{
switch(PXA255_LCD_BASE_ADDR | (offset << 2))
{
case PXA255_LCCR0: // 0x44000000
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Control 0: %08x & %08x\n", data, mem_mask );
lcd_regs.lccr0 = data & 0x00fffeff;
break;
case PXA255_LCCR1: // 0x44000004
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Control 1: %08x & %08x\n", data, mem_mask );
lcd_regs.lccr1 = data;
break;
case PXA255_LCCR2: // 0x44000008
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Control 2: %08x & %08x\n", data, mem_mask );
lcd_regs.lccr2 = data;
break;
case PXA255_LCCR3: // 0x4400000c
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Control 3: %08x & %08x\n", data, mem_mask );
lcd_regs.lccr3 = data;
break;
case PXA255_FBR0: // 0x44000020
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Frame Branch Register 0: %08x & %08x\n", data, mem_mask );
lcd_regs.fbr0 = data & 2;
if(data & 1)
{
pxa255_lcd_initiate_dma(space, data & 0xfffffff0, 0);
lcd_regs.fbr0 |= memory_read_dword_32le(space, data & 0xfffffff0) & 0xfffffff0;
if(!(lcd_regs.lccr0 & PXA255_LCCR0_BM))
{
lcd_regs.lcsr |= PXA255_LCSR_BS;
pxa255_lcd_irq_check(space->machine);
}
}
break;
case PXA255_FBR1: // 0x44000024
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Frame Branch Register 1: %08x & %08x\n", data, mem_mask );
lcd_regs.fbr1 = data & 2;
if(data & 1)
{
pxa255_lcd_initiate_dma(space, data & 0xfffffff0, 1);
lcd_regs.fbr1 |= memory_read_dword_32le(space, data & 0xfffffff0) & 0xfffffff0;
if(!(lcd_regs.lccr0 & PXA255_LCCR0_BM))
{
lcd_regs.lcsr |= PXA255_LCSR_BS;
pxa255_lcd_irq_check(space->machine);
}
}
break;
case PXA255_LCSR: // 0x44000038
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Controller Status Register: %08x & %08x\n", data, mem_mask );
lcd_regs.lcsr &= ~data;
pxa255_lcd_irq_check(space->machine);
break;
case PXA255_LIIDR: // 0x4400003c
verboselog( space->machine, 3, "pxa255_lcd_w: LCD Controller Interrupt ID Register: %08x & %08x\n", data, mem_mask );
break;
case PXA255_TRGBR: // 0x44000040
verboselog( space->machine, 3, "pxa255_lcd_w: TMED RGB Seed Register: %08x & %08x\n", data, mem_mask );
lcd_regs.trgbr = data & 0x00ffffff;
break;
case PXA255_TCR: // 0x44000044
verboselog( space->machine, 3, "pxa255_lcd_w: TMED Control Register: %08x & %08x\n", data, mem_mask );
lcd_regs.tcr = data & 0x00004fff;
break;
case PXA255_FDADR0: // 0x44000200
verboselog( space->machine, 3, "pxa255_lcd_w: LCD DMA Frame Descriptor Address Register 0: %08x & %08x\n", data, mem_mask );
pxa255_lcd_initiate_dma(space, data & 0xfffffff0, 0);
break;
case PXA255_FSADR0: // 0x44000204
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame Source Address Register 0: %08x & %08x\n", data, mem_mask );
break;
case PXA255_FIDR0: // 0x44000208
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame ID Register 0: %08x & %08x\n", data, mem_mask );
break;
case PXA255_LDCMD0: // 0x4400020c
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Command Register 0: %08x & %08x\n", data, mem_mask );
break;
case PXA255_FDADR1: // 0x44000210
verboselog( space->machine, 3, "pxa255_lcd_w: LCD DMA Frame Descriptor Address Register 1: %08x & %08x\n", data, mem_mask );
pxa255_lcd_initiate_dma(space, data & 0xfffffff0, 1);
break;
case PXA255_FSADR1: // 0x44000214
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame Source Address Register 1: %08x & %08x\n", data, mem_mask );
break;
case PXA255_FIDR1: // 0x44000218
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Frame ID Register 1: %08x & %08x\n", data, mem_mask );
break;
case PXA255_LDCMD1: // 0x4400021c
verboselog( space->machine, 3, "pxa255_lcd_w: (Invalid Write) LCD DMA Command Register 1: %08x & %08x\n", data, mem_mask );
break;
default:
verboselog( space->machine, 0, "pxa255_lcd_w: Unknown address: %08x = %08x & %08x\n", PXA255_LCD_BASE_ADDR | (offset << 2), data, mem_mask);
break;
}
}
static TIMER_CALLBACK( pxa255_lcd_dma_eof )
{
printf( "LCD EOF: %d\n", param );
lcd_regs.liidr = lcd_regs.dma[param].fidr;
lcd_regs.lcsr |= PXA255_LCSR_EOF;
pxa255_lcd_irq_check(machine);
}
static INTERRUPT_GEN( pxa255_vblank_start )
{
if(lcd_regs.lccr0 & PXA255_LCCR0_ENB)
{
// Mark the start of the current DMA frame as appropriate
int channel = 0;
for(channel = 0; channel < 2; channel++)
{
if(lcd_regs.dma[channel].fdadr != 0)
{
if(lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_SOFINT)
{
printf( "LCD SOF: %d\n", channel );
lcd_regs.liidr = lcd_regs.dma[channel].fidr;
lcd_regs.lcsr |= PXA255_LCSR_SOF;
pxa255_lcd_irq_check(device->machine);
}
if(lcd_regs.dma[channel].ldcmd & PXA255_LDCMD_EOFINT)
{
attotime period = attotime_mul(ATTOTIME_IN_HZ(200000000), lcd_regs.dma[channel].ldcmd & 0x000fffff);
timer_adjust_oneshot(lcd_regs.dma[channel].eof, period, channel);
}
}
}
}
}
static ADDRESS_MAP_START( 39in1_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x00000000, 0x0007ffff) AM_ROM
AM_RANGE(0x40a00010, 0x40a00013) AM_READ( os_timer_counter_r )
AM_RANGE(0x40e00000, 0x40e00003) AM_READ( unknown_r )
AM_RANGE(0x40000000, 0x400002ff) AM_READ( pxa255_dma_r )
AM_RANGE(0x40a00000, 0x40a0001f) AM_READWRITE( pxa255_ostimer_r, pxa255_ostimer_w )
AM_RANGE(0x40d00000, 0x40d00017) AM_READWRITE( pxa255_intc_r, pxa255_intc_w )
AM_RANGE(0x40e00000, 0x40e0006b) AM_READWRITE( pxa255_gpio_r, pxa255_gpio_w )
AM_RANGE(0x44000000, 0x4400021f) AM_READWRITE( pxa255_lcd_r, pxa255_lcd_w )
AM_RANGE(0xa0000000, 0xa3ffffff) AM_RAM
ADDRESS_MAP_END
@ -57,6 +959,32 @@ static VIDEO_UPDATE( 39in1 )
return 0;
}
/* To be moved to DEVICE_START( pxa255 ) upon completion */
static void pxa255_start(running_machine *machine)
{
//pxa255_t* pxa255 = pxa255_get_safe_token( device );
//pxa255->iface = device->static_config;
ostimer_regs.osmr0 = ostimer_regs.osmr1 = ostimer_regs.osmr2 = ostimer_regs.osmr3 = 0;
ostimer_regs.oscr = ostimer_regs.ossr = ostimer_regs.ower = ostimer_regs.oier = 0;
intc_regs.icmr = intc_regs.iclr = intc_regs.iccr = intc_regs.icip = intc_regs.icfp = intc_regs.icpr = 0;
lcd_regs.lccr0 = lcd_regs.lccr1 = lcd_regs.lccr2 = lcd_regs.lccr3 = 0;
lcd_regs.dma[0].fdadr = lcd_regs.dma[1].fdadr = 0;
lcd_regs.dma[0].fsadr = lcd_regs.dma[1].fsadr = 0;
lcd_regs.dma[0].fidr = lcd_regs.dma[1].fidr = 0;
lcd_regs.dma[0].ldcmd = lcd_regs.dma[1].ldcmd = 0;
lcd_regs.dma[0].eof = timer_alloc(machine, pxa255_lcd_dma_eof, 0);
lcd_regs.dma[1].eof = timer_alloc(machine, pxa255_lcd_dma_eof, 0);
lcd_regs.fbr0 = lcd_regs.fbr1 = lcd_regs.lcsr = lcd_regs.liidr = 0;
lcd_regs.trgbr = 0x00aa5500;
lcd_regs.tcr = 0x0000754f;
//pxa255_register_state_save(device);
}
static MACHINE_START(39in1)
{
UINT8 *ROM = memory_region(machine, "maincpu");
@ -67,12 +995,13 @@ static MACHINE_START(39in1)
ROM[i] = BITSWAP8(ROM[i],7,2,5,6,0,3,1,4) ^ BITSWAP8((i>>3)&0xf, 3,2,4,1,4,4,0,4) ^ 0x90;
}
counter_timer = 0x300;
pxa255_start(machine);
}
static MACHINE_DRIVER_START( 39in1 )
MDRV_CPU_ADD("maincpu", PXA255, 200000000)
MDRV_CPU_PROGRAM_MAP(39in1_map)
MDRV_CPU_VBLANK_INT("screen", pxa255_vblank_start)
MDRV_PALETTE_LENGTH(32768)