diff options
Diffstat (limited to 'trunk/src/emu/cpu/m68000/68307tmu.c')
-rw-r--r-- | trunk/src/emu/cpu/m68000/68307tmu.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/m68000/68307tmu.c b/trunk/src/emu/cpu/m68000/68307tmu.c new file mode 100644 index 00000000000..104a65c6738 --- /dev/null +++ b/trunk/src/emu/cpu/m68000/68307tmu.c @@ -0,0 +1,245 @@ +/* 68307 TIMER module */ +// 2x timers + +#include "emu.h" +#include "m68kcpu.h" + +READ16_HANDLER( m68307_internal_timer_r ) +{ + m68ki_cpu_core *m68k = m68k_get_safe_token(&space->device()); + m68307_timer* timer = m68k->m68307TIMER; + assert(timer != NULL); + + if (timer) + { + int pc = cpu_get_pc(&space->device()); + int which = offset & 0x8; + + switch (offset&0x7) + { + case m68307TIMER_TCN: /* 0x3 (0x126 / 0x136) */ + //if (pc!=0x2182e) logerror("%08x m68307_internal_timer_r %08x (%04x) (TCN - Timer Counter for timer %d)\n", pc, offset*2,mem_mask, which); + return timer->read_tcn(mem_mask, which); + break; + + + default: + logerror("%08x m68307_internal_timer_r %08x, (%04x)\n", pc, offset*2,mem_mask); + break; + } + } + + return 0x0000; +} + +WRITE16_HANDLER( m68307_internal_timer_w ) +{ + m68ki_cpu_core *m68k = m68k_get_safe_token(&space->device()); + m68307_timer* timer = m68k->m68307TIMER; + assert(timer != NULL); + + if (timer) + { + int pc = cpu_get_pc(&space->device()); + int which = offset & 0x8; + + switch (offset&0x7) + { + case m68307TIMER_TMR: /* 0x0 (0x120 / 0x130) */ + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TMR - Timer Mode Register for timer %d)\n", pc, offset*2,data,mem_mask, which); + timer->write_tmr(data, mem_mask, which); + break; + + case m68307TIMER_TRR: /* 0x1 (0x122 / 0x132) */ + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TRR - Timer Reference Register for timer %d)\n", pc, offset*2,data,mem_mask, which); + timer->write_trr(data, mem_mask, which); + break; + + case m68307TIMER_TCR: /* 0x2 (0x124 / 0x134) */ + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TCR - Timer Capture Register for timer %d) (illegal, read-only)\n", pc, offset*2,data,mem_mask, which); + break; + + case m68307TIMER_TCN: /* 0x3 (0x126 / 0x136) */ + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TCN - Timer Counter for timer %d)\n", pc, offset*2,data,mem_mask, which); + break; + + case m68307TIMER_TER: /* 0x4 (0x128 / 0x138) */ + /* 8-bit only!! */ + //logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (TER - Timer Event Register for timer %d)\n", pc, offset*2,data,mem_mask, which); + timer->write_ter(data, mem_mask, which); + break; + + case m68307TIMER_WRR: /* 0x5 (0x12a / 0x13a) */ + if (which==0) + { + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (WRR - Watchdog Reference Register)\n", pc, offset*2,data,mem_mask); + } + else + { + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", pc, offset*2,data,mem_mask); + } + break; + + case m68307TIMER_WCR: /* 0x6 (0x12c / 0x13c) */ + if (which==0) + { + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (WRR - Watchdog Counter Register)\n", pc, offset*2,data,mem_mask); + } + else + { + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", pc, offset*2,data,mem_mask); + } + break; + + case m68307TIMER_XXX: /* 0x7 (0x12e / 0x13e) */ + logerror("%08x m68307_internal_timer_w %08x, %04x (%04x) (illegal)\n", pc, offset*2,data,mem_mask); + break; + + } + } +} + +static TIMER_CALLBACK( m68307_timer0_callback ) +{ + + legacy_cpu_device *dev = (legacy_cpu_device *)ptr; + m68ki_cpu_core* m68k = m68k_get_safe_token(dev); + m68307_single_timer* tptr = &m68k->m68307TIMER->singletimer[0]; + tptr->regs[m68307TIMER_TMR] |= 0x2; + + m68307_timer0_interrupt(dev); + + tptr->mametimer->adjust(m68k->device->cycles_to_attotime(20000)); +} + +static TIMER_CALLBACK( m68307_timer1_callback ) +{ + legacy_cpu_device *dev = (legacy_cpu_device *)ptr; + m68ki_cpu_core* m68k = m68k_get_safe_token(dev); + m68307_single_timer* tptr = &m68k->m68307TIMER->singletimer[1]; + tptr->regs[m68307TIMER_TMR] |= 0x2; + + m68307_timer1_interrupt(dev); + + tptr->mametimer->adjust(m68k->device->cycles_to_attotime(20000)); + +} + +static TIMER_CALLBACK( m68307_wd_timer_callback ) +{ + printf("wd timer\n"); +} + +void m68307_timer::init(legacy_cpu_device *device) +{ + m68307_single_timer* tptr; + + tptr = &singletimer[0]; + tptr->mametimer = device->machine().scheduler().timer_alloc(FUNC(m68307_timer0_callback), device); + + tptr = &singletimer[1]; + tptr->mametimer = device->machine().scheduler().timer_alloc(FUNC(m68307_timer1_callback), device); + + parent = device; + + wd_mametimer = device->machine().scheduler().timer_alloc(FUNC(m68307_wd_timer_callback), device); + + +} + +UINT16 m68307_timer::read_tcn(UINT16 mem_mask, int which) +{ + // we should return the current timer value by + // calculating what it should be based on the time + // since it was last set + return 0x3a98; +} + +void m68307_timer::write_ter(UINT16 data, UINT16 mem_mask, int which) +{ + m68307_single_timer* tptr = &singletimer[which]; + if (data & 0x2) tptr->regs[m68307TIMER_TMR] &= ~0x2; +} + +void m68307_timer::write_tmr(UINT16 data, UINT16 mem_mask, int which) +{ + m68ki_cpu_core* m68k = m68k_get_safe_token(parent); + m68307_single_timer* tptr = &singletimer[which]; + + COMBINE_DATA(&tptr->regs[m68307TIMER_TMR]); + + data = tptr->regs[m68307TIMER_TMR]; + + int ps = data & (0xff00)>>8; + int ce = data & (0x00c0)>>6; + int om = data & (0x0020)>>5; + int ori = data & (0x0010)>>4; + int frr = data & (0x0008)>>3; + int iclk = data & (0x0006)>>1; + int rst = data & (0x0001)>>0; + + + logerror("tmr value %04x : Details :\n", data); + logerror("prescale %d\n", ps); + logerror("(clock divided by %d)\n", ps+1); + logerror("capture edge / enable interrupt %d\n", ce); + if (ce==0x0) logerror("(disable interrupt on capture event)\n"); + if (ce==0x1) logerror("(capture on rising edge only + enable capture interrupt)\n"); + if (ce==0x2) logerror("(capture on falling edge only + enable capture interrupt)\n"); + if (ce==0x3) logerror("(capture on any edge + enable capture interrupt)\n"); + logerror("output mode %d\n", om); + if (om==0x0) logerror("(active-low pulse for one cycle))\n"); + if (om==0x1) logerror("(toggle output)\n"); + logerror("output reference interrupt %d\n", ori); + if (ori==0x0) logerror("(disable reference interrupt)\n"); + if (ori==0x1) logerror("(enable interrupt on reaching reference value))\n"); + logerror("free running %d\n", frr); + if (frr==0x0) logerror("(free running mode, counter continues after value reached)\n"); + if (frr==0x1) logerror("(restart mode, counter resets after value reached)\n"); + logerror("interrupt clock source %d\n", iclk); + if (iclk==0x0) logerror("(stop count)\n"); + if (iclk==0x1) logerror("(master system clock)\n"); + if (iclk==0x2) logerror("(master system clock divided by 16)\n"); + if (iclk==0x3) logerror("(TIN Pin)\n"); + logerror("reset %d\n", rst); + if (rst==0x0) logerror("(timer is reset)\n"); + if (rst==0x1) logerror("(timer is running)\n"); + + tptr->mametimer->adjust(m68k->device->cycles_to_attotime(100000)); + + logerror("\n"); + +} + +void m68307_timer::write_trr(UINT16 data, UINT16 mem_mask, int which) +{ + m68307_single_timer* tptr = &singletimer[which]; + + COMBINE_DATA(&tptr->regs[m68307TIMER_TRR]); +} + + + +void m68307_timer::reset(void) +{ + for (int i=0;i<2;i++) + { + m68307_single_timer* tptr = &singletimer[i]; + + tptr->regs[m68307TIMER_TMR] = 0x0000; + tptr->regs[m68307TIMER_TRR] = 0xffff; + tptr->regs[m68307TIMER_TCR] = 0x0000; + tptr->regs[m68307TIMER_TCN] = 0x0000; + tptr->regs[m68307TIMER_TER] = 0x0000; + tptr->regs[m68307TIMER_WRR] = 0xffff; + tptr->regs[m68307TIMER_WCR] = 0xffff; + tptr->regs[m68307TIMER_XXX] = 0; + tptr->enabled = false; + tptr->mametimer->adjust(attotime::never); + } + + wd_mametimer->adjust(attotime::never); + + +} + |