mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Checkpoint
This commit is contained in:
parent
5c17a1f4af
commit
cc5d6bd930
@ -4,7 +4,9 @@
|
||||
|
||||
TODO:
|
||||
- PXA-255 ID opcode fails on this
|
||||
- ARM TLB look-up errors
|
||||
- ARM TLB look-up errors?
|
||||
- RTC irq doesn't fire?
|
||||
- For whatever reason, after RTC check ARM executes invalid code at 0-0x200
|
||||
- Dumps are questionable to say the least
|
||||
|
||||
***************************************************************************/
|
||||
@ -30,6 +32,21 @@ public:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_shared_ptr<UINT32> m_ram;
|
||||
|
||||
UINT8 m_rtc_tick;
|
||||
DECLARE_READ32_MEMBER(pxa255_ostimer_r);
|
||||
DECLARE_WRITE32_MEMBER(pxa255_ostimer_w);
|
||||
DECLARE_READ32_MEMBER(pxa255_rtc_r);
|
||||
DECLARE_WRITE32_MEMBER(pxa255_rtc_w);
|
||||
DECLARE_READ32_MEMBER(pxa255_intc_r);
|
||||
DECLARE_WRITE32_MEMBER(pxa255_intc_w);
|
||||
PXA255_OSTMR_Regs m_ostimer_regs;
|
||||
PXA255_INTC_Regs m_intc_regs;
|
||||
|
||||
void pxa255_ostimer_irq_check();
|
||||
void pxa255_update_interrupts();
|
||||
void pxa255_set_irq_line(UINT32 line, int irq_state);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(rtc_irq_callback);
|
||||
|
||||
// screen updates
|
||||
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
@ -42,6 +59,23 @@ protected:
|
||||
virtual void palette_init();
|
||||
};
|
||||
|
||||
#define VERBOSE_LEVEL ( 5 )
|
||||
|
||||
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine& machine, int n_level, const char* s_fmt, ... )
|
||||
{
|
||||
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", machine.describe_context(), buf );
|
||||
//printf( "%s: %s", machine.describe_context(), buf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void zaurus_state::video_start()
|
||||
{
|
||||
}
|
||||
@ -53,8 +87,242 @@ UINT32 zaurus_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zaurus_state::pxa255_update_interrupts()
|
||||
{
|
||||
PXA255_INTC_Regs *intc_regs = &m_intc_regs;
|
||||
|
||||
intc_regs->icfp = (intc_regs->icpr & intc_regs->icmr) & intc_regs->iclr;
|
||||
intc_regs->icip = (intc_regs->icpr & intc_regs->icmr) & (~intc_regs->iclr);
|
||||
m_maincpu->set_input_line(ARM7_FIRQ_LINE, intc_regs->icfp ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_maincpu->set_input_line(ARM7_IRQ_LINE, intc_regs->icip ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void zaurus_state::pxa255_set_irq_line(UINT32 line, int irq_state)
|
||||
{
|
||||
PXA255_INTC_Regs *intc_regs = &m_intc_regs;
|
||||
|
||||
intc_regs->icpr &= ~line;
|
||||
intc_regs->icpr |= irq_state ? line : 0;
|
||||
//printf( "Setting IRQ line %08x to %d\n", line, irq_state );
|
||||
pxa255_update_interrupts();
|
||||
}
|
||||
|
||||
void zaurus_state::pxa255_ostimer_irq_check()
|
||||
{
|
||||
PXA255_OSTMR_Regs *ostimer_regs = &m_ostimer_regs;
|
||||
|
||||
// logerror("%08x OStimer irq check\n",ostimer_regs->oier);
|
||||
|
||||
pxa255_set_irq_line(PXA255_INT_OSTIMER0, (ostimer_regs->oier & PXA255_OIER_E0) ? ((ostimer_regs->ossr & PXA255_OSSR_M0) ? 1 : 0) : 0);
|
||||
//pxa255_set_irq_line(PXA255_INT_OSTIMER1, (ostimer_regs->oier & PXA255_OIER_E1) ? ((ostimer_regs->ossr & PXA255_OSSR_M1) ? 1 : 0) : 0);
|
||||
//pxa255_set_irq_line(PXA255_INT_OSTIMER2, (ostimer_regs->oier & PXA255_OIER_E2) ? ((ostimer_regs->ossr & PXA255_OSSR_M2) ? 1 : 0) : 0);
|
||||
//pxa255_set_irq_line(PXA255_INT_OSTIMER3, (ostimer_regs->oier & PXA255_OIER_E3) ? ((ostimer_regs->ossr & PXA255_OSSR_M3) ? 1 : 0) : 0);
|
||||
}
|
||||
|
||||
READ32_MEMBER(zaurus_state::pxa255_ostimer_r)
|
||||
{
|
||||
PXA255_OSTMR_Regs *ostimer_regs = &m_ostimer_regs;
|
||||
|
||||
switch(PXA255_OSTMR_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_OSMR0:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Match Register 0: %08x & %08x\n", ostimer_regs->osmr[0], mem_mask );
|
||||
return ostimer_regs->osmr[0];
|
||||
case PXA255_OSMR1:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Match Register 1: %08x & %08x\n", ostimer_regs->osmr[1], mem_mask );
|
||||
return ostimer_regs->osmr[1];
|
||||
case PXA255_OSMR2:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Match Register 2: %08x & %08x\n", ostimer_regs->osmr[2], mem_mask );
|
||||
return ostimer_regs->osmr[2];
|
||||
case PXA255_OSMR3:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Match Register 3: %08x & %08x\n", ostimer_regs->osmr[3], mem_mask );
|
||||
return ostimer_regs->osmr[3];
|
||||
case PXA255_OSCR:
|
||||
if (0) verboselog( 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:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Status Register: %08x & %08x\n", ostimer_regs->ossr, mem_mask );
|
||||
return ostimer_regs->ossr;
|
||||
case PXA255_OWER:
|
||||
if (0) verboselog( 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:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_r: OS Timer Interrupt Enable Register: %08x & %08x\n", ostimer_regs->oier, mem_mask );
|
||||
return ostimer_regs->oier;
|
||||
default:
|
||||
if (0) verboselog( machine(), 0, "pxa255_ostimer_r: Unknown address: %08x\n", PXA255_OSTMR_BASE_ADDR | (offset << 2));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(zaurus_state::pxa255_ostimer_w)
|
||||
{
|
||||
PXA255_OSTMR_Regs *ostimer_regs = &m_ostimer_regs;
|
||||
|
||||
switch(PXA255_OSTMR_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_OSMR0:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Match Register 0: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->osmr[0] = data;
|
||||
if(ostimer_regs->oier & PXA255_OIER_E0)
|
||||
{
|
||||
attotime period = attotime::from_hz(3846400) * (ostimer_regs->osmr[0] - ostimer_regs->oscr);
|
||||
|
||||
//printf( "Adjusting one-shot timer to 200MHz * %08x\n", ostimer_regs->osmr[0]);
|
||||
ostimer_regs->timer[0]->adjust(period);
|
||||
}
|
||||
break;
|
||||
case PXA255_OSMR1:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Match Register 1: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->osmr[1] = data;
|
||||
if(ostimer_regs->oier & PXA255_OIER_E1)
|
||||
{
|
||||
attotime period = attotime::from_hz(3846400) * (ostimer_regs->osmr[1] - ostimer_regs->oscr);
|
||||
|
||||
ostimer_regs->timer[1]->adjust(period, 1);
|
||||
}
|
||||
break;
|
||||
case PXA255_OSMR2:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Match Register 2: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->osmr[2] = data;
|
||||
if(ostimer_regs->oier & PXA255_OIER_E2)
|
||||
{
|
||||
attotime period = attotime::from_hz(3846400) * (ostimer_regs->osmr[2] - ostimer_regs->oscr);
|
||||
|
||||
ostimer_regs->timer[2]->adjust(period, 2);
|
||||
}
|
||||
break;
|
||||
case PXA255_OSMR3:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Match Register 3: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->osmr[3] = data;
|
||||
if(ostimer_regs->oier & PXA255_OIER_E3)
|
||||
{
|
||||
//attotime period = attotime::from_hz(3846400) * (ostimer_regs->osmr[3] - ostimer_regs->oscr);
|
||||
|
||||
//ostimer_regs->timer[3]->adjust(period, 3);
|
||||
}
|
||||
break;
|
||||
case PXA255_OSCR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Count Register: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->oscr = data;
|
||||
break;
|
||||
case PXA255_OSSR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Status Register: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->ossr &= ~data;
|
||||
pxa255_ostimer_irq_check();
|
||||
break;
|
||||
case PXA255_OWER:
|
||||
if (0) verboselog( 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:
|
||||
{
|
||||
int index = 0;
|
||||
if (0) verboselog( machine(), 3, "pxa255_ostimer_w: OS Timer Interrupt Enable Register: %08x & %08x\n", data, mem_mask );
|
||||
ostimer_regs->oier = data & 0x0000000f;
|
||||
for(index = 0; index < 4; index++)
|
||||
{
|
||||
if(ostimer_regs->oier & (1 << index))
|
||||
{
|
||||
//attotime period = attotime::from_hz(200000000) * ostimer_regs->osmr[index];
|
||||
|
||||
//ostimer_regs->timer[index]->adjust(period, index);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
verboselog( machine(), 0, "pxa255_ostimer_w: Unknown address: %08x = %08x & %08x\n", PXA255_OSTMR_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(zaurus_state::pxa255_intc_r)
|
||||
{
|
||||
PXA255_INTC_Regs *intc_regs = &m_intc_regs;
|
||||
|
||||
switch(PXA255_INTC_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_ICIP:
|
||||
if (0) verboselog( 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:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_r: Interrupt Controller Mask Register: %08x & %08x\n", intc_regs->icmr, mem_mask );
|
||||
return intc_regs->icmr;
|
||||
case PXA255_ICLR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_r: Interrupt Controller Level Register: %08x & %08x\n", intc_regs->iclr, mem_mask );
|
||||
return intc_regs->iclr;
|
||||
case PXA255_ICFP:
|
||||
if (0) verboselog( 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:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_r: Interrupt Controller Pending Register: %08x & %08x\n", intc_regs->icpr, mem_mask );
|
||||
return intc_regs->icpr;
|
||||
case PXA255_ICCR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_r: Interrupt Controller Control Register: %08x & %08x\n", intc_regs->iccr, mem_mask );
|
||||
return intc_regs->iccr;
|
||||
default:
|
||||
verboselog( machine(), 0, "pxa255_intc_r: Unknown address: %08x\n", PXA255_INTC_BASE_ADDR | (offset << 2));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(zaurus_state::pxa255_intc_w)
|
||||
{
|
||||
PXA255_INTC_Regs *intc_regs = &m_intc_regs;
|
||||
|
||||
switch(PXA255_INTC_BASE_ADDR | (offset << 2))
|
||||
{
|
||||
case PXA255_ICIP:
|
||||
verboselog( machine(), 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register: %08x & %08x\n", data, mem_mask );
|
||||
break;
|
||||
case PXA255_ICMR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_w: Interrupt Controller Mask Register: %08x & %08x\n", data, mem_mask );
|
||||
intc_regs->icmr = data & 0xfffe7f00;
|
||||
break;
|
||||
case PXA255_ICLR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_w: Interrupt Controller Level Register: %08x & %08x\n", data, mem_mask );
|
||||
intc_regs->iclr = data & 0xfffe7f00;
|
||||
break;
|
||||
case PXA255_ICFP:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register: %08x & %08x\n", data, mem_mask );
|
||||
break;
|
||||
case PXA255_ICPR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_w: (Invalid Write) Interrupt Controller Pending Register: %08x & %08x\n", data, mem_mask );
|
||||
break;
|
||||
case PXA255_ICCR:
|
||||
if (0) verboselog( machine(), 3, "pxa255_intc_w: Interrupt Controller Control Register: %08x & %08x\n", data, mem_mask );
|
||||
intc_regs->iccr = data & 0x00000001;
|
||||
break;
|
||||
default:
|
||||
verboselog( machine(), 0, "pxa255_intc_w: Unknown address: %08x = %08x & %08x\n", PXA255_INTC_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(zaurus_state::pxa255_rtc_r)
|
||||
{
|
||||
printf("%08x\n",offset << 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(zaurus_state::pxa255_rtc_w)
|
||||
{
|
||||
printf("%08x %08x\n",offset << 2,data);
|
||||
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( zaurus_map, AS_PROGRAM, 32, zaurus_state )
|
||||
AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_REGION("firmware", 0)
|
||||
AM_RANGE(0x40900000, 0x4090000f) AM_READWRITE(pxa255_rtc_r,pxa255_rtc_w)
|
||||
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(0xa0000000, 0xa07fffff) AM_RAM AM_SHARE("ram")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -77,6 +345,20 @@ void zaurus_state::palette_init()
|
||||
{
|
||||
}
|
||||
|
||||
/* TODO: Hack */
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(zaurus_state::rtc_irq_callback)
|
||||
{
|
||||
#if 0
|
||||
m_rtc_tick++;
|
||||
m_rtc_tick&=1;
|
||||
|
||||
if(m_rtc_tick & 1)
|
||||
pxa255_set_irq_line(PXA255_INT_RTC_HZ,1);
|
||||
else
|
||||
pxa255_set_irq_line(PXA255_INT_RTC_HZ,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: main CPU differs greatly between versions!
|
||||
static MACHINE_CONFIG_START( zaurus, zaurus_state )
|
||||
|
||||
@ -84,6 +366,8 @@ static MACHINE_CONFIG_START( zaurus, zaurus_state )
|
||||
MCFG_CPU_ADD("maincpu",PXA255,MAIN_CLOCK)
|
||||
MCFG_CPU_PROGRAM_MAP(zaurus_map)
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("rtc_timer", zaurus_state, rtc_irq_callback, attotime::from_hz(XTAL_32_768kHz))
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
|
Loading…
Reference in New Issue
Block a user