Initial commit

This commit is contained in:
Chris
2026-02-04 20:51:17 +01:00
commit ddac1a791e
132 changed files with 11491 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
#include "cli_utils.h"
void cli_cmd_about(char *args) {
(void)args;
cli_write("BrewOS Desktop v0.01 Alpha\n");
}

View File

@@ -0,0 +1,16 @@
#include "cli_utils.h"
#include "io.h"
void cli_cmd_beep(char *args) {
(void)args;
cli_write("BEEP!\n");
outb(0x43, 0xB6);
int freq = 1000;
int div = 1193180 / freq;
outb(0x42, div & 0xFF);
outb(0x42, (div >> 8) & 0xFF);
outb(0x61, inb(0x61) | 0x03);
cli_delay(10000000);
outb(0x61, inb(0x61) & 0xFC);
}

View File

@@ -0,0 +1,8 @@
#include "cli_utils.h"
void cli_cmd_blind(char *args) {
(void)args;
cli_write("Woah.. is this heaven?\n");
cli_write("no.\n");
cli_write("This isn't TempleOS you fucking retard.\n");
}

View File

@@ -0,0 +1,9 @@
#include "cli_utils.h"
// Public declaration from cmd.c
extern void cmd_screen_clear(void);
void cli_cmd_clear(char *args) {
(void)args;
cmd_screen_clear();
}

View File

@@ -0,0 +1,39 @@
#ifndef CLI_APPS_H
#define CLI_APPS_H
// All CLI command function declarations
void cli_cmd_help(char *args);
void cli_cmd_date(char *args);
void cli_cmd_math(char *args);
void cli_cmd_beep(char *args);
void cli_cmd_cowsay(char *args);
void cli_cmd_reboot(char *args);
void cli_cmd_shutdown(char *args);
void cli_cmd_uptime(char *args);
void cli_cmd_man(char *args);
void cli_cmd_license(char *args);
void cli_cmd_txtedit(char *args);
void cli_cmd_blind(char *args);
void cli_cmd_readtheman(char *args);
void cli_cmd_about(char *args);
void cli_cmd_clear(char *args);
void cli_cmd_exit(char *args);
// Filesystem commands
void cli_cmd_cd(char *args);
void cli_cmd_pwd(char *args);
void cli_cmd_ls(char *args);
void cli_cmd_mkdir(char *args);
void cli_cmd_rm(char *args);
void cli_cmd_echo(char *args);
void cli_cmd_cat(char *args);
// Memory management commands
void cli_cmd_meminfo(char *args);
void cli_cmd_malloc(char *args);
void cli_cmd_free_mem(char *args);
void cli_cmd_memblock(char *args);
void cli_cmd_memvalid(char *args);
void cli_cmd_memtest(char *args);
#endif

View File

@@ -0,0 +1,22 @@
#ifndef CLI_COMMAND_H
#define CLI_COMMAND_H
#include <stddef.h>
// Standard interface for CLI command output
// Commands should call these functions to write to the terminal
extern void cli_write(const char *str);
extern void cli_write_int(int n);
extern void cli_putchar(char c);
// Callback function type for command execution
typedef void (*cmd_callback_t)(char *args);
// Command entry in dispatch table
typedef struct {
const char *name;
cmd_callback_t callback;
const char *help_text;
} CLI_Command;
#endif

View File

@@ -0,0 +1,80 @@
#include "cli_utils.h"
// Forward declarations - these will be provided by cmd.c
extern void cmd_putchar(char c);
extern void cmd_write(const char *str);
extern void cmd_write_int(int n);
void cli_memset(void *dest, int val, size_t len) {
unsigned char *ptr = dest;
while (len-- > 0) *ptr++ = val;
}
size_t cli_strlen(const char *str) {
size_t len = 0;
while (str[len]) len++;
return len;
}
int cli_strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
void cli_strcpy(char *dest, const char *src) {
while (*src) *dest++ = *src++;
*dest = 0;
}
int cli_atoi(const char *str) {
int res = 0;
int sign = 1;
if (*str == '-') { sign = -1; str++; }
while (*str >= '0' && *str <= '9') {
res = res * 10 + (*str - '0');
str++;
}
return res * sign;
}
void cli_itoa(int n, char *buf) {
if (n == 0) {
buf[0] = '0'; buf[1] = 0; return;
}
int i = 0;
int sign = n < 0;
if (sign) n = -n;
while (n > 0) {
buf[i++] = (n % 10) + '0';
n /= 10;
}
if (sign) buf[i++] = '-';
buf[i] = 0;
// Reverse
for (int j = 0; j < i / 2; j++) {
char t = buf[j];
buf[j] = buf[i - 1 - j];
buf[i - 1 - j] = t;
}
}
void cli_write(const char *str) {
cmd_write(str);
}
void cli_write_int(int n) {
cmd_write_int(n);
}
void cli_putchar(char c) {
cmd_putchar(c);
}
void cli_delay(int iterations) {
for (volatile int i = 0; i < iterations; i++) {
__asm__ __volatile__("nop");
}
}

