diff options
author | Bad Diode <bd@badd10de.dev> | 2021-09-09 15:56:16 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-09-09 15:56:16 +0200 |
commit | a1bc2913625b45c6ac28b856b8ee2051489479b7 (patch) | |
tree | b2225cfc55710080173f09853cd50f68773a9667 | |
parent | 4eaa5313c9c591dffb6f52c2674009622cbdd28e (diff) | |
download | uxnrpi-a1bc2913625b45c6ac28b856b8ee2051489479b7.tar.gz uxnrpi-a1bc2913625b45c6ac28b856b8ee2051489479b7.zip |
Add workarounds for working hardware RPI4
For now we need to disable compiler optimizations, since they seem to
mess up the mempoke16 memory access.
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | src/common.h | 20 | ||||
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/ppu.c | 25 |
4 files changed, 52 insertions, 14 deletions
@@ -2,6 +2,8 @@ | |||
2 | .SUFFIXES: | 2 | .SUFFIXES: |
3 | .PHONY: clean run | 3 | .PHONY: clean run |
4 | 4 | ||
5 | RPI_VERSION ?= 3 | ||
6 | |||
5 | # Compiler. | 7 | # Compiler. |
6 | AS := aarch64-elf-as | 8 | AS := aarch64-elf-as |
7 | CC := aarch64-elf-gcc | 9 | CC := aarch64-elf-gcc |
@@ -21,7 +23,8 @@ OBJ_START = $(BUILD_DIR)/start.o | |||
21 | OBJ_MAIN = $(BUILD_DIR)/main.o | 23 | OBJ_MAIN = $(BUILD_DIR)/main.o |
22 | SRC_LINK = $(SRC_DIR)/linker.ld | 24 | SRC_LINK = $(SRC_DIR)/linker.ld |
23 | 25 | ||
24 | CFLAGS := -Wall -ffreestanding -O2 -nostdlib -lgcc -mgeneral-regs-only -fstack-protector | 26 | CFLAGS := -Wall -ffreestanding -O1 -nostdlib -lgcc -mgeneral-regs-only -fstack-protector |
27 | CFLAGS += -DRPI_VERSION=$(RPI_VERSION) | ||
25 | AFLAGS := | 28 | AFLAGS := |
26 | LDFLAGS := | 29 | LDFLAGS := |
27 | 30 | ||
diff --git a/src/common.h b/src/common.h index b983ca5..94e499e 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -3,6 +3,16 @@ | |||
3 | 3 | ||
4 | // Header definitions for memory mapped IO and common utilities. | 4 | // Header definitions for memory mapped IO and common utilities. |
5 | 5 | ||
6 | // Setup the right base memory address for different types of RPI. | ||
7 | #if RPI_VERSION == 3 | ||
8 | #define MEM_BASE 0x3F000000 | ||
9 | #elif RPI_VERSION == 4 | ||
10 | #define MEM_BASE 0xFE000000 | ||
11 | #else | ||
12 | #define MEM_BASE 0 | ||
13 | #error RPI_VERSION NOT DEFINED | ||
14 | #endif | ||
15 | |||
6 | #include "shorthand.h" | 16 | #include "shorthand.h" |
7 | 17 | ||
8 | // | 18 | // |
@@ -15,8 +25,6 @@ void delay(u64 ticks); | |||
15 | // Clear N bytes at the given address. Implemented in start.s. | 25 | // Clear N bytes at the given address. Implemented in start.s. |
16 | void memzero(u64 src, u32 n); | 26 | void memzero(u64 src, u32 n); |
17 | 27 | ||
18 | #define MEM_BASE 0x3F000000 | ||
19 | |||
20 | // | 28 | // |
21 | // GPIO Registers. | 29 | // GPIO Registers. |
22 | // | 30 | // |
@@ -112,8 +120,14 @@ uart_init() { | |||
112 | AUX->mu_lcr = 3; | 120 | AUX->mu_lcr = 3; |
113 | AUX->mu_mcr = 0; | 121 | AUX->mu_mcr = 0; |
114 | 122 | ||
123 | #if RPI_VERSION == 3 | ||
115 | AUX->mu_baud_rate = 270; // RPI3: 115200 @ 250 MHz | 124 | AUX->mu_baud_rate = 270; // RPI3: 115200 @ 250 MHz |
116 | // AUX->mu_baud_rate = 541; // RPI4: 115200 @ 500 MHz | 125 | #endif |
126 | |||
127 | #if RPI_VERSION == 4 | ||
128 | AUX->mu_baud_rate = 541; // RPI4: 115200 @ 500 MHz | ||
129 | #endif | ||
130 | |||
117 | AUX->mu_control = 3; | 131 | AUX->mu_control = 3; |
118 | return; | 132 | return; |
119 | } | 133 | } |
@@ -39,7 +39,16 @@ docolors(Device *d) { | |||
39 | u8 r = ((d->dat[0x8 + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | 39 | u8 r = ((d->dat[0x8 + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; |
40 | u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | 40 | u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; |
41 | u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; | 41 | u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; |
42 | |||
43 | // NOTE: This is a bit of a hack. We probably want to check the RGB byte | ||
44 | // order on the mailbox request. | ||
45 | #if RPI_VERSION == 3 | ||
42 | palette[i] = (b << 16) | (g << 8) | r; | 46 | palette[i] = (b << 16) | (g << 8) | r; |
47 | #endif | ||
48 | |||
49 | #if RPI_VERSION == 4 | ||
50 | palette[i] = (r << 16) | (g << 8) | b; | ||
51 | #endif | ||
43 | } | 52 | } |
44 | for(size_t i = 4; i < 16; ++i) { | 53 | for(size_t i = 4; i < 16; ++i) { |
45 | palette[i] = palette[i / 4]; | 54 | palette[i] = palette[i / 4]; |
@@ -124,6 +133,13 @@ init_uxn() { | |||
124 | uart_init(); | 133 | uart_init(); |
125 | 134 | ||
126 | uart_puts("Initializing UXN.\n"); | 135 | uart_puts("Initializing UXN.\n"); |
136 | |||
137 | // Clear UXN memory. | ||
138 | u8 * uxnptr = (u8*)&u; | ||
139 | for (size_t i = 0; i < sizeof(Uxn); i++) { | ||
140 | uxnptr[i] = 0; | ||
141 | } | ||
142 | |||
127 | ppu_init(&ppu, SCREEN_WIDTH / 8, SCREEN_HEIGHT / 8); | 143 | ppu_init(&ppu, SCREEN_WIDTH / 8, SCREEN_HEIGHT / 8); |
128 | 144 | ||
129 | // Copy rom to VM. | 145 | // Copy rom to VM. |
@@ -20,9 +20,9 @@ WITH REGARD TO THIS SOFTWARE. | |||
20 | 20 | ||
21 | static u32 *framebuffer = 0; | 21 | static u32 *framebuffer = 0; |
22 | 22 | ||
23 | static u32 palette[16] = {0}; | 23 | static u32 palette[16]; |
24 | static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT] = {0}; | 24 | static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT]; |
25 | static u8 dirty_lines[SCREEN_HEIGHT] = {0}; | 25 | static u8 dirty_lines[SCREEN_HEIGHT]; |
26 | static u8 reqdraw = 0; | 26 | static u8 reqdraw = 0; |
27 | 27 | ||
28 | static Uint8 blending[5][16] = { | 28 | static Uint8 blending[5][16] = { |
@@ -80,7 +80,7 @@ ppu_2bpp(Ppu *p, Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Ui | |||
80 | void | 80 | void |
81 | redraw_screen(void) { | 81 | redraw_screen(void) { |
82 | for (size_t j = 0; j < SCREEN_HEIGHT; j++) { | 82 | for (size_t j = 0; j < SCREEN_HEIGHT; j++) { |
83 | dirty_lines[j] |= 1; | 83 | dirty_lines[j] = 1; |
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
@@ -139,10 +139,15 @@ ppu_init(Ppu *p, Uint8 hor, Uint8 ver) { | |||
139 | p->pixels = pixels_buf; | 139 | p->pixels = pixels_buf; |
140 | 140 | ||
141 | // Initialize default palette. | 141 | // Initialize default palette. |
142 | palette[0] = 0x00444444; | 142 | palette[0] = 0x444444; |
143 | palette[1] = 0x00ffffff; | 143 | palette[1] = 0xffffff; |
144 | palette[2] = 0x007777ff; | 144 | palette[2] = 0x7777ff; |
145 | palette[3] = 0x00ff7777; | 145 | palette[3] = 0xff7777; |
146 | |||
147 | // Clear pixel buffer memory. | ||
148 | for (size_t i = 0; i < sizeof(pixels_buf); i++) { | ||
149 | p->pixels[i] = 0; | ||
150 | } | ||
146 | 151 | ||
147 | // Make sure we perform an initial screen drawing. | 152 | // Make sure we perform an initial screen drawing. |
148 | reqdraw = 1; | 153 | reqdraw = 1; |
@@ -157,10 +162,10 @@ blit_framebuffer(Ppu *p) { | |||
157 | return; | 162 | return; |
158 | } | 163 | } |
159 | for (size_t j = 0; j < SCREEN_HEIGHT; j++) { | 164 | for (size_t j = 0; j < SCREEN_HEIGHT; j++) { |
160 | if (dirty_lines[j] == 1) { | 165 | if (dirty_lines[j] != 0) { |
161 | for (size_t i = 0; i < SCREEN_WIDTH; i++) { | 166 | for (size_t i = 0; i < SCREEN_WIDTH; i++) { |
162 | size_t idx = i + j * SCREEN_WIDTH; | 167 | size_t idx = i + j * SCREEN_WIDTH; |
163 | framebuffer[idx] = palette[p->pixels[idx]]; | 168 | framebuffer[idx] = palette[p->pixels[idx] % 16]; |
164 | } | 169 | } |
165 | } | 170 | } |
166 | dirty_lines[j] = 0; | 171 | dirty_lines[j] = 0; |