thank u gemini this is good too

This commit is contained in:
2026-04-16 15:51:12 -04:00
parent 51c553524f
commit 1f27048c50
5 changed files with 53 additions and 64 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -10,7 +10,8 @@ uint16_t* vga_buffer = (uint16_t*) 0xB8000;
// System State // System State
size_t terminal_row = 0; size_t terminal_row = 0;
size_t terminal_col = 0; size_t terminal_col = 0;
uint8_t terminal_color = 7; // Light grey on black uint8_t terminal_color = 7;
int is_shift_pressed = 0;
// --- Low Level I/O --- // --- Low Level I/O ---
@@ -24,30 +25,34 @@ static inline uint8_t inb(uint16_t port) {
return ret; return ret;
} }
// --- Hardware Cursor Logic ---
void update_cursor(int x, int y) { void update_cursor(int x, int y) {
uint16_t pos = y * VGA_WIDTH + x; uint16_t pos = y * VGA_WIDTH + x;
outb(0x3D4, 0x0F); outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t) (pos & 0xFF)); outb(0x3D5, (uint8_t) (pos & 0xFF));
outb(0x3D4, 0x0E); outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
} }
// --- String & Memory Utilities --- // --- Memory & Scrolling ---
int strlen(const char* str) { void scroll() {
int len = 0; // Move every row up by one
while (str[len]) len++; for (size_t y = 0; y < VGA_HEIGHT - 1; y++) {
return len; for (size_t x = 0; x < VGA_WIDTH; x++) {
vga_buffer[y * VGA_WIDTH + x] = vga_buffer[(y + 1) * VGA_WIDTH + x];
}
}
// Clear the last row
for (size_t x = 0; x < VGA_WIDTH; x++) {
vga_buffer[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = (uint16_t)' ' | (uint16_t)terminal_color << 8;
}
terminal_row = VGA_HEIGHT - 1;
} }
// --- String Utilities ---
int strcmp(const char* s1, const char* s2) { int strcmp(const char* s1, const char* s2) {
while (*s1 && (*s1 == *s2)) { while (*s1 && (*s1 == *s2)) { s1++; s2++; }
s1++;
s2++;
}
return *(unsigned char*)s1 - *(unsigned char*)s2; return *(unsigned char*)s1 - *(unsigned char*)s2;
} }
@@ -63,11 +68,7 @@ char* itoa(int value, char* str, int base) {
v /= base; v /= base;
} while (v); } while (v);
*ptr-- = '\0'; *ptr-- = '\0';
while (low < ptr) { while (low < ptr) { char tmp = *low; *low++ = *ptr; *ptr-- = tmp; }
char tmp = *low;
*low++ = *ptr;
*ptr-- = tmp;
}
return rc; return rc;
} }
@@ -77,13 +78,8 @@ void putchar(char c) {
if (c == '\n') { if (c == '\n') {
terminal_col = 0; terminal_col = 0;
terminal_row++; terminal_row++;
} else if (c == '\b') {
// Backspace logic is handled in scanf,
// but putchar supports it for generic use
if (terminal_col > 0) terminal_col--;
} else { } else {
const size_t index = terminal_row * VGA_WIDTH + terminal_col; vga_buffer[terminal_row * VGA_WIDTH + terminal_col] = (uint16_t) c | (uint16_t) terminal_color << 8;
vga_buffer[index] = (uint16_t) c | (uint16_t) terminal_color << 8;
if (++terminal_col == VGA_WIDTH) { if (++terminal_col == VGA_WIDTH) {
terminal_col = 0; terminal_col = 0;
terminal_row++; terminal_row++;
@@ -91,8 +87,7 @@ void putchar(char c) {
} }
if (terminal_row >= VGA_HEIGHT) { if (terminal_row >= VGA_HEIGHT) {
// Simple scroll: just reset to top for now scroll();
terminal_row = 0;
} }
update_cursor(terminal_col, terminal_row); update_cursor(terminal_col, terminal_row);
} }
@@ -107,11 +102,8 @@ void printf(const char* format, ...) {
char* s = va_arg(args, char*); char* s = va_arg(args, char*);
while (*s) putchar(*s++); while (*s) putchar(*s++);
} else if (format[i] == 'd') { } else if (format[i] == 'd') {
char buf[32]; char buf[32]; itoa(va_arg(args, int), buf, 10);
itoa(va_arg(args, int), buf, 10);
for (int j = 0; buf[j]; j++) putchar(buf[j]); for (int j = 0; buf[j]; j++) putchar(buf[j]);
} else if (format[i] == 'c') {
putchar((char)va_arg(args, int));
} }
} else { } else {
putchar(format[i]); putchar(format[i]);
@@ -120,22 +112,30 @@ void printf(const char* format, ...) {
va_end(args); va_end(args);
} }
// --- Keyboard Input --- // --- Keyboard Logic ---
char getchar() { char getchar() {
static unsigned char map[128] = { static unsigned char normal_map[128] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ' 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' '
}; };
static unsigned char shift_map[128] = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '~', 0, '|',
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' '
};
while (1) { while (1) {
if (inb(0x64) & 0x01) { if (inb(0x64) & 0x01) {
uint8_t scancode = inb(0x60); uint8_t scancode = inb(0x60);
// Ignore key-release events (scancode + 128) and non-mapped keys (Alt/Shift) if (scancode == 0x2A || scancode == 0x36) is_shift_pressed = 1;
if (scancode < 128 && map[scancode] != 0) { else if (scancode == 0xAA || scancode == 0xB6) is_shift_pressed = 0;
return map[scancode]; else if (scancode < 128) {
unsigned char c = is_shift_pressed ? shift_map[scancode] : normal_map[scancode];
if (c != 0) return c;
} }
} }
} }
@@ -149,54 +149,43 @@ void scanf(char* buffer) {
buffer[i] = '\0'; buffer[i] = '\0';
putchar('\n'); putchar('\n');
break; break;
} else if (c == '\b') { } else if (c == '\b' && i > 0) {
if (i > 0) { i--;
i--; if (terminal_col > 0) terminal_col--;
if (terminal_col > 0) { vga_buffer[terminal_row * VGA_WIDTH + terminal_col] = (uint16_t)' ' | (uint16_t)terminal_color << 8;
terminal_col--; update_cursor(terminal_col, terminal_row);
} else if (terminal_row > 0) { } else if (c != '\b') {
terminal_row--;
terminal_col = VGA_WIDTH - 1;
}
// Clear the character visually
vga_buffer[terminal_row * VGA_WIDTH + terminal_col] = (uint16_t)' ' | (uint16_t)terminal_color << 8;
update_cursor(terminal_col, terminal_row);
}
} else {
buffer[i++] = c; buffer[i++] = c;
putchar(c); putchar(c);
} }
} }
} }
// --- Kernel Entry --- // --- Main Loop ---
void kernel_main(void) { void kernel_main(void) {
// Clear Screen for (size_t i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) vga_buffer[i] = (uint16_t)' ' | (uint16_t)7 << 8;
for (size_t i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
vga_buffer[i] = (uint16_t)' ' | (uint16_t)7 << 8;
}
update_cursor(0, 0); update_cursor(0, 0);
printf("BUGS (Buggy Unverified Greatish Script) v1.1\n"); printf("BUGS v1.2 (Scroll & Shift Enabled)\n");
printf("Hardware Cursor: ENABLED\n");
printf("Filtering Alt/Tab symbols: ENABLED\n\n");
while (1) { while (1) {
printf("BUGS> "); printf("BUGS> ");
char input[64]; char input[64];
scanf(input); scanf(input);
if (strcmp(input, "help") == 0) { if (strcmp(input, "clear") == 0) {
printf("Available commands: help, clear, hello\n");
} else if (strcmp(input, "clear") == 0) {
for (size_t i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) vga_buffer[i] = (uint16_t)' ' | (uint16_t)7 << 8; for (size_t i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) vga_buffer[i] = (uint16_t)' ' | (uint16_t)7 << 8;
terminal_row = 0; terminal_col = 0; terminal_row = 0; terminal_col = 0;
update_cursor(0,0); update_cursor(0,0);
} else if (strcmp(input, "hello") == 0) { } else if (strcmp(input, "help") == 0) {
printf("Greetings from the kernel!\n"); printf("Commands: help, clear, color, test\n");
} else if (strlen(input) > 0) { } else if (strcmp(input, "color") == 0) {
printf("Unknown command: %s\n", input); terminal_color = (terminal_color + 1) % 15;
if (terminal_color == 0) terminal_color = 1;
printf("Text color changed!\n");
} else if (strcmp(input, "test") == 0) {
printf("Symbols: !@#$%^&*()_+\n");
} }
} }
} }

Binary file not shown.