Esthetic improvements #3

Merged
xamidev merged 3 commits from dev into main 2024-08-24 22:19:29 +02:00
14 changed files with 427 additions and 25 deletions

View File

@@ -43,11 +43,19 @@ Triggers a kernel panic by trying to divide four by zero.
#### `words`
Prints ten random words using an arbitrary dictionary that you can expand in `src/programs/words.c`.
Prints random words using an arbitrary dictionary that you can expand in `src/programs/words.c`.
Options:
- `<nothing>` will default amount of words to 10
- `<integer>` will set the amount of words to that number
#### `primes`
Computes prime numbers up to `PRIMES_MAX`, defined in `src/programs/primes.c`.
Computes prime numbers.
Options:
- `<nothing>` will default to `PRIMES_MAX` (a million)
- `<integer>` will compute primes up to that number
#### `rainbow`
@@ -78,7 +86,7 @@ The classic echo command, that outputs your input.
Outputs information about the current system (CPU and RAM).
Options:
- `nothing` will show basic info about the CPUid and lower/upper memory.
- `<nothing>` will show basic info about the CPUid and lower/upper memory.
- `-v` will output the CPUID, lower/upper memory, and the memory map.
#### `conway`

64
src/drivers/rtc.c Normal file
View File

@@ -0,0 +1,64 @@
// Real-time clock driver implementation for better PRNG
// Author: xamidev
// Licensed under the Unlicense. See the repo below.
// https://github.com/xamidev/blankos
#include <stdint.h>
#include "rtc.h"
#include "../kernel/io.h"
#include "../libc/stdio.h"
uint8_t rtc_read_register(uint8_t reg)
{
outb(0x70, reg);
return inb(0x71);
}
uint8_t bcd_to_bin(uint8_t bcd)
{
return ((bcd/16)*10) + (bcd%16);
}
int rtc_is_updating()
{
outb(0x70, 0x0A);
return (inb(0x71) & 0x80);
}
void rtc_read_time(rtc_time_t *time)
{
while (rtc_is_updating());
time->seconds = rtc_read_register(0x00);
time->minutes = rtc_read_register(0x02);
time->hours = rtc_read_register(0x04);
time->day = rtc_read_register(0x06);
time->month = rtc_read_register(0x07);
time->year = rtc_read_register(0x08);
outb(0x70, 0x0B);
uint8_t registerB = inb(0x71);
if (!(registerB & 0x04))
{
time->seconds = bcd_to_bin(time->seconds);
time->minutes = bcd_to_bin(time->minutes);
time->hours = bcd_to_bin(time->hours);
time->day = bcd_to_bin(time->day);
time->month = bcd_to_bin(time->month);
time->year = bcd_to_bin(time->year);
}
}
void print_time(const rtc_time_t *time)
{
printf("%02d/%02d/%02d %02d:%02d:%02d\n", time->day, time->month, time->year, time->hours, time->minutes, time->seconds);
}
long time_seed()
{
rtc_time_t* time = {0};
rtc_read_time(time);
return time->day + time->month + time->year + time->hours + time->minutes + time->seconds;
}

23
src/drivers/rtc.h Normal file
View File

@@ -0,0 +1,23 @@
// Real-time clock driver implementation header for better PRNG
// Author: xamidev
// Licensed under the Unlicense. See the repo below.
// https://github.com/xamidev/blankos
#ifndef RTC_H
#define RTC_H
typedef struct
{
uint8_t seconds;
uint8_t minutes;
uint8_t hours;
uint8_t day;
uint8_t month;
uint8_t year;
} rtc_time_t;
void rtc_read_time(rtc_time_t *time);
long time_seed();
void print_time(const rtc_time_t *time);
#endif

View File

@@ -282,5 +282,5 @@ void serial_printf(int errlevel, const char* fmt, ...)
}
fmt++;
}
serial_puts("\n");
serial_puts("\r\n");
}

View File

@@ -31,11 +31,11 @@ void kmain(multiboot2_info *mb_info)
tags += ((tag_size + 7) & ~7);
}
serial_printf(3, "Framebuffer Address: 0x%x\r", fb_info->framebuffer_addr);
serial_printf(3, "Framebuffer Width: %u\r\n", fb_info->framebuffer_width);
serial_printf(3, "Framebuffer Height: %u\r\n", fb_info->framebuffer_height);
serial_printf(3, "Framebuffer Pitch: %u\r\n", fb_info->framebuffer_pitch);
serial_printf(3, "Framebuffer BPP: %u\r\n", fb_info->framebuffer_bpp);
serial_printf(3, "Framebuffer Address: 0x%x", fb_info->framebuffer_addr);
serial_printf(3, "Framebuffer Width: %u", fb_info->framebuffer_width);
serial_printf(3, "Framebuffer Height: %u", fb_info->framebuffer_height);
serial_printf(3, "Framebuffer Pitch: %u", fb_info->framebuffer_pitch);
serial_printf(3, "Framebuffer BPP: %u", fb_info->framebuffer_bpp);
if (fb_info) {
framebuffer = (uint32_t *)(uintptr_t) fb_info->framebuffer_addr;
@@ -47,6 +47,7 @@ void kmain(multiboot2_info *mb_info)
//8x16 font, not padded
VGA_WIDTH = width/8;
VGA_HEIGHT = height/16;
serial_printf(3, "VGA_WIDTH=%d, VGA_HEIGHT=%d", VGA_WIDTH, VGA_HEIGHT);
scanline = width * (bpp/8);
}

