From baa0de8847d302a66691a1713748d7f346d6b054 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sun, 23 Jan 2022 16:44:47 +0100 Subject: [PATCH] got basic framebuffer --- include/framebuffer.h | 30 ++++++++++++++++++ include/mb.h | 6 +++- src/framebuffer.c | 35 +++++++++++++++++++++ src/kernel.c | 13 ++++++++ src/mb.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 include/framebuffer.h create mode 100644 src/framebuffer.c diff --git a/include/framebuffer.h b/include/framebuffer.h new file mode 100644 index 0000000..6454a00 --- /dev/null +++ b/include/framebuffer.h @@ -0,0 +1,30 @@ +#pragma once + +#include "stdint.h" + +struct FrameBuffer +{ + struct + { + uint32_t width; + uint32_t height; + } physicalDisplay; + + struct + { + uint32_t width; + uint32_t height; + uint32_t xOffset; + uint32_t yOffset; + } virtualDisplay; + + uint32_t pitch; + uint32_t bitsPerPixel; + uint8_t* pixels; + uint32_t size; +}; + +struct FrameBuffer* framebuffer_init(unsigned int width, unsigned int height); +void framebuffer_release(void); + +void draw_test_image(void); \ No newline at end of file diff --git a/include/mb.h b/include/mb.h index 1ebd1c6..339f728 100644 --- a/include/mb.h +++ b/include/mb.h @@ -2,5 +2,9 @@ #include "stdint.h" +struct FrameBuffer; + uint32_t get_vc_firmware_rev(void); -uint8_t* get_board_mac_address(uint8_t* buffer); \ No newline at end of file +uint8_t* get_board_mac_address(uint8_t* buffer); + +void create_framebuffer(struct FrameBuffer* buffer, unsigned int width, unsigned int height); \ No newline at end of file diff --git a/src/framebuffer.c b/src/framebuffer.c new file mode 100644 index 0000000..5ecc79b --- /dev/null +++ b/src/framebuffer.c @@ -0,0 +1,35 @@ +#include "framebuffer.h" + +#include "mb.h" +#include "memory.h" +#include "io.h" + +static struct FrameBuffer framebuffer; + +struct FrameBuffer* framebuffer_init(unsigned int width, unsigned int height) +{ + create_framebuffer(&framebuffer, width, height); + + return &framebuffer; +} + +void framebuffer_release(void) +{ + +} + +void draw_test_image(void) +{ + for(uint32_t y = 0; y < framebuffer.virtualDisplay.height; y++) + { + for(uint32_t x = 0; x < framebuffer.virtualDisplay.width; x++) + { + size_t offset = y * framebuffer.pitch + (x * (framebuffer.bitsPerPixel / 8)); + + framebuffer.pixels[offset + 0] = 255; + framebuffer.pixels[offset + 1] = y * 255 / framebuffer.virtualDisplay.height; + framebuffer.pixels[offset + 2] = x * 255 / framebuffer.virtualDisplay.width; + framebuffer.pixels[offset + 3] = 100; + } + } +} \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index 58eec5e..2d1db8f 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -3,6 +3,7 @@ #include "string.h" #include "memory.h" #include "mb.h" +#include "framebuffer.h" void print_clippy(); char* get_user_input(char* buffer); @@ -36,6 +37,18 @@ void main() uart_puts("Started execution at 0x"); uart_puts(ultoa((long)&_start, buffer, 16)); + struct FrameBuffer* framebuffer = framebuffer_init(1920, 1080); + uart_puts("\n\nFramebuffer info\n---------------\n"); + uart_puts("Physical display : "); uart_puts(utoa(framebuffer->physicalDisplay.width, buffer, 10)); uart_puts("x"); uart_puts(utoa(framebuffer->physicalDisplay.height, buffer, 10)); uart_puts(" pixels\n"); + uart_puts("Virtual display : "); uart_puts(utoa(framebuffer->virtualDisplay.width, buffer, 10)); uart_puts("x"); uart_puts(utoa(framebuffer->virtualDisplay.height, buffer, 10)); uart_puts(" pixels\n"); + uart_puts("Virt. disp. offset: ("); uart_puts(utoa(framebuffer->virtualDisplay.xOffset, buffer, 10)); uart_puts(","); uart_puts(utoa(framebuffer->virtualDisplay.yOffset, buffer, 10)); uart_puts(")\n"); + uart_puts("Pitch: : "); uart_puts(utoa(framebuffer->pitch, buffer, 10)); uart_puts(" bytes\n"); + uart_puts("Bit depth : "); uart_puts(utoa(framebuffer->bitsPerPixel, buffer, 10)); uart_puts(" bits per pixel\n"); + uart_puts("Memory location : 0x"); uart_puts(ultoa((unsigned long)framebuffer->pixels, buffer, 16)); uart_puts("\n"); + uart_puts("Size : "); uart_puts(utoa(framebuffer->size, buffer, 10)); uart_puts(" bytes\n\n"); + + draw_test_image(); + for(;;) { uart_puts("\n\nPlease enter first operand\n"); diff --git a/src/mb.c b/src/mb.c index f6092dc..87f1b30 100644 --- a/src/mb.c +++ b/src/mb.c @@ -3,6 +3,7 @@ #include "memory.h" #include "io.h" #include "convert.h" +#include "framebuffer.h" volatile uint32_t __attribute__((aligned(16))) mailbox[36]; @@ -118,4 +119,75 @@ uint8_t* get_board_mac_address(uint8_t* buffer) buffer[i] = mac_address[i]; return buffer; +} + +void create_framebuffer(struct FrameBuffer* buffer, unsigned int width, unsigned int height) +{ + mailbox[0] = 35 * sizeof(uint32_t); // buffer size + mailbox[1] = 0; + + // Set physical display dimensions + mailbox[2] = 0x00048003; + mailbox[3] = 2 * sizeof(uint32_t); + mailbox[4] = 0; + mailbox[5] = width; + mailbox[6] = height; + + // Set virtual display dimensions + mailbox[7] = 0x00048004; + mailbox[8] = 2 * sizeof(uint32_t); + mailbox[9] = 0; + mailbox[10] = width; + mailbox[11] = height; + + // Set bit depth + mailbox[12] = 0x00048005; + mailbox[13] = 1 * sizeof(uint32_t); + mailbox[14] = 0; + mailbox[15] = 32; + + // Set pixel order + mailbox[16] = 0x00048006; + mailbox[17] = 1 * sizeof(uint32_t); + mailbox[18] = 0; + mailbox[19] = 1; + + // Set virtual offset + mailbox[20] = 0x00048009; + mailbox[21] = 2 * sizeof(uint32_t); + mailbox[22] = 0; + mailbox[23] = 0; + mailbox[24] = 0; + + // Allocate buffer + mailbox[25] = 0x00040001; + mailbox[26] = 8; + mailbox[27] = 0; + mailbox[28] = 4096; + mailbox[29] = 0; + + // Get pitch + mailbox[30] = 0x00040008; + mailbox[31] = 1 * sizeof(uint32_t); + mailbox[32] = 0; + mailbox[33] = 0; + + mailbox[34] = 0; + + mailbox_call(8); + + mailbox[28] &= 0x3FFFFFFF; + + buffer->physicalDisplay.width = mailbox[5]; + buffer->physicalDisplay.height = mailbox[6]; + + buffer->virtualDisplay.width = mailbox[10]; + buffer->virtualDisplay.height = mailbox[11]; + buffer->virtualDisplay.xOffset = mailbox[23]; + buffer->virtualDisplay.yOffset = mailbox[24]; + + buffer->bitsPerPixel = mailbox[15]; + buffer->pitch = mailbox[33]; + buffer->pixels = (uint8_t*)((uint64_t)mailbox[28]); + buffer->size = mailbox[29]; } \ No newline at end of file