Fix merge conflicts
This commit is contained in:
commit
913c2d2844
10
.clang-format
Normal file
10
.clang-format
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
DerivePointerAlignment: 'true'
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
UseTab: ForIndentation
|
||||||
|
IndentWidth: 2
|
||||||
|
TabWidth: 2
|
||||||
|
ColumnLimit: 120
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
|
||||||
|
...
|
59
.gitignore
vendored
Normal file
59
.gitignore
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/c
|
||||||
|
# Edit at https://www.gitignore.io/?templates=c
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/c
|
449
arch/i386/tty.c
Executable file → Normal file
449
arch/i386/tty.c
Executable file → Normal file
|
@ -3,18 +3,18 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <kernel/tty.h>
|
#include "kernel/tty.h"
|
||||||
#include <kernel/utils.h>
|
#include "kernel/utils.h"
|
||||||
|
|
||||||
static const size_t TERM_WIDTH=80;
|
static const size_t TERM_WIDTH = 80;
|
||||||
static const size_t TERM_HEIGHT=25;
|
static const size_t TERM_HEIGHT = 25;
|
||||||
|
|
||||||
static size_t terminal_row;
|
static size_t terminal_row;
|
||||||
static size_t terminal_column;
|
static size_t terminal_column;
|
||||||
|
|
||||||
static uint8_t current_color;
|
static uint8_t current_color;
|
||||||
static uint16_t* term_buffer;
|
static uint16_t* term_buffer;
|
||||||
static uint16_t* const vga_buffer = (uint16_t*) 0xB8000;
|
static uint16_t* const vga_buffer = (uint16_t*)0xB8000;
|
||||||
|
|
||||||
void screen_initialize(void) {
|
void screen_initialize(void) {
|
||||||
|
|
||||||
|
@ -24,18 +24,16 @@ void screen_initialize(void) {
|
||||||
term_buffer = vga_buffer;
|
term_buffer = vga_buffer;
|
||||||
|
|
||||||
for (size_t y = 0; y < TERM_HEIGHT; y++) {
|
for (size_t y = 0; y < TERM_HEIGHT; y++) {
|
||||||
for(size_t x = 0; x < TERM_WIDTH; x++) {
|
for (size_t x = 0; x < TERM_WIDTH; x++) {
|
||||||
const size_t offset = y * TERM_WIDTH + x;
|
const size_t offset = y * TERM_WIDTH + x;
|
||||||
term_buffer[offset] = vga_entry(' ', current_color);
|
term_buffer[offset] = vga_entry(' ', current_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_setcolor(enum vga_colors color) {
|
void term_setcolor(enum vga_colors color) { current_color = color; }
|
||||||
current_color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void term_putentryat (char c, uint8_t color, size_t x, size_t y) {
|
void term_putentryat(char c, uint8_t color, size_t x, size_t y) {
|
||||||
const size_t offset = y * TERM_WIDTH + x;
|
const size_t offset = y * TERM_WIDTH + x;
|
||||||
term_buffer[offset] = vga_entry(c, color);
|
term_buffer[offset] = vga_entry(c, color);
|
||||||
}
|
}
|
||||||
|
@ -43,252 +41,293 @@ void term_putentryat (char c, uint8_t color, size_t x, size_t y) {
|
||||||
void term_putchar(char c) {
|
void term_putchar(char c) {
|
||||||
unsigned char uc = c;
|
unsigned char uc = c;
|
||||||
|
|
||||||
//Handle escaped characters, such as newline, and crtn.
|
// Handle escaped characters, such as newline, and crtn.
|
||||||
switch (uc) {
|
switch (uc) {
|
||||||
case '\n':
|
case '\n':
|
||||||
terminal_column = 0;
|
|
||||||
terminal_row += 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
term_putentryat(uc, current_color, terminal_column, terminal_row);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(++terminal_column == TERM_WIDTH)
|
|
||||||
{
|
|
||||||
terminal_column = 0;
|
terminal_column = 0;
|
||||||
if(++terminal_row == TERM_HEIGHT){
|
terminal_row += 1;
|
||||||
term_scroll(false);
|
break;
|
||||||
terminal_row = 0;
|
default:
|
||||||
|
term_putentryat(uc, current_color, terminal_column, terminal_row);
|
||||||
|
if (++terminal_column == TERM_WIDTH) {
|
||||||
|
terminal_column = 0;
|
||||||
|
if (++terminal_row == TERM_HEIGHT) {
|
||||||
|
term_scroll(false);
|
||||||
|
terminal_row = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct csi_sequence parse_csi(const char* data, size_t size) {
|
||||||
|
enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID };
|
||||||
|
enum State state = PARAMETER;
|
||||||
|
|
||||||
|
struct csi_sequence sequence = {.parameter = NULL,
|
||||||
|
.parameter_len = 0,
|
||||||
|
.intermediate = NULL,
|
||||||
|
.intermediate_len = 0,
|
||||||
|
.final = NULL,
|
||||||
|
.valid = false};
|
||||||
|
|
||||||
|
for (size_t j = 0; j < size; j++) {
|
||||||
|
uint8_t c = data[j];
|
||||||
|
if (state == PARAMETER && (c >= 0x30 && c <= 0x3F)) {
|
||||||
|
if (!sequence.parameter)
|
||||||
|
sequence.parameter = data + j;
|
||||||
|
sequence.parameter_len++;
|
||||||
|
} else if (c >= 0x20 && c <= 0x2F) {
|
||||||
|
if (!sequence.intermediate)
|
||||||
|
sequence.intermediate = data + j;
|
||||||
|
sequence.intermediate_len++;
|
||||||
|
state = INTERMEDIATE;
|
||||||
|
} else if (c >= 0x40 && c <= 0x7F) {
|
||||||
|
sequence.final = data + j;
|
||||||
|
sequence.valid = true;
|
||||||
|
state = FINAL;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// Parameter found in intermediate byte location, or byte out of
|
||||||
|
// range
|
||||||
|
state = INVALID;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_write(const char* data, size_t size) {
|
void term_write(const char* data, size_t size) {
|
||||||
for(size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
//Begin handling ANSI escape codes.
|
// Begin handling ANSI escape codes.
|
||||||
if(data[i] == 0x1B) { //The current character is ESC - the start of ANSI codes.
|
if (data[i] == 0x1b) { // The current character is ESC - the start of ANSI codes.
|
||||||
term_writes("ANSI Code encountered: ");
|
// term_writes("ANSI Code encountered: ");
|
||||||
|
|
||||||
bool string_terminated = false; //Flag used in some of the escape codes
|
bool string_terminated = false; // Flag used in some of the escape codes
|
||||||
switch(data[i+1]) {
|
|
||||||
case 0x9b/*[*/: //CSI - Control Sequence Introducer (The most common one, hence it comes first)
|
|
||||||
char* controlSequence;
|
|
||||||
if(data[i+2] == NULL) {
|
|
||||||
controlSequence = '\0';
|
|
||||||
for(size_t j = 0; j < (strlen(data) - (i+2); j++) {
|
|
||||||
if(data[j] == ' ')
|
|
||||||
break;
|
|
||||||
controlSequence += data[j];
|
|
||||||
}
|
|
||||||
handleControlSequence(controlSequence); //Send it off to our handler function to keep this part clean
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Single shifts are not handled, so just print them and exit
|
// TODO: Should only progress if we have at least 2 more bytes
|
||||||
case 0x8e/*N*/: //SS2 - Single Shift Two
|
|
||||||
term_writes("Single Shift Two\n");
|
|
||||||
break;
|
|
||||||
case 0x8f/*O*/: //SS3 - Single Shift Three
|
|
||||||
term_writes("Single Shift Three\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Control Strings
|
switch ((uint8_t)data[i + 1]) {
|
||||||
case 0x90/*P*/: //DCS - Device Control String
|
case '[': // CSI - Control Sequence Introducer (The most common one, hence it comes first)
|
||||||
term_writes("Device Control String");
|
{
|
||||||
string_terminated = false;
|
struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2));
|
||||||
break;
|
if (sequence.valid) {
|
||||||
case 0x9c/*\*/: //ST - String Terminator
|
// Send it off to our handler function to keep this part clean
|
||||||
term_writes("String Terminator\n");
|
handleControlSequence(sequence);
|
||||||
string_terminated = true;
|
i += sequence.parameter_len + sequence.intermediate_len + 2; // Move past sequence
|
||||||
break;
|
}
|
||||||
case 0x9d/*]*/: //OSC - Operating System Command
|
} break;
|
||||||
term_writes("Operating System Command\n");
|
// Single shifts are not handled, so just print them and exit
|
||||||
string_terminated = false;
|
case 'N': // SS2 - Single Shift Two
|
||||||
break;
|
term_writes("Single Shift Two\n");
|
||||||
case 0x98/*X*/: //SOS - Start Of String
|
break;
|
||||||
term_writes("Start of String");
|
case 'O': // SS3 - Single Shift Three
|
||||||
string_terminated = false;
|
term_writes("Single Shift Three\n");
|
||||||
break;
|
break;
|
||||||
case 0x9e/*^*/: //PM - Privacy Message
|
|
||||||
term_writes("Privacy Message\n");
|
// Control Strings
|
||||||
break;
|
case 'P': // DCS - Device Control String
|
||||||
case 0x9f/*_*/: //APC - Application Program Command
|
term_writes("Device Control String");
|
||||||
term_writes("Application Program Command\n");
|
string_terminated = false;
|
||||||
break;
|
break;
|
||||||
|
case '\\': // ST - String Terminator
|
||||||
|
term_writes("String Terminator\n");
|
||||||
|
string_terminated = true;
|
||||||
|
break;
|
||||||
|
case ']': // OSC - Operating System Command
|
||||||
|
term_writes("Operating System Command\n");
|
||||||
|
string_terminated = false;
|
||||||
|
break;
|
||||||
|
case 'X': // SOS - Start Of String
|
||||||
|
term_writes("Start of String");
|
||||||
|
string_terminated = false;
|
||||||
|
break;
|
||||||
|
case '^': // PM - Privacy Message
|
||||||
|
term_writes("Privacy Message\n");
|
||||||
|
break;
|
||||||
|
case '_': // APC - Application Program Command
|
||||||
|
term_writes("Application Program Command\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
term_putchar(data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_putchar(data[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_writes(const char* data) {
|
void term_writes(const char* data) { term_write(data, strlen(data)); }
|
||||||
term_write(data, strlen(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void puts(const char* string) {
|
void puts(const char* string) {
|
||||||
term_write(string, strlen(string));
|
term_write(string, strlen(string));
|
||||||
term_putchar('\n');
|
term_putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleControlSequence(const char* sequence) {
|
void handleControlSequence(struct csi_sequence sequence) {
|
||||||
//Check for our failsafes
|
// Check for our failsafes
|
||||||
if(sequence) {
|
|
||||||
if(sequence != '\0') {
|
|
||||||
int n = 0; //Default of the flag used for a few items
|
|
||||||
|
|
||||||
bool nPresent = false;
|
if (sequence.valid) {
|
||||||
bool terminated = false;
|
int n = 0; // Default of the flag used for a few items
|
||||||
for(size_t i = 0; i < strlen(sequence); i++) {
|
|
||||||
if(isDigit(sequence[i])) {
|
|
||||||
nPresent = true;
|
|
||||||
n = (n*10) + sequence[i];
|
|
||||||
} else if(n > 80) {
|
|
||||||
n = 80;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n == 0)
|
// Parse parameters, we only care about a max 2 of number only parameters
|
||||||
n = 1;
|
// for now
|
||||||
|
int params[2] = {0};
|
||||||
switch(sequence[i]) {
|
int param_count = 0;
|
||||||
case ';':
|
if (sequence.parameter_len) {
|
||||||
terminated = true;
|
for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) {
|
||||||
int m = 0;
|
char c = sequence.parameter[i];
|
||||||
for(size_t j = 0; j < strlen(sequence - i); j++) {
|
if (isDigit(c)) {
|
||||||
if(sequence[j] == 'H' ||sequence[j] == 'f')
|
n = (n * 10) + (sequence.parameter[i] - '0');
|
||||||
break;
|
} else if (c == ';') {
|
||||||
|
params[param_count++] = n;
|
||||||
if(isDigit(sequence[j])) {
|
|
||||||
m = (m*10) + sequence[j];
|
|
||||||
} else if(j > 80) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m == 0)
|
|
||||||
m = 1;
|
|
||||||
cursor_pos(n, m);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'A': //CUU - Cursor Up
|
|
||||||
//cursor_pos(x, y)
|
|
||||||
|
|
||||||
cursor_pos(terminal_column, terminal_row + n);
|
|
||||||
break;
|
|
||||||
case 'B': //CUD - Cursor Down
|
|
||||||
cursor_pos(terminal_column, terminal_row - n);
|
|
||||||
break;
|
|
||||||
case 'C': //CUF - Cursor Forward
|
|
||||||
cursor_pos(terminal_column + n, terminal_row);
|
|
||||||
break;
|
|
||||||
case 'D': //CUB - Cursor Back
|
|
||||||
cursor_pos(terminal_column - n, terminal_row);
|
|
||||||
break;
|
|
||||||
case 'E': //CNL - Cursor Next Line
|
|
||||||
cursor_pos(0, terminal_row + n);
|
|
||||||
break;
|
|
||||||
case 'F': //CPL - Cursor Previous Line
|
|
||||||
cursor_pos(0, terminal_row - n);
|
|
||||||
break;
|
|
||||||
case 'G': //CHA - Cursor Horizontal Absolute
|
|
||||||
cursor_pos(n, terminal_row);
|
|
||||||
case 'J': //ED - Erase in Display
|
|
||||||
//current cursor pos = y * width + x
|
|
||||||
int pos = terminal_row * 80 + terminal_column;
|
|
||||||
if(!nPresent) {
|
|
||||||
for(pos < (25 * 80); pos++) {
|
|
||||||
vga_buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
} else if(nPresent && n == 1) {
|
|
||||||
for(pos > 0; pos--) {
|
|
||||||
vga_buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
} else if(n == 2 || n == 3) {
|
|
||||||
for(int i = 0; i < (25*80); i++) {
|
|
||||||
vga_buffer[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'K': //EL - Erase in Line
|
|
||||||
|
|
||||||
int pos = terminal_row * 80 + terminal_column;
|
|
||||||
if(!nPresent) { //From cursor to end of line
|
|
||||||
int endPos = (terminal_row + 1) * 80 - 1; //End of line = current row + 25 columns = current row + 1
|
|
||||||
for(pos < endPos; pos++) {
|
|
||||||
vga_buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
} else if(nPresent && n == 1) { //From cursor to start of line
|
|
||||||
int endPos = terminal_row * 80; //Start of line = end of previous line + 1 == current line
|
|
||||||
for(pos > endPos; pos--) {
|
|
||||||
vga_buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
} else if(nPresent && n == 2) { //Entire current line
|
|
||||||
pos = terminal_row * 80;
|
|
||||||
int endPos = (terminal_row + 1) * 80 - 1;
|
|
||||||
for(pos < endPos; pos++) {
|
|
||||||
vga_buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'S': //SU - Scroll Up
|
|
||||||
term_scroll(true);
|
|
||||||
break;
|
|
||||||
case 'T': //SD - Scroll Down
|
|
||||||
term_scroll(false);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
params[param_count++] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*(sequence.final)) {
|
||||||
|
case 'H':
|
||||||
|
case 'f': // CUP - Cursor Position
|
||||||
|
// TODO: Check to see if we have 2 paramaters
|
||||||
|
if (params[0])
|
||||||
|
params[0]--;
|
||||||
|
if (params[1])
|
||||||
|
params[1]--;
|
||||||
|
set_cursor(params[0], params[1]);
|
||||||
|
break;
|
||||||
|
case 'A': // CUU - Cursor Up
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(terminal_column, terminal_row - params[0]);
|
||||||
|
break;
|
||||||
|
case 'B': // CUD - Cursor Down
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(terminal_column, terminal_row + params[0]);
|
||||||
|
break;
|
||||||
|
case 'C': // CUF - Cursor Forward
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(terminal_column + params[0], terminal_row);
|
||||||
|
break;
|
||||||
|
case 'D': // CUB - Cursor Back
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(terminal_column - params[0], terminal_row);
|
||||||
|
break;
|
||||||
|
case 'E': // CNL - Cursor Next Line
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(0, terminal_row + params[0]);
|
||||||
|
break;
|
||||||
|
case 'F': // CPL - Cursor Previous Line
|
||||||
|
if (!params[0])
|
||||||
|
params[0] = 1;
|
||||||
|
set_cursor(0, terminal_row - params[0]);
|
||||||
|
break;
|
||||||
|
case 'G': // CHA - Cursor Horizontal Absolute
|
||||||
|
if (params[0])
|
||||||
|
params[0]--;
|
||||||
|
set_cursor(params[0], terminal_row);
|
||||||
|
break;
|
||||||
|
case 'J': // ED - Erase in Display
|
||||||
|
{
|
||||||
|
// current cursor pos = y * width + x
|
||||||
|
int pos = terminal_row * 80 + terminal_column;
|
||||||
|
if (params[0] == 0) { // Clear from cursor to end of screen
|
||||||
|
for (; pos < (25 * 80); pos++) {
|
||||||
|
vga_buffer[pos] = '\0';
|
||||||
|
}
|
||||||
|
} else if (params[0] == 1) { // Clear from cursor to beginning
|
||||||
|
for (; pos > 0; pos--) {
|
||||||
|
vga_buffer[pos] = '\0';
|
||||||
|
}
|
||||||
|
} else if (params[0] == 2 || params[0] == 3) { // Clear entire screen
|
||||||
|
// TODO: Support scrollback buffer? (n = 3)
|
||||||
|
for (int i = 0; i < (25 * 80); i++) {
|
||||||
|
vga_buffer[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'K': // EL - Erase in Line
|
||||||
|
{
|
||||||
|
int pos = terminal_row * 80 + terminal_column;
|
||||||
|
if (params[0] == 0) { // From cursor to end of line
|
||||||
|
int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1
|
||||||
|
for (; pos < endPos; pos++) {
|
||||||
|
vga_buffer[pos] = '\0';
|
||||||
|
}
|
||||||
|
} else if (params[0] == 1) { // From cursor to start of line
|
||||||
|
int endPos = terminal_row * 80; // Start of line = end of previous line + 1 == current line
|
||||||
|
for (; pos > endPos; pos--) {
|
||||||
|
vga_buffer[pos] = '\0';
|
||||||
|
}
|
||||||
|
} else if (params[0] == 2) { // Entire current line
|
||||||
|
pos = terminal_row * 80;
|
||||||
|
int endPos = (terminal_row + 1) * 80 - 1;
|
||||||
|
for (; pos < endPos; pos++) {
|
||||||
|
vga_buffer[pos] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'S': // SU - Scroll Up
|
||||||
|
term_scroll(true);
|
||||||
|
break;
|
||||||
|
case 'T': // SD - Scroll Down
|
||||||
|
term_scroll(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDigit(const char c) {
|
bool isDigit(char c) { return c >= '0' && c <= '9'; }
|
||||||
return c == '0' || c == '1' || c == '2' || c == '3' ||
|
|
||||||
c == '4' || c == '5' || c == '6' || c == '7' ||
|
void set_cursor(int n, int m) {
|
||||||
c == '8' || c == '9';
|
terminal_column = n;
|
||||||
|
terminal_row = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_scroll(bool down) {
|
void term_scroll(bool down) {
|
||||||
|
|
||||||
int current_pos;
|
int current_pos;
|
||||||
if(down) {
|
if (down) {
|
||||||
current_pos = 25 * 80; //Start of the last line.
|
current_pos = 25 * 80; // Start of the last line.
|
||||||
} else {
|
} else {
|
||||||
current_pos = 160; //Start of the second line.
|
current_pos = 160; // Start of the second line.
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* term_buffer = (unsigned char*) vga_buffer;
|
unsigned char* term_buffer = (unsigned char*)vga_buffer;
|
||||||
|
|
||||||
if(down) { //To scroll down, move every character into the one below it, or "pull" every character down
|
if (down) { // To scroll down, move every character into the one below it, or "pull" every character down
|
||||||
while(current_pos > 80) {
|
while (current_pos > 80) {
|
||||||
term_buffer[current_pos + 160] = vga_buffer[current_pos];
|
term_buffer[current_pos + 160] = vga_buffer[current_pos];
|
||||||
term_buffer[current_pos + 159] = vga_buffer[current_pos - 1];
|
term_buffer[current_pos + 159] = vga_buffer[current_pos - 1];
|
||||||
current_pos -= 2;
|
current_pos -= 2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
while (current_pos <= 4000) {
|
while (current_pos <= 4000) {
|
||||||
term_buffer[current_pos - 160 /*The character immediately below it*/] = vga_buffer[current_pos]; //Move each character up a line
|
term_buffer[current_pos - 160 /*The character immediately below it*/] =
|
||||||
term_buffer[current_pos - 159 /*The color of the character below*/] = vga_buffer[current_pos + 1]; //As well as its color
|
vga_buffer[current_pos]; // Move each character up a line
|
||||||
current_pos += 2; //Move to next char
|
term_buffer[current_pos - 159 /*The color of the character below*/] =
|
||||||
|
vga_buffer[current_pos + 1]; // As well as its color
|
||||||
|
current_pos += 2; // Move to next char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(down) {
|
if (down) {
|
||||||
current_pos = 0; //Start of first line
|
current_pos = 0; // Start of first line
|
||||||
for(current_pos < 80; current_pos++) {
|
for (; current_pos < 80; current_pos++) {
|
||||||
term_buffer[current_pos] = '\0';
|
term_buffer[current_pos] = '\0';
|
||||||
current_pos += 2;
|
current_pos += 2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
; //Start of the last line
|
; // Start of the last line
|
||||||
//Wipe out the bottom line
|
// Wipe out the bottom line
|
||||||
for(current_pos = 3840; current_pos <= 3920; i++) {
|
for (current_pos = 3840; current_pos <= 3920; current_pos += 2) {
|
||||||
term_buffer[current_pos] = 0;
|
term_buffer[current_pos] = 0;
|
||||||
current_pos += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
terminal_row = 24; // Start writing on the last line
|
||||||
terminal_row = 24; //Start writing on the last line
|
|
||||||
terminal_column = 0;
|
terminal_column = 0;
|
||||||
}
|
}
|
9
include/arch/i386/vga.h
Executable file → Normal file
9
include/arch/i386/vga.h
Executable file → Normal file
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
enum vga_colors {
|
enum vga_colors {
|
||||||
BLACK = 0,
|
BLACK = 0,
|
||||||
BLUE = 1,
|
BLUE = 1,
|
||||||
|
@ -23,12 +22,8 @@ enum vga_colors {
|
||||||
WHITE = 15
|
WHITE = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) {
|
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; }
|
||||||
return fg | bg << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
|
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { return (uint16_t)uc | (uint16_t)color << 8; }
|
||||||
return (uint16_t) uc | (uint16_t) color << 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
18
include/kernel/tty.h
Executable file → Normal file
18
include/kernel/tty.h
Executable file → Normal file
|
@ -1,8 +1,19 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vga.h>
|
|
||||||
|
#include "vga.h"
|
||||||
|
|
||||||
|
struct csi_sequence {
|
||||||
|
const char* parameter;
|
||||||
|
size_t parameter_len;
|
||||||
|
const char* intermediate;
|
||||||
|
size_t intermediate_len;
|
||||||
|
const char* final;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
void term_setcolor(enum vga_colors);
|
void term_setcolor(enum vga_colors);
|
||||||
void screen_initialize(void);
|
void screen_initialize(void);
|
||||||
|
@ -11,8 +22,11 @@ void term_putchar(char);
|
||||||
void term_write(const char*, size_t);
|
void term_write(const char*, size_t);
|
||||||
void term_writes(const char*);
|
void term_writes(const char*);
|
||||||
void puts(const char*);
|
void puts(const char*);
|
||||||
|
void handleControlSequence(struct csi_sequence);
|
||||||
void set_cursor(int, int);
|
void set_cursor(int, int);
|
||||||
void term_scroll(void);
|
void term_scroll(bool);
|
||||||
void int_to_ascii(int, char*);
|
void int_to_ascii(int, char*);
|
||||||
void int_to_hex(int, char*);
|
void int_to_hex(int, char*);
|
||||||
void empty_string(char*);
|
void empty_string(char*);
|
||||||
|
|
||||||
|
bool isDigit(char c);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
9
include/vga.h
Executable file → Normal file
9
include/vga.h
Executable file → Normal file
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
enum vga_colors {
|
enum vga_colors {
|
||||||
BLACK = 0,
|
BLACK = 0,
|
||||||
BLUE = 1,
|
BLUE = 1,
|
||||||
|
@ -22,10 +21,6 @@ enum vga_colors {
|
||||||
WHITE = 15
|
WHITE = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) {
|
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; }
|
||||||
return fg | bg << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
|
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { return (uint16_t)uc | (uint16_t)color << 8; }
|
||||||
return (uint16_t) uc | (uint16_t) color << 8;
|
|
||||||
}
|
|
||||||
|
|
Binary file not shown.
1
kernel/kernel.c
Executable file → Normal file
1
kernel/kernel.c
Executable file → Normal file
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
//#include <stdio.h>
|
//#include <stdio.h>
|
||||||
|
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
|
|
10
kernel/syscalls.c
Executable file → Normal file
10
kernel/syscalls.c
Executable file → Normal file
|
@ -1,10 +1,10 @@
|
||||||
/*#include <sys/stat.h>
|
/*#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/times.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
//prototypes; these are the bare minimum for newlib to compile.
|
//prototypes; these are the bare minimum for newlib to compile.
|
||||||
|
|
||||||
|
|
0
kernel/utils.c
Executable file → Normal file
0
kernel/utils.c
Executable file → Normal file
77
libc/include/stdlib.h
Executable file → Normal file
77
libc/include/stdlib.h
Executable file → Normal file
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
__attribute__((__noreturn__))
|
__attribute__((__noreturn__)) void abort(void);
|
||||||
void abort(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Default header file for malloc-2.8.x, written by Doug Lea
|
Default header file for malloc-2.8.x, written by Doug Lea
|
||||||
|
@ -32,24 +31,24 @@ void abort(void);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h> /* for size_t */
|
#include <stddef.h> /* for size_t */
|
||||||
|
|
||||||
#ifndef ONLY_MSPACES
|
#ifndef ONLY_MSPACES
|
||||||
#define ONLY_MSPACES 0 /* define to a value */
|
#define ONLY_MSPACES 0 /* define to a value */
|
||||||
#elif ONLY_MSPACES != 0
|
#elif ONLY_MSPACES != 0
|
||||||
#define ONLY_MSPACES 1
|
#define ONLY_MSPACES 1
|
||||||
#endif /* ONLY_MSPACES */
|
#endif /* ONLY_MSPACES */
|
||||||
#ifndef NO_MALLINFO
|
#ifndef NO_MALLINFO
|
||||||
#define NO_MALLINFO 0
|
#define NO_MALLINFO 0
|
||||||
#endif /* NO_MALLINFO */
|
#endif /* NO_MALLINFO */
|
||||||
|
|
||||||
#ifndef MSPACES
|
#ifndef MSPACES
|
||||||
#if ONLY_MSPACES
|
#if ONLY_MSPACES
|
||||||
#define MSPACES 1
|
#define MSPACES 1
|
||||||
#else /* ONLY_MSPACES */
|
#else /* ONLY_MSPACES */
|
||||||
#define MSPACES 0
|
#define MSPACES 0
|
||||||
#endif /* ONLY_MSPACES */
|
#endif /* ONLY_MSPACES */
|
||||||
#endif /* MSPACES */
|
#endif /* MSPACES */
|
||||||
|
|
||||||
#if !ONLY_MSPACES
|
#if !ONLY_MSPACES
|
||||||
|
|
||||||
|
@ -62,21 +61,21 @@ extern "C" {
|
||||||
#ifndef STRUCT_MALLINFO_DECLARED
|
#ifndef STRUCT_MALLINFO_DECLARED
|
||||||
#define STRUCT_MALLINFO_DECLARED 1
|
#define STRUCT_MALLINFO_DECLARED 1
|
||||||
struct mallinfo {
|
struct mallinfo {
|
||||||
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
|
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
|
||||||
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
|
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
|
||||||
MALLINFO_FIELD_TYPE smblks; /* always 0 */
|
MALLINFO_FIELD_TYPE smblks; /* always 0 */
|
||||||
MALLINFO_FIELD_TYPE hblks; /* always 0 */
|
MALLINFO_FIELD_TYPE hblks; /* always 0 */
|
||||||
MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */
|
MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */
|
||||||
MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */
|
MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */
|
||||||
MALLINFO_FIELD_TYPE fsmblks; /* always 0 */
|
MALLINFO_FIELD_TYPE fsmblks; /* always 0 */
|
||||||
MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
|
MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
|
||||||
MALLINFO_FIELD_TYPE fordblks; /* total free space */
|
MALLINFO_FIELD_TYPE fordblks; /* total free space */
|
||||||
MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
|
MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
|
||||||
};
|
};
|
||||||
#endif /* STRUCT_MALLINFO_DECLARED */
|
#endif /* STRUCT_MALLINFO_DECLARED */
|
||||||
#endif /* _MALLOC_H */
|
#endif /* _MALLOC_H */
|
||||||
#endif /* HAVE_USR_INCLUDE_MALLOC_H */
|
#endif /* HAVE_USR_INCLUDE_MALLOC_H */
|
||||||
#endif /* !NO_MALLINFO */
|
#endif /* !NO_MALLINFO */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
malloc(size_t n)
|
malloc(size_t n)
|
||||||
|
@ -198,10 +197,9 @@ void* valloc(size_t);
|
||||||
*/
|
*/
|
||||||
int mallopt(int, int);
|
int mallopt(int, int);
|
||||||
|
|
||||||
#define M_TRIM_THRESHOLD (-1)
|
#define M_TRIM_THRESHOLD (-1)
|
||||||
#define M_GRANULARITY (-2)
|
#define M_GRANULARITY (-2)
|
||||||
#define M_MMAP_THRESHOLD (-3)
|
#define M_MMAP_THRESHOLD (-3)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
malloc_footprint();
|
malloc_footprint();
|
||||||
|
@ -280,8 +278,7 @@ size_t malloc_set_footprint_limit(size_t bytes);
|
||||||
|
|
||||||
malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
|
malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
|
||||||
*/
|
*/
|
||||||
void malloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
|
void malloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg);
|
||||||
void* arg);
|
|
||||||
|
|
||||||
#if !NO_MALLINFO
|
#if !NO_MALLINFO
|
||||||
/*
|
/*
|
||||||
|
@ -308,7 +305,7 @@ void malloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct mallinfo mallinfo(void);
|
struct mallinfo mallinfo(void);
|
||||||
#endif /* NO_MALLINFO */
|
#endif /* NO_MALLINFO */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
|
independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
|
||||||
|
@ -428,14 +425,14 @@ void** independent_comalloc(size_t, size_t*, void**);
|
||||||
is returned. For large arrays of pointers with poor locality, it
|
is returned. For large arrays of pointers with poor locality, it
|
||||||
may be worthwhile to sort this array before calling bulk_free.
|
may be worthwhile to sort this array before calling bulk_free.
|
||||||
*/
|
*/
|
||||||
size_t bulk_free(void**, size_t n_elements);
|
size_t bulk_free(void**, size_t n_elements);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pvalloc(size_t n);
|
pvalloc(size_t n);
|
||||||
Equivalent to valloc(minimum-page-that-holds(n)), that is,
|
Equivalent to valloc(minimum-page-that-holds(n)), that is,
|
||||||
round up n to nearest pagesize.
|
round up n to nearest pagesize.
|
||||||
*/
|
*/
|
||||||
void* pvalloc(size_t);
|
void* pvalloc(size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
malloc_trim(size_t pad);
|
malloc_trim(size_t pad);
|
||||||
|
@ -458,7 +455,7 @@ void* pvalloc(size_t);
|
||||||
|
|
||||||
Malloc_trim returns 1 if it actually released any memory, else 0.
|
Malloc_trim returns 1 if it actually released any memory, else 0.
|
||||||
*/
|
*/
|
||||||
int malloc_trim(size_t);
|
int malloc_trim(size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
malloc_stats();
|
malloc_stats();
|
||||||
|
@ -481,7 +478,7 @@ int malloc_trim(size_t);
|
||||||
|
|
||||||
malloc_stats is not compiled if NO_MALLOC_STATS is defined.
|
malloc_stats is not compiled if NO_MALLOC_STATS is defined.
|
||||||
*/
|
*/
|
||||||
void malloc_stats(void);
|
void malloc_stats(void);
|
||||||
|
|
||||||
#endif /* !ONLY_MSPACES */
|
#endif /* !ONLY_MSPACES */
|
||||||
|
|
||||||
|
@ -577,10 +574,8 @@ void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
|
||||||
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
|
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
|
||||||
void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize);
|
void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize);
|
||||||
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
|
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
|
||||||
void** mspace_independent_calloc(mspace msp, size_t n_elements,
|
void** mspace_independent_calloc(mspace msp, size_t n_elements, size_t elem_size, void* chunks[]);
|
||||||
size_t elem_size, void* chunks[]);
|
void** mspace_independent_comalloc(mspace msp, size_t n_elements, size_t sizes[], void* chunks[]);
|
||||||
void** mspace_independent_comalloc(mspace msp, size_t n_elements,
|
|
||||||
size_t sizes[], void* chunks[]);
|
|
||||||
size_t mspace_bulk_free(mspace msp, void**, size_t n_elements);
|
size_t mspace_bulk_free(mspace msp, void**, size_t n_elements);
|
||||||
size_t mspace_usable_size(const void* mem);
|
size_t mspace_usable_size(const void* mem);
|
||||||
void mspace_malloc_stats(mspace msp);
|
void mspace_malloc_stats(mspace msp);
|
||||||
|
@ -589,13 +584,11 @@ size_t mspace_footprint(mspace msp);
|
||||||
size_t mspace_max_footprint(mspace msp);
|
size_t mspace_max_footprint(mspace msp);
|
||||||
size_t mspace_footprint_limit(mspace msp);
|
size_t mspace_footprint_limit(mspace msp);
|
||||||
size_t mspace_set_footprint_limit(mspace msp, size_t bytes);
|
size_t mspace_set_footprint_limit(mspace msp, size_t bytes);
|
||||||
void mspace_inspect_all(mspace msp,
|
void mspace_inspect_all(mspace msp, void (*handler)(void*, void*, size_t, void*), void* arg);
|
||||||
void(*handler)(void *, void *, size_t, void*),
|
#endif /* MSPACES */
|
||||||
void* arg);
|
|
||||||
#endif /* MSPACES */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}; /* end of extern "C" */
|
}; /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MALLOC_280_H */
|
#endif /* MALLOC_280_H */
|
||||||
|
|
2
libc/include/string.h
Executable file → Normal file
2
libc/include/string.h
Executable file → Normal file
|
@ -1,8 +1,8 @@
|
||||||
#ifndef _STRING_H
|
#ifndef _STRING_H
|
||||||
#define _STRING_H 1
|
#define _STRING_H 1
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
int memcmp(const void*, const void*, size_t);
|
int memcmp(const void*, const void*, size_t);
|
||||||
void* memcpy(void* __restrict, const void* __restrict, size_t);
|
void* memcpy(void* __restrict, const void* __restrict, size_t);
|
||||||
|
|
91
libc/stdio/printf.c
Executable file → Normal file
91
libc/stdio/printf.c
Executable file → Normal file
|
@ -1,15 +1,14 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static bool print(const char* data, size_t length) {
|
static bool print(const char* data, size_t length) {
|
||||||
const unsigned char* bytes = (const unsigned char*) data;
|
const unsigned char* bytes = (const unsigned char*)data;
|
||||||
for (size_t i = 0; i < length; i++)
|
for (size_t i = 0; i < length; i++)
|
||||||
if(putchar(bytes[i]) == EOF)
|
if (putchar(bytes[i]) == EOF)
|
||||||
return false'
|
return false' return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf(const char* restrict format, ...) {
|
int printf(const char* restrict format, ...) {
|
||||||
|
@ -18,19 +17,19 @@ int printf(const char* restrict format, ...) {
|
||||||
|
|
||||||
int written = 0;
|
int written = 0;
|
||||||
|
|
||||||
while(*format != '\0') {
|
while (*format != '\0') {
|
||||||
size_t maxrem = INT_MAX - writen;
|
size_t maxrem = INT_MAX - writen;
|
||||||
|
|
||||||
if(format[0] != '%' || format[1] == '%') {
|
if (format[0] != '%' || format[1] == '%') {
|
||||||
if(format[0] == '%')
|
if (format[0] == '%')
|
||||||
format++;
|
format++;
|
||||||
size_t amount = 1;
|
size_t amount = 1;
|
||||||
|
|
||||||
while (format[amount] && format[amount] != '%')
|
while (format[amount] && format[amount] != '%')
|
||||||
amount++;
|
amount++;
|
||||||
|
|
||||||
if(maxrem < amount) {
|
if (maxrem < amount) {
|
||||||
//TODO: Set an OVERFLOW error
|
// TODO: Set an OVERFLOW error
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,48 +43,48 @@ int printf(const char* restrict format, ...) {
|
||||||
|
|
||||||
const char* first_format = format++;
|
const char* first_format = format++;
|
||||||
|
|
||||||
switch(*format) {
|
switch (*format) {
|
||||||
case 'c':
|
case 'c':
|
||||||
format++;
|
format++;
|
||||||
char c = (char) va_arg(parameters, int);
|
char c = (char)va_arg(parameters, int);
|
||||||
if(!maxrem) {
|
if (!maxrem) {
|
||||||
//TODO: Set OVERFLOW
|
// TODO: Set OVERFLOW
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!print(&c, sizeof(c)))
|
if (!print(&c, sizeof(c)))
|
||||||
return -1;
|
return -1;
|
||||||
written++;
|
written++;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
format++;
|
format++;
|
||||||
|
|
||||||
const char* str = va_arg(parameters, const char*);
|
const char* str = va_arg(parameters, const char*);
|
||||||
size_t len = strlen(str);
|
size_t len = strlen(str);
|
||||||
|
|
||||||
if(maxrem < len) {
|
if (maxrem < len) {
|
||||||
//TODO: Set OVERFLOW
|
// TODO: Set OVERFLOW
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!print(str, len))
|
if (!print(str, len))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
written += len;
|
written += len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
format = first_format;
|
format = first_format;
|
||||||
size_t len = strlen(format);
|
size_t len = strlen(format);
|
||||||
if(maxrem < len) {
|
if (maxrem < len) {
|
||||||
//TODO: Set OVERFLOW
|
// TODO: Set OVERFLOW
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!print(format, len))
|
if (!print(format, len))
|
||||||
return -1;
|
return -1;
|
||||||
written += len;
|
written += len;
|
||||||
format += len;
|
format += len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
libc/stdio/putchar.c
Executable file → Normal file
4
libc/stdio/putchar.c
Executable file → Normal file
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
int putchar(int ic) {
|
int putchar(int ic) {
|
||||||
#if defined(__is_libk)
|
#if defined(__is_libk)
|
||||||
char c = (char) ic;
|
char c = (char)ic;
|
||||||
term_write(&c, sizeof(c));
|
term_write(&c, sizeof(c));
|
||||||
#else
|
#else
|
||||||
//TODO: Implement stdio & the write call
|
// TODO: Implement stdio & the write call
|
||||||
#endif
|
#endif
|
||||||
return ic;
|
return ic;
|
||||||
}
|
}
|
14
libc/stdlib/abort.c
Executable file → Normal file
14
libc/stdlib/abort.c
Executable file → Normal file
|
@ -1,15 +1,15 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
__attribute__((__noreturn__))
|
__attribute__((__noreturn__)) void abort(void) {
|
||||||
void abort(void) {
|
|
||||||
|
|
||||||
#if defined(__is_libk)
|
#if defined(__is_libk)
|
||||||
//TODO: Kernel panic.
|
// TODO: Kernel panic.
|
||||||
printf(">>PANIC<<<\n abort() panicked!\n");
|
printf(">>PANIC<<<\n abort() panicked!\n");
|
||||||
#else
|
#else
|
||||||
printf("abort() called\n");
|
printf("abort() called\n");
|
||||||
#endif
|
#endif
|
||||||
while(1) {}
|
while (1) {
|
||||||
__builtin_unreachable();
|
}
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
4
libc/string/memcmp.c
Executable file → Normal file
4
libc/string/memcmp.c
Executable file → Normal file
|
@ -1,8 +1,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int memcmp(const void* aptr, const void* bptr, size_t size_ {
|
int memcmp(const void* aptr, const void* bptr, size_t size_ {
|
||||||
const unsigned char* a = (const unsigned char*) aptr;
|
const unsigned char* a = (const unsigned char*)aptr;
|
||||||
const unsigned char* b = (const unsigned char*) bptr;
|
const unsigned char* b = (const unsigned char*)bptr;
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
if(a[i] < b[i]
|
if(a[i] < b[i]
|
||||||
|
|
12
libc/string/memmove.c
Executable file → Normal file
12
libc/string/memmove.c
Executable file → Normal file
|
@ -1,14 +1,14 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
||||||
unsigned char* dst = (unsigned char*) dstptr;
|
unsigned char* dst = (unsigned char*)dstptr;
|
||||||
const unsigned char* stc = (const unsigned char*) srcptr;
|
const unsigned char* stc = (const unsigned char*)srcptr;
|
||||||
if(dst < src) {
|
if (dst < src) {
|
||||||
for(size_t i = o; i < size; i++)
|
for (size_t i = o; i < size; i++)
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
} else {
|
} else {
|
||||||
for(size_t i = size; i != 0; i--)
|
for (size_t i = size; i != 0; i--)
|
||||||
dst[i-1] = src[i-1];
|
dst[i - 1] = src[i - 1];
|
||||||
}
|
}
|
||||||
return dstptr;
|
return dstptr;
|
||||||
}
|
}
|
6
libc/string/memset.c
Executable file → Normal file
6
libc/string/memset.c
Executable file → Normal file
|
@ -1,8 +1,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void* memset(void* bufptr, int value, size_t size) {
|
void* memset(void* bufptr, int value, size_t size) {
|
||||||
unsigned char* buf = (unsigned char*) bufptr;
|
unsigned char* buf = (unsigned char*)bufptr;
|
||||||
for(size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buf[i] = (unsigned char) value;
|
buf[i] = (unsigned char)value;
|
||||||
return bufptr;
|
return bufptr;
|
||||||
}
|
}
|
3
libc/string/strlen.c
Executable file → Normal file
3
libc/string/strlen.c
Executable file → Normal file
|
@ -3,6 +3,5 @@
|
||||||
size_t strlen(const char* str) {
|
size_t strlen(const char* str) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
while (str[len])
|
while (str[len])
|
||||||
len++
|
len++ return len;
|
||||||
return len;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user