//! bare0.rs
//! Simple bare metal application

// feature to ensure symbols to be linked
#![feature(used)]
// build without the Rust standard library
#![no_std]

// Minimal runtime / startup for Cortex-M microcontrollers
extern crate cortex_m_rt;

const X_INIT: u32 = 10;

static mut X: u32 = X_INIT;
static mut Y: u32 = 0;

#[inline(never)]
fn main() {
    let mut x = unsafe { X };

    loop {
        x += 1;
        unsafe {
            X += 1;
            Y = X;
            assert!(x == X && X == Y);
        }
    }
    }
}
// 1. run the program in the debugger,
//    let the program run for a while and then press pause
//    look in the (Local -vscode) Variables view what do you find
//    x: 7852532
//
//    in the Expressions (WATCH -vscode) view add X and Y
//    what do you find
//
//    X: 785232
//    Y: 785232
//    step through one complete iteration of the loop
//    and see how the (Local) Variables are updated
//    can you foresee what will eventually happen?
// 	  Yes
//
//    commit your answers (bare0_1)
//
// 2. alter the constant X_INIT so that line 22 directly causes the x to wrap
// 	  what happens when x wraps
//    ** your answer here **
//
//    commit your answers (bare0_2)
//
// 3. change += opertions to wrapping_add
//    place a breakpoint at line 22
//    load and run the progam, what happens
//    ** your answer here **
//
//    now continue exectution, what happens
//    ** your answer here **
//
//    commit your answers (bare0_3)
//
//    (if the program did not succed back to the breakpoint
//    you have some fault in the program and go back to 3)
//
// 4. change the asserion to assert!(x == X && X == Y + 1), what happens
//    ** place your answer here **
//
//    commit your answers (bare0_4)
//
// 5. remove the assertion and
//
//    make "safe" functions for reading and writing X and Y
//    e.g. read_x, read_y, write_x, write_y
//
//    rewrite the program to use ONLY "safe" code besides the
//    read/write functions (which are internally "unsafe")
//
//    commit your solution (bare0_5)
//
// 6*. optional
//    implement a read_u32/write_u32, taking a reference to a
//    "static" variable
//
//    rewrite the program to use this abstraction instead of "read_x", etc.
//
//    commit your solution (bare0_6)
//

// As we are not using interrupts, we just register a dummy catch all handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];

extern "C" fn default_handler() {
    loop {}
}