summaryrefslogtreecommitdiff
path: root/src/kernel/cmos.c
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/kernel/cmos.c
parent2de07a2abea4081ebab6d80729e5665ba862c74c (diff)
downloadportland-os-ab4e1cfc8c587e4144d847bbd41307eff03130b2.tar.gz
rtc timestamp, knob rand, random terminal color
Diffstat (limited to 'src/kernel/cmos.c')
-rw-r--r--src/kernel/cmos.c34
1 files changed, 34 insertions, 0 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