Search
lxdream.org :: lxdream/src/sh4/timer.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/timer.c
changeset 23:1ec3acd0594d
next30:89b30313d757
author nkeynes
date Fri Dec 23 11:44:55 2005 +0000 (15 years ago)
permissions -rw-r--r--
last change Start of "real" time slices, general structure in place now
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/timer.c Fri Dec 23 11:44:55 2005 +0000
1.3 @@ -0,0 +1,128 @@
1.4 +/**
1.5 + * $Id: timer.c,v 1.1 2005-12-23 11:44:55 nkeynes Exp $
1.6 + *
1.7 + * SH4 Timer/Clock peripheral modules (CPG, TMU, RTC), combined together to
1.8 + * keep things simple (they intertwine a bit).
1.9 + *
1.10 + * Copyright (c) 2005 Nathan Keynes.
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.21 + */
1.22 +
1.23 +#include "dream.h"
1.24 +#include "mem.h"
1.25 +#include "clock.h"
1.26 +#include "sh4core.h"
1.27 +#include "sh4mmio.h"
1.28 +
1.29 +/********************************* CPG *************************************/
1.30 +
1.31 +int32_t mmio_region_CPG_read( uint32_t reg )
1.32 +{
1.33 + return MMIO_READ( CPG, reg );
1.34 +}
1.35 +
1.36 +void mmio_region_CPG_write( uint32_t reg, uint32_t val )
1.37 +{
1.38 + MMIO_WRITE( CPG, reg, val );
1.39 +}
1.40 +
1.41 +/********************************** RTC *************************************/
1.42 +
1.43 +int32_t mmio_region_RTC_read( uint32_t reg )
1.44 +{
1.45 + return MMIO_READ( RTC, reg );
1.46 +}
1.47 +
1.48 +void mmio_region_RTC_write( uint32_t reg, uint32_t val )
1.49 +{
1.50 + MMIO_WRITE( RTC, reg, val );
1.51 +}
1.52 +
1.53 +/********************************** TMU *************************************/
1.54 +
1.55 +int timer_divider[3] = {16,16,16};
1.56 +
1.57 +int32_t mmio_region_TMU_read( uint32_t reg )
1.58 +{
1.59 + return MMIO_READ( TMU, reg );
1.60 +}
1.61 +
1.62 +
1.63 +int get_timer_div( int val )
1.64 +{
1.65 + switch( val & 0x07 ) {
1.66 + case 0: return 16; /* assume peripheral clock is IC/4 */
1.67 + case 1: return 64;
1.68 + case 2: return 256;
1.69 + case 3: return 1024;
1.70 + case 4: return 4096;
1.71 + }
1.72 + return 1;
1.73 +}
1.74 +
1.75 +void mmio_region_TMU_write( uint32_t reg, uint32_t val )
1.76 +{
1.77 + switch( reg ) {
1.78 + case TCR0:
1.79 + timer_divider[0] = get_timer_div(val);
1.80 + break;
1.81 + case TCR1:
1.82 + timer_divider[1] = get_timer_div(val);
1.83 + break;
1.84 + case TCR2:
1.85 + timer_divider[2] = get_timer_div(val);
1.86 + break;
1.87 + }
1.88 + MMIO_WRITE( TMU, reg, val );
1.89 +}
1.90 +
1.91 +void TMU_run_slice( int microsecs )
1.92 +{
1.93 + int tcr = MMIO_READ( TMU, TSTR );
1.94 + int cycles = microsecs * 16 * 200;
1.95 + if( tcr & 0x01 ) {
1.96 + int count = cycles / timer_divider[0];
1.97 + int *val = MMIO_REG( TMU, TCNT0 );
1.98 + if( *val < count ) {
1.99 + MMIO_READ( TMU, TCR0 ) |= 0x100;
1.100 + /* interrupt goes here */
1.101 + count -= *val;
1.102 + *val = MMIO_READ( TMU, TCOR0 ) - count;
1.103 + } else {
1.104 + *val -= count;
1.105 + }
1.106 + }
1.107 + if( tcr & 0x02 ) {
1.108 + int count = cycles / timer_divider[1];
1.109 + int *val = MMIO_REG( TMU, TCNT1 );
1.110 + if( *val < count ) {
1.111 + MMIO_READ( TMU, TCR1 ) |= 0x100;
1.112 + /* interrupt goes here */
1.113 + count -= *val;
1.114 + *val = MMIO_READ( TMU, TCOR1 ) - count;
1.115 + } else {
1.116 + *val -= count;
1.117 + }
1.118 + }
1.119 + if( tcr & 0x04 ) {
1.120 + int count = cycles / timer_divider[2];
1.121 + int *val = MMIO_REG( TMU, TCNT2 );
1.122 + if( *val < count ) {
1.123 + MMIO_READ( TMU, TCR2 ) |= 0x100;
1.124 + /* interrupt goes here */
1.125 + count -= *val;
1.126 + *val = MMIO_READ( TMU, TCOR2 ) - count;
1.127 + } else {
1.128 + *val -= count;
1.129 + }
1.130 + }
1.131 +}
.