moros 0.6.0

MOROS: Obscure Rust Operating System
Documentation
diff --git a/src/sys/cmos.rs b/src/sys/cmos.rs
index 0dff841..0fa8426 100644
--- a/src/sys/cmos.rs
+++ b/src/sys/cmos.rs
@@ -21,7 +21,7 @@ enum Interrupt {
     Update = 1 << 4,
 }
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
 pub struct RTC {
     pub year: u16,
     pub month: u8,
@@ -44,35 +44,52 @@ impl CMOS {
         }
     }
 
+    fn rtc_unchecked(&mut self) -> RTC {
+        RTC {
+            second: self.read_register(Register::Second),
+            minute: self.read_register(Register::Minute),
+            hour: self.read_register(Register::Hour),
+            day: self.read_register(Register::Day),
+            month: self.read_register(Register::Month),
+            year: self.read_register(Register::Year) as u16,
+        }
+    }
+
     pub fn rtc(&mut self) -> RTC {
-        while self.is_updating() {
-            x86_64::instructions::hlt();
+        // Read twice the RTC, discard the result and try again if the reads
+        // happened during an update
+        let mut rtc;
+        loop {
+            while self.is_updating() {
+                x86_64::instructions::hlt();
+            }
+            rtc = self.rtc_unchecked();
+            while self.is_updating() {
+                x86_64::instructions::hlt();
+            }
+            if rtc == self.rtc_unchecked() {
+                break;
+            }
         }
-        let mut second = self.read_register(Register::Second);
-        let mut minute = self.read_register(Register::Minute);
-        let mut hour = self.read_register(Register::Hour);
-        let mut day = self.read_register(Register::Day);
-        let mut month = self.read_register(Register::Month);
-        let mut year = self.read_register(Register::Year) as u16;
 
         let b = self.read_register(Register::B);
 
         if b & 0x04 == 0 { // BCD Mode
-            second = (second & 0x0F) + ((second / 16) * 10);
-            minute = (minute & 0x0F) + ((minute / 16) * 10);
-            hour = ((hour & 0x0F) + (((hour & 0x70) / 16) * 10)) | (hour & 0x80);
-            day = (day & 0x0F) + ((day / 16) * 10);
-            month = (month & 0x0F) + ((month / 16) * 10);
-            year = (year & 0x0F) + ((year / 16) * 10);
+            rtc.second = (rtc.second & 0x0F) + ((rtc.second / 16) * 10);
+            rtc.minute = (rtc.minute & 0x0F) + ((rtc.minute / 16) * 10);
+            rtc.hour = ((rtc.hour & 0x0F) + (((rtc.hour & 0x70) / 16) * 10)) | (rtc.hour & 0x80);
+            rtc.day = (rtc.day & 0x0F) + ((rtc.day / 16) * 10);
+            rtc.month = (rtc.month & 0x0F) + ((rtc.month / 16) * 10);
+            rtc.year = (rtc.year & 0x0F) + ((rtc.year / 16) * 10);
         }
 
-        if (b & 0x02 == 0) && (hour & 0x80 == 0) { // 12 hour format
-            hour = ((hour & 0x7F) + 12) % 24;
+        if (b & 0x02 == 0) && (rtc.hour & 0x80 == 0) { // 12 hour format
+            rtc.hour = ((rtc.hour & 0x7F) + 12) % 24;
         }
 
-        year += 2000; // TODO: Don't forget to change this next century
+        rtc.year += 2000; // TODO: Don't forget to change this next century
 
-        RTC { year, month, day, hour, minute, second }
+        rtc
     }
 
     pub fn enable_periodic_interrupt(&mut self) {
diff --git a/src/sys/fs/file.rs b/src/sys/fs/file.rs
index 7a64bf9..3697a2a 100644
--- a/src/sys/fs/file.rs
+++ b/src/sys/fs/file.rs
@@ -3,7 +3,7 @@ use super::dir::Dir;
 use super::block::Block;
 use super::dir_entry::DirEntry;
 
-use alloc::string::String;
+use alloc::string::{String, ToString};
 use alloc::vec;
 use core::convert::From;
 
@@ -120,7 +120,7 @@ impl File {
         let mut buf = vec![0; self.size()];
         let bytes = self.read(&mut buf);
         buf.resize(bytes, 0);
-        String::from_utf8(buf).unwrap()
+        String::from_utf8_lossy(&buf).to_string()
     }
 
     pub fn write(&mut self, buf: &[u8]) -> Result<usize, ()> {
diff --git a/src/usr/hex.rs b/src/usr/hex.rs
index 7647be0..13b2fab 100644
--- a/src/usr/hex.rs
+++ b/src/usr/hex.rs
@@ -8,7 +8,7 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
 
     let pathname = args[1];
 
-    if let Some(mut file) = sys::fs::File::open(pathname) {
+    if let Some(mut file) = sys::fs::File::open(pathname) { // TODO: Use new api::fs::read(path) -> Result<Vec<u8>, ()>
         let contents = file.read_to_string();
         print_hex(contents.as_bytes());
         usr::shell::ExitCode::CommandSuccessful
diff --git a/src/usr/shell.rs b/src/usr/shell.rs
index b502552..7803741 100644
--- a/src/usr/shell.rs
+++ b/src/usr/shell.rs
@@ -194,8 +194,6 @@ pub fn run() -> usr::shell::ExitCode {
         match exec(&cmd) {
             ExitCode::CommandSuccessful => {
                 success = true;
-                prompt.history.add(&cmd);
-                prompt.history.save(history_file);
             },
             ExitCode::ShellExit => {
                 break;
@@ -204,6 +202,8 @@ pub fn run() -> usr::shell::ExitCode {
                 success = false;
             },
         }
+        prompt.history.add(&cmd);
+        prompt.history.save(history_file);
         sys::console::drain();
         println!();
     }