From 9e103cf8d70a66301e77258c0f5042803e3b0298 Mon Sep 17 00:00:00 2001 From: Arslaan Pathan Date: Tue, 21 Apr 2026 11:42:43 +1200 Subject: Update README to add a short description and legal notice so that california doesn't sue me --- README.md | 10 ++++ src/kernel.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) diff --git a/README.md b/README.md index 7fa4c80..7d5b65d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # FrenchToastOS +FrenchToastOS is a simple, from-scratch x86 operating system. It currently has support for PS/2 keyboard input and can print text to a graphical framebuffer. + +## Legal Notice + +Residents of territories that require age verification for operating systems are prohibited from using FrenchToastOS. This list currently includes Brazil (Lei 15.211, effective March 17, 2026), California (AB-1043, effective January 1, 2027), and will include Colorado, Illinois, and New York if they pass their currently proposed legislations. + +As a hobby operating system project developed by a single developer in his free time, I do not have the legal infrastructure nor resources to implement the 'auditable age verification' and 'identity verification' mechanisms required by these laws, and I have no intention of modifying FrenchToastOS to fit these requirements. + +I find it ridiculous that I have to even place this legal notice here in the first place, OS providers should not need to verify ages, neither should platforms. Wanted to have online safety? We had a tool for that, it was called **PARENTS.** + ## Credits - Terminal font: https://github.com/dhepper/font8x8 diff --git a/src/kernel.c b/src/kernel.c index 28b1dc8..97a42b5 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -6,6 +6,10 @@ This software is licensed under the ARPL. See LICENSE for details. */ #include #include "font8x8_basic.h" +#define KB_DATA_PORT 0x60 +#define KB_STATUS_PORT 0x64 +#define KB_OBF 0x01 + /* check if compiler thinks we are targeting incorrect OS. */ #if defined(__linux__) #error "you are not using a cross-compiler, this is bad. use an elf cross-compiler for ix86 targets, for example, i386-elf-gcc" @@ -22,6 +26,7 @@ static uint32_t *g_framebuffer = NULL; static uint32_t g_width = 0; static uint32_t g_height = 0; static uint32_t g_default_color = 0xFFFFFF; +static bool kbd_shifted = false; /* what in the dark magic? ok just dont touch one can hope */ struct multiboot_info { @@ -55,6 +60,138 @@ struct multiboot_info { uint8_t color_info[6]; } __attribute__((packed)); +static const char scancode_to_ascii[128] __attribute__((section(".text"))) = { + [0x29] = '`', + [0x02] = '1', + [0x03] = '2', + [0x04] = '3', + [0x05] = '4', + [0x06] = '5', + [0x07] = '6', + [0x08] = '7', + [0x09] = '8', + [0x0A] = '9', + [0x0B] = '0', + [0x0C] = '-', + [0x0D] = '=', + [0x0E] = '\b', + + [0x10] = 'q', + [0x11] = 'w', + [0x12] = 'e', + [0x13] = 'r', + [0x14] = 't', + [0x15] = 'y', + [0x16] = 'u', + [0x17] = 'i', + [0x18] = 'o', + [0x19] = 'p', + + [0x1A] = '[', + [0x1B] = ']', + [0x1C] = '\n', + [0x2B] = '\\', + + [0x1E] = 'a', + [0x1F] = 's', + [0x20] = 'd', + [0x21] = 'f', + [0x22] = 'g', + [0x23] = 'h', + [0x24] = 'j', + [0x25] = 'k', + [0x26] = 'l', + + [0x27] = ';', + [0x28] = '\'', + + [0x2C] = 'z', + [0x2D] = 'x', + [0x2E] = 'c', + [0x2F] = 'v', + [0x30] = 'b', + [0x31] = 'n', + [0x32] = 'm', + [0x33] = ',', + [0x34] = '.', + [0x35] = '/', + + [0x39] = ' ', +}; + +static const char scancode_to_ascii_shifted[128] __attribute__((section(".text"))) = { + [0x29] = '~', + [0x02] = '!', + [0x03] = '@', + [0x04] = '#', + [0x05] = '$', + [0x06] = '%', + [0x07] = '^', + [0x08] = '&', + [0x09] = '*', + [0x0A] = '(', + [0x0B] = ')', + [0x0C] = '_', + [0x0D] = '+', + [0x0E] = '\b', + + [0x10] = 'Q', + [0x11] = 'W', + [0x12] = 'E', + [0x13] = 'R', + [0x14] = 'T', + [0x15] = 'Y', + [0x16] = 'U', + [0x17] = 'I', + [0x18] = 'O', + [0x19] = 'P', + + [0x1A] = '{', + [0x1B] = '}', + [0x1C] = '\n', + [0x2B] = '|', + + [0x1E] = 'A', + [0x1F] = 'S', + [0x20] = 'D', + [0x21] = 'F', + [0x22] = 'G', + [0x23] = 'H', + [0x24] = 'J', + [0x25] = 'K', + [0x26] = 'L', + + [0x27] = ':', + [0x28] = '"', + + [0x2C] = 'Z', + [0x2D] = 'X', + [0x2E] = 'C', + [0x2F] = 'V', + [0x30] = 'B', + [0x31] = 'N', + [0x32] = 'M', + [0x33] = '<', + [0x34] = '>', + [0x35] = '?', + + [0x39] = ' ', +}; + +static inline void outb(uint16_t port, uint8_t val) { + asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +uint8_t keyboard_read_scan_code() { + while (!(inb(KB_STATUS_PORT) & KB_OBF)); + return inb(KB_DATA_PORT); +} void draw_char(int x, int y, int c, uint32_t color, uint32_t *framebuffer, uint32_t width) { char *glyph = font8x8_basic[(unsigned char)c]; @@ -117,6 +254,46 @@ void term_printf(const char *str) } } +void shell() { + term_set_color(0xFCD24D); + term_printf("\n> "); + term_set_color(0xFFFFFF); + while (1) { + uint8_t scancode = keyboard_read_scan_code(); + + // shift or no shift???? + if (scancode == 0x2A) kbd_shifted = true; + if (scancode == 0xAA) kbd_shifted = false; + + // we dont care abt key releases + if (scancode & 0x80) continue; + + char c = kbd_shifted ? scancode_to_ascii_shifted[scancode] : scancode_to_ascii[scancode]; + + if (c) { + if (c == '\n') { + // enter, interpret command + // we dont know what to do with command yet so new prompt and pretend we did something + // we also need to add like handling of the current command, do that soon! + term_set_color(0xFCD24D); + term_printf("\n> "); + term_set_color(0xFFFFFF); + } + if (c == '\b') { + // stupid nut keep trying to use backspace when its not done yet, just add a handler placeholder + term_printf("\n---\nyou stupid nut!\n"); + term_printf("we dont have backspace yet, stop trying to when testing! get better\n"); + term_set_color(0xFCD24D); + term_printf("\n> "); + term_set_color(0xFFFFFF); + } + else { + term_printf(&c); + } + } + } +} + void kernel_main(struct multiboot_info *mbi) { // check if framebuffer info is available (bit 12) @@ -142,6 +319,9 @@ void kernel_main(struct multiboot_info *mbi) term_printf("---\n"); term_printf("https://arslaancodes.com\n"); + term_printf("\n---\nShell:\n"); + shell(); + // if theres nothing left to do, halt the cpu or else cooked // our boot.s already does this but better to be safe than sorry while (1) { -- cgit v1.2.3