View File

@@ -7,20 +7,48 @@
#include "../libc/stdio.h"
#include "../libc/string.h"
#include "../programs/programs.h"
#include "../libc/crypto.h"
#include <stdint.h>
#include "../drivers/rtc.h"
#define BUFFER_SIZE 256
#define MAX_COMMANDS 16
#define MAX_ARGS 64
// Splash screen: esthetic stuff.
char* ascii_title =
"\n"
"----------------------------------------------\n"
"Blank OS version 0.3.71-dev\n"
"Blank OS version 0.3.84-alpha\n"
"Author: @xamidev - star the repo for a cookie!\n"
"----------------------------------------------\n"
"\n";
char* motd[] =
{
"Now in 2D!",
"Supercalifragilisticexpialidocious!",
"Tylko jedno w glowie mam!",
};
int motd_size = sizeof(motd)/sizeof(motd[0]);
void splash()
{
int random = randint(time_seed());
char* motd_pick = motd[random%motd_size];
cowsay(motd_pick, red, black);
colorputs(" blankOS 0.3.84-alpha", 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
@@ -66,8 +94,8 @@ int parse_input(char* input, char* argv[], int max_args)
}
void shell_install()
{
colorputs(ascii_title, yellow, black);
{
splash();
register_command("help", program_help);
register_command("panic", program_panic);
@@ -83,6 +111,7 @@ void shell_install()
register_command("conway", program_conway);
register_command("rot13", program_rot13);
register_command("morse", program_morse);
register_command("cowsay", program_cowsay);
for (;;)
{

View File

@@ -74,3 +74,32 @@ char* strtok(char* str, const char* delimiter)
return token_start;
}
int atoi(char* str)
{
int result = 0;
for (int i=0; str[i] != '\0'; i++)
{
result = result*10 + str[i] - '0';
}
return result;
}
void strcat(char* dest, const char* src)
{
while (*dest)
{
dest++;
}
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
}

View File

@@ -9,5 +9,8 @@
int strlen(const char* str);
int strcmp(const char* str1, const char* str2);
char* strtok(char* str, const char* delimiter);
int atoi(char* str);
void strcat(char* dest, const char* src);
#endif

View File

@@ -13,14 +13,13 @@
void print_grid(const unsigned char grid[X][Y])
{
clear();
for (int i=0; i<X; i++)
{
for (int j=0; j<Y; j++)
{
//(grid[i][j] == LIVE) ? putc(42) : putc(32);
if (grid[i][j] == LIVE) {
serial_printf(3, "alive");
//colorputc(32, 120);
putc(35);
} else {
putc(32);
}

View File

@@ -6,8 +6,8 @@
#ifndef CONWAY_H
#define CONWAY_H
#define X 25
#define Y 80
#define X 66
#define Y 240
#define GENERATIONS 100
#define DEAD 0

72
src/programs/cowsay.c Normal file
View File

@@ -0,0 +1,72 @@
// 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);
}

View File

@@ -6,6 +6,7 @@
#include <stdint.h>
#include "../libc/stdio.h"
#include "../kernel/system.h"
#include "../libc/string.h"
#define PRIMES_MAX 1000000
@@ -16,15 +17,25 @@ bool isPrime(int n)
return true;
}
void program_primes()
void program_primes(int argc, char* argv[])
{
for (long long x=0; x<PRIMES_MAX; x++)
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))
{
printf("%d ", x);
}
delay(2);
delay(1);
}
puts("\n");
}

View File

@@ -15,6 +15,8 @@ void program_sysinfo();
void get_cpuid();
void get_meminfo(unsigned int multiboot_info_address);
void program_conway();
void program_cowsay();
void cowsay(); // Splash screen
// Ciphers
void program_rot13();

View File

@@ -6,45 +6,206 @@
#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",
"be", "blindfold", "brilliant", "boy", "brilliant", "bring", "buddy",
"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",
"eagle", "ear", "effort", "evening",
"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",
"jog", "joint", "joke", "judge",
"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()
void program_words(int argc, char* argv[])
{
for (int i=0; i<10; i++)
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];