summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-16 22:26:47 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-16 22:26:47 -0500
commitab4e1cfc8c587e4144d847bbd41307eff03130b2 (patch)
tree4e5502422977c747f3e65633ede26b73d9556ca1 /src
parent2de07a2abea4081ebab6d80729e5665ba862c74c (diff)
downloadportland-os-ab4e1cfc8c587e4144d847bbd41307eff03130b2.tar.gz
rtc timestamp, knob rand, random terminal color
Diffstat (limited to 'src')
-rw-r--r--src/kernel/cmos.c34
-rw-r--r--src/kernel/cmos.h18
-rw-r--r--src/kernel/idt.c19
-rw-r--r--src/kernel/isrs.asm2
-rw-r--r--src/kernel/main.c11
-rw-r--r--src/user/highway/line.c20
-rw-r--r--src/user/highway/main.c6
-rw-r--r--src/user/highway/vars.c21
-rw-r--r--src/user/highway/vars.h1
-rw-r--r--src/user/include/knob/rand.h8
-rw-r--r--src/user/include/pland/syscall.h7
-rw-r--r--src/user/knob/rand.c19
12 files changed, 147 insertions, 19 deletions
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 <https://wiki.osdev.org/CMOS#The_Real-Time_Clock>.
+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 <stdint.h>
+
+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 <knob/format.h>
#include <knob/block.h>
#include <knob/heap.h>
+#include <knob/rand.h>
#include <pland/pcrt.h>
@@ -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 <stdint.h>
+
+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 <pland/syscall.h>
+#include <pland/pcrt.h>
+
+#include <stdint.h>
+
+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