pub struct rtc_time_t {
    pub second: i32,
    pub minute: i32,
    pub hour: i32,
    pub day: i32,
    pub month: i32,
    pub year: i32,
}

use crate::{
    arch::x86_64::interrupt::{cli, sti},
    include::bindings::bindings::{io_in8, io_out8},
};

///置位0x70的第7位，禁止不可屏蔽中断
#[inline]
fn read_cmos(addr: u8) -> u8 {
    unsafe {
        io_out8(0x70, 0x80 | addr);
        return io_in8(0x71);
    }
}

enum CMOSTimeSelector {
    T_SECOND = 0x00,
    T_MINUTE = 0x02,
    T_HOUR = 0x04,
    T_DAY = 0x07,
    T_MONTH = 0x08,
    T_YEAR = 0x09,
}

///@brief 从主板cmos中获取时间
///
///@param t time结构体
///@return int 成功则为0
pub fn rtc_get_cmos_time(t: &mut rtc_time_t) -> Result<i32,i32> {
    unsafe {
        // 为防止中断请求打断该过程，需要先关中断
        cli();
        //0x0B
        let status_register_B: u8 = read_cmos(0x0B); // 读取状态寄存器B
        let is_24h: bool = if (status_register_B & 0x02) != 0 {
            true
        } else {
            false
        }; // 判断是否启用24小时模式

        let is_binary: bool = if (status_register_B & 0x04) != 0 {
            true
        } else {
            false
        }; // 判断是否为二进制码

        loop {
            t.year = read_cmos(CMOSTimeSelector::T_YEAR as u8) as i32;
            t.month = read_cmos(CMOSTimeSelector::T_MONTH as u8) as i32;
            t.day = read_cmos(CMOSTimeSelector::T_DAY as u8) as i32;
            t.hour = read_cmos(CMOSTimeSelector::T_HOUR as u8) as i32;
            t.minute = read_cmos(CMOSTimeSelector::T_MINUTE as u8) as i32;
            t.second = read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32;

            if t.second == read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32 {
                break;
            } // 若读取时间过程中时间发生跳变则重新读取
        }

        io_out8(0x70, 0x00);

        if !is_binary
        // 把BCD转为二进制
        {
            t.second = (t.second & 0xf) + (t.second >> 4) * 10;
            t.minute = (t.minute & 0xf) + (t.minute >> 4) * 10;
            t.hour = ((t.hour & 0xf) + ((t.hour & 0x70) >> 4) * 10) | (t.hour & 0x80);
            t.day = (t.day & 0xf) + ((t.day / 16) * 10);
            t.month = (t.month & 0xf) + (t.month >> 4) * 10;
            t.year = (t.year & 0xf) + (t.year >> 4) * 10;
        }
        t.year += 2000;

        if (!is_24h) && (t.hour & 0x80) != 0 {
            t.hour = ((t.hour & 0x7f) + 12) % 24;
        } // 将十二小时制转为24小时

        sti();
    }
    return Ok(0);
}
