diff options
author | Bad Diode <bd@badd10de.dev> | 2021-09-09 12:01:10 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-09-09 12:01:10 +0200 |
commit | 4eaa5313c9c591dffb6f52c2674009622cbdd28e (patch) | |
tree | facb0d86c55c5e1699c570b621185346a586c7d9 | |
parent | 05589c7cefdb554876db97ded9370e353d0ec0b1 (diff) | |
download | uxnrpi-4eaa5313c9c591dffb6f52c2674009622cbdd28e.tar.gz uxnrpi-4eaa5313c9c591dffb6f52c2674009622cbdd28e.zip |
Add system timer regs and sync execution at 60fps
-rw-r--r-- | src/common.h | 36 | ||||
-rw-r--r-- | src/main.c | 7 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/common.h b/src/common.h index 6f3bd70..b983ca5 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -246,7 +246,41 @@ mb_call(unsigned char ch, void *msg) { | |||
246 | } | 246 | } |
247 | 247 | ||
248 | // | 248 | // |
249 | // Utilities | 249 | // Timers. |
250 | // | ||
251 | |||
252 | typedef struct TimerRegs { | ||
253 | vu32 ctrl_status; | ||
254 | vu32 counter_low; | ||
255 | vu32 counter_high; | ||
256 | vu32 compare[4]; | ||
257 | } TimerRegs; | ||
258 | |||
259 | #define TIMER ((TimerRegs *)(MEM_BASE + 0x00003000)) | ||
260 | |||
261 | u64 | ||
262 | timer_get_ticks(void) { | ||
263 | u32 high = TIMER->counter_high; | ||
264 | u32 low = TIMER->counter_low; | ||
265 | |||
266 | // Reading is not atomic, since we need to read two 32 bit values. We check | ||
267 | // if the high bits changed after reading the low bits for safety. | ||
268 | if (high != TIMER->counter_high) { | ||
269 | high = TIMER->counter_high; | ||
270 | low = TIMER->counter_low; | ||
271 | } | ||
272 | return ((u64)high << 32) | low; | ||
273 | } | ||
274 | |||
275 | void | ||
276 | wait(u64 usec) { | ||
277 | u64 current_ticks = timer_get_ticks(); | ||
278 | // The system timer clock runs at 1 Mhz. | ||
279 | while (timer_get_ticks() < (current_ticks + usec)); | ||
280 | } | ||
281 | |||
282 | // | ||
283 | // Utilities. | ||
250 | // | 284 | // |
251 | 285 | ||
252 | void * | 286 | void * |
@@ -155,11 +155,18 @@ void main(void) { | |||
155 | init_uxn(); | 155 | init_uxn(); |
156 | 156 | ||
157 | uxn_eval(&u, 0x0100); | 157 | uxn_eval(&u, 0x0100); |
158 | u64 current_ticks = timer_get_ticks(); | ||
158 | while(1) { | 159 | while(1) { |
159 | // Echo input to standard output. | 160 | // Echo input to standard output. |
160 | uxn_eval(&u, mempeek16(devscreen->dat, 0)); | 161 | uxn_eval(&u, mempeek16(devscreen->dat, 0)); |
161 | 162 | ||
162 | // Blit ppu.pixels to the framebuffer. | 163 | // Blit ppu.pixels to the framebuffer. |
163 | blit_framebuffer(&ppu); | 164 | blit_framebuffer(&ppu); |
165 | |||
166 | // Sync at 60 Hz. | ||
167 | if ((timer_get_ticks() - current_ticks) < 16666) { | ||
168 | wait(16666 - (timer_get_ticks() - current_ticks)); | ||
169 | } | ||
170 | current_ticks = timer_get_ticks(); | ||
164 | } | 171 | } |
165 | } | 172 | } |