aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-09-09 12:01:10 +0200
committerBad Diode <bd@badd10de.dev>2021-09-09 12:01:10 +0200
commit4eaa5313c9c591dffb6f52c2674009622cbdd28e (patch)
treefacb0d86c55c5e1699c570b621185346a586c7d9
parent05589c7cefdb554876db97ded9370e353d0ec0b1 (diff)
downloaduxnrpi-4eaa5313c9c591dffb6f52c2674009622cbdd28e.tar.gz
uxnrpi-4eaa5313c9c591dffb6f52c2674009622cbdd28e.zip
Add system timer regs and sync execution at 60fps
-rw-r--r--src/common.h36
-rw-r--r--src/main.c7
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
252typedef 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
261u64
262timer_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
275void
276wait(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
252void * 286void *
diff --git a/src/main.c b/src/main.c
index d72ae20..624d3c8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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}