aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..77cabcc
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,155 @@
1#include <string.h>
2
3#include "common.h"
4#include "bitmap.h"
5#include "text.h"
6#include "small-font.c"
7
8#include "uxn/uxn.h"
9#include "uxn/uxn.c"
10#include "uxn/devices/ppu.h"
11#include "uxn/devices/ppu.c"
12// #include "uxn/roms/console.c"
13#include "uxn/roms/dvd.c"
14// #include "uxn/roms/proportional_fonts.c"
15// #include "uxn/roms/automata.c"
16// #include "uxn/roms/life.c"
17
18static Ppu ppu;
19u8 reqdraw = 0;
20static Device *devscreen;
21
22void
23nil_talk(Device *d, Uint8 b0, Uint8 w) {
24 (void)d;
25 (void)b0;
26 (void)w;
27}
28
29void
30console_talk(Device *d, u8 b0, u8 w) {
31 if(!w) {
32 return;
33 }
34 switch(b0) {
35 case 0x8: txt_printf("%c", d->dat[0x8]); break;
36 case 0x9: txt_printf("0x%02x", d->dat[0x9]); break;
37 case 0xb: txt_printf("0x%04x", mempeek16(d->dat, 0xa)); break;
38 case 0xd: txt_printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break;
39 }
40}
41
42void
43system_talk(Device *d, Uint8 b0, Uint8 w)
44{
45 if(!w) {
46 d->dat[0x2] = d->u->wst.ptr;
47 d->dat[0x3] = d->u->rst.ptr;
48 } else {
49 putcolors(&ppu, &d->dat[0x8]);
50 reqdraw = 1;
51 }
52 (void)b0;
53}
54
55void
56screen_talk(Device *d, Uint8 b0, Uint8 w) {
57 if(w && b0 == 0xe) {
58 Uint16 x = mempeek16(d->dat, 0x8);
59 Uint16 y = mempeek16(d->dat, 0xa);
60 Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
61 Uint8 *layer = d->dat[0xe] >> 4 & 0x1 ? ppu.fg : ppu.bg;
62 Uint8 mode = d->dat[0xe] >> 5;
63 if(!mode) {
64 putpixel(&ppu, layer, x, y, d->dat[0xe] & 0x3);
65 } else if(mode-- & 0x1) {
66 puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
67 } else {
68 putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
69 }
70 reqdraw = 1;
71 }
72}
73
74void
75redraw(Uint16 *dst, Uxn *u) {
76 // TODO: The screen will flicker but using Mode4 for double buffering would
77 // be way too slow.
78 drawppu(&ppu);
79 clear_screen_m3();
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}
88
89void
90init_uxn(Uxn *u) {
91 // Initialize PPU.
92 initppu(&ppu, 30, 20, 0);
93
94 // Copy rom to VM.
95 memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom));
96
97 // Prepare devices.
98 portuxn(u, 0x0, "system", system_talk);
99 portuxn(u, 0x1, "console", console_talk);
100 devscreen = portuxn(u, 0x2, "screen", screen_talk);
101 portuxn(u, 0x3, "---", nil_talk);
102 portuxn(u, 0x4, "---", nil_talk);
103 portuxn(u, 0x5, "---", nil_talk);
104 portuxn(u, 0x6, "---", nil_talk);
105 portuxn(u, 0x7, "---", nil_talk);
106 portuxn(u, 0x8, "---", nil_talk);
107 portuxn(u, 0x9, "---", nil_talk);
108 portuxn(u, 0xa, "---", nil_talk);
109 portuxn(u, 0xb, "---", nil_talk);
110 portuxn(u, 0xc, "---", nil_talk);
111 portuxn(u, 0xd, "---", nil_talk);
112 portuxn(u, 0xe, "---", nil_talk);
113 portuxn(u, 0xf, "---", nil_talk);
114 mempoke16(devscreen->dat, 2, ppu.hor * 8);
115 mempoke16(devscreen->dat, 4, ppu.ver * 8);
116}
117
118int main(void) {
119 // Initialize display mode and bg palette.
120 DISP_CTRL = DISP_MODE_3 | DISP_BG_2;
121
122 // Initialize text engine.
123 txt_init_bitmap(
124 TXT_MODE_MODE3,
125 (Font){
126 .data = small_font,
127 .char_width = 4,
128 .char_height = 8,
129 .color = COLOR_BLUE,
130 .char_map = small_font_map,
131 });
132
133 // Register interrupts.
134 irq_init();
135 irs_set(IRQ_VBLANK, irs_stub);
136
137 // Initialize VM.
138 Uxn u = {0};
139 init_uxn(&u);
140 evaluxn(&u, 0x0100);
141
142 // Main loop.
143 int frame_counter = 0;
144 while(true) {
145 bios_vblank_wait();
146 poll_keys();
147 evaluxn(&u, mempeek16(devscreen->dat, 0));
148 if(reqdraw) {
149 redraw(ppu.output, &u);
150 }
151 frame_counter++;
152 };
153
154 return 0;
155}