getting rid of shit to focus more on kernel, drivers, and real stuff
This commit is contained in:
19
makefile
19
makefile
@@ -9,19 +9,15 @@ AR = i386-elf-7.5.0-Linux-x86_64/bin/i386-elf-ar
|
||||
SRC_DIR = src
|
||||
KERNEL_DIR = $(SRC_DIR)/kernel
|
||||
LIBC_DIR = $(SRC_DIR)/libc
|
||||
UTILS_DIR = $(SRC_DIR)/utils
|
||||
DRIVERS_DIR = $(SRC_DIR)/drivers
|
||||
PROGRAMS_DIR = $(SRC_DIR)/programs
|
||||
INCLUDE_DIR = include
|
||||
FONTS_DIR = $(INCLUDE_DIR)/fonts
|
||||
OBJ_DIR = build
|
||||
|
||||
C_SOURCES = $(wildcard $(KERNEL_DIR)/*.c) $(wildcard $(LIBC_DIR)/*.c) $(wildcard $(UTILS_DIR)/*.c) $(wildcard $(DRIVERS_DIR)/*.c)
|
||||
ASM_SOURCES = $(wildcard $(KERNEL_DIR)/*.s) $(wildcard $(LIBC_DIR)/*.s) $(wildcard $(UTILS_DIR)/*.s) $(wildcard $(DRIVERS_DIR)/*.s)
|
||||
PROGRAM_SOURCES = $(wildcard $(PROGRAMS_DIR)/*.c)
|
||||
C_SOURCES = $(wildcard $(KERNEL_DIR)/*.c) $(wildcard $(LIBC_DIR)/*.c) $(wildcard $(DRIVERS_DIR)/*.c)
|
||||
ASM_SOURCES = $(wildcard $(KERNEL_DIR)/*.s) $(wildcard $(LIBC_DIR)/*.s) $(wildcard $(DRIVERS_DIR)/*.s)
|
||||
|
||||
OBJECTS = $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(C_SOURCES:.c=.o) $(ASM_SOURCES:.s=.o))
|
||||
PROGRAM_OBJECTS = $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(PROGRAM_SOURCES:.c=.o))
|
||||
|
||||
TOOLCHAIN_SRC = https://newos.org/toolchains/i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
TOOLCHAIN_FILE = i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
@@ -29,22 +25,15 @@ TOOLCHAIN_FILE = i386-elf-7.5.0-Linux-x86_64.tar.xz
|
||||
FONT_OBJ = $(OBJ_DIR)/fonts/viscii10-8x16.o
|
||||
FONT_SRC = $(FONTS_DIR)/viscii10-8x16.psfu
|
||||
|
||||
all: $(OBJ_DIR) kernel.elf programs
|
||||
all: $(OBJ_DIR) kernel.elf
|
||||
|
||||
$(OBJ_DIR):
|
||||
mkdir -p $(OBJ_DIR)
|
||||
mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/utils $(OBJ_DIR)/drivers $(OBJ_DIR)/fonts $(OBJ_DIR)/programs
|
||||
mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/drivers $(OBJ_DIR)/fonts $(OBJ_DIR)/programs
|
||||
|
||||
kernel.elf: $(OBJECTS) $(FONT_OBJ)
|
||||
$(LD) $(LDFLAGS) $(OBJECTS) $(FONT_OBJ) -o kernel.elf
|
||||
|
||||
programs: $(PROGRAM_OBJECTS)
|
||||
@mkdir -p $(SRC_DIR)/initrd
|
||||
@for prog in $(PROGRAM_OBJECTS); do \
|
||||
base=$$(basename $$prog .o); \
|
||||
$(LD) -melf_i386 -T program.ld $$prog -o $(SRC_DIR)/initrd/$$base.bin; \
|
||||
done
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
10
program.ld
10
program.ld
@@ -1,10 +0,0 @@
|
||||
OUTPUT_FORMAT(binary)
|
||||
ENTRY(main)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x1000;
|
||||
.text : { *(.text*) }
|
||||
.data : { *(.data*) }
|
||||
.bss : { *(.bss*) }
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
@@ -1 +0,0 @@
|
||||
-[------->+<]>-.-[->+++++<]>++.+++++++..+++.[--->+<]>-----.---[->+++<]>.-[--->+<]>---.+++.------.--------.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,8 +0,0 @@
|
||||
Subfolder support!
|
||||
|
||||
I am making a bit of scurity improvements but clearly it has no meaing here.
|
||||
The real meanng is the tellin of the Genesis; a true work of art. So many
|
||||
cool stuff here!! Look, there are functions, comands, bits and bytes, conditions,
|
||||
and lgorithms. What a fantastic world! But after all it stays formless and empty.
|
||||
|
||||
1:5:1 1:1:1 7:8:1 1:7:3 1:4:3 2:1:2
|
||||
@@ -1,37 +0,0 @@
|
||||
***********************
|
||||
* Welcome to BlankOS! *
|
||||
***********************
|
||||
|
||||
Congratulations, you've entered my small world!
|
||||
|
||||
You can try all the commands, try tweaking stuff like explained
|
||||
in the DEVELOPERS.md file, and even contribute if you got the
|
||||
guts. lol.
|
||||
|
||||
Don't look too much at the code, it's badly designed, but hey,
|
||||
that's my first OS project so I find it kinda cool.
|
||||
|
||||
There's no paging, ring 3, processes... I am not smart enough
|
||||
for all this modern stuff. Let's keep it simple and stay in
|
||||
ring0, without processes, maybe one day there'll be more
|
||||
advanced features, but not today.
|
||||
|
||||
** Why am I doing this?
|
||||
|
||||
I wanted to explore the world of low-level programing.
|
||||
As I had only 1 year of experience in C, it was super challenging
|
||||
especially at the beginning, and I needed much time to understand
|
||||
even the most basic things around OSDev.
|
||||
|
||||
I'll backup the project on archival media once it'll be at a good
|
||||
enough point; I think it's cool to leave a trace of my passage on
|
||||
Earth.
|
||||
|
||||
** Easter eggs
|
||||
|
||||
To make the exploration a bit funnier, I hid some easter eggs
|
||||
around. You can try to find them if you have time to lose.
|
||||
|
||||
** Ravtzn
|
||||
|
||||
Jub xabjf? Znlor fbzrguvat'f uvqqra va gurer...
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "multiboot2.h"
|
||||
#include "kheap.h"
|
||||
#include "initrd.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../libc/crypto.h"
|
||||
|
||||
void kmain(multiboot2_info *mb_info)
|
||||
@@ -126,6 +125,6 @@ void kmain(multiboot2_info *mb_info)
|
||||
|
||||
timer_install();
|
||||
keyboard_install();
|
||||
printf("[kernel] spawning shell...\n");
|
||||
shell_install();
|
||||
printf("Nothing to do, halting...");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
// Basic shell and commands kernel module
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include <stdint.h>
|
||||
#include "../drivers/rtc.h"
|
||||
#include "kmain.h"
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
#define MAX_COMMANDS 64
|
||||
#define MAX_ARGS 64
|
||||
|
||||
// Splash screen: esthetic stuff.
|
||||
char* motd[] =
|
||||
{
|
||||
"I should be root, really.",
|
||||
"Not watching you!",
|
||||
"Now in 2D!",
|
||||
"Supercalifragilisticexpialidocious!",
|
||||
"Tylko jedno w glowie mam!",
|
||||
"Greetings, magic poppy!",
|
||||
"I'm stuck in this kernel's shell, get me out!",
|
||||
"And now, solve that equation!",
|
||||
"Powered by TCC Incorporated.",
|
||||
"Compiled at 69, CoquaineBaule Ave.",
|
||||
"Shouldn't we be, uh, doing something?",
|
||||
"We are the florists, we pick the plants!",
|
||||
"Lalalalala, I pick the plants!",
|
||||
"Woah, we're half-way there...",
|
||||
"The CROU will never die!",
|
||||
"Technoblade never dies!",
|
||||
"Hi. My name is Guitar.",
|
||||
"space station No. 9",
|
||||
"May the orange juice be with you !",
|
||||
"Bloody grated carrots!",
|
||||
"Good night, kiddos...",
|
||||
"I like trains",
|
||||
"I fear planes",
|
||||
"Bruteforce.exe",
|
||||
"Ohayogozaimasu!",
|
||||
};
|
||||
|
||||
int motd_size = sizeof(motd)/sizeof(motd[0]);
|
||||
|
||||
bool do_splash = true;
|
||||
|
||||
void splash()
|
||||
{
|
||||
int random = randint(time_seed());
|
||||
char* motd_pick = motd[random%motd_size];
|
||||
cowsay(motd_pick, red, black);
|
||||
puts(" ");
|
||||
colorputs("blankOS", black, white);
|
||||
puts(" ");
|
||||
colorputs(BLANK_VERSION, red, black);
|
||||
puts("\n");
|
||||
|
||||
|
||||
puts(" Time: ");
|
||||
rtc_time_t time;
|
||||
rtc_read_time(&time);
|
||||
print_time(&time);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
typedef void (*command_func_t)(int argc, char *argv[]);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* name;
|
||||
command_func_t function;
|
||||
} shell_command_t;
|
||||
|
||||
shell_command_t shell_commands[MAX_COMMANDS];
|
||||
int command_count = 0;
|
||||
|
||||
void register_command(const char* name, command_func_t function)
|
||||
{
|
||||
if (command_count < MAX_COMMANDS)
|
||||
{
|
||||
shell_commands[command_count].name = name;
|
||||
shell_commands[command_count].function = function;
|
||||
command_count++;
|
||||
}
|
||||
}
|
||||
|
||||
command_func_t find_command(const char* name)
|
||||
{
|
||||
for (int i=0; i < command_count; i++)
|
||||
{
|
||||
if (strcmp(name, shell_commands[i].name) == 0)
|
||||
return shell_commands[i].function;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_input(char* input, char* argv[], int max_args)
|
||||
{
|
||||
int argc = 0;
|
||||
char* token = strtok(input, " ");
|
||||
while (token != NULL && argc < max_args - 1)
|
||||
{
|
||||
argv[argc++] = token;
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
return argc;
|
||||
}
|
||||
|
||||
void shell_install()
|
||||
{
|
||||
if (do_splash == true)
|
||||
{
|
||||
do_splash = false;
|
||||
splash();
|
||||
}
|
||||
|
||||
register_command("help", program_help);
|
||||
register_command("panic", program_panic);
|
||||
register_command("words", program_words);
|
||||
register_command("primes", program_primes);
|
||||
register_command("rainbow", program_rainbow);
|
||||
register_command("clear", program_clear);
|
||||
register_command("math", program_math);
|
||||
register_command("bf", program_bf);
|
||||
register_command("uptime", program_uptime);
|
||||
register_command("echo", program_echo);
|
||||
register_command("sysinfo", program_sysinfo);
|
||||
register_command("conway", program_conway);
|
||||
register_command("rot13", program_rot13);
|
||||
register_command("morse", program_morse);
|
||||
register_command("cowsay", program_cowsay);
|
||||
register_command("time", program_time);
|
||||
register_command("read", program_read);
|
||||
register_command("reboot", program_reboot);
|
||||
register_command("pi", program_pi);
|
||||
register_command("ls", program_ls);
|
||||
register_command("cat", program_cat);
|
||||
register_command("bmp", program_bmp);
|
||||
register_command("lspci", program_lspci);
|
||||
register_command("naval", program_navalbattle);
|
||||
register_command("snake", program_snake);
|
||||
register_command("exec", program_exec);
|
||||
register_command("uhex", program_uhex);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
char* argv[MAX_ARGS];
|
||||
|
||||
// Prompt
|
||||
colorputs("root", blue, black);
|
||||
colorputs("@", white, black);
|
||||
colorputs("blankos", green, black);
|
||||
colorputs("~$ ", white, black);
|
||||
|
||||
get_input(input_buffer, BUFFER_SIZE);
|
||||
puts("\n");
|
||||
|
||||
int argc = parse_input(input_buffer, argv, MAX_ARGS);
|
||||
|
||||
if (argc == 0) continue;
|
||||
|
||||
command_func_t command = find_command(argv[0]);
|
||||
if (command)
|
||||
{
|
||||
command(argc, argv);
|
||||
} else {
|
||||
printf("Unknown command %s\n", argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
void user_syscall(int syscall_no) {
|
||||
asm volatile ("mov %0, %%eax" : : "r"(syscall_no));
|
||||
asm volatile ("int $0x80");
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
user_syscall(1);
|
||||
return;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
// Simple brainfuck interpreter program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/kmain.h"
|
||||
#include "../kernel/initrd.h"
|
||||
|
||||
#define BUF_SIZE 256
|
||||
|
||||
void brainfuck(char* input)
|
||||
{
|
||||
unsigned char tape[30000] = {0};
|
||||
unsigned char* ptr = tape;
|
||||
char current_char;
|
||||
size_t i;
|
||||
size_t loop;
|
||||
|
||||
for (i=0; input[i] != 0; i++)
|
||||
{
|
||||
current_char = input[i];
|
||||
if (current_char == '>') {
|
||||
++ptr;
|
||||
} else if (current_char == '<') {
|
||||
--ptr;
|
||||
} else if (current_char == '+') {
|
||||
++*ptr;
|
||||
} else if (current_char == '-') {
|
||||
--*ptr;
|
||||
} else if (current_char == '.') {
|
||||
putc(*ptr);
|
||||
} else if (current_char == ',') {
|
||||
*ptr = keyboard_getchar();
|
||||
} else if (current_char == '[') {
|
||||
continue;
|
||||
} else if (current_char == ']' && *ptr) {
|
||||
loop = 1;
|
||||
while (loop > 0)
|
||||
{
|
||||
current_char = input[--i];
|
||||
if (current_char == '[') {
|
||||
loop--;
|
||||
} else if (current_char == ']') {
|
||||
loop++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void program_bf(int argc, char* argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
char input_buffer[BUF_SIZE];
|
||||
puts("Brainfuck code? ");
|
||||
get_input(input_buffer, BUF_SIZE);
|
||||
brainfuck(input_buffer);
|
||||
puts("\n");
|
||||
} else if (argc == 2) {
|
||||
// Read file content into buffer, then interpret it
|
||||
char input_buffer[BUF_SIZE];
|
||||
int read = tar_file_to_buffer((uint8_t*)initrd_addr, argv[1], input_buffer);
|
||||
if (read == 0)
|
||||
{
|
||||
brainfuck(input_buffer);
|
||||
puts("\n");
|
||||
} else {
|
||||
printf("Could not find file '%s'\n", argv[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// Bitmap image renderer
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/kmain.h"
|
||||
#include <stdint.h>
|
||||
#include "../kernel/initrd.h"
|
||||
#include "../drivers/framebuffer.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../drivers/serial.h"
|
||||
#include "../kernel/kheap.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
} BMPHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t biSize;
|
||||
int32_t biWidth;
|
||||
int32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
int32_t biXPelsPerMeter;
|
||||
int32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
} BMPInfoHeader;
|
||||
#pragma pack(pop)
|
||||
|
||||
void display_bmp(uint32_t* fb, int pitch, int bpp, uint8_t* initrd, const char* filename)
|
||||
{
|
||||
uint32_t buf_size = tar_get_file_size(initrd, filename);
|
||||
char* buffer = (char*)malloc(buf_size);
|
||||
int file_status = tar_file_to_buffer(initrd, filename, buffer);
|
||||
|
||||
if (file_status != 0)
|
||||
{
|
||||
printf("Error loading file '%s'\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
BMPHeader* bmp_header = (BMPHeader*)buffer;
|
||||
BMPInfoHeader* bmp_info = (BMPInfoHeader*) (buffer+sizeof(BMPHeader));
|
||||
|
||||
if (bmp_header->bfType != 0x4D42)
|
||||
{
|
||||
printf("'%s' is not a valid BMP file\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
int width = bmp_info->biWidth;
|
||||
int height = bmp_info->biHeight;
|
||||
int pixel_offset = bmp_header->bfOffBits;
|
||||
|
||||
printf("%d-bit BMP, width: %d, height: %d, pixel offset: %d\n", bmp_info->biBitCount, bmp_info->biWidth, bmp_info->biHeight, (int)bmp_header->bfOffBits);
|
||||
erase_cursor();
|
||||
uint8_t* pixel_data = (uint8_t*)(buffer + pixel_offset);
|
||||
|
||||
int cursor_y = (get_cursor_y()+1)*16;
|
||||
serial_printf(3, "cursor_y=%d\n", cursor_y);
|
||||
|
||||
for (int y=cursor_y; y<height+cursor_y; y++)
|
||||
{
|
||||
for (int x=0; x<width; x++)
|
||||
{
|
||||
int index = (x+(height-y-1+cursor_y)*width)*3;
|
||||
uint8_t blue = pixel_data[index];
|
||||
uint8_t green = pixel_data[index+1];
|
||||
uint8_t red = pixel_data[index+2];
|
||||
|
||||
uint32_t color = (0xFF << 24) | (red << 16) | (green << 8) | blue;
|
||||
putpixel(fb, pitch, bpp, x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
// Update cursor pos after image drawing
|
||||
move_cursor(get_cursor_x(), get_cursor_y()+(height/16)+2);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void program_bmp(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
puts("Usage: bmp <file>\n");
|
||||
return;
|
||||
}
|
||||
display_bmp(framebuffer, pitch, bpp, (uint8_t*)initrd_addr, argv[1]);
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
// Cipher programs
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "ciphers.h"
|
||||
#include "../libc/string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void rot13(char* input, char* output)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (input[i] != '\0')
|
||||
{
|
||||
char c = input[i];
|
||||
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
output[i] = ((c - 'a' + 13) % 26) + 'a';
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
output[i] = ((c - 'A' + 13) % 26) + 'A';
|
||||
} else {
|
||||
output[i] = c;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
output[i] = '\0';
|
||||
}
|
||||
|
||||
void program_rot13(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <string>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char input_buffer[BUFFER_SIZE] = {0};
|
||||
char output[BUFFER_SIZE] = {0};
|
||||
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
strcat(input_buffer, argv[i]);
|
||||
if (i<argc-1)
|
||||
{
|
||||
strcat(input_buffer, " ");
|
||||
}
|
||||
}
|
||||
rot13(input_buffer, output);
|
||||
printf("%s\n", output);
|
||||
}
|
||||
|
||||
const char* morse_alphabet[] = {
|
||||
".-", // A
|
||||
"-...", // B
|
||||
"-.-.", // C
|
||||
"-..", // D
|
||||
".", // E
|
||||
"..-.", // F
|
||||
"--.", // G
|
||||
"....", // H
|
||||
"..", // I
|
||||
".---", // J
|
||||
"-.-", // K
|
||||
".-..", // L
|
||||
"--", // M
|
||||
"-.", // N
|
||||
"---", // O
|
||||
".--.", // P
|
||||
"--.-", // Q
|
||||
".-.", // R
|
||||
"...", // S
|
||||
"-", // T
|
||||
"..-", // U
|
||||
"...-", // V
|
||||
".--", // W
|
||||
"-..-", // X
|
||||
"-.--", // Y
|
||||
"--.." // Z
|
||||
};
|
||||
|
||||
const char* morse_digits[] = {
|
||||
"-----", // 0
|
||||
".----", // 1
|
||||
"..---", // 2
|
||||
"...--", // 3
|
||||
"....-", // 4
|
||||
".....", // 5
|
||||
"-....", // 6
|
||||
"--...", // 7
|
||||
"---..", // 8
|
||||
"----." // 9
|
||||
};
|
||||
|
||||
void to_morse(const char* input, char* output) {
|
||||
int i = 0;
|
||||
int pos = 0;
|
||||
|
||||
while (input[i] != '\0') {
|
||||
char c = input[i];
|
||||
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
const char* morse_code = morse_alphabet[c - 'a'];
|
||||
int j = 0;
|
||||
while (morse_code[j] != '\0') {
|
||||
output[pos++] = morse_code[j++];
|
||||
}
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
const char* morse_code = morse_alphabet[c - 'A'];
|
||||
int j = 0;
|
||||
while (morse_code[j] != '\0') {
|
||||
output[pos++] = morse_code[j++];
|
||||
}
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
const char* morse_code = morse_digits[c - '0'];
|
||||
int j = 0;
|
||||
while (morse_code[j] != '\0') {
|
||||
output[pos++] = morse_code[j++];
|
||||
}
|
||||
} else if (c == ' ') {
|
||||
output[pos++] = ' ';
|
||||
}
|
||||
|
||||
output[pos++] = ' ';
|
||||
i++;
|
||||
}
|
||||
|
||||
if (pos > 0) {
|
||||
output[pos - 1] = '\0';
|
||||
} else {
|
||||
output[pos] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void program_morse(int argc, char* argv[]) {
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <string>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char output[512];
|
||||
char message[BUFFER_SIZE];
|
||||
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
strcat(message, argv[i]);
|
||||
if (i < argc-1)
|
||||
{
|
||||
strcat(message, " ");
|
||||
}
|
||||
}
|
||||
|
||||
to_morse(message, output);
|
||||
printf("%s\n", output);
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Cipher programs header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CIPHERS_H
|
||||
#define CIPHERS_H
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
#endif
|
||||
@@ -1,136 +0,0 @@
|
||||
// Conway's Game of Life program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "conway.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include <stdint.h>
|
||||
#include "../drivers/serial.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
void print_grid(const unsigned char grid[X][Y])
|
||||
{
|
||||
clear();
|
||||
for (int i=0; i<X; i++)
|
||||
{
|
||||
for (int j=0; j<Y; j++)
|
||||
{
|
||||
if (grid[i][j] == LIVE) {
|
||||
putc(35);
|
||||
} else {
|
||||
putc(32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count_live_neighbors(const unsigned char grid[X][Y], int i, int j)
|
||||
{
|
||||
int live_neighbors = 0;
|
||||
|
||||
for (int x=-1; x<=1; x++)
|
||||
{
|
||||
for (int y=-1; y<=1; y++)
|
||||
{
|
||||
if (x==0 && y==0) continue;
|
||||
|
||||
int ni = i+x;
|
||||
int nj = j+y;
|
||||
|
||||
if (ni >= 0 && ni < X && nj >= 0)
|
||||
{
|
||||
if (grid[ni][nj] == LIVE) live_neighbors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return live_neighbors;
|
||||
}
|
||||
|
||||
void grid_new_generation(unsigned char grid[X][Y], unsigned char temp[X][Y])
|
||||
{
|
||||
for (int i=0; i<X; i++)
|
||||
{
|
||||
for (int j=0; j<Y; j++)
|
||||
{
|
||||
int cell = grid[i][j];
|
||||
int live_neighbors = count_live_neighbors(grid, i, j);
|
||||
|
||||
if (cell == LIVE)
|
||||
{
|
||||
switch(live_neighbors)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
temp[i][j] = LIVE;
|
||||
break;
|
||||
default:
|
||||
temp[i][j] = DEAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cell == DEAD && live_neighbors == 3)
|
||||
{
|
||||
temp[i][j] = LIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<X; i++)
|
||||
{
|
||||
for (int j=0; j<Y; j++)
|
||||
{
|
||||
grid[i][j] = temp[i][j];
|
||||
temp[i][j] = DEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void soup(unsigned char grid[X][Y])
|
||||
{
|
||||
srand(global_ticks);
|
||||
for (int i=0; i<X; i++)
|
||||
{
|
||||
for (int j=0; j<Y; j++)
|
||||
{
|
||||
grid[i][j] = rand_float() > SOUP_PROB ? LIVE : DEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void program_conway(int argc, char* argv[])
|
||||
{
|
||||
clear();
|
||||
unsigned char grid[X][Y] = {0};
|
||||
unsigned char temp[X][Y] = {0};
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
soup(grid);
|
||||
} else if (argc == 2 && strcmp(argv[1], "-g") == 0) {
|
||||
grid[1][2] = LIVE;
|
||||
grid[2][3] = LIVE;
|
||||
grid[3][1] = LIVE;
|
||||
grid[3][2] = LIVE;
|
||||
grid[3][3] = LIVE;
|
||||
} else if (argc == 2 && strcmp(argv[1], "-l") == 0) {
|
||||
grid[10][3] = LIVE; grid[10][4] = LIVE; grid[10][5] = LIVE; grid[10][6] = LIVE;
|
||||
grid[11][2] = LIVE; grid[11][6] = LIVE;
|
||||
grid[12][6] = LIVE;
|
||||
grid[13][2] = LIVE; grid[13][5] = LIVE;
|
||||
}
|
||||
|
||||
print_grid(grid);
|
||||
puts("generation 0");
|
||||
for (int i=1; i<GENERATIONS; i++)
|
||||
{
|
||||
grid_new_generation(grid, temp);
|
||||
delay(DELAY);
|
||||
clear();
|
||||
print_grid(grid);
|
||||
printf("generation %d", i);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// Conway's Game of Life program header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef CONWAY_H
|
||||
#define CONWAY_H
|
||||
|
||||
#define X 66
|
||||
#define Y 240
|
||||
|
||||
#define GENERATIONS 100
|
||||
#define DEAD 0
|
||||
#define LIVE 1
|
||||
#define SOUP_PROB 0.7
|
||||
#define DELAY 10
|
||||
|
||||
void print_grid(const unsigned char grid[X][Y]);
|
||||
int count_live_neighbors(const unsigned char grid[X][Y], int i, int j);
|
||||
void grid_new_generation(unsigned char grid[X][Y], unsigned char temp[X][Y]);
|
||||
void soup(unsigned char grid[X][Y]);
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
// Cowsay-like program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
#define MAX_MSG_LEN 128
|
||||
|
||||
const char* cow =
|
||||
" \\ ^__^\n"
|
||||
" \\ (oo)\\_______\n"
|
||||
" (__)\\ )\\/\\\n"
|
||||
" ||----w |\n"
|
||||
" || ||\n";
|
||||
|
||||
void print_bubble(const char* message)
|
||||
{
|
||||
int len = strlen(message);
|
||||
puts(" ");
|
||||
for (int i=0; i<len+2; i++)
|
||||
{
|
||||
puts("_");
|
||||
}
|
||||
puts("\n");
|
||||
|
||||
printf("< %s >\n", message);
|
||||
|
||||
puts(" ");
|
||||
for (int i=0; i<len+2; i++)
|
||||
{
|
||||
puts("-");
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void cowsay(char* msg, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
print_bubble(msg);
|
||||
colorputs(cow, fg, bg);
|
||||
}
|
||||
|
||||
void program_cowsay(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <message>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char message[MAX_MSG_LEN];
|
||||
message[0] = '\0';
|
||||
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
if (strlen(message) + strlen(argv[i]) + 1 < MAX_MSG_LEN)
|
||||
{
|
||||
strcat(message, argv[i]);
|
||||
if (i < argc-1)
|
||||
{
|
||||
strcat(message, " ");
|
||||
}
|
||||
} else {
|
||||
puts("Too long message.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
print_bubble(message);
|
||||
printf("%s", cow);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Filesystem utilities (for initrd)
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/initrd.h"
|
||||
#include "../kernel/kmain.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
void program_ls(int argc, char* argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
ls_initrd((uint8_t*)initrd_addr, 0);
|
||||
} else if (argc == 2 && strcmp(argv[1], "-l") == 0) {
|
||||
ls_initrd((uint8_t*)initrd_addr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Basic cat just to read, no concatenation here
|
||||
void program_cat(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
puts("Usage: cat <file>\n");
|
||||
return;
|
||||
}
|
||||
cat_initrd((uint8_t*)initrd_addr, argv[1]);
|
||||
}
|
||||
245
src/utils/math.c
245
src/utils/math.c
@@ -1,245 +0,0 @@
|
||||
// Basic math expression lexer and parser program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/ctype.h"
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TOKEN_NUMBER,
|
||||
TOKEN_PLUS,
|
||||
TOKEN_MINUS,
|
||||
TOKEN_MULTIPLY,
|
||||
TOKEN_DIVIDE,
|
||||
TOKEN_LPAREN,
|
||||
TOKEN_RPAREN,
|
||||
TOKEN_END
|
||||
} TokenType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TokenType type;
|
||||
double value;
|
||||
} Token;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *text;
|
||||
size_t pos;
|
||||
Token current_token;
|
||||
} Lexer;
|
||||
|
||||
void lexer_init(Lexer *lexer, const char *text)
|
||||
{
|
||||
lexer->text = text;
|
||||
lexer->pos = 0;
|
||||
lexer->current_token.type = TOKEN_END;
|
||||
lexer->current_token.value = 0;
|
||||
}
|
||||
|
||||
void lexer_advance(Lexer *lexer)
|
||||
{
|
||||
lexer->pos++;
|
||||
}
|
||||
|
||||
char lexer_peek(const Lexer *lexer)
|
||||
{
|
||||
return lexer->text[lexer->pos];
|
||||
}
|
||||
|
||||
bool lexer_is_at_end(const Lexer *lexer)
|
||||
{
|
||||
return lexer->text[lexer->pos] == '\0';
|
||||
}
|
||||
|
||||
Token lexer_get_next_token(Lexer *lexer)
|
||||
{
|
||||
while (!lexer_is_at_end(lexer))
|
||||
{
|
||||
char current_char = lexer_peek(lexer);
|
||||
|
||||
if (isspace(current_char)) {
|
||||
lexer_advance(lexer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isdigit(current_char)) {
|
||||
double value = 0;
|
||||
while (isdigit(current_char))
|
||||
{
|
||||
value = value * 10 + (current_char - '0');
|
||||
lexer_advance(lexer);
|
||||
current_char = lexer_peek(lexer);
|
||||
}
|
||||
if (current_char == '.')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
double decimal_place = 0.1;
|
||||
while (isdigit(lexer_peek(lexer)))
|
||||
{
|
||||
value += decimal_place * (lexer_peek(lexer)-'0');
|
||||
decimal_place *= 0.1;
|
||||
lexer_advance(lexer);
|
||||
}
|
||||
}
|
||||
lexer->current_token.type = TOKEN_NUMBER;
|
||||
lexer->current_token.value = value;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == '+')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_PLUS;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == '-')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_MINUS;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == '*')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_MULTIPLY;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == '/')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_DIVIDE;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == '(')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_LPAREN;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
if (current_char == ')')
|
||||
{
|
||||
lexer_advance(lexer);
|
||||
lexer->current_token.type = TOKEN_RPAREN;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
printf("\nUnknown character %c\n", current_char);
|
||||
shell_install();
|
||||
}
|
||||
|
||||
lexer->current_token.type = TOKEN_END;
|
||||
return lexer->current_token;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Lexer lexer;
|
||||
Token current_token;
|
||||
} Parser;
|
||||
|
||||
void parser_init(Parser *parser, const char *text)
|
||||
{
|
||||
lexer_init(&parser->lexer, text);
|
||||
parser->current_token = lexer_get_next_token(&parser->lexer);
|
||||
}
|
||||
|
||||
void parser_eat(Parser *parser, TokenType type)
|
||||
{
|
||||
if (parser->current_token.type == type)
|
||||
{
|
||||
parser->current_token = lexer_get_next_token(&parser->lexer);
|
||||
} else {
|
||||
printf("\nUnexpected token %d\n", parser->current_token.type);
|
||||
shell_install();
|
||||
}
|
||||
}
|
||||
|
||||
double parser_factor(Parser *parser);
|
||||
double parser_term(Parser *parser);
|
||||
double parser_expression(Parser *parser);
|
||||
|
||||
double parser_factor(Parser *parser)
|
||||
{
|
||||
Token token = parser->current_token;
|
||||
if (token.type == TOKEN_NUMBER)
|
||||
{
|
||||
parser_eat(parser, TOKEN_NUMBER);
|
||||
return token.value;
|
||||
} else if (token.type == TOKEN_LPAREN) {
|
||||
parser_eat(parser, TOKEN_LPAREN);
|
||||
double result = parser_expression(parser);
|
||||
parser_eat(parser, TOKEN_RPAREN);
|
||||
return result;
|
||||
} else {
|
||||
printf("\nUnexpected token in factor %d\n", token.type);
|
||||
shell_install();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
double parser_term(Parser *parser)
|
||||
{
|
||||
double result = parser_factor(parser);
|
||||
|
||||
while (parser->current_token.type == TOKEN_MULTIPLY || parser->current_token.type == TOKEN_DIVIDE)
|
||||
{
|
||||
Token token = parser->current_token;
|
||||
if (token.type == TOKEN_MULTIPLY)
|
||||
{
|
||||
parser_eat(parser, TOKEN_MULTIPLY);
|
||||
result *= parser_factor(parser);
|
||||
} else if (token.type == TOKEN_DIVIDE) {
|
||||
parser_eat(parser, TOKEN_DIVIDE);
|
||||
result /= parser_factor(parser);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double parser_expression(Parser *parser)
|
||||
{
|
||||
double result = parser_term(parser);
|
||||
|
||||
while (parser->current_token.type == TOKEN_PLUS || parser->current_token.type == TOKEN_MINUS)
|
||||
{
|
||||
Token token = parser->current_token;
|
||||
if (token.type == TOKEN_PLUS)
|
||||
{
|
||||
parser_eat(parser, TOKEN_PLUS);
|
||||
result += parser_term(parser);
|
||||
} else if (token.type == TOKEN_MINUS) {
|
||||
parser_eat(parser, TOKEN_MINUS);
|
||||
result -= parser_term(parser);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double parse(const char* text)
|
||||
{
|
||||
Parser parser;
|
||||
parser_init(&parser, text);
|
||||
double result = parser_expression(&parser);
|
||||
return result;
|
||||
}
|
||||
|
||||
void program_math()
|
||||
{
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
puts("Expression? ");
|
||||
get_input(input_buffer, BUFFER_SIZE);
|
||||
double result = parse(input_buffer);
|
||||
printf("\n%f\n", result);
|
||||
}
|
||||
176
src/utils/misc.c
176
src/utils/misc.c
@@ -1,176 +0,0 @@
|
||||
// Miscellaneous small programs
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../drivers/framebuffer.h"
|
||||
#include "../drivers/ata.h"
|
||||
#include "../drivers/rtc.h"
|
||||
#include "../kernel/io.h"
|
||||
#include "../drivers/pci.h"
|
||||
#include "../kernel/initrd.h"
|
||||
#include "../kernel/kmain.h"
|
||||
|
||||
// Print a rainbow colorful text for testing
|
||||
|
||||
#define BUF_SIZE 256
|
||||
#define COLORS 20
|
||||
|
||||
void program_rainbow(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <string>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char input_buffer[BUF_SIZE] = {0};
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
strcat(input_buffer, argv[i]);
|
||||
if (i<argc-1)
|
||||
{
|
||||
strcat(input_buffer, " ");
|
||||
}
|
||||
}
|
||||
|
||||
enum Colors colors[] = {
|
||||
white, black, red, green, blue, yellow,
|
||||
cyan, magenta, orange, purple, brown,
|
||||
gray, pink, lime, navy, teal, maroon,
|
||||
olive, silver, gold, indigo, violet,
|
||||
coral, turquoise, salmon, chocolate,
|
||||
khaki, lavender, beige
|
||||
};
|
||||
int colors_count = sizeof(colors)/sizeof(colors[0]);
|
||||
|
||||
for (int i=0; i<colors_count-1; i++)
|
||||
{
|
||||
colorputs(input_buffer, colors[i], colors[i+1]);
|
||||
puts("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the terminal
|
||||
|
||||
#define ROWS 25
|
||||
|
||||
void program_clear()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// Get uptime in ticks
|
||||
|
||||
void program_uptime()
|
||||
{
|
||||
int ticks = uptime();
|
||||
double seconds = ticks/18.2065; // PIT channel 0 freq
|
||||
printf("%d ticks\t%f seconds\n", ticks, seconds);
|
||||
}
|
||||
|
||||
// Get help
|
||||
|
||||
void program_help()
|
||||
{
|
||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\t naval\nsnake exec\t uhex\n");
|
||||
}
|
||||
|
||||
// Panic
|
||||
|
||||
void program_panic()
|
||||
{
|
||||
asm volatile("int $0x13");
|
||||
}
|
||||
|
||||
// Output input
|
||||
|
||||
void program_echo(int argc, char* argv[])
|
||||
{
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
puts(argv[i]);
|
||||
if (i < argc-1) {
|
||||
putc(' ');
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
// Get current RTC time
|
||||
|
||||
void program_time()
|
||||
{
|
||||
rtc_time_t time;
|
||||
rtc_read_time(&time);
|
||||
puts("Current RTC time: ");
|
||||
print_time(&time);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
// Read a sector
|
||||
|
||||
void program_read(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <sector>\n", argv[0]);
|
||||
} else if (argc == 2)
|
||||
{
|
||||
uint8_t buffer[512];
|
||||
ata_read_sector(atoi(argv[1]), buffer);
|
||||
|
||||
for (int i=0; i<512; i++)
|
||||
{
|
||||
if (i%50==0) puts("\n"); // hardcoded = bad
|
||||
printf("%02x ", buffer[i]);
|
||||
}
|
||||
puts("\n");
|
||||
} else
|
||||
{
|
||||
puts("Invalid argument number\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Reboots the machine (might just shutdown) (or do nothing if youre lucky)
|
||||
|
||||
void program_reboot()
|
||||
{
|
||||
puts("Rebooting...\n");
|
||||
|
||||
while(inb(0x64) & 0x02);
|
||||
outb(0x64, 0xFE);
|
||||
|
||||
while (1) asm volatile("hlt");
|
||||
}
|
||||
|
||||
// List PCI buses and devices
|
||||
|
||||
void program_lspci()
|
||||
{
|
||||
scan_pci_bus();
|
||||
}
|
||||
|
||||
// Executes binary file
|
||||
|
||||
void program_exec(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
puts("Usage: exec <binary>\n");
|
||||
return;
|
||||
}
|
||||
void* binary_file = load_file_from_initrd((uint8_t*)initrd_addr, argv[1]);
|
||||
|
||||
if (binary_file == NULL)
|
||||
{
|
||||
printf("[exec] Failed to load program '%s'.\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
void (*program_entry)() = (void (*)())binary_file;
|
||||
program_entry();
|
||||
}
|
||||
@@ -1,348 +0,0 @@
|
||||
// Simplified naval battle game
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "navalbattle.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../kernel/kheap.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include "../drivers/serial.h"
|
||||
|
||||
// Porting problems:
|
||||
// - Color printf? (Need to implement ANSI escape sequences).
|
||||
// - Scanf?
|
||||
// - Malloc? (proof of concept)
|
||||
|
||||
void program_navalbattle()
|
||||
{
|
||||
clear();
|
||||
|
||||
grid_t* grid[SIZE][SIZE];
|
||||
grid_t* enemyGrid[SIZE][SIZE];
|
||||
|
||||
init_battlefield(grid);
|
||||
init_battlefield(enemyGrid);
|
||||
|
||||
placing_ally_ships(grid);
|
||||
puts("Now, time for the enemies to prepare...\n");
|
||||
placing_enemy_ships(enemyGrid);
|
||||
|
||||
delay((rand()%MAX_WAIT_TIME)+10);
|
||||
|
||||
puts("Here we go!\n");
|
||||
show_game_stats(grid, enemyGrid);
|
||||
|
||||
do
|
||||
{
|
||||
ally_do_attack(enemyGrid);
|
||||
enemy_do_attack(grid);
|
||||
show_game_stats(grid, enemyGrid);
|
||||
} while (check_victory(grid, enemyGrid) == 0);
|
||||
|
||||
free_grid(grid);
|
||||
free_grid(enemyGrid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_battlefield(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
grid[i][j] = (grid_t*)malloc(sizeof(grid_t));
|
||||
grid[i][j]->x = i;
|
||||
grid[i][j]->y = j;
|
||||
grid[i][j]->role = 0;
|
||||
grid[i][j]->state = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// To avoid memory leaks..
|
||||
void free_grid(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
free(grid[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void show_ally_battlefield(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
puts("\n*** Ally grid ***\n");
|
||||
puts(" 0 1 2 3 4 5\n");
|
||||
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
printf("%d ", i);
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
char roleChar = 0;
|
||||
switch(grid[i][j]->state)
|
||||
{
|
||||
case -2:
|
||||
roleChar = 32; // space
|
||||
break;
|
||||
case -1:
|
||||
roleChar = 120;
|
||||
break;
|
||||
case 0:
|
||||
roleChar = 79;
|
||||
break;
|
||||
case 1:
|
||||
roleChar = 88;
|
||||
break;
|
||||
default:
|
||||
printf("Error: bad value in grid at x=%d y=%d\n", grid[i][j]->x, grid[i][j]->y);
|
||||
shell_install();
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == SIZE-1)
|
||||
{
|
||||
printf("%c]", roleChar);
|
||||
} else if (j == 0) {
|
||||
printf("[%c|", roleChar);
|
||||
} else {
|
||||
printf("%c|", roleChar);
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void placing_ally_ships(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
puts("==== Allied preparation phase =====\nPlease enter the positions for your ships, sir.\n");
|
||||
|
||||
for (size_t i=0; i<BOATS; i++)
|
||||
{
|
||||
int posX = 0, posY = 0;
|
||||
|
||||
do
|
||||
{
|
||||
printf("Ship %d\n------\n", (int)i);
|
||||
puts("X coord: ");
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
get_input(input_buffer, BUFFER_SIZE);
|
||||
posY = atoi(input_buffer);
|
||||
|
||||
puts("\nY coord: ");
|
||||
char input_buffer2[BUFFER_SIZE];
|
||||
get_input(input_buffer2, BUFFER_SIZE);
|
||||
posX = atoi(input_buffer2);
|
||||
|
||||
puts("\n");
|
||||
if (posX < 0 || posX >= SIZE || posY < 0 || posY >= SIZE)
|
||||
{
|
||||
printf("Invalid position x=%d y=%d, please retry.\n", posX, posY);
|
||||
}
|
||||
if (grid[posX][posY]->role == 1)
|
||||
{
|
||||
printf("A ship is already in x=%d y=%d, please retry.\n", posX, posY);
|
||||
}
|
||||
} while (posX < 0 || posX >= SIZE || posY < 0 || posY >= SIZE || grid[posX][posY]->role == 1);
|
||||
|
||||
grid[posX][posY]->role = 1;
|
||||
grid[posX][posY]->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void placing_enemy_ships(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
for (size_t i=0; i<BOATS; i++)
|
||||
{
|
||||
int posX = 0, posY = 0;
|
||||
do
|
||||
{
|
||||
posX = rand() % SIZE;
|
||||
posY = rand() % SIZE;
|
||||
} while (grid[posX][posY]->role != 0);
|
||||
|
||||
grid[posX][posY]->role = 1;
|
||||
grid[posX][posY]->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void show_enemy_battlefield(grid_t* grid[SIZE][SIZE])
|
||||
{
|
||||
puts("\n*** Enemy grid ***\n");
|
||||
puts(" 0 1 2 3 4 5\n");
|
||||
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
printf("%d ", (int)i);
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
char roleChar = 0;
|
||||
switch(grid[i][j]->state)
|
||||
{
|
||||
case -2:
|
||||
case 0:
|
||||
roleChar = 32;
|
||||
break;
|
||||
case -1:
|
||||
roleChar = 120;
|
||||
break;
|
||||
case 1:
|
||||
roleChar = 88;
|
||||
break;
|
||||
default:
|
||||
printf("Error: bad value in battlefield at x=%d y=%d\n", grid[i][j]->x, grid[i][j]->y);
|
||||
shell_install();
|
||||
break;
|
||||
}
|
||||
if (j == SIZE-1)
|
||||
{
|
||||
printf("%c]", roleChar);
|
||||
} else if (j == 0) {
|
||||
printf("[%c|", roleChar);
|
||||
} else {
|
||||
printf("%c|", roleChar);
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void show_remaining_boats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE])
|
||||
{
|
||||
int allyShips = 0;
|
||||
int enemyShips = 0;
|
||||
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
if (allyGrid[i][j]->state == 0)
|
||||
{
|
||||
allyShips++;
|
||||
}
|
||||
|
||||
if (enemyGrid[i][j]->state == 0)
|
||||
{
|
||||
enemyShips++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d ally ships and %d enemy ships remaining.\n", allyShips, enemyShips);
|
||||
allyShips >= enemyShips ? colorputs("The allies are in a good posture.\n", yellow, black) : colorputs("The allies are losing terrain...\n", salmon, black);
|
||||
}
|
||||
|
||||
void show_game_stats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE])
|
||||
{
|
||||
clear();
|
||||
colorputs("\n\n\nShowing known information:\n\n", cyan, black);
|
||||
show_ally_battlefield(allyGrid);
|
||||
show_enemy_battlefield(enemyGrid);
|
||||
show_remaining_boats(allyGrid, enemyGrid);
|
||||
}
|
||||
|
||||
void do_attack(grid_t* grid[SIZE][SIZE], int x, int y)
|
||||
{
|
||||
switch(grid[x][y]->state)
|
||||
{
|
||||
case -2: // Untouched ocean
|
||||
colorputs("The torpedo explodes in water. Missed.\n", orange, black);
|
||||
grid[x][y]->state = -1;
|
||||
delay(30);
|
||||
break;
|
||||
case -1: // Already hit ocean
|
||||
colorputs("We already striked here, sir... Too late.\n", orange, black);
|
||||
break;
|
||||
case 0: // Ship
|
||||
colorputs("Hit! Well done!\n", green, black);
|
||||
grid[x][y]->state = 1;
|
||||
delay(30);
|
||||
break;
|
||||
case 1: // Already hit ship
|
||||
colorputs("Sir, we already sunk that ship... (looser)\n", orange, black);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ally_do_attack(grid_t* enemyGrid[SIZE][SIZE])
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
colorputs("\n* Ally attack preparation *\n", blue, black);
|
||||
do
|
||||
{
|
||||
// yes, x and y are inverted.
|
||||
puts("X coord: ");
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
get_input(input_buffer, BUFFER_SIZE);
|
||||
y = atoi(input_buffer);
|
||||
|
||||
puts("\nY coord: ");
|
||||
char input_buffer2[BUFFER_SIZE];
|
||||
get_input(input_buffer2, BUFFER_SIZE);
|
||||
x = atoi(input_buffer2);
|
||||
|
||||
puts("\n");
|
||||
|
||||
if (x < 0 || x >= SIZE || y < 0 || y >= SIZE)
|
||||
{
|
||||
puts("Sir, this zone is not in our operation area! Please retry.\n");
|
||||
}
|
||||
} while (x < 0 || x >= SIZE || y < 0 || y >= SIZE);
|
||||
|
||||
do_attack(enemyGrid, x, y);
|
||||
}
|
||||
|
||||
void enemy_do_attack(grid_t* allyGrid[SIZE][SIZE])
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
colorputs("\n* Enemies are preparing for attack, everyone take shelter! *\n", blue, black);
|
||||
|
||||
do
|
||||
{
|
||||
x = rand() % SIZE;
|
||||
y = rand() % SIZE;
|
||||
} while (allyGrid[x][y]->state == -1 || allyGrid[x][y]->state == 1);
|
||||
|
||||
delay((rand()%MAX_WAIT_TIME)+10);
|
||||
do_attack(allyGrid, x, y);
|
||||
}
|
||||
|
||||
int check_victory(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE])
|
||||
{
|
||||
int allyShips = 0;
|
||||
int enemyShips = 0;
|
||||
|
||||
for (size_t i=0; i<SIZE; i++)
|
||||
{
|
||||
for (size_t j=0; j<SIZE; j++)
|
||||
{
|
||||
if (allyGrid[i][j]->state == 0)
|
||||
{
|
||||
allyShips++;
|
||||
}
|
||||
|
||||
if (enemyGrid[i][j]->state == 0)
|
||||
{
|
||||
enemyShips++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allyShips > 0 && enemyShips == 0)
|
||||
{
|
||||
colorputs("The allies have won! Congratulations, chief!\n", green, black);
|
||||
return 1;
|
||||
} else if (enemyShips > 0 && allyShips == 0)
|
||||
{
|
||||
colorputs("The ennemies have won.. We must retreat.\n", red, black);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Simplified naval battle game header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef NAVALBATTLE_H
|
||||
#define NAVALBATTLE_H
|
||||
|
||||
#include "../drivers/framebuffer.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int role;
|
||||
int state;
|
||||
} grid_t;
|
||||
|
||||
#define SIZE 6
|
||||
#define BOATS 5
|
||||
#define MAX_WAIT_TIME 20
|
||||
#define BUFFER_SIZE 16
|
||||
|
||||
void init_battlefield(grid_t* grid[SIZE][SIZE]);
|
||||
void free_grid(grid_t* grid[SIZE][SIZE]);
|
||||
void show_ally_battlefield(grid_t* grid[SIZE][SIZE]);
|
||||
void placing_ally_ships(grid_t* grid[SIZE][SIZE]);
|
||||
void placing_enemy_ships(grid_t* grid[SIZE][SIZE]);
|
||||
void show_enemy_battlefield(grid_t* grid[SIZE][SIZE]);
|
||||
void show_remaining_boats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]);
|
||||
void show_game_stats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]);
|
||||
void do_attack(grid_t* grid[SIZE][SIZE], int x, int y);
|
||||
void ally_do_attack(grid_t* enemyGrid[SIZE][SIZE]);
|
||||
void enemy_do_attack(grid_t* allyGrid[SIZE][SIZE]);
|
||||
int check_victory(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]);
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
// Program for Pi computation using Leibniz series
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
void program_pi(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <terms>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
double pi = 0.0;
|
||||
int terms = atoi(argv[1]);
|
||||
|
||||
for (int i=0; i<terms; i++)
|
||||
{
|
||||
double term = 1.0/(2*i+1);
|
||||
if (i%2 == 0)
|
||||
{
|
||||
pi += term;
|
||||
} else {
|
||||
pi -= term;
|
||||
}
|
||||
}
|
||||
|
||||
pi *= 4;
|
||||
|
||||
printf("%f\n", pi);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// Prime number computation program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
#define PRIMES_MAX 1000000
|
||||
|
||||
bool isPrime(int n)
|
||||
{
|
||||
if (n == 1 || n == 0) return false;
|
||||
for (int i=2; i<= n/2; i++) if (n%i == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void program_primes(int argc, char* argv[])
|
||||
{
|
||||
int primes_max;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
primes_max = PRIMES_MAX;
|
||||
} else if (argc == 2)
|
||||
{
|
||||
primes_max = atoi(argv[1]);
|
||||
}
|
||||
|
||||
for (long long x=0; x<primes_max; x++)
|
||||
{
|
||||
if (isPrime(x) && x != 3301)
|
||||
{
|
||||
printf("%d ", (int)x);
|
||||
} else if(x == 3301)
|
||||
{
|
||||
colorputs("3301 ", red, black);
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
// Snake game
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../drivers/framebuffer.h"
|
||||
#include "../drivers/kb.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../libc/crypto.h"
|
||||
|
||||
#define WIDTH 25
|
||||
#define HEIGHT 25
|
||||
#define PIXEL_SIZE 20
|
||||
#define MAX_SNAKE_LENGTH 256
|
||||
// to add:
|
||||
// sound
|
||||
// optimization (shit)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} SnakeSegment;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SnakeSegment segments[MAX_SNAKE_LENGTH];
|
||||
int length;
|
||||
int dx;
|
||||
int dy;
|
||||
} Snake;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} Food;
|
||||
|
||||
Snake snake;
|
||||
Food food;
|
||||
int score = 0;
|
||||
bool onSnake;
|
||||
|
||||
int is_snake(int x, int y);
|
||||
|
||||
void init_game()
|
||||
{
|
||||
snake.length = 1;
|
||||
snake.segments[0].x = WIDTH/2;
|
||||
snake.segments[0].y = HEIGHT/2;
|
||||
snake.dx = 1;
|
||||
snake.dy = 0;
|
||||
|
||||
food.x = rand() % (WIDTH-1);
|
||||
food.y = rand() % (HEIGHT-1);
|
||||
}
|
||||
|
||||
void draw_board()
|
||||
{
|
||||
for (int y=0; y<=HEIGHT; y++)
|
||||
{
|
||||
for (int x=0; x<=WIDTH; x++)
|
||||
{
|
||||
if (x == 0 || x == WIDTH || y == 0 || y == HEIGHT)
|
||||
{
|
||||
draw_square(x, y, white, PIXEL_SIZE);
|
||||
}
|
||||
else if (is_snake(x, y)) {
|
||||
draw_square(x, y, green, PIXEL_SIZE);
|
||||
} else if(x == food.x && y == food.y) {
|
||||
draw_square(x, y, red, PIXEL_SIZE);
|
||||
} else {
|
||||
draw_square(x, y, black, PIXEL_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
move_cursor(WIDTH+42, 2);
|
||||
colorputs("Snake Game!", black, green);
|
||||
move_cursor(WIDTH+42, 4);
|
||||
colorprintf(yellow, black, "Score: %d", score);
|
||||
move_cursor(WIDTH+42, 5);
|
||||
puts("Use WASD keys to move");
|
||||
move_cursor(WIDTH+42, 6);
|
||||
puts("Press Q to quit");
|
||||
}
|
||||
|
||||
int is_snake(int x, int y)
|
||||
{
|
||||
for (int i=0; i<snake.length; i++)
|
||||
{
|
||||
if (snake.segments[i].x == x && snake.segments[i].y == y)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void move_snake()
|
||||
{
|
||||
for (int i=snake.length-1; i>0; i--)
|
||||
{
|
||||
snake.segments[i] = snake.segments[i-1];
|
||||
}
|
||||
|
||||
snake.segments[0].x += snake.dx;
|
||||
snake.segments[0].y += snake.dy;
|
||||
|
||||
if (snake.segments[0].x < 0) snake.segments[0].x = WIDTH-1;
|
||||
if (snake.segments[0].x >= WIDTH) snake.segments[0].x = 0;
|
||||
if (snake.segments[0].y < 0) snake.segments[0].y = HEIGHT-1;
|
||||
if (snake.segments[0].y >= HEIGHT) snake.segments[0].y = 0;
|
||||
|
||||
if (snake.segments[0].x == food.x && snake.segments[0].y == food.y)
|
||||
{
|
||||
snake.length++;
|
||||
score++;
|
||||
|
||||
do
|
||||
{
|
||||
onSnake = false;
|
||||
food.x = rand() % (WIDTH-1) + 1;
|
||||
food.y = rand() % (HEIGHT-1) + 1;
|
||||
|
||||
for (int i=0; i<snake.length; i++)
|
||||
{
|
||||
if (snake.segments[i].x == food.x && snake.segments[i].y == food.y)
|
||||
{
|
||||
onSnake = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (onSnake);
|
||||
}
|
||||
|
||||
for (int i=1; i<snake.length; i++)
|
||||
{
|
||||
if (snake.segments[0].x == snake.segments[i].x && snake.segments[0].y == snake.segments[i].y)
|
||||
{
|
||||
|
||||
move_cursor(WIDTH+42, 8);
|
||||
colorputs("Game Over!\n", white, red);
|
||||
move_cursor(0, HEIGHT+10);
|
||||
shell_install();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handle_input(char key)
|
||||
{
|
||||
if (key == 'w' && snake.dy == 0) {
|
||||
snake.dx = 0;
|
||||
snake.dy = -1;
|
||||
} else if (key == 's' && snake.dy == 0) {
|
||||
snake.dx = 0;
|
||||
snake.dy = 1;
|
||||
} else if (key == 'a' && snake.dx == 0) {
|
||||
snake.dx = -1;
|
||||
snake.dy = 0;
|
||||
} else if (key == 'd' && snake.dx == 0) {
|
||||
snake.dx = 1;
|
||||
snake.dy = 0;
|
||||
} else if (key =='q') {
|
||||
move_cursor(0, HEIGHT+10);
|
||||
shell_install();
|
||||
}
|
||||
}
|
||||
|
||||
void program_snake(int argc, char* argv[])
|
||||
{
|
||||
int game_speed;
|
||||
if (argc < 2)
|
||||
{
|
||||
game_speed = 4;
|
||||
} else {
|
||||
game_speed = atoi(argv[1]);
|
||||
}
|
||||
|
||||
clear();
|
||||
init_game();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char key = keyboard_getchar_non_blocking();
|
||||
|
||||
if (key)
|
||||
{
|
||||
handle_input(key);
|
||||
}
|
||||
|
||||
move_snake();
|
||||
draw_board();
|
||||
delay(game_speed);
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// System information program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../kernel/sysinfo.h"
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
extern unsigned int multiboot_info_address;
|
||||
|
||||
typedef struct multiboot_memory_map
|
||||
{
|
||||
unsigned int size;
|
||||
unsigned int base_addr_low;
|
||||
unsigned int base_addr_high;
|
||||
unsigned int length_low;
|
||||
unsigned int length_high;
|
||||
unsigned int type;
|
||||
} multiboot_memory_map_t;
|
||||
|
||||
void get_cpuid()
|
||||
{
|
||||
// CPUid
|
||||
|
||||
unsigned int eax, edx;
|
||||
char vendor[13];
|
||||
unsigned int* v = (unsigned int*)vendor;
|
||||
|
||||
asm volatile("cpuid"
|
||||
: "=b"(v[0]), "=d"(v[1]), "=c"(v[2])
|
||||
: "a"(0));
|
||||
vendor[12] = '\0';
|
||||
|
||||
cpuid(1, &eax, &edx);
|
||||
unsigned int model = (eax >> 4) & 0xF;
|
||||
unsigned int family = (eax >> 8) & 0xF;
|
||||
|
||||
printf("CPU information\n\tvendor: %s\n\tfamily: %u\n\tmodel: %u\n\tfeatures: 0x%x\n", vendor, family, model, edx);
|
||||
}
|
||||
|
||||
// Not really working anymore as it was made for multiboot1, now using multiboot2
|
||||
void get_meminfo(unsigned int multiboot_info_address, int verbose)
|
||||
{
|
||||
// RAM
|
||||
|
||||
unsigned int mem_lower = *((unsigned int*)(multiboot_info_address + 4));
|
||||
unsigned int mem_upper = *((unsigned int*)(multiboot_info_address + 8));
|
||||
|
||||
printf("RAM information\n\tLower memory: %u KB\n\tUpper memory: %u KB\n", mem_lower, mem_upper);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
multiboot_memory_map_t* mmap = (multiboot_memory_map_t*)*((unsigned int*)(multiboot_info_address + 44));
|
||||
printf("Memory map:\nBase addr | Length | Type\n----------------------------------------------------\n");
|
||||
|
||||
while ((unsigned int)mmap < multiboot_info_address + *((unsigned int*)(multiboot_info_address + 40)))
|
||||
{
|
||||
/*
|
||||
if (mmap->length_high != 0 && mmap->length_low != 0)
|
||||
{*/
|
||||
printf("0x%x%x | 0x%x%x | %u\n",
|
||||
mmap->base_addr_high, mmap->base_addr_low,
|
||||
mmap->length_high, mmap->length_low,
|
||||
mmap->type);
|
||||
//}
|
||||
|
||||
mmap = (multiboot_memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void program_sysinfo(int argc, char* argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
get_cpuid();
|
||||
get_meminfo(g_multiboot_info_address, 0);
|
||||
} else if (argc == 2 && strcmp(argv[1], "-v") == 0)
|
||||
{
|
||||
get_cpuid();
|
||||
get_meminfo(g_multiboot_info_address, 1);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
// uhex (microhex) port for BlankOS; read-only version
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
// This version is the port of a hex viewer which already was not great,
|
||||
// and now by being here it is even worse because it is RO and will have
|
||||
// hardcoded stuff in it (no ioctl, STDOUT, or other stuff here...)
|
||||
|
||||
#define BYTES 1024
|
||||
#define round(x) (int)(x < 0 ? (x -0.5) : x + 0.5)
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../kernel/kmain.h"
|
||||
#include "../kernel/initrd.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../kernel/kheap.h"
|
||||
|
||||
int isprint(int c)
|
||||
{
|
||||
return (c >= 32 && c <= 126);
|
||||
}
|
||||
|
||||
void print_hex(unsigned char* buf, int byteno, int pos, int BYTES_PER_LINE)
|
||||
{
|
||||
for (int i=0; i<byteno; i++)
|
||||
{
|
||||
if (i%BYTES_PER_LINE == 0)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
printf(" ");
|
||||
for (int j=i-BYTES_PER_LINE; j<i; j++)
|
||||
{
|
||||
if (isprint(buf[j])) colorprintf(salmon, black, "%c", buf[j]);
|
||||
else printf(".");
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
|
||||
if (pos == 0) printf("%06d: ", i);
|
||||
else printf("%06d: ", pos);
|
||||
}
|
||||
printf("%2x ", buf[i]);
|
||||
}
|
||||
|
||||
int padding = BYTES_PER_LINE - (byteno % BYTES_PER_LINE);
|
||||
if (padding < BYTES_PER_LINE)
|
||||
{
|
||||
for (int i=0; i<padding; i++) printf(" ");
|
||||
printf(" ");
|
||||
}
|
||||
int start = byteno-(byteno%BYTES_PER_LINE);
|
||||
for (int j=start; j<byteno; j++)
|
||||
{
|
||||
if (isprint(buf[j])) {
|
||||
colorprintf(salmon, black, "%c", buf[j]);
|
||||
} else {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void program_uhex(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
puts("Usage: uhex <file>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int BYTES_PER_LINE = 20;
|
||||
|
||||
//unsigned char buf[BYTES]; // malloc with file_size next?
|
||||
uint32_t file_size = tar_get_file_size((uint8_t*)initrd_addr, argv[1]);
|
||||
unsigned char* buf = (unsigned char*)malloc(file_size);
|
||||
tar_file_to_buffer((uint8_t*)initrd_addr, argv[1], (char*)buf);
|
||||
print_hex(buf, file_size, 0, BYTES_PER_LINE);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// Global program entry points header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
void program_words();
|
||||
void program_primes();
|
||||
void program_math();
|
||||
void program_bf();
|
||||
void program_sysinfo();
|
||||
|
||||
void get_cpuid();
|
||||
void get_meminfo(unsigned int multiboot_info_address); // to be fixed: cannot get full memory map (sysinfo -v)
|
||||
void program_cowsay();
|
||||
void cowsay(); // Splash screen
|
||||
void program_pi();
|
||||
|
||||
// Ciphers
|
||||
void program_rot13();
|
||||
void program_morse();
|
||||
|
||||
// Misc
|
||||
void program_rainbow();
|
||||
void program_clear();
|
||||
void program_uptime();
|
||||
void program_panic();
|
||||
void program_help();
|
||||
void program_echo();
|
||||
void program_time();
|
||||
void program_read();
|
||||
void program_reboot();
|
||||
|
||||
// Filesystem (initrd)
|
||||
void program_ls();
|
||||
void program_cat();
|
||||
|
||||
void program_bmp();
|
||||
void program_lspci();
|
||||
|
||||
// Games
|
||||
void program_navalbattle();
|
||||
void program_conway();
|
||||
void program_snake();
|
||||
|
||||
// Binaries loading and execution
|
||||
void program_exec();
|
||||
|
||||
void program_uhex();
|
||||
|
||||
#endif
|
||||
@@ -1,217 +0,0 @@
|
||||
// Pseudo-random word generation program
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include "../libc/stdio.h"
|
||||
#include "../libc/crypto.h"
|
||||
#include "../kernel/system.h"
|
||||
#include "../libc/string.h"
|
||||
|
||||
// Small dictionary
|
||||
|
||||
char* words[] =
|
||||
{
|
||||
// A
|
||||
"I", "us", "they", "my",
|
||||
"a", "an", "is", "are", "for", "while", "not", "none", "yes", "no",
|
||||
"absolutely", "addition", "additive", "afternoon", "architect", "ask",
|
||||
"ability", "above", "absence", "academy", "account", "achieve", "acquire",
|
||||
"adapt", "admit", "adventure", "affection", "agenda", "agreement", "airport",
|
||||
"alert", "alibi", "alive", "allow", "almond", "alphabet", "always",
|
||||
|
||||
// B
|
||||
"be", "blindfold", "brilliant", "boy", "bring", "buddy",
|
||||
"balance", "bamboo", "band", "banjo", "bank", "banner", "barrel",
|
||||
"basic", "battery", "beach", "beacon", "beard", "behavior", "believe",
|
||||
"belt", "benefit", "berry", "bicycle", "bingo", "biology", "birthday",
|
||||
"biscuit", "bitter", "blanket", "blizzard", "blossom", "blueprint", "board",
|
||||
|
||||
// C
|
||||
"career", "caterpillar", "change", "cheeky", "chop",
|
||||
"cabin", "cactus", "camera", "candle", "candy", "canoe", "canvas",
|
||||
"capital", "captain", "caravan", "carbon", "carpet", "cartoon", "castle",
|
||||
"casual", "catalog", "catch", "category", "celebrate", "ceremony", "certain",
|
||||
"chain", "chair", "chamber", "charge", "charity", "cheese", "chef",
|
||||
|
||||
// D
|
||||
"decide", "demonstrate", "draw", "druggist",
|
||||
"daisy", "dance", "danger", "daring", "database", "debate", "decade",
|
||||
"decline", "decorate", "decrease", "dedicate", "defeat", "defend", "define",
|
||||
"degree", "delight", "delivery", "demand", "dentist", "deny", "depart",
|
||||
"depth", "describe", "deserve", "desire", "destroy", "develop", "device",
|
||||
|
||||
// E
|
||||
"eagle", "ear", "effort", "evening",
|
||||
"early", "earn", "earth", "ease", "east", "easy", "echo",
|
||||
"eclipse", "economy", "edge", "edit", "educate", "effect", "effort",
|
||||
"egg", "eight", "either", "elder", "elect", "elegant", "element",
|
||||
"elephant", "elevator", "elite", "embark", "embrace", "emerge", "emotion",
|
||||
|
||||
// F
|
||||
"fabric", "famous", "fuse",
|
||||
"face", "factor", "fail", "fair", "fall", "false", "fame",
|
||||
"family", "fancy", "fantasy", "farewell", "farm", "fashion", "fast",
|
||||
"fault", "favor", "feather", "feature", "federal", "feedback", "feeling",
|
||||
"female", "fence", "festival", "fever", "fiber", "fiction", "field",
|
||||
|
||||
// G
|
||||
"generation", "generous", "girl", "gypsy", "grip",
|
||||
"gallery", "game", "garage", "garden", "garlic", "gas", "gate",
|
||||
"gather", "general", "genius", "gentle", "genuine", "geography", "gesture",
|
||||
"ghost", "giant", "gift", "giggle", "ginger", "giraffe", "glance",
|
||||
"glass", "globe", "glory", "glove", "glue", "goal", "gold",
|
||||
|
||||
// H
|
||||
"habit", "handsome", "helmet", "help", "horror",
|
||||
"hair", "half", "hammer", "hand", "handle", "hang", "happen",
|
||||
"harbor", "hard", "harm", "harvest", "hat", "hate", "have",
|
||||
"head", "health", "heart", "heat", "heaven", "heavy", "hedge",
|
||||
"height", "hello", "heritage", "hero", "hesitate", "hidden", "high",
|
||||
|
||||
// I
|
||||
"insist", "inventor", "itself", "ivory",
|
||||
"ice", "idea", "ideal", "identify", "ignore", "ill", "image",
|
||||
"imagine", "impact", "import", "impress", "improve", "impulse", "inch",
|
||||
"include", "income", "increase", "index", "industry", "infant", "inform",
|
||||
"insect", "inside", "inspire", "install", "instead", "insult", "intact",
|
||||
|
||||
// J
|
||||
"jog", "joint", "joke", "judge",
|
||||
"jacket", "jaguar", "jail", "jam", "january", "jar", "jazz",
|
||||
"jealous", "jeans", "jelly", "jewel", "job", "join", "journey",
|
||||
"joy", "judge", "juice", "jump", "jungle", "junior", "justice",
|
||||
"just", "justify", "juggle", "juice", "jumper", "junction", "jury",
|
||||
|
||||
// K
|
||||
"karate", "kebab", "kitchen",
|
||||
"kangaroo", "keen", "keep", "kettle", "key", "keyboard", "kick",
|
||||
"kid", "kidney", "king", "kiss", "kite", "knee", "knife",
|
||||
"knit", "knock", "knot", "know", "knowledge", "koala", "kudos",
|
||||
"keen", "kernel", "kit", "kitten", "knack", "knight", "knock",
|
||||
|
||||
// L
|
||||
"lamb", "lawnmower", "left", "lock",
|
||||
"label", "labor", "lace", "ladder", "lady", "lake", "lamp",
|
||||
"land", "language", "large", "laser", "last", "later", "laugh",
|
||||
"launch", "law", "layer", "lead", "leaf", "learn", "least",
|
||||
"leather", "leave", "lecture", "legal", "legend", "lemon", "length",
|
||||
|
||||
// M
|
||||
"math", "medicine", "most",
|
||||
"machine", "magnet", "mail", "main", "major", "make", "male",
|
||||
"manage", "mango", "manner", "manual", "map", "marble", "march",
|
||||
"mark", "market", "marriage", "master", "match", "material", "matter",
|
||||
"maximum", "mayor", "meal", "mean", "measure", "media", "memory",
|
||||
|
||||
// N
|
||||
"noodles", "nowadays", "nowhere",
|
||||
"nail", "name", "narrow", "nation", "native", "nature", "navy",
|
||||
"near", "neat", "necessary", "neck", "need", "negative", "neglect",
|
||||
"neither", "nerve", "nest", "net", "network", "neutral", "never",
|
||||
"new", "news", "next", "nice", "night", "noble", "noise",
|
||||
|
||||
// O
|
||||
"ocean", "older", "ounce",
|
||||
"object", "observe", "obtain", "occasion", "occupy", "occur", "ocean",
|
||||
"offer", "office", "often", "oil", "old", "olive", "olympic",
|
||||
"omit", "once", "one", "onion", "online", "only", "open",
|
||||
"opera", "opinion", "oppose", "option", "orange", "orbit", "order",
|
||||
|
||||
// P
|
||||
"part", "pathetic", "pastime",
|
||||
"pace", "package", "page", "pain", "paint", "pair", "palm",
|
||||
"panel", "panic", "paper", "parent", "park", "part", "party",
|
||||
"pass", "path", "patient", "pattern", "pause", "peace", "peak",
|
||||
"pen", "pencil", "people", "pepper", "perfect", "perform", "permit",
|
||||
|
||||
// Q
|
||||
"quite", "quits", "quotation",
|
||||
"quality", "quantity", "quarter", "queen", "query", "quest", "quick",
|
||||
"quiet", "quilt", "quit", "quote", "quiz", "quota", "quiver",
|
||||
"quirky", "quaint", "quake", "qualification", "qualify", "quark", "quartz",
|
||||
"queue", "quench", "question", "quote", "quiver", "quorum", "quote",
|
||||
|
||||
// R
|
||||
"race", "raise", "reality",
|
||||
"rabbit", "race", "radio", "rain", "raise", "random", "range",
|
||||
"rapid", "rare", "rate", "rather", "ratio", "reach", "react",
|
||||
"read", "ready", "real", "reason", "rebel", "recall", "receive",
|
||||
"recipe", "record", "recover", "reduce", "refer", "reflect", "reform",
|
||||
|
||||
// S
|
||||
"safe", "scare", "screen",
|
||||
"sack", "sail", "salad", "salt", "same", "sample", "sand",
|
||||
"save", "scale", "scan", "scar", "scene", "school", "science",
|
||||
"score", "scratch", "scream", "screen", "script", "search", "season",
|
||||
"seat", "second", "secret", "section", "secure", "see", "seed",
|
||||
|
||||
// T
|
||||
"taught", "temple", "that", "this",
|
||||
"table", "tackle", "tail", "take", "tale", "talent", "talk",
|
||||
"tank", "tape", "target", "task", "taste", "tax", "teach",
|
||||
"team", "tear", "technology", "telephone", "television", "temperature", "tend",
|
||||
"tennis", "tent", "term", "test", "text", "thank", "theory",
|
||||
|
||||
// U
|
||||
"unable", "unkind", "usual",
|
||||
"umbrella", "unable", "uncle", "under", "undo", "unfair", "unfold",
|
||||
"union", "unique", "unit", "universe", "unknown", "unless", "unlike",
|
||||
"unlock", "until", "unusual", "update", "upgrade", "upon", "upper",
|
||||
"upset", "urban", "urge", "use", "usual", "utility", "utter",
|
||||
|
||||
// V
|
||||
"velvet", "vivid", "vote",
|
||||
"vacuum", "valid", "valley", "value", "vampire", "van", "vase",
|
||||
"vast", "vault", "vector", "vehicle", "velvet", "vendor", "venture",
|
||||
"verb", "verify", "version", "vessel", "veteran", "veto", "vibrate",
|
||||
"victory", "video", "view", "village", "violin", "virtue", "virus",
|
||||
|
||||
// W
|
||||
"we", "warm", "watch",
|
||||
"wage", "wait", "walk", "wall", "wander", "want", "war",
|
||||
"wash", "waste", "watch", "water", "wave", "way", "wealth",
|
||||
"weapon", "wear", "weather", "weave", "wedding", "week", "weight",
|
||||
"welcome", "well", "west", "wheel", "when", "whisper", "white",
|
||||
|
||||
// X
|
||||
"xylophone",
|
||||
"xenon", "xenophobia", "xerox", "xmas", "x-ray", "xylophone", "xylem",
|
||||
|
||||
// Y
|
||||
"yolk", "young", "your",
|
||||
"yard", "yarn", "year", "yell", "yellow", "yes", "yesterday",
|
||||
"yet", "yield", "yogurt", "yoke", "youth", "yawn", "yearn",
|
||||
"yacht", "yummy", "yogurt", "yoga", "yardstick", "yonder", "yummy",
|
||||
|
||||
// Z
|
||||
"zebra", "zodiac", "zucchini",
|
||||
"zero", "zone", "zoo", "zoom", "zeal", "zip", "zigzag",
|
||||
"zenith", "zest", "zipper", "zombie", "zonal", "zinc", "zephyr"
|
||||
};
|
||||
|
||||
int words_size = sizeof(words)/sizeof(words[0]);
|
||||
|
||||
// Generates random words
|
||||
void program_words(int argc, char* argv[])
|
||||
{
|
||||
int amount;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
amount = 10;
|
||||
} else if (argc == 2)
|
||||
{
|
||||
amount = atoi(argv[1]);
|
||||
}
|
||||
|
||||
for (int i=0; i<amount; i++)
|
||||
{
|
||||
int random = randint(global_ticks);
|
||||
char* word = words[random%words_size];
|
||||
//printf("Global ticks: %d\nRandom integer: %d\nWord: %s\n", global_ticks, random, word);
|
||||
printf("%s ", word);
|
||||
delay(10);
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
Reference in New Issue
Block a user