View File

@@ -0,0 +1,27 @@
#ifndef CLI_UTILS_H
#define CLI_UTILS_H
#include <stddef.h>
#include <stdint.h>
// String utilities
void cli_memset(void *dest, int val, size_t len);
size_t cli_strlen(const char *str);
int cli_strcmp(const char *s1, const char *s2);
void cli_strcpy(char *dest, const char *src);
int cli_atoi(const char *str);
void cli_itoa(int n, char *buf);
// IO utilities
void cli_write(const char *str);
void cli_write_int(int n);
void cli_putchar(char c);
// Timing utility
void cli_delay(int iterations);
// CLI Command declarations
void cli_cmd_shutdown(char *args);
void cli_cmd_reboot(char *args);
#endif

View File

@@ -0,0 +1,17 @@
#include "cli_utils.h"
void cli_cmd_cowsay(char *args) {
if (!args || !*args) args = (char*)"Brew!";
size_t len = cli_strlen(args);
cli_write(" ");
for(size_t i=0; i<len+2; i++) cli_write("_");
cli_write("\n< "); cli_write(args); cli_write(" >\n ");
for(size_t i=0; i<len+2; i++) cli_write("-");
cli_write("\n");
cli_write(" \\ ^__^\n");
cli_write(" \\ (oo)\\_______\n");
cli_write(" (__)\\ )\\/\\\n");
cli_write(" ||----w |\n");
cli_write(" || ||\n\n");
}

View File

@@ -0,0 +1,15 @@
#include "cli_utils.h"
// Forward declaration from cmd.c
extern void rtc_get_datetime(int *y, int *m, int *d, int *h, int *min, int *s);
void cli_cmd_date(char *args) {
(void)args;
int y, m, d, h, min, s;
rtc_get_datetime(&y, &m, &d, &h, &min, &s);
cli_write("Current Date: ");
cli_write_int(y); cli_write("-"); cli_write_int(m); cli_write("-"); cli_write_int(d);
cli_write(" ");
cli_write_int(h); cli_write(":"); cli_write_int(min); cli_write(":"); cli_write_int(s);
cli_write("\n");
}

View File

@@ -0,0 +1,9 @@
#include "cli_utils.h"
// Public declaration from cmd.c
extern void cmd_window_exit(void);
void cli_cmd_exit(char *args) {
(void)args;
cmd_window_exit();
}

View File

