diff options
author | Bad Diode <bd@badd10de.dev> | 2022-03-04 15:16:29 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-03-04 15:16:29 +0100 |
commit | 232f303cf139ec7aa0b3af1c89003c3f01a9f25b (patch) | |
tree | 82ca690528043d179450ca4830bbc138e88fe80e | |
parent | bfd3c8ece9299146b94efca129b1f382c79da346 (diff) | |
download | uxnfb-232f303cf139ec7aa0b3af1c89003c3f01a9f25b.tar.gz uxnfb-232f303cf139ec7aa0b3af1c89003c3f01a9f25b.zip |
Port uxnrpi main function
-rw-r--r-- | src/main.c | 191 | ||||
-rw-r--r-- | src/ppu.c | 2 |
2 files changed, 166 insertions, 27 deletions
@@ -13,37 +13,176 @@ | |||
13 | #include "uxn-fast.c" | 13 | #include "uxn-fast.c" |
14 | #include "rom.c" | 14 | #include "rom.c" |
15 | 15 | ||
16 | // static Uxn u; | 16 | static Uxn u; |
17 | // static Device *devscreen; | 17 | static Device *devscreen; |
18 | // static Device *devctrl; | 18 | static Device *devctrl; |
19 | // static Device *devmouse; | 19 | static Device *devmouse; |
20 | // static Device *devaudio; | 20 | static Device *devaudio; |
21 | |||
22 | void | ||
23 | nil_talk(Device *d, u8 b0, u8 w) { | ||
24 | (void)d; | ||
25 | (void)b0; | ||
26 | (void)w; | ||
27 | } | ||
28 | |||
29 | void | ||
30 | console_talk(Device *d, u8 b0, u8 w) { | ||
31 | (void)d; | ||
32 | (void)b0; | ||
33 | (void)w; | ||
34 | // char stmp[2]; | ||
35 | // if(!w) { | ||
36 | // return; | ||
37 | // } | ||
38 | // switch(b0) { | ||
39 | // case 0x8: stmp[0] = d->dat[0x8]; stmp[1] = 0; uart_puts(stmp); break; | ||
40 | // TODO: implement printf for the uart to be able to format | ||
41 | // numbers. | ||
42 | // case 0x9: txt_printf("0x%02x", d->dat[0x9]); break; | ||
43 | // case 0xb: txt_printf("0x%04x", mempeek16(d->dat, 0xa)); break; | ||
44 | // case 0xd: txt_printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break; | ||
45 | // } | ||
46 | } | ||
47 | |||
48 | static void | ||
49 | docolors(Device *d) { | ||
50 | for(size_t i = 0; i < 4; ++i) { | ||
51 | u8 r = ((d->dat[0x8 + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | ||
52 | u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | ||
53 | u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | ||
54 | |||
55 | if (rgb_order) { | ||
56 | palette[i] = (b << 16) | (g << 8) | r; | ||
57 | } else { | ||
58 | palette[i] = (r << 16) | (g << 8) | b; | ||
59 | } | ||
60 | } | ||
61 | for(size_t i = 4; i < 16; ++i) { | ||
62 | palette[i] = palette[i / 4]; | ||
63 | } | ||
64 | |||
65 | // Redraw the screen if we change the color palette. | ||
66 | reqdraw = 1; | ||
67 | redraw_screen(); | ||
68 | } | ||
69 | |||
70 | void | ||
71 | system_talk(Device *d, u8 b0, u8 w) { | ||
72 | if(!w) { /* read */ | ||
73 | switch(b0) { | ||
74 | case 0x2: d->dat[0x2] = d->u->wst.ptr; break; | ||
75 | case 0x3: d->dat[0x3] = d->u->rst.ptr; break; | ||
76 | } | ||
77 | } else { /* write */ | ||
78 | switch(b0) { | ||
79 | case 0x2: d->u->wst.ptr = d->dat[0x2]; break; | ||
80 | case 0x3: d->u->rst.ptr = d->dat[0x3]; break; | ||
81 | case 0xf: d->u->ram.ptr = 0x0000; break; | ||
82 | } | ||
83 | if(b0 > 0x7 && b0 < 0xe) { | ||
84 | docolors(d); | ||
85 | } | ||
86 | } | ||
87 | (void)b0; | ||
88 | } | ||
89 | |||
90 | void | ||
91 | screen_talk(Device *d, u8 b0, u8 w) { | ||
92 | if(w && b0 == 0xe) { | ||
93 | Uint16 x = mempeek16(d->dat, 0x8); | ||
94 | Uint16 y = mempeek16(d->dat, 0xa); | ||
95 | Uint8 layer = d->dat[0xe] >> 4 & 0x1; | ||
96 | ppu_pixel(layer, x, y, d->dat[0xe] & 0x3); | ||
97 | reqdraw = 1; | ||
98 | } else if(w && b0 == 0xf) { | ||
99 | Uint16 x = mempeek16(d->dat, 0x8); | ||
100 | Uint16 y = mempeek16(d->dat, 0xa); | ||
101 | Uint8 layer = d->dat[0xf] >> 0x6 & 0x1; | ||
102 | Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; | ||
103 | if(d->dat[0xf] >> 0x7 & 0x1) | ||
104 | ppu_2bpp(layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); | ||
105 | else | ||
106 | ppu_1bpp(layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); | ||
107 | reqdraw = 1; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | audio_talk(Device *d, u8 b0, u8 w) { | ||
113 | // TODO: Implement... | ||
114 | (void)d; | ||
115 | (void)b0; | ||
116 | (void)w; | ||
117 | } | ||
118 | |||
119 | void | ||
120 | datetime_talk(Device *d, u8 b0, u8 w) { | ||
121 | // TODO: Implement... | ||
122 | (void)d; | ||
123 | (void)b0; | ||
124 | (void)w; | ||
125 | } | ||
126 | |||
127 | void | ||
128 | file_talk(Device *d, u8 b0, u8 w) { | ||
129 | // TODO: Implement... | ||
130 | (void)d; | ||
131 | (void)b0; | ||
132 | (void)w; | ||
133 | } | ||
134 | |||
135 | void | ||
136 | init_uxn() { | ||
137 | // Clear UXN memory. | ||
138 | memset(&u, 0, sizeof(Uxn)); | ||
139 | |||
140 | ppu_init(); | ||
141 | |||
142 | // Copy rom to VM. | ||
143 | memcpy(u.ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); | ||
144 | |||
145 | // Prepare devices. | ||
146 | uxn_port(&u, 0x0, "system", system_talk); | ||
147 | uxn_port(&u, 0x1, "console", console_talk); | ||
148 | devscreen = uxn_port(&u, 0x2, "screen", screen_talk); | ||
149 | devaudio = uxn_port(&u, 0x3, "audio0", audio_talk); | ||
150 | uxn_port(&u, 0x4, "audio1", audio_talk); | ||
151 | uxn_port(&u, 0x5, "audio2", audio_talk); | ||
152 | uxn_port(&u, 0x6, "audio3", audio_talk); | ||
153 | uxn_port(&u, 0x7, "---", nil_talk); | ||
154 | devctrl = uxn_port(&u, 0x8, "controller", nil_talk); | ||
155 | devmouse = uxn_port(&u, 0x9, "mouse", nil_talk); | ||
156 | uxn_port(&u, 0xa, "file", file_talk); | ||
157 | uxn_port(&u, 0xb, "datetime", datetime_talk); | ||
158 | uxn_port(&u, 0xc, "---", nil_talk); | ||
159 | uxn_port(&u, 0xd, "---", nil_talk); | ||
160 | uxn_port(&u, 0xe, "---", nil_talk); | ||
161 | uxn_port(&u, 0xf, "---", nil_talk); | ||
162 | mempoke16(devscreen->dat, 2, screen_width); | ||
163 | mempoke16(devscreen->dat, 4, screen_height); | ||
164 | } | ||
21 | 165 | ||
22 | int | 166 | int |
23 | main(void) { | 167 | main(void) { |
24 | ppu_init(); | 168 | init_uxn(); |
25 | 169 | ||
26 | // Main loop. | 170 | // Main loop. |
27 | uint8_t shade = 0; | 171 | uxn_eval(&u, 0x0100); |
28 | size_t counter = 0; | 172 | // u64 current_ticks = timer_get_ticks(); |
29 | size_t direction = 1; | 173 | while (true) { |
30 | while (true) { | 174 | // Echo input to standard output. |
31 | for (size_t j = 0; j < screen_height; j++) { | 175 | uxn_eval(&u, mempeek16(devscreen->dat, 0)); |
32 | for (size_t i = 0; i < screen_width; i++) { | 176 | |
33 | framebuffer[j * screen_width + i] = shade; | 177 | // Blit ppu.pixels to the framebuffer. |
34 | } | 178 | blit_framebuffer(); |
35 | } | 179 | |
36 | counter++; | 180 | // TODO: Sync at 60 Hz. |
37 | if (counter > 10) { | 181 | // if ((timer_get_ticks() - current_ticks) < 16666) { |
38 | shade += direction; | 182 | // wait(16666 - (timer_get_ticks() - current_ticks)); |
39 | counter = 0; | 183 | // } |
40 | } | 184 | // current_ticks = timer_get_ticks(); |
41 | if (shade == 0xFF) { | 185 | } |
42 | direction = -1; | ||
43 | } else if (shade == 0x00) { | ||
44 | direction = 1; | ||
45 | } | ||
46 | } | ||
47 | 186 | ||
48 | return 0; | 187 | return 0; |
49 | } | 188 | } |
@@ -25,7 +25,7 @@ static u8 *pixels_buf; | |||
25 | static u8 *dirty_lines; | 25 | static u8 *dirty_lines; |
26 | static u8 reqdraw = 0; | 26 | static u8 reqdraw = 0; |
27 | // TODO: Probably should consider this | 27 | // TODO: Probably should consider this |
28 | // static u32 rgb_order; | 28 | static u32 rgb_order = 0; |
29 | 29 | ||
30 | static u8 blending[5][16] = { | 30 | static u8 blending[5][16] = { |
31 | {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0}, | 31 | {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0}, |