From 67776035b682a18b4d47ce24e522ada48b5ad16c Mon Sep 17 00:00:00 2001 From: AfonsoCMSousa Date: Wed, 19 Nov 2025 23:12:45 +0000 Subject: [PATCH] Feat: Kernel has now a functions for better screen printing --- build.sh | 5 +-- colors.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel.c | 77 +++++++++++++++++++++++------------------ 3 files changed, 150 insertions(+), 35 deletions(-) create mode 100644 colors.h diff --git a/build.sh b/build.sh index 3bebeef..b3e8e59 100755 --- a/build.sh +++ b/build.sh @@ -6,6 +6,7 @@ set -e # Exit on any error echo "===================================" echo " SoraOS Build System v1.0" echo "===================================" +echo "" # Colors GREEN='\033[0;32m' @@ -17,7 +18,7 @@ NC='\033[0m' echo -e "Preparing build environment...${NC}" echo -e "Creating Folders${NC}" mkdir -p bin obj boot include -echo -e "${GREEN}✓ ${NC}Folders created.${NC}" +echo -e "${GREEN}✓${NC} Folders created.${NC}" # Step 1: Assemble Stage 1 bootloader (MBR - 512 bytes) echo -e "${BLUE}[1/6]${NC} Assembling Stage 1 bootloader (MBR)..." @@ -46,7 +47,7 @@ cat ./bin/boot.bin ./bin/elevator.bin ./bin/kernel.bin > os.bin # Pad to floppy size (1.44MB) # FIX: Uncomment the line below if you want to ensure the image is exactly 1.44MB # -# truncate -s 1440K os-image.bin +truncate -s 1440K os.bin echo "" echo -e "${GREEN}✓ Build complete!${NC}" diff --git a/colors.h b/colors.h new file mode 100644 index 0000000..3542a35 --- /dev/null +++ b/colors.h @@ -0,0 +1,103 @@ +#ifndef COLORS_H +#define COLORS_H + +#define VGA_WIDTH 80 +#define VGA_HEIGHT 25 + +#define VGA_MEMORY_ADDRESS 0xB8000 + +/* IN VGA - Video Memory Arrya: + * short + * 1s byte (left most) -> TEXT COLOR + * 2s byte -> BACK COLOR + * 3rd and 4rt byte -> TEXT (unsigned char) AKA CodePoint + */ + +typedef struct __attribute__((packed)) _VGA { + unsigned char codepoint; // 3rd and 4th byte + unsigned char color; // 1st byte: text color, 2nd byte: background color + // LAST BIT IS BLINKING FLAG +} _VGA; + +typedef enum _VGA_COLOR { + BLACK = 0x0, + BLUE = 0x1, + GREEN = 0x2, + CYAN = 0x3, + RED = 0x4, + MAGENTA = 0x5, + BROWN = 0x6, + LIGHT_GREY = 0x7, + DARK_GREY = 0x8, + LIGHT_BLUE = 0x9, + LIGHT_GREEN = 0xA, + LIGHT_CYAN = 0xB, + LIGHT_RED = 0xC, + LIGHT_MAGENTA = 0xD, + YELLOW = 0xE, + WHITE = 0xF +} _VGA_COLOR; + +typedef struct _VGA_screen_space{ + unsigned int line; + unsigned int column; + +} _VGA_screen_space; + +static _VGA_screen_space cursor_pos = {0, 0}; + +/* + * END OF DECLARATIONS + */ + +/* + * START OF FUNCTIONS + */ + +// Convert _VGA_COLOR to color byte +static inline unsigned char __vga_color_byte(_VGA_COLOR fg, _VGA_COLOR bg, int blink) { + unsigned char color = (bg << 4) | fg; + if (blink) { + color |= 0x80; // Set the blinking BIT + // to the highest bit + } + return color; +} + +// Get pointer to VGA memory +static inline volatile _VGA* __vga_memory() { + return (volatile _VGA*)VGA_MEMORY_ADDRESS; +} + +static inline void __clear_screen() { + volatile _VGA* vga = __vga_memory(); + for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) { + vga[i].codepoint = ' '; + vga[i].color = __vga_color_byte(WHITE, BLACK, 0); + } +} + +static inline int __put_char_VGA_POS(_VGA _c, _VGA_screen_space _position, int _blink) { + if(_position.line > VGA_HEIGHT || _position.column > VGA_WIDTH) return 0; + + volatile _VGA* vga = __vga_memory(); + + vga[(_position.line * VGA_WIDTH) + _position.column].codepoint = _c.codepoint; + vga[(_position.line * VGA_WIDTH) + _position.column].color = _c.color; + + return 1; +} + +static inline int __put_char(int column, int line, unsigned codepoint, _VGA_COLOR foreground, _VGA_COLOR background, int _blink) { + _VGA __temp_vga; + __temp_vga.color = __vga_color_byte(foreground, background, _blink); + __temp_vga.codepoint = codepoint; + + _VGA_screen_space __temp_vga_space; + __temp_vga_space.column = column; + __temp_vga_space.line = line; + + return __put_char_VGA_POS(__temp_vga, __temp_vga_space, _blink); +} + +#endif diff --git a/kernel.c b/kernel.c index e8c4e6d..e582cbb 100644 --- a/kernel.c +++ b/kernel.c @@ -1,42 +1,53 @@ // File: kernel.c // SoraOS Kernel - Main entry point -// Simple helper to write a character at a specific position -static inline void write_char(int row, int col, char c, unsigned char color) { - volatile unsigned short *vga = (volatile unsigned short *)0xB8000; - int pos = (row * 80) + col; - vga[pos] = (color << 8) | c; -} +// INFO: +// 0xA0000 for EGA/VGA graphics modes (64 KB) +// 0xB0000 for monochrome text mode (32 KB) +// 0xB8000 for color text mode and CGA-compatible graphics modes (32 KB) -// Simple helper to write a string -static void write_string(int row, int col, const char *str, unsigned char color) { - int i = 0; - while (str[i] != '\0') { - write_char(row, col + i, str[i], color); - i++; - } -} +#include "colors.h" -// Clear the entire screen -static void clear_screen(void) { - volatile unsigned short *vga = (volatile unsigned short *)0xB8000; - int i; - for (i = 0; i < 80 * 25; i++) { - vga[i] = (0x00 << 8) | ' '; - } + +/* +static void __put_char(char c, unsigned char color) { + volatile unsigned short *vga = (volatile unsigned short *)0xB8000; + + static int line = 0; + static int column = 2; + + if (line >= 16) { + column += 3; + line = 0; + } + + line++; + + vga[line * 80 + 0 + column] = (0x2F << 8) | line; // White color + vga[line * 80 + 1 + column] = (color << 8) | c; // White color } +*/ void kmain(void) { - // Clear screen - clear_screen(); - - // Write messages - write_string(10, 30, "SORA OS KERNEL", 0x0A); // Green - write_string(12, 25, "64-bit kernel running!", 0x0F); // White - write_string(14, 28, "System Initialized", 0x0E); // Yellow - - // Infinite loop - while (1) { - __asm__ volatile ("hlt"); - } + __clear_screen(); + + _VGA Char; + Char.codepoint = 'T'; + Char.color = (WHITE << 4) | BLACK; + + _VGA_screen_space Space; + Space.column = 2; + Space.line = 7; + + __put_char_VGA_POS(Char, Space, 1); + + Space.line = 4; + Space.column = 3; + + __put_char_VGA_POS(Char, Space, 0); + + // Infinite loop + while (1) { + __asm__ volatile("hlt"); + } }