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.
This commit is contained in:
parent
8f4382793c
commit
0fc40ad5e4
@ -1,5 +1,4 @@
|
|||||||
#include "atapio.h"
|
#include "atapio.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
|
||||||
typedef struct {
|
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() {
|
void main() {
|
||||||
init_term();
|
|
||||||
init_atapio();
|
init_atapio();
|
||||||
|
|
||||||
// e820 memory map exists at 0x20000
|
// e820 memory map exists at 0x20000
|
||||||
@ -73,13 +56,8 @@ void main() {
|
|||||||
memset(bitmap, 0x20000, 0);
|
memset(bitmap, 0x20000, 0);
|
||||||
// Ensure the bitmap data is clear
|
// 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++) {
|
for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) {
|
||||||
e820entry entry = e820_entries[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)
|
if (entry.type != 1)
|
||||||
continue;
|
continue;
|
||||||
@ -97,8 +75,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
uint32_t page_index = base / 4096;
|
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++) {
|
for (int j=0; length > 4096; length -= 4096, j++) {
|
||||||
set_bit(page_index + j, bitmap);
|
set_bit(page_index + j, bitmap);
|
||||||
}
|
}
|
||||||
@ -185,8 +161,6 @@ void main() {
|
|||||||
|
|
||||||
load_file("KERNEL BIN", kernel_location);
|
load_file("KERNEL BIN", kernel_location);
|
||||||
|
|
||||||
printf("Stage2 success!\n");
|
|
||||||
|
|
||||||
//while (1);
|
//while (1);
|
||||||
|
|
||||||
asm volatile("mov %0, %%eax;"
|
asm volatile("mov %0, %%eax;"
|
||||||
|
@ -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<TERM_WIDTH*TERM_HEIGHT; i++) {
|
|
||||||
VMEM_ADDR[i] = 0x0720;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_line(int line) {
|
|
||||||
for (int x=0; x<TERM_WIDTH; x++) {
|
|
||||||
VMEM_ADDR[TERM_WIDTH*line + x] = 0x0720;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_curpos_raw(int curpos) {
|
|
||||||
uint8_t* cursor_position_split = (uint8_t*)&curpos;
|
|
||||||
outb(0x3D4, 0x0F);
|
|
||||||
outb(0x3D5, cursor_position_split[0]);
|
|
||||||
outb(0x3D4, 0x0E);
|
|
||||||
outb(0x3D5, cursor_position_split[1]);
|
|
||||||
|
|
||||||
cursor_x = (*(uint16_t*)cursor_position_split) % TERM_WIDTH;
|
|
||||||
cursor_y = (*(uint16_t*)cursor_position_split) / TERM_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_curpos(int x, int y) {
|
|
||||||
set_curpos_raw(y * TERM_WIDTH + x);
|
|
||||||
|
|
||||||
cursor_x = x;
|
|
||||||
cursor_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int int_to_decimal(unsigned int number, char* string_buffer) {
|
|
||||||
for (int i=0; i<11; i++)
|
|
||||||
string_buffer[i] = 0;
|
|
||||||
|
|
||||||
int index = 9;
|
|
||||||
unsigned int acc = number;
|
|
||||||
if (acc == 0)
|
|
||||||
string_buffer[index--] = '0';
|
|
||||||
while (acc != 0) {
|
|
||||||
string_buffer[index--] = 0x30+(acc%10);
|
|
||||||
acc /= 10;
|
|
||||||
}
|
|
||||||
return (index+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char dec_to_hex[16] = "0123456789abcdef";
|
|
||||||
int int_to_hex(unsigned int number, char* string_buffer) {
|
|
||||||
for (int i=0; i<8; i++)
|
|
||||||
string_buffer[i] = '0';
|
|
||||||
string_buffer[8] = 0;
|
|
||||||
|
|
||||||
int index = 7;
|
|
||||||
unsigned int acc = number;
|
|
||||||
if (acc == 0)
|
|
||||||
string_buffer[index--] = '0';
|
|
||||||
while (acc != 0) {
|
|
||||||
string_buffer[index--] = dec_to_hex[acc%0x10];
|
|
||||||
acc /= 0x10;
|
|
||||||
}
|
|
||||||
return (index+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printf(const char* string, ...) {
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr, string);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
int count = 0;
|
|
||||||
char current;
|
|
||||||
while (current=string[index++]) {
|
|
||||||
count++;
|
|
||||||
if (current == '\n') {
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_x == TERM_WIDTH) {
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_y == TERM_HEIGHT) {
|
|
||||||
for (int i=1; i<TERM_HEIGHT; i++) {
|
|
||||||
for (int x=0; x<TERM_WIDTH; x++) {
|
|
||||||
int from = i * TERM_WIDTH + x;
|
|
||||||
int to = (i-1) * TERM_WIDTH + x;
|
|
||||||
VMEM_ADDR[to] = VMEM_ADDR[from];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clear_line(24);
|
|
||||||
cursor_y--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == '%') {
|
|
||||||
int type = string[index++];
|
|
||||||
int offset;
|
|
||||||
switch (type) {
|
|
||||||
case 'd': {
|
|
||||||
char decimal_buffer[11];
|
|
||||||
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
|
|
||||||
printf(decimal_buffer + offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'x': {
|
|
||||||
char hex_buffer[8];
|
|
||||||
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
|
|
||||||
printf(hex_buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 's': {
|
|
||||||
printf(va_arg(ptr, const char*));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c': {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
|
||||||
int promoted = va_arg(ptr, int);
|
|
||||||
char charred = promoted;
|
|
||||||
VMEM_ADDR[mem_pos] = charred + (0x07<<8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current != '\n') {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
|
||||||
VMEM_ADDR[mem_pos] = current + (0x07<<8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_curpos(cursor_x, cursor_y);
|
|
||||||
|
|
||||||
va_end(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void non_moving_put(char chr) {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x;
|
|
||||||
VMEM_ADDR[mem_pos] = chr + (0x07<<8);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#ifndef SCREENSTUFF_H
|
|
||||||
#define SCREENSTUFF_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#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
|
|
@ -9,61 +9,3 @@ bool strcmp(char* a, char* b, int max) {
|
|||||||
}
|
}
|
||||||
return true;
|
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];
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,8 +4,5 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool strcmp(char* a, char* b, int max);
|
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
|
#endif
|
@ -3,6 +3,31 @@
|
|||||||
|
|
||||||
#include "../kernel/types.h"
|
#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) \
|
#define syscall_hdlr_0(a, b, c) \
|
||||||
a b();
|
a b();
|
||||||
#define syscall_hdlr_1(a, b, c, d, e) \
|
#define syscall_hdlr_1(a, b, c, d, e) \
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
syscall_hdlr_1(void*, localalloc, "4", uint32_t, size);
|
#include <stdbool.h>
|
||||||
syscall_hdlr_1(void, localdelete, "5", void*, ptr);
|
|
||||||
|
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_0(uint32_t, getPID, "8");
|
||||||
syscall_hdlr_3(int, read, "10", uint32_t, count, void*, filehandler, uint8_t*, buffer);
|
syscall_hdlr_3(int, read, "10", uint32_t, count, uint32_t, filehandler, uint8_t*, buffer);
|
||||||
syscall_hdlr_3(int, write, "11", uint32_t, count, void*, 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, fork, "7", uint32_t, filehandler);
|
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, bindStdout, "13", uint32_t, PID);
|
||||||
syscall_hdlr_1(uint32_t, bindStdin, "14", uint32_t, PID);
|
syscall_hdlr_1(uint32_t, bindStdin, "14", uint32_t, PID);
|
||||||
syscall_hdlr_1(uint32_t, fopen, "15", char*, filename);
|
syscall_hdlr_1(uint32_t, fopen, "15", char*, filename);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "datatypes/tuple.h"
|
#include "datatypes/tuple.h"
|
||||||
//void init_allocator();
|
|
||||||
|
|
||||||
extern uint8_t* bitmap;
|
extern uint8_t* bitmap;
|
||||||
extern PDE* kernel_page_directory;
|
extern PDE* kernel_page_directory;
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
#ifndef ATA_PIO
|
#ifndef ATA_PIO
|
||||||
#define ATA_PIO
|
#define ATA_PIO
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "allocate.h"
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "ioport.h"
|
|
||||||
|
|
||||||
#include "stdio/readwriter.h"
|
#include "stdio/readwriter.h"
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
#include "../memory.h"
|
#include "../memory.h"
|
||||||
#include "maybe.h"
|
#include "maybe.h"
|
||||||
#include "../screenstuff.h"
|
|
||||||
|
|
||||||
namespace xnoe {
|
namespace xnoe {
|
||||||
template <class key, class value>
|
template <class key, class value>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef LINKEDLIST_H
|
#ifndef LINKEDLIST_H
|
||||||
#define LINKEDLIST_H
|
#define LINKEDLIST_H
|
||||||
|
|
||||||
|
#include "../types.h"
|
||||||
#include "../memory.h"
|
#include "../memory.h"
|
||||||
|
|
||||||
namespace xnoe {
|
namespace xnoe {
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
uint32_t FAT16FileReadWriter::offsetBytesToCluster(uint32_t offset) {
|
uint32_t FAT16FileReadWriter::offsetBytesToCluster(uint32_t offset) {
|
||||||
uint32_t cluster = this->firstCluster;
|
uint32_t cluster = this->firstCluster;
|
||||||
uint32_t remaining = offset;
|
uint32_t remaining = offset;
|
||||||
while (remaining > 512) {
|
while (remaining > this->clusterSize) {
|
||||||
cluster = this->backingFS->FAT1[this->firstCluster];
|
cluster = this->backingFS->FAT1[this->firstCluster];
|
||||||
remaining -= 512;
|
remaining -= this->clusterSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cluster;
|
return cluster;
|
||||||
@ -17,28 +17,29 @@ FAT16FileReadWriter::FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster,
|
|||||||
this->sizeBytes = sizeBytes;
|
this->sizeBytes = sizeBytes;
|
||||||
this->currentPosition = 0;
|
this->currentPosition = 0;
|
||||||
this->backingFS = backingFS;
|
this->backingFS = backingFS;
|
||||||
|
this->clusterSize = 512 * (uint32_t)(*this->backingFS->sectorsPerCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT16FileReadWriter::read(uint32_t count, uint8_t* buffer) {
|
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 clusterToRead = offsetBytesToCluster(this->currentPosition);
|
||||||
uint32_t sectorToRead = this->backingFS->clusterToSector(clusterToRead);
|
uint32_t sectorToRead = this->backingFS->clusterToSector(clusterToRead);
|
||||||
this->backingFS->backingDevice->seek(sectorToRead * 512);
|
this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize);
|
||||||
this->backingFS->backingDevice->read(512, clusterBuffer);
|
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 remaining = count;
|
||||||
|
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
if (currentClusterIndex == 512) {
|
if (currentClusterIndex == this->clusterSize) {
|
||||||
clusterToRead = this->backingFS->FAT1[clusterToRead];
|
clusterToRead = this->backingFS->FAT1[clusterToRead];
|
||||||
if (clusterToRead == 0xffff)
|
if (clusterToRead == 0xffff)
|
||||||
break;
|
break;
|
||||||
sectorToRead = this->backingFS->clusterToSector(clusterToRead);
|
sectorToRead = this->backingFS->clusterToSector(clusterToRead);
|
||||||
this->backingFS->backingDevice->seek(sectorToRead * 512);
|
this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize);
|
||||||
this->backingFS->backingDevice->read(512, clusterBuffer);
|
this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer);
|
||||||
currentClusterIndex = 0;
|
currentClusterIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ bool FAT16FS::pathEntryTo83(PathEntry pe, char* buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT16FS::clusterToSector(uint32_t cluster) {
|
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) {
|
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;
|
bool loaded = false;
|
||||||
while (!loaded) {
|
while (!loaded) {
|
||||||
uint16_t fromSector = clusterToSector(location);
|
uint16_t fromSector = clusterToSector(location);
|
||||||
this->backingDevice->seek(fromSector * 512);
|
this->backingDevice->seek(fromSector * 512 * *this->sectorsPerCluster);
|
||||||
this->backingDevice->read(512, destination+offset);
|
this->backingDevice->read(512 * *this->sectorsPerCluster, destination+offset);
|
||||||
offset += 512;
|
offset += 512 * *this->sectorsPerCluster;
|
||||||
|
|
||||||
location = FAT1[location++];
|
location = FAT1[location++];
|
||||||
if (location == 0xffff)
|
if (location == 0xffff)
|
||||||
@ -116,7 +117,7 @@ uint32_t FAT16FS::calc_size(uint32_t location) {
|
|||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
while (!loaded) {
|
while (!loaded) {
|
||||||
uint16_t fromSector = clusterToSector(location);
|
uint16_t fromSector = clusterToSector(location);
|
||||||
offset += 512;
|
offset += 512 * *this->sectorsPerCluster;
|
||||||
|
|
||||||
location = FAT1[location++];
|
location = FAT1[location++];
|
||||||
if (location == 0xffff)
|
if (location == 0xffff)
|
||||||
@ -349,7 +350,7 @@ uint32_t FAT16FS::getDentsSize(Path p) {
|
|||||||
uint32_t found = 0;
|
uint32_t found = 0;
|
||||||
uint32_t count = xnoe::get<1>(directory);
|
uint32_t count = xnoe::get<1>(directory);
|
||||||
|
|
||||||
found += 4;
|
found += sizeof(FSDirectoryListing);
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
if (directoryEntries[i].name[0] != 0 && directoryEntries[i].name[0] != 0xE5 && !directoryEntries[i].volumeid) {
|
if (directoryEntries[i].name[0] != 0 && directoryEntries[i].name[0] != 0xE5 && !directoryEntries[i].volumeid) {
|
||||||
found += sizeof(FSDirectoryEntry);
|
found += sizeof(FSDirectoryEntry);
|
||||||
@ -375,9 +376,10 @@ void FAT16FS::getDents(Path p, FSDirectoryListing* buffer) {
|
|||||||
uint32_t written=0;
|
uint32_t written=0;
|
||||||
|
|
||||||
buffer->count = getRealCount(directoryEntries, count);
|
buffer->count = getRealCount(directoryEntries, count);
|
||||||
|
buffer->stringsLength = 0;
|
||||||
|
|
||||||
char* nameBuffer = ((char*)buffer);
|
char* nameBuffer = ((char*)buffer);
|
||||||
nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + 4;
|
nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + sizeof(FSDirectoryListing);
|
||||||
|
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
if (directoryEntries[i].name[0] != 0 && directoryEntries[i].name[0] != 0xE5 && !directoryEntries[i].volumeid) {
|
if (directoryEntries[i].name[0] != 0 && directoryEntries[i].name[0] != 0xE5 && !directoryEntries[i].volumeid) {
|
||||||
@ -387,6 +389,7 @@ void FAT16FS::getDents(Path p, FSDirectoryListing* buffer) {
|
|||||||
directoryEntries[i].size
|
directoryEntries[i].size
|
||||||
};
|
};
|
||||||
written++;
|
written++;
|
||||||
|
buffer->stringsLength += 13;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#define FAT16_H
|
#define FAT16_H
|
||||||
|
|
||||||
#include "fstree.h"
|
#include "fstree.h"
|
||||||
#include "strings.h"
|
|
||||||
#include "../memory.h"
|
#include "../memory.h"
|
||||||
#include "../stdio/readwriter.h"
|
#include "../stdio/readwriter.h"
|
||||||
#include "../datatypes/tuple.h"
|
#include "../datatypes/tuple.h"
|
||||||
@ -10,7 +9,6 @@
|
|||||||
struct __attribute__((packed)) DirectoryEntry {
|
struct __attribute__((packed)) DirectoryEntry {
|
||||||
char name[11];
|
char name[11];
|
||||||
|
|
||||||
|
|
||||||
uint8_t readonly : 1;
|
uint8_t readonly : 1;
|
||||||
uint8_t hidden : 1;
|
uint8_t hidden : 1;
|
||||||
uint8_t system : 1;
|
uint8_t system : 1;
|
||||||
@ -72,6 +70,8 @@ private:
|
|||||||
|
|
||||||
uint32_t offsetBytesToCluster(uint32_t offset);
|
uint32_t offsetBytesToCluster(uint32_t offset);
|
||||||
|
|
||||||
|
uint32_t clusterSize;
|
||||||
|
|
||||||
FAT16FS* backingFS;
|
FAT16FS* backingFS;
|
||||||
public:
|
public:
|
||||||
FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, uint32_t sizeBytes, FAT16FS* backingFS);
|
FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, uint32_t sizeBytes, FAT16FS* backingFS);
|
||||||
@ -88,6 +88,7 @@ public:
|
|||||||
uint16_t* FAT1;
|
uint16_t* FAT1;
|
||||||
uint8_t sectorOne[512];
|
uint8_t sectorOne[512];
|
||||||
|
|
||||||
|
uint8_t* sectorsPerCluster = ((uint8_t*)(sectorOne + 0x0d));
|
||||||
uint16_t* countReserved = ((uint16_t*)(sectorOne + 0x0e));
|
uint16_t* countReserved = ((uint16_t*)(sectorOne + 0x0e));
|
||||||
uint8_t* countFATs = ((uint8_t*)(sectorOne + 0x10));
|
uint8_t* countFATs = ((uint8_t*)(sectorOne + 0x10));
|
||||||
uint16_t* countRDEs = ((uint16_t*)(sectorOne + 0x11));
|
uint16_t* countRDEs = ((uint16_t*)(sectorOne + 0x11));
|
||||||
|
@ -4,11 +4,17 @@ bool operator==(const PathEntry& lhs, const PathEntry& rhs) {
|
|||||||
if (lhs.length == rhs.length)
|
if (lhs.length == rhs.length)
|
||||||
if (lhs.length == 0)
|
if (lhs.length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
else if (lhs.length < rhs.length)
|
||||||
|
return strcmp(lhs.path, rhs.path, lhs.length);
|
||||||
else
|
else
|
||||||
return strcmp(lhs.path, rhs.path, lhs.length);
|
return strcmp(lhs.path, rhs.path, lhs.length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const PathEntry& lhs, const PathEntry& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
// FS Tree Skeleton
|
// FS Tree Skeleton
|
||||||
bool FSTree::exists(Path p){}
|
bool FSTree::exists(Path p){}
|
||||||
FSType FSTree::type(Path p){}
|
FSType FSTree::type(Path p){}
|
||||||
@ -116,6 +122,21 @@ Path* RootFSTree::getRemainingPath(Path p) {
|
|||||||
return 0;
|
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<typename T>
|
template<typename T>
|
||||||
T RootFSTree::attempt(T(FSTree::*fn)(Path), Path p, T fallback) {
|
T RootFSTree::attempt(T(FSTree::*fn)(Path), Path p, T fallback) {
|
||||||
FSTree* mp = getLongestMatchingUnder(p);
|
FSTree* mp = getLongestMatchingUnder(p);
|
||||||
@ -156,10 +177,53 @@ ReadWriter* RootFSTree::open(Path p){
|
|||||||
return attempt<ReadWriter*>(&FSTree::open, p, 0);
|
return attempt<ReadWriter*>(&FSTree::open, p, 0);
|
||||||
}
|
}
|
||||||
uint32_t RootFSTree::getDentsSize(Path p){
|
uint32_t RootFSTree::getDentsSize(Path p){
|
||||||
return attempt<uint32_t>(&FSTree::getDentsSize, p, 0);
|
uint32_t size = attempt<uint32_t>(&FSTree::getDentsSize, p, 0);
|
||||||
|
FSTreeNode* n = getExhaustive(p);
|
||||||
|
if (n) {
|
||||||
|
xnoe::linkedlistelem<FSTreeNode*>* 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){
|
void RootFSTree::getDents(Path p, FSDirectoryListing* buffer){
|
||||||
attempt(&FSTree::getDents, p, 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<FSTreeNode*>* 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) {
|
bool RootFSTree::isMountpoint(Path p) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#define FSTREE_H
|
#define FSTREE_H
|
||||||
|
|
||||||
#include "../datatypes/linkedlist.h"
|
#include "../datatypes/linkedlist.h"
|
||||||
#include "strings.h"
|
|
||||||
#include "../stdio/readwriter.h"
|
#include "../stdio/readwriter.h"
|
||||||
|
#include "../strings.h"
|
||||||
|
|
||||||
struct PathEntry {
|
struct PathEntry {
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
@ -31,6 +31,7 @@ struct FSDirectoryEntry {
|
|||||||
|
|
||||||
struct FSDirectoryListing {
|
struct FSDirectoryListing {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
|
uint32_t stringsLength;
|
||||||
FSDirectoryEntry entries[];
|
FSDirectoryEntry entries[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ class RootFSTree: public FSTree {
|
|||||||
private:
|
private:
|
||||||
FSTree* getLongestMatchingUnder(Path p);
|
FSTree* getLongestMatchingUnder(Path p);
|
||||||
Path* getRemainingPath(Path p);
|
Path* getRemainingPath(Path p);
|
||||||
|
FSTreeNode* getExhaustive(Path p);
|
||||||
|
|
||||||
FSTreeNode* makeNodeIfNotExist(Path p);
|
FSTreeNode* makeNodeIfNotExist(Path p);
|
||||||
|
|
||||||
|
@ -171,29 +171,29 @@ void awaken(frame_struct* frame, Process* p) {
|
|||||||
|
|
||||||
void syscall(frame_struct* frame) {
|
void syscall(frame_struct* frame) {
|
||||||
// Syscall ABI:
|
// Syscall ABI:
|
||||||
// 0: X
|
// 0: getDentsSize :: char* path -> uint32_t size
|
||||||
// 1: X
|
// 1: getDents :: char* path -> uint8_t* buffer -> void
|
||||||
// 2: X
|
// 2: exists :: char* path -> bool
|
||||||
// 3: X
|
// 3: type :: char* path -> FSType
|
||||||
// 4: localalloc: LocalAlloc: Allocate under current process (in esi: size; out eax void* ptr)
|
// 4: localalloc :: uint32_t size -> void* ptr
|
||||||
// 5: localdelete: LocalDelete: Deallocate under current process (in esi: pointer)
|
// 5: localdelete :: void* ptr -> void
|
||||||
// 6: X
|
// 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)
|
// 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
|
// 9: getFileHandler :: char* path -> void* // 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
|
// 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 ebx -> void* filehandler esi -> uint8_t* inputbuffer edi -> int written // Reads from a buffer in to a file, returns successful written
|
// 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.
|
// 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.
|
// 13: bindStdout :: int PID -> 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.
|
// 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.
|
// 15: fopen :: char* path -> int filehandler // Returns a filehandler to the file.
|
||||||
// 16: fclose :: int filehandler esi -> void // Closes a file handler.
|
// 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:
|
// File handlers:
|
||||||
// 0: Stdout
|
// 0: Stdout
|
||||||
@ -207,12 +207,16 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
switch (frame->eax) {
|
switch (frame->eax) {
|
||||||
case 0:
|
case 0:
|
||||||
|
rval = Global::kernel->rootfs->getDentsSize(createPathFromString(frame->ebx));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
Global::kernel->rootfs->getDents(createPathFromString(frame->ebx), frame->ecx);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
rval = Global::kernel->rootfs->exists(createPathFromString(frame->ebx));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
rval = Global::kernel->rootfs->type(createPathFromString(frame->ebx));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
rval = currentProc->allocate(frame->ebx);
|
rval = currentProc->allocate(frame->ebx);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#define IDT_H
|
#define IDT_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
@ -19,3 +19,21 @@ extern "C" {
|
|||||||
return result;
|
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);
|
||||||
|
}
|
@ -11,4 +11,17 @@ extern "C" {
|
|||||||
uint16_t inw(uint16_t portnumber);
|
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
|
#endif
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
|
||||||
void init_keyboard();
|
void init_keyboard();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
@ -20,7 +19,6 @@
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
init_gdt();
|
init_gdt();
|
||||||
init_term();
|
|
||||||
|
|
||||||
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
|
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "allocate.h"
|
#include "allocate.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
void memset(uint8_t* address, uint32_t count, uint8_t value);
|
void memset(uint8_t* address, uint32_t count, uint8_t value);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#ifndef PAGING_H
|
#ifndef PAGING_H
|
||||||
#define PAGING_H
|
#define PAGING_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
struct __attribute__((packed)) split_addr {
|
struct __attribute__((packed)) split_addr {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "datatypes/linkedlist.h"
|
#include "datatypes/linkedlist.h"
|
||||||
#include "datatypes/hashtable.h"
|
#include "datatypes/hashtable.h"
|
||||||
#include "datatypes/maybe.h"
|
#include "datatypes/maybe.h"
|
||||||
#include "screenstuff.h"
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
|
|
||||||
|
@ -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<TERM_WIDTH*TERM_HEIGHT; i++) {
|
|
||||||
VMEM_ADDR[i] = 0x0720;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_line(int line) {
|
|
||||||
for (int x=0; x<TERM_WIDTH; x++) {
|
|
||||||
VMEM_ADDR[TERM_WIDTH*line + x] = 0x0720;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_curpos_raw(int curpos) {
|
|
||||||
uint8_t* cursor_position_split = (uint8_t*)&curpos;
|
|
||||||
outb(0x3D4, 0x0F);
|
|
||||||
outb(0x3D5, cursor_position_split[0]);
|
|
||||||
outb(0x3D4, 0x0E);
|
|
||||||
outb(0x3D5, cursor_position_split[1]);
|
|
||||||
|
|
||||||
cursor_x = (*(uint16_t*)cursor_position_split) % TERM_WIDTH;
|
|
||||||
cursor_y = (*(uint16_t*)cursor_position_split) / TERM_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_curpos(int x, int y) {
|
|
||||||
set_curpos_raw(y * TERM_WIDTH + x);
|
|
||||||
|
|
||||||
cursor_x = x;
|
|
||||||
cursor_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printf(const char* string, ...) {
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr, string);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
int count = 0;
|
|
||||||
char current;
|
|
||||||
while (current=string[index++]) {
|
|
||||||
count++;
|
|
||||||
if (current == '\n') {
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_x == TERM_WIDTH) {
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_y == TERM_HEIGHT) {
|
|
||||||
for (int i=1; i<TERM_HEIGHT; i++) {
|
|
||||||
for (int x=0; x<TERM_WIDTH; x++) {
|
|
||||||
int from = i * TERM_WIDTH + x;
|
|
||||||
int to = (i-1) * TERM_WIDTH + x;
|
|
||||||
VMEM_ADDR[to] = VMEM_ADDR[from];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clear_line(24);
|
|
||||||
cursor_y--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == '%') {
|
|
||||||
int type = string[index++];
|
|
||||||
int offset;
|
|
||||||
switch (type) {
|
|
||||||
case 'd': {
|
|
||||||
char decimal_buffer[11];
|
|
||||||
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
|
|
||||||
printf(decimal_buffer + offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'x': {
|
|
||||||
char hex_buffer[8];
|
|
||||||
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
|
|
||||||
printf(hex_buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 's': {
|
|
||||||
printf(va_arg(ptr, const char*));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c': {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
|
||||||
int promoted = va_arg(ptr, int);
|
|
||||||
char charred = promoted;
|
|
||||||
VMEM_ADDR[mem_pos] = charred + (0x07<<8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current != '\n') {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
|
|
||||||
VMEM_ADDR[mem_pos] = current + (0x07<<8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_curpos(cursor_x, cursor_y);
|
|
||||||
|
|
||||||
va_end(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void non_moving_put(char chr) {
|
|
||||||
int mem_pos = cursor_y * TERM_WIDTH + cursor_x;
|
|
||||||
VMEM_ADDR[mem_pos] = chr + (0x07<<8);
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#ifndef SCREENSTUFF_H
|
|
||||||
#define SCREENSTUFF_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#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
|
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef STRINGS_H
|
#ifndef STRINGS_H
|
||||||
#define STRINGS_H
|
#define STRINGS_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
bool strcmp(char* a, char* b, int max);
|
bool strcmp(char* a, char* b, int max);
|
||||||
char* split_on_first(char delimeter, char* string);
|
char* split_on_first(char delimeter, char* string);
|
||||||
int string_split(char delimeter, char* string, char** pointer_array);
|
int string_split(char delimeter, char* string, char** pointer_array);
|
||||||
|
@ -1,6 +1,26 @@
|
|||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
void Terminal::scroll_up() {
|
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; i<count; i++) {
|
||||||
// Scroll the entire buffer up.
|
// Scroll the entire buffer up.
|
||||||
for (int y = 0; y < (height * pages); y++) {
|
for (int y = 0; y < (height * pages); y++) {
|
||||||
uint16_t* cline = buffer + y * width;
|
uint16_t* cline = buffer + y * width;
|
||||||
@ -12,24 +32,193 @@ void Terminal::scroll_up() {
|
|||||||
// Clear the last line
|
// Clear the last line
|
||||||
uint16_t* last_line = buffer + (height * pages - 1) * width;
|
uint16_t* last_line = buffer + (height * pages - 1) * width;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
last_line[x] = 0x0720;
|
last_line[x] = 0x20 | (edata << 8);
|
||||||
}
|
}
|
||||||
this->cur_y--;
|
this->cur_y--;
|
||||||
|
}
|
||||||
|
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::putchar(uint32_t ptr, uint8_t c, uint8_t edata) {
|
|
||||||
|
void Terminal::scroll_down(uint32_t count) {
|
||||||
|
for (int i=0; i<count; i++) {
|
||||||
|
// Scroll the entire buffer up.
|
||||||
|
for (int y = (height * pages)-2; y >= 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.
|
// All modifications to the screen are done to the last page.
|
||||||
last_page_pointer[ptr] = c | (edata<<8);
|
last_page_pointer[this->cur_y*this->width+this->cur_x] = c | (edata<<8);
|
||||||
|
|
||||||
if (active)
|
if (active)
|
||||||
putchar_internal(ptr, c, edata);
|
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(){}
|
||||||
void Terminal::update_cur(){}
|
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)
|
Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
||||||
: ReadWriter(0) {
|
: ReadWriter(0) {
|
||||||
@ -46,23 +235,6 @@ Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
|||||||
this->active = false;
|
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, ...) {
|
void Terminal::printf(const char* string, ...) {
|
||||||
va_list ptr;
|
va_list ptr;
|
||||||
va_start(ptr, string);
|
va_start(ptr, string);
|
||||||
@ -71,73 +243,6 @@ void Terminal::printf(const char* string, ...) {
|
|||||||
char current;
|
char current;
|
||||||
|
|
||||||
while (current=string[index++]) {
|
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 == '%') {
|
if (current == '%') {
|
||||||
int type = string[index++];
|
int type = string[index++];
|
||||||
int offset;
|
int offset;
|
||||||
@ -159,22 +264,17 @@ void Terminal::printf(const char* string, ...) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'c': {
|
case 'c': {
|
||||||
int mem_pos = this->cur_y * this->width + this->cur_x++;
|
|
||||||
int promoted = va_arg(ptr, int);
|
int promoted = va_arg(ptr, int);
|
||||||
char charred = promoted;
|
char charred = promoted;
|
||||||
|
|
||||||
this->putchar(mem_pos, charred);
|
this->putchar(charred);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current != '\n') {
|
this->putchar(current);
|
||||||
int mem_pos = this->cur_y * this->width + this->cur_x++;
|
|
||||||
|
|
||||||
this->putchar(mem_pos, current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->set_curpos(this->cur_x, this->cur_y);
|
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) {
|
uint32_t Terminal::write(uint32_t count, uint8_t* string) {
|
||||||
int index = 0;
|
for (int index=0; index < count; index++)
|
||||||
char current;
|
this->putchar(string[index]);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->set_curpos(this->cur_x, this->cur_y);
|
this->set_curpos(this->cur_x, this->cur_y);
|
||||||
}
|
}
|
||||||
@ -322,7 +346,7 @@ void TextModeTerminal::update_cur() {
|
|||||||
outb(0x3D5, cursor_position_split[1]);
|
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);
|
text_mode_pointer[ptr] = c | (edata << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +357,7 @@ TextModeTerminal::TextModeTerminal(uint16_t* text_mode_pointer): Terminal(80, 25
|
|||||||
void VGAModeTerminal::update() {
|
void VGAModeTerminal::update() {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int x = 0; x < width; x++) {
|
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
|
// 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 col = ptr % width;
|
||||||
uint32_t row = 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;
|
return;
|
||||||
uint8_t* char_data = font[c];
|
uint8_t* char_data = font[c];
|
||||||
|
|
||||||
for (int y=0; y<8; y++) {
|
for (int y=0; y<8; y++)
|
||||||
//for (int x=0; x<8; x++) {
|
put_pixels_byte(sx, sy+y, edata, char_data[y]);
|
||||||
put_pixels_byte(sx, sy+y, 15, char_data[y]);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) {
|
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++) {
|
for (int i=0; i<4; i++) {
|
||||||
if (color & (1<<i))
|
|
||||||
this->planes[i][pixelindex] = trbyte;
|
|
||||||
else
|
|
||||||
this->planes[i][pixelindex] = 0;
|
this->planes[i][pixelindex] = 0;
|
||||||
|
if (color & (1<<i))
|
||||||
|
this->planes[i][pixelindex] |= trbyte;
|
||||||
|
if ((color>>4) & (1<<i))
|
||||||
|
this->planes[i][pixelindex] |= ~trbyte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,15 +17,32 @@ namespace Timer {
|
|||||||
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false);
|
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 {
|
class Terminal: public ReadWriter {
|
||||||
private:
|
private:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
virtual void update_cur();
|
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:
|
protected:
|
||||||
uint16_t* buffer;
|
uint16_t* buffer;
|
||||||
@ -40,6 +57,8 @@ protected:
|
|||||||
uint16_t* last_page_pointer;
|
uint16_t* last_page_pointer;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
|
uint8_t edata=0x07;
|
||||||
public:
|
public:
|
||||||
Terminal(uint32_t width, uint32_t height, uint32_t pages);
|
Terminal(uint32_t width, uint32_t height, uint32_t pages);
|
||||||
|
|
||||||
@ -62,7 +81,7 @@ class TextModeTerminal : public Terminal {
|
|||||||
private:
|
private:
|
||||||
void update() override;
|
void update() override;
|
||||||
void update_cur() 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;
|
uint16_t* text_mode_pointer;
|
||||||
public:
|
public:
|
||||||
@ -74,7 +93,7 @@ class VGAModeTerminal : public Terminal {
|
|||||||
private:
|
private:
|
||||||
void update() override;
|
void update() override;
|
||||||
void update_cur() 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_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);
|
void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte);
|
||||||
|
@ -169,6 +169,7 @@ int main() {
|
|||||||
for (int i=0; i < 1000; i++)
|
for (int i=0; i < 1000; i++)
|
||||||
write(1, 0, &space);
|
write(1, 0, &space);
|
||||||
print("\x1b[1;1H");
|
print("\x1b[1;1H");
|
||||||
|
print("\x1b[45;33;1m");
|
||||||
|
|
||||||
char* mid = "+ ++ +";
|
char* mid = "+ ++ +";
|
||||||
char* bottom = "+ +";
|
char* bottom = "+ +";
|
||||||
@ -181,20 +182,21 @@ int main() {
|
|||||||
write(90, 0, bottom);
|
write(90, 0, bottom);
|
||||||
for (int i=0; i<90;i++)
|
for (int i=0; i<90;i++)
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
|
print("\x1b[42;36;1m");
|
||||||
|
|
||||||
uint32_t program = fopen("/hello.bin");
|
uint32_t program = fopen("/hello.bin");
|
||||||
uint32_t p1 = fork(program);
|
uint32_t p1 = exec(program);
|
||||||
uint32_t p1out = bindStdout(p1);
|
uint32_t p1out = bindStdout(p1);
|
||||||
uint32_t p1in = bindStdin(p1);
|
uint32_t p1in = bindStdin(p1);
|
||||||
fclose(program);
|
fclose(program);
|
||||||
program = fopen("/timer.bin");
|
program = fopen("/timer.bin");
|
||||||
uint32_t p2 = fork(program);
|
uint32_t p2 = exec(program);
|
||||||
uint32_t p2out = bindStdout(p2);
|
uint32_t p2out = bindStdout(p2);
|
||||||
uint32_t p2in = bindStdin(p2);
|
uint32_t p2in = bindStdin(p2);
|
||||||
fclose(program);
|
fclose(program);
|
||||||
|
|
||||||
procbuffer b1 = {
|
procbuffer b1 = {
|
||||||
.buffer = localalloc(56 * 43),
|
.buffer = malloc(56 * 43),
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.process = p1,
|
.process = p1,
|
||||||
@ -203,7 +205,7 @@ int main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
procbuffer b2 = {
|
procbuffer b2 = {
|
||||||
.buffer = localalloc(56 * 43),
|
.buffer = malloc(56 * 43),
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.process = p2,
|
.process = p2,
|
||||||
@ -247,6 +249,11 @@ int main() {
|
|||||||
writeStrToBuf(" Kills the current process\n", selectedBuf);
|
writeStrToBuf(" Kills the current process\n", selectedBuf);
|
||||||
writeStrToBuf(":load <filename>\n", selectedBuf);
|
writeStrToBuf(":load <filename>\n", selectedBuf);
|
||||||
writeStrToBuf(" Loads and executes the program <filename>\n", selectedBuf);
|
writeStrToBuf(" Loads and executes the program <filename>\n", selectedBuf);
|
||||||
|
writeStrToBuf(":ls <path>\n", selectedBuf);
|
||||||
|
writeStrToBuf(" Lists the files in directory <path>\n", selectedBuf);
|
||||||
|
writeStrToBuf(":clear\n", selectedBuf);
|
||||||
|
writeStrToBuf(" Clears the buffer\n", selectedBuf);
|
||||||
|
|
||||||
writeStrToBuf("--------\n", selectedBuf);
|
writeStrToBuf("--------\n", selectedBuf);
|
||||||
} else if (strcmpcnt(4, buf, "kill")) {
|
} else if (strcmpcnt(4, buf, "kill")) {
|
||||||
if (selectedBuf->process) {
|
if (selectedBuf->process) {
|
||||||
@ -255,21 +262,28 @@ int main() {
|
|||||||
selectedBuf->process = 0;
|
selectedBuf->process = 0;
|
||||||
selectedBuf->stdin = 0;
|
selectedBuf->stdin = 0;
|
||||||
selectedBuf->stdout = 0;
|
selectedBuf->stdout = 0;
|
||||||
if (selectedBuf == &b1) {
|
|
||||||
selectedBuf = &b2;
|
|
||||||
} else {
|
|
||||||
selectedBuf = &b1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (strcmpcnt(4, buf, "load")) {
|
} else if (strcmpcnt(4, buf, "load")) {
|
||||||
if (!selectedBuf->process) {
|
if (!selectedBuf->process) {
|
||||||
char* potFn = buf+5;
|
char* potFn = buf+5;
|
||||||
uint32_t fh = fopen(potFn);
|
uint32_t fh = fopen(potFn);
|
||||||
selectedBuf->process = fork(fh);
|
selectedBuf->process = exec(fh);
|
||||||
selectedBuf->stdout = bindStdout(selectedBuf->process);
|
selectedBuf->stdout = bindStdout(selectedBuf->process);
|
||||||
selectedBuf->stdin = bindStdin(selectedBuf->process);
|
selectedBuf->stdin = bindStdin(selectedBuf->process);
|
||||||
fclose(fh);
|
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; i<listing->count; 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 {
|
} else {
|
||||||
if (selectedBuf->process)
|
if (selectedBuf->process)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user