Search
lxdream.org :: lxdream/src/sh4/timer.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/timer.c
changeset 115:699aa8916803
prev53:f2981805b929
next260:c82e26ec0cac
author nkeynes
date Fri Mar 17 12:13:12 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change Implement timer interrupt clearing (kinda useful)
file annotate diff log raw
1.1 --- a/src/sh4/timer.c Thu Dec 29 12:52:29 2005 +0000
1.2 +++ b/src/sh4/timer.c Fri Mar 17 12:13:12 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: timer.c,v 1.3 2005-12-29 12:52:29 nkeynes Exp $
1.6 + * $Id: timer.c,v 1.4 2006-03-17 12:13:12 nkeynes Exp $
1.7 *
1.8 * SH4 Timer/Clock peripheral modules (CPG, TMU, RTC), combined together to
1.9 * keep things simple (they intertwine a bit).
1.10 @@ -91,6 +91,8 @@
1.11 #define TCR_UNF 0x0100
1.12 #define TCR_UNIE 0x0020
1.13
1.14 +#define TCR_IRQ_ACTIVE (TCR_UNF|TCR_UNIE)
1.15 +
1.16 struct TMU_timer {
1.17 uint32_t timer_period;
1.18 uint32_t timer_remainder; /* left-over cycles from last count */
1.19 @@ -104,9 +106,23 @@
1.20 return MMIO_READ( TMU, reg );
1.21 }
1.22
1.23 -void TMU_set_timer_period( int timer, int tcr )
1.24 +void TMU_set_timer_control( int timer, int tcr )
1.25 {
1.26 uint32_t period = 1;
1.27 + uint32_t oldtcr = MMIO_READ( TMU, TCR0 + (12*timer) );
1.28 +
1.29 + if( (oldtcr & TCR_UNF) == 0 ) {
1.30 + tcr = tcr & (~TCR_UNF);
1.31 + } else {
1.32 + if( (oldtcr & TCR_UNIE == 0) &&
1.33 + (tcr & TCR_IRQ_ACTIVE) == TCR_IRQ_ACTIVE ) {
1.34 + intc_raise_interrupt( INT_TMU_TUNI0 + timer );
1.35 + } else if( (oldtcr & TCR_UNIE) != 0 &&
1.36 + (tcr & TCR_IRQ_ACTIVE) != TCR_IRQ_ACTIVE ) {
1.37 + intc_clear_interrupt( INT_TMU_TUNI0 + timer );
1.38 + }
1.39 + }
1.40 +
1.41 switch( tcr & 0x07 ) {
1.42 case 0:
1.43 period = sh4_peripheral_period << 2 ;
1.44 @@ -137,6 +153,8 @@
1.45 break;
1.46 }
1.47 TMU_timers[timer].timer_period = period;
1.48 +
1.49 + MMIO_WRITE( TMU, TCR0 + (12*timer), tcr );
1.50 }
1.51
1.52 void TMU_start( int timer )
1.53 @@ -193,14 +211,14 @@
1.54 }
1.55 break;
1.56 case TCR0:
1.57 - TMU_set_timer_period( 0, val );
1.58 - break;
1.59 + TMU_set_timer_control( 0, val );
1.60 + return;
1.61 case TCR1:
1.62 - TMU_set_timer_period( 1, val );
1.63 - break;
1.64 + TMU_set_timer_control( 1, val );
1.65 + return;
1.66 case TCR2:
1.67 - TMU_set_timer_period( 2, val );
1.68 - break;
1.69 + TMU_set_timer_control( 2, val );
1.70 + return;
1.71 }
1.72 MMIO_WRITE( TMU, reg, val );
1.73 }
1.74 @@ -224,9 +242,9 @@
1.75
1.76 void TMU_update_clocks()
1.77 {
1.78 - TMU_set_timer_period( 0, MMIO_READ( TMU, TCR0 ) );
1.79 - TMU_set_timer_period( 1, MMIO_READ( TMU, TCR1 ) );
1.80 - TMU_set_timer_period( 2, MMIO_READ( TMU, TCR2 ) );
1.81 + TMU_set_timer_control( 0, MMIO_READ( TMU, TCR0 ) );
1.82 + TMU_set_timer_control( 1, MMIO_READ( TMU, TCR1 ) );
1.83 + TMU_set_timer_control( 2, MMIO_READ( TMU, TCR2 ) );
1.84 }
1.85
1.86 void TMU_reset( )
.