aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-03-04 18:43:38 +0100
committerBad Diode <bd@badd10de.dev>2022-03-04 18:43:38 +0100
commit6b29a0cb080aa7e8fad9de8943d2637437cad53d (patch)
treef0d107f88f0af53cf145039ea172e0921977a110
parent87ce7bbb4b5812e672b4912cc0c981a8037c2cd6 (diff)
downloaduxnfb-6b29a0cb080aa7e8fad9de8943d2637437cad53d.tar.gz
uxnfb-6b29a0cb080aa7e8fad9de8943d2637437cad53d.zip
Sync updates at 60hz
-rw-r--r--Makefile2
-rw-r--r--src/main.c153
2 files changed, 85 insertions, 70 deletions
diff --git a/Makefile b/Makefile
index 8de6bb0..3d41a4a 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ EXE_NAME ?= uxnfb
6BIN := $(BUILD_DIR)/$(EXE_NAME) 6BIN := $(BUILD_DIR)/$(EXE_NAME)
7UXN_HEAD := $(BASE_UXN)/src/uxn.h 7UXN_HEAD := $(BASE_UXN)/src/uxn.h
8TAL_SRC ?= $(BASE_UXN)/projects/examples/devices/screen.tal 8TAL_SRC ?= $(BASE_UXN)/projects/examples/devices/screen.tal
9UXN_ROM ?= $(BUILD_DIR)/screen.rom 9UXN_ROM ?= $(BUILD_DIR)/rom.rom
10UXN_ASM ?= $(BUILD_DIR)/uxnasm 10UXN_ASM ?= $(BUILD_DIR)/uxnasm
11 11
12CC ?= cc 12CC ?= cc
diff --git a/src/main.c b/src/main.c
index 1a4d6f6..e213bbb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,9 +1,11 @@
1#include <fcntl.h>
2#include <stdbool.h>
3#include <stdint.h>
1#include <stdio.h> 4#include <stdio.h>
2#include <stdlib.h> 5#include <stdlib.h>
3#include <stdint.h> 6#include <time.h>
4#include <stdbool.h>
5#include <unistd.h> 7#include <unistd.h>
6#include <fcntl.h> 8
7#include <linux/fb.h> 9#include <linux/fb.h>
8#include <sys/ioctl.h> 10#include <sys/ioctl.h>
9#include <sys/mman.h> 11#include <sys/mman.h>
@@ -18,6 +20,21 @@ static Device *devctrl;
18static Device *devmouse; 20static Device *devmouse;
19static Device *devaudio; 21static Device *devaudio;
20 22
23typedef struct timespec Time;
24
25Time
26time_now(){
27 struct timespec t;
28 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
29 return t;
30}
31
32size_t
33time_elapsed(Time since){
34 struct timespec now = time_now();
35 return (now.tv_sec - since.tv_sec) * 1e9 + (now.tv_nsec - since.tv_nsec);
36}
37
21void 38void
22nil_talk(Device *d, u8 b0, u8 w) { 39nil_talk(Device *d, u8 b0, u8 w) {
23 (void)d; 40 (void)d;
@@ -36,11 +53,11 @@ console_talk(Device *d, u8 b0, u8 w) {
36 // } 53 // }
37 // switch(b0) { 54 // switch(b0) {
38 // case 0x8: stmp[0] = d->dat[0x8]; stmp[1] = 0; uart_puts(stmp); break; 55 // case 0x8: stmp[0] = d->dat[0x8]; stmp[1] = 0; uart_puts(stmp); break;
39 // TODO: implement printf for the uart to be able to format 56 // TODO: implement printf for the uart to be able to format
40 // numbers. 57 // numbers.
41 // case 0x9: txt_printf("0x%02x", d->dat[0x9]); break; 58 // case 0x9: txt_printf("0x%02x", d->dat[0x9]); break;
42 // case 0xb: txt_printf("0x%04x", mempeek16(d->dat, 0xa)); break; 59 // case 0xb: txt_printf("0x%04x", mempeek16(d->dat, 0xa)); break;
43 // case 0xd: txt_printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break; 60 // case 0xd: txt_printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break;
44 // } 61 // }
45} 62}
46 63
@@ -70,14 +87,14 @@ void
70system_talk(Device *d, u8 b0, u8 w) { 87system_talk(Device *d, u8 b0, u8 w) {
71 if(!w) { /* read */ 88 if(!w) { /* read */
72 switch(b0) { 89 switch(b0) {
73 case 0x2: d->dat[0x2] = d->u->wst.ptr; break; 90 case 0x2: d->dat[0x2] = d->u->wst.ptr; break;
74 case 0x3: d->dat[0x3] = d->u->rst.ptr; break; 91 case 0x3: d->dat[0x3] = d->u->rst.ptr; break;
75 } 92 }
76 } else { /* write */ 93 } else { /* write */
77 switch(b0) { 94 switch(b0) {
78 case 0x2: d->u->wst.ptr = d->dat[0x2]; break; 95 case 0x2: d->u->wst.ptr = d->dat[0x2]; break;
79 case 0x3: d->u->rst.ptr = d->dat[0x3]; break; 96 case 0x3: d->u->rst.ptr = d->dat[0x3]; break;
80 case 0xf: d->u->ram.ptr = 0x0000; break; 97 case 0xf: d->u->ram.ptr = 0x0000; break;
81 } 98 }
82 if(b0 > 0x7 && b0 < 0xe) { 99 if(b0 > 0x7 && b0 < 0xe) {
83 docolors(d); 100 docolors(d);
@@ -91,51 +108,51 @@ screen_talk(Device *d, u8 b0, u8 w) {
91 if (w) { 108 if (w) {
92 switch (b0) { 109 switch (b0) {
93 case 0x1: { 110 case 0x1: {
94 d->vector = mempeek16(d->dat, 0x0); 111 d->vector = mempeek16(d->dat, 0x0);
95 } break; 112 } break;
96 case 0xe: { 113 case 0xe: {
97 u16 x = mempeek16(d->dat, 0x8); 114 u16 x = mempeek16(d->dat, 0x8);
98 u16 y = mempeek16(d->dat, 0xa); 115 u16 y = mempeek16(d->dat, 0xa);
99 u8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; 116 u8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
100 u8 *layer = d->dat[0xe] >> 4 & 0x1 ? pixels_fg : pixels_bg; 117 u8 *layer = d->dat[0xe] >> 4 & 0x1 ? pixels_fg : pixels_bg;
101 u8 mode = d->dat[0xe] >> 5; 118 u8 mode = d->dat[0xe] >> 5;
102 u8 color = d->dat[0xf] & 0xf; 119 u8 color = d->dat[0xf] & 0xf;
103 if(!mode) { 120 if(!mode) {
104 ppu_pixel(layer, x, y, d->dat[0xe] & 0x3); 121 ppu_pixel(layer, x, y, d->dat[0xe] & 0x3);
105 } else if(mode-- & 0x1) { 122 } else if(mode-- & 0x1) {
106 u8 flipx = mode & 0x2; 123 u8 flipx = mode & 0x2;
107 u8 flipy = mode & 0x4; 124 u8 flipy = mode & 0x4;
108 ppu_1bpp(layer, x, y, addr, color, flipx, flipy); 125 ppu_1bpp(layer, x, y, addr, color, flipx, flipy);
109 } else { 126 } else {
110 u8 flipx = mode & 0x2; 127 u8 flipx = mode & 0x2;
111 u8 flipy = mode & 0x4; 128 u8 flipy = mode & 0x4;
112 ppu_2bpp(layer, x, y, addr, color, flipx, flipy); 129 ppu_2bpp(layer, x, y, addr, color, flipx, flipy);
113 } 130 }
114 if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 1); } 131 if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 1); }
115 if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 1); } 132 if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 1); }
116 } break; 133 } break;
117 case 0xf: { 134 case 0xf: {
118 u16 x = mempeek16(d->dat, 0x8); 135 u16 x = mempeek16(d->dat, 0x8);
119 u16 y = mempeek16(d->dat, 0xa); 136 u16 y = mempeek16(d->dat, 0xa);
120 u8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; 137 u8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
121 u8 *layer = d->dat[0xf] >> 6 & 0x1 ? pixels_fg : pixels_bg; 138 u8 *layer = d->dat[0xf] >> 6 & 0x1 ? pixels_fg : pixels_bg;
122 u8 color = d->dat[0xf] & 0xf; 139 u8 color = d->dat[0xf] & 0xf;
123 u8 flipx = (d->dat[0xf] >> 0x4) & 0x1; 140 u8 flipx = (d->dat[0xf] >> 0x4) & 0x1;
124 u8 flipy = (d->dat[0xf] >> 0x5) & 0x1; 141 u8 flipy = (d->dat[0xf] >> 0x5) & 0x1;
125 if(d->dat[0xf] >> 0x7 & 0x1) { 142 if(d->dat[0xf] >> 0x7 & 0x1) {
126 ppu_2bpp(layer, x, y, addr, color, flipx, flipy); 143 ppu_2bpp(layer, x, y, addr, color, flipx, flipy);
127 if(d->dat[0x6] & 0x04) { 144 if(d->dat[0x6] & 0x04) {
128 mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 16); 145 mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 16);
129 } 146 }
130 } else { 147 } else {
131 ppu_1bpp(layer, x, y, addr, color, flipx, flipy); 148 ppu_1bpp(layer, x, y, addr, color, flipx, flipy);
132 if(d->dat[0x6] & 0x04) { 149 if(d->dat[0x6] & 0x04) {
133 mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 8); 150 mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 8);
134 } 151 }
135 } 152 }
136 if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 8); } 153 if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 8); }
137 if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 8); } 154 if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 8); }
138 } break; 155 } break;
139 default: break; 156 default: break;
140 } 157 }
141 } 158 }
@@ -226,22 +243,20 @@ main(int argc, char *argv[]) {
226 } 243 }
227 init_uxn(argv[1]); 244 init_uxn(argv[1]);
228 245
229 // Main loop. 246 // Main loop.
230 uxn_eval(&u, 0x0100); 247 uxn_eval(&u, 0x0100);
231 // u64 current_ticks = timer_get_ticks(); 248 Time frame_time = time_now();
232 while (true) { 249 while (true) {
233 // Echo input to standard output. 250 size_t elapsed = time_elapsed(frame_time);
234 uxn_eval(&u, mempeek16(devscreen->dat, 0)); 251 if (elapsed >= 16666666) {
235 252 // Echo input to standard output.
236 // Blit ppu.pixels to the framebuffer. 253 uxn_eval(&u, mempeek16(devscreen->dat, 0));
237 blit_framebuffer();
238 254
239 // TODO: Sync at 60 Hz. 255 // Blit ppu.pixels to the framebuffer.
240 // if ((timer_get_ticks() - current_ticks) < 16666) { 256 blit_framebuffer();
241 // wait(16666 - (timer_get_ticks() - current_ticks)); 257 frame_time = time_now();
242 // } 258 }
243 // current_ticks = timer_get_ticks();
244 } 259 }
245 260
246 return 0; 261 return 0;
247} 262}