summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2010-02-13 14:24:46 +0100
committerSegher Boessenkool <segher@kernel.crashing.org>2010-02-13 14:24:46 +0100
commit052306240edc38dd43eef552c51d8131cc8aaf34 (patch)
tree82bcf3ab3276877891da2849dc87e20f96abe1c0
parent381a00b5e4da7b8b64f8ed9f064e55288acd07d9 (diff)
Add timers for TMB1 and TMB2; use timer.interval if timer.time == 0
-rw-r--r--emu.c5
-rw-r--r--io.c45
-rw-r--r--io.h2
-rw-r--r--timer.c9
-rw-r--r--timer.h6
5 files changed, 55 insertions, 12 deletions
diff --git a/emu.c b/emu.c
index d3d8b4d..f257b42 100644
--- a/emu.c
+++ b/emu.c
@@ -835,8 +835,6 @@ static void run(void)
last_retrace_time = now;
- mem[0x3d22] |= 2; // TMB2 FIXME: freq
-
if (do_extint1) {
mem[0x3d22] |= 0x0200;
do_extint1 = 0;
@@ -868,9 +866,10 @@ void emu(void)
{
platform_init();
read_rom(0);
+ timer_init();
board_init();
+ io_init();
audio_init();
- timer_init();
memset(reg, 0, sizeof reg);
reg[7] = mem[0xfff7]; // reset vector
diff --git a/io.c b/io.c
index 856e90d..ddde04a 100644
--- a/io.c
+++ b/io.c
@@ -9,6 +9,7 @@
#include "emu.h"
#include "platform.h"
#include "board.h"
+#include "timer.h"
#include "io.h"
@@ -119,6 +120,28 @@ static void do_dma(u32 len)
mem[0x3e02] = 0;
}
+static void do_tmb1(void)
+{
+ mem[0x3d22] |= 0x0001;
+}
+
+static void do_tmb2(void)
+{
+ mem[0x3d22] |= 0x0002;
+}
+
+static struct timer timer_tmb1 = {
+ .name = "TMB1",
+ .interval = 1000000/8,
+ .run = do_tmb1
+};
+
+static struct timer timer_tmb2 = {
+ .name = "TMB2",
+ .interval = 1000000/128,
+ .run = do_tmb2
+};
+
void io_store(u16 val, u32 addr)
{
if (trace_unknown_io)
@@ -164,12 +187,16 @@ void io_store(u16 val, u32 addr)
return;
case 0x3d10: // timebase control
- if ((mem[addr] & 0x0003) != (val & 0x0003))
- printf("*** TMB1 FREQ set to %dHz\n",
- 8 << (val & 0x0003));
- if ((mem[addr] & 0x000c) != (val & 0x000c))
- printf("*** TMB2 FREQ set to %dHz\n",
- 128 << ((val & 0x000c) >> 2));
+ if ((mem[addr] & 0x0003) != (val & 0x0003)) {
+ u16 hz = 8 << (val & 0x0003);
+ printf("*** TMB1 FREQ set to %dHz\n", hz);
+ timer_tmb1.interval = 1000000 / hz;
+ }
+ if ((mem[addr] & 0x000c) != (val & 0x000c)) {
+ u16 hz = 128 << ((val & 0x000c) >> 2);
+ printf("*** TMB2 FREQ set to %dHz\n", hz);
+ timer_tmb2.interval = 1000000 / hz;
+ }
break;
// case 0x3d11: timebase clear
@@ -440,3 +467,9 @@ u16 io_load(u32 addr)
return val;
}
+
+void io_init(void)
+{
+ timer_add(&timer_tmb1);
+ timer_add(&timer_tmb2);
+}
diff --git a/io.h b/io.h
index 8d5af6c..3c5ac37 100644
--- a/io.h
+++ b/io.h
@@ -10,4 +10,6 @@
void io_store(u16 val, u32 addr);
u16 io_load(u32 addr);
+void io_init(void);
+
#endif
diff --git a/timer.c b/timer.c
index 0e2c599..ed9988a 100644
--- a/timer.c
+++ b/timer.c
@@ -13,6 +13,8 @@
#include "timer.h"
+static int trace_timer = 1;
+
volatile u32 timer_triggered;
static struct timer *timers;
@@ -50,6 +52,9 @@ void timer_debug(void)
void timer_add(struct timer *timer)
{
+ if (timer->time == 0)
+ timer->time = timer->interval;
+
u32 time = timer_now() - timer_time + timer->time;
struct timer **p = &timers;
@@ -76,7 +81,9 @@ void timer_run(void)
timer_time += timer->time;
elapsed -= timer->time;
-printf("running timer \"%s\" (%u)\n", timer->name, now);
+ if (trace_timer)
+ printf("running timer \"%s\" (%u)\n", timer->name, now);
+
if (timer->run)
timer->run();
diff --git a/timer.h b/timer.h
index a426b9e..2f0fb25 100644
--- a/timer.h
+++ b/timer.h
@@ -18,12 +18,14 @@ struct timer {
};
void timer_debug(void);
-void timer_init(void);
+
+u32 timer_now(void);
void timer_add(struct timer *timer);
void timer_run(void);
-u32 timer_now(void);
// XXX: temp
void timer_set(u32 usecs);
+void timer_init(void);
+
#endif