
#![feature(lang_items, no_core)]
#![no_core]
#![no_main]

#[lang = "eh_personality"]
extern fn eh_personality() {}

#[lang = "panic_fmt"]
fn panic_fmt() -> ! { loop {} }

#[lang = "panic"]
pub fn panic(_expr_file_line: &(&'static str, &'static str, u32)) -> ! { panic_fmt() }

#[lang = "panic_location"]
struct Location<'a> {
    _file: &'a str,
    _line: u32,
    _col: u32,
}


#[lang = "sized"]
pub trait Sized {}

#[lang = "copy"]
trait Copy {}

#[lang = "add"]
pub trait Add<RHS=Self> {
    type Output;
    fn add(self, _rhs: RHS) -> Self::Output;
}

/* this can be bogus, apparently? */
impl Add for usize {
    type Output = usize;
    fn add(self, _rhs: usize) -> usize { 1 }
}

#[lang = "mul"]
pub trait Mul<RHS = Self> {
    type Output;
    fn mul(self, _rhs: RHS) -> Self::Output;
}

impl Mul for usize {
    type Output = usize;
    fn mul(self, _rhs: usize) -> usize { 1 }
}
    

#[no_mangle]
pub extern fn rust_entry() {

    //white A on black
    let spec: u16 = 0x0f_41;

    write_to_coord(1, 2, spec);

    loop { }
}

const X86_COLS: usize = 80;
#[allow(dead_code)]
const X86_ROWS: usize = 25;
const VRAM_OFFSET: usize  = 0xb8000;

fn write_to_coord(x: u8, y: u8, x86_specifier: u16) {
    unsafe {
        let offset = VRAM_OFFSET + (X86_COLS*2*(y as usize)) + (x as usize)*2;
        *(offset as *mut u16) = x86_specifier;
    }
}
