aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-09-09 15:56:16 +0200
committerBad Diode <bd@badd10de.dev>2021-09-09 15:56:16 +0200
commita1bc2913625b45c6ac28b856b8ee2051489479b7 (patch)
treeb2225cfc55710080173f09853cd50f68773a9667
parent4eaa5313c9c591dffb6f52c2674009622cbdd28e (diff)
downloaduxnrpi-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--Makefile5
-rw-r--r--src/common.h20
-rw-r--r--src/main.c16
-rw-r--r--src/ppu.c25
4 files changed, 52 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 96c1b74..1fced4f 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,8 @@
2.SUFFIXES: 2.SUFFIXES:
3.PHONY: clean run 3.PHONY: clean run
4 4
5RPI_VERSION ?= 3
6
5# Compiler. 7# Compiler.
6AS := aarch64-elf-as 8AS := aarch64-elf-as
7CC := aarch64-elf-gcc 9CC := aarch64-elf-gcc
@@ -21,7 +23,8 @@ OBJ_START = $(BUILD_DIR)/start.o
21OBJ_MAIN = $(BUILD_DIR)/main.o 23OBJ_MAIN = $(BUILD_DIR)/main.o
22SRC_LINK = $(SRC_DIR)/linker.ld 24SRC_LINK = $(SRC_DIR)/linker.ld
23 25
24CFLAGS := -Wall -ffreestanding -O2 -nostdlib -lgcc -mgeneral-regs-only -fstack-protector 26CFLAGS := -Wall -ffreestanding -O1 -nostdlib -lgcc -mgeneral-regs-only -fstack-protector
27CFLAGS += -DRPI_VERSION=$(RPI_VERSION)
25AFLAGS := 28AFLAGS :=
26LDFLAGS := 29LDFLAGS :=
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.
16void memzero(u64 src, u32 n); 26void 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}
diff --git a/src/main.c b/src/main.c
index 624d3c8..7ac7037 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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.
diff --git a/src/ppu.c b/src/ppu.c
index 85245b2..e153c4d 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -20,9 +20,9 @@ WITH REGARD TO THIS SOFTWARE.
20 20
21static u32 *framebuffer = 0; 21static u32 *framebuffer = 0;
22 22
23static u32 palette[16] = {0}; 23static u32 palette[16];
24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT] = {0}; 24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT];
25static u8 dirty_lines[SCREEN_HEIGHT] = {0}; 25static u8 dirty_lines[SCREEN_HEIGHT];
26static u8 reqdraw = 0; 26static u8 reqdraw = 0;
27 27
28static Uint8 blending[5][16] = { 28static Uint8 blending[5][16] = {
@@ -80,7 +80,7 @@ ppu_2bpp(Ppu *p, Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Ui
80void 80void
81redraw_screen(void) { 81redraw_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;