Add command line editor
This commit is contained in:
parent
2f4311b2c0
commit
a9b31d6bfd
|
@ -146,6 +146,9 @@ static void text_putchar(char c) {
|
|||
text_set_cursor_pos(0, (text_get_cursor_pos_y() + 1));
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
text_set_cursor_pos(0, text_get_cursor_pos_y());
|
||||
break;
|
||||
case 0x08:
|
||||
if (cursor_offset) {
|
||||
clear_cursor();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/real.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <lib/libc.h>
|
||||
|
||||
void pit_sleep(uint64_t pit_ticks) {
|
||||
uint64_t target = global_pit_tick + pit_ticks;
|
||||
|
@ -13,6 +14,18 @@ void pit_sleep(uint64_t pit_ticks) {
|
|||
}
|
||||
}
|
||||
|
||||
int pit_sleep_and_quit_on_keypress(uint64_t pit_ticks) {
|
||||
uint64_t target = global_pit_tick + pit_ticks;
|
||||
while (global_pit_tick < target && !kbd_int) {
|
||||
asm volatile ("hlt");
|
||||
}
|
||||
if (kbd_int) {
|
||||
kbd_int = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t strtoui(const char *s) {
|
||||
uint64_t n = 0;
|
||||
while (*s)
|
||||
|
@ -26,8 +39,11 @@ char getchar(void) {
|
|||
return (char)(r.eax & 0xff);
|
||||
}
|
||||
|
||||
void gets(char *buf, size_t limit) {
|
||||
for (size_t i = 0; ; ) {
|
||||
void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
size_t orig_str_len = strlen(orig_str);
|
||||
memmove(buf, orig_str, orig_str_len);
|
||||
text_write(orig_str, orig_str_len);
|
||||
for (size_t i = orig_str_len; ; ) {
|
||||
char c = getchar();
|
||||
switch (c) {
|
||||
case '\b':
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void pit_sleep(uint64_t pit_ticks);
|
||||
int pit_sleep_and_quit_on_keypress(uint64_t pit_ticks);
|
||||
|
||||
void print(const char *fmt, ...);
|
||||
char getchar(void);
|
||||
void gets(char *buf, size_t limit);
|
||||
void gets(const char *orig_str, char *buf, size_t limit);
|
||||
uint64_t strtoui(const char *s);
|
||||
|
||||
#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
|
||||
|
|
10
src/main.c
10
src/main.c
|
@ -67,6 +67,16 @@ void main(int boot_drive) {
|
|||
for (;;);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
for (int i = 3; i; i--) {
|
||||
print("\rBooting in %d (press any key to edit command line)...", i);
|
||||
if (pit_sleep_and_quit_on_keypress(18)) {
|
||||
print("\n\n> ");
|
||||
gets(cmdline, cmdline, 128);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
load_echfs_file(drive, part, (void *)0x100000, path);
|
||||
|
||||
// Boot the kernel.
|
||||
|
|
|
@ -4,19 +4,28 @@
|
|||
#include <lib/cio.h>
|
||||
#include <lib/blib.h>
|
||||
|
||||
volatile uint64_t global_pit_tick = 0;
|
||||
|
||||
__attribute__((interrupt)) static void unhandled_int(void *r) {
|
||||
(void)r;
|
||||
print("Warning: unhandled interrupt");
|
||||
}
|
||||
|
||||
volatile uint64_t global_pit_tick = 0;
|
||||
|
||||
__attribute__((interrupt)) static void pit_irq(void *r) {
|
||||
(void)r;
|
||||
global_pit_tick++;
|
||||
port_out_b(0x20, 0x20);
|
||||
}
|
||||
|
||||
volatile int kbd_int = 0;
|
||||
|
||||
__attribute__((interrupt)) static void keyboard_handler(void *r) {
|
||||
(void)r;
|
||||
kbd_int = 1;
|
||||
(void)port_in_b(0x60);
|
||||
port_out_b(0x20, 0x20);
|
||||
}
|
||||
|
||||
uint8_t rm_pic0_mask = 0xff;
|
||||
uint8_t rm_pic1_mask = 0xff;
|
||||
uint8_t pm_pic0_mask = 0xff;
|
||||
|
@ -48,6 +57,7 @@ void init_idt(void) {
|
|||
}
|
||||
|
||||
register_interrupt_handler(0x08, pit_irq, 0x8e);
|
||||
register_interrupt_handler(0x09, keyboard_handler, 0x8e);
|
||||
|
||||
struct idt_ptr_t idt_ptr = {
|
||||
sizeof(idt) - 1,
|
||||
|
@ -60,7 +70,7 @@ void init_idt(void) {
|
|||
: "m" (idt_ptr)
|
||||
);
|
||||
|
||||
pm_pic0_mask = 0xfe;
|
||||
pm_pic0_mask = 0xfc;
|
||||
pm_pic1_mask = 0xff;
|
||||
port_out_b(0x21, pm_pic0_mask);
|
||||
port_out_b(0xa1, pm_pic1_mask);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stddef.h>
|
||||
|
||||
extern volatile uint64_t global_pit_tick;
|
||||
extern volatile int kbd_int;
|
||||
|
||||
extern uint8_t rm_pic0_mask;
|
||||
extern uint8_t rm_pic1_mask;
|
||||
|
|
Loading…
Reference in New Issue