@@ -0,0 +1,241 @@
#include "cli_utils.h"
#include "fat32.h"
void cli_cmd_cd(char *args) {
if (!args || args[0] == 0) {
// No argument - show current directory
char cwd[256];
fat32_get_current_dir(cwd, sizeof(cwd));
cli_write("Current directory: ");
cli_write(cwd);
cli_write("\n");
return;
}
// Parse argument
char path[256];
int i = 0;
while (args[i] && args[i] != ' ' && args[i] != '\t') {
path[i] = args[i];
i++;
}
path[i] = 0;
if (fat32_chdir(path)) {
char cwd[256];
fat32_get_current_dir(cwd, sizeof(cwd));
cli_write("Changed to: ");
cli_write(cwd);
cli_write("\n");
} else {
cli_write("Error: Cannot change to directory: ");
cli_write(path);
cli_write("\n");
}
}
void cli_cmd_pwd(char *args) {
(void)args;
char cwd[256];
fat32_get_current_dir(cwd, sizeof(cwd));
cli_write(cwd);
cli_write("\n");
}
void cli_cmd_ls(char *args) {
char path[256];
if (!args || args[0] == 0) {
// List current directory
fat32_get_current_dir(path, sizeof(path));
} else {
// Parse argument
int i = 0;
while (args[i] && args[i] != ' ' && args[i] != '\t') {
path[i] = args[i];
i++;
}
path[i] = 0;
}
FAT32_FileInfo entries[256];
int count = fat32_list_directory(path, entries, 256);
if (count < 0) {
cli_write("Error: Cannot list directory\n");
return;
}
for (int i = 0; i < count; i++) {
cli_write(entries[i].name);
if (entries[i].is_directory) {
cli_write("/");
}
cli_write(" (");
cli_write_int(entries[i].size);
cli_write(" bytes)\n");
}
cli_write("\n");
cli_write("Total: ");
cli_write_int(count);
cli_write(" items\n");
}
void cli_cmd_mkdir(char *args) {
if (!args || args[0] == 0) {
cli_write("Usage: mkdir <dirname>\n");
return;
}
char dirname[256];
int i = 0;
while (args[i] && args[i] != ' ' && args[i] != '\t') {
dirname[i] = args[i];
i++;
}
dirname[i] = 0;
if (fat32_mkdir(dirname)) {
cli_write("Created directory: ");
cli_write(dirname);
cli_write("\n");
} else {
cli_write("Error: Cannot create directory\n");
}
}
void cli_cmd_rm(char *args) {
if (!args || args[0] == 0) {
cli_write("Usage: rm <filename>\n");
return;
}
char filename[256];
int i = 0;
while (args[i] && args[i] != ' ' && args[i] != '\t') {
filename[i] = args[i];
i++;
}
filename[i] = 0;
if (fat32_delete(filename)) {
cli_write("Deleted: ");
cli_write(filename);
cli_write("\n");
} else {
cli_write("Error: Cannot delete file\n");
}
}
void cli_cmd_echo(char *args) {
if (!args || args[0] == 0) {
cli_write("\n");
return;
}
// Check for redirection operators
char *redirect_ptr = NULL;
char redirect_mode = 0; // '>' for write, 'a' for append
char output_file[256] = {0};
char echo_text[512] = {0};
// Find > or >>
for (int i = 0; args[i]; i++) {
if (args[i] == '>' && args[i+1] == '>') {
redirect_ptr = args + i + 2;
redirect_mode = 'a'; // append
// Copy text before redirection
for (int j = 0; j < i; j++) {
echo_text[j] = args[j];
}
echo_text[i] = 0;
break;
} else if (args[i] == '>') {
redirect_ptr = args + i + 1;
redirect_mode = '>'; // write
// Copy text before redirection
for (int j = 0; j < i; j++) {
echo_text[j] = args[j];
}
echo_text[i] = 0;
break;
}
}
// If no redirection, just print the text
if (!redirect_ptr) {
cli_write(args);
cli_write("\n");
return;
}
// Parse output filename
int i = 0;
while (redirect_ptr[i] && (redirect_ptr[i] == ' ' || redirect_ptr[i] == '\t')) {
i++;
}
int j = 0;
while (redirect_ptr[i] && redirect_ptr[i] != ' ' && redirect_ptr[i] != '\t') {
output_file[j++] = redirect_ptr[i++];
}
output_file[j] = 0;
if (!output_file[0]) {
cli_write("Error: No output file specified\n");
return;
}
// Open file
const char *mode = (redirect_mode == 'a') ? "a" : "w";
FAT32_FileHandle *fh = fat32_open(output_file, mode);
if (!fh) {
cli_write("Error: Cannot open file for writing\n");
return;
}
// Write text
int text_len = 0;
while (echo_text[text_len]) text_len++;
fat32_write(fh, echo_text, text_len);
fat32_write(fh, "\n", 1);
fat32_close(fh);
cli_write("Wrote to: ");
cli_write(output_file);
cli_write("\n");
}
void cli_cmd_cat(char *args) {
if (!args || args[0] == 0) {
cli_write("Usage: cat <filename>\n");
return;
}
char filename[256];
int i = 0;
while (args[i] && args[i] != ' ' && args[i] != '\t') {
filename[i] = args[i];
i++;
}
filename[i] = 0;
FAT32_FileHandle *fh = fat32_open(filename, "r");
if (!fh) {
cli_write("Error: Cannot open file\n");
return;
}
// Read and display file
char buffer[4096];
int bytes_read;
while ((bytes_read = fat32_read(fh, buffer, sizeof(buffer))) > 0) {
for (int j = 0; j < bytes_read; j++) {
cli_putchar(buffer[j]);
}
}
fat32_close(fh);
}

