caos-with-snake/kernel.c

131 lines
3.7 KiB
C

#include "console.h"
#include "cpu/isr.h"
#include "cpu/gdt.h"
#include "cpu/memlayout.h"
#include "drivers/keyboard.h"
#include "drivers/vga.h"
#include "drivers/ata.h"
#include "drivers/misc.h"
#include "drivers/pit.h"
#include "drivers/uart.h"
#include "fs/fs.h"
#include "lib/string.h"
#include "proc.h"
#include "kernel/mem.h"
void vga_set_pixel(int x, int y, int color) {
unsigned char* pixel = (unsigned char*) (KERNBASE + 0xA0000 + 320 * y + x);
*pixel = color;
}
void graphtest() {
vgaMode13();
for (int i = 0; i < 320; ++i) {
for (int j = 0; j < 200; ++j) {
vga_set_pixel(i, j, (i+j)/2);
}
}
msleep(5000);
vgaMode3();
vga_clear_screen();
}
void read_line_input(char* buf, size_t* ret_len, size_t cap) {
size_t len = 0;
while (1) {
while (kbd_can_take_from_copy_buffer()) {
uint8_t keycode = kbd_take_from_copy_buffer();
bool shift_pressed = kbd_is_pressed(KEYCODE_SHIFT);
const size_t keycodes = sizeof(keysym_mapped_ascii_upper);
check(keycodes == sizeof(keysym_mapped_ascii_lower));
if (keycode == KEYCODE_ENTER) {
goto end;
} else if (keycode == KEYCODE_BACKSPACE) {
unsigned scr_offset = vga_get_cursor();
if (len > 0 && scr_offset > 0) {
// if (scr_offset % VGA_COLS) {
// vga_set
// }
// vga_set_char()
vga_set_char(scr_offset - 1, ' ');
vga_set_cursor(scr_offset - 1);
len--;
}
} else if (keycode < keycodes) {
char ch = shift_pressed ? keysym_mapped_ascii_upper[keycode] :
keysym_mapped_ascii_lower[keycode];
if (ch != 0) {
char haha[2] = {ch, 0};
printk(haha);
buf[len++] = ch;
if (len == cap) {
goto end;
}
}
}
}
asm("hlt");
size_t count = kbd_state_shrd.len;
if (count > 0) {
cli();
size_t rem = KEYBOARD_INTERRUPT_BUF_CAP - kbd_state_shrd.copy_len;
size_t copying = rem < count ? rem : count;
memcpy(kbd_state_shrd.copy_buf, kbd_state_shrd.buf, copying);
kbd_state_shrd.len -= copying;
kbd_state_shrd.copy_len += copying;
sti();
}
}
end:
printk("\n");
*ret_len = len;
}
void kmain() {
freerange(P2V(2u<<20), P2V(3u<<20));
kvmalloc(); // map all of physical memory at KERNBASE
freerange(P2V(3u<<20), P2V(PHYSTOP));
load_gdt();
init_keyboard();
init_pit();
uartinit();
load_idt();
sti();
vga_clear_screen();
printk("YABLOKO\n\n");
while (1) {
char input[100];
size_t input_len = 0;
const size_t input_cap = sizeof(input) - 1;
printk("> ");
read_line_input(input, &input_len, input_cap);
input[input_len] = 0;
printk(input);
printk("\n");
if (cstr_equal(input, "halt")) {
printk("Bye\n");
qemu_shutdown();
} else if (cstr_equal(input, "work")) {
for (int i = 0; i < 5; ++i) {
msleep(1000);
printk(".");
}
} else if (cstr_equal(input, "graphtest")) {
graphtest();
} else if (cstr_starts_with(input, "run ")) {
const char* cmd = input + 4;
run_elf(cmd);
} else {
printk("unknown command, try: halt | run CMD\n");
}
}
}