From ab4e1cfc8c587e4144d847bbd41307eff03130b2 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Tue, 16 Feb 2021 22:26:47 -0500 Subject: rtc timestamp, knob rand, random terminal color --- src/kernel/cmos.c | 34 ++++++++++++++++++++++++++++++++++ src/kernel/cmos.h | 18 ++++++++++++++++++ src/kernel/idt.c | 19 ++++++++++++++++++- src/kernel/isrs.asm | 2 +- src/kernel/main.c | 11 ++++++----- src/user/highway/line.c | 20 +++++++++++++------- src/user/highway/main.c | 6 ++---- src/user/highway/vars.c | 21 +++++++++++++++++++++ src/user/highway/vars.h | 1 + src/user/include/knob/rand.h | 8 ++++++++ src/user/include/pland/syscall.h | 7 ++++++- src/user/knob/rand.c | 19 +++++++++++++++++++ 12 files changed, 147 insertions(+), 19 deletions(-) create mode 100644 src/kernel/cmos.c create mode 100644 src/kernel/cmos.h create mode 100644 src/user/include/knob/rand.h create mode 100644 src/user/knob/rand.c (limited to 'src') diff --git a/src/kernel/cmos.c b/src/kernel/cmos.c new file mode 100644 index 0000000..39f7c4f --- /dev/null +++ b/src/kernel/cmos.c @@ -0,0 +1,34 @@ +#include "cmos.h" +#include "util.h" + +static inline uint8_t read_cmos(uint8_t reg) { + outb(0x0070, reg); + return inb(0x0071); +} + +//The idea of reading until you get the same value twice, and checking the status register +// is from the OSDev Wiki page at . +struct rtc_time get_rtc_time() { + uint8_t prev_sec = -1; + struct rtc_time ret; +get_sec: + while (read_cmos(0x0a) & 0x80) + ;//spin while rtc is being updated + ret.seconds = read_cmos(0x00); + if (ret.seconds != prev_sec) { + prev_sec = ret.seconds; + goto get_sec; + } + ret.minutes = read_cmos(0x02); + ret.hours = read_cmos(0x04); + if (ret.hours & 0x80) { + ret.hours -= 0x80 - 12; + if (ret.hours == 24) + ret.hours = 0; + } + ret.day_of_week = read_cmos(0x06); + ret.day_of_month = read_cmos(0x07); + ret.month = read_cmos(0x08); + ret.year = read_cmos(0x09); + return ret; +} \ No newline at end of file diff --git a/src/kernel/cmos.h b/src/kernel/cmos.h new file mode 100644 index 0000000..53ec398 --- /dev/null +++ b/src/kernel/cmos.h @@ -0,0 +1,18 @@ +#ifndef CMOS_H +#define CMOS_H + +#include + +struct rtc_time { + uint8_t seconds; + uint8_t minutes; + uint8_t hours; + uint8_t day_of_week; + uint8_t day_of_month; + uint8_t month; + uint8_t year; +}; + +struct rtc_time get_rtc_time(); + +#endif \ No newline at end of file diff --git a/src/kernel/idt.c b/src/kernel/idt.c index 9b3ba96..99284ac 100644 --- a/src/kernel/idt.c +++ b/src/kernel/idt.c @@ -2,6 +2,7 @@ #include "window.h" #include "drive.h" #include "panic.h" +#include "cmos.h" #include "pmap.h" #include "task.h" #include "util.h" @@ -141,6 +142,21 @@ uint32_t sc_is_task_running(uint32_t handle) { return tasks[handle - 1].page_directory ? 1 : 0; } +static const uint16_t days_into_four_years_per_month[] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, + 366, 366+31, 366+59, 366+90, 366+120, 366+151, 366+181, 366+212, 366+243, 366+273, 366+304, 366+334, + 731, 731+31, 731+59, 731+90, 731+120, 731+151, 731+181, 731+212, 731+243, 731+273, 731+304, 731+334, + 1096, 1096+31, 1096+59, 1096+90, 1096+120, 1096+151, 1096+181, 1096+212, 1096+243, 1096+273, 1096+304, 1096+334 +}; + +//gregorian, assumes year is in 2001 to 2099 +uint32_t sc_get_timestamp() { + const struct rtc_time time = get_rtc_time(); + const uint32_t secs_into_month = time.seconds + time.minutes * 60 + time.hours * 3600 + (time.day_of_month - 1) * 86400; + const uint32_t days_to_month_into_four_years = days_into_four_years_per_month[time.month + (time.year % 4) * 12 - 1]; + return secs_into_month + days_to_month_into_four_years * 86400 + (time.year / 4) * (365 * 4 + 1) * 86400; +} + void const *syscall_table[] = { &sc_open_file, &sc_close_file, @@ -166,7 +182,8 @@ void const *syscall_table[] = { &sc_wait_any_ipc_sent, &find_unread_ipc, &sc_wait_ipc_read, - &sc_is_task_running + &sc_is_task_running, + &sc_get_timestamp }; //these aren't really void ()'s, but gcc complains if we take an address of a void, so we give it a type diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm index a4eb988..f547bfb 100644 --- a/src/kernel/isrs.asm +++ b/src/kernel/isrs.asm @@ -25,7 +25,7 @@ extern exception_halt extern pf_check_stack extern dump -n_syscalls equ 0x19 +n_syscalls equ 0x1a ;section .bss ;_debug_is_start_task resb 1 diff --git a/src/kernel/main.c b/src/kernel/main.c index 26cc5e4..1fd3182 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -4,16 +4,17 @@ #include "window.h" #include "panic.h" #include "boot.h" +#include "cmos.h" +#include "pmap.h" +#include "task.h" #include "util.h" +#include "elf.h" #include "fat.h" #include "ide.h" #include "idt.h" -#include "pmap.h" -#include "task.h" -#include "pci.h" -#include "elf.h" -#include "log.h" #include "kbd.h" +#include "log.h" +#include "pci.h" void _start_user_mode() __attribute__ ((noreturn)); diff --git a/src/user/highway/line.c b/src/user/highway/line.c index cefdf92..5d1e543 100644 --- a/src/user/highway/line.c +++ b/src/user/highway/line.c @@ -17,12 +17,12 @@ static inline uint8_t hex_to_int(char ch) { } void ensure_color() { - const struct no_null_sn *fg = get_var((struct no_null_sn){.data = "_color_fg", .length = 9}); - const struct no_null_sn *bg = get_var((struct no_null_sn){.data = "_color_bg", .length = 9}); - if (fg && bg) + const struct no_null_sn *color = get_var((struct no_null_sn){.data = "_color", .length = 6}); + //fgbg + if (color) term_set_color( - (hex_to_int(fg->data[0]) << 4) | hex_to_int(fg->data[1]), - (hex_to_int(bg->data[0]) << 4) | hex_to_int(bg->data[1]) + (hex_to_int(color->data[0]) << 4) | hex_to_int(color->data[1]), + (hex_to_int(color->data[2]) << 4) | hex_to_int(color->data[3]) ); } @@ -100,13 +100,19 @@ void run_line(const char *original_line) { term_clear(); term_paint(); } + else if (blockequ(line, "color", 6)) { + new_color(); + ensure_color(); + term_paint(); + } else if (blockequ(line, "help", 5)) { term_add_sz("Highway is a command shell for Portland OS. It includes variable support and a couple of pseudo-commands. Variables are addressed by surrounding with \"$\". The following list shows each of the pseudo-commands.\n\n" " source FILE\t" "run each command in FILE\n" - " clear\t\t\t" "clear the screen\n" - " echo STRING\t" "print STRING\n" " set VAR VALUE\t" "set $VAR$ to VALUE\n" + " color\t\t\t" "new color scheme\n" + " clear\t\t\t" "clear the screen\n" " vars\t\t\t" "dump variables\n" + " echo STRING\t" "print STRING\n" " quit\t\t\t" "exit highway\n" " help\t\t\t" "show this\n"); term_paint(); diff --git a/src/user/highway/main.c b/src/user/highway/main.c index c9ceee2..59586c1 100644 --- a/src/user/highway/main.c +++ b/src/user/highway/main.c @@ -5,12 +5,10 @@ #include "cmds.h" #include "line.h" +#include "vars.h" void main(const char *arg) { -//syslogf(" this task: 0x%2h", this_task); -//syslogf(" stdio task: 0x%2h", stdio_task); -//syslogf("calling task: 0x%2h", calling_task); - + new_color(); source(*arg ? arg : "user/default.rc"); ensure_color(); diff --git a/src/user/highway/vars.c b/src/user/highway/vars.c index 82062c4..ed9fa3a 100644 --- a/src/user/highway/vars.c +++ b/src/user/highway/vars.c @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -80,4 +81,24 @@ void dump_vars() { term_addf_no_ww("$%ns$\t= %ns\n", node->name.length, node->name.data, node->value.length, node->value.data); term_paint(); } +} + +static const char hex_digits[] = "0123456789abcdef"; +static char color[] = {'1', '0', '.', '.'}; + +static const struct no_null_sn color_name = { + .data = "_color", + .length = 6 +}; + +static const struct no_null_sn color_value = { + .data = color, + .length = 4 +}; + +void new_color() { + const uint8_t bg = gen_rand() % 0x30 + 0x38; + color[2] = hex_digits[bg >> 4]; + color[3] = hex_digits[bg & 0xf]; + set_var(color_name, color_value); } \ No newline at end of file diff --git a/src/user/highway/vars.h b/src/user/highway/vars.h index fc4d197..eca58d4 100644 --- a/src/user/highway/vars.h +++ b/src/user/highway/vars.h @@ -13,5 +13,6 @@ const struct no_null_sn *get_var(struct no_null_sn name) __attribute__ ((pure)); void del_var(struct no_null_sn name); void dump_vars(); +void new_color(); #endif \ No newline at end of file diff --git a/src/user/include/knob/rand.h b/src/user/include/knob/rand.h new file mode 100644 index 0000000..46052e2 --- /dev/null +++ b/src/user/include/knob/rand.h @@ -0,0 +1,8 @@ +#ifndef RAND_H +#define RAND_H + +#include + +uint32_t gen_rand(); + +#endif \ No newline at end of file diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h index 6870865..fd0b416 100644 --- a/src/user/include/pland/syscall.h +++ b/src/user/include/pland/syscall.h @@ -43,7 +43,8 @@ enum _scn { _SCN_WAIT_ANY_IPC_SENT, _SCN_FIND_UNREAD_IPC, _SCN_WAIT_IPC_READ, - _SCN_IS_TASK_RUNNING + _SCN_IS_TASK_RUNNING, + _SCN_GET_TIMESTAMP }; static inline uint32_t _sc0(enum _scn eax) { @@ -228,4 +229,8 @@ static inline bool _is_task_running(_task_handle_t handle) { return (bool)_sc1(_SCN_IS_TASK_RUNNING, handle); } +static inline uint32_t _get_timestamp() { + return _sc0(_SCN_GET_TIMESTAMP); +} + #endif \ No newline at end of file diff --git a/src/user/knob/rand.c b/src/user/knob/rand.c new file mode 100644 index 0000000..63648fb --- /dev/null +++ b/src/user/knob/rand.c @@ -0,0 +1,19 @@ +#include +#include + +#include + +static uint32_t r; + +static void seed_rand() { + r = _get_timestamp(); +} + +BEFORE_MAIN(seed_rand) + +uint32_t gen_rand() { + r ^= r << 13; + r ^= r >> 17; + r ^= r << 5; + return r; +} \ No newline at end of file -- cgit v1.2.3