View File

@@ -0,0 +1,18 @@
#include "cli_utils.h"
void cli_cmd_help(char *args) {
(void)args;
cli_write("Available commands:\n");
cli_write(" HELP - Display this help message\n");
cli_write(" DATE - Display current date and time\n");
cli_write(" CLEAR - Clear the screen\n");
cli_write(" ABOUT - System info\n");
cli_write(" MATH - math <op> <a> <b> (e.g. math + 1 2)\n");
cli_write(" MAN - Show user manual (interactive)\n");
cli_write(" LICENSE - Show license (interactive)\n");
cli_write(" UPTIME - System uptime\n");
cli_write(" BEEP - Make a sound\n");
cli_write(" COWSAY - cowsay <msg>\n");
cli_write(" REBOOT - Reboot system\n");
cli_write(" SHUTDOWN- Shutdown system\n");
}

View File

@@ -0,0 +1,21 @@
#include "cli_utils.h"
// Forward declaration from cmd.c
extern void pager_wrap_content(const char **lines, int count);
extern void pager_set_mode(void);
const char* license_pages[] = {
" GNU GENERAL PUBLIC LICENSE",
" Version 3, 29 June 2007",
" Copyright (C) 2024-2026 boreddevnl",
"",
" (License text abbreviated for build size. See https://www.gnu.org/licenses/gpl-3.0.txt)",
"--- End of License ---"
};
const int license_num_lines = sizeof(license_pages) / sizeof(char*);
void cli_cmd_license(char *args) {
(void)args;
pager_wrap_content(license_pages, license_num_lines);
pager_set_mode();
}

46
src/kernel/cli_apps/man.c Normal file
View File

@@ -0,0 +1,46 @@
#include "cli_utils.h"
// Forward declaration from cmd.c
extern void pager_wrap_content(const char **lines, int count);
extern void pager_set_mode(void);
const char* manual_pages[] = {
"BrewKernel User Manual",
"----------------------",
"",
"Welcome to the BrewKernel.",
"",
"== Features ==",
"* Ramdisk-based Filesystem: A simple in-memory filesystem.",
"* VGA Text Mode Driver: Full control over text/colors.",
"* PS/2 Keyboard Driver: Handles key presses.",
"* Simple CLI: A basic shell.",
"",
"== Available Commands ==",
"HELP: Displays a short list of available commands.",
"MAN: Shows this detailed user manual.",
"ABOUT: Displays information about the kernel.",
"MATH: A simple calculator.",
"DATE: Displays the current date and time.",
"TXTEDIT: A simple text editor with file path support.",
" USAGE: txtedit <filename>",
" EXAMPLES:",
" txtedit file.txt (relative path in current directory)",
" txtedit /file.txt (absolute path in root)",
" txtedit /docs/note.txt (absolute path with subdirectories)",
" FEATURES: Create/Edit files, Save (to RAM), Navigation.",
"CLEAR: Clears the entire screen.",
"EXIT: Exits the CLI mode.",
"LICENSE: Displays the full GNU GPL v3.",
"COWSAY: Moo!",
"UPTIME: Shows how long the system has been running.",
"BEEP: Makes a beep sound.",
"--- End of Manual ---"
};
const int manual_num_lines = sizeof(manual_pages) / sizeof(char*);
void cli_cmd_man(char *args) {
(void)args;
pager_wrap_content(manual_pages, manual_num_lines);
pager_set_mode();
}

View File

