BaseOS
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
||||||
57
makefile
Executable file
57
makefile
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
CROSS = aarch64-none-elf-
|
||||||
|
|
||||||
|
CC = $(CROSS)gcc
|
||||||
|
AS = $(CROSS)as
|
||||||
|
LD = $(CROSS)ld
|
||||||
|
OBJCOPY = $(CROSS)objcopy
|
||||||
|
|
||||||
|
CFLAGS = -O2 -ffreestanding -nostdlib -Wall -Wextra
|
||||||
|
LDFLAGS = -T src/linker.ld
|
||||||
|
|
||||||
|
SRC = src
|
||||||
|
BUILD = build
|
||||||
|
|
||||||
|
# List all C source files here (update as needed)
|
||||||
|
SOURCES_C = $(SRC)/renderer.c $(SRC)/font_pack.c $(SRC)/main.c
|
||||||
|
|
||||||
|
# List assembler source files
|
||||||
|
SOURCES_ASM = $(SRC)/boot.s
|
||||||
|
|
||||||
|
# Object files (one per source file)
|
||||||
|
OBJ_C = $(patsubst $(SRC)/%.c,$(BUILD)/%.o,$(SOURCES_C))
|
||||||
|
OBJ_ASM = $(patsubst $(SRC)/%.s,$(BUILD)/%.o,$(SOURCES_ASM))
|
||||||
|
|
||||||
|
TARGET_ELF = $(BUILD)/kernel.elf
|
||||||
|
TARGET_IMG = $(BUILD)/kernel8.img
|
||||||
|
|
||||||
|
.PHONY: all clean run
|
||||||
|
|
||||||
|
all: $(TARGET_IMG)
|
||||||
|
|
||||||
|
# Create build directory if it does not exist
|
||||||
|
$(BUILD):
|
||||||
|
mkdir -p $(BUILD)
|
||||||
|
|
||||||
|
# Assemble assembly sources
|
||||||
|
$(BUILD)/%.o: $(SRC)/%.s | $(BUILD)
|
||||||
|
$(AS) $< -o $@
|
||||||
|
|
||||||
|
# Compile C sources
|
||||||
|
$(BUILD)/%.o: $(SRC)/%.c | $(BUILD)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Link all object files into ELF kernel
|
||||||
|
$(TARGET_ELF): $(OBJ_ASM) $(OBJ_C)
|
||||||
|
$(LD) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
# Convert ELF to raw binary image
|
||||||
|
$(TARGET_IMG): $(TARGET_ELF)
|
||||||
|
$(OBJCOPY) $< -O binary $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD)
|
||||||
|
|
||||||
|
# Run QEMU emulator for Raspberry Pi 3 with serial output redirected to terminal
|
||||||
|
run: $(TARGET_IMG)
|
||||||
|
sudo qemu-system-aarch64 -M raspi3b -serial stdio -kernel $(TARGET_IMG)
|
||||||
17
src/boot.s
Normal file
17
src/boot.s
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
ldr x0, =stack_top
|
||||||
|
mov sp, x0
|
||||||
|
|
||||||
|
bl kernel_main
|
||||||
|
|
||||||
|
1:
|
||||||
|
b 1b
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.align 3
|
||||||
|
.global stack_top
|
||||||
|
stack_top:
|
||||||
|
.skip 0x8000 // 32 KB stack
|
||||||
27
src/color.h
Normal file
27
src/color.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef COLOR_H
|
||||||
|
#define COLOR_H
|
||||||
|
|
||||||
|
// Color format: 0xAABBGGRR (BGRA32 - little endian)
|
||||||
|
|
||||||
|
#define COLOR_BLACK 0xFF000000
|
||||||
|
#define COLOR_WHITE 0xFFFFFFFF
|
||||||
|
#define COLOR_RED 0xFF0000FF
|
||||||
|
#define COLOR_GREEN 0xFF00FF00
|
||||||
|
#define COLOR_BLUE 0xFFFF0000
|
||||||
|
#define COLOR_YELLOW 0xFF00FFFF
|
||||||
|
#define COLOR_CYAN 0xFFFFFF00
|
||||||
|
#define COLOR_MAGENTA 0xFFFF00FF
|
||||||
|
#define COLOR_GRAY 0xFF808080
|
||||||
|
#define COLOR_ORANGE 0xFF00A5FF
|
||||||
|
#define COLOR_BROWN 0xFF2A2AA5
|
||||||
|
#define COLOR_PURPLE 0xFF800080
|
||||||
|
#define COLOR_PINK 0xFFCBC0FF
|
||||||
|
#define COLOR_LIME 0xFF00FFBF
|
||||||
|
#define COLOR_NAVY 0xFF800000
|
||||||
|
#define COLOR_TEAL 0xFF808000
|
||||||
|
#define COLOR_OLIVE 0xFF008080
|
||||||
|
|
||||||
|
// For custom BGR colors
|
||||||
|
#define BGR(r, g, b) (0xFF000000 | ((b) << 16) | ((g) << 8) | (r))
|
||||||
|
|
||||||
|
#endif // COLOR_H
|
||||||
544
src/font_pack.c
Normal file
544
src/font_pack.c
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
#include "font_pack.h"
|
||||||
|
|
||||||
|
// Letter A: Thickened diagonals and vertical legs
|
||||||
|
static const uint8_t letter_A_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00011100, // ** ***
|
||||||
|
0b00111000, 0b00011100, // ** ***
|
||||||
|
0b01110000, 0b00001110, //*** ***
|
||||||
|
0b01110000, 0b00001110, //*** ***
|
||||||
|
0b11111111, 0b11111111, //************
|
||||||
|
0b11111111, 0b11111111, //************
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter B: Thickened vertical and horizontal strokes
|
||||||
|
static const uint8_t letter_B_16x16[32] = {
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter C: Thickened curves
|
||||||
|
static const uint8_t letter_C_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter D: Thickened vertical and curved strokes
|
||||||
|
static const uint8_t letter_D_16x16[32] = {
|
||||||
|
0b11111111, 0b11000000, //********
|
||||||
|
0b11111111, 0b11000000, //********
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b00110000, //*** **
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11111111, 0b11000000, //********
|
||||||
|
0b11111111, 0b11000000, //********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter E: Thickened horizontal and vertical strokes
|
||||||
|
static const uint8_t letter_E_16x16[32] = {
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter F: Thickened horizontal and vertical strokes
|
||||||
|
static const uint8_t letter_F_16x16[32] = {
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter G: Thickened curves and horizontal bar
|
||||||
|
static const uint8_t letter_G_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111111, 0b11100000, // *** ****
|
||||||
|
0b00111111, 0b11100000, // *** ****
|
||||||
|
0b00111000, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter H: Thickened vertical and horizontal bars
|
||||||
|
static const uint8_t letter_H_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11111111, 0b11111111, //************
|
||||||
|
0b11111111, 0b11111111, //************
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter I: Thickened vertical and horizontal bars
|
||||||
|
static const uint8_t letter_I_16x16[32] = {
|
||||||
|
0b00001111, 0b11110000, // ******
|
||||||
|
0b00001111, 0b11110000, // ******
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00001111, 0b11110000, // ******
|
||||||
|
0b00001111, 0b11110000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter J: Thickened vertical and curved strokes
|
||||||
|
static const uint8_t letter_J_16x16[32] = {
|
||||||
|
0b00000000, 0b01111000, // ****
|
||||||
|
0b00000000, 0b01111000, // ****
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b00000000, 0b00111000, // ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b01111111, 0b11110000, // ********
|
||||||
|
0b01111111, 0b11110000, // ********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter K: Thickened vertical and diagonal strokes
|
||||||
|
static const uint8_t letter_K_16x16[32] = {
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11100000, 0b01100000, //*** **
|
||||||
|
0b11100000, 0b11000000, //*** *
|
||||||
|
0b11100000, 0b11000000, //*** *
|
||||||
|
0b11100111, 0b00000000, //*** ***
|
||||||
|
0b11100111, 0b00000000, //*** ***
|
||||||
|
0b11111100, 0b00000000, //**** *
|
||||||
|
0b11111100, 0b00000000, //**** *
|
||||||
|
0b11111000, 0b00000000, //**** *
|
||||||
|
0b11111000, 0b00000000, //**** *
|
||||||
|
0b11111100, 0b00000000, //**** *
|
||||||
|
0b11111100, 0b00000000, //**** *
|
||||||
|
0b11101100, 0b00000000, //*** **
|
||||||
|
0b11101100, 0b00000000, //*** **
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter L: Thickened vertical and horizontal strokes
|
||||||
|
static const uint8_t letter_L_16x16[32] = {
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter M: Thickened vertical and diagonal strokes
|
||||||
|
static const uint8_t letter_M_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11110000, 0b00011110, //**** ****
|
||||||
|
0b11110000, 0b00011110, //**** ****
|
||||||
|
0b11111000, 0b00111110, //**** *****
|
||||||
|
0b11111000, 0b00111110, //**** *****
|
||||||
|
0b11101100, 0b01101110, //*** ** ***
|
||||||
|
0b11101100, 0b01101110, //*** ** ***
|
||||||
|
0b11100110, 0b11001110, //*** *** ***
|
||||||
|
0b11100110, 0b11001110, //*** *** ***
|
||||||
|
0b11100011, 0b10001110, //*** ** ***
|
||||||
|
0b11100011, 0b10001110, //*** ** ***
|
||||||
|
0b11100001, 0b00001110, //*** ***
|
||||||
|
0b11100001, 0b00001110, //*** ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter N: Thickened vertical and diagonal strokes
|
||||||
|
static const uint8_t letter_N_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11110000, 0b00001110, //**** ***
|
||||||
|
0b11110000, 0b00001110, //**** ***
|
||||||
|
0b11111000, 0b00001110, //**** ***
|
||||||
|
0b11111000, 0b00001110, //**** ***
|
||||||
|
0b11101100, 0b00001110, //*** * ***
|
||||||
|
0b11101100, 0b00001110, //*** * ***
|
||||||
|
0b11100110, 0b00001110, //*** * ***
|
||||||
|
0b11100110, 0b00001110, //*** * ***
|
||||||
|
0b11100011, 0b00001110, //*** * ***
|
||||||
|
0b11100011, 0b00001110, //*** * ***
|
||||||
|
0b11100001, 0b00001110, //*** ***
|
||||||
|
0b11100001, 0b00001110, //*** ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter O: Thickened curves
|
||||||
|
static const uint8_t letter_O_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter P: Thickened vertical and horizontal strokes
|
||||||
|
static const uint8_t letter_P_16x16[32] = {
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b11100000, 0b00000000, //***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter Q: Thickened curves and diagonal tail
|
||||||
|
static const uint8_t letter_Q_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00111010, 0b00111000, // *** ***
|
||||||
|
0b00111001, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b11100000, // *** ***
|
||||||
|
0b00011111, 0b11000000, // **** *
|
||||||
|
0b00011111, 0b11000000, // **** *
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter R: Thickened vertical, horizontal, and diagonal strokes
|
||||||
|
static const uint8_t letter_R_16x16[32] = {
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11100000, 0b00111000, //*** ***
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11111111, 0b11100000, //*********
|
||||||
|
0b11100000, 0b11000000, //*** *
|
||||||
|
0b11100000, 0b11000000, //*** *
|
||||||
|
0b11100000, 0b01100000, //*** *
|
||||||
|
0b11100000, 0b00110000, //*** *
|
||||||
|
0b11100000, 0b00011000, //*** *
|
||||||
|
0b11100000, 0b00001100, //*** *
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter S: Thickened curves
|
||||||
|
static const uint8_t letter_S_16x16[32] = {
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00011100, 0b01110000, // *** ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00111000, 0b00000000, // ***
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00001111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b01110000, // ***
|
||||||
|
0b00000000, 0b01110000, // ***
|
||||||
|
0b00000000, 0b01110000, // ***
|
||||||
|
0b00111000, 0b00011100, // *** ***
|
||||||
|
0b00011111, 0b11100000, // ******
|
||||||
|
0b00011111, 0b11100000, // ******
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter T: Thickened horizontal and vertical strokes
|
||||||
|
static const uint8_t letter_T_16x16[32] = {
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter U: Thickened vertical and curved strokes
|
||||||
|
static const uint8_t letter_U_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b01111111, 0b11111000, // *********
|
||||||
|
0b01111111, 0b11111000, // *********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter V: Thickened diagonal strokes
|
||||||
|
static const uint8_t letter_V_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00000111, 0b11000000, // ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter W: Thickened vertical and diagonal strokes
|
||||||
|
static const uint8_t letter_W_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100111, 0b00011100, //*** ***
|
||||||
|
0b11100111, 0b00011100, //*** ***
|
||||||
|
0b11101110, 0b00111000, //*** ***
|
||||||
|
0b11101110, 0b00111000, //*** ***
|
||||||
|
0b11111100, 0b01110000, //**** ***
|
||||||
|
0b11111100, 0b01110000, //**** ***
|
||||||
|
0b11111000, 0b11100000, //**** ***
|
||||||
|
0b11111000, 0b11100000, //**** ***
|
||||||
|
0b11111100, 0b11000000, //***** **
|
||||||
|
0b11111100, 0b11000000, //***** **
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter X: Thickened diagonal strokes
|
||||||
|
static const uint8_t letter_X_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter Y: Thickened diagonal and vertical strokes
|
||||||
|
static const uint8_t letter_Y_16x16[32] = {
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b11100000, 0b00001110, //*** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b01110000, 0b00011100, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00111000, 0b00111000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00011100, 0b01110000, // ** ***
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00001110, 0b11100000, // ** **
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
// Letter Z: Thickened horizontal and diagonal strokes
|
||||||
|
static const uint8_t letter_Z_16x16[32] = {
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b00000000, 0b11100000, // ***
|
||||||
|
0b00000000, 0b11100000, // ***
|
||||||
|
0b00000001, 0b11000000, // **
|
||||||
|
0b00000001, 0b11000000, // **
|
||||||
|
0b00000011, 0b10000000, // **
|
||||||
|
0b00000011, 0b10000000, // **
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00000111, 0b00000000, // ***
|
||||||
|
0b00001110, 0b00000000, // ***
|
||||||
|
0b00001110, 0b00000000, // ***
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b11111111, 0b11111000, //***********
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
0b00000000, 0b00000000, //
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Font bitmaps array
|
||||||
|
static const uint8_t *font_bitmaps_16x16[26] = {
|
||||||
|
letter_A_16x16, letter_B_16x16, letter_C_16x16, letter_D_16x16, letter_E_16x16,
|
||||||
|
letter_F_16x16, letter_G_16x16, letter_H_16x16, letter_I_16x16, letter_J_16x16,
|
||||||
|
letter_K_16x16, letter_L_16x16, letter_M_16x16, letter_N_16x16, letter_O_16x16,
|
||||||
|
letter_P_16x16, letter_Q_16x16, letter_R_16x16, letter_S_16x16, letter_T_16x16,
|
||||||
|
letter_U_16x16, letter_V_16x16, letter_W_16x16, letter_X_16x16, letter_Y_16x16,
|
||||||
|
letter_Z_16x16
|
||||||
|
};
|
||||||
|
|
||||||
|
// Font pack structure
|
||||||
|
const FontPack basic_font_pack = {
|
||||||
|
.bitmaps = {
|
||||||
|
letter_A_16x16, letter_B_16x16, letter_C_16x16, letter_D_16x16, letter_E_16x16,
|
||||||
|
letter_F_16x16, letter_G_16x16, letter_H_16x16, letter_I_16x16, letter_J_16x16,
|
||||||
|
letter_K_16x16, letter_L_16x16, letter_M_16x16, letter_N_16x16, letter_O_16x16,
|
||||||
|
letter_P_16x16, letter_Q_16x16, letter_R_16x16, letter_S_16x16, letter_T_16x16,
|
||||||
|
letter_U_16x16, letter_V_16x16, letter_W_16x16, letter_X_16x16, letter_Y_16x16,
|
||||||
|
letter_Z_16x16
|
||||||
|
}
|
||||||
|
};
|
||||||
22
src/font_pack.h
Normal file
22
src/font_pack.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef FONT_PACK_H
|
||||||
|
#define FONT_PACK_H
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FONT_WIDTH 16
|
||||||
|
#define FONT_HEIGHT 16
|
||||||
|
#define FONT_BITMAP_SIZE ((FONT_WIDTH * FONT_HEIGHT) / 8) // 32 bytes per character
|
||||||
|
static const uint8_t empty_char_16x16[32] = {0};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *bitmaps[26]; // Pointers to each 16x16 bitmap
|
||||||
|
} FontPack;
|
||||||
|
|
||||||
|
extern const FontPack basic_font_pack;
|
||||||
|
|
||||||
|
static inline const uint8_t *font_get_char_bitmap(const FontPack *pack, char c) {
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
return pack->bitmaps[c - 'A'];
|
||||||
|
return empty_char_16x16; // Or point to empty_char_16x16
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FONT_PACK_H
|
||||||
64
src/io.h
Normal file
64
src/io.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef UART_IO_H
|
||||||
|
#define UART_IO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define UART0_BASE 0x3F201000
|
||||||
|
#define UART0_DR (*((volatile uint32_t *)(UART0_BASE + 0x00)))
|
||||||
|
#define UART0_FR (*((volatile uint32_t *)(UART0_BASE + 0x18)))
|
||||||
|
|
||||||
|
typedef struct UART_IO {
|
||||||
|
void (*putc)(char c);
|
||||||
|
void (*puts)(const char* str);
|
||||||
|
char (*getc)(void);
|
||||||
|
void (*print_int)(unsigned int value);
|
||||||
|
} UART_IO;
|
||||||
|
|
||||||
|
// Function implementations
|
||||||
|
|
||||||
|
static void uart_putc(char c)
|
||||||
|
{
|
||||||
|
while (UART0_FR & (1 << 5)) { } // Wait while TXFF is set
|
||||||
|
UART0_DR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_puts(const char* str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
uart_putc(*str++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char uart_getc(void)
|
||||||
|
{
|
||||||
|
while (UART0_FR & (1 << 4)) { } // Wait while RXFE is set
|
||||||
|
return (char)(UART0_DR & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_print_int(unsigned int value)
|
||||||
|
{
|
||||||
|
char buffer[10];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
uart_putc('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (value > 0 && i < 10) {
|
||||||
|
buffer[i++] = (value % 10) + '0';
|
||||||
|
value /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
uart_putc(buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UART_IO instance with function pointers assigned
|
||||||
|
static const UART_IO uart_io = {
|
||||||
|
.putc = uart_putc,
|
||||||
|
.puts = uart_puts,
|
||||||
|
.getc = uart_getc,
|
||||||
|
.print_int = uart_print_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UART_IO_H
|
||||||
10
src/linker.ld
Normal file
10
src/linker.ld
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { *(.text*) }
|
||||||
|
.rodata : { *(.rodata*) }
|
||||||
|
.data : { *(.data*) }
|
||||||
|
.bss : { *(.bss*) }
|
||||||
|
. = ALIGN(8);
|
||||||
|
stack_top = . + 0x8000;
|
||||||
|
}
|
||||||
70
src/main.c
Normal file
70
src/main.c
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include "renderer.h"
|
||||||
|
#include "color.h"
|
||||||
|
#include "font_pack.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
int kernel_main(void)
|
||||||
|
{
|
||||||
|
uart_io.puts("Initializing renderer...\n");
|
||||||
|
|
||||||
|
Renderer renderer;
|
||||||
|
if (!renderer_init(&renderer))
|
||||||
|
{
|
||||||
|
uart_io.puts("Failed to allocate framebuffer.\n");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_io.puts("Framebuffer allocated.\n");
|
||||||
|
uart_io.puts("Width: ");
|
||||||
|
uart_io.print_int(renderer.width);
|
||||||
|
uart_io.puts("\nHeight: ");
|
||||||
|
uart_io.print_int(renderer.height);
|
||||||
|
uart_io.putc('\n');
|
||||||
|
|
||||||
|
RenderObject background = {0, 0, renderer.width, renderer.height, COLOR_RED};
|
||||||
|
RenderObject blue_rect = {100, 100, 100, 100, COLOR_BLUE};
|
||||||
|
|
||||||
|
RenderText text = {
|
||||||
|
.base = {
|
||||||
|
.x = 20,
|
||||||
|
.y = 30,
|
||||||
|
.color = 0xFFFFFFFF},
|
||||||
|
.text = "HELLO MARIO",
|
||||||
|
.font = &basic_font_pack,
|
||||||
|
};
|
||||||
|
uart_io.puts("Use WASD keys to move the rectangle.\n");
|
||||||
|
|
||||||
|
// Initial draw
|
||||||
|
renderer.clear_screen(&renderer, background.color);
|
||||||
|
renderer.draw_rect(&renderer, &blue_rect);
|
||||||
|
renderer.draw_text(&renderer, &text);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char c = uart_io.getc();
|
||||||
|
uart_io.putc(c);
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
if ((c == 'w' || c == 'W') && blue_rect.y > 0)
|
||||||
|
blue_rect.y = (blue_rect.y > 10) ? blue_rect.y - 10 : 0;
|
||||||
|
if ((c == 's' || c == 'S') && (blue_rect.y + blue_rect.height) < renderer.height)
|
||||||
|
blue_rect.y += 10;
|
||||||
|
if ((c == 'a' || c == 'A') && blue_rect.x > 0)
|
||||||
|
blue_rect.x = (blue_rect.x > 10) ? blue_rect.x - 10 : 0;
|
||||||
|
if ((c == 'd' || c == 'D') && (blue_rect.x + blue_rect.width) < renderer.width)
|
||||||
|
blue_rect.x += 10;
|
||||||
|
|
||||||
|
// Redraw everything
|
||||||
|
renderer.clear_screen(&renderer, background.color);
|
||||||
|
renderer.draw_rect(&renderer, &blue_rect);
|
||||||
|
renderer.draw_text(&renderer, &text);
|
||||||
|
|
||||||
|
// Print updated position
|
||||||
|
uart_io.puts("\nRect X: ");
|
||||||
|
uart_io.print_int(blue_rect.x);
|
||||||
|
uart_io.puts(" Y: ");
|
||||||
|
uart_io.print_int(blue_rect.y);
|
||||||
|
uart_io.putc('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
174
src/renderer.c
Normal file
174
src/renderer.c
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#include "renderer.h"
|
||||||
|
#include "font_pack.h"
|
||||||
|
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
#define MBOX_BASE 0x3F00B880
|
||||||
|
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
// Small delay loop
|
||||||
|
static inline void delay(int n)
|
||||||
|
{
|
||||||
|
while (n--)
|
||||||
|
__asm__ volatile("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mailbox call function for communication with GPU
|
||||||
|
unsigned int mailbox_call(unsigned int channel)
|
||||||
|
{
|
||||||
|
unsigned int r = ((unsigned int)((unsigned long)&mbox) & ~0xF) | (channel & 0xF);
|
||||||
|
|
||||||
|
// Wait until mailbox not full
|
||||||
|
while (*(volatile unsigned int *)(MBOX_BASE + 0x18) & 0x80000000)
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
// Write the channel combined with mailbox address
|
||||||
|
*(volatile unsigned int *)(MBOX_BASE + 0x20) = r;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// Wait for response
|
||||||
|
while (*(volatile unsigned int *)(MBOX_BASE + 0x18) & 0x40000000)
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
// Check if response is for our message
|
||||||
|
if (*(volatile unsigned int *)(MBOX_BASE + 0x00) == r)
|
||||||
|
{
|
||||||
|
// Return true if response is successful
|
||||||
|
return mbox[1] == 0x80000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void draw_text_impl(Renderer *renderer, RenderText *text_obj) {
|
||||||
|
if (!renderer || !text_obj || !text_obj->text || !text_obj->font) {
|
||||||
|
return; // Invalid inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int x0 = text_obj->base.x;
|
||||||
|
unsigned int y0 = text_obj->base.y;
|
||||||
|
unsigned int color = text_obj->base.color;
|
||||||
|
const char *str = text_obj->text;
|
||||||
|
|
||||||
|
// For each character in string
|
||||||
|
for (const char *p = str; *p != '\0'; p++) {
|
||||||
|
unsigned char c = (unsigned char)*p; // Ensure unsigned char for safety
|
||||||
|
|
||||||
|
// Get bitmap (guaranteed non-NULL due to empty_char_16x16 fallback)
|
||||||
|
const uint8_t *bitmap = font_get_char_bitmap(text_obj->font, c);
|
||||||
|
|
||||||
|
// Draw this single character (16x16)
|
||||||
|
for (unsigned int y = 0; y < FONT_HEIGHT; y++) {
|
||||||
|
// Read two bytes separately to avoid alignment issues
|
||||||
|
uint16_t row = ((uint16_t)bitmap[y * 2] << 8) | bitmap[y * 2 + 1];
|
||||||
|
for (unsigned int bit = 0; bit < FONT_WIDTH; bit++) {
|
||||||
|
if (row & (1 << (15 - bit))) { // Check 16 bits, MSB first
|
||||||
|
unsigned int px = x0 + bit;
|
||||||
|
unsigned int py = y0 + y;
|
||||||
|
if (px < renderer->width && py < renderer->height) {
|
||||||
|
// Assume 32-bit pixels; pitch in bytes
|
||||||
|
unsigned int *pixel = &renderer->fb[py * (renderer->pitch / 4) + px];
|
||||||
|
*pixel = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Advance x for next char
|
||||||
|
x0 += FONT_WIDTH + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Initialize the framebuffer via mailbox property channel
|
||||||
|
bool renderer_init(Renderer *renderer)
|
||||||
|
{
|
||||||
|
mbox[0] = 35 * 4; // Buffer size in bytes
|
||||||
|
mbox[1] = 0; // Request
|
||||||
|
|
||||||
|
// Set physical width and height
|
||||||
|
mbox[2] = 0x48003;
|
||||||
|
mbox[3] = 8;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 640;
|
||||||
|
mbox[6] = 480;
|
||||||
|
|
||||||
|
// Set virtual width and height
|
||||||
|
mbox[7] = 0x48004;
|
||||||
|
mbox[8] = 8;
|
||||||
|
mbox[9] = 8;
|
||||||
|
mbox[10] = 640;
|
||||||
|
mbox[11] = 480;
|
||||||
|
|
||||||
|
// Set depth (bits per pixel)
|
||||||
|
mbox[12] = 0x48005;
|
||||||
|
mbox[13] = 4;
|
||||||
|
mbox[14] = 4;
|
||||||
|
mbox[15] = 32;
|
||||||
|
|
||||||
|
// Allocate framebuffer
|
||||||
|
mbox[16] = 0x40001;
|
||||||
|
mbox[17] = 8;
|
||||||
|
mbox[18] = 8;
|
||||||
|
mbox[19] = 16; // alignment
|
||||||
|
mbox[20] = 0;
|
||||||
|
|
||||||
|
// Get pitch
|
||||||
|
mbox[21] = 0x40008;
|
||||||
|
mbox[22] = 4;
|
||||||
|
mbox[23] = 4;
|
||||||
|
mbox[24] = 0;
|
||||||
|
|
||||||
|
// End tag
|
||||||
|
mbox[25] = 0;
|
||||||
|
|
||||||
|
if (!mailbox_call(MBOX_CH_PROP))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
renderer->width = mbox[5];
|
||||||
|
renderer->height = mbox[6];
|
||||||
|
renderer->pitch = mbox[24];
|
||||||
|
renderer->fb = (volatile unsigned int *)(mbox[19] & 0x3FFFFFFF);
|
||||||
|
|
||||||
|
renderer->clear_screen = clear_screen_impl;
|
||||||
|
renderer->draw_rect = draw_rect_impl;
|
||||||
|
renderer->draw_text = draw_text_impl;
|
||||||
|
renderer->draw_objects = draw_objects_impl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Render function implementations
|
||||||
|
|
||||||
|
void clear_screen_impl(Renderer *renderer, unsigned int color)
|
||||||
|
{
|
||||||
|
for (unsigned int y = 0; y < renderer->height; y++)
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x < renderer->width; x++)
|
||||||
|
{
|
||||||
|
renderer->fb[y * (renderer->pitch / 4) + x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_rect_impl(Renderer *renderer, RenderObject *obj)
|
||||||
|
{
|
||||||
|
unsigned int max_y = obj->y + obj->height;
|
||||||
|
unsigned int max_x = obj->x + obj->width;
|
||||||
|
|
||||||
|
if (max_y > renderer->height)
|
||||||
|
max_y = renderer->height;
|
||||||
|
if (max_x > renderer->width)
|
||||||
|
max_x = renderer->width;
|
||||||
|
|
||||||
|
for (unsigned int y = obj->y; y < max_y; y++)
|
||||||
|
{
|
||||||
|
for (unsigned int x = obj->x; x < max_x; x++)
|
||||||
|
{
|
||||||
|
renderer->fb[y * (renderer->pitch / 4) + x] = obj->color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_objects_impl(Renderer *renderer, RenderObject *objs[], unsigned int count)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
draw_rect_impl(renderer, objs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/renderer.h
Normal file
59
src/renderer.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef RENDERER_H
|
||||||
|
#define RENDERER_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "font_pack.h"
|
||||||
|
|
||||||
|
typedef struct RenderObject {
|
||||||
|
unsigned int x, y;
|
||||||
|
unsigned int width, height;
|
||||||
|
unsigned int color;
|
||||||
|
} RenderObject;
|
||||||
|
|
||||||
|
typedef struct RenderText {
|
||||||
|
RenderObject base; // Position, size, color
|
||||||
|
const char *text; // String to render
|
||||||
|
const FontPack *font; // Font used for rendering
|
||||||
|
} RenderText;
|
||||||
|
|
||||||
|
typedef struct Renderer {
|
||||||
|
volatile unsigned int *fb;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int pitch;
|
||||||
|
|
||||||
|
void (*clear_screen)(struct Renderer *renderer, unsigned int color);
|
||||||
|
void (*draw_rect)(struct Renderer *renderer, RenderObject *obj);
|
||||||
|
void (*draw_text)(struct Renderer *renderer, RenderText *text);
|
||||||
|
void (*draw_objects)(struct Renderer *renderer, RenderObject *objs[], unsigned int count);
|
||||||
|
} Renderer;
|
||||||
|
|
||||||
|
// ===== Window definition =====
|
||||||
|
typedef struct Window {
|
||||||
|
RenderObject frame; // Outer frame of the window
|
||||||
|
RenderObject content_area; // Area inside window (excluding titlebar)
|
||||||
|
RenderText title_bar; // Title bar text
|
||||||
|
unsigned int background_color; // Background fill color for content
|
||||||
|
bool visible; // Visibility flag
|
||||||
|
} Window;
|
||||||
|
|
||||||
|
// Function to initialize a Window
|
||||||
|
void window_init(Window *win,
|
||||||
|
unsigned int x, unsigned int y,
|
||||||
|
unsigned int width, unsigned int height,
|
||||||
|
const char *title, const FontPack *font,
|
||||||
|
unsigned int title_color, unsigned int bg_color,
|
||||||
|
unsigned int text_color);
|
||||||
|
|
||||||
|
// Function to render the Window
|
||||||
|
void window_draw(Renderer *renderer, Window *win);
|
||||||
|
|
||||||
|
// ===== Renderer functions =====
|
||||||
|
bool renderer_init(Renderer *renderer);
|
||||||
|
void clear_screen_impl(Renderer *renderer, unsigned int color);
|
||||||
|
void draw_rect_impl(Renderer *renderer, RenderObject *obj);
|
||||||
|
void draw_text_impl(Renderer *renderer, RenderText *text);
|
||||||
|
void draw_objects_impl(Renderer *renderer, RenderObject *objs[], unsigned int count);
|
||||||
|
|
||||||
|
#endif // RENDERER_H
|
||||||
Reference in New Issue
Block a user