nuclear@0: /* nuclear@0: Copyright 2004 John Tsiombikas nuclear@0: nuclear@0: This file is part of libgba, a library for GameBoy Advance development. nuclear@0: nuclear@0: This program is free software; you can redistribute it and/or modify nuclear@0: it under the terms of the GNU General Public License as published by nuclear@0: the Free Software Foundation; either version 2 of the License, or nuclear@0: (at your option) any later version. nuclear@0: nuclear@0: This program is distributed in the hope that it will be useful, nuclear@0: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@0: GNU General Public License for more details. nuclear@0: nuclear@0: You should have received a copy of the GNU General Public License nuclear@0: along with this program; if not, write to the Free Software nuclear@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nuclear@0: */ nuclear@0: nuclear@0: #include nuclear@0: #include "intr.h" nuclear@0: #include "signal.h" nuclear@0: nuclear@0: /* prescalar selection based on the system clock (16.78MHz) */ nuclear@0: #define TIMER_CNTL_CLK 0 nuclear@0: #define TIMER_CNTL_CLK64 1 nuclear@0: #define TIMER_CNTL_CLK256 2 nuclear@0: #define TIMER_CNTL_CLK1024 3 nuclear@0: nuclear@0: /* control bits */ nuclear@0: #define TIMER_CNTL_COUNTUP 4 nuclear@0: #define TIMER_CNTL_INTR 0x40 nuclear@0: #define TIMER_CNTL_ENABLE 0x80 nuclear@0: nuclear@0: static void timer_intr_handler(void); nuclear@0: nuclear@0: volatile static unsigned short *reg_timer[] = {(void*)0x4000100, (void*)0x4000104, (void*)0x4000108, (void*)0x400010c}; nuclear@0: static unsigned short *reg_timer_cntl[] = {(void*)0x4000102, (void*)0x4000106, (void*)0x400010a, (void*)0x400010e}; nuclear@0: nuclear@0: static unsigned long milli_sec; nuclear@0: static unsigned long alarm_val; nuclear@0: nuclear@0: void enable_timer(int timer) { nuclear@0: *reg_timer_cntl[timer] |= TIMER_CNTL_ENABLE; nuclear@0: } nuclear@0: nuclear@0: void disable_timer(int timer) { nuclear@0: *reg_timer_cntl[timer] &= ~TIMER_CNTL_ENABLE; nuclear@0: } nuclear@0: nuclear@0: void reset_msec_timer(void) { nuclear@0: *reg_timer_cntl[0] &= ~TIMER_CNTL_ENABLE; nuclear@0: interrupt(INTR_TIMER0, timer_intr_handler); nuclear@0: milli_sec = 0; nuclear@0: *reg_timer[0] = USHRT_MAX - 16779; nuclear@0: *reg_timer_cntl[0] = TIMER_CNTL_INTR | TIMER_CNTL_ENABLE; nuclear@0: unmask(INTR_TIMER0); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: unsigned long get_millisec(void) { nuclear@0: return milli_sec; nuclear@0: } nuclear@0: nuclear@0: unsigned int alarm(unsigned int seconds) { nuclear@0: unsigned int prev = alarm_val; nuclear@0: alarm_val = seconds * 1000; nuclear@0: } nuclear@0: nuclear@0: static void timer_intr_handler(void) { nuclear@0: milli_sec++; nuclear@0: nuclear@0: if(alarm_val > 0) { nuclear@0: if(!--alarm_val) raise(SIGALRM); nuclear@0: } nuclear@0: }