@@ -0,0 +1,34 @@
#include "cli_utils.h"
void cli_cmd_math(char *args) {
while (*args == ' ') args++;
if (!*args) {
cli_write("Usage: math <op> <n1> <n2>\n");
return;
}
char op = *args;
args++;
while (*args == ' ') args++;
char *end = args;
while (*end && *end != ' ') end++;
int saved = *end;
*end = 0;
int n1 = cli_atoi(args);
if (saved) *end = saved;
args = end;
while (*args == ' ') args++;
int n2 = cli_atoi(args);
int res = 0;
switch(op) {
case '+': res = n1 + n2; break;
case '-': res = n1 - n2; break;
case '*': res = n1 * n2; break;
case '/': if(n2!=0) res = n1/n2; else { cli_write("Div by zero\n"); return; } break;
default: cli_write("Invalid op.\n"); return;
}
cli_write("Result: "); cli_write_int(res); cli_write("\n");
}

View File

@@ -0,0 +1,143 @@
#include "cli_utils.h"
#include "../memory_manager.h"
#define MAX_TEST_ALLOCS 64
static void *test_allocs[MAX_TEST_ALLOCS];
static int test_alloc_count = 0;
void cli_cmd_malloc(char *args) {
if (!args || !args[0]) {
cli_write("Usage: malloc <size_in_kb>\n");
cli_write("Example: malloc 10\n");
return;
}
// Parse size in KB
int size_kb = cli_atoi(args);
if (size_kb <= 0 || size_kb > 1024) {
cli_write("Invalid size. Use 1-1024 KB\n");
return;
}
size_t size = size_kb * 1024;
void *ptr = kmalloc(size);
if (ptr == NULL) {
cli_write("Allocation failed!\n");
return;
}
// Track allocation for later freeing
if (test_alloc_count < MAX_TEST_ALLOCS) {
test_allocs[test_alloc_count++] = ptr;
}
cli_write("Allocated ");
cli_write_int(size_kb);
cli_write("KB at address 0x");
cli_write_int((uintptr_t)ptr / 1024);
cli_write("\n");
cli_write("Test allocation index: ");
cli_write_int(test_alloc_count - 1);
cli_write("\n");
memory_print_stats();
}
void cli_cmd_free_mem(char *args) {
if (!args || !args[0]) {
cli_write("Usage: freemem <index>\n");
cli_write("Specify the allocation index from malloc output\n");
return;
}
int idx = cli_atoi(args);
if (idx < 0 || idx >= test_alloc_count) {
cli_write("Invalid index. Must be 0-");
cli_write_int(test_alloc_count - 1);
cli_write("\n");
return;
}
void *ptr = test_allocs[idx];
if (ptr == NULL) {
cli_write("Allocation at index ");
cli_write_int(idx);
cli_write(" is NULL\n");
return;
}
kfree(ptr);
test_allocs[idx] = NULL;
cli_write("Freed allocation at index ");
cli_write_int(idx);
cli_write("\n");
memory_print_stats();
}
void cli_cmd_memblock(char *args) {
(void)args;
cli_write("Detailed block information:\n");
memory_print_detailed();
}
void cli_cmd_memvalid(char *args) {
(void)args;
cli_write("Validating memory integrity...\n");
memory_validate();
}
void cli_cmd_memtest(char *args) {
(void)args;
cli_write("\n=== MEMORY STRESS TEST ===\n");
// Allocate multiple blocks
cli_write("Allocating 10 blocks of 256KB each...\n");
void *test_ptrs[10];
for (int i = 0; i < 10; i++) {
test_ptrs[i] = kmalloc(256 * 1024);
if (test_ptrs[i] == NULL) {
cli_write("Allocation ");
cli_write_int(i);
cli_write(" failed\n");
// Free previous allocations
for (int j = 0; j < i; j++) {
kfree(test_ptrs[j]);
}
return;
}
cli_write("Allocated block ");
cli_write_int(i);
cli_write("\n");
}
memory_print_stats();
// Free every other block (create fragmentation)
cli_write("\nFreeing alternate blocks to create fragmentation...\n");
for (int i = 0; i < 10; i += 2) {
kfree(test_ptrs[i]);
cli_write("Freed block ");
cli_write_int(i);
cli_write("\n");
}
memory_print_stats();
// Free remaining blocks
cli_write("\nFreeing remaining blocks...\n");
for (int i = 1; i < 10; i += 2) {
kfree(test_ptrs[i]);
}
memory_print_stats();
cli_write("=== TEST COMPLETE ===\n\n");
}

View File

@@ -0,0 +1,9 @@
#include "cli_utils.h"
#include "../memory_manager.h"
void cli_cmd_meminfo(char *args) {
(void)args;
// Print memory statistics
memory_print_stats();
}

View File

@@ -0,0 +1,14 @@
#include "cli_utils.h"
// Forward declaration from cmd.c
extern void cli_cmd_beep(char *args);
void cli_cmd_readtheman(char *args) {
(void)args;
cli_write("\nYou read the manual? NERD. you know what?\n");
cli_write("Fuck you.\n");
for(int i=0; i<3; i++) {
cli_cmd_beep(NULL);
cli_delay(1000000);
}
}

View File

@@ -0,0 +1,11 @@
#include "cli_utils.h"
#include "io.h"
void cli_cmd_reboot(char *args) {
(void)args;
cli_write("Rebooting...\n");
cli_delay(10000000);
while ((inb(0x64) & 2) != 0) cli_delay(1000);
outb(0x64, 0xFE);
asm volatile ("int $0x3");
}

View File

@@ -0,0 +1,11 @@
#include "cli_utils.h"
#include "io.h"
void cli_cmd_shutdown(char *args) {
(void)args;
cli_write("Shutting down...\n");
cli_delay(10000000);
outb(0x64, 0xFE);
outw(0x604, 0x2000);
outw(0xB004, 0x2000);
}

View File

@@ -0,0 +1,61 @@
#include "cli_utils.h"
#include "fat32.h"
#include "wm.h"
// Forward declarations from editor.h and wm.c
extern void editor_open_file(const char *filename);
extern void editor_init(void);
extern Window win_editor;
extern Window win_explorer;
extern Window win_cmd;
extern Window win_notepad;
extern Window win_calculator;
void cli_cmd_txtedit(char *args) {
// Parse the file path argument
char filepath[256];
int i = 0;
// Skip leading whitespace
while (args && args[i] && (args[i] == ' ' || args[i] == '\t')) {
i++;
}
// Extract filepath
int j = 0;
while (args && args[i] && args[i] != ' ' && args[i] != '\t' && j < 255) {
filepath[j++] = args[i++];
}
filepath[j] = 0;
// If no filepath provided, create a new empty file
if (j == 0) {
cli_write("Usage: txtedit <filename>\n");
cli_write("Example: txtedit myfile.txt\n");
cli_write(" txtedit /document.txt\n");
return;
}
// Normalize the path (handles relative and absolute paths)
char normalized_path[256];
fat32_normalize_path(filepath, normalized_path);
// Open the file in the GUI editor
editor_open_file(normalized_path);
// Make editor window visible and focused, bring to front
win_editor.visible = true;
win_editor.focused = true;
// Calculate max z_index to bring window to front
int max_z = 0;
if (win_explorer.z_index > max_z) max_z = win_explorer.z_index;
if (win_cmd.z_index > max_z) max_z = win_cmd.z_index;
if (win_notepad.z_index > max_z) max_z = win_notepad.z_index;
if (win_calculator.z_index > max_z) max_z = win_calculator.z_index;
win_editor.z_index = max_z + 1;
cli_write("Opening: ");
cli_write(normalized_path);
cli_write("\n");
}

View File

@@ -0,0 +1,26 @@
#include "cli_utils.h"
// Forward declarations from cmd.c
extern void rtc_get_datetime(int *y, int *m, int *d, int *h, int *min, int *s);
extern int boot_time_init;
extern int boot_year, boot_month, boot_day, boot_hour, boot_min, boot_sec;
void cli_cmd_uptime(char *args) {
(void)args;
int y, m, d, h, min, s;
rtc_get_datetime(&y, &m, &d, &h, &min, &s);
int start_sec = boot_hour * 3600 + boot_min * 60 + boot_sec;
int curr_sec = h * 3600 + min * 60 + s;
if (curr_sec < start_sec) curr_sec += 24 * 3600;
int diff = curr_sec - start_sec;
int up_h = diff / 3600;
int up_m = (diff % 3600) / 60;
int up_s = diff % 60;
cli_write("Uptime: ");
cli_write_int(up_h); cli_write("h ");
cli_write_int(up_m); cli_write("m ");
cli_write_int(up_s); cli_write("s\n");
}