diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2010-02-13 14:24:46 +0100 |
---|---|---|
committer | Segher Boessenkool <segher@kernel.crashing.org> | 2010-02-13 14:24:46 +0100 |
commit | 052306240edc38dd43eef552c51d8131cc8aaf34 (patch) | |
tree | 82bcf3ab3276877891da2849dc87e20f96abe1c0 | |
parent | 381a00b5e4da7b8b64f8ed9f064e55288acd07d9 (diff) |
Add timers for TMB1 and TMB2; use timer.interval if timer.time == 0
-rw-r--r-- | emu.c | 5 | ||||
-rw-r--r-- | io.c | 45 | ||||
-rw-r--r-- | io.h | 2 | ||||
-rw-r--r-- | timer.c | 9 | ||||
-rw-r--r-- | timer.h | 6 |
5 files changed, 55 insertions, 12 deletions
@@ -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 @@ -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); +} @@ -10,4 +10,6 @@ void io_store(u16 val, u32 addr); u16 io_load(u32 addr); +void io_init(void); + #endif @@ -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(); @@ -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 |