aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-18 18:18:18 +0200
committerBad Diode <bd@badd10de.dev>2021-05-18 18:18:18 +0200
commitec5b9644db2ff26cc6f0cc3d84854b714a25eff9 (patch)
treee6806bbe0bc84a20d11f620c0425ab58aba12b42 /src
parent0c7265cf0de9d4ec95d28c5e103c00a63f4a1697 (diff)
downloaduxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.tar.gz
uxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.zip
Draw directly to the FRAMEBUFFER
Diffstat (limited to 'src')
-rw-r--r--src/main.c118
-rw-r--r--src/uxn/devices/ppu.c21
-rw-r--r--src/uxn/uxn.c46
3 files changed, 63 insertions, 122 deletions
diff --git a/src/main.c b/src/main.c
index 77cabcc..9866f19 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,14 +21,14 @@ static Device *devscreen;
21 21
22void 22void
23nil_talk(Device *d, Uint8 b0, Uint8 w) { 23nil_talk(Device *d, Uint8 b0, Uint8 w) {
24 (void)d; 24 (void)d;
25 (void)b0; 25 (void)b0;
26 (void)w; 26 (void)w;
27} 27}
28 28
29void 29void
30console_talk(Device *d, u8 b0, u8 w) { 30console_talk(Device *d, u8 b0, u8 w) {
31 if(!w) { 31 if(!w) {
32 return; 32 return;
33 } 33 }
34 switch(b0) { 34 switch(b0) {
@@ -42,77 +42,70 @@ console_talk(Device *d, u8 b0, u8 w) {
42void 42void
43system_talk(Device *d, Uint8 b0, Uint8 w) 43system_talk(Device *d, Uint8 b0, Uint8 w)
44{ 44{
45 if(!w) { 45 if(!w) {
46 d->dat[0x2] = d->u->wst.ptr; 46 d->dat[0x2] = d->u->wst.ptr;
47 d->dat[0x3] = d->u->rst.ptr; 47 d->dat[0x3] = d->u->rst.ptr;
48 } else { 48 } else {
49 putcolors(&ppu, &d->dat[0x8]); 49 putcolors(&ppu, &d->dat[0x8]);
50 reqdraw = 1; 50 reqdraw = 1;
51 } 51 }
52 (void)b0; 52 (void)b0;
53} 53}
54 54
55void 55void
56screen_talk(Device *d, Uint8 b0, Uint8 w) { 56screen_talk(Device *d, Uint8 b0, Uint8 w) {
57 if(w && b0 == 0xe) { 57 if(w && b0 == 0xe) {
58 Uint16 x = mempeek16(d->dat, 0x8); 58 Uint16 x = mempeek16(d->dat, 0x8);
59 Uint16 y = mempeek16(d->dat, 0xa); 59 Uint16 y = mempeek16(d->dat, 0xa);
60 Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; 60 Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
61 Uint8 *layer = d->dat[0xe] >> 4 & 0x1 ? ppu.fg : ppu.bg; 61 Uint8 *layer = d->dat[0xe] >> 4 & 0x1 ? ppu.fg : ppu.bg;
62 Uint8 mode = d->dat[0xe] >> 5; 62 Uint8 mode = d->dat[0xe] >> 5;
63 if(!mode) { 63 if(!mode) {
64 putpixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); 64 putpixel(&ppu, layer, x, y, d->dat[0xe] & 0x3);
65 } else if(mode-- & 0x1) { 65 } else if(mode-- & 0x1) {
66 puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); 66 puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
67 } else { 67 } else {
68 putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); 68 putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
69 } 69 }
70 reqdraw = 1; 70 reqdraw = 1;
71 } 71 }
72} 72}
73 73
74void 74void
75redraw(Uint16 *dst, Uxn *u) { 75redraw(Uint16 *dst, Uxn *u) {
76 // TODO: The screen will flicker but using Mode4 for double buffering would 76 // TODO: The screen will flicker but using Mode4 for double buffering would
77 // be way too slow. 77 // be way too slow.
78 drawppu(&ppu); 78 drawppu(&ppu);
79 clear_screen_m3(); 79 reqdraw = 0;
80 // Copy ppu data to framebuffer.
81 for (size_t j = 0; j < ppu.height; ++j) {
82 for (size_t i = 0; i < ppu.width; ++i) {
83 FRAMEBUFFER[j][i] = ppu.output[i + j * ppu.width];
84 }
85 }
86 reqdraw = 0;
87} 80}
88 81
89void 82void
90init_uxn(Uxn *u) { 83init_uxn(Uxn *u) {
91 // Initialize PPU. 84 // Initialize PPU.
92 initppu(&ppu, 30, 20, 0); 85 initppu(&ppu, 30, 20, 0);
93 86
94 // Copy rom to VM. 87 // Copy rom to VM.
95 memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); 88 memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom));
96 89
97 // Prepare devices. 90 // Prepare devices.
98 portuxn(u, 0x0, "system", system_talk); 91 portuxn(u, 0x0, "system", system_talk);
99 portuxn(u, 0x1, "console", console_talk); 92 portuxn(u, 0x1, "console", console_talk);
100 devscreen = portuxn(u, 0x2, "screen", screen_talk); 93 devscreen = portuxn(u, 0x2, "screen", screen_talk);
101 portuxn(u, 0x3, "---", nil_talk); 94 portuxn(u, 0x3, "---", nil_talk);
102 portuxn(u, 0x4, "---", nil_talk); 95 portuxn(u, 0x4, "---", nil_talk);
103 portuxn(u, 0x5, "---", nil_talk); 96 portuxn(u, 0x5, "---", nil_talk);
104 portuxn(u, 0x6, "---", nil_talk); 97 portuxn(u, 0x6, "---", nil_talk);
105 portuxn(u, 0x7, "---", nil_talk); 98 portuxn(u, 0x7, "---", nil_talk);
106 portuxn(u, 0x8, "---", nil_talk); 99 portuxn(u, 0x8, "---", nil_talk);
107 portuxn(u, 0x9, "---", nil_talk); 100 portuxn(u, 0x9, "---", nil_talk);
108 portuxn(u, 0xa, "---", nil_talk); 101 portuxn(u, 0xa, "---", nil_talk);
109 portuxn(u, 0xb, "---", nil_talk); 102 portuxn(u, 0xb, "---", nil_talk);
110 portuxn(u, 0xc, "---", nil_talk); 103 portuxn(u, 0xc, "---", nil_talk);
111 portuxn(u, 0xd, "---", nil_talk); 104 portuxn(u, 0xd, "---", nil_talk);
112 portuxn(u, 0xe, "---", nil_talk); 105 portuxn(u, 0xe, "---", nil_talk);
113 portuxn(u, 0xf, "---", nil_talk); 106 portuxn(u, 0xf, "---", nil_talk);
114 mempoke16(devscreen->dat, 2, ppu.hor * 8); 107 mempoke16(devscreen->dat, 2, ppu.hor * 8);
115 mempoke16(devscreen->dat, 4, ppu.ver * 8); 108 mempoke16(devscreen->dat, 4, ppu.ver * 8);
116} 109}
117 110
118int main(void) { 111int main(void) {
@@ -126,7 +119,7 @@ int main(void) {
126 .data = small_font, 119 .data = small_font,
127 .char_width = 4, 120 .char_width = 4,
128 .char_height = 8, 121 .char_height = 8,
129 .color = COLOR_BLUE, 122 .color = COLOR_WHITE,
130 .char_map = small_font_map, 123 .char_map = small_font_map,
131 }); 124 });
132 125
@@ -137,17 +130,24 @@ int main(void) {
137 // Initialize VM. 130 // Initialize VM.
138 Uxn u = {0}; 131 Uxn u = {0};
139 init_uxn(&u); 132 init_uxn(&u);
140 evaluxn(&u, 0x0100); 133 evaluxn(&u, 0x0100);
141 134
142 // Main loop. 135 // Main loop.
143 int frame_counter = 0; 136 int frame_counter = 0;
144 while(true) { 137 while(true) {
145 bios_vblank_wait(); 138 bios_vblank_wait();
146 poll_keys(); 139 poll_keys();
147 evaluxn(&u, mempeek16(devscreen->dat, 0)); 140 profile_start();
148 if(reqdraw) { 141 evaluxn(&u, mempeek16(devscreen->dat, 0));
149 redraw(ppu.output, &u); 142 int eval_cycles = profile_stop();
143 profile_start();
144 if(reqdraw) {
145 redraw(ppu.output, &u);
150 } 146 }
147 int redraw_cycles = profile_stop();
148 txt_position(0, 0);
149 txt_printf("EVAL: %d\n", eval_cycles);
150 txt_printf("REDRAW: %d\n", redraw_cycles);
151 frame_counter++; 151 frame_counter++;
152 }; 152 };
153 153
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c
index b977f97..06d84bf 100644
--- a/src/uxn/devices/ppu.c
+++ b/src/uxn/devices/ppu.c
@@ -121,26 +121,7 @@ void
121drawpixel(Ppu *p, Uint16 x, Uint16 y, Uint8 color) 121drawpixel(Ppu *p, Uint16 x, Uint16 y, Uint8 color)
122{ 122{
123 if(x >= p->pad && x <= p->width - p->pad - 1 && y >= p->pad && y <= p->height - p->pad - 1) 123 if(x >= p->pad && x <= p->width - p->pad - 1 && y >= p->pad && y <= p->height - p->pad - 1)
124 p->output[y * p->width + x] = p->colors[color]; 124 FRAMEBUFFER[y][x] = p->colors[color];
125}
126
127void
128drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr)
129{
130 Uint8 i, x, y, b;
131 for(i = 0; i < 0x20; ++i) { /* memory */
132 x = ((i % 8) * 3 + 1) * 8, y = (i / 8 + 1) * 8, b = stack[i];
133 puticn(p, p->bg, x, y, font[(b >> 4) & 0xf], 1 + (ptr == i) * 0x7, 0, 0);
134 puticn(p, p->bg, x + 8, y, font[b & 0xf], 1 + (ptr == i) * 0x7, 0, 0);
135 }
136 for(x = 0; x < 0x20; ++x) {
137 drawpixel(p, x, p->height / 2, 2);
138 drawpixel(p, p->width - x, p->height / 2, 2);
139 drawpixel(p, p->width / 2, p->height - x, 2);
140 drawpixel(p, p->width / 2, x, 2);
141 drawpixel(p, p->width / 2 - 16 + x, p->height / 2, 2);
142 drawpixel(p, p->width / 2, p->height / 2 - 16 + x, 2);
143 }
144} 125}
145 126
146void 127void
diff --git a/src/uxn/uxn.c b/src/uxn/uxn.c
index 796a980..08b3b9b 100644
--- a/src/uxn/uxn.c
+++ b/src/uxn/uxn.c
@@ -116,14 +116,6 @@ void (*ops[])(Uxn *u) = {
116 116
117#pragma mark - Core 117#pragma mark - Core
118 118
119int
120haltuxn(Uxn *u, char *name, int id)
121{
122 txt_printf("Halted: %s#%04x, at 0x%04x\n", name, id, u->ram.ptr);
123 u->ram.ptr = 0;
124 return 0;
125}
126
127void 119void
128opcuxn(Uxn *u, Uint8 instr) 120opcuxn(Uxn *u, Uint8 instr)
129{ 121{
@@ -140,46 +132,14 @@ opcuxn(Uxn *u, Uint8 instr)
140} 132}
141 133
142int 134int
143stepuxn(Uxn *u, Uint8 instr)
144{
145 opcuxn(u, instr);
146 if(u->wst.error)
147 return haltuxn(u, u->wst.error == 1 ? "Working-stack underflow" : "Working-stack overflow", instr);
148 if(u->rst.error)
149 return haltuxn(u, u->rst.error == 1 ? "Return-stack underflow" : "Return-stack overflow", instr);
150 return 1;
151}
152
153int
154evaluxn(Uxn *u, Uint16 vec) 135evaluxn(Uxn *u, Uint16 vec)
155{ 136{
156 u->ram.ptr = vec; 137 u->ram.ptr = vec;
157 u->wst.error = 0; 138 u->wst.error = 0;
158 u->rst.error = 0; 139 u->rst.error = 0;
159 while(u->ram.ptr) 140 while(u->ram.ptr) {
160 if(!stepuxn(u, u->ram.dat[u->ram.ptr++])) 141 opcuxn(u, u->ram.dat[u->ram.ptr++]);
161 return 0; 142 }
162 return 1;
163}
164
165int
166bootuxn(Uxn *u)
167{
168 size_t i;
169 char *cptr = (char *)u;
170 for(i = 0; i < sizeof(*u); i++)
171 cptr[i] = 0;
172 return 1;
173}
174
175int
176loaduxn(Uxn *u, char *filepath)
177{
178 FILE *f;
179 if(!(f = fopen(filepath, "rb")))
180 return haltuxn(u, "Missing input rom.", 0);
181 fread(u->ram.dat + PAGE_PROGRAM, sizeof(u->ram.dat) - PAGE_PROGRAM, 1, f);
182 txt_printf("Uxn loaded[%s].\n", filepath);
183 return 1; 143 return 1;
184} 144}
185 145