129 lines
3.6 KiB
C
129 lines
3.6 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() {
|
|
switch_to_graphics_mode();
|
|
for (int i = 0; i < 320; ++i) {
|
|
for (int j = 0; j < 200; ++j) {
|
|
vga_set_pixel(i, j, (i+j)/2);
|
|
}
|
|
}
|
|
msleep(5000);
|
|
switch_to_text_mode();
|
|
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) {
|
|
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 volatile("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(3u<<20), P2V(4u<<20));
|
|
kvmalloc(); // map all of physical memory at KERNBASE
|
|
freerange(P2V(4u<<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, "")) {
|
|
run_elf("snake");
|
|
} else 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");
|
|
}
|
|
}
|
|
}
|