diff --git a/makefile b/makefile index 51c5778..d703321 100644 --- a/makefile +++ b/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 $@ diff --git a/program.ld b/program.ld deleted file mode 100644 index dc36352..0000000 --- a/program.ld +++ /dev/null @@ -1,10 +0,0 @@ -OUTPUT_FORMAT(binary) -ENTRY(main) - -SECTIONS -{ - . = 0x1000; - .text : { *(.text*) } - .data : { *(.data*) } - .bss : { *(.bss*) } -} diff --git a/src/initrd/flower.bmp b/src/initrd/flower.bmp deleted file mode 100644 index 0d4f9c3..0000000 Binary files a/src/initrd/flower.bmp and /dev/null differ diff --git a/src/initrd/hello.bf b/src/initrd/hello.bf deleted file mode 100644 index 5a39f53..0000000 --- a/src/initrd/hello.bf +++ /dev/null @@ -1 +0,0 @@ --[------->+<]>-.-[->+++++<]>++.+++++++..+++.[--->+<]>-----.---[->+++<]>.-[--->+<]>---.+++.------.--------. diff --git a/src/initrd/hibou.bmp b/src/initrd/hibou.bmp deleted file mode 100644 index 35af2b7..0000000 Binary files a/src/initrd/hibou.bmp and /dev/null differ diff --git a/src/initrd/red.bmp b/src/initrd/red.bmp deleted file mode 100644 index bf748ed..0000000 Binary files a/src/initrd/red.bmp and /dev/null differ diff --git a/src/initrd/smiley.bmp b/src/initrd/smiley.bmp deleted file mode 100644 index 6d5fc22..0000000 Binary files a/src/initrd/smiley.bmp and /dev/null differ diff --git a/src/initrd/stuff/nice.txt b/src/initrd/stuff/nice.txt deleted file mode 100644 index 5849978..0000000 --- a/src/initrd/stuff/nice.txt +++ /dev/null @@ -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 diff --git a/src/initrd/welcome.txt b/src/initrd/welcome.txt deleted file mode 100644 index 60365aa..0000000 --- a/src/initrd/welcome.txt +++ /dev/null @@ -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... diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 0477cd5..cf2de4c 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -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"); } diff --git a/src/kernel/shell.c b/src/kernel/shell.c deleted file mode 100644 index 36d89ce..0000000 --- a/src/kernel/shell.c +++ /dev/null @@ -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 -#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]); - } - } -} diff --git a/src/programs/hello.c b/src/programs/hello.c deleted file mode 100644 index af3a85f..0000000 --- a/src/programs/hello.c +++ /dev/null @@ -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; -} diff --git a/src/utils/bf.c b/src/utils/bf.c deleted file mode 100644 index b530216..0000000 --- a/src/utils/bf.c +++ /dev/null @@ -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]); - } - } -} diff --git a/src/utils/bmp.c b/src/utils/bmp.c deleted file mode 100644 index f813ce4..0000000 --- a/src/utils/bmp.c +++ /dev/null @@ -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 -#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\n"); - return; - } - display_bmp(framebuffer, pitch, bpp, (uint8_t*)initrd_addr, argv[1]); -} diff --git a/src/utils/ciphers.c b/src/utils/ciphers.c deleted file mode 100644 index 4ff9460..0000000 --- a/src/utils/ciphers.c +++ /dev/null @@ -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 - -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 \n", argv[0]); - return; - } - - char input_buffer[BUFFER_SIZE] = {0}; - char output[BUFFER_SIZE] = {0}; - - for (int i=1; i= '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 \n", argv[0]); - return; - } - - char output[512]; - char message[BUFFER_SIZE]; - - for (int i=1; i -#include "../drivers/serial.h" -#include "../libc/string.h" - -void print_grid(const unsigned char grid[X][Y]) -{ - clear(); - for (int i=0; i= 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 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\n", message); - - puts(" "); - for (int i=0; i\n", argv[0]); - return; - } - - char message[MAX_MSG_LEN]; - message[0] = '\0'; - - for (int i=1; i\n"); - return; - } - cat_initrd((uint8_t*)initrd_addr, argv[1]); -} diff --git a/src/utils/math.c b/src/utils/math.c deleted file mode 100644 index 3acd2b1..0000000 --- a/src/utils/math.c +++ /dev/null @@ -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 -#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); -} diff --git a/src/utils/misc.c b/src/utils/misc.c deleted file mode 100644 index ec1374a..0000000 --- a/src/utils/misc.c +++ /dev/null @@ -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 \n", argv[0]); - return; - } - - char input_buffer[BUF_SIZE] = {0}; - for (int i=1; i\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 \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(); -} diff --git a/src/utils/navalbattle.c b/src/utils/navalbattle.c deleted file mode 100644 index dbc50fb..0000000 --- a/src/utils/navalbattle.c +++ /dev/null @@ -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; ix = 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; istate) - { - 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= 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; irole != 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; istate) - { - 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; istate == 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; istate == 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; -} diff --git a/src/utils/navalbattle.h b/src/utils/navalbattle.h deleted file mode 100644 index 0314c63..0000000 --- a/src/utils/navalbattle.h +++ /dev/null @@ -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 diff --git a/src/utils/pi.c b/src/utils/pi.c deleted file mode 100644 index 9db027e..0000000 --- a/src/utils/pi.c +++ /dev/null @@ -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 \n", argv[0]); - return; - } - - double pi = 0.0; - int terms = atoi(argv[1]); - - for (int i=0; i -#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; x0; 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> 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); - } -} diff --git a/src/utils/uhex.c b/src/utils/uhex.c deleted file mode 100644 index fab1523..0000000 --- a/src/utils/uhex.c +++ /dev/null @@ -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\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); -} diff --git a/src/utils/utils.h b/src/utils/utils.h deleted file mode 100644 index 8ee3176..0000000 --- a/src/utils/utils.h +++ /dev/null @@ -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 diff --git a/src/utils/words.c b/src/utils/words.c deleted file mode 100644 index 835d347..0000000 --- a/src/utils/words.c +++ /dev/null @@ -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