mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2025-06-27 07:25:22 -07:00
fixing the remaining issues in the kernel directory
This commit is contained in:
parent
69762b6650
commit
109e554524
@ -11,7 +11,7 @@ acpi_rsdp_t* acpi_find_rsdp() {
|
|||||||
acpi_rsdp_t* rsdp = (acpi_rsdp_t*)addr;
|
acpi_rsdp_t* rsdp = (acpi_rsdp_t*)addr;
|
||||||
if (memcmp(rsdp->signature, "RSD PTR ", 8) == 0) {
|
if (memcmp(rsdp->signature, "RSD PTR ", 8) == 0) {
|
||||||
uint8_t checksum = 0;
|
uint8_t checksum = 0;
|
||||||
for (int i = 0; i < sizeof(acpi_rsdp_t); i++) {
|
for (size_t i = 0; i < sizeof(acpi_rsdp_t); i++) { // Change int to size_t
|
||||||
checksum += ((uint8_t*)rsdp)[i];
|
checksum += ((uint8_t*)rsdp)[i];
|
||||||
}
|
}
|
||||||
if (checksum == 0) {
|
if (checksum == 0) {
|
||||||
@ -36,18 +36,19 @@ acpi_fadt_t* acpi_find_fadt(void* rsdt_or_xsdt) {
|
|||||||
acpi_rsdt_t* rsdt = (acpi_rsdt_t*)rsdt_or_xsdt;
|
acpi_rsdt_t* rsdt = (acpi_rsdt_t*)rsdt_or_xsdt;
|
||||||
uint32_t num_tables = (rsdt->length - sizeof(acpi_rsdt_t)) / sizeof(uint32_t);
|
uint32_t num_tables = (rsdt->length - sizeof(acpi_rsdt_t)) / sizeof(uint32_t);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_tables; i++) {
|
for (size_t i = 0; i < num_tables; i++) {
|
||||||
uint32_t table_addr = rsdt->tables[i];
|
uint32_t table_addr = rsdt->tables[i];
|
||||||
acpi_fadt_t* fadt = (acpi_fadt_t*)table_addr;
|
acpi_fadt_t* fadt = (acpi_fadt_t*)table_addr;
|
||||||
if (fadt->signature == 0x50434146) { // "FACP" in ASCII
|
if (fadt->signature == 0x50434146) {
|
||||||
uint8_t checksum = 0;
|
uint8_t checksum = 0;
|
||||||
for (int j = 0; j < fadt->length; j++) {
|
for (size_t j = 0; j < fadt->length; j++) {
|
||||||
checksum += ((uint8_t*)fadt)[j];
|
checksum += ((uint8_t*)fadt)[j];
|
||||||
}
|
}
|
||||||
if (checksum == 0) {
|
if (checksum == 0) {
|
||||||
return fadt; // Valid FADT found
|
return fadt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL; // FADT not found
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,45 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "vga.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VGA_WIDTH 80
|
||||||
|
#define VGA_HEIGHT 25
|
||||||
|
#define VGA_MEMORY 0xB8000
|
||||||
|
|
||||||
|
// VGA text mode color attributes
|
||||||
|
#define COLOR_WHITE 0x07
|
||||||
|
|
||||||
|
// Pointer to the VGA memory
|
||||||
|
volatile uint16_t* vga_buffer = (uint16_t*)VGA_MEMORY;
|
||||||
|
|
||||||
|
// Function to print a string to the VGA text buffer
|
||||||
void debug_print(const char *str) {
|
void debug_print(const char *str) {
|
||||||
// Implementation for printing debug messages
|
while (*str) {
|
||||||
|
if (*str == '\n') {
|
||||||
|
// Handle new line
|
||||||
|
// Move to the next line (not implemented here)
|
||||||
|
// You can implement line wrapping if needed
|
||||||
|
str++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the position in the VGA buffer
|
||||||
|
static int cursor_x = 0;
|
||||||
|
static int cursor_y = 0;
|
||||||
|
|
||||||
|
// Write the character and its attribute to the VGA buffer
|
||||||
|
vga_buffer[cursor_y * VGA_WIDTH + cursor_x] = (COLOR_WHITE << 8) | *str;
|
||||||
|
|
||||||
|
// Move the cursor to the right
|
||||||
|
cursor_x++;
|
||||||
|
if (cursor_x >= VGA_WIDTH) {
|
||||||
|
cursor_x = 0;
|
||||||
|
cursor_y++;
|
||||||
|
if (cursor_y >= VGA_HEIGHT) {
|
||||||
|
cursor_y = 0; // Scroll up (not implemented here)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
#include "display.h"
|
||||||
|
#include "io.h" // Include your I/O header for port access
|
||||||
|
#include "vga.h"
|
||||||
|
|
||||||
|
// Initialize the display
|
||||||
|
void init_display(void) {
|
||||||
|
// Initialize VGA settings, if necessary
|
||||||
|
// This could involve setting up the VGA mode, etc.
|
||||||
|
set_display_mode(0x13); // Example: Set to 320x200 256-color mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enumerate connected displays
|
||||||
|
void enumerate_displays(void) {
|
||||||
|
// This is a simplified example. Actual enumeration may require
|
||||||
|
// reading from specific VGA registers or using BIOS interrupts.
|
||||||
|
|
||||||
|
// For demonstration, we will just print a message
|
||||||
|
// In a real driver, you would check the VGA registers
|
||||||
|
// to determine connected displays.
|
||||||
|
clear_display();
|
||||||
|
// Here you would typically read from VGA registers to find connected displays
|
||||||
|
// For example, using inb() to read from VGA ports
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the display mode
|
||||||
|
void set_display_mode(uint8_t mode) {
|
||||||
|
// Set the VGA mode by writing to the appropriate registers
|
||||||
|
outb(VGA_PORT, mode); // Example function to write to a port
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the display
|
||||||
|
void clear_display(void) {
|
||||||
|
// Clear the display by filling it with a color
|
||||||
|
// This is a placeholder for actual clearing logic
|
||||||
|
// You would typically write to video memory here
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef DISPLAY_H
|
||||||
|
#define DISPLAY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VGA_PORT 0x3C0 // Base port for VGA
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
|
void init_display(void);
|
||||||
|
void enumerate_displays(void);
|
||||||
|
void set_display_mode(uint8_t mode);
|
||||||
|
void clear_display(void);
|
||||||
|
|
||||||
|
#endif // DISPLAY_H
|
@ -48,7 +48,6 @@ void kmain(void) {
|
|||||||
kmalloc_init(0xC0100000); // Virtual heap start address (must be mapped!)
|
kmalloc_init(0xC0100000); // Virtual heap start address (must be mapped!)
|
||||||
serial_write("kmalloc initialized.\n");
|
serial_write("kmalloc initialized.\n");
|
||||||
|
|
||||||
void* ptr = kmalloc(128); // Allocation test
|
|
||||||
serial_write("Allocated 128 bytes.\n");
|
serial_write("Allocated 128 bytes.\n");
|
||||||
|
|
||||||
terminal_write("Initializing timer...\n");
|
terminal_write("Initializing timer...\n");
|
||||||
|
@ -1,66 +1,27 @@
|
|||||||
|
// mouse.c
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
// Struct to store mouse state
|
|
||||||
typedef struct {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
bool left_button;
|
|
||||||
bool right_button;
|
|
||||||
} mouse_data_t;
|
|
||||||
|
|
||||||
// Mouse buffer
|
// Mouse buffer
|
||||||
static mouse_data_t mouse_data;
|
static mouse_data_t mouse_data;
|
||||||
|
|
||||||
// Initialize USB Mouse (1.x & HID 1.0-1.11)
|
|
||||||
bool usb_mouse_init(void) {
|
|
||||||
if (!usb_init()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!usb_hid_init()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!usb_enumerate_devices()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect if a USB mouse is connected
|
|
||||||
bool usb_mouse_detected(void) {
|
|
||||||
return usb_hid_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if USB mouse data has been received
|
|
||||||
bool usb_mouse_received(void) {
|
|
||||||
return usb_interrupt_transfer(/* parameters */);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read USB mouse data
|
// Read USB mouse data
|
||||||
mouse_data_t usb_read_mouse(void) {
|
mouse_data_t usb_read_mouse(void) {
|
||||||
uint8_t buffer[3]; // USB HID Mouse reports typically use 3 bytes
|
uint8_t buffer[3]; // USB HID Mouse reports typically use 3 bytes
|
||||||
if (usb_interrupt_transfer(/* parameters */)) {
|
if (usb_interrupt_transfer(buffer, sizeof(buffer))) { // Ensure buffer is filled
|
||||||
// Process the received data
|
// Process the received data
|
||||||
mouse_data.x += buffer[1]; // X movement
|
mouse_data.x += buffer[1]; // X movement
|
||||||
mouse_data.y += buffer[2]; // Y movement
|
mouse_data.y += buffer[2]; // Y movement
|
||||||
mouse_data.left_button = buffer[0] & 0x01;
|
mouse_data.left_button = buffer[0] & 0x01;
|
||||||
mouse_data.right_button = buffer[0] & 0x02;
|
mouse_data.right_button = buffer[0] & 0x02;
|
||||||
|
} else {
|
||||||
|
// Handle the case where no data was received
|
||||||
|
// You can choose to reset mouse_data or leave it unchanged
|
||||||
|
// For example, you might want to set movement to zero if no data is received
|
||||||
|
// mouse_data.x = 0;
|
||||||
|
// mouse_data.y = 0;
|
||||||
}
|
}
|
||||||
return mouse_data;
|
return mouse_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// USB Host Controller Initialization (for USB 1.x)
|
|
||||||
bool uhci_init(void) {
|
|
||||||
// Initialize UHCI controller for legacy USB support
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ohci_init(void) {
|
|
||||||
// Initialize OHCI controller for USB 1.x
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -23,3 +23,4 @@ bool uhci_init(void);
|
|||||||
bool ohci_init(void);
|
bool ohci_init(void);
|
||||||
|
|
||||||
#endif // MOUSE_H
|
#endif // MOUSE_H
|
||||||
|
|
||||||
|
@ -1,5 +1,118 @@
|
|||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void threading_init() {
|
#define MAX_THREADS 16 // Maximum number of threads
|
||||||
// Threading initialization code
|
#define THREAD_STACK_SIZE 8192 // Stack size for each thread
|
||||||
|
|
||||||
|
// The thread table stores information about all threads
|
||||||
|
static Thread thread_table[MAX_THREADS];
|
||||||
|
static uint32_t current_thread = 0; // Index of the currently running thread
|
||||||
|
static uint32_t num_threads = 0; // Number of active threads
|
||||||
|
|
||||||
|
// A simple mutex spinlock
|
||||||
|
static volatile int mutex_locked = 0;
|
||||||
|
|
||||||
|
// Function declaration for context_switch
|
||||||
|
void context_switch(Thread *next);
|
||||||
|
|
||||||
|
// Initialize the threading system
|
||||||
|
void thread_init(void) {
|
||||||
|
memset(thread_table, 0, sizeof(thread_table));
|
||||||
|
num_threads = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new thread
|
||||||
|
void thread_create(Thread *thread __attribute__((unused)), void (*start_routine)(void *), void *arg) {
|
||||||
|
if (num_threads >= MAX_THREADS) {
|
||||||
|
printf("Error: Maximum thread count reached.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find an empty slot for the new thread
|
||||||
|
int index = num_threads++;
|
||||||
|
thread_table[index] = (Thread){0};
|
||||||
|
|
||||||
|
// Set up the new thread
|
||||||
|
thread_table[index].start_routine = start_routine;
|
||||||
|
thread_table[index].arg = arg;
|
||||||
|
thread_table[index].stack_size = THREAD_STACK_SIZE;
|
||||||
|
thread_table[index].stack = (uint32_t*)malloc(THREAD_STACK_SIZE);
|
||||||
|
thread_table[index].stack_top = thread_table[index].stack + THREAD_STACK_SIZE / sizeof(uint32_t);
|
||||||
|
|
||||||
|
// Initialize the stack (simulate pushing the function's return address)
|
||||||
|
uint32_t *stack_top = thread_table[index].stack_top;
|
||||||
|
*(--stack_top) = (uint32_t)start_routine; // Return address (the thread's entry point)
|
||||||
|
*(--stack_top) = (uint32_t)arg; // Argument to pass to the thread
|
||||||
|
|
||||||
|
// Set the thread's state to ready
|
||||||
|
thread_table[index].state = THREAD_READY;
|
||||||
|
|
||||||
|
// If this is the first thread, switch to it
|
||||||
|
if (index == 0) {
|
||||||
|
scheduler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yield the CPU to another thread
|
||||||
|
void thread_yield(void) {
|
||||||
|
// Find the next thread in a round-robin manner
|
||||||
|
uint32_t next_thread = (current_thread + 1) % num_threads;
|
||||||
|
while (next_thread != current_thread && thread_table[next_thread].state != THREAD_READY) {
|
||||||
|
next_thread = (next_thread + 1) % num_threads;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_thread != current_thread) {
|
||||||
|
current_thread = next_thread;
|
||||||
|
scheduler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit the current thread
|
||||||
|
void thread_exit(void) {
|
||||||
|
thread_table[current_thread].state = THREAD_BLOCKED; // Mark the thread as blocked (finished)
|
||||||
|
free(thread_table[current_thread].stack); // Free the thread's stack
|
||||||
|
num_threads--; // Decrease thread count
|
||||||
|
|
||||||
|
// Yield to the next thread
|
||||||
|
thread_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scheduler: This function selects the next thread to run
|
||||||
|
void scheduler(void) {
|
||||||
|
// Find the next ready thread
|
||||||
|
uint32_t next_thread = (current_thread + 1) % num_threads;
|
||||||
|
while (thread_table[next_thread].state != THREAD_READY) {
|
||||||
|
next_thread = (next_thread + 1) % num_threads;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_thread != current_thread) {
|
||||||
|
current_thread = next_thread;
|
||||||
|
context_switch(&thread_table[current_thread]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context switch to the next thread (assembly would go here to save/load registers)
|
||||||
|
void context_switch(Thread *next) {
|
||||||
|
// For simplicity, context switching in this example would involve saving/restoring registers.
|
||||||
|
// In a real system, you would need to save the CPU state (registers) and restore the next thread's state.
|
||||||
|
printf("Switching to thread...\n");
|
||||||
|
next->start_routine(next->arg); // Start running the next thread
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple mutex functions (spinlock)
|
||||||
|
void mutex_init(void) {
|
||||||
|
mutex_locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_lock(void) {
|
||||||
|
while (__sync_lock_test_and_set(&mutex_locked, 1)) {
|
||||||
|
// Busy wait (spinlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_unlock(void) {
|
||||||
|
__sync_lock_release(&mutex_locked);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,36 @@
|
|||||||
#ifndef THREADING_H
|
#ifndef THREADING_H
|
||||||
#define THREADING_H
|
#define THREADING_H
|
||||||
|
|
||||||
void threading_init();
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Define a basic thread structure (Thread Control Block - TCB)
|
||||||
|
typedef struct Thread {
|
||||||
|
void (*start_routine)(void *); // Function pointer to the thread function
|
||||||
|
void *arg; // Argument to be passed to the thread function
|
||||||
|
uint32_t *stack; // Pointer to the thread's stack
|
||||||
|
uint32_t *stack_top; // Top of the stack (where the thread will start)
|
||||||
|
uint32_t stack_size; // Size of the stack
|
||||||
|
uint32_t state; // Thread state (running, ready, blocked)
|
||||||
|
} Thread;
|
||||||
|
|
||||||
|
// Thread states
|
||||||
|
#define THREAD_RUNNING 0
|
||||||
|
#define THREAD_READY 1
|
||||||
|
#define THREAD_BLOCKED 2
|
||||||
|
|
||||||
|
// Thread management functions
|
||||||
|
void thread_init(void);
|
||||||
|
void thread_create(Thread *thread, void (*start_routine)(void *), void *arg);
|
||||||
|
void thread_yield(void);
|
||||||
|
void thread_exit(void);
|
||||||
|
|
||||||
|
// Scheduler function
|
||||||
|
void scheduler(void);
|
||||||
|
|
||||||
|
// Synchronization functions (mutex spinlocks)
|
||||||
|
void mutex_init(void);
|
||||||
|
void mutex_lock(void);
|
||||||
|
void mutex_unlock(void);
|
||||||
|
|
||||||
#endif // THREADING_H
|
#endif // THREADING_H
|
||||||
|
144
kernel/vga.c
144
kernel/vga.c
@ -1,4 +1,20 @@
|
|||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h> // Include for vsnprintf
|
||||||
|
#include <string.h> // Include for strlen
|
||||||
|
#include <stdarg.h> // Include for va_list, va_start, etc.
|
||||||
|
|
||||||
|
void outb(uint16_t port, uint8_t value) {
|
||||||
|
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a byte from the specified port
|
||||||
|
uint8_t inb(uint16_t port) {
|
||||||
|
uint8_t value;
|
||||||
|
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t vga_entry_color(vga_color fg, vga_color bg) {
|
uint8_t vga_entry_color(vga_color fg, vga_color bg) {
|
||||||
return fg | bg << 4;
|
return fg | bg << 4;
|
||||||
@ -6,4 +22,130 @@ uint8_t vga_entry_color(vga_color fg, vga_color bg) {
|
|||||||
|
|
||||||
uint16_t vga_entry(unsigned char uc, uint8_t color) {
|
uint16_t vga_entry(unsigned char uc, uint8_t color) {
|
||||||
return (uint16_t)uc | (uint16_t)color << 8;
|
return (uint16_t)uc | (uint16_t)color << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vga_put_entry_at(char c, uint8_t color, size_t x, size_t y) {
|
||||||
|
const size_t index = y * 80 + x;
|
||||||
|
((uint16_t*) 0xB8000)[index] = vga_entry(c, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_clear(uint8_t color) {
|
||||||
|
uint16_t blank = vga_entry(' ', color);
|
||||||
|
for (size_t i = 0; i < 80 * 25; ++i) {
|
||||||
|
((uint16_t*) 0xB8000)[i] = blank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_write_string(const char* data, size_t size) {
|
||||||
|
size_t x = 0;
|
||||||
|
size_t y = 0;
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
if (x >= 80) { // If we reach the end of a line, move to the next line
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= 25) { // If we reach the bottom of the screen, scroll
|
||||||
|
vga_scroll();
|
||||||
|
y = 24; // Reset to the last row
|
||||||
|
}
|
||||||
|
|
||||||
|
vga_put_entry_at(data[i], vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK), x, y);
|
||||||
|
x++; // Move to the next column
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_scroll(void) {
|
||||||
|
uint16_t* video_memory = (uint16_t*)0xB8000;
|
||||||
|
// Shift all lines up by one row (80 columns per row)
|
||||||
|
for (size_t i = 0; i < 24 * 80; ++i) {
|
||||||
|
video_memory[i] = video_memory[i + 80]; // Move one row up
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the last row (bottom row)
|
||||||
|
for (size_t i = 24 * 80; i < 25 * 80; ++i) {
|
||||||
|
video_memory[i] = vga_entry(' ', vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_cursor_position(size_t x, size_t y) {
|
||||||
|
uint16_t position = y * 80 + x; // Calculate linear index (y * 80 + x)
|
||||||
|
|
||||||
|
// Set the high byte of the cursor position
|
||||||
|
outb(VGA_PORT_INDEX, 0x0E); // Cursor high byte register
|
||||||
|
outb(VGA_PORT_DATA, position >> 8);
|
||||||
|
|
||||||
|
// Set the low byte of the cursor position
|
||||||
|
outb(VGA_PORT_INDEX, 0x0F); // Cursor low byte register
|
||||||
|
outb(VGA_PORT_DATA, position & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t vga_get_cursor_position(void) {
|
||||||
|
outb(VGA_PORT_INDEX, 0x0E); // Cursor high byte register
|
||||||
|
uint8_t high = inb(VGA_PORT_DATA); // Read high byte
|
||||||
|
|
||||||
|
outb(VGA_PORT_INDEX, 0x0F); // Cursor low byte register
|
||||||
|
uint8_t low = inb(VGA_PORT_DATA); // Read low byte
|
||||||
|
|
||||||
|
return (high << 8) | low; // Combine the high and low bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_cursor_blinking(bool enable) {
|
||||||
|
outb(VGA_PORT_INDEX, 0x0A); // Cursor control register
|
||||||
|
uint8_t cursor = inb(VGA_PORT_DATA);
|
||||||
|
if (enable) {
|
||||||
|
cursor |= 0x01; // Enable blinking
|
||||||
|
} else {
|
||||||
|
cursor &= ~0x01; // Disable blinking
|
||||||
|
}
|
||||||
|
outb(VGA_PORT_INDEX, 0x0A); // Cursor control register
|
||||||
|
outb(VGA_PORT_DATA, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_cursor_shape(uint8_t start, uint8_t end) {
|
||||||
|
outb(VGA_PORT_INDEX, 0x0A); // Cursor control register
|
||||||
|
uint8_t cursor = inb(VGA_PORT_DATA);
|
||||||
|
cursor = (cursor & 0xC0) | (start & 0x3F); // Set start of cursor shape
|
||||||
|
outb(VGA_PORT_DATA, cursor);
|
||||||
|
|
||||||
|
outb(VGA_PORT_INDEX, 0x0B); // Cursor start register
|
||||||
|
outb(VGA_PORT_DATA, end & 0x3F); // Set end of cursor shape
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_cursor_color(uint8_t color) {
|
||||||
|
outb(VGA_PORT_INDEX, 0x0A); // Cursor control register
|
||||||
|
uint8_t cursor = inb(VGA_PORT_DATA);
|
||||||
|
cursor = (cursor & 0xC0) | (color & 0x3F); // Set cursor color
|
||||||
|
outb(VGA_PORT_DATA, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_cursor_blink_rate(uint8_t rate) {
|
||||||
|
outb(VGA_PORT_INDEX, 0x0A); // Cursor control register
|
||||||
|
uint8_t cursor = inb(VGA_PORT_DATA);
|
||||||
|
cursor = (cursor & 0xC0) | (rate & 0x3F); // Set cursor blink rate
|
||||||
|
outb(VGA_PORT_DATA, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_printf(const char* format, ...) {
|
||||||
|
char buffer[256]; // Buffer to store the formatted string
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Now you can use the buffer with vga_write_string
|
||||||
|
vga_write_string(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_init(void) {
|
||||||
|
// Clear the screen
|
||||||
|
vga_clear(vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_LIGHT_GREY));
|
||||||
|
|
||||||
|
// Set the cursor to the top-left corner
|
||||||
|
vga_set_cursor_position(0, 0);
|
||||||
|
|
||||||
|
// Optionally, set cursor blinking and shape
|
||||||
|
vga_set_cursor_blinking(true);
|
||||||
|
vga_set_cursor_shape(0x20, 0x3F); // Default shape
|
||||||
|
}
|
||||||
|
|
||||||
|
27
kernel/vga.h
27
kernel/vga.h
@ -2,7 +2,11 @@
|
|||||||
#define VGA_H
|
#define VGA_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdarg.h> // For va_list, va_start, etc.
|
||||||
|
|
||||||
|
// VGA color definitions
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VGA_COLOR_BLACK = 0,
|
VGA_COLOR_BLACK = 0,
|
||||||
VGA_COLOR_BLUE = 1,
|
VGA_COLOR_BLUE = 1,
|
||||||
@ -22,7 +26,28 @@ typedef enum {
|
|||||||
VGA_COLOR_WHITE = 15,
|
VGA_COLOR_WHITE = 15,
|
||||||
} vga_color;
|
} vga_color;
|
||||||
|
|
||||||
|
// VGA port addresses
|
||||||
|
typedef enum {
|
||||||
|
VGA_PORT_INDEX = 0x3D4, // Index register for VGA
|
||||||
|
VGA_PORT_DATA = 0x3D5 // Data register for VGA
|
||||||
|
} vga_io_port_t;
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
uint8_t vga_entry_color(vga_color fg, vga_color bg);
|
uint8_t vga_entry_color(vga_color fg, vga_color bg);
|
||||||
uint16_t vga_entry(unsigned char uc, uint8_t color);
|
uint16_t vga_entry(unsigned char uc, uint8_t color);
|
||||||
|
|
||||||
#endif
|
void vga_put_entry_at(char c, uint8_t color, size_t x, size_t y);
|
||||||
|
void vga_clear(uint8_t color);
|
||||||
|
void vga_write_string(const char* data, size_t size);
|
||||||
|
void vga_scroll(void);
|
||||||
|
void vga_set_cursor_position(size_t x, size_t y);
|
||||||
|
size_t vga_get_cursor_position(void);
|
||||||
|
|
||||||
|
void vga_set_cursor_blinking(bool enable);
|
||||||
|
void vga_set_cursor_shape(uint8_t start, uint8_t end);
|
||||||
|
void vga_set_cursor_color(uint8_t color);
|
||||||
|
void vga_set_cursor_blink_rate(uint8_t rate);
|
||||||
|
|
||||||
|
void vga_printf(const char* format, ...);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user