From 0fc40ad5e401653e5d683da95a39d7f2961bdbfd Mon Sep 17 00:00:00 2001 From: Xnoe Date: Tue, 12 Apr 2022 03:42:13 +0100 Subject: [PATCH] Add system calls for more file system related functionality. Add ls command to world.c. Remove and reorganise certain source code files. Update terminal to no longer have two copies of ANSI escape code handling between write and printf. Massively simplify my printf function. Combine io and ioports. --- src/bootstage2/main.c | 26 -- src/bootstage2/screenstuff.c | 165 ------------ src/bootstage2/screenstuff.h | 19 -- src/bootstage2/strings.c | 58 ----- src/bootstage2/strings.h | 3 - src/common/common.h | 25 ++ src/common/syscalls.h | 16 +- src/kernel/allocate.h | 1 - src/kernel/ata.h | 4 - src/kernel/datatypes/hashtable.h | 1 - src/kernel/datatypes/linkedlist.h | 1 + src/kernel/filesystem/fat16.cpp | 35 +-- src/kernel/filesystem/fat16.h | 5 +- src/kernel/filesystem/fstree.cpp | 66 ++++- src/kernel/filesystem/fstree.h | 4 +- src/kernel/idt.cpp | 36 +-- src/kernel/idt.h | 1 - src/kernel/io.cpp | 18 ++ src/kernel/io.h | 13 + src/kernel/ioport.cpp | 19 -- src/kernel/ioport.h | 19 -- src/kernel/keyboard.h | 1 - src/kernel/kmain.cpp | 2 - src/kernel/memory.h | 1 - src/kernel/paging.h | 1 - src/kernel/process.h | 1 - src/kernel/screenstuff.cpp | 133 ---------- src/kernel/screenstuff.h | 18 -- src/kernel/strings.h | 2 - src/kernel/terminal.cpp | 420 ++++++++++++++++-------------- src/kernel/terminal.h | 29 ++- src/programs/world/world.c | 34 ++- 32 files changed, 447 insertions(+), 730 deletions(-) delete mode 100644 src/bootstage2/screenstuff.c delete mode 100644 src/bootstage2/screenstuff.h delete mode 100644 src/kernel/ioport.cpp delete mode 100644 src/kernel/ioport.h delete mode 100644 src/kernel/screenstuff.cpp delete mode 100644 src/kernel/screenstuff.h diff --git a/src/bootstage2/main.c b/src/bootstage2/main.c index d2d4231..8cb2792 100644 --- a/src/bootstage2/main.c +++ b/src/bootstage2/main.c @@ -1,5 +1,4 @@ #include "atapio.h" -#include "screenstuff.h" #include "paging.h" typedef struct { @@ -47,23 +46,7 @@ void mark_unavailble(uint32_t address, uint32_t size, uint8_t* buffer) { } } -char* stringify_type(uint32_t type) { - switch (type) { - case 1: - return "Usable"; - case 3: - return "ACPI Reclaimable"; - case 4: - return "ACPI NVS"; - case 5: - return "Bad memory"; - default: - return "Reserved"; - } -} - void main() { - init_term(); init_atapio(); // e820 memory map exists at 0x20000 @@ -73,13 +56,8 @@ void main() { memset(bitmap, 0x20000, 0); // Ensure the bitmap data is clear - for (int i=0; i<0x20000; i++) - if (bitmap[i]) - printf("Found data in bitmap at %x!\n", (bitmap+i)); - for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) { e820entry entry = e820_entries[i]; - printf("BIOS-e820: Starting %x%x, length %x%x is %s\n", entry.base_high, entry.base_low, entry.length_high, entry.length_low, stringify_type(entry.type)); if (entry.type != 1) continue; @@ -97,8 +75,6 @@ void main() { } uint32_t page_index = base / 4096; - printf("Page Index: %d\nLength (Pages): %d\n", page_index, length / 4096); - for (int j=0; length > 4096; length -= 4096, j++) { set_bit(page_index + j, bitmap); } @@ -185,8 +161,6 @@ void main() { load_file("KERNEL BIN", kernel_location); - printf("Stage2 success!\n"); - //while (1); asm volatile("mov %0, %%eax;" diff --git a/src/bootstage2/screenstuff.c b/src/bootstage2/screenstuff.c deleted file mode 100644 index 1b898e1..0000000 --- a/src/bootstage2/screenstuff.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "screenstuff.h" - -uint16_t* VMEM_ADDR = (uint16_t*)0xb8000; -const int TERM_WIDTH = 80; -const int TERM_HEIGHT = 25; - -int cursor_x = 0; -int cursor_y = 0; - -uint16_t get_curpos() { - uint16_t cursor_position = 0; - uint8_t* cursor_position_split = (uint8_t*)&cursor_position; - outb(0x3D4, 0x0F); - cursor_position_split[0] = inb(0x3D5); - outb(0x3D4, 0x0E); - cursor_position_split[1] = inb(0x3D5); - return cursor_position; -} - -void init_term() { - uint16_t cursor_position = get_curpos(); - - cursor_y = cursor_position / TERM_WIDTH; - cursor_x = cursor_position % TERM_WIDTH; -} - -void clear_screen() { - for (int i=0; i -#include "types.h" -#include "io.h" - -uint16_t get_curpos(); -void init_term(); -void clear_screen(); -void clear_line(int line); -void set_curpos_raw(int curpos); -void set_curpos(int x, int y); -int int_to_decimal(unsigned int number, char* string_buffer); -int int_to_hex(unsigned int number, char* string_buffer); -void printf(const char* string, ...); -void non_moving_put(char chr); - -#endif \ No newline at end of file diff --git a/src/bootstage2/strings.c b/src/bootstage2/strings.c index cc48b9f..8e04442 100644 --- a/src/bootstage2/strings.c +++ b/src/bootstage2/strings.c @@ -8,62 +8,4 @@ bool strcmp(char* a, char* b, int max) { index++; } return true; -} - -char* split_on_first(char delimeter, char* string) { - int index = 0; - char current; - - while (current = string[index++]) { - if (current == delimeter) { - string[index-1] = 0; - return string+index; - } - } - - return 0; -} - -int string_split(char delimeter, char* string, char** pointer_array) { - int index = 0; - int last_split_index = 0; - int split_count = 0; - - char current; - - while (current = string[index]) { - if (current == delimeter) { - string[index] = 0; - pointer_array[split_count++] = (string+last_split_index); - last_split_index = (index+1); - } - index++; - } - - // Add remaining part of the string to the pointer_array - pointer_array[split_count] = (string+last_split_index); - - return split_count; -} - -void decode_filename(char* nice_name, char* filenamebuffer) { - // Clear filenamebuffer - for (int i=0; i<11; i++) - filenamebuffer[i] = ' '; - filenamebuffer[11] = 0; - - int fbIndex = 0; - for (int i=0; i<12; i++) { - if (nice_name[i] == 0) - return; - if (nice_name[i] == '.') { - fbIndex = 8; - continue; - } - - if (nice_name[i] >= 0x61 && nice_name[i] <= 0x7f) - filenamebuffer[fbIndex++] = nice_name[i] - 32; - else - filenamebuffer[fbIndex++] = nice_name[i]; - } } \ No newline at end of file diff --git a/src/bootstage2/strings.h b/src/bootstage2/strings.h index baf7c5c..7ea7d6a 100644 --- a/src/bootstage2/strings.h +++ b/src/bootstage2/strings.h @@ -4,8 +4,5 @@ #include bool strcmp(char* a, char* b, int max); -char* split_on_first(char delimeter, char* string); -int string_split(char delimeter, char* string, char** pointer_array); -void decode_filename(char* nice_name, char* filenamebuffer); #endif \ No newline at end of file diff --git a/src/common/common.h b/src/common/common.h index af3e523..4726e13 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -3,6 +3,31 @@ #include "../kernel/types.h" +typedef enum { + File, + Directory, + CharacterDev, + BlockDev, + NoExist +} FSType; + +typedef struct { + uint16_t length; + uint8_t* path; +} PathEntry; + +typedef struct { + PathEntry path; + FSType type; + uint32_t sizeBytes; +} FSDirectoryEntry; + +typedef struct { + uint32_t count; + uint32_t stringsLength; + FSDirectoryEntry entries[]; +} FSDirectoryListing; + #define syscall_hdlr_0(a, b, c) \ a b(); #define syscall_hdlr_1(a, b, c, d, e) \ diff --git a/src/common/syscalls.h b/src/common/syscalls.h index f4bc08e..07e0103 100644 --- a/src/common/syscalls.h +++ b/src/common/syscalls.h @@ -1,9 +1,15 @@ -syscall_hdlr_1(void*, localalloc, "4", uint32_t, size); -syscall_hdlr_1(void, localdelete, "5", void*, ptr); +#include + +syscall_hdlr_1(uint32_t, getDentsSize, "0", char*, path); +syscall_hdlr_2(void, getDents, "1", char*, path, uint8_t*, buffer); +syscall_hdlr_1(bool, exists, "2", char*, path); +syscall_hdlr_1(FSType, type, "3", char*, path); +syscall_hdlr_1(void*, malloc, "4", uint32_t, size); +syscall_hdlr_1(void, free, "5", void*, ptr); syscall_hdlr_0(uint32_t, getPID, "8"); -syscall_hdlr_3(int, read, "10", uint32_t, count, void*, filehandler, uint8_t*, buffer); -syscall_hdlr_3(int, write, "11", uint32_t, count, void*, filehandler, uint8_t*, buffer); -syscall_hdlr_1(uint32_t, fork, "7", uint32_t, filehandler); +syscall_hdlr_3(int, read, "10", uint32_t, count, uint32_t, filehandler, uint8_t*, buffer); +syscall_hdlr_3(int, write, "11", uint32_t, count, uint32_t, filehandler, const uint8_t*, buffer); +syscall_hdlr_1(uint32_t, exec, "7", uint32_t, filehandler); syscall_hdlr_1(uint32_t, bindStdout, "13", uint32_t, PID); syscall_hdlr_1(uint32_t, bindStdin, "14", uint32_t, PID); syscall_hdlr_1(uint32_t, fopen, "15", char*, filename); diff --git a/src/kernel/allocate.h b/src/kernel/allocate.h index 3e7d36e..822ae82 100644 --- a/src/kernel/allocate.h +++ b/src/kernel/allocate.h @@ -3,7 +3,6 @@ #include "paging.h" #include "datatypes/tuple.h" -//void init_allocator(); extern uint8_t* bitmap; extern PDE* kernel_page_directory; diff --git a/src/kernel/ata.h b/src/kernel/ata.h index 65d710e..b7c3350 100644 --- a/src/kernel/ata.h +++ b/src/kernel/ata.h @@ -1,14 +1,10 @@ #ifndef ATA_PIO #define ATA_PIO -#include - #include "io.h" #include "types.h" #include "strings.h" -#include "allocate.h" #include "global.h" -#include "ioport.h" #include "stdio/readwriter.h" diff --git a/src/kernel/datatypes/hashtable.h b/src/kernel/datatypes/hashtable.h index 12add28..c546866 100644 --- a/src/kernel/datatypes/hashtable.h +++ b/src/kernel/datatypes/hashtable.h @@ -5,7 +5,6 @@ #include "linkedlist.h" #include "../memory.h" #include "maybe.h" -#include "../screenstuff.h" namespace xnoe { template diff --git a/src/kernel/datatypes/linkedlist.h b/src/kernel/datatypes/linkedlist.h index 45dcb44..9b3fbeb 100644 --- a/src/kernel/datatypes/linkedlist.h +++ b/src/kernel/datatypes/linkedlist.h @@ -1,6 +1,7 @@ #ifndef LINKEDLIST_H #define LINKEDLIST_H +#include "../types.h" #include "../memory.h" namespace xnoe { diff --git a/src/kernel/filesystem/fat16.cpp b/src/kernel/filesystem/fat16.cpp index 8cdf839..00759dd 100644 --- a/src/kernel/filesystem/fat16.cpp +++ b/src/kernel/filesystem/fat16.cpp @@ -3,9 +3,9 @@ uint32_t FAT16FileReadWriter::offsetBytesToCluster(uint32_t offset) { uint32_t cluster = this->firstCluster; uint32_t remaining = offset; - while (remaining > 512) { + while (remaining > this->clusterSize) { cluster = this->backingFS->FAT1[this->firstCluster]; - remaining -= 512; + remaining -= this->clusterSize; } return cluster; @@ -17,28 +17,29 @@ FAT16FileReadWriter::FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, this->sizeBytes = sizeBytes; this->currentPosition = 0; this->backingFS = backingFS; + this->clusterSize = 512 * (uint32_t)(*this->backingFS->sectorsPerCluster); } uint32_t FAT16FileReadWriter::read(uint32_t count, uint8_t* buffer) { - uint8_t* clusterBuffer = new uint8_t[512]; + uint8_t* clusterBuffer = new uint8_t[this->clusterSize]; uint32_t clusterToRead = offsetBytesToCluster(this->currentPosition); uint32_t sectorToRead = this->backingFS->clusterToSector(clusterToRead); - this->backingFS->backingDevice->seek(sectorToRead * 512); - this->backingFS->backingDevice->read(512, clusterBuffer); + this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize); + this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer); - uint32_t currentClusterIndex = this->currentPosition % 512; + uint32_t currentClusterIndex = this->currentPosition % this->clusterSize; uint32_t remaining = count; uint32_t index = 0; while (remaining) { - if (currentClusterIndex == 512) { + if (currentClusterIndex == this->clusterSize) { clusterToRead = this->backingFS->FAT1[clusterToRead]; if (clusterToRead == 0xffff) break; sectorToRead = this->backingFS->clusterToSector(clusterToRead); - this->backingFS->backingDevice->seek(sectorToRead * 512); - this->backingFS->backingDevice->read(512, clusterBuffer); + this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize); + this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer); currentClusterIndex = 0; } @@ -91,7 +92,7 @@ bool FAT16FS::pathEntryTo83(PathEntry pe, char* buffer) { } uint32_t FAT16FS::clusterToSector(uint32_t cluster) { - return cluster + (*sectorsPerFAT * *countFATs) + (*countRDEs / 16) + (*countReserved - 1) - 1; + return (cluster * (uint32_t)(*this->sectorsPerCluster)) + (*sectorsPerFAT * *countFATs) + (*countRDEs / 16) + (*countReserved - 1) - 1; } void FAT16FS::load_file(uint32_t location, uint8_t* destination) { @@ -100,9 +101,9 @@ void FAT16FS::load_file(uint32_t location, uint8_t* destination) { bool loaded = false; while (!loaded) { uint16_t fromSector = clusterToSector(location); - this->backingDevice->seek(fromSector * 512); - this->backingDevice->read(512, destination+offset); - offset += 512; + this->backingDevice->seek(fromSector * 512 * *this->sectorsPerCluster); + this->backingDevice->read(512 * *this->sectorsPerCluster, destination+offset); + offset += 512 * *this->sectorsPerCluster; location = FAT1[location++]; if (location == 0xffff) @@ -116,7 +117,7 @@ uint32_t FAT16FS::calc_size(uint32_t location) { bool loaded = false; while (!loaded) { uint16_t fromSector = clusterToSector(location); - offset += 512; + offset += 512 * *this->sectorsPerCluster; location = FAT1[location++]; if (location == 0xffff) @@ -349,7 +350,7 @@ uint32_t FAT16FS::getDentsSize(Path p) { uint32_t found = 0; uint32_t count = xnoe::get<1>(directory); - found += 4; + found += sizeof(FSDirectoryListing); for (int i=0; icount = getRealCount(directoryEntries, count); + buffer->stringsLength = 0; char* nameBuffer = ((char*)buffer); - nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + 4; + nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + sizeof(FSDirectoryListing); for (int i=0; istringsLength += 13; } } diff --git a/src/kernel/filesystem/fat16.h b/src/kernel/filesystem/fat16.h index 957202d..0c26787 100644 --- a/src/kernel/filesystem/fat16.h +++ b/src/kernel/filesystem/fat16.h @@ -2,7 +2,6 @@ #define FAT16_H #include "fstree.h" -#include "strings.h" #include "../memory.h" #include "../stdio/readwriter.h" #include "../datatypes/tuple.h" @@ -10,7 +9,6 @@ struct __attribute__((packed)) DirectoryEntry { char name[11]; - uint8_t readonly : 1; uint8_t hidden : 1; uint8_t system : 1; @@ -72,6 +70,8 @@ private: uint32_t offsetBytesToCluster(uint32_t offset); + uint32_t clusterSize; + FAT16FS* backingFS; public: FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, uint32_t sizeBytes, FAT16FS* backingFS); @@ -88,6 +88,7 @@ public: uint16_t* FAT1; uint8_t sectorOne[512]; + uint8_t* sectorsPerCluster = ((uint8_t*)(sectorOne + 0x0d)); uint16_t* countReserved = ((uint16_t*)(sectorOne + 0x0e)); uint8_t* countFATs = ((uint8_t*)(sectorOne + 0x10)); uint16_t* countRDEs = ((uint16_t*)(sectorOne + 0x11)); diff --git a/src/kernel/filesystem/fstree.cpp b/src/kernel/filesystem/fstree.cpp index 7473b0c..654a96d 100644 --- a/src/kernel/filesystem/fstree.cpp +++ b/src/kernel/filesystem/fstree.cpp @@ -4,11 +4,17 @@ bool operator==(const PathEntry& lhs, const PathEntry& rhs) { if (lhs.length == rhs.length) if (lhs.length == 0) return true; + else if (lhs.length < rhs.length) + return strcmp(lhs.path, rhs.path, lhs.length); else return strcmp(lhs.path, rhs.path, lhs.length); return false; } +bool operator!=(const PathEntry& lhs, const PathEntry& rhs) { + return !(lhs == rhs); +} + // FS Tree Skeleton bool FSTree::exists(Path p){} FSType FSTree::type(Path p){} @@ -116,6 +122,21 @@ Path* RootFSTree::getRemainingPath(Path p) { return 0; } +FSTreeNode* RootFSTree::getExhaustive(Path p) { + PathElement* currentPath = p.start; + FSTreeNode* currentNode = this->node; + if (currentPath->elem != currentNode->self) + return 0; + while (currentPath && currentNode) { + currentNode = getNodeFromPathEntry(currentPath->elem, currentNode); + currentPath = currentPath->next; + } + if (currentPath) + return 0; + else + return currentNode; +} + template T RootFSTree::attempt(T(FSTree::*fn)(Path), Path p, T fallback) { FSTree* mp = getLongestMatchingUnder(p); @@ -156,10 +177,53 @@ ReadWriter* RootFSTree::open(Path p){ return attempt(&FSTree::open, p, 0); } uint32_t RootFSTree::getDentsSize(Path p){ - return attempt(&FSTree::getDentsSize, p, 0); + uint32_t size = attempt(&FSTree::getDentsSize, p, 0); + FSTreeNode* n = getExhaustive(p); + if (n) { + xnoe::linkedlistelem* current = n->children.start; + while (current) { + size += sizeof(FSDirectoryEntry); + size += current->elem->self.length; + current = current->next; + } + } + return size; } void RootFSTree::getDents(Path p, FSDirectoryListing* buffer){ attempt(&FSTree::getDents, p, buffer); + uint32_t oldCount = buffer->count; + uint32_t stringsOffset = buffer->count * sizeof(FSDirectoryEntry) + sizeof(FSDirectoryListing); + uint32_t addCount = 0; + char* strings = ((uint32_t)buffer) + stringsOffset; + FSTreeNode* n = getExhaustive(p); + if (n) { + xnoe::linkedlistelem* current = n->children.start; + while (current) { + addCount++; + current = current->next; + } + if (addCount) { + current = n->children.start; + for (int i=buffer->stringsLength; i>=0; i--) + strings[i+addCount*sizeof(FSDirectoryEntry)] = strings[i]; + for (int i=0; i < buffer->count; i++) + buffer->entries[i].path.path += addCount*sizeof(FSDirectoryEntry); + while (current) { + strings += addCount*sizeof(FSDirectoryEntry) + buffer->stringsLength; + memcpy(current->elem->self.path, strings, current->elem->self.length); + buffer->entries[buffer->count++] = FSDirectoryEntry { + PathEntry{ + current->elem->self.length, + strings + }, + Directory, + 0 + }; + strings += current->elem->self.length; + current = current->next; + } + } + } } bool RootFSTree::isMountpoint(Path p) { diff --git a/src/kernel/filesystem/fstree.h b/src/kernel/filesystem/fstree.h index ed5b614..e22f08e 100644 --- a/src/kernel/filesystem/fstree.h +++ b/src/kernel/filesystem/fstree.h @@ -2,8 +2,8 @@ #define FSTREE_H #include "../datatypes/linkedlist.h" -#include "strings.h" #include "../stdio/readwriter.h" +#include "../strings.h" struct PathEntry { uint16_t length; @@ -31,6 +31,7 @@ struct FSDirectoryEntry { struct FSDirectoryListing { uint32_t count; + uint32_t stringsLength; FSDirectoryEntry entries[]; }; @@ -56,6 +57,7 @@ class RootFSTree: public FSTree { private: FSTree* getLongestMatchingUnder(Path p); Path* getRemainingPath(Path p); + FSTreeNode* getExhaustive(Path p); FSTreeNode* makeNodeIfNotExist(Path p); diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 4f0cc94..0bd7a1e 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -171,29 +171,29 @@ void awaken(frame_struct* frame, Process* p) { void syscall(frame_struct* frame) { // Syscall ABI: - // 0: X - // 1: X - // 2: X - // 3: X - // 4: localalloc: LocalAlloc: Allocate under current process (in esi: size; out eax void* ptr) - // 5: localdelete: LocalDelete: Deallocate under current process (in esi: pointer) + // 0: getDentsSize :: char* path -> uint32_t size + // 1: getDents :: char* path -> uint8_t* buffer -> void + // 2: exists :: char* path -> bool + // 3: type :: char* path -> FSType + // 4: localalloc :: uint32_t size -> void* ptr + // 5: localdelete :: void* ptr -> void // 6: X - // 7: fork :: void* filehandler esi -> int PID // Spawns a process and returns its PID. + // 7: exec :: void* filehandler -> int PID // Spawns a process and returns its PID. // 8: getPID: returns the current process's PID (out eax: uint32_t) - // 9: getFileHandler :: char* path esi -> void* eax // Returns a file handlers for a specific file - // 10: read :: uint32_t count ebx -> void* filehandler esi -> uint8_t* outputbuffer edi -> int read // Reads from a file handler in to a buffer, returns successful read - // 11: write :: uint32_t count ebx -> void* filehandler esi -> uint8_t* inputbuffer edi -> int written // Reads from a buffer in to a file, returns successful written + // 9: getFileHandler :: char* path -> void* // Returns a file handlers for a specific file + // 10: read :: uint32_t count -> void* filehandler -> uint8_t* outputbuffer -> int read // Reads from a file handler in to a buffer, returns successful read + // 11: write :: uint32_t count -> void* filehandler -> uint8_t* inputbuffer -> int written // Reads from a buffer in to a file, returns successful written // 12: bindToKeyboard :: void -> void // Binds the current process's stdout to the keyboard. - // 13: bindStdout :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process. - // 14: bindStdin :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process. + // 13: bindStdout :: int PID -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process. + // 14: bindStdin :: int PID -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process. - // 15: fopen :: char* path esi -> int filehandler // Returns a filehandler to the file. - // 16: fclose :: int filehandler esi -> void // Closes a file handler. + // 15: fopen :: char* path -> int filehandler // Returns a filehandler to the file. + // 16: fclose :: int filehandler -> void // Closes a file handler. - // 17: kill :: int PID esi -> void // Destroys a process. + // 17: kill :: int PID -> void // Destroys a process. - // 18: sleep :: int time ms esi -> void // Sleeps the current process for esi milliseconds. + // 18: sleep :: int time ms -> void // Sleeps the current process for time milliseconds. // File handlers: // 0: Stdout @@ -207,12 +207,16 @@ void syscall(frame_struct* frame) { switch (frame->eax) { case 0: + rval = Global::kernel->rootfs->getDentsSize(createPathFromString(frame->ebx)); break; case 1: + Global::kernel->rootfs->getDents(createPathFromString(frame->ebx), frame->ecx); break; case 2: + rval = Global::kernel->rootfs->exists(createPathFromString(frame->ebx)); break; case 3: + rval = Global::kernel->rootfs->type(createPathFromString(frame->ebx)); break; case 4: rval = currentProc->allocate(frame->ebx); diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 2f7a852..ccb0918 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -2,7 +2,6 @@ #define IDT_H #include "types.h" -#include "screenstuff.h" #include "global.h" #include "kernel.h" #include "gdt.h" diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index 6d600ea..e85f11c 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -18,4 +18,22 @@ extern "C" { asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber)); return result; } +} + +Port::Port(uint16_t a) { + this->addr = a; +} + +uint8_t Port::readb() { + return inb(this->addr); +} +uint16_t Port::readw() { + return inw(this->addr); +} + +void Port::writeb(uint8_t d) { + outb(this->addr, d); +} +void Port::writew(uint16_t d) { + outw(this->addr, d); } \ No newline at end of file diff --git a/src/kernel/io.h b/src/kernel/io.h index a6a2919..4649d2c 100644 --- a/src/kernel/io.h +++ b/src/kernel/io.h @@ -11,4 +11,17 @@ extern "C" { uint16_t inw(uint16_t portnumber); } +class Port { +private: + uint16_t addr; +public: + Port(uint16_t a); + + uint8_t readb(); + uint16_t readw(); + + void writeb(uint8_t d); + void writew(uint16_t d); +}; + #endif \ No newline at end of file diff --git a/src/kernel/ioport.cpp b/src/kernel/ioport.cpp deleted file mode 100644 index 20553c1..0000000 --- a/src/kernel/ioport.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "ioport.h" - -Port::Port(uint16_t a) { - this->addr = a; -} - -uint8_t Port::readb() { - return inb(this->addr); -} -uint16_t Port::readw() { - return inw(this->addr); -} - -void Port::writeb(uint8_t d) { - outb(this->addr, d); -} -void Port::writew(uint16_t d) { - outw(this->addr, d); -} \ No newline at end of file diff --git a/src/kernel/ioport.h b/src/kernel/ioport.h deleted file mode 100644 index fcee08d..0000000 --- a/src/kernel/ioport.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef IOPORT_H -#define IOPORT_H - -#include "io.h" - -class Port { -private: - uint16_t addr; -public: - Port(uint16_t a); - - uint8_t readb(); - uint16_t readw(); - - void writeb(uint8_t d); - void writew(uint16_t d); -}; - -#endif \ No newline at end of file diff --git a/src/kernel/keyboard.h b/src/kernel/keyboard.h index 4318016..a6ce60d 100644 --- a/src/kernel/keyboard.h +++ b/src/kernel/keyboard.h @@ -3,7 +3,6 @@ #include #include "io.h" -#include "screenstuff.h" #include "idt.h" void init_keyboard(); diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 78544ba..798bdea 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -1,5 +1,4 @@ #include "types.h" -#include "screenstuff.h" #include "io.h" #include "idt.h" #include "keyboard.h" @@ -20,7 +19,6 @@ int main() { init_gdt(); - init_term(); PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); diff --git a/src/kernel/memory.h b/src/kernel/memory.h index c008c4a..2947d20 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -3,7 +3,6 @@ #include "paging.h" #include "allocate.h" -#include "screenstuff.h" #include "global.h" void memset(uint8_t* address, uint32_t count, uint8_t value); diff --git a/src/kernel/paging.h b/src/kernel/paging.h index b3bed31..1890a01 100644 --- a/src/kernel/paging.h +++ b/src/kernel/paging.h @@ -1,7 +1,6 @@ #ifndef PAGING_H #define PAGING_H -#include #include "types.h" struct __attribute__((packed)) split_addr { diff --git a/src/kernel/process.h b/src/kernel/process.h index f780c19..118f153 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -6,7 +6,6 @@ #include "datatypes/linkedlist.h" #include "datatypes/hashtable.h" #include "datatypes/maybe.h" -#include "screenstuff.h" #include "global.h" #include "ata.h" diff --git a/src/kernel/screenstuff.cpp b/src/kernel/screenstuff.cpp deleted file mode 100644 index 0a75ed6..0000000 --- a/src/kernel/screenstuff.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "screenstuff.h" - -uint16_t* VMEM_ADDR = (uint16_t*)0xc0501000; -const int TERM_WIDTH = 80; -const int TERM_HEIGHT = 25; - -int cursor_x = 0; -int cursor_y = 0; - -uint16_t get_curpos() { - uint16_t cursor_position = 0; - uint8_t* cursor_position_split = (uint8_t*)&cursor_position; - outb(0x3D4, 0x0F); - cursor_position_split[0] = inb(0x3D5); - outb(0x3D4, 0x0E); - cursor_position_split[1] = inb(0x3D5); - return cursor_position; -} - -void init_term() { - uint16_t cursor_position = get_curpos(); - - cursor_y = cursor_position / TERM_WIDTH; - cursor_x = cursor_position % TERM_WIDTH; -} - -void clear_screen() { - for (int i=0; i -#include "types.h" -#include "io.h" -#include "strings.h" - -uint16_t get_curpos(); -void init_term(); -void clear_screen(); -void clear_line(int line); -void set_curpos_raw(int curpos); -void set_curpos(int x, int y); -void printf(const char* string, ...); -void non_moving_put(char chr); - -#endif \ No newline at end of file diff --git a/src/kernel/strings.h b/src/kernel/strings.h index 8b9b051..300138c 100644 --- a/src/kernel/strings.h +++ b/src/kernel/strings.h @@ -1,8 +1,6 @@ #ifndef STRINGS_H #define STRINGS_H -#include - bool strcmp(char* a, char* b, int max); char* split_on_first(char delimeter, char* string); int string_split(char delimeter, char* string, char** pointer_array); diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index a76ce47..f010760 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -1,35 +1,224 @@ #include "terminal.h" -void Terminal::scroll_up() { - // Scroll the entire buffer up. - for (int y = 0; y < (height * pages); y++) { - uint16_t* cline = buffer + y * width; - uint16_t* nline = buffer + (y+1) * width; - for (int x = 0; x < width; x++) { - cline[x] = nline[x]; +int strToInt(char* str, uint32_t max) { + int r=0; + int i=0; + while (*str >= 0x30 && *str <= 0x39 && i < max) { + r *= 10; + r += *(str++) - 0x30; + i++; + } + return r; +} + +int clamp(int a, int b, int c) { + if (a < b) + return b; + if (a > c) + return c; + return a; +} + +void Terminal::scroll_up(uint32_t count) { + for (int i=0; icur_y--; } - // Clear the last line - uint16_t* last_line = buffer + (height * pages - 1) * width; - for (int x = 0; x < width; x++) { - last_line[x] = 0x0720; - } - this->cur_y--; this->update(); } -void Terminal::putchar(uint32_t ptr, uint8_t c, uint8_t edata) { - // All modifications to the screen are done to the last page. - last_page_pointer[ptr] = c | (edata<<8); - if (active) - putchar_internal(ptr, c, edata); +void Terminal::scroll_down(uint32_t count) { + for (int i=0; i= 0; y--) { + uint16_t* nline = buffer + y * width; + uint16_t* cline = buffer + (y+1) * width; + for (int x = 0; x < width; x++) { + cline[x] = nline[x]; + } + } + // Clear the last line + uint16_t* last_line = buffer + (height * (pages - 1)) * width; + for (int x = 0; x < width; x++) { + last_line[x] = 0x20 | (edata << 8); + } + this->cur_y--; + } + + this->update(); +} + +void Terminal::putchar(uint8_t c) { + again: + switch (this->state) { + case None: + switch (c) { + case 0x1b: + this->state = EscapeCode; + break; + case '\n': + this->cur_x = 0; + this->cur_y++; + break; + case '\b': + if (this->cur_x == 0) { + if (this->cur_y > 0) { + this->cur_x = this->width-1; + this->cur_y--; + } + } else { + this->cur_x--; + } + last_page_pointer[this->cur_y*this->width+this->cur_x] = ' ' | (edata<<8); + if (active) + putchar_internal(this->cur_y*this->width+this->cur_x, ' '); + break; + default: + if (this->cur_x == this->width) { + this->cur_x = 0; + this->cur_y++; + } + // All modifications to the screen are done to the last page. + last_page_pointer[this->cur_y*this->width+this->cur_x] = c | (edata<<8); + + if (active) + putchar_internal(this->cur_y*this->width+this->cur_x, c); + this->cur_x++; + break; + } + break; + case EscapeCode: + switch (c) { + case '[': + this->state = CSI; + break; + default: + break; + } + break; + case CSI: + this->state = ParameterBytes; + this->parameterIndex = 0; + this->intermediaryIndex = 0; + goto again; + break; + case ParameterBytes: + if (parameterIndex < 128 && c >= 0x30 && c <= 0x3F) { + parameterBytes[parameterIndex++] = c; + } else { + parameterIndex; + this->state = IntermediaryBytes; + goto again; + } + break; + case IntermediaryBytes: + if (intermediaryIndex < 128 && c >= 0x20 && c <= 0x2F) { + intermediaryBytes[intermediaryIndex++] = c; + } else { + intermediaryIndex; + this->state = FinalByte; + goto again; + } + break; + case FinalByte: + switch (c) { + case 'A': + this->cur_y -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_y); + break; + case 'B': + this->cur_y += clamp(strToInt(parameterBytes, parameterIndex), 0, this->height - this->cur_y); + break; + case 'C': + this->cur_x += clamp(strToInt(parameterBytes, parameterIndex), 0, this->width - this->cur_x); + break; + case 'D': + this->cur_x -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_x); + break; + case 'E': + this->cur_y += clamp(strToInt(parameterBytes, parameterIndex), 0, this->height - this->cur_y); + this->cur_x = 0; + break; + case 'F': + this->cur_y -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_y); + this->cur_x = 0; + break; + case 'G': + this->cur_x = clamp(strToInt(parameterBytes, parameterIndex), 0, this->width); + break; + case 'f': + case 'H': { + uint32_t semicolonIndex = 0; + while (parameterBytes[semicolonIndex++] != ';' && semicolonIndex <= parameterIndex); + this->cur_y = clamp(strToInt(parameterBytes, parameterIndex) - 1, 0, this->height) ; + this->cur_x = clamp(strToInt(parameterBytes+semicolonIndex, parameterIndex-semicolonIndex) - 1, 0, this->width); + break; + } + case 'm': + this->state = SGR; + goto again; + break; + default: + break; + } + this->state = None; + break; + case SGR: { + uint32_t index = 0; + while (index <= parameterIndex) { + uint32_t n = strToInt(parameterBytes+index, parameterIndex-index); + switch (n) { + case 0: + this->edata = 0xf; + break; + case 1: + if ((this->edata&0xf) <= 0x7) + this->edata += 8; + break; + case 2: + if ((this->edata&0xf) >= 0x7) + this->edata -= 8; + break; + case 30 ... 37: + this->edata &= 0xf0; + this->edata |= n-30; + break; + case 40 ... 47: + this->edata &= 0x0f; + this->edata |= (n-40)<<4; + break; + default: + break; + } + while (parameterBytes[index++] != ';' && index <= parameterIndex); + } + this->state = None; + } + default: + break; + } + if (this->cur_y == this->height) { + this->cur_y--; + scroll_up(); + } } void Terminal::update(){} void Terminal::update_cur(){} -void Terminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {} +void Terminal::putchar_internal(uint32_t ptr, uint8_t c) {} Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) : ReadWriter(0) { @@ -46,23 +235,6 @@ Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) this->active = false; } -int strToInt(char* str) { - int r=0; - while (*str >= 0x30 && *str <= 0x39) { - r *= 10; - r += *(str++) - 0x30; - } - return r; -} - -int clamp(int a, int b, int c) { - if (a < b) - return b; - if (a > c) - return c; - return a; -} - void Terminal::printf(const char* string, ...) { va_list ptr; va_start(ptr, string); @@ -71,73 +243,6 @@ void Terminal::printf(const char* string, ...) { char current; while (current=string[index++]) { - if (current == '\n') { - this->cur_x = 0; - this->cur_y++; - } - - if (current == 0x1b && string[index] == '[') { - index++; - char* parameterStart = (string+index); - while (string[index] >= 0x30 && string[index] <= 0x3F) - index++; - char* parameterEnd = (string+index); - - char* intermediateStart = (string+index); - while (string[index] >= 0x20 && string[index] <= 0x2F) - index++; - - char final = *(string+(index++)); - - switch (final) { - case 'A': - this->cur_y -= clamp(strToInt(parameterStart), 0, this->cur_y); - break; - case 'B': - this->cur_y += clamp(strToInt(parameterStart), 0, this->height - this->cur_y); - break; - case 'C': - this->cur_x += clamp(strToInt(parameterStart), 0, this->width - this->cur_x); - break; - case 'D': - this->cur_x -= clamp(strToInt(parameterStart), 0, this->cur_x); - break; - case 'H': { - char* s=parameterStart; - while (*s != ';' && s < parameterEnd) - s++; - s++; - this->cur_y = clamp(strToInt(parameterStart), 1, this->height) - 1; - this->cur_x = clamp(strToInt(s), 1, this->width) - 1; - break; - } - } - - continue; - } - - if (current == '\b') { - if (this->cur_x > 0) { - this->cur_x--; - } else if (this->cur_y > 0) { - this->cur_y--; - this->cur_x = this->width-1; - } - - int mem_pos = this->cur_y * this->width + this->cur_x; - - this->putchar(mem_pos, ' '); - continue; - } - - if (this->cur_x == this->width) { - this->cur_x = 0; - this->cur_y++; - } - - if (this->cur_y == this->height) - this->scroll_up(); - if (current == '%') { int type = string[index++]; int offset; @@ -159,22 +264,17 @@ void Terminal::printf(const char* string, ...) { break; } case 'c': { - int mem_pos = this->cur_y * this->width + this->cur_x++; int promoted = va_arg(ptr, int); char charred = promoted; - this->putchar(mem_pos, charred); + this->putchar(charred); break; } } continue; } - - if (current != '\n') { - int mem_pos = this->cur_y * this->width + this->cur_x++; - this->putchar(mem_pos, current); - } + this->putchar(current); } this->set_curpos(this->cur_x, this->cur_y); @@ -183,84 +283,8 @@ void Terminal::printf(const char* string, ...) { } uint32_t Terminal::write(uint32_t count, uint8_t* string) { - int index = 0; - char current; - - while (index < count) { - current=string[index++]; - if (current == '\n') { - this->cur_x = 0; - this->cur_y++; - } - - if (current == 0x1b && string[index] == '[') { - index++; - char* parameterStart = (string+index); - while (string[index] >= 0x30 && string[index] <= 0x3F) - index++; - char* parameterEnd = (string+index); - - char* intermediateStart = (string+index); - while (string[index] >= 0x20 && string[index] <= 0x2F) - index++; - - char final = *(string+(index++)); - - switch (final) { - case 'A': - this->cur_y -= clamp(strToInt(parameterStart), 0, this->cur_y); - break; - case 'B': - this->cur_y += clamp(strToInt(parameterStart), 0, this->height - this->cur_y); - break; - case 'C': - this->cur_x += clamp(strToInt(parameterStart), 0, this->width - this->cur_x); - break; - case 'D': - this->cur_x -= clamp(strToInt(parameterStart), 0, this->cur_x); - break; - case 'H': { - char* s=parameterStart; - while (*s != ';' && s < parameterEnd) - s++; - s++; - this->cur_y = clamp(strToInt(parameterStart), 1, this->height) - 1; - this->cur_x = clamp(strToInt(s), 1, this->width) - 1; - break; - } - } - - continue; - } - - if (current == '\b') { - if (this->cur_x > 0) { - this->cur_x--; - } else if (this->cur_y > 0) { - this->cur_y--; - this->cur_x = this->width-1; - } - - int mem_pos = this->cur_y * this->width + this->cur_x; - - this->putchar(mem_pos, ' '); - continue; - } - - if (this->cur_x == this->width) { - this->cur_x = 0; - this->cur_y++; - } - - if (this->cur_y == this->height) - this->scroll_up(); - - if (current != '\n') { - int mem_pos = this->cur_y * this->width + this->cur_x++; - - this->putchar(mem_pos, current); - } - } + for (int index=0; index < count; index++) + this->putchar(string[index]); this->set_curpos(this->cur_x, this->cur_y); } @@ -322,7 +346,7 @@ void TextModeTerminal::update_cur() { outb(0x3D5, cursor_position_split[1]); } -void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { +void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) { text_mode_pointer[ptr] = c | (edata << 8); } @@ -333,7 +357,7 @@ TextModeTerminal::TextModeTerminal(uint16_t* text_mode_pointer): Terminal(80, 25 void VGAModeTerminal::update() { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x]), 0); + putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x])); } } } @@ -342,7 +366,7 @@ void VGAModeTerminal::update_cur() { // Todo: Implement cursor for VGAModeTerminal } -void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { +void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) { uint32_t col = ptr % width; uint32_t row = ptr / width; @@ -353,11 +377,8 @@ void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { return; uint8_t* char_data = font[c]; - for (int y=0; y<8; y++) { - //for (int x=0; x<8; x++) { - put_pixels_byte(sx, sy+y, 15, char_data[y]); - //} - } + for (int y=0; y<8; y++) + put_pixels_byte(sx, sy+y, edata, char_data[y]); } void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) { @@ -371,10 +392,11 @@ void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uin } for (int i=0; i<4; i++) { + this->planes[i][pixelindex] = 0; if (color & (1<planes[i][pixelindex] = trbyte; - else - this->planes[i][pixelindex] = 0; + this->planes[i][pixelindex] |= trbyte; + if ((color>>4) & (1<planes[i][pixelindex] |= ~trbyte; } } diff --git a/src/kernel/terminal.h b/src/kernel/terminal.h index b90f699..2a17fdd 100644 --- a/src/kernel/terminal.h +++ b/src/kernel/terminal.h @@ -17,15 +17,32 @@ namespace Timer { void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false); } +enum TerminalState { + None, + EscapeCode, + CSI, + ParameterBytes, + IntermediaryBytes, + FinalByte, + SGR +}; + class Terminal: public ReadWriter { private: virtual void update(); virtual void update_cur(); - virtual void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07); + virtual void putchar_internal(uint32_t ptr, uint8_t c); - void scroll_up(); + void scroll_up(uint32_t count=1); + void scroll_down(uint32_t count=1); - void putchar(uint32_t ptr, uint8_t c, uint8_t edata=0x07); + void putchar(uint8_t c); + + TerminalState state = None; + uint8_t parameterBytes[128]; + uint8_t intermediaryBytes[128]; + uint32_t parameterIndex = 0; + uint32_t intermediaryIndex = 0; protected: uint16_t* buffer; @@ -40,6 +57,8 @@ protected: uint16_t* last_page_pointer; bool active; + + uint8_t edata=0x07; public: Terminal(uint32_t width, uint32_t height, uint32_t pages); @@ -62,7 +81,7 @@ class TextModeTerminal : public Terminal { private: void update() override; void update_cur() override; - void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + void putchar_internal(uint32_t ptr, uint8_t c) override; uint16_t* text_mode_pointer; public: @@ -74,7 +93,7 @@ class VGAModeTerminal : public Terminal { private: void update() override; void update_cur() override; - void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + void putchar_internal(uint32_t ptr, uint8_t c) override; void put_pixel(uint32_t x, uint32_t y, uint8_t color); void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte); diff --git a/src/programs/world/world.c b/src/programs/world/world.c index e5a92ed..914ce74 100644 --- a/src/programs/world/world.c +++ b/src/programs/world/world.c @@ -169,6 +169,7 @@ int main() { for (int i=0; i < 1000; i++) write(1, 0, &space); print("\x1b[1;1H"); + print("\x1b[45;33;1m"); char* mid = "+ ++ +"; char* bottom = "+ +"; @@ -181,20 +182,21 @@ int main() { write(90, 0, bottom); for (int i=0; i<90;i++) write(1, 0, &plus); + print("\x1b[42;36;1m"); uint32_t program = fopen("/hello.bin"); - uint32_t p1 = fork(program); + uint32_t p1 = exec(program); uint32_t p1out = bindStdout(p1); uint32_t p1in = bindStdin(p1); fclose(program); program = fopen("/timer.bin"); - uint32_t p2 = fork(program); + uint32_t p2 = exec(program); uint32_t p2out = bindStdout(p2); uint32_t p2in = bindStdin(p2); fclose(program); procbuffer b1 = { - .buffer = localalloc(56 * 43), + .buffer = malloc(56 * 43), .x = 0, .y = 0, .process = p1, @@ -203,7 +205,7 @@ int main() { }; procbuffer b2 = { - .buffer = localalloc(56 * 43), + .buffer = malloc(56 * 43), .x = 0, .y = 0, .process = p2, @@ -247,6 +249,11 @@ int main() { writeStrToBuf(" Kills the current process\n", selectedBuf); writeStrToBuf(":load \n", selectedBuf); writeStrToBuf(" Loads and executes the program \n", selectedBuf); + writeStrToBuf(":ls \n", selectedBuf); + writeStrToBuf(" Lists the files in directory \n", selectedBuf); + writeStrToBuf(":clear\n", selectedBuf); + writeStrToBuf(" Clears the buffer\n", selectedBuf); + writeStrToBuf("--------\n", selectedBuf); } else if (strcmpcnt(4, buf, "kill")) { if (selectedBuf->process) { @@ -255,21 +262,28 @@ int main() { selectedBuf->process = 0; selectedBuf->stdin = 0; selectedBuf->stdout = 0; - if (selectedBuf == &b1) { - selectedBuf = &b2; - } else { - selectedBuf = &b1; - } } } else if (strcmpcnt(4, buf, "load")) { if (!selectedBuf->process) { char* potFn = buf+5; uint32_t fh = fopen(potFn); - selectedBuf->process = fork(fh); + selectedBuf->process = exec(fh); selectedBuf->stdout = bindStdout(selectedBuf->process); selectedBuf->stdin = bindStdin(selectedBuf->process); fclose(fh); } + } else if (strcmpcnt(2, buf, "ls")) { + uint32_t size = getDentsSize((char*)(buf+3)); + FSDirectoryListing* listing = (FSDirectoryListing*)malloc(size); + getDents((char*)(buf+3), listing); + writeStrToBuf("\n", selectedBuf); + for (int i=0; icount; i++) { + writeCountToBuf(listing->entries[i].path.length, listing->entries[i].path.path, selectedBuf); + writeStrToBuf("\n", selectedBuf); + } + free(listing); + } else if (strcmpcnt(5, buf, "clear")) { + clearBuf(selectedBuf); } } else { if (selectedBuf->process)