From a39baf2d6e6dd759fb8c4ce4bab6779aac586126 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Thu, 31 Mar 2022 15:40:48 +0200 Subject: init: move ansiterm to `driver/` --- src/init/ansiterm.c | 105 -------------------------------------------- src/init/driver/ansiterm.c | 106 +++++++++++++++++++++++++++++++++++++++++++++ src/init/driver/driver.h | 3 ++ src/init/main.c | 3 +- 4 files changed, 110 insertions(+), 107 deletions(-) delete mode 100644 src/init/ansiterm.c create mode 100644 src/init/driver/ansiterm.c create mode 100644 src/init/driver/driver.h diff --git a/src/init/ansiterm.c b/src/init/ansiterm.c deleted file mode 100644 index 41b313f..0000000 --- a/src/init/ansiterm.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include - -struct vga_cell { - unsigned char c; - unsigned char style; -} __attribute__((__packed__)); -static struct vga_cell vga[80 * 25]; - -static handle_t tty_fd; -static handle_t vga_fd; - -static struct {int x, y;} cursor = {0}; -static bool dirty = false; -static bool pendingFlush = false; - -/* TODO unflushed writes mix with the kernel's vga driver */ - -static void flush(void) { - _syscall_write(vga_fd, vga, sizeof vga, 0); - dirty = false; - pendingFlush = false; -} - -static void scroll(void) { - for (size_t i = 0; i < 80 * 24; i++) - vga[i] = vga[i + 80]; - for (size_t i = 80 * 24; i < 80 * 25; i++) - vga[i].c = ' '; - cursor.y--; - pendingFlush = true; -} - -static void in_char(char c) { - switch (c) { - case '\n': - cursor.x = 0; - cursor.y++; - pendingFlush = true; - break; - case '\b': - if (--cursor.x < 0) cursor.x = 0; - break; - default: - vga[cursor.y * 80 + cursor.x++].c = c; - } - - if (cursor.x >= 80) { - cursor.x = 0; - cursor.y++; - } - while (cursor.y >= 25) scroll(); - dirty = true; -} - -void ansiterm_drv(void) { - tty_fd = _syscall_open("/tty", 4); - _syscall_write(tty_fd, "ansiterm...\n", 12, 0); - - vga_fd = _syscall_open("/vga", 4); - _syscall_read(vga_fd, vga, sizeof vga, 0); - - // find first empty line - for (cursor.y = 0; cursor.y < 25; cursor.y++) { - for (cursor.x = 0; cursor.x < 80; cursor.x++) { - char c = vga[cursor.y * 80 + cursor.x].c; - if (c != ' ' && c != '\0') break; - } - if (cursor.x == 80) break; - } - cursor.x = 0; - - static char buf[512]; - struct fs_wait_response res; - while (!_syscall_fs_wait(buf, sizeof buf, &res)) { - switch (res.op) { - case VFSOP_OPEN: - // TODO check path - _syscall_fs_respond(NULL, 1); - break; - - case VFSOP_WRITE: - _syscall_write(tty_fd, buf, res.len, 0); - for (int i = 0; i < res.len; i++) - in_char(buf[i]); - if (pendingFlush) flush(); - _syscall_fs_respond(NULL, res.len); - break; - - case VFSOP_READ: - if (res.capacity > sizeof buf) - res.capacity = sizeof buf; - if (dirty) flush(); - size_t len = _syscall_read(tty_fd, buf, res.capacity, 0); - _syscall_fs_respond(buf, len); - break; - - default: - _syscall_fs_respond(NULL, -1); - break; - } - } - - _syscall_exit(1); -} diff --git a/src/init/driver/ansiterm.c b/src/init/driver/ansiterm.c new file mode 100644 index 0000000..5b05af1 --- /dev/null +++ b/src/init/driver/ansiterm.c @@ -0,0 +1,106 @@ +#include +#include +#include + +struct vga_cell { + unsigned char c; + unsigned char style; +} __attribute__((__packed__)); +static struct vga_cell vga[80 * 25]; + +static handle_t tty_fd; +static handle_t vga_fd; + +static struct {int x, y;} cursor = {0}; +static bool dirty = false; +static bool pendingFlush = false; + +/* TODO unflushed writes mix with the kernel's vga driver */ + +static void flush(void) { + _syscall_write(vga_fd, vga, sizeof vga, 0); + dirty = false; + pendingFlush = false; +} + +static void scroll(void) { + for (size_t i = 0; i < 80 * 24; i++) + vga[i] = vga[i + 80]; + for (size_t i = 80 * 24; i < 80 * 25; i++) + vga[i].c = ' '; + cursor.y--; + pendingFlush = true; +} + +static void in_char(char c) { + switch (c) { + case '\n': + cursor.x = 0; + cursor.y++; + pendingFlush = true; + break; + case '\b': + if (--cursor.x < 0) cursor.x = 0; + break; + default: + vga[cursor.y * 80 + cursor.x++].c = c; + } + + if (cursor.x >= 80) { + cursor.x = 0; + cursor.y++; + } + while (cursor.y >= 25) scroll(); + dirty = true; +} + +void ansiterm_drv(void) { + tty_fd = _syscall_open("/tty", 4); + _syscall_write(tty_fd, "ansiterm...\n", 12, 0); + + vga_fd = _syscall_open("/vga", 4); + _syscall_read(vga_fd, vga, sizeof vga, 0); + + // find first empty line + for (cursor.y = 0; cursor.y < 25; cursor.y++) { + for (cursor.x = 0; cursor.x < 80; cursor.x++) { + char c = vga[cursor.y * 80 + cursor.x].c; + if (c != ' ' && c != '\0') break; + } + if (cursor.x == 80) break; + } + cursor.x = 0; + + static char buf[512]; + struct fs_wait_response res; + while (!_syscall_fs_wait(buf, sizeof buf, &res)) { + switch (res.op) { + case VFSOP_OPEN: + // TODO check path + _syscall_fs_respond(NULL, 1); + break; + + case VFSOP_WRITE: + _syscall_write(tty_fd, buf, res.len, 0); + for (int i = 0; i < res.len; i++) + in_char(buf[i]); + if (pendingFlush) flush(); + _syscall_fs_respond(NULL, res.len); + break; + + case VFSOP_READ: + if (res.capacity > sizeof buf) + res.capacity = sizeof buf; + if (dirty) flush(); + size_t len = _syscall_read(tty_fd, buf, res.capacity, 0); + _syscall_fs_respond(buf, len); + break; + + default: + _syscall_fs_respond(NULL, -1); + break; + } + } + + _syscall_exit(1); +} diff --git a/src/init/driver/driver.h b/src/init/driver/driver.h new file mode 100644 index 0000000..e854c65 --- /dev/null +++ b/src/init/driver/driver.h @@ -0,0 +1,3 @@ +#pragma once + +void ansiterm_drv(void); diff --git a/src/init/main.c b/src/init/main.c index 1b9c7ed..18ff9c3 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -17,8 +18,6 @@ extern char _initrd; void read_file(const char *path, size_t len); void fs_prep(void); -void ansiterm_drv(void); // TODO header file - __attribute__((section(".text.startup"))) int main(void) { // allocate bss -- cgit v